Software /
code /
prosody
Comparison
util/sql.lua @ 7278:1891854b25ac
Merge 0.10->trunk
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Mon, 14 Mar 2016 14:20:37 +0100 |
parent | 7276:30dfaf36ea6d |
child | 7306:98c4c3a2b536 |
comparison
equal
deleted
inserted
replaced
7270:df22e314946c | 7278:1891854b25ac |
---|---|
23 | 23 |
24 local function is_column(x) return getmetatable(x)==column_mt; end | 24 local function is_column(x) return getmetatable(x)==column_mt; end |
25 local function is_index(x) return getmetatable(x)==index_mt; end | 25 local function is_index(x) return getmetatable(x)==index_mt; end |
26 local function is_table(x) return getmetatable(x)==table_mt; end | 26 local function is_table(x) return getmetatable(x)==table_mt; end |
27 local function is_query(x) return getmetatable(x)==query_mt; end | 27 local function is_query(x) return getmetatable(x)==query_mt; end |
28 local function Integer(n) return "Integer()" end | 28 local function Integer() return "Integer()" end |
29 local function String(n) return "String()" end | 29 local function String() return "String()" end |
30 | 30 |
31 local function Column(definition) | 31 local function Column(definition) |
32 return setmetatable(definition, column_mt); | 32 return setmetatable(definition, column_mt); |
33 end | 33 end |
34 local function Table(definition) | 34 local function Table(definition) |
122 return true; | 122 return true; |
123 end | 123 end |
124 function engine:onconnect() | 124 function engine:onconnect() |
125 -- Override from create_engine() | 125 -- Override from create_engine() |
126 end | 126 end |
127 | |
128 function engine:prepquery(sql) | |
129 if self.params.driver == "PostgreSQL" then | |
130 sql = sql:gsub("`", "\""); | |
131 end | |
132 return sql; | |
133 end | |
134 | |
127 function engine:execute(sql, ...) | 135 function engine:execute(sql, ...) |
128 local success, err = self:connect(); | 136 local success, err = self:connect(); |
129 if not success then return success, err; end | 137 if not success then return success, err; end |
130 local prepared = self.prepared; | 138 local prepared = self.prepared; |
131 | 139 |
151 local i = 0; local a = {...} | 159 local i = 0; local a = {...} |
152 log("debug", "[%s] %s", where, sql:gsub("%?", function () i = i + 1; local v = a[i]; if type(v) == "string" then v = ("%q"):format(v); end return tostring(v); end)); | 160 log("debug", "[%s] %s", where, sql:gsub("%?", function () i = i + 1; local v = a[i]; if type(v) == "string" then v = ("%q"):format(v); end return tostring(v); end)); |
153 end | 161 end |
154 | 162 |
155 function engine:execute_query(sql, ...) | 163 function engine:execute_query(sql, ...) |
156 if self.params.driver == "PostgreSQL" then | 164 sql = self:prepquery(sql); |
157 sql = sql:gsub("`", "\""); | |
158 end | |
159 local stmt = assert(self.conn:prepare(sql)); | 165 local stmt = assert(self.conn:prepare(sql)); |
160 assert(stmt:execute(...)); | 166 assert(stmt:execute(...)); |
161 return stmt:rows(); | 167 return stmt:rows(); |
162 end | 168 end |
163 function engine:execute_update(sql, ...) | 169 function engine:execute_update(sql, ...) |
164 if self.params.driver == "PostgreSQL" then | 170 sql = self:prepquery(sql); |
165 sql = sql:gsub("`", "\""); | |
166 end | |
167 local prepared = self.prepared; | 171 local prepared = self.prepared; |
168 local stmt = prepared[sql]; | 172 local stmt = prepared[sql]; |
169 if not stmt then | 173 if not stmt then |
170 stmt = assert(self.conn:prepare(sql)); | 174 stmt = assert(self.conn:prepare(sql)); |
171 prepared[sql] = stmt; | 175 prepared[sql] = stmt; |
293 end | 297 end |
294 function engine:set_encoding() -- to UTF-8 | 298 function engine:set_encoding() -- to UTF-8 |
295 local driver = self.params.driver; | 299 local driver = self.params.driver; |
296 if driver == "SQLite3" then | 300 if driver == "SQLite3" then |
297 return self:transaction(function() | 301 return self:transaction(function() |
298 if self:select"PRAGMA encoding;"()[1] == "UTF-8" then | 302 for encoding in self:select"PRAGMA encoding;" do |
299 self.charset = "utf8"; | 303 if encoding[1] == "UTF-8" then |
304 self.charset = "utf8"; | |
305 end | |
300 end | 306 end |
301 end); | 307 end); |
302 end | 308 end |
303 local set_names_query = "SET NAMES '%s';" | 309 local set_names_query = "SET NAMES '%s';" |
304 local charset = "utf8"; | 310 local charset = "utf8"; |
305 if driver == "MySQL" then | 311 if driver == "MySQL" then |
306 local ok, charsets = self:transaction(function() | 312 self:transaction(function() |
307 return self:select"SELECT `CHARACTER_SET_NAME` FROM `information_schema`.`CHARACTER_SETS` WHERE `CHARACTER_SET_NAME` LIKE 'utf8%' ORDER BY MAXLEN DESC LIMIT 1;"; | 313 for row in self:select"SELECT `CHARACTER_SET_NAME` FROM `information_schema`.`CHARACTER_SETS` WHERE `CHARACTER_SET_NAME` LIKE 'utf8%' ORDER BY MAXLEN DESC LIMIT 1;" do |
314 charset = row and row[1] or charset; | |
315 end | |
308 end); | 316 end); |
309 local row = ok and charsets(); | |
310 charset = row and row[1] or charset; | |
311 set_names_query = set_names_query:gsub(";$", (" COLLATE '%s';"):format(charset.."_bin")); | 317 set_names_query = set_names_query:gsub(";$", (" COLLATE '%s';"):format(charset.."_bin")); |
312 end | 318 end |
313 self.charset = charset; | 319 self.charset = charset; |
314 log("debug", "Using encoding '%s' for database connection", charset); | 320 log("debug", "Using encoding '%s' for database connection", charset); |
315 local ok, err = self:transaction(function() return self:execute(set_names_query:format(charset)); end); | 321 local ok, err = self:transaction(function() return self:execute(set_names_query:format(charset)); end); |
319 | 325 |
320 if driver == "MySQL" then | 326 if driver == "MySQL" then |
321 local ok, actual_charset = self:transaction(function () | 327 local ok, actual_charset = self:transaction(function () |
322 return self:select"SHOW SESSION VARIABLES LIKE 'character_set_client'"; | 328 return self:select"SHOW SESSION VARIABLES LIKE 'character_set_client'"; |
323 end); | 329 end); |
330 local charset_ok; | |
324 for row in actual_charset do | 331 for row in actual_charset do |
325 if row[2] ~= charset then | 332 if row[2] ~= charset then |
326 log("error", "MySQL %s is actually %q (expected %q)", row[1], row[2], charset); | 333 log("error", "MySQL %s is actually %q (expected %q)", row[1], row[2], charset); |
327 return false, "Failed to set connection encoding"; | 334 charset_ok = false; |
328 end | 335 end |
336 end | |
337 if not charset_ok then | |
338 return false, "Failed to set connection encoding"; | |
329 end | 339 end |
330 end | 340 end |
331 | 341 |
332 return true; | 342 return true; |
333 end | 343 end |