Software / code / prosody
Comparison
plugins/mod_storage_sql.lua @ 8033:6c3cae9b96cb
mod_storage_sql: Move SQL queries into multiline strings for readability [luacheck]
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Sat, 01 Apr 2017 19:26:27 +0200 |
| parent | 8032:aa9f198cb3c9 |
| child | 8034:149553feb04e |
comparison
equal
deleted
inserted
replaced
| 8032:aa9f198cb3c9 | 8033:6c3cae9b96cb |
|---|---|
| 55 local user, store; | 55 local user, store; |
| 56 | 56 |
| 57 local function keyval_store_get() | 57 local function keyval_store_get() |
| 58 local haveany; | 58 local haveany; |
| 59 local result = {}; | 59 local result = {}; |
| 60 for row in engine:select("SELECT `key`,`type`,`value` FROM `prosody` WHERE `host`=? AND `user`=? AND `store`=?", host, user or "", store) do | 60 local select_sql = [[ |
| 61 SELECT `key`,`type`,`value` | |
| 62 FROM `prosody` | |
| 63 WHERE `host`=? AND `user`=? AND `store`=?; | |
| 64 ]] | |
| 65 for row in engine:select(select_sql, host, user or "", store) do | |
| 61 haveany = true; | 66 haveany = true; |
| 62 local k = row[1]; | 67 local k = row[1]; |
| 63 local v = deserialize(row[2], row[3]); | 68 local v = deserialize(row[2], row[3]); |
| 64 if k and v then | 69 if k and v then |
| 65 if k ~= "" then result[k] = v; elseif type(v) == "table" then | 70 if k ~= "" then result[k] = v; elseif type(v) == "table" then |
| 72 if haveany then | 77 if haveany then |
| 73 return result; | 78 return result; |
| 74 end | 79 end |
| 75 end | 80 end |
| 76 local function keyval_store_set(data) | 81 local function keyval_store_set(data) |
| 77 engine:delete("DELETE FROM `prosody` WHERE `host`=? AND `user`=? AND `store`=?", host, user or "", store); | 82 local delete_sql = [[ |
| 78 | 83 DELETE FROM `prosody` |
| 84 WHERE `host`=? AND `user`=? AND `store`=? | |
| 85 ]]; | |
| 86 engine:delete(delete_sql, host, user or "", store); | |
| 87 | |
| 88 local insert_sql = [[ | |
| 89 INSERT INTO `prosody` | |
| 90 (`host`,`user`,`store`,`key`,`type`,`value`) | |
| 91 VALUES (?,?,?,?,?,?); | |
| 92 ]] | |
| 79 if data and next(data) ~= nil then | 93 if data and next(data) ~= nil then |
| 80 local extradata = {}; | 94 local extradata = {}; |
| 81 for key, value in pairs(data) do | 95 for key, value in pairs(data) do |
| 82 if type(key) == "string" and key ~= "" then | 96 if type(key) == "string" and key ~= "" then |
| 83 local t, encoded_value = assert(serialize(value)); | 97 local t, encoded_value = assert(serialize(value)); |
| 84 engine:insert("INSERT INTO `prosody` (`host`,`user`,`store`,`key`,`type`,`value`) VALUES (?,?,?,?,?,?)", host, user or "", store, key, t, encoded_value); | 98 engine:insert(delete_sql, host, user or "", store, key, t, encoded_value); |
| 85 else | 99 else |
| 86 extradata[key] = value; | 100 extradata[key] = value; |
| 87 end | 101 end |
| 88 end | 102 end |
| 89 if next(extradata) ~= nil then | 103 if next(extradata) ~= nil then |
| 90 local t, encoded_extradata = assert(serialize(extradata)); | 104 local t, encoded_extradata = assert(serialize(extradata)); |
| 91 engine:insert("INSERT INTO `prosody` (`host`,`user`,`store`,`key`,`type`,`value`) VALUES (?,?,?,?,?,?)", host, user or "", store, "", t, encoded_extradata); | 105 engine:insert(insert_sql, host, user or "", store, "", t, encoded_extradata); |
| 92 end | 106 end |
| 93 end | 107 end |
| 94 return true; | 108 return true; |
| 95 end | 109 end |
| 96 | 110 |
| 113 return keyval_store_set(data); | 127 return keyval_store_set(data); |
| 114 end); | 128 end); |
| 115 end | 129 end |
| 116 function keyval_store:users() | 130 function keyval_store:users() |
| 117 local ok, result = engine:transaction(function() | 131 local ok, result = engine:transaction(function() |
| 118 return engine:select("SELECT DISTINCT `user` FROM `prosody` WHERE `host`=? AND `store`=?", host, self.store); | 132 local select_sql = [[ |
| 133 SELECT DISTINCT `user` | |
| 134 FROM `prosody` | |
| 135 WHERE `host`=? AND `store`=?; | |
| 136 ]]; | |
| 137 return engine:select(select_sql, host, self.store); | |
| 119 end); | 138 end); |
| 120 if not ok then return ok, result end | 139 if not ok then return ok, result end |
| 121 return iterator(result); | 140 return iterator(result); |
| 122 end | 141 end |
| 123 | 142 |
| 127 local map_store = {}; | 146 local map_store = {}; |
| 128 map_store.__index = map_store; | 147 map_store.__index = map_store; |
| 129 map_store.remove = {}; | 148 map_store.remove = {}; |
| 130 function map_store:get(username, key) | 149 function map_store:get(username, key) |
| 131 local ok, result = engine:transaction(function() | 150 local ok, result = engine:transaction(function() |
| 151 local query = [[ | |
| 152 SELECT `type`, `value` | |
| 153 FROM `prosody` | |
| 154 WHERE `host`=? AND `user`=? AND `store`=? AND `key`=? | |
| 155 LIMIT 1 | |
| 156 ]]; | |
| 132 local data; | 157 local data; |
| 133 if type(key) == "string" and key ~= "" then | 158 if type(key) == "string" and key ~= "" then |
| 134 for row in engine:select("SELECT `type`, `value` FROM `prosody` WHERE `host`=? AND `user`=? AND `store`=? AND `key`=? LIMIT 1", host, username or "", self.store, key) do | 159 for row in engine:select(query, host, username or "", self.store, key) do |
| 135 data = deserialize(row[1], row[2]); | 160 data = deserialize(row[1], row[2]); |
| 136 end | 161 end |
| 137 return data; | 162 return data; |
| 138 else | 163 else |
| 139 for row in engine:select("SELECT `type`, `value` FROM `prosody` WHERE `host`=? AND `user`=? AND `store`=? AND `key`=? LIMIT 1", host, username or "", self.store, "") do | 164 for row in engine:select(query, host, username or "", self.store, "") do |
| 140 data = deserialize(row[1], row[2]); | 165 data = deserialize(row[1], row[2]); |
| 141 end | 166 end |
| 142 return data and data[key] or nil; | 167 return data and data[key] or nil; |
| 143 end | 168 end |
| 144 end); | 169 end); |
| 149 if data == nil then data = self.remove; end | 174 if data == nil then data = self.remove; end |
| 150 return self:set_keys(username, { [key] = data }); | 175 return self:set_keys(username, { [key] = data }); |
| 151 end | 176 end |
| 152 function map_store:set_keys(username, keydatas) | 177 function map_store:set_keys(username, keydatas) |
| 153 local ok, result = engine:transaction(function() | 178 local ok, result = engine:transaction(function() |
| 179 local delete_sql = [[ | |
| 180 DELETE FROM `prosody` | |
| 181 WHERE `host`=? AND `user`=? AND `store`=? AND `key`=?; | |
| 182 ]]; | |
| 183 local insert_sql = [[ | |
| 184 INSERT INTO `prosody` | |
| 185 (`host`,`user`,`store`,`key`,`type`,`value`) | |
| 186 VALUES (?,?,?,?,?,?); | |
| 187 ]]; | |
| 188 local select_extradata_sql = [[ | |
| 189 SELECT `type`, `value` | |
| 190 FROM `prosody` | |
| 191 WHERE `host`=? AND `user`=? AND `store`=? AND `key`=? | |
| 192 LIMIT 1; | |
| 193 ]]; | |
| 154 for key, data in pairs(keydatas) do | 194 for key, data in pairs(keydatas) do |
| 155 if type(key) == "string" and key ~= "" then | 195 if type(key) == "string" and key ~= "" then |
| 156 engine:delete("DELETE FROM `prosody` WHERE `host`=? AND `user`=? AND `store`=? AND `key`=?", | 196 engine:delete(delete_sql, |
| 157 host, username or "", self.store, key); | 197 host, username or "", self.store, key); |
| 158 if data ~= self.remove then | 198 if data ~= self.remove then |
| 159 local t, value = assert(serialize(data)); | 199 local t, value = assert(serialize(data)); |
| 160 engine:insert("INSERT INTO `prosody` (`host`,`user`,`store`,`key`,`type`,`value`) VALUES (?,?,?,?,?,?)", host, username or "", self.store, key, t, value); | 200 engine:insert(insert_sql, host, username or "", self.store, key, t, value); |
| 161 end | 201 end |
| 162 else | 202 else |
| 163 local extradata = {}; | 203 local extradata = {}; |
| 164 for row in engine:select("SELECT `type`, `value` FROM `prosody` WHERE `host`=? AND `user`=? AND `store`=? AND `key`=? LIMIT 1", host, username or "", self.store, "") do | 204 for row in engine:select(select_extradata_sql, host, username or "", self.store, "") do |
| 165 extradata = deserialize(row[1], row[2]); | 205 extradata = deserialize(row[1], row[2]); |
| 166 end | 206 end |
| 167 engine:delete("DELETE FROM `prosody` WHERE `host`=? AND `user`=? AND `store`=? AND `key`=?", | 207 engine:delete(delete_sql, host, username or "", self.store, ""); |
| 168 host, username or "", self.store, ""); | |
| 169 extradata[key] = data; | 208 extradata[key] = data; |
| 170 local t, value = assert(serialize(extradata)); | 209 local t, value = assert(serialize(extradata)); |
| 171 engine:insert("INSERT INTO `prosody` (`host`,`user`,`store`,`key`,`type`,`value`) VALUES (?,?,?,?,?,?)", host, username or "", self.store, "", t, value); | 210 engine:insert(insert_sql, host, username or "", self.store, "", t, value); |
| 172 end | 211 end |
| 173 end | 212 end |
| 174 return true; | 213 return true; |
| 175 end); | 214 end); |
| 176 if not ok then return nil, result; end | 215 if not ok then return nil, result; end |
| 185 function archive_store:append(username, key, value, when, with) | 224 function archive_store:append(username, key, value, when, with) |
| 186 local user,store = username,self.store; | 225 local user,store = username,self.store; |
| 187 when = when or os.time(); | 226 when = when or os.time(); |
| 188 with = with or ""; | 227 with = with or ""; |
| 189 local ok, ret = engine:transaction(function() | 228 local ok, ret = engine:transaction(function() |
| 229 local delete_sql = [[ | |
| 230 DELETE FROM `prosodyarchive` | |
| 231 WHERE `host`=? AND `user`=? AND `store`=? AND `key`=?; | |
| 232 ]]; | |
| 233 local insert_sql = [[ | |
| 234 INSERT INTO `prosodyarchive` | |
| 235 (`host`, `user`, `store`, `when`, `with`, `key`, `type`, `value`) | |
| 236 VALUES (?,?,?,?,?,?,?,?); | |
| 237 ]]; | |
| 190 if key then | 238 if key then |
| 191 engine:delete("DELETE FROM `prosodyarchive` WHERE `host`=? AND `user`=? AND `store`=? AND `key`=?", host, user or "", store, key); | 239 engine:delete(delete_sql, host, user or "", store, key); |
| 192 else | 240 else |
| 193 key = uuid.generate(); | 241 key = uuid.generate(); |
| 194 end | 242 end |
| 195 local t, encoded_value = assert(serialize(value)); | 243 local t, encoded_value = assert(serialize(value)); |
| 196 engine:insert(insert_sql, host, user or "", store, when, with, key, t, encoded_value); | 244 engine:insert(insert_sql, host, user or "", store, when, with, key, t, encoded_value); |
| 231 end | 279 end |
| 232 local function archive_where_id_range(query, args, where) | 280 local function archive_where_id_range(query, args, where) |
| 233 local args_len = #args | 281 local args_len = #args |
| 234 -- Before or after specific item, exclusive | 282 -- Before or after specific item, exclusive |
| 235 if query.after then -- keys better be unique! | 283 if query.after then -- keys better be unique! |
| 236 where[#where+1] = "`sort_id` > COALESCE((SELECT `sort_id` FROM `prosodyarchive` WHERE `key` = ? AND `host` = ? AND `user` = ? AND `store` = ? LIMIT 1), 0)" | 284 where[#where+1] = [[ |
| 285 `sort_id` > COALESCE( | |
| 286 ( | |
| 287 SELECT `sort_id` | |
| 288 FROM `prosodyarchive` | |
| 289 WHERE `key` = ? AND `host` = ? AND `user` = ? AND `store` = ? | |
| 290 LIMIT 1 | |
| 291 ), 0) | |
| 292 ]]; | |
| 237 args[args_len+1], args[args_len+2], args[args_len+3], args[args_len+4] = query.after, args[1], args[2], args[3]; | 293 args[args_len+1], args[args_len+2], args[args_len+3], args[args_len+4] = query.after, args[1], args[2], args[3]; |
| 238 args_len = args_len + 4 | 294 args_len = args_len + 4 |
| 239 end | 295 end |
| 240 if query.before then | 296 if query.before then |
| 241 where[#where+1] = "`sort_id` < COALESCE((SELECT `sort_id` FROM `prosodyarchive` WHERE `key` = ? AND `host` = ? AND `user` = ? AND `store` = ? LIMIT 1), (SELECT MAX(`sort_id`)+1 FROM `prosodyarchive`))" | 297 where[#where+1] = [[ |
| 298 `sort_id` < COALESCE( | |
| 299 ( | |
| 300 SELECT `sort_id` | |
| 301 FROM `prosodyarchive` | |
| 302 WHERE `key` = ? AND `host` = ? AND `user` = ? AND `store` = ? | |
| 303 LIMIT 1 | |
| 304 ), | |
| 305 ( | |
| 306 SELECT MAX(`sort_id`)+1 | |
| 307 FROM `prosodyarchive` | |
| 308 ) | |
| 309 ) | |
| 310 ]] | |
| 242 args[args_len+1], args[args_len+2], args[args_len+3], args[args_len+4] = query.before, args[1], args[2], args[3]; | 311 args[args_len+1], args[args_len+2], args[args_len+3], args[args_len+4] = query.before, args[1], args[2], args[3]; |
| 243 end | 312 end |
| 244 end | 313 end |
| 245 | 314 |
| 246 function archive_store:find(username, query) | 315 function archive_store:find(username, query) |
| 247 query = query or {}; | 316 query = query or {}; |
| 248 local user,store = username,self.store; | 317 local user,store = username,self.store; |
| 249 local total; | 318 local total; |
| 250 local ok, result = engine:transaction(function() | 319 local ok, result = engine:transaction(function() |
| 251 local sql_query = "SELECT `key`, `type`, `value`, `when`, `with` FROM `prosodyarchive` WHERE %s ORDER BY `sort_id` %s%s;"; | 320 local sql_query = [[ |
| 321 SELECT `key`, `type`, `value`, `when`, `with` | |
| 322 FROM `prosodyarchive` | |
| 323 WHERE %s | |
| 324 ORDER BY `sort_id` %s%s; | |
| 325 ]]; | |
| 252 local args = { host, user or "", store, }; | 326 local args = { host, user or "", store, }; |
| 253 local where = { "`host` = ?", "`user` = ?", "`store` = ?", }; | 327 local where = { "`host` = ?", "`user` = ?", "`store` = ?", }; |
| 254 | 328 |
| 255 archive_where(query, args, where); | 329 archive_where(query, args, where); |
| 256 | 330 |
| 257 -- Total matching | 331 -- Total matching |
| 258 if query.total then | 332 if query.total then |
| 259 local stats = engine:select("SELECT COUNT(*) FROM `prosodyarchive` WHERE " .. t_concat(where, " AND "), unpack(args)); | 333 local stats = engine:select("SELECT COUNT(*) FROM `prosodyarchive` WHERE " |
| 334 .. t_concat(where, " AND "), unpack(args)); | |
| 260 if stats then | 335 if stats then |
| 261 for row in stats do | 336 for row in stats do |
| 262 total = row[1]; | 337 total = row[1]; |
| 263 end | 338 end |
| 264 end | 339 end |
| 271 | 346 |
| 272 if query.limit then | 347 if query.limit then |
| 273 args[#args+1] = query.limit; | 348 args[#args+1] = query.limit; |
| 274 end | 349 end |
| 275 | 350 |
| 276 sql_query = sql_query:format(t_concat(where, " AND "), query.reverse and "DESC" or "ASC", query.limit and " LIMIT ?" or ""); | 351 sql_query = sql_query:format(t_concat(where, " AND "), query.reverse |
| 352 and "DESC" or "ASC", query.limit and " LIMIT ?" or ""); | |
| 277 return engine:select(sql_query, unpack(args)); | 353 return engine:select(sql_query, unpack(args)); |
| 278 end); | 354 end); |
| 279 if not ok then return ok, result end | 355 if not ok then return ok, result end |
| 280 return function() | 356 return function() |
| 281 local row = result(); | 357 local row = result(); |
| 403 err or "unknown error"); | 479 err or "unknown error"); |
| 404 return false; | 480 return false; |
| 405 end | 481 end |
| 406 | 482 |
| 407 -- COMPAT w/pre-0.10: Upgrade table to UTF-8 if not already | 483 -- COMPAT w/pre-0.10: Upgrade table to UTF-8 if not already |
| 408 local check_encoding_query = "SELECT `COLUMN_NAME`,`COLUMN_TYPE`,`TABLE_NAME` FROM `information_schema`.`columns` WHERE `TABLE_NAME` LIKE 'prosody%%' AND ( `CHARACTER_SET_NAME`!='%s' OR `COLLATION_NAME`!='%s_bin' );"; | 484 local check_encoding_query = [[ |
| 485 SELECT `COLUMN_NAME`,`COLUMN_TYPE`,`TABLE_NAME` | |
| 486 FROM `information_schema`.`columns` | |
| 487 WHERE `TABLE_NAME` LIKE 'prosody%%' AND ( `CHARACTER_SET_NAME`!='%s' OR `COLLATION_NAME`!='%s_bin' ); | |
| 488 ]]; | |
| 409 check_encoding_query = check_encoding_query:format(engine.charset, engine.charset); | 489 check_encoding_query = check_encoding_query:format(engine.charset, engine.charset); |
| 410 success,err = engine:transaction(function() | 490 success,err = engine:transaction(function() |
| 411 local result = engine:execute(check_encoding_query); | 491 local result = engine:execute(check_encoding_query); |
| 412 local n_bad_columns = result:rowcount(); | 492 local n_bad_columns = result:rowcount(); |
| 413 if n_bad_columns > 0 then | 493 if n_bad_columns > 0 then |