Comparison

plugins/mod_storage_sql2.lua @ 6767:d01c29b62b16

Merge 0.10->trunk
author Matthew Wild <mwild1@gmail.com>
date Thu, 09 Jul 2015 00:14:27 +0100
parent 6749:9dc05d3efdc9
parent 6761:b20efae224c9
comparison
equal deleted inserted replaced
6749:9dc05d3efdc9 6767:d01c29b62b16
11 local function is_stanza(x) return getmetatable(x) == stanza_mt; end 11 local function is_stanza(x) return getmetatable(x) == stanza_mt; end
12 12
13 local noop = function() end 13 local noop = function() end
14 local unpack = unpack 14 local unpack = unpack
15 local function iterator(result) 15 local function iterator(result)
16 return function(result) 16 return function(result_)
17 local row = result(); 17 local row = result_();
18 if row ~= nil then 18 if row ~= nil then
19 return unpack(row); 19 return unpack(row);
20 end 20 end
21 end, result, nil; 21 end, result, nil;
22 end 22 end
383 err or "unknown error"); 383 err or "unknown error");
384 return false; 384 return false;
385 end 385 end
386 386
387 -- COMPAT w/pre-0.10: Upgrade table to UTF-8 if not already 387 -- COMPAT w/pre-0.10: Upgrade table to UTF-8 if not already
388 local check_encoding_query = "SELECT `COLUMN_NAME`,`COLUMN_TYPE` FROM `information_schema`.`columns` WHERE `TABLE_NAME`='prosody' AND ( `CHARACTER_SET_NAME`!='utf8' OR `COLLATION_NAME`!='utf8_bin' );"; 388 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' );";
389 check_encoding_query = check_encoding_query:format(engine.charset, engine.charset);
389 success,err = engine:transaction(function() 390 success,err = engine:transaction(function()
390 local result = engine:execute(check_encoding_query); 391 local result = engine:execute(check_encoding_query);
391 local n_bad_columns = result:rowcount(); 392 local n_bad_columns = result:rowcount();
392 if n_bad_columns > 0 then 393 if n_bad_columns > 0 then
393 changes = true; 394 changes = true;
394 if apply_changes then 395 if apply_changes then
395 module:log("warn", "Found %d columns in prosody table requiring encoding change, updating now...", n_bad_columns); 396 module:log("warn", "Found %d columns in prosody table requiring encoding change, updating now...", n_bad_columns);
396 local fix_column_query1 = "ALTER TABLE `prosody` CHANGE `%s` `%s` BLOB;"; 397 local fix_column_query1 = "ALTER TABLE `%s` CHANGE `%s` `%s` BLOB;";
397 local fix_column_query2 = "ALTER TABLE `prosody` CHANGE `%s` `%s` %s CHARACTER SET 'utf8' COLLATE 'utf8_bin';"; 398 local fix_column_query2 = "ALTER TABLE `%s` CHANGE `%s` `%s` %s CHARACTER SET '%s' COLLATE '%s_bin';";
398 for row in result:rows() do 399 for row in result:rows() do
399 local column_name, column_type = unpack(row); 400 local column_name, column_type, table_name = unpack(row);
400 engine:execute(fix_column_query1:format(column_name, column_name)); 401 module:log("debug", "Fixing column %s in table %s", column_name, table_name);
401 engine:execute(fix_column_query2:format(column_name, column_name, column_type)); 402 engine:execute(fix_column_query1:format(table_name, column_name, column_name));
403 engine:execute(fix_column_query2:format(table_name, column_name, column_name, column_type, engine.charset, engine.charset));
402 end 404 end
403 module:log("info", "Database encoding upgrade complete!"); 405 module:log("info", "Database encoding upgrade complete!");
404 end 406 end
405 end 407 end
406 end); 408 end);
408 if not success then 410 if not success then
409 module:log("error", "Failed to check/upgrade database encoding: %s", err or "unknown error"); 411 module:log("error", "Failed to check/upgrade database encoding: %s", err or "unknown error");
410 return false; 412 return false;
411 end 413 end
412 end 414 end
415 return changes;
413 end 416 end
414 417
415 local function normalize_params(params) 418 local function normalize_params(params)
416 if params.driver == "SQLite3" then 419 if params.driver == "SQLite3" then
417 params.database = resolve_relative_path(prosody.paths.data or ".", params.database or "prosody.sqlite"); 420 params.database = resolve_relative_path(prosody.paths.data or ".", params.database or "prosody.sqlite");
427 if module:get_option("sql_manage_tables", true) then 430 if module:get_option("sql_manage_tables", true) then
428 -- Automatically create table, ignore failure (table probably already exists) 431 -- Automatically create table, ignore failure (table probably already exists)
429 -- FIXME: we should check in information_schema, etc. 432 -- FIXME: we should check in information_schema, etc.
430 create_table(); 433 create_table();
431 -- Check whether the table needs upgrading 434 -- Check whether the table needs upgrading
432 if not upgrade_table(params, true) then 435 if upgrade_table(params, false) then
433 module:log("error", "Old database format detected, and upgrade failed"); 436 module:log("error", "Old database format detected. Please run: prosodyctl mod_%s upgrade", module.name);
434 return false, "database upgrade needed"; 437 return false, "database upgrade needed";
435 end 438 end
436 end 439 end
437 end); 440 end);
438 441
439 module:provides("storage", driver); 442 module:provides("storage", driver);
440 end 443 end
444
445 function module.command(arg)
446 local config = require "core.configmanager";
447 local prosodyctl = require "util.prosodyctl";
448 local command = table.remove(arg, 1);
449 if command == "upgrade" then
450 -- We need to find every unique dburi in the config
451 local uris = {};
452 for host in pairs(prosody.hosts) do
453 local params = config.get(host, "sql") or default_params;
454 uris[sql.db2uri(params)] = params;
455 end
456 print("We will check and upgrade the following databases:\n");
457 for _, params in pairs(uris) do
458 print("", "["..params.driver.."] "..params.database..(params.host and " on "..params.host or ""));
459 end
460 print("");
461 print("Ensure you have working backups of the above databases before continuing! ");
462 if not prosodyctl.show_yesno("Continue with the database upgrade? [yN]") then
463 print("Ok, no upgrade. But you do have backups, don't you? ...don't you?? :-)");
464 return;
465 end
466 -- Upgrade each one
467 for _, params in pairs(uris) do
468 print("Checking "..params.database.."...");
469 engine = sql:create_engine(params);
470 upgrade_table(params, true);
471 end
472 print("All done!");
473 else
474 print("Unknown command: "..command);
475 end
476 end