File

plugins/storage/sqlbasic.lib.lua @ 5901:1d13f73af58e

certmanager: Default to using the server's cipher preference order by default, as clients have been shown to commonly select weak and insecure ciphers even when they support stronger ones
author Matthew Wild <mwild1@gmail.com>
date Sat, 09 Nov 2013 17:50:19 +0000
parent 5021:85b2689dbcfe
line wrap: on
line source


-- Basic SQL driver
-- This driver stores data as simple key-values

local ser = require "util.serialization".serialize;
local envload = require "util.envload".envload;
local deser = function(data)
	module:log("debug", "deser: %s", tostring(data));
	if not data then return nil; end
	local f = envload("return "..data, nil, {});
	if not f then return nil; end
	local s, d = pcall(f);
	if not s then return nil; end
	return d;
end;

local driver = {};
driver.__index = driver;

driver.item_table = "item";
driver.list_table = "list";

function driver:prepare(sql)
	module:log("debug", "query: %s", sql);
	local err;
	if not self.sqlcache then self.sqlcache = {}; end
	local r = self.sqlcache[sql];
	if r then return r; end
	r, err = self.connection:prepare(sql);
	if not r then error("Unable to prepare SQL statement: "..err); end
	self.sqlcache[sql] = r;
	return r;
end

function driver:load(username, host, datastore)
	local select = self:prepare("select data from "..self.item_table.." where username=? and host=? and datastore=?");
	select:execute(username, host, datastore);
	local row = select:fetch();
	return row and deser(row[1]) or nil;
end

function driver:store(username, host, datastore, data)
	if not data or next(data) == nil then
		local delete = self:prepare("delete from "..self.item_table.." where username=? and host=? and datastore=?");
		delete:execute(username, host, datastore);
		return true;
	else
		local d = self:load(username, host, datastore);
		if d then -- update
			local update = self:prepare("update "..self.item_table.." set data=? where username=? and host=? and datastore=?");
			return update:execute(ser(data), username, host, datastore);
		else -- insert
			local insert = self:prepare("insert into "..self.item_table.." values (?, ?, ?, ?)");
			return insert:execute(username, host, datastore, ser(data));
		end
	end
end

function driver:list_append(username, host, datastore, data)
	if not data then return; end
	local insert = self:prepare("insert into "..self.list_table.." values (?, ?, ?, ?)");
	return insert:execute(username, host, datastore, ser(data));
end

function driver:list_store(username, host, datastore, data)
	-- remove existing data
	local delete = self:prepare("delete from "..self.list_table.." where username=? and host=? and datastore=?");
	delete:execute(username, host, datastore);
	if data and next(data) ~= nil then
		-- add data
		for _, d in ipairs(data) do
			self:list_append(username, host, datastore, ser(d));
		end
	end
	return true;
end

function driver:list_load(username, host, datastore)
	local select = self:prepare("select data from "..self.list_table.." where username=? and host=? and datastore=?");
	select:execute(username, host, datastore);
	local r = {};
	for row in select:rows() do
		table.insert(r, deser(row[1]));
	end
	return r;
end

local _M = {};
function _M.new(dbtype, dbname, ...)
	local d = {};
	setmetatable(d, driver);
	local dbh = get_database(dbtype, dbname, ...);
	--d:set_connection(dbh);
	d.connection = dbh;
	return d;
end
return _M;