Search code examples
functionclassluadestroy

Call function when class is deleted/garbage collected


I have a class that opens a sqlite database in its constructor. Is there a way to have it close the database when it is destroyed (whether that be due to the programmer destroying it or being destroyed via Lua's garbage collection)?

The code so far:

local MyClass   = {}
local myClass_mt= {__index=MyClass,  __gc=__del}

function DBHandler.__init()
    -- constructor  
    local newMyClass = {
        db    = sqlite3.open(dbPath)
    }
    return setmetatable(newMyClass , myClass_mt)
end

local function __del()
    self.db.close()
end

Solution

  • For your particular case, according to its source code, LuaSQLite already closes its handle when it is destroyed:

    /* close method */
    static int db_close(lua_State *L) {
        sdb *db = lsqlite_checkdb(L, 1);
        lua_pushnumber(L, cleanupdb(L, db));
        return 1;
    }
    
    /* __gc method */
    static int db_gc(lua_State *L) {
        sdb *db = lsqlite_getdb(L, 1);
        if (db->db != NULL)  /* ignore closed databases */
            cleanupdb(L, db);
        return 0;
    }
    

    But IMO, freeing such resources on GC should be a backup solution: your object could be GCed after quite some time, so SQLite handle will stay open during this time. Some languages provides mechanism to release unmanaged resources as early as possible such as Python's with or C# using.

    Unfortunately Lua does not provide such feature so you should call close yourself when possible, by making a close method on your class too for instance.