login

local ffi = require "ffi"

ffi.cdef[[
typedef struct sqlite3 sqlite3;
int sqlite3_open(
  const char *filename,   /* Database filename (UTF-8) */
  sqlite3 **ppDb          /* OUT: SQLite db handle */
);
int sqlite3_close(sqlite3*);
int sqlite3_exec(
  sqlite3*,                                  /* An open database */
  const char *sql,                           /* SQL to be evaluated */
  int (*callback)(void*,int,char**,char**),  /* Callback function */
  void *,                                    /* 1st argument to callback */
  char **errmsg                              /* Error msg written here */
);
]]
local C = ffi.load("sqlite3")

local DB = {}
DB.__index = DB

function DB:execute(sql, cb, arg)
    if C.sqlite3_exec(self.db, sql, cb, arg, self.err) ~= 0 then
        print(ffi.string(self.err[0]))
    end
end

function DB:get_rows(sql)
    local rows = {}
    self:execute(sql, function (obj, argc, argv, col)
        local row = {}
        for i = 0, argc-1 do
            local col_name = ffi.string(col[i])
            local col_value = ffi.string(argv[i])
            row[col_name] = col_value
        end
        table.insert(rows, row)
        return 0
    end)
    return rows
end

function DB:close()
    C.sqlite3_close(self.db)
end

local function open(fname)
    local self = setmetatable({}, DB)
    local pdb = ffi.new("sqlite3 *[1]")
    C.sqlite3_open(fname, pdb)
    self.db = pdb[0]
    self.err = ffi.new("char *[1]")
    return self
end

return {open=open}