aboutsummaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/mod_storage_sql_ejabberd.lua232
-rw-r--r--plugins/storage/ejabberd_init.lib.lua252
-rw-r--r--plugins/storage/ejabberdstore.lib.lua190
3 files changed, 0 insertions, 674 deletions
diff --git a/plugins/mod_storage_sql_ejabberd.lua b/plugins/mod_storage_sql_ejabberd.lua
deleted file mode 100644
index 74763c92..00000000
--- a/plugins/mod_storage_sql_ejabberd.lua
+++ /dev/null
@@ -1,232 +0,0 @@
-
-local setmetatable = setmetatable;
-local error = error;
-local unpack = unpack;
-local module = module;
-local tostring = tostring;
-local pairs, next = pairs, next;
-local prosody = prosody;
-local assert = assert;
-local require = require;
-local st = require "util.stanza";
-local DBI = require "DBI";
-
--- connect to db
-local params = module:get_option("sql_ejabberd") or error("No sql_ejabberd config option");
-local database;
-do
- module:log("debug", "Opening database: %s", "dbi:"..params.driver..":"..params.database);
- prosody.unlock_globals();
- local dbh, err = DBI.Connect(
- params.driver, params.database,
- params.username, params.password,
- params.host, params.port
- );
- prosody.lock_globals();
- assert(dbh, err);
- dbh:autocommit(true);
- database = dbh;
-end
-
--- initialize db
-local ejabberd_init = module:require("ejabberd_init");
-ejabberd_init.init(database);
-
-local sqlcache = {};
-local function prepare(sql)
- module:log("debug", "query: %s", sql);
- local err;
- local r = sqlcache[sql];
- if not r then
- r, err = database:prepare(sql);
- if not r then error("Unable to prepare SQL statement: "..err); end
- sqlcache[sql] = r;
- end
- return r;
-end
-
-local _parse_xml = module:require("xmlparse");
-local function parse_xml(str)
- local s = _parse_xml(str);
- if s and not s.gsub then
- return st.preserialize(s);
- end
-end
-local function unparse_xml(s)
- return tostring(st.deserialize(s));
-end
-
-
-local handlers = {};
-
-handlers.accounts = {
- get = function(self, user)
- local select = self:query("select password from users where username=? and host=?", user, self.host);
- local row = select and select:fetch();
- if row then return { password = row[1] }; end
- end;
- set = function(self, user, data)
- if data and data.password then
- return self:modify("update users set password=? where username=? and host=?", data.password, user, self.host)
- or self:modify("insert into users (username, host, password) values (?, ?, ?)", user, self.host, data.password);
- else
- return self:modify("delete from users where username=? and host=?", user, self.host);
- end
- end;
-};
-handlers.vcard = {
- get = function(self, user)
- local select = self:query("select vcard from vcard where username=? and host=?", user, self.host);
- local row = select and select:fetch();
- if row then return parse_xml(row[1]); end
- end;
- set = function(self, user, data)
- if data then
- data = unparse_xml(data);
- return self:modify("update vcard set vcard=? where username=? and host=?", data, user, self.host)
- or self:modify("insert into vcard (username, host, vcard) values (?, ?, ?)", user, self.host, data);
- else
- return self:modify("delete from vcard where username=? and host=?", user, self.host);
- end
- end;
-};
-handlers.private = {
- get = function(self, user)
- local select = self:query("select namespace,data from private_storage where username=? and host=?", user, self.host);
- if select then
- local data = {};
- for row in select:rows() do
- data[row[1]] = parse_xml(row[2]);
- end
- return data;
- end
- end;
- set = function(self, user, data)
- if data then
- self:modify("delete from private_storage where username=? and host=?", user, self.host);
- for namespace,text in pairs(data) do
- self:modify("insert into private_storage (username, host, namespace, data) values (?, ?, ?, ?)", user, self.host, namespace, unparse_xml(text));
- end
- return true;
- else
- return self:modify("delete from private_storage where username=? and host=?", user, self.host);
- end
- end;
- -- TODO map_set, map_get
-};
-local subscription_map = { N = "none", B = "both", F = "from", T = "to" };
-local subscription_map_reverse = { none = "N", both = "B", from = "F", to = "T" };
-handlers.roster = {
- get = function(self, user)
- local select = self:query("select jid,nick,subscription,ask,server,subscribe,type from rosterusers where username=?", user);
- if select then
- local roster = { pending = {} };
- for row in select:rows() do
- local jid,nick,subscription,ask,server,subscribe,typ = unpack(row);
- local item = { groups = {} };
- if nick == "" then nick = nil; end
- item.nick = nick;
- item.subscription = subscription_map[subscription];
- if ask == "N" then ask = nil;
- elseif ask == "O" then ask = "subscribe"
- elseif ask == "I" then roster.pending[jid] = true; ask = nil;
- elseif ask == "B" then roster.pending[jid] = true; ask = "subscribe";
- else module:log("debug", "bad roster_item.ask: %s", ask); ask = nil; end
- item.ask = ask;
- roster[jid] = item;
- end
-
- select = self:query("select jid,grp from rostergroups where username=?", user);
- if select then
- for row in select:rows() do
- local jid,grp = unpack(row);
- if roster[jid] then roster[jid].groups[grp] = true; end
- end
- end
- select = self:query("select version from roster_version where username=?", user);
- local row = select and select:fetch();
- if row then
- roster[false] = { version = row[1]; };
- end
- return roster;
- end
- end;
- set = function(self, user, data)
- if data and next(data) ~= nil then
- self:modify("delete from rosterusers where username=?", user);
- self:modify("delete from rostergroups where username=?", user);
- self:modify("delete from roster_version where username=?", user);
- local done = {};
- local pending = data.pending or {};
- for jid,item in pairs(data) do
- if jid and jid ~= "pending" then
- local subscription = subscription_map_reverse[item.subscription];
- local ask;
- if pending[jid] then
- if item.ask then ask = "B"; else ask = "I"; end
- else
- if item.ask then ask = "O"; else ask = "N"; end
- end
- local r = self:modify("insert into rosterusers (username,jid,nick,subscription,ask,askmessage,server,subscribe) values (?, ?, ?, ?, ?, '', '', '')", user, jid, item.nick or "", subscription, ask);
- if not r then module:log("debug", "--- :( %s", tostring(r)); end
- done[jid] = true;
- for group in pairs(item.groups) do
- self:modify("insert into rostergroups (username,jid,grp) values (?, ?, ?)", user, jid, group);
- end
- end
- end
- for jid in pairs(pending) do
- if not done[jid] then
- self:modify("insert into rosterusers (username,jid,nick,subscription,ask,askmessage,server,subscribe) values (?, ?, ?, ?, ?. ''. ''. '')", user, jid, "", "N", "I");
- end
- end
- local version = data[false] and data[false].version;
- if version then
- self:modify("insert into roster_version (username,version) values (?, ?)", user, version);
- end
- return true;
- else
- self:modify("delete from rosterusers where username=?", user);
- self:modify("delete from rostergroups where username=?", user);
- self:modify("delete from roster_version where username=?", user);
- end
- end;
-};
-
------------------------------
-local driver = {};
-driver.__index = driver;
-
-function driver:query(sql, ...)
- local stmt,err = prepare(sql);
- if not stmt then
- module:log("error", "Failed to prepare SQL [[%s]], error: %s", sql, err);
- return nil, err;
- end
- local ok, err = stmt:execute(...);
- if not ok then
- module:log("error", "Failed to execute SQL [[%s]], error: %s", sql, err);
- return nil, err;
- end
- return stmt;
-end
-function driver:modify(sql, ...)
- local stmt, err = self:query(sql, ...);
- if stmt and stmt:affected() > 0 then return stmt; end
- return nil, err;
-end
-
-function driver:open(datastore, typ)
- local instance = setmetatable({ host = module.host, datastore = datastore }, self);
- local handler = handlers[datastore];
- if not handler then return nil; end
- for key,val in pairs(handler) do
- instance[key] = val;
- end
- if instance.init then instance:init(); end
- return instance;
-end
-
------------------------------
-
-module:add_item("data-driver", driver);
diff --git a/plugins/storage/ejabberd_init.lib.lua b/plugins/storage/ejabberd_init.lib.lua
deleted file mode 100644
index 91f8563b..00000000
--- a/plugins/storage/ejabberd_init.lib.lua
+++ /dev/null
@@ -1,252 +0,0 @@
-
-local t_concat = table.concat;
-local t_insert = table.insert;
-local pairs = pairs;
-local DBI = require "DBI";
-
-local sqlite = true;
-local q = {};
-
-local function set(key, val)
--- t_insert(q, "SET "..key.."="..val..";\n")
-end
-local function create_table(name, fields)
- t_insert(q, "CREATE TABLE ".."IF NOT EXISTS "..name.." (\n");
- for _, field in pairs(fields) do
- t_insert(q, "\t");
- field = t_concat(field, " ");
- if sqlite then
- if field:lower():match("^primary key *%(") then field = field:gsub("%(%d+%)", ""); end
- end
- t_insert(q, field);
- if _ ~= #fields then t_insert(q, ",\n"); end
- t_insert(q, "\n");
- end
- if sqlite then
- t_insert(q, ");\n");
- else
- t_insert(q, ") CHARACTER SET utf8;\n");
- end
-end
-local function create_index(name, index)
- --t_insert(q, "CREATE INDEX "..name.." ON "..index..";\n");
-end
-local function create_unique_index(name, index)
- --t_insert(q, "CREATE UNIQUE INDEX "..name.." ON "..index..";\n");
-end
-local function insert(target, value)
- t_insert(q, "INSERT INTO "..target.."\nVALUES "..value..";\n");
-end
-local function foreign_key(name, fkey, fname, fcol)
- t_insert(q, "ALTER TABLE `"..name.."` ADD FOREIGN KEY (`"..fkey.."`) REFERENCES `"..fname.."` (`"..fcol.."`) ON DELETE CASCADE;\n");
-end
-
-function build_query()
- q = {};
- set('table_type', 'InnoDB');
- create_table('hosts', {
- {'clusterid','integer','NOT','NULL'};
- {'host','varchar(250)','NOT','NULL','PRIMARY','KEY'};
- {'config','text','NOT','NULL'};
- });
- insert("hosts (clusterid, host, config)", "(1, 'localhost', '')");
- create_table('users', {
- {'host','varchar(250)','NOT','NULL'};
- {'username','varchar(250)','NOT','NULL'};
- {'password','text','NOT','NULL'};
- {'created_at','timestamp','NOT','NULL','DEFAULT','CURRENT_TIMESTAMP'};
- {'PRIMARY','KEY','(host, username)'};
- });
- create_table('last', {
- {'host','varchar(250)','NOT','NULL'};
- {'username','varchar(250)','NOT','NULL'};
- {'seconds','text','NOT','NULL'};
- {'state','text','NOT','NULL'};
- {'PRIMARY','KEY','(host, username)'};
- });
- create_table('rosterusers', {
- {'host','varchar(250)','NOT','NULL'};
- {'username','varchar(250)','NOT','NULL'};
- {'jid','varchar(250)','NOT','NULL'};
- {'nick','text','NOT','NULL'};
- {'subscription','character(1)','NOT','NULL'};
- {'ask','character(1)','NOT','NULL'};
- {'askmessage','text','NOT','NULL'};
- {'server','character(1)','NOT','NULL'};
- {'subscribe','text','NOT','NULL'};
- {'type','text'};
- {'created_at','timestamp','NOT','NULL','DEFAULT','CURRENT_TIMESTAMP'};
- {'PRIMARY','KEY','(host(75), username(75), jid(75))'};
- });
- create_index('i_rosteru_username', 'rosterusers(username)');
- create_index('i_rosteru_jid', 'rosterusers(jid)');
- create_table('rostergroups', {
- {'host','varchar(250)','NOT','NULL'};
- {'username','varchar(250)','NOT','NULL'};
- {'jid','varchar(250)','NOT','NULL'};
- {'grp','text','NOT','NULL'};
- {'PRIMARY','KEY','(host(75), username(75), jid(75))'};
- });
- --[[create_table('spool', {
- {'host','varchar(250)','NOT','NULL'};
- {'username','varchar(250)','NOT','NULL'};
- {'xml','text','NOT','NULL'};
- {'seq','BIGINT','UNSIGNED','NOT','NULL','AUTO_INCREMENT','UNIQUE'};
- {'created_at','timestamp','NOT','NULL','DEFAULT','CURRENT_TIMESTAMP'};
- {'PRIMARY','KEY','(host, username, seq)'};
- });]]
- create_table('vcard', {
- {'host','varchar(250)','NOT','NULL'};
- {'username','varchar(250)','NOT','NULL'};
- {'vcard','text','NOT','NULL'};
- {'created_at','timestamp','NOT','NULL','DEFAULT','CURRENT_TIMESTAMP'};
- {'PRIMARY','KEY','(host, username)'};
- });
- create_table('vcard_search', {
- {'host','varchar(250)','NOT','NULL'};
- {'username','varchar(250)','NOT','NULL'};
- {'lusername','varchar(250)','NOT','NULL'};
- {'fn','text','NOT','NULL'};
- {'lfn','varchar(250)','NOT','NULL'};
- {'family','text','NOT','NULL'};
- {'lfamily','varchar(250)','NOT','NULL'};
- {'given','text','NOT','NULL'};
- {'lgiven','varchar(250)','NOT','NULL'};
- {'middle','text','NOT','NULL'};
- {'lmiddle','varchar(250)','NOT','NULL'};
- {'nickname','text','NOT','NULL'};
- {'lnickname','varchar(250)','NOT','NULL'};
- {'bday','text','NOT','NULL'};
- {'lbday','varchar(250)','NOT','NULL'};
- {'ctry','text','NOT','NULL'};
- {'lctry','varchar(250)','NOT','NULL'};
- {'locality','text','NOT','NULL'};
- {'llocality','varchar(250)','NOT','NULL'};
- {'email','text','NOT','NULL'};
- {'lemail','varchar(250)','NOT','NULL'};
- {'orgname','text','NOT','NULL'};
- {'lorgname','varchar(250)','NOT','NULL'};
- {'orgunit','text','NOT','NULL'};
- {'lorgunit','varchar(250)','NOT','NULL'};
- {'PRIMARY','KEY','(host, lusername)'};
- });
- create_index('i_vcard_search_lfn ', 'vcard_search(lfn)');
- create_index('i_vcard_search_lfamily ', 'vcard_search(lfamily)');
- create_index('i_vcard_search_lgiven ', 'vcard_search(lgiven)');
- create_index('i_vcard_search_lmiddle ', 'vcard_search(lmiddle)');
- create_index('i_vcard_search_lnickname', 'vcard_search(lnickname)');
- create_index('i_vcard_search_lbday ', 'vcard_search(lbday)');
- create_index('i_vcard_search_lctry ', 'vcard_search(lctry)');
- create_index('i_vcard_search_llocality', 'vcard_search(llocality)');
- create_index('i_vcard_search_lemail ', 'vcard_search(lemail)');
- create_index('i_vcard_search_lorgname ', 'vcard_search(lorgname)');
- create_index('i_vcard_search_lorgunit ', 'vcard_search(lorgunit)');
- create_table('privacy_default_list', {
- {'host','varchar(250)','NOT','NULL'};
- {'username','varchar(250)'};
- {'name','varchar(250)','NOT','NULL'};
- {'PRIMARY','KEY','(host, username)'};
- });
- --[[create_table('privacy_list', {
- {'host','varchar(250)','NOT','NULL'};
- {'username','varchar(250)','NOT','NULL'};
- {'name','varchar(250)','NOT','NULL'};
- {'id','BIGINT','UNSIGNED','NOT','NULL','AUTO_INCREMENT','UNIQUE'};
- {'created_at','timestamp','NOT','NULL','DEFAULT','CURRENT_TIMESTAMP'};
- {'PRIMARY','KEY','(host, username, name)'};
- });]]
- create_table('privacy_list_data', {
- {'id','bigint'};
- {'t','character(1)','NOT','NULL'};
- {'value','text','NOT','NULL'};
- {'action','character(1)','NOT','NULL'};
- {'ord','NUMERIC','NOT','NULL'};
- {'match_all','boolean','NOT','NULL'};
- {'match_iq','boolean','NOT','NULL'};
- {'match_message','boolean','NOT','NULL'};
- {'match_presence_in','boolean','NOT','NULL'};
- {'match_presence_out','boolean','NOT','NULL'};
- });
- create_table('private_storage', {
- {'host','varchar(250)','NOT','NULL'};
- {'username','varchar(250)','NOT','NULL'};
- {'namespace','varchar(250)','NOT','NULL'};
- {'data','text','NOT','NULL'};
- {'created_at','timestamp','NOT','NULL','DEFAULT','CURRENT_TIMESTAMP'};
- {'PRIMARY','KEY','(host(75), username(75), namespace(75))'};
- });
- create_index('i_private_storage_username USING BTREE', 'private_storage(username)');
- create_table('roster_version', {
- {'username','varchar(250)','PRIMARY','KEY'};
- {'version','text','NOT','NULL'};
- });
- --[[create_table('pubsub_node', {
- {'host','text'};
- {'node','text'};
- {'parent','text'};
- {'type','text'};
- {'nodeid','bigint','auto_increment','primary','key'};
- });
- create_index('i_pubsub_node_parent', 'pubsub_node(parent(120))');
- create_unique_index('i_pubsub_node_tuple', 'pubsub_node(host(20), node(120))');
- create_table('pubsub_node_option', {
- {'nodeid','bigint'};
- {'name','text'};
- {'val','text'};
- });
- create_index('i_pubsub_node_option_nodeid', 'pubsub_node_option(nodeid)');
- foreign_key('pubsub_node_option', 'nodeid', 'pubsub_node', 'nodeid');
- create_table('pubsub_node_owner', {
- {'nodeid','bigint'};
- {'owner','text'};
- });
- create_index('i_pubsub_node_owner_nodeid', 'pubsub_node_owner(nodeid)');
- foreign_key('pubsub_node_owner', 'nodeid', 'pubsub_node', 'nodeid');
- create_table('pubsub_state', {
- {'nodeid','bigint'};
- {'jid','text'};
- {'affiliation','character(1)'};
- {'subscriptions','text'};
- {'stateid','bigint','auto_increment','primary','key'};
- });
- create_index('i_pubsub_state_jid', 'pubsub_state(jid(60))');
- create_unique_index('i_pubsub_state_tuple', 'pubsub_state(nodeid, jid(60))');
- foreign_key('pubsub_state', 'nodeid', 'pubsub_node', 'nodeid');
- create_table('pubsub_item', {
- {'nodeid','bigint'};
- {'itemid','text'};
- {'publisher','text'};
- {'creation','text'};
- {'modification','text'};
- {'payload','text'};
- });
- create_index('i_pubsub_item_itemid', 'pubsub_item(itemid(36))');
- create_unique_index('i_pubsub_item_tuple', 'pubsub_item(nodeid, itemid(36))');
- foreign_key('pubsub_item', 'nodeid', 'pubsub_node', 'nodeid');
- create_table('pubsub_subscription_opt', {
- {'subid','text'};
- {'opt_name','varchar(32)'};
- {'opt_value','text'};
- });
- create_unique_index('i_pubsub_subscription_opt', 'pubsub_subscription_opt(subid(32), opt_name(32))');]]
- return t_concat(q);
-end
-
-local function init(dbh)
- local q = build_query();
- for statement in q:gmatch("[^;]*;") do
- statement = statement:gsub("\n", ""):gsub("\t", " ");
- if sqlite then
- statement = statement:gsub("AUTO_INCREMENT", "AUTOINCREMENT");
- statement = statement:gsub("auto_increment", "autoincrement");
- end
- local result, err = DBI.Do(dbh, statement);
- if not result then
- print("X", result, err);
- print("Y", statement);
- end
- end
-end
-
-local _M = { init = init };
-return _M;
diff --git a/plugins/storage/ejabberdstore.lib.lua b/plugins/storage/ejabberdstore.lib.lua
deleted file mode 100644
index 7e8592a8..00000000
--- a/plugins/storage/ejabberdstore.lib.lua
+++ /dev/null
@@ -1,190 +0,0 @@
-
-local handlers = {};
-
-handlers.accounts = {
- get = function(self, user)
- local select = self:query("select password from users where username=?", user);
- local row = select and select:fetch();
- if row then return { password = row[1] }; end
- end;
- set = function(self, user, data)
- if data and data.password then
- return self:modify("update users set password=? where username=?", data.password, user)
- or self:modify("insert into users (username, password) values (?, ?)", user, data.password);
- else
- return self:modify("delete from users where username=?", user);
- end
- end;
-};
-handlers.vcard = {
- get = function(self, user)
- local select = self:query("select vcard from vcard where username=?", user);
- local row = select and select:fetch();
- if row then return parse_xml(row[1]); end
- end;
- set = function(self, user, data)
- if data then
- data = unparse_xml(data);
- return self:modify("update vcard set vcard=? where username=?", data, user)
- or self:modify("insert into vcard (username, vcard) values (?, ?)", user, data);
- else
- return self:modify("delete from vcard where username=?", user);
- end
- end;
-};
-handlers.private = {
- get = function(self, user)
- local select = self:query("select namespace,data from private_storage where username=?", user);
- if select then
- local data = {};
- for row in select:rows() do
- data[row[1]] = parse_xml(row[2]);
- end
- return data;
- end
- end;
- set = function(self, user, data)
- if data then
- self:modify("delete from private_storage where username=?", user);
- for namespace,text in pairs(data) do
- self:modify("insert into private_storage (username, namespace, data) values (?, ?, ?)", user, namespace, unparse_xml(text));
- end
- return true;
- else
- return self:modify("delete from private_storage where username=?", user);
- end
- end;
- -- TODO map_set, map_get
-};
-local subscription_map = { N = "none", B = "both", F = "from", T = "to" };
-local subscription_map_reverse = { none = "N", both = "B", from = "F", to = "T" };
-handlers.roster = {
- get = function(self, user)
- local select = self:query("select jid,nick,subscription,ask,server,subscribe,type from rosterusers where username=?", user);
- if select then
- local roster = { pending = {} };
- for row in select:rows() do
- local jid,nick,subscription,ask,server,subscribe,typ = unpack(row);
- local item = { groups = {} };
- if nick == "" then nick = nil; end
- item.nick = nick;
- item.subscription = subscription_map[subscription];
- if ask == "N" then ask = nil;
- elseif ask == "O" then ask = "subscribe"
- elseif ask == "I" then roster.pending[jid] = true; ask = nil;
- elseif ask == "B" then roster.pending[jid] = true; ask = "subscribe";
- else module:log("debug", "bad roster_item.ask: %s", ask); ask = nil; end
- item.ask = ask;
- roster[jid] = item;
- end
-
- select = self:query("select jid,grp from rostergroups where username=?", user);
- if select then
- for row in select:rows() do
- local jid,grp = unpack(rows);
- if roster[jid] then roster[jid].groups[grp] = true; end
- end
- end
- select = self:query("select version from roster_version where username=?", user);
- local row = select and select:fetch();
- if row then
- roster[false] = { version = row[1]; };
- end
- return roster;
- end
- end;
- set = function(self, user, data)
- if data and next(data) ~= nil then
- self:modify("delete from rosterusers where username=?", user);
- self:modify("delete from rostergroups where username=?", user);
- self:modify("delete from roster_version where username=?", user);
- local done = {};
- local pending = data.pending or {};
- for jid,item in pairs(data) do
- if jid and jid ~= "pending" then
- local subscription = subscription_map_reverse[item.subscription];
- local ask;
- if pending[jid] then
- if item.ask then ask = "B"; else ask = "I"; end
- else
- if item.ask then ask = "O"; else ask = "N"; end
- end
- local r = self:modify("insert into rosterusers (username,jid,nick,subscription,ask,askmessage,server,subscribe) values (?, ?, ?, ?, ?, '', '', '')", user, jid, item.nick or "", subscription, ask);
- if not r then module:log("debug", "--- :( %s", tostring(r)); end
- done[jid] = true;
- for group in pairs(item.groups) do
- self:modify("insert into rostergroups (username,jid,grp) values (?, ?, ?)", user, jid, group);
- end
- end
- end
- for jid in pairs(pending) do
- if not done[jid] then
- self:modify("insert into rosterusers (username,jid,nick,subscription,ask,askmessage,server,subscribe) values (?, ?, ?, ?, ?. ''. ''. '')", user, jid, "", "N", "I");
- end
- end
- local version = data[false] and data[false].version;
- if version then
- self:modify("insert into roster_version (username,version) values (?, ?)", user, version);
- end
- return true;
- else
- self:modify("delete from rosterusers where username=?", user);
- self:modify("delete from rostergroups where username=?", user);
- self:modify("delete from roster_version where username=?", user);
- end
- end;
-};
-
------------------------------
-local driver = {};
-driver.__index = driver;
-
-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.database:prepare(sql);
- if not r then error("Unable to prepare SQL statement: "..err); end
- self.sqlcache[sql] = r;
- return r;
-end
-
-function driver:query(sql, ...)
- local stmt = self:prepare(sql);
- if stmt:execute(...) then return stmt; end
-end
-function driver:modify(sql, ...)
- local stmt = self:query(sql, ...);
- if stmt and stmt:affected() > 0 then return stmt; end
-end
-
-function driver:open(host, datastore, typ)
- local cache_key = host.." "..datastore;
- if self.ds_cache[cache_key] then return self.ds_cache[cache_key]; end
- local instance = setmetatable({}, self);
- instance.host = host;
- instance.datastore = datastore;
- local handler = handlers[datastore];
- if not handler then return nil; end
- for key,val in pairs(handler) do
- instance[key] = val;
- end
- if instance.init then instance:init(); end
- self.ds_cache[cache_key] = instance;
- return instance;
-end
-
------------------------------
-local _M = {};
-
-function _M.new(dbtype, dbname, ...)
- local instance = setmetatable({}, driver);
- instance.__index = instance;
- instance.database = get_database(dbtype, dbname, ...);
- instance.ds_cache = {};
- return instance;
-end
-
-return _M;