singe/testScripts/packedSql/packedSql.singe

82 lines
3 KiB
Text

-- sqlite3.open against a database that exists only inside a .game. Asked to read, Singe opens it
-- where it lies, through a read-only SQLite VFS over the packed rows; asked to write, it copies the
-- database once to the game's data directory and opens the copy, then and from then on.
--
-- It has to be run packed, with no loose copy beside the container -- a loose file shadows the
-- packed one and the whole test then proves nothing -- so from a directory holding this folder:
--
-- Singe -P packedSql packedSql.game
-- rm -rf packedSql
-- Singe -w -C 720x480 packedSql.game
-- Singe -w -C 720x480 packedSql.game
--
-- Each run prints one line: SQLTEST pass=N fail=0 count=C. The count is the rows the writable
-- copy holds after this run adds one: 4 the first time, 5 the second, since the copy persists.
-- The .game itself is never written. Every failure prints what it wanted first.
dofile("Singe/Framework.singe")
local sqlite3 = require("sqlite3")
local pass = 0
local fail = 0
local function check(what, got, want)
if got == want then
pass = pass + 1
else
fail = fail + 1
debugPrint(string.format("FAIL %s: got %s, wanted %s", what, tostring(got), tostring(want)))
end
end
local function count(db)
local n = nil
for row in db:nrows("SELECT COUNT(*) AS n FROM levels") do
n = row.n
end
return n
end
-- Read only: the packed database, read where it lies. On a later run the writable copy exists and
-- is what a name resolves to, as io.open's does; either way the first three rows are the packed ones.
local reader = sqlite3.open("packedSql/levels.db", sqlite3.OPEN_READONLY)
local names = {}
check("read-only open", reader ~= nil, true)
for row in reader:nrows("SELECT name FROM levels WHERE id <= 3 ORDER BY id") do
names[#names + 1] = row.name
end
check("rows read", table.concat(names, ","), "first,second,third")
check("a read-only open refuses a write", reader:exec("INSERT INTO levels VALUES (99, 'nope')") == sqlite3.OK, false)
reader:close()
-- Writable: copied out to the data directory the first time, and the copy changed.
local writer = sqlite3.open("packedSql/levels.db")
local before = writer and count(writer)
check("writable open", writer ~= nil, true)
check("a write", writer:exec("INSERT INTO levels (name) VALUES ('added')"), sqlite3.OK)
local after = count(writer)
check("the write is there", after, before + 1)
writer:close()
-- The copy is what the name means now, read only or not.
local again = sqlite3.open("packedSql/levels.db", sqlite3.OPEN_READONLY)
check("the copy is what a read now opens", count(again), after)
again:close()
-- What is not there, and the names SQLite keeps for itself.
check("a missing packed name does not open", sqlite3.open("packedSql/missing.db", sqlite3.OPEN_READONLY), nil)
local memory = sqlite3.open(":memory:")
check(":memory: still opens", memory ~= nil, true)
check(":memory: still works", memory:exec("CREATE TABLE t (x)"), sqlite3.OK)
memory:close()
debugPrint(string.format("SQLTEST pass=%d fail=%d count=%d", pass, fail, after or -1))
singeQuit()