summaryrefslogtreecommitdiff
path: root/web/db.lua
blob: 5b616c2c4b7dfa512b53fd42661f5f331011a1a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
local dbi = require'DBI'
local cqueues = require'cqueues'

local function db_do(db, sql, ...)
	-- print('>>',sql,...)
	local stmt = assert(db:prepare(sql))
	::tryagain::
	local ok, err = stmt:execute(...)
	if not ok and err:match"locked" then
		print'still waiting'
		cqueues.sleep(1)
		goto tryagain
	end
	assert(ok, err)
	return stmt
end

local extra_methods = {}
function extra_methods.fetch_one(db, sql, ...)
	local stmt = db_do(db, sql, ...)
	local row = stmt:fetch(true)
	stmt:close()
	return row
end
function extra_methods.fetch(db, sql, ...)
	local stmt = db_do(db, sql, ...)
	local rows, i = {}, 1
	for row in stmt:rows(true) do
		rows[i] = row
		i = i + 1
	end
	stmt:close()
	return rows
end
function extra_methods.exec(db, sql, ...)
	local stmt = db_do(db, sql, ...)
	stmt:close()
end

local function get_conn()
	local c = assert(dbi.Connect('SQLite3','database.db'))
	-- fuck it
	local mt = getmetatable(c)
	for k,v in pairs(extra_methods) do mt.__index[k] = v end
	mt.__close = function(x) x:close() end
	c:exec('pragma foreign_keys=ON;')
	return c
end

local function apply_migrations(migrations)
	local conn <close> = get_conn()
	local ver = conn:fetch_one"pragma user_version".user_version
	for i = ver+1, #migrations do
		print("applying migration #"..i)
		conn:exec(migrations[i])
	end
	conn:exec("pragma user_version="..#migrations)
	assert(conn:commit())
end


return {conn=get_conn,apply_migrations=apply_migrations}