plugins/mod_storage_sql.lua
author Matthew Wild <mwild1@gmail.com>
Sat, 11 Jun 2011 02:15:38 +0100
changeset 4317 5b0fcc5cdd4d
parent 4309 7ad81d81f5ec
child 4318 44b131d7041b
permissions -rw-r--r--
mod_storage_sql: Add sql_manage_tables to disable table creation/updating.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     1
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     2
--[[
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     3
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     4
DB Tables:
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     5
	Prosody - key-value, map
4045
054e05b27611 mod_storage_sql: Remove the subkey column from the Prosody table, and make the map store compatible with the key-value store.
Waqas Hussain <waqas20@gmail.com>
parents: 4044
diff changeset
     6
		| host | user | store | key | type | value |
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     7
	ProsodyArchive - list
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     8
		| host | user | store | key | time | stanzatype | jsonvalue |
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     9
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    10
Mapping:
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    11
	Roster - Prosody
4045
054e05b27611 mod_storage_sql: Remove the subkey column from the Prosody table, and make the map store compatible with the key-value store.
Waqas Hussain <waqas20@gmail.com>
parents: 4044
diff changeset
    12
		| host | user | "roster" | "contactjid" | type | value |
054e05b27611 mod_storage_sql: Remove the subkey column from the Prosody table, and make the map store compatible with the key-value store.
Waqas Hussain <waqas20@gmail.com>
parents: 4044
diff changeset
    13
		| host | user | "roster" | NULL | "json" | roster[false] data |
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    14
	Account - Prosody
4045
054e05b27611 mod_storage_sql: Remove the subkey column from the Prosody table, and make the map store compatible with the key-value store.
Waqas Hussain <waqas20@gmail.com>
parents: 4044
diff changeset
    15
		| host | user | "accounts" | "username" | type | value |
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    16
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    17
	Offline - ProsodyArchive
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    18
		| host | user | "offline" | "contactjid" | time | "message" | json|XML |
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    19
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    20
]]
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    21
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    22
local type = type;
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    23
local tostring = tostring;
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    24
local tonumber = tonumber;
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    25
local pairs = pairs;
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    26
local next = next;
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    27
local setmetatable = setmetatable;
4073
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
    28
local xpcall = xpcall;
4048
c64b0aefb922 mod_storage_sql: Use util.json instead of util.serialization.
Waqas Hussain <waqas20@gmail.com>
parents: 4046
diff changeset
    29
local json = require "util.json";
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    30
4105
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    31
local DBI;
4070
c11f1cc2c79d mod_storage_sql: Removed unnecessary initialization of a variable.
Waqas Hussain <waqas20@gmail.com>
parents: 4048
diff changeset
    32
local connection;
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    33
local host,user,store = module.host;
4044
61ae809da8ee mod_storage_sql: Dynamically replace backquotes with double quotes when connecting to PostgreSQL...
Waqas Hussain <waqas20@gmail.com>
parents: 4043
diff changeset
    34
local params = module:get_option("sql");
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    35
4096
3b991ceb228e mod_storage_sql: Make the 'database' value for the SQLite3 driver relative to the data path
Matthew Wild <mwild1@gmail.com>
parents: 4073
diff changeset
    36
local resolve_relative_path = require "core.configmanager".resolve_relative_path;
3b991ceb228e mod_storage_sql: Make the 'database' value for the SQLite3 driver relative to the data path
Matthew Wild <mwild1@gmail.com>
parents: 4073
diff changeset
    37
4105
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    38
local function test_connection()
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    39
	if not connection then return nil; end
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    40
	if connection:ping() then
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    41
		return true;
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    42
	else
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    43
		module:log("debug", "Database connection closed");
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    44
		connection = nil;
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    45
	end
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    46
end
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    47
local function connect()
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    48
	if not test_connection() then
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    49
		prosody.unlock_globals();
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    50
		local dbh, err = DBI.Connect(
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    51
			params.driver, params.database,
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    52
			params.username, params.password,
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    53
			params.host, params.port
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    54
		);
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    55
		prosody.lock_globals();
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    56
		if not dbh then
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    57
			module:log("debug", "Database connection failed: %s", tostring(err));
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    58
			return nil, err;
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    59
		end
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    60
		module:log("debug", "Successfully connected to database");
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    61
		dbh:autocommit(false); -- don't commit automatically
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    62
		connection = dbh;
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    63
		return connection;
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    64
	end
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    65
end
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
    66
4109
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    67
local function create_table()
4317
5b0fcc5cdd4d mod_storage_sql: Add sql_manage_tables to disable table creation/updating.
Matthew Wild <mwild1@gmail.com>
parents: 4309
diff changeset
    68
	if not module:get_option("sql_manage_tables", true) then
5b0fcc5cdd4d mod_storage_sql: Add sql_manage_tables to disable table creation/updating.
Matthew Wild <mwild1@gmail.com>
parents: 4309
diff changeset
    69
		return;
5b0fcc5cdd4d mod_storage_sql: Add sql_manage_tables to disable table creation/updating.
Matthew Wild <mwild1@gmail.com>
parents: 4309
diff changeset
    70
	end
4109
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    71
	local create_sql = "CREATE TABLE `prosody` (`host` TEXT, `user` TEXT, `store` TEXT, `key` TEXT, `type` TEXT, `value` TEXT);";
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    72
	if params.driver == "PostgreSQL" then
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    73
		create_sql = create_sql:gsub("`", "\"");
4285
c806a599224a mod_storage_sql: Switch to MEDIUMTEXT for the 'value' column when using MySQL, as it imposes a 64K limit otherwise, potentially truncating data. Automatically upgrades existing tables.
Matthew Wild <mwild1@gmail.com>
parents: 4218
diff changeset
    74
	elseif params.driver == "MySQL" then
c806a599224a mod_storage_sql: Switch to MEDIUMTEXT for the 'value' column when using MySQL, as it imposes a 64K limit otherwise, potentially truncating data. Automatically upgrades existing tables.
Matthew Wild <mwild1@gmail.com>
parents: 4218
diff changeset
    75
		create_sql = create_sql:gsub("`value` TEXT", "`value` MEDIUMTEXT");
4109
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    76
	end
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    77
	
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    78
	local stmt = connection:prepare(create_sql);
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    79
	if stmt then
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    80
		local ok = stmt:execute();
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    81
		local commit_ok = connection:commit();
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    82
		if ok and commit_ok then
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    83
			module:log("info", "Initialized new %s database with prosody table", params.driver);
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    84
			local index_sql = "CREATE INDEX `prosody_index` ON `prosody` (`host`, `user`, `store`, `key`)";
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    85
			if params.driver == "PostgreSQL" then
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    86
				index_sql = index_sql:gsub("`", "\"");
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    87
			elseif params.driver == "MySQL" then
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    88
				index_sql = index_sql:gsub("`([,)])", "`(20)%1");
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    89
			end
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    90
			local stmt, err = connection:prepare(index_sql);
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    91
			local ok, commit_ok, commit_err;
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    92
			if stmt then
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    93
				ok, err = stmt:execute();
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    94
				commit_ok, commit_err = connection:commit();
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    95
			end
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    96
			if not(ok and commit_ok) then
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    97
				module:log("warn", "Failed to create index (%s), lookups may not be optimised", err or commit_err);
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
    98
			end
4309
7ad81d81f5ec mod_storage_sql: Fix commit c806a599224a for compatibility with non-MySQL databases (thanks Ognyan Kulev)
Matthew Wild <mwild1@gmail.com>
parents: 4297
diff changeset
    99
		elseif params.driver == "MySQL" then  -- COMPAT: Upgrade tables from 0.8.0
4285
c806a599224a mod_storage_sql: Switch to MEDIUMTEXT for the 'value' column when using MySQL, as it imposes a 64K limit otherwise, potentially truncating data. Automatically upgrades existing tables.
Matthew Wild <mwild1@gmail.com>
parents: 4218
diff changeset
   100
			-- Failed to create, but check existing MySQL table here
c806a599224a mod_storage_sql: Switch to MEDIUMTEXT for the 'value' column when using MySQL, as it imposes a 64K limit otherwise, potentially truncating data. Automatically upgrades existing tables.
Matthew Wild <mwild1@gmail.com>
parents: 4218
diff changeset
   101
			local stmt = connection:prepare("SHOW COLUMNS FROM prosody WHERE Field='value' and Type='text'");
c806a599224a mod_storage_sql: Switch to MEDIUMTEXT for the 'value' column when using MySQL, as it imposes a 64K limit otherwise, potentially truncating data. Automatically upgrades existing tables.
Matthew Wild <mwild1@gmail.com>
parents: 4218
diff changeset
   102
			local ok = stmt:execute();
c806a599224a mod_storage_sql: Switch to MEDIUMTEXT for the 'value' column when using MySQL, as it imposes a 64K limit otherwise, potentially truncating data. Automatically upgrades existing tables.
Matthew Wild <mwild1@gmail.com>
parents: 4218
diff changeset
   103
			local commit_ok = connection:commit();
c806a599224a mod_storage_sql: Switch to MEDIUMTEXT for the 'value' column when using MySQL, as it imposes a 64K limit otherwise, potentially truncating data. Automatically upgrades existing tables.
Matthew Wild <mwild1@gmail.com>
parents: 4218
diff changeset
   104
			if ok and commit_ok then
c806a599224a mod_storage_sql: Switch to MEDIUMTEXT for the 'value' column when using MySQL, as it imposes a 64K limit otherwise, potentially truncating data. Automatically upgrades existing tables.
Matthew Wild <mwild1@gmail.com>
parents: 4218
diff changeset
   105
				if stmt:rowcount() > 0 then
c806a599224a mod_storage_sql: Switch to MEDIUMTEXT for the 'value' column when using MySQL, as it imposes a 64K limit otherwise, potentially truncating data. Automatically upgrades existing tables.
Matthew Wild <mwild1@gmail.com>
parents: 4218
diff changeset
   106
					local stmt = connection:prepare("ALTER TABLE prosody MODIFY COLUMN `value` MEDIUMTEXT");
c806a599224a mod_storage_sql: Switch to MEDIUMTEXT for the 'value' column when using MySQL, as it imposes a 64K limit otherwise, potentially truncating data. Automatically upgrades existing tables.
Matthew Wild <mwild1@gmail.com>
parents: 4218
diff changeset
   107
					local ok = stmt:execute();
c806a599224a mod_storage_sql: Switch to MEDIUMTEXT for the 'value' column when using MySQL, as it imposes a 64K limit otherwise, potentially truncating data. Automatically upgrades existing tables.
Matthew Wild <mwild1@gmail.com>
parents: 4218
diff changeset
   108
					local commit_ok = connection:commit();
c806a599224a mod_storage_sql: Switch to MEDIUMTEXT for the 'value' column when using MySQL, as it imposes a 64K limit otherwise, potentially truncating data. Automatically upgrades existing tables.
Matthew Wild <mwild1@gmail.com>
parents: 4218
diff changeset
   109
					if ok and commit_ok then
c806a599224a mod_storage_sql: Switch to MEDIUMTEXT for the 'value' column when using MySQL, as it imposes a 64K limit otherwise, potentially truncating data. Automatically upgrades existing tables.
Matthew Wild <mwild1@gmail.com>
parents: 4218
diff changeset
   110
						module:log("info", "Database table automatically upgraded");
c806a599224a mod_storage_sql: Switch to MEDIUMTEXT for the 'value' column when using MySQL, as it imposes a 64K limit otherwise, potentially truncating data. Automatically upgrades existing tables.
Matthew Wild <mwild1@gmail.com>
parents: 4218
diff changeset
   111
					end
c806a599224a mod_storage_sql: Switch to MEDIUMTEXT for the 'value' column when using MySQL, as it imposes a 64K limit otherwise, potentially truncating data. Automatically upgrades existing tables.
Matthew Wild <mwild1@gmail.com>
parents: 4218
diff changeset
   112
				end
c806a599224a mod_storage_sql: Switch to MEDIUMTEXT for the 'value' column when using MySQL, as it imposes a 64K limit otherwise, potentially truncating data. Automatically upgrades existing tables.
Matthew Wild <mwild1@gmail.com>
parents: 4218
diff changeset
   113
				repeat until not stmt:fetch();
4297
3421dfaa8188 mod_storage_sql: Log error when failing to update MySQL schema
Matthew Wild <mwild1@gmail.com>
parents: 4285
diff changeset
   114
			else
3421dfaa8188 mod_storage_sql: Log error when failing to update MySQL schema
Matthew Wild <mwild1@gmail.com>
parents: 4285
diff changeset
   115
				module:log("error", "Failed to upgrade database schema, please see http://prosody.im/doc/mysql for help");
4285
c806a599224a mod_storage_sql: Switch to MEDIUMTEXT for the 'value' column when using MySQL, as it imposes a 64K limit otherwise, potentially truncating data. Automatically upgrades existing tables.
Matthew Wild <mwild1@gmail.com>
parents: 4218
diff changeset
   116
			end
4109
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
   117
		end
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
   118
	end
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
   119
end
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
   120
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   121
do -- process options to get a db connection
4218
8a271b3fcaa7 mod_storage_sql: Display friendlier error when LuaDBI is missing
Matthew Wild <mwild1@gmail.com>
parents: 4109
diff changeset
   122
	local ok;
8a271b3fcaa7 mod_storage_sql: Display friendlier error when LuaDBI is missing
Matthew Wild <mwild1@gmail.com>
parents: 4109
diff changeset
   123
	prosody.unlock_globals();
8a271b3fcaa7 mod_storage_sql: Display friendlier error when LuaDBI is missing
Matthew Wild <mwild1@gmail.com>
parents: 4109
diff changeset
   124
	ok, DBI = pcall(require, "DBI");
8a271b3fcaa7 mod_storage_sql: Display friendlier error when LuaDBI is missing
Matthew Wild <mwild1@gmail.com>
parents: 4109
diff changeset
   125
	if not ok then
8a271b3fcaa7 mod_storage_sql: Display friendlier error when LuaDBI is missing
Matthew Wild <mwild1@gmail.com>
parents: 4109
diff changeset
   126
		package.loaded["DBI"] = {};
8a271b3fcaa7 mod_storage_sql: Display friendlier error when LuaDBI is missing
Matthew Wild <mwild1@gmail.com>
parents: 4109
diff changeset
   127
		module:log("error", "Failed to load the LuaDBI library for accessing SQL databases: %s", DBI);
8a271b3fcaa7 mod_storage_sql: Display friendlier error when LuaDBI is missing
Matthew Wild <mwild1@gmail.com>
parents: 4109
diff changeset
   128
		module:log("error", "More information on installing LuaDBI can be found at http://prosody.im/doc/depends#luadbi");
8a271b3fcaa7 mod_storage_sql: Display friendlier error when LuaDBI is missing
Matthew Wild <mwild1@gmail.com>
parents: 4109
diff changeset
   129
	end
8a271b3fcaa7 mod_storage_sql: Display friendlier error when LuaDBI is missing
Matthew Wild <mwild1@gmail.com>
parents: 4109
diff changeset
   130
	prosody.lock_globals();
8a271b3fcaa7 mod_storage_sql: Display friendlier error when LuaDBI is missing
Matthew Wild <mwild1@gmail.com>
parents: 4109
diff changeset
   131
	if not ok or not DBI.Connect then
8a271b3fcaa7 mod_storage_sql: Display friendlier error when LuaDBI is missing
Matthew Wild <mwild1@gmail.com>
parents: 4109
diff changeset
   132
		return; -- Halt loading of this module
8a271b3fcaa7 mod_storage_sql: Display friendlier error when LuaDBI is missing
Matthew Wild <mwild1@gmail.com>
parents: 4109
diff changeset
   133
	end
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   134
4096
3b991ceb228e mod_storage_sql: Make the 'database' value for the SQLite3 driver relative to the data path
Matthew Wild <mwild1@gmail.com>
parents: 4073
diff changeset
   135
	params = params or { driver = "SQLite3" };
3b991ceb228e mod_storage_sql: Make the 'database' value for the SQLite3 driver relative to the data path
Matthew Wild <mwild1@gmail.com>
parents: 4073
diff changeset
   136
	
3b991ceb228e mod_storage_sql: Make the 'database' value for the SQLite3 driver relative to the data path
Matthew Wild <mwild1@gmail.com>
parents: 4073
diff changeset
   137
	if params.driver == "SQLite3" then
3b991ceb228e mod_storage_sql: Make the 'database' value for the SQLite3 driver relative to the data path
Matthew Wild <mwild1@gmail.com>
parents: 4073
diff changeset
   138
		params.database = resolve_relative_path(prosody.paths.data or ".", params.database or "prosody.sqlite");
3b991ceb228e mod_storage_sql: Make the 'database' value for the SQLite3 driver relative to the data path
Matthew Wild <mwild1@gmail.com>
parents: 4073
diff changeset
   139
	end
3b991ceb228e mod_storage_sql: Make the 'database' value for the SQLite3 driver relative to the data path
Matthew Wild <mwild1@gmail.com>
parents: 4073
diff changeset
   140
	
3b991ceb228e mod_storage_sql: Make the 'database' value for the SQLite3 driver relative to the data path
Matthew Wild <mwild1@gmail.com>
parents: 4073
diff changeset
   141
	assert(params.driver and params.database, "Both the SQL driver and the database need to be specified");
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   142
	
4105
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
   143
	assert(connect());
3854
5a1551d604b1 mod_storage_sql: Auto-initialize SQLite3 database.
Waqas Hussain <waqas20@gmail.com>
parents: 3853
diff changeset
   144
	
4101
06778bc27d53 mod_storage_sql: Create table automatically for all databases now, not just SQLite. Also rename table from Prosody -> prosody.
Matthew Wild <mwild1@gmail.com>
parents: 4096
diff changeset
   145
	-- Automatically create table, ignore failure (table probably already exists)
4109
d26db1f936f8 mod_storage_sql: Create index when creating a new table
Matthew Wild <mwild1@gmail.com>
parents: 4105
diff changeset
   146
	create_table();
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   147
end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   148
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   149
local function serialize(value)
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   150
	local t = type(value);
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   151
	if t == "string" or t == "boolean" or t == "number" then
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   152
		return t, tostring(value);
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   153
	elseif t == "table" then
4048
c64b0aefb922 mod_storage_sql: Use util.json instead of util.serialization.
Waqas Hussain <waqas20@gmail.com>
parents: 4046
diff changeset
   154
		local value,err = json.encode(value);
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   155
		if value then return "json", value; end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   156
		return nil, err;
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   157
	end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   158
	return nil, "Unhandled value type: "..t;
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   159
end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   160
local function deserialize(t, value)
3863
2a9475dce7ff mod_storage_sql: Fixed the deserialization of string-typed values.
Waqas Hussain <waqas20@gmail.com>
parents: 3854
diff changeset
   161
	if t == "string" then return value;
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   162
	elseif t == "boolean" then
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   163
		if value == "true" then return true;
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   164
		elseif value == "false" then return false; end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   165
	elseif t == "number" then return tonumber(value);
3891
f82af9f7f1cd mod_storage_sql: Fix a couple of bugs in "JSON" decoding
Matthew Wild <mwild1@gmail.com>
parents: 3864
diff changeset
   166
	elseif t == "json" then
4048
c64b0aefb922 mod_storage_sql: Use util.json instead of util.serialization.
Waqas Hussain <waqas20@gmail.com>
parents: 4046
diff changeset
   167
		return json.decode(value);
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   168
	end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   169
end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   170
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   171
local function getsql(sql, ...)
4044
61ae809da8ee mod_storage_sql: Dynamically replace backquotes with double quotes when connecting to PostgreSQL...
Waqas Hussain <waqas20@gmail.com>
parents: 4043
diff changeset
   172
	if params.driver == "PostgreSQL" then
61ae809da8ee mod_storage_sql: Dynamically replace backquotes with double quotes when connecting to PostgreSQL...
Waqas Hussain <waqas20@gmail.com>
parents: 4043
diff changeset
   173
		sql = sql:gsub("`", "\"");
61ae809da8ee mod_storage_sql: Dynamically replace backquotes with double quotes when connecting to PostgreSQL...
Waqas Hussain <waqas20@gmail.com>
parents: 4043
diff changeset
   174
	end
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   175
	-- do prepared statement stuff
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   176
	local stmt, err = connection:prepare(sql);
4105
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
   177
	if not stmt and not test_connection() then error("connection failed"); end
4046
467e73951610 mod_storage_sql: Log an error on query failure.
Waqas Hussain <waqas20@gmail.com>
parents: 4045
diff changeset
   178
	if not stmt then module:log("error", "QUERY FAILED: %s %s", err, debug.traceback()); return nil, err; end
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   179
	-- run query
4042
3294f12ea602 mod_storage_sql: Quote identifiers in SQL with backquotes, and use the empty string for NULL, and '=' instead of 'IS' for comparison, to work with MySQL's limitations...
Waqas Hussain <waqas20@gmail.com>
parents: 3891
diff changeset
   180
	local ok, err = stmt:execute(host or "", user or "", store or "", ...);
4105
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
   181
	if not ok and not test_connection() then error("connection failed"); end
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   182
	if not ok then return nil, err; end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   183
	
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   184
	return stmt;
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   185
end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   186
local function setsql(sql, ...)
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   187
	local stmt, err = getsql(sql, ...);
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   188
	if not stmt then return stmt, err; end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   189
	return stmt:affected();
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   190
end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   191
local function transact(...)
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   192
	-- ...
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   193
end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   194
local function rollback(...)
4105
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
   195
	if connection then connection:rollback(); end -- FIXME check for rollback error?
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   196
	return ...;
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   197
end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   198
local function commit(...)
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   199
	if not connection:commit() then return nil, "SQL commit failed"; end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   200
	return ...;
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   201
end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   202
4073
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   203
local function keyval_store_get()
4101
06778bc27d53 mod_storage_sql: Create table automatically for all databases now, not just SQLite. Also rename table from Prosody -> prosody.
Matthew Wild <mwild1@gmail.com>
parents: 4096
diff changeset
   204
	local stmt, err = getsql("SELECT * FROM `prosody` WHERE `host`=? AND `user`=? AND `store`=?");
4105
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
   205
	if not stmt then return rollback(nil, err); end
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   206
	
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   207
	local haveany;
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   208
	local result = {};
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   209
	for row in stmt:rows(true) do
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   210
		haveany = true;
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   211
		local k = row.key;
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   212
		local v = deserialize(row.type, row.value);
4045
054e05b27611 mod_storage_sql: Remove the subkey column from the Prosody table, and make the map store compatible with the key-value store.
Waqas Hussain <waqas20@gmail.com>
parents: 4044
diff changeset
   213
		if k and v then
054e05b27611 mod_storage_sql: Remove the subkey column from the Prosody table, and make the map store compatible with the key-value store.
Waqas Hussain <waqas20@gmail.com>
parents: 4044
diff changeset
   214
			if k ~= "" then result[k] = v; elseif type(v) == "table" then
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   215
				for a,b in pairs(v) do
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   216
					result[a] = b;
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   217
				end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   218
			end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   219
		end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   220
	end
4043
d3f5c60a72b1 mod_storage_sql: Call commit() after all SQL statements, including SELECT, to get SQLite to drop its locks.
Waqas Hussain <waqas20@gmail.com>
parents: 4042
diff changeset
   221
	return commit(haveany and result or nil);
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   222
end
4073
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   223
local function keyval_store_set(data)
4101
06778bc27d53 mod_storage_sql: Create table automatically for all databases now, not just SQLite. Also rename table from Prosody -> prosody.
Matthew Wild <mwild1@gmail.com>
parents: 4096
diff changeset
   224
	local affected, err = setsql("DELETE FROM `prosody` WHERE `host`=? AND `user`=? AND `store`=?");
4105
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
   225
	if not affected then return rollback(affected, err); end
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   226
	
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   227
	if data and next(data) ~= nil then
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   228
		local extradata = {};
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   229
		for key, value in pairs(data) do
4042
3294f12ea602 mod_storage_sql: Quote identifiers in SQL with backquotes, and use the empty string for NULL, and '=' instead of 'IS' for comparison, to work with MySQL's limitations...
Waqas Hussain <waqas20@gmail.com>
parents: 3891
diff changeset
   230
			if type(key) == "string" and key ~= "" then
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   231
				local t, value = serialize(value);
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   232
				if not t then return rollback(t, value); end
4101
06778bc27d53 mod_storage_sql: Create table automatically for all databases now, not just SQLite. Also rename table from Prosody -> prosody.
Matthew Wild <mwild1@gmail.com>
parents: 4096
diff changeset
   233
				local ok, err = setsql("INSERT INTO `prosody` (`host`,`user`,`store`,`key`,`type`,`value`) VALUES (?,?,?,?,?,?)", key, t, value);
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   234
				if not ok then return rollback(ok, err); end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   235
			else
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   236
				extradata[key] = value;
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   237
			end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   238
		end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   239
		if next(extradata) ~= nil then
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   240
			local t, extradata = serialize(extradata);
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   241
			if not t then return rollback(t, extradata); end
4101
06778bc27d53 mod_storage_sql: Create table automatically for all databases now, not just SQLite. Also rename table from Prosody -> prosody.
Matthew Wild <mwild1@gmail.com>
parents: 4096
diff changeset
   242
			local ok, err = setsql("INSERT INTO `prosody` (`host`,`user`,`store`,`key`,`type`,`value`) VALUES (?,?,?,?,?,?)", "", t, extradata);
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   243
			if not ok then return rollback(ok, err); end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   244
		end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   245
	end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   246
	return commit(true);
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   247
end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   248
4073
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   249
local keyval_store = {};
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   250
keyval_store.__index = keyval_store;
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   251
function keyval_store:get(username)
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   252
	user,store = username,self.store;
4105
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
   253
	if not connection and not connect() then return nil, "Unable to connect to database"; end
4073
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   254
	local success, ret, err = xpcall(keyval_store_get, debug.traceback);
4105
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
   255
	if not connection and connect() then
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
   256
		success, ret, err = xpcall(keyval_store_get, debug.traceback);
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
   257
	end
4073
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   258
	if success then return ret, err; else return rollback(nil, ret); end
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   259
end
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   260
function keyval_store:set(username, data)
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   261
	user,store = username,self.store;
4105
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
   262
	if not connection and not connect() then return nil, "Unable to connect to database"; end
4073
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   263
	local success, ret, err = xpcall(function() return keyval_store_set(data); end, debug.traceback);
4105
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
   264
	if not connection and connect() then
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
   265
		success, ret, err = xpcall(function() return keyval_store_set(data); end, debug.traceback);
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
   266
	end
4073
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   267
	if success then return ret, err; else return rollback(nil, ret); end
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   268
end
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   269
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   270
local function map_store_get(key)
4101
06778bc27d53 mod_storage_sql: Create table automatically for all databases now, not just SQLite. Also rename table from Prosody -> prosody.
Matthew Wild <mwild1@gmail.com>
parents: 4096
diff changeset
   271
	local stmt, err = getsql("SELECT * FROM `prosody` WHERE `host`=? AND `user`=? AND `store`=? AND `key`=?", key or "");
4105
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
   272
	if not stmt then return rollback(nil, err); end
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   273
	
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   274
	local haveany;
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   275
	local result = {};
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   276
	for row in stmt:rows(true) do
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   277
		haveany = true;
4045
054e05b27611 mod_storage_sql: Remove the subkey column from the Prosody table, and make the map store compatible with the key-value store.
Waqas Hussain <waqas20@gmail.com>
parents: 4044
diff changeset
   278
		local k = row.key;
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   279
		local v = deserialize(row.type, row.value);
4045
054e05b27611 mod_storage_sql: Remove the subkey column from the Prosody table, and make the map store compatible with the key-value store.
Waqas Hussain <waqas20@gmail.com>
parents: 4044
diff changeset
   280
		if k and v then
054e05b27611 mod_storage_sql: Remove the subkey column from the Prosody table, and make the map store compatible with the key-value store.
Waqas Hussain <waqas20@gmail.com>
parents: 4044
diff changeset
   281
			if k ~= "" then result[k] = v; elseif type(v) == "table" then
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   282
				for a,b in pairs(v) do
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   283
					result[a] = b;
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   284
				end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   285
			end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   286
		end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   287
	end
4045
054e05b27611 mod_storage_sql: Remove the subkey column from the Prosody table, and make the map store compatible with the key-value store.
Waqas Hussain <waqas20@gmail.com>
parents: 4044
diff changeset
   288
	return commit(haveany and result[key] or nil);
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   289
end
4073
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   290
local function map_store_set(key, data)
4101
06778bc27d53 mod_storage_sql: Create table automatically for all databases now, not just SQLite. Also rename table from Prosody -> prosody.
Matthew Wild <mwild1@gmail.com>
parents: 4096
diff changeset
   291
	local affected, err = setsql("DELETE FROM `prosody` WHERE `host`=? AND `user`=? AND `store`=? AND `key`=?", key or "");
4105
08560575762f mod_storage_sql: Reconnect in all cases, and rollback on error.
Waqas Hussain <waqas20@gmail.com>
parents: 4101
diff changeset
   292
	if not affected then return rollback(affected, err); end
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   293
	
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   294
	if data and next(data) ~= nil then
4045
054e05b27611 mod_storage_sql: Remove the subkey column from the Prosody table, and make the map store compatible with the key-value store.
Waqas Hussain <waqas20@gmail.com>
parents: 4044
diff changeset
   295
		if type(key) == "string" and key ~= "" then
054e05b27611 mod_storage_sql: Remove the subkey column from the Prosody table, and make the map store compatible with the key-value store.
Waqas Hussain <waqas20@gmail.com>
parents: 4044
diff changeset
   296
			local t, value = serialize(data);
054e05b27611 mod_storage_sql: Remove the subkey column from the Prosody table, and make the map store compatible with the key-value store.
Waqas Hussain <waqas20@gmail.com>
parents: 4044
diff changeset
   297
			if not t then return rollback(t, value); end
4101
06778bc27d53 mod_storage_sql: Create table automatically for all databases now, not just SQLite. Also rename table from Prosody -> prosody.
Matthew Wild <mwild1@gmail.com>
parents: 4096
diff changeset
   298
			local ok, err = setsql("INSERT INTO `prosody` (`host`,`user`,`store`,`key`,`type`,`value`) VALUES (?,?,?,?,?,?)", key, t, value);
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   299
			if not ok then return rollback(ok, err); end
4045
054e05b27611 mod_storage_sql: Remove the subkey column from the Prosody table, and make the map store compatible with the key-value store.
Waqas Hussain <waqas20@gmail.com>
parents: 4044
diff changeset
   300
		else
054e05b27611 mod_storage_sql: Remove the subkey column from the Prosody table, and make the map store compatible with the key-value store.
Waqas Hussain <waqas20@gmail.com>
parents: 4044
diff changeset
   301
			-- TODO non-string keys
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   302
		end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   303
	end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   304
	return commit(true);
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   305
end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   306
4073
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   307
local map_store = {};
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   308
map_store.__index = map_store;
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   309
function map_store:get(username, key)
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   310
	user,store = username,self.store;
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   311
	local success, ret, err = xpcall(function() return map_store_get(key); end, debug.traceback);
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   312
	if success then return ret, err; else return rollback(nil, ret); end
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   313
end
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   314
function map_store:set(username, key, data)
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   315
	user,store = username,self.store;
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   316
	local success, ret, err = xpcall(function() return map_store_set(key, data); end, debug.traceback);
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   317
	if success then return ret, err; else return rollback(nil, ret); end
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   318
end
79fd38ab224b mod_storage_sql: Catch Lua errors during SQL transactions, and rollback.
Waqas Hussain <waqas20@gmail.com>
parents: 4070
diff changeset
   319
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   320
local list_store = {};
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   321
list_store.__index = list_store;
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   322
function list_store:scan(username, from, to, jid, typ)
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   323
	user,store = username,self.store;
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   324
	
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   325
	local cols = {"from", "to", "jid", "typ"};
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   326
	local vals = { from ,  to ,  jid ,  typ };
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   327
	local stmt, err;
4101
06778bc27d53 mod_storage_sql: Create table automatically for all databases now, not just SQLite. Also rename table from Prosody -> prosody.
Matthew Wild <mwild1@gmail.com>
parents: 4096
diff changeset
   328
	local query = "SELECT * FROM `prosodyarchive` WHERE `host`=? AND `user`=? AND `store`=?";
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   329
	
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   330
	query = query.." ORDER BY time";
4101
06778bc27d53 mod_storage_sql: Create table automatically for all databases now, not just SQLite. Also rename table from Prosody -> prosody.
Matthew Wild <mwild1@gmail.com>
parents: 4096
diff changeset
   331
	--local stmt, err = getsql("SELECT * FROM `prosody` WHERE `host`=? AND `user`=? AND `store`=? AND `key`=?", key or "");
3851
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   332
	
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   333
	return nil, "not-implemented"
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   334
end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   335
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   336
local driver = { name = "sql" };
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   337
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   338
function driver:open(store, typ)
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   339
	if not typ then -- default key-value store
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   340
		return setmetatable({ store = store }, keyval_store);
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   341
	end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   342
	return nil, "unsupported-store";
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   343
end
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   344
e979b5fe859d mod_storage_sql: Initial commit of new SQL data driver.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   345
module:add_item("data-driver", driver);