Software /
code /
prosody
Comparison
plugins/storage/sqlbasic.lib.lua @ 2678:c5882e2e12b5
mod_storage, plus a bit of SQL and XML.
author | Waqas Hussain <waqas20@gmail.com> |
---|---|
date | Fri, 19 Feb 2010 22:32:28 +0500 |
child | 5021:85b2689dbcfe |
comparison
equal
deleted
inserted
replaced
2677:467568f1117d | 2678:c5882e2e12b5 |
---|---|
1 | |
2 -- Basic SQL driver | |
3 -- This driver stores data as simple key-values | |
4 | |
5 local ser = require "util.serialization".serialize; | |
6 local deser = function(data) | |
7 module:log("debug", "deser: %s", tostring(data)); | |
8 if not data then return nil; end | |
9 local f = loadstring("return "..data); | |
10 if not f then return nil; end | |
11 setfenv(f, {}); | |
12 local s, d = pcall(f); | |
13 if not s then return nil; end | |
14 return d; | |
15 end; | |
16 | |
17 local driver = {}; | |
18 driver.__index = driver; | |
19 | |
20 driver.item_table = "item"; | |
21 driver.list_table = "list"; | |
22 | |
23 function driver:prepare(sql) | |
24 module:log("debug", "query: %s", sql); | |
25 local err; | |
26 if not self.sqlcache then self.sqlcache = {}; end | |
27 local r = self.sqlcache[sql]; | |
28 if r then return r; end | |
29 r, err = self.connection:prepare(sql); | |
30 if not r then error("Unable to prepare SQL statement: "..err); end | |
31 self.sqlcache[sql] = r; | |
32 return r; | |
33 end | |
34 | |
35 function driver:load(username, host, datastore) | |
36 local select = self:prepare("select data from "..self.item_table.." where username=? and host=? and datastore=?"); | |
37 select:execute(username, host, datastore); | |
38 local row = select:fetch(); | |
39 return row and deser(row[1]) or nil; | |
40 end | |
41 | |
42 function driver:store(username, host, datastore, data) | |
43 if not data or next(data) == nil then | |
44 local delete = self:prepare("delete from "..self.item_table.." where username=? and host=? and datastore=?"); | |
45 delete:execute(username, host, datastore); | |
46 return true; | |
47 else | |
48 local d = self:load(username, host, datastore); | |
49 if d then -- update | |
50 local update = self:prepare("update "..self.item_table.." set data=? where username=? and host=? and datastore=?"); | |
51 return update:execute(ser(data), username, host, datastore); | |
52 else -- insert | |
53 local insert = self:prepare("insert into "..self.item_table.." values (?, ?, ?, ?)"); | |
54 return insert:execute(username, host, datastore, ser(data)); | |
55 end | |
56 end | |
57 end | |
58 | |
59 function driver:list_append(username, host, datastore, data) | |
60 if not data then return; end | |
61 local insert = self:prepare("insert into "..self.list_table.." values (?, ?, ?, ?)"); | |
62 return insert:execute(username, host, datastore, ser(data)); | |
63 end | |
64 | |
65 function driver:list_store(username, host, datastore, data) | |
66 -- remove existing data | |
67 local delete = self:prepare("delete from "..self.list_table.." where username=? and host=? and datastore=?"); | |
68 delete:execute(username, host, datastore); | |
69 if data and next(data) ~= nil then | |
70 -- add data | |
71 for _, d in ipairs(data) do | |
72 self:list_append(username, host, datastore, ser(d)); | |
73 end | |
74 end | |
75 return true; | |
76 end | |
77 | |
78 function driver:list_load(username, host, datastore) | |
79 local select = self:prepare("select data from "..self.list_table.." where username=? and host=? and datastore=?"); | |
80 select:execute(username, host, datastore); | |
81 local r = {}; | |
82 for row in select:rows() do | |
83 table.insert(r, deser(row[1])); | |
84 end | |
85 return r; | |
86 end | |
87 | |
88 local _M = {}; | |
89 function _M.new(dbtype, dbname, ...) | |
90 local d = {}; | |
91 setmetatable(d, driver); | |
92 local dbh = get_database(dbtype, dbname, ...); | |
93 --d:set_connection(dbh); | |
94 d.connection = dbh; | |
95 return d; | |
96 end | |
97 return _M; |