comparison plugins/mod_storage_sql2.lua @ 5897:296e32a1ff33

Merge 0.10 -> trunk
author Kim Alvefur <zash@zash.se>
date Thu, 31 Oct 2013 20:49:03 +0100
parents 9e47ece9457c
children 0e0aab930e10
comparison
equal deleted inserted replaced
5880:11f14d44438e 5897:296e32a1ff33
25 25
26 local engine; -- TODO create engine 26 local engine; -- TODO create engine
27 27
28 local function create_table() 28 local function create_table()
29 local Table,Column,Index = mod_sql.Table,mod_sql.Column,mod_sql.Index; 29 local Table,Column,Index = mod_sql.Table,mod_sql.Column,mod_sql.Index;
30 --[[ 30
31 local ProsodyTable = Table { 31 local ProsodyTable = Table {
32 name="prosody"; 32 name="prosody";
33 Column { name="host", type="TEXT", nullable=false }; 33 Column { name="host", type="TEXT", nullable=false };
34 Column { name="user", type="TEXT", nullable=false }; 34 Column { name="user", type="TEXT", nullable=false };
35 Column { name="store", type="TEXT", nullable=false }; 35 Column { name="store", type="TEXT", nullable=false };
36 Column { name="key", type="TEXT", nullable=false }; 36 Column { name="key", type="TEXT", nullable=false };
37 Column { name="type", type="TEXT", nullable=false }; 37 Column { name="type", type="TEXT", nullable=false };
38 Column { name="value", type="TEXT", nullable=false }; 38 Column { name="value", type="MEDIUMTEXT", nullable=false };
39 Index { name="prosody_index", "host", "user", "store", "key" }; 39 Index { name="prosody_index", "host", "user", "store", "key" };
40 }; 40 };
41 engine:transaction(function() 41 engine:transaction(function()
42 ProsodyTable:create(engine); 42 ProsodyTable:create(engine);
43 end);]] 43 end);
44 if not module:get_option("sql_manage_tables", true) then 44
45 return;
46 end
47
48 local create_sql = "CREATE TABLE `prosody` (`host` TEXT, `user` TEXT, `store` TEXT, `key` TEXT, `type` TEXT, `value` TEXT);";
49 if params.driver == "PostgreSQL" then
50 create_sql = create_sql:gsub("`", "\"");
51 elseif params.driver == "MySQL" then
52 create_sql = create_sql:gsub("`value` TEXT", "`value` MEDIUMTEXT")
53 :gsub(";$", " CHARACTER SET 'utf8' COLLATE 'utf8_bin';");
54 end
55
56 local index_sql = "CREATE INDEX `prosody_index` ON `prosody` (`host`, `user`, `store`, `key`)";
57 if params.driver == "PostgreSQL" then
58 index_sql = index_sql:gsub("`", "\"");
59 elseif params.driver == "MySQL" then
60 index_sql = index_sql:gsub("`([,)])", "`(20)%1");
61 end
62
63 local success,err = engine:transaction(function()
64 engine:execute(create_sql);
65 engine:execute(index_sql);
66 end);
67 if not success then -- so we failed to create
68 if params.driver == "MySQL" then
69 success,err = engine:transaction(function()
70 local result = engine:execute("SHOW COLUMNS FROM prosody WHERE Field='value' and Type='text'");
71 if result:rowcount() > 0 then
72 module:log("info", "Upgrading database schema...");
73 engine:execute("ALTER TABLE prosody MODIFY COLUMN `value` MEDIUMTEXT");
74 module:log("info", "Database table automatically upgraded");
75 end
76 return true;
77 end);
78 if not success then
79 module:log("error", "Failed to check/upgrade database schema (%s), please see "
80 .."http://prosody.im/doc/mysql for help",
81 err or "unknown error");
82 end
83 end
84 end
85 local ProsodyArchiveTable = Table { 45 local ProsodyArchiveTable = Table {
86 name="prosodyarchive"; 46 name="prosodyarchive";
87 Column { name="sort_id", type="INTEGER PRIMARY KEY AUTOINCREMENT", nullable=false }; 47 Column { name="sort_id", type="INTEGER", primary_key=true, auto_increment=true, nullable=false };
88 Column { name="host", type="TEXT", nullable=false }; 48 Column { name="host", type="TEXT", nullable=false };
89 Column { name="user", type="TEXT", nullable=false }; 49 Column { name="user", type="TEXT", nullable=false };
90 Column { name="store", type="TEXT", nullable=false }; 50 Column { name="store", type="TEXT", nullable=false };
91 Column { name="key", type="TEXT", nullable=false }; -- item id 51 Column { name="key", type="TEXT", nullable=false }; -- item id
92 Column { name="when", type="INTEGER", nullable=false }; -- timestamp 52 Column { name="when", type="INTEGER", nullable=false }; -- timestamp
93 Column { name="with", type="TEXT", nullable=false }; -- related id 53 Column { name="with", type="TEXT", nullable=false }; -- related id
94 Column { name="type", type="TEXT", nullable=false }; 54 Column { name="type", type="TEXT", nullable=false };
95 Column { name="value", type=params.driver == "MySQL" and "MEDIUMTEXT" or "TEXT", nullable=false }; 55 Column { name="value", type="MEDIUMTEXT", nullable=false };
96 Index { name="prosodyarchive_index", "host", "user", "store", "key" }; 56 Index { name="prosodyarchive_index", unique = true, "host", "user", "store", "key" };
97 }; 57 };
98 engine:transaction(function() 58 engine:transaction(function()
99 ProsodyArchiveTable:create(engine); 59 ProsodyArchiveTable:create(engine);
100 end); 60 end);
101 end 61 end
102 local function set_encoding() 62
103 if params.driver == "SQLite3" then return end 63 local function upgrade_table()
104 local set_names_query = "SET NAMES 'utf8';";
105 if params.driver == "MySQL" then 64 if params.driver == "MySQL" then
106 set_names_query = set_names_query:gsub(";$", " COLLATE 'utf8_bin';"); 65 local success,err = engine:transaction(function()
107 end 66 local result = engine:execute("SHOW COLUMNS FROM prosody WHERE Field='value' and Type='text'");
108 local success,err = engine:transaction(function() return engine:execute(set_names_query); end); 67 if result:rowcount() > 0 then
109 if not success then 68 module:log("info", "Upgrading database schema...");
110 module:log("error", "Failed to set database connection encoding to UTF8: %s", err); 69 engine:execute("ALTER TABLE prosody MODIFY COLUMN `value` MEDIUMTEXT");
111 return; 70 module:log("info", "Database table automatically upgraded");
112 end 71 end
113 if params.driver == "MySQL" then 72 return true;
73 end);
74 if not success then
75 module:log("error", "Failed to check/upgrade database schema (%s), please see "
76 .."http://prosody.im/doc/mysql for help",
77 err or "unknown error");
78 return false;
79 end
114 -- COMPAT w/pre-0.9: Upgrade tables to UTF-8 if not already 80 -- COMPAT w/pre-0.9: Upgrade tables to UTF-8 if not already
115 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' );"; 81 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' );";
116 local success,err = engine:transaction(function() 82 success,err = engine:transaction(function()
117 local result = engine:execute(check_encoding_query); 83 local result = engine:execute(check_encoding_query);
118 local n_bad_columns = result:rowcount(); 84 local n_bad_columns = result:rowcount();
119 if n_bad_columns > 0 then 85 if n_bad_columns > 0 then
120 module:log("warn", "Found %d columns in prosody table requiring encoding change, updating now...", n_bad_columns); 86 module:log("warn", "Found %d columns in prosody table requiring encoding change, updating now...", n_bad_columns);
121 local fix_column_query1 = "ALTER TABLE `prosody` CHANGE `%s` `%s` BLOB;"; 87 local fix_column_query1 = "ALTER TABLE `prosody` CHANGE `%s` `%s` BLOB;";
126 engine:execute(fix_column_query2:format(column_name, column_name, column_type)); 92 engine:execute(fix_column_query2:format(column_name, column_name, column_type));
127 end 93 end
128 module:log("info", "Database encoding upgrade complete!"); 94 module:log("info", "Database encoding upgrade complete!");
129 end 95 end
130 end); 96 end);
131 local success,err = engine:transaction(function() return engine:execute(check_encoding_query); end); 97 success,err = engine:transaction(function() return engine:execute(check_encoding_query); end);
132 if not success then 98 if not success then
133 module:log("error", "Failed to check/upgrade database encoding: %s", err or "unknown error"); 99 module:log("error", "Failed to check/upgrade database encoding: %s", err or "unknown error");
134 end 100 end
135 end 101 end
136 end 102 end
145 assert(params.driver and params.database, "Both the SQL driver and the database need to be specified"); 111 assert(params.driver and params.database, "Both the SQL driver and the database need to be specified");
146 112
147 --local dburi = db2uri(params); 113 --local dburi = db2uri(params);
148 engine = mod_sql:create_engine(params); 114 engine = mod_sql:create_engine(params);
149 115
150 -- Encoding mess 116 engine:set_encoding();
151 set_encoding(); 117
152 118 if module:get_option("sql_manage_tables", true) then
153 -- Automatically create table, ignore failure (table probably already exists) 119 -- Automatically create table, ignore failure (table probably already exists)
154 create_table(); 120 create_table();
121 -- Encoding mess
122 upgrade_table();
123 end
155 end 124 end
156 125
157 local function serialize(value) 126 local function serialize(value)
158 local t = type(value); 127 local t = type(value);
159 if t == "string" or t == "boolean" or t == "number" then 128 if t == "string" or t == "boolean" or t == "number" then