2019-07-17 19:37:18 +02:00
//
// Created by wolverindev on 24.03.18.
//
# include <sql/sqlite/SqliteSQL.h>
# include <src/Configuration.h>
# include <log/LogUtils.h>
# include <Properties.h>
# include <sql/mysql/MySQL.h>
# include <PermissionManager.h>
# include "SqlDataManager.h"
using namespace std ;
using namespace std : : chrono ;
using namespace ts ;
using namespace ts : : server ;
SqlDataManager : : SqlDataManager ( ) { }
SqlDataManager : : ~ SqlDataManager ( ) { }
# define EXECUTE(msg, cmd) \
result = sql : : command ( this - > manager , cmd ) . execute ( ) ; \
if ( ! result ) { \
2020-01-24 02:57:58 +01:00
error = string ( msg ) + " Command ' " + std : : string ( cmd ) + " ' returns " + result . fmtStr ( ) ; \
return false ; \
2019-07-17 19:37:18 +02:00
}
# define EXECUTE_(error_message, cmd, ignore) \
result = sql : : command ( this - > manager , cmd ) . execute ( ) ; \
if ( ! result & & result . msg ( ) . find ( ignore ) = = string : : npos ) { \
2020-01-24 02:57:58 +01:00
error = string ( error_message ) + " Command ' " + std : : string ( cmd ) + " ' returns " + result . fmtStr ( ) ; \
return false ; \
2019-07-17 19:37:18 +02:00
}
# define BUILD_CREATE_TABLE(tblName, types) "CREATE TABLE IF NOT EXISTS `" tblName "` (" types ")"
# define CREATE_TABLE(table, types, append) EXECUTE("Could not setup SQL tables! ", BUILD_CREATE_TABLE(table, types) + append);
# define DROP_INDEX(tblName, rowName) EXECUTE_("Failed to drop old indexes", "DROP INDEX IF EXISTS `idx_" tblName "_" rowName "`", "");
# define BUILD_CREATE_INDEX(tblName, rowName) "CREATE INDEX `idx_" tblName "_" rowName "` ON `" tblName "` (`" rowName "`);"
# define CREATE_INDEX(tblName, rowName) EXECUTE_("Could not setup SQL table indexes! ", BUILD_CREATE_INDEX(tblName, rowName), "Duplicate");
# define DROP_INDEX2R(tblName, rowName1, rowName2) EXECUTE_("Failed to drop old indexes", "DROP INDEX IF EXISTS `idx_" tblName "_" rowName1 "_" rowName2 "`;", "");
# define BUILD_CREATE_INDEX2R(tblName, rowName1, rowName2) "CREATE INDEX `idx_" tblName "_" rowName1 "_" rowName2 "` ON `" tblName "` (`" rowName1 "`, `" rowName2 "`);"
# define CREATE_INDEX2R(tblName, rowName1, rowName2) EXECUTE_("Could not setup SQL table indexes! ", BUILD_CREATE_INDEX2R(tblName, rowName1, rowName2), "Duplicate");
# define RESIZE_COLUMN(tblName, rowName, size) up vote EXECUTE("Could not change column size", "ALTER TABLE " tblName " ALTER COLUMN " rowName " varchar(" size ")");
2020-07-30 20:25:45 +02:00
# define CURRENT_DATABASE_VERSION 14
2020-04-24 22:04:07 +02:00
# define CURRENT_PERMISSION_VERSION 4
2019-07-17 19:37:18 +02:00
# define CLIENT_UID_LENGTH "64"
# define CLIENT_NAME_LENGTH "128"
# define UNKNOWN_KEY_LENGTH "256"
template < typename T >
struct alive_watch {
2020-01-24 02:57:58 +01:00
bool do_notify ;
T notify ;
alive_watch ( T & & function ) : notify ( std : : forward < T > ( function ) ) , do_notify ( true ) { }
~ alive_watch ( ) {
if ( do_notify )
notify ( ) ;
}
2019-07-17 19:37:18 +02:00
} ;
2019-08-16 16:13:52 +02:00
# define db_version(new_version) \
do { \
2020-01-24 02:57:58 +01:00
if ( ! this - > change_database_version ( new_version ) ) { \
error = " failed to update database version " ; \
return false ; \
} \
2019-08-16 16:13:52 +02:00
} while ( 0 )
# define perm_version(new_version) \
do { \
2020-01-24 02:57:58 +01:00
if ( ! this - > change_permission_version ( new_version ) ) { \
error = " failed to update permission version " ; \
return false ; \
} \
2019-08-16 16:13:52 +02:00
} while ( 0 )
2020-08-13 12:58:19 +02:00
std : : string replace_all ( std : : string str , const std : : string & from , const std : : string & to ) {
size_t start_pos = 0 ;
while ( ( start_pos = str . find ( from , start_pos ) ) ! = std : : string : : npos ) {
str . replace ( start_pos , from . length ( ) , to ) ;
start_pos + = to . length ( ) ;
}
return str ;
}
2020-07-30 20:25:45 +02:00
template < typename T , size_t N >
inline bool execute_commands ( sql : : SqlManager * sql , std : : string & error , const std : : array < T , N > & commands ) {
std : : string insert_or_ignore { sql - > getType ( ) = = sql : : TYPE_SQLITE ? " INSERT OR IGNORE " : " INSERT IGNORE " } ;
2020-08-13 12:58:19 +02:00
std : : string auto_increment { sql - > getType ( ) = = sql : : TYPE_SQLITE ? " AUTOINCREMENT " : " AUTO_INCREMENT " } ;
2020-07-30 20:25:45 +02:00
for ( const auto & cmd : commands ) {
std : : string command { cmd } ;
2020-07-31 19:42:40 +02:00
command . erase ( command . begin ( ) , std : : find_if ( command . begin ( ) , command . end ( ) , [ ] ( int ch ) {
return ! std : : isspace ( ch ) ;
} ) ) ;
2020-08-13 12:58:19 +02:00
command = replace_all ( command , " [INSERT_OR_IGNORE] " , insert_or_ignore ) ;
command = replace_all ( command , " [AUTO_INCREMENT] " , auto_increment ) ;
2020-07-30 20:25:45 +02:00
auto result = sql : : command ( sql , command ) . execute ( ) ;
if ( ! result ) {
error = result . fmtStr ( ) ;
return false ;
}
}
return true ;
}
2019-07-17 19:37:18 +02:00
bool SqlDataManager : : initialize ( std : : string & error ) {
2020-01-24 02:57:58 +01:00
if ( ts : : config : : database : : url . find ( " sqlite:// " ) = = 0 )
this - > manager = new sql : : sqlite : : SqliteManager ( ) ;
else if ( ts : : config : : database : : url . find ( " mysql:// " ) = = 0 )
this - > manager = new sql : : mysql : : MySQLManager ( ) ;
else {
error = " Invalid database type! " ;
return false ;
}
auto result = manager - > connect ( ts : : config : : database : : url ) ;
if ( ! result ) {
error = " Could not connect to " + ts : : config : : database : : url + " ( " + result . fmtStr ( ) + " ). " ;
return false ;
}
if ( manager - > getType ( ) = = sql : : TYPE_MYSQL ) {
sql : : command ( this - > manager , " SET NAMES utf8 " ) . execute ( ) ;
//sql::command(this->manager, "DEFAULT CHARSET=utf8").execute();
} else if ( manager - > getType ( ) = = sql : : TYPE_SQLITE ) {
if ( ! config : : database : : sqlite : : journal_mode . empty ( ) )
sql : : command ( this - > manager , " PRAGMA journal_mode= " + config : : database : : sqlite : : journal_mode + " ; " ) . execute ( ) ;
if ( ! config : : database : : sqlite : : sync_mode . empty ( ) )
sql : : command ( this - > manager , " PRAGMA synchronous= " + config : : database : : sqlite : : sync_mode + " ; " ) . execute ( ) ;
if ( ! config : : database : : sqlite : : locking_mode . empty ( ) )
sql : : command ( this - > manager , " PRAGMA locking_mode= " + config : : database : : sqlite : : locking_mode + " ; " ) . execute ( ) ;
sql : : command ( this - > manager , " PRAGMA encoding = \" UTF-8 \" ; " ) . execute ( ) ;
}
/* begin transaction, if available */
if ( manager - > getType ( ) = = sql : : TYPE_SQLITE ) {
result = sql : : command ( this - > sql ( ) , " BEGIN TRANSACTION; " ) . execute ( ) ;
if ( ! result ) {
error = " failed to begin transaction ( " + result . fmtStr ( ) + " ) " ;
return false ;
}
}
alive_watch rollback_watch ( [ & ] {
if ( manager - > getType ( ) = = sql : : TYPE_SQLITE ) {
auto result = sql : : command ( this - > sql ( ) , " ROLLBACK; " ) . execute ( ) ;
if ( ! result ) {
logCritical ( LOG_GENERAL , " Failed to rollback database after transaction. " ) ;
return ;
}
debugMessage ( LOG_GENERAL , " Rollbacked database successfully. " ) ;
}
} ) ;
if ( ! this - > detect_versions ( ) ) {
error = " failed to detect database/permission version " ;
return false ;
}
if ( ! this - > update_database ( error ) ) {
error = " failed to upgrade database: " + error ;
return false ;
}
//Advanced locked test
{
bool property_exists = false ;
2020-04-14 11:49:07 +02:00
sql : : command ( this - > sql ( ) , " SELECT * FORM `general` WHERE `key` = :key " , variable { " :key " , " lock_test " } ) . query ( [ & ] ( int , string * , string * ) { property_exists = true ; } ) ;
2020-01-24 02:57:58 +01:00
sql : : result res ;
if ( ! property_exists ) {
res = sql : : command ( this - > sql ( ) , " INSERT INTO `general` (`key`, `value`) VALUES (:key, :value); " , variable { " :key " , " lock_test " } , variable { " :value " , " UPDATE ME! " } ) . execute ( ) ;
} else {
res = sql : : command ( this - > sql ( ) , " UPDATE `general` SET `value`= :value WHERE `key`= :key; " , variable { " :key " , " lock_test " } , variable { " :value " , " TeaSpeak created by WolverinDEV <3 " } ) . execute ( ) ;
}
2020-07-31 17:35:14 +02:00
2020-01-24 02:57:58 +01:00
if ( ! res ) {
if ( res . msg ( ) . find ( " database is locked " ) ! = string : : npos ) error = " database is locked " ;
else error = " Failed to execute lock test! Command result: " + res . fmtStr ( ) ;
return false ;
}
2020-07-31 17:35:14 +02:00
res = sql : : command { this - > sql ( ) , " DELETE FROM `general` WHERE `key` = :key ORDER BY `key` LIMIT -1 OFFSET 1; " , variable { " :key " , " lock_test " } } . execute ( ) ;
if ( ! res ) {
error = res . fmtStr ( ) ;
return false ;
}
2020-01-24 02:57:58 +01:00
}
if ( ! this - > update_permissions ( error ) ) {
error = " failed to upgrade permissions: " + error ;
return false ;
}
rollback_watch . do_notify = false ; /* transaction was successful */
if ( manager - > getType ( ) = = sql : : TYPE_SQLITE ) {
result = sql : : command ( this - > sql ( ) , " COMMIT; " ) . execute ( ) ;
if ( ! result ) {
error = " failed to commit changes " ;
return false ;
}
}
return true ;
2019-08-16 16:13:52 +02:00
}
bool SqlDataManager : : update_database ( std : : string & error ) {
2020-01-24 02:57:58 +01:00
if ( this - > _database_version ! = CURRENT_DATABASE_VERSION ) {
string command_append_utf8 = manager - > getType ( ) = = sql : : TYPE_MYSQL ? " CHARACTER SET=utf8 " : " " ;
sql : : result result ;
auto timestamp_start = system_clock : : now ( ) ;
logMessage ( LOG_GENERAL , " Upgrading database from version " + to_string ( this - > _database_version ) + " to " + to_string ( CURRENT_DATABASE_VERSION ) + " . This could take a moment! " ) ;
switch ( this - > _database_version ) {
case - 1 :
CREATE_TABLE ( " general " , " `key` VARCHAR( " UNKNOWN_KEY_LENGTH " ), `value` TEXT " , command_append_utf8 ) ;
CREATE_TABLE ( " servers " , " `serverId` INT NOT NULL, `host` TEXT NOT NULL, `port` INT " , command_append_utf8 ) ;
CREATE_TABLE ( " assignedGroups " , " `serverId` INT NOT NULL, `cldbid` INT NOT NULL, `groupId` INT, `channelId` INT DEFAULT -1, `until` BIGINT DEFAULT -1 " , command_append_utf8 ) ;
CREATE_TABLE ( " groups " , " `serverId` INT NOT NULL, `groupId` INTEGER, `target` INT, `type` INT, `displayName` VARCHAR( " CLIENT_NAME_LENGTH " ) " , command_append_utf8 ) ;
CREATE_TABLE ( " queries " , " `username` VARCHAR( " CLIENT_NAME_LENGTH " ), `password` TEXT, `uniqueId` VARCHAR( " CLIENT_UID_LENGTH " ) " , command_append_utf8 ) ;
CREATE_TABLE ( " clients " , " `serverId` INT NOT NULL, `cldbid` INTEGER, `clientUid` VARCHAR( " CLIENT_UID_LENGTH " ), `firstConnect` BIGINT, `lastConnect` BIGINT, `connections` INT, `lastName` VARCHAR( " CLIENT_NAME_LENGTH " ) " , command_append_utf8 ) ;
CREATE_TABLE ( " channels " , " `serverId` INT NOT NULL, `channelId` INT, `type` INT, `parentId` INT " , command_append_utf8 ) ;
CREATE_TABLE ( " properties " , " `serverId` INTEGER DEFAULT -1, `type` INTEGER, `id` INTEGER, `key` VARCHAR( " UNKNOWN_KEY_LENGTH " ), `value` TEXT " , command_append_utf8 ) ;
CREATE_TABLE ( " permissions " , " `serverId` INT NOT NULL, `type` INT, `id` INT, `channelId` INT, `permId` VARCHAR( " UNKNOWN_KEY_LENGTH " ), `value` INT, `grant` INT " , command_append_utf8 ) ;
CREATE_TABLE ( " bannedClients " , " `banId` INTEGER NOT NULL PRIMARY KEY, `serverId` INT NOT NULL, `invokerDbId` INT NOT NULL, `reason` TEXT, `hwid` VARCHAR( " CLIENT_UID_LENGTH " ), `uid` VARCHAR( " CLIENT_UID_LENGTH " ), `name` VARCHAR( " CLIENT_NAME_LENGTH " ), `ip` VARCHAR(128), `strType` VARCHAR(32), `created` BIGINT DEFAULT -1, `until` BIGINT DEFAULT -1 " , command_append_utf8 ) ;
CREATE_TABLE ( " tokens " , " `serverId` INT NOT NULL, `type` INT NOT NULL, `token` VARCHAR(128), `targetGroup` INT NOT NULL, `targetChannel` INT, `description` TEXT , `created` INT " , command_append_utf8 ) ;
CREATE_TABLE ( " complains " , " `serverId` INT NOT NULL, `targetId` INT NOT NULL, `reporterId` INT NOT NULL, `reason` TEXT, `created` INT " , command_append_utf8 ) ;
CREATE_TABLE ( " letters " , " `serverId` INT NOT NULL, `letterId` INTEGER NOT NULL PRIMARY KEY, `sender` VARCHAR( " CLIENT_UID_LENGTH " ), `receiver` VARCHAR( " CLIENT_UID_LENGTH " ), `created` INT, `subject` TEXT, `message` TEXT, `read` INT " , command_append_utf8 ) ;
CREATE_TABLE ( " musicbots " , " `serverId` INT, `botId` INT, `uniqueId` VARCHAR( " CLIENT_UID_LENGTH " ), `owner` INT " , command_append_utf8 ) ;
db_version ( 0 ) ;
case 0 :
CREATE_INDEX ( " general " , " key " ) ;
CREATE_INDEX ( " servers " , " serverId " ) ;
CREATE_INDEX2R ( " assignedGroups " , " serverId " , " cldbid " ) ;
CREATE_INDEX2R ( " groups " , " serverId " , " groupId " ) ;
CREATE_INDEX ( " groups " , " serverId " ) ;
CREATE_INDEX ( " queries " , " username " ) ;
CREATE_INDEX ( " clients " , " serverId " ) ;
CREATE_INDEX2R ( " clients " , " serverId " , " cldbid " ) ;
CREATE_INDEX ( " channels " , " serverId " ) ;
CREATE_INDEX ( " properties " , " serverId " ) ;
CREATE_INDEX ( " permissions " , " serverId " ) ;
CREATE_INDEX2R ( " properties " , " serverId " , " id " ) ;
CREATE_INDEX2R ( " permissions " , " serverId " , " channelId " ) ;
CREATE_INDEX ( " bannedClients " , " serverId " ) ;
CREATE_INDEX ( " bannedClients " , " banId " ) ;
CREATE_INDEX2R ( " bannedClients " , " serverId " , " hwid " ) ;
CREATE_INDEX2R ( " bannedClients " , " serverId " , " name " ) ;
CREATE_INDEX2R ( " bannedClients " , " serverId " , " uid " ) ;
CREATE_INDEX2R ( " bannedClients " , " serverId " , " ip " ) ;
CREATE_INDEX ( " tokens " , " serverId " ) ;
CREATE_INDEX ( " complains " , " serverId " ) ;
CREATE_INDEX ( " letters " , " serverId " ) ;
CREATE_INDEX ( " letters " , " letterId " ) ;
CREATE_INDEX ( " musicbots " , " serverId " ) ;
db_version ( 1 ) ;
case 1 :
sql : : command ( this - > sql ( ) , " UPDATE `properties` SET `type` = :type WHERE `serverId` = 0 AND `id` = 0 " , variable { " :type " , property : : PropertyType : : PROP_TYPE_INSTANCE } ) . execute ( ) ;
db_version ( 2 ) ;
case 2 :
sql : : command ( this - > sql ( ) , " ALTER TABLE permissions ADD flag_skip BOOL; " ) . execute ( ) ;
sql : : command ( this - > sql ( ) , " ALTER TABLE permissions ADD flag_negate BOOL; " ) . execute ( ) ;
db_version ( 3 ) ;
case 3 :
EXECUTE ( " Failed to update ban table " , " ALTER TABLE `bannedClients` ADD COLUMN `triggered` INT DEFAULT 0; " ) ;
CREATE_TABLE ( " ban_trigger " , " `server_id` INT, `ban_id` INT, `unique_id` VARCHAR( " CLIENT_UID_LENGTH " ), `hardware_id` VARCHAR( " CLIENT_UID_LENGTH " ), `name` VARCHAR( " CLIENT_NAME_LENGTH " ), `ip` VARCHAR(128), `timestamp` BIGINT " , command_append_utf8 ) ;
CREATE_INDEX2R ( " ban_trigger " , " server_id " , " ban_id " ) ;
db_version ( 4 ) ;
case 4 :
sql : : command ( this - > sql ( ) , " ALTER TABLE queries ADD server INT; " ) . execute ( ) ;
db_version ( 5 ) ;
case 5 :
CREATE_TABLE ( " playlists " , " `serverId` INT NOT NULL, `playlist_id` INT " , command_append_utf8 ) ;
CREATE_INDEX ( " playlists " , " serverId " ) ;
CREATE_TABLE ( " playlist_songs " , " `serverId` INT NOT NULL, `playlist_id` INT, `song_id` INT, `order_id` INT, `invoker_dbid` INT, `url` TEXT, `url_loader` TEXT " , command_append_utf8 ) ;
CREATE_INDEX2R ( " playlist_songs " , " serverId " , " playlist_id " ) ;
db_version ( 6 ) ;
sql : : command ( this - > sql ( ) , " UPDATE `permissions ` SET `permId` = `b_client_music_create_temporary` WHERE `permId` = `b_client_music_create` " ) . execute ( ) ;
case 6 :
sql : : command ( this - > sql ( ) , " ALTER TABLE playlist_songs ADD loaded BOOL; " ) . execute ( ) ;
sql : : command ( this - > sql ( ) , " ALTER TABLE playlist_songs ADD metadata TEXT; " ) . execute ( ) ;
case 7 :
/* recreate permission table */
2020-05-09 16:55:15 +02:00
/*
DROP TABLE ` permissions ` , ` properties ` ;
ALTER TABLE permissions_v6 RENAME permissions ;
ALTER TABLE properties_v6 RENAME properties ;
*/
2019-07-17 19:37:18 +02:00
2020-01-24 02:57:58 +01:00
/* MySQL command
2019-07-17 19:37:18 +02:00
2020-05-09 16:55:15 +02:00
START TRANSACTION ;
SET SESSION sql_mode = ' STRICT_TRANS_TABLES , NO_ZERO_IN_DATE , NO_ZERO_DATE , ERROR_FOR_DIVISION_BY_ZERO , NO_AUTO_CREATE_USER , NO_ENGINE_SUBSTITUTION ' ;
- - Modify the permissions
ALTER TABLE permissions RENAME TO permissions_v6 ;
CREATE TABLE ` permissions ` ( ` serverId ` INT NOT NULL , ` type ` INT , ` id ` INT , ` channelId ` INT , ` permId ` VARCHAR ( 256 ) , ` value ` INT , ` grant ` INT , ` flag_skip ` TINYINT ( 1 ) , ` flag_negate ` TINYINT ( 1 ) , CONSTRAINT PK PRIMARY KEY ( ` serverId ` , ` type ` , ` id ` , ` channelId ` , ` permId ` ) ) CHARACTER SET = utf8 ;
CREATE INDEX ` idx_permissions_serverId ` ON ` permissions ` ( ` serverId ` ) ;
CREATE INDEX ` idx_permissions_serverId_channelId ` ON ` permissions ` ( ` serverId ` , ` channelId ` ) ;
INSERT INTO ` permissions ` SELECT * FROM ` permissions_v6 ` GROUP BY ` serverId ` , ` type ` , ` id ` , ` channelId ` , ` permId ` ;
- - Modify the properties
ALTER TABLE properties RENAME TO properties_v6 ;
CREATE TABLE properties ( ` serverId ` INTEGER DEFAULT - 1 , ` type ` INTEGER , ` id ` INTEGER , ` key ` VARCHAR ( 256 ) , ` value ` TEXT , CONSTRAINT PK PRIMARY KEY ( ` serverId ` , ` type ` , ` id ` , ` key ` ) ) CHARACTER SET = utf8 ;
CREATE INDEX ` idx_properties_serverId ` ON ` properties ` ( ` serverId ` ) ;
CREATE INDEX ` idx_properties_serverId_id ` ON ` properties ` ( ` serverId ` , ` id ` ) ;
INSERT INTO ` properties ` SELECT * FROM ` properties_v6 ` GROUP BY ` serverId ` , ` type ` , ` id ` , ` key ` ;
- - Delete orphaned permissions and properties
DELETE FROM ` permissions ` WHERE ( ` type ` = 1 OR ` type ` = 2 ) AND NOT ( ( ` serverId ` , ` channelId ` ) IN ( SELECT ` serverId ` , ` channelId ` FROM ` channels ` ) OR ` channelId ` = 0 ) ;
DELETE FROM ` permissions ` WHERE ` type ` = 0 AND NOT ( ` serverId ` , ` id ` ) IN ( SELECT ` serverId ` , ` groupId ` FROM ` groups ` ) ;
DELETE FROM ` permissions ` WHERE ` type ` = 2 AND NOT ( ` serverId ` , ` id ` ) IN ( SELECT ` serverId ` , ` cldbid ` FROM ` clients ` ) ;
DELETE FROM ` properties ` WHERE ` type ` = 1 AND NOT ( ` serverId ` IN ( SELECT ` serverId ` FROM servers ) OR ` serverId ` = 0 ) ;
ROLLBACK ;
2020-01-24 02:57:58 +01:00
*/
if ( manager - > getType ( ) = = sql : : TYPE_MYSQL ) {
/*
* FIXME implement update for MySQL as well !
auto mysql = ( sql : : mysql : : MySQLManager * ) this - > sql ( ) ;
if ( ! result ) {
error = " failed to update database ( " + result . fmtStr ( ) + " ) " ;
return false ;
}
*/
} else {
result = sql : : command ( this - > sql ( ) , " ALTER TABLE permissions RENAME TO permissions_v6; " ) . execute ( ) ;
if ( ! result ) {
error = " Failed to rename permission to permission v6 ( " + result . fmtStr ( ) + " ) " ;
return false ;
}
result = sql : : command ( this - > sql ( ) , " CREATE TABLE `permissions`(`serverId` INT NOT NULL, `type` INT, `id` INT, `channelId` INT, `permId` VARCHAR(256), `value` INT, `grant` INT, `flag_skip` BOOL, `flag_negate` BOOL, CONSTRAINT PK PRIMARY KEY(`serverId`, `type`, `id`, `channelId`, `permId`)); " ) . execute ( ) ;
if ( ! result ) {
error = " Failed to create new permission table ( " + result . fmtStr ( ) + " ) " ;
return false ;
}
result = sql : : command ( this - > sql ( ) , " INSERT INTO `permissions` SELECT * FROM `permissions_v6` GROUP BY `serverId`, `type`, `id`, `channelId`, `permId`; " ) . execute ( ) ;
if ( ! result ) {
error = " Failed to insert unique permissions ( " + result . fmtStr ( ) + " ) " ;
return false ;
}
2020-07-30 20:25:45 +02:00
DROP_INDEX ( " permissions " , " serverId " ) ;
DROP_INDEX2R ( " permissions " , " serverId " , " channelId " ) ;
2020-01-24 02:57:58 +01:00
CREATE_INDEX ( " permissions " , " serverId " ) ;
CREATE_INDEX2R ( " permissions " , " serverId " , " channelId " ) ;
/* recreate property table */
result = sql : : command ( this - > sql ( ) , " ALTER TABLE properties RENAME TO properties_v6; " ) . execute ( ) ;
if ( ! result ) {
error = " Failed to rename properties to properties v6 ( " + result . fmtStr ( ) + " ) " ;
return false ;
}
result = sql : : command ( this - > sql ( ) , " CREATE TABLE properties(`serverId` INTEGER DEFAULT -1, `type` INTEGER, `id` INTEGER, `key` VARCHAR(256), `value` TEXT, CONSTRAINT PK PRIMARY KEY (`serverId`, `type`, `id`, `key`)); " ) . execute ( ) ;
if ( ! result ) {
error = " Failed to create new properties table ( " + result . fmtStr ( ) + " ) " ;
return false ;
}
/*
SET SESSION sql_mode = ' STRICT_TRANS_TABLES , NO_ZERO_IN_DATE , NO_ZERO_DATE , ERROR_FOR_DIVISION_BY_ZERO , NO_AUTO_CREATE_USER , NO_ENGINE_SUBSTITUTION ' ;
INSERT INTO ` properties ` SELECT * FROM ` properties_v6 ` GROUP BY ` serverId ` , ` type ` , ` id ` , ` key ` ;
*/
result = sql : : command ( this - > sql ( ) , " INSERT INTO `properties` SELECT * FROM `properties_v6` GROUP BY `serverId`, `type`, `id`, `key`; " ) . execute ( ) ;
if ( ! result ) {
error = " Failed to insert unique properties ( " + result . fmtStr ( ) + " ) " ;
return false ;
}
2020-07-30 20:25:45 +02:00
DROP_INDEX ( " properties " , " serverId " ) ;
DROP_INDEX2R ( " properties " , " serverId " , " id " ) ;
2020-01-24 02:57:58 +01:00
CREATE_INDEX ( " properties " , " serverId " ) ;
CREATE_INDEX2R ( " properties " , " serverId " , " id " ) ;
/* SELECT * FROM `permissions` WHERE `type` = 1 AND (`serverId`, `channelId`) IN (SELECT `serverId`, `channelId` FROM `channels`) */
/* Channel permission cleanup: DELETE FROM `permissions` WHERE `type` = 1 AND NOT (`serverId`, `channelId`) IN (SELECT `serverId`, `channelId` FROM `channels`) */
sql : : command ( this - > sql ( ) , " DELETE FROM `permissions` WHERE (`type` = 1 OR `type` = 2) AND NOT ((`serverId`, `channelId`) IN (SELECT `serverId`, `channelId` FROM `channels`) OR `channelId` = 0); " ) . execute ( ) ;
sql : : command ( this - > sql ( ) , " DELETE FROM `permissions` WHERE `type` = 0 AND NOT (`serverId`, `id`) IN (SELECT `serverId`, `groupId` FROM `groups`); " ) . execute ( ) ;
sql : : command ( this - > sql ( ) , " DELETE FROM `permissions` WHERE `type` = 2 AND NOT (`serverId`, `id`) IN (SELECT `serverId`, `cldbid` FROM `clients`); " ) . execute ( ) ;
sql : : command ( this - > sql ( ) , " DELETE FROM `properties` WHERE `type` = 1 AND NOT (`serverId` IN (SELECT `serverId` FROM servers) OR `serverId` = 0); " ) . execute ( ) ;
}
db_version ( 8 ) ;
case 8 :
result = sql : : command ( this - > sql ( ) , " UPDATE `queries` SET `server` = 0 WHERE `server` IS NULL " ) . execute ( ) ;
if ( ! result ) {
error = " Failed to drop null query entries ( " + result . fmtStr ( ) + " ) " ;
return false ;
}
db_version ( 9 ) ;
case 9 :
//
//"UPDATE `permissions` SET `id` = :id WHERE `type` = :channel_type" ;permission::SQL_PERM_CHANNEL
result = sql : : command ( this - > sql ( ) , " UPDATE `permissions` SET `id` = :id WHERE `type` = :channel_type; " , variable { " :channel_type " , permission : : SQL_PERM_CHANNEL } , variable { " :id " , 0 } ) . execute ( ) ;
if ( ! result ) {
if ( result . code ( ) = = 1 ) { //constraint failed => duplicated ids for example
size_t count = 0 ;
result = sql : : command ( this - > sql ( ) , " SELECT COUNT(*) FROM `permissions` WHERE NOT `id` = :id AND `type` = :type " , variable { " :type " , permission : : SQL_PERM_CHANNEL } , variable { " :id " , 0 } ) . query ( [ & ] ( int , std : : string * values , std : : string * ) {
count = stoll ( values [ 0 ] ) ;
} ) ;
logError ( LOG_GENERAL , " Database contains invalid channel permissions. Deleting permissions ({}). " , count ) ;
result = sql : : command ( this - > sql ( ) , " DELETE FROM `permissions` WHERE NOT `id` = :id AND `type` = :type " , variable { " :channel_type " , permission : : SQL_PERM_CHANNEL } , variable { " :id " , 0 } ) . execute ( ) ;
}
if ( ! result ) {
error = " Failed to fix channel properties ( " + result . fmtStr ( ) + " ) " ;
return false ;
}
}
db_version ( 10 ) ;
case 10 :
CREATE_TABLE ( " conversations " , " `server_id` INT, `channel_id` INT, `conversation_id` INT, `file_path` TEXT " , command_append_utf8 ) ;
CREATE_TABLE ( " conversation_blocks " , " `server_id` INT, `conversation_id` INT, `begin_timestamp` INT, `end_timestamp` INT, `block_offset` INT, `flags` INT " , command_append_utf8 ) ;
CREATE_INDEX ( " conversations " , " server_id " ) ;
CREATE_INDEX2R ( " conversation_blocks " , " server_id " , " conversation_id " ) ;
db_version ( 11 ) ;
2020-04-14 11:49:07 +02:00
2020-05-09 16:55:15 +02:00
case 11 :
2020-05-09 19:56:10 +02:00
result = sql : : command ( this - > sql ( ) , " UPDATE `letters` SET `created` = 0 WHERE 1; " ) . execute ( ) ;
2020-05-09 16:55:15 +02:00
if ( ! result ) {
2020-05-09 19:56:10 +02:00
error = " Failed to reset offline messages timestamps ( " + result . fmtStr ( ) + " ) " ;
2020-05-09 16:55:15 +02:00
return false ;
}
db_version ( 12 ) ;
2020-07-30 20:25:45 +02:00
case 12 : {
constexpr static std : : string_view kCreateClientsV2 { R " (
CREATE TABLE ` clients_v2 ` (
2020-08-13 12:58:19 +02:00
` client_database_id ` INTEGER NOT NULL PRIMARY KEY [ AUTO_INCREMENT ] ,
2020-07-30 20:25:45 +02:00
` client_unique_id ` VARCHAR ( 40 ) UNIQUE ,
` client_created ` BIGINT ,
` client_login_name ` VARCHAR ( 20 ) UNIQUE
) ;
) " };
constexpr static std : : string_view kCreateClientsServer { R " (
CREATE TABLE ` clients_server ` (
` server_id ` INTEGER ,
` client_unique_id ` VARCHAR ( 40 ) NOT NULL ,
` client_database_id ` INTEGER NOT NULL ,
` client_nickname ` VARCHAR ( 128 ) ,
` client_ip ` VARCHAR ( 64 ) ,
` client_login_password ` VARCHAR ( 40 ) ,
` client_last_connected ` BIGINT DEFAULT 0 ,
` client_created ` BIGINT ,
` client_total_connections ` BIGINT DEFAULT 0 ,
` client_month_upload ` BIGINT DEFAULT 0 ,
` client_month_download ` BIGINT DEFAULT 0 ,
` client_total_upload ` BIGINT DEFAULT 0 ,
` client_total_download ` BIGINT DEFAULT 0 ,
` original_client_id ` BIGINT DEFAULT 0 ,
PRIMARY KEY ( ` server_id ` , ` client_database_id ` )
) ;
) " };
constexpr static std : : string_view kInsertClientsGlobal { " [INSERT_OR_IGNORE] INTO `clients_v2` (`client_database_id`, `client_unique_id`, `client_created`) SELECT `cldbid`, `clientUid`, `firstConnect` FROM `clients` WHERE `serverId` = 0; " } ;
constexpr static std : : string_view kInsertClientsServer { R " (
[ INSERT_OR_IGNORE ] INTO ` clients_server ` ( ` server_id ` , ` client_unique_id ` , ` client_database_id ` , ` client_nickname ` , ` client_created ` , ` client_last_connected ` , ` client_total_connections ` )
SELECT ` serverId ` , ` clientUid ` , ` cldbid ` , ` lastName ` , ` firstConnect ` , ` lastConnect ` , ` connections ` FROM ` clients ` ;
) " };
constexpr static std : : array < std : : string_view , 11 > kUpdateCommands {
kCreateClientsV2 ,
kCreateClientsServer ,
kInsertClientsGlobal ,
kInsertClientsServer ,
" CREATE INDEX `idx_clients_unique_id` ON `clients_v2` (`client_unique_id`); " ,
" CREATE INDEX `idx_clients_database_id` ON `clients_v2` (`client_database_id`); " ,
" CREATE INDEX `idx_clients_login` ON `clients_v2` (`client_login_name`); " ,
" CREATE INDEX `idx_clients_server_server_unique` ON `clients_server` (`server_id`, `client_unique_id`); " ,
" CREATE INDEX `idx_clients_server_server_database` ON `clients_server` (`server_id`, `client_database_id`); " ,
" DROP TABLE `clients`; " ,
" ALTER TABLE `clients_v2` RENAME TO `clients`; " ,
} ;
if ( ! execute_commands ( this - > sql ( ) , error , kUpdateCommands ) )
return false ;
db_version ( 13 ) ;
}
case 13 : {
2020-07-31 17:35:14 +02:00
constexpr static std : : array < std : : string_view , 8 > kUpdateCommands {
2020-07-30 20:25:45 +02:00
" CREATE INDEX `idx_properties_serverid_id_value` ON `properties` (`serverId`, `id`, `key`); " ,
2020-07-31 17:35:14 +02:00
" CREATE INDEX `idx_properties_serverid_id_type` ON `properties` (`serverId`, `id`, `type`); " ,
2020-07-30 20:25:45 +02:00
2020-08-13 12:58:19 +02:00
" CREATE TABLE `groups_v2` (`serverId` INT NOT NULL, `groupId` INTEGER NOT NULL PRIMARY KEY [AUTO_INCREMENT], `target` INT, `type` INT, `displayName` VARCHAR(128), `original_group_id` INTEGER); " ,
2020-07-30 20:25:45 +02:00
" INSERT INTO `groups_v2` (`serverId`, `groupId`, `target`, `type`, `displayName`) SELECT `serverId`, `groupId`, `target`, `type`, `displayName` FROM `groups`; " ,
" DROP TABLE `groups`; " ,
" ALTER TABLE `groups_v2` RENAME TO groups; " ,
2020-07-31 17:35:14 +02:00
" CREATE INDEX `idx_groups_serverId_groupId` ON `groups` (`serverId`); " ,
" CREATE INDEX `idx_groups_serverid` ON `groups` (`serverId`, `groupId`); "
2020-07-30 20:25:45 +02:00
} ;
if ( ! execute_commands ( this - > sql ( ) , error , kUpdateCommands ) )
return false ;
db_version ( 14 ) ;
}
2020-01-24 02:57:58 +01:00
default :
break ;
}
auto timestamp_end = system_clock : : now ( ) ;
logMessage ( LOG_GENERAL , " Database upgrade took {}ms " , duration_cast < milliseconds > ( timestamp_end - timestamp_start ) . count ( ) ) ;
}
return true ;
2019-08-16 16:13:52 +02:00
}
bool SqlDataManager : : update_permissions ( std : : string & error ) {
2020-01-24 02:57:58 +01:00
if ( this - > _permissions_version ! = CURRENT_PERMISSION_VERSION ) {
sql : : result result ;
auto timestamp_start = system_clock : : now ( ) ;
logMessage ( LOG_GENERAL , " Upgrading permissions from version " + to_string ( this - > _permissions_version ) + " to " + to_string ( CURRENT_PERMISSION_VERSION ) + " . This could take a moment! " ) ;
const auto auto_update = [ & ] ( permission : : update : : GroupUpdateType update_type , const std : : string & permission , permission : : v2 : : PermissionFlaggedValue value , bool skip , bool negate , permission : : v2 : : PermissionFlaggedValue granted ) {
/*
INSERT [ OR IGNORE | IGNORE ] INTO ` perms ` ( serverId , type , id , channelId , permId , value , grant , flag_skip , flag_negate )
SELECT DISTINCT ` permissions ` . ` serverId ` , 0 , ` groupId ` , 0 , : name , : value , : grant , : skip , : negate FROM groups
INNER JOIN ` permissions `
ON permissions . permId = ' i_group_auto_update_type ' AND permissions . channelId = 0 AND permissions . id = groups . groupId AND permissions . serverId = groups . serverId AND permissions . value = : update_type ;
*/
std : : string query = " INSERT " ;
if ( this - > sql ( ) - > getType ( ) = = sql : : TYPE_MYSQL )
query + = " IGNORE " ;
else
query + = " OR IGNORE " ;
query + = " INTO `permissions` (`serverId`, `type`, `id`, `channelId`, `permId`, `value`, `grant`, `flag_skip`, `flag_negate`) " ;
2020-03-30 22:53:15 +02:00
query + = string ( ) + " SELECT DISTINCT `permissions`.`serverId`, `permissions`.`type`, `groupId`, `permissions`.`channelId`, "
2020-01-24 02:57:58 +01:00
+ " ' " + permission + " ', "
+ to_string ( value . has_value ? value . value : - 2 ) + " , "
+ to_string ( granted . has_value ? granted . value : - 2 ) + " , "
+ to_string ( skip ) + " , "
+ to_string ( negate ) + " FROM groups " ;
query + = " INNER JOIN `permissions` " ;
2020-03-30 22:53:15 +02:00
query + = " ON permissions.permId = 'i_group_auto_update_type' AND permissions.id = groups.groupId AND permissions.serverId = groups.serverId AND permissions.value = " + to_string ( update_type ) ;
2020-01-24 02:57:58 +01:00
logTrace ( LOG_GENERAL , " Executing sql update: {} " , query ) ;
auto result = sql : : command ( this - > sql ( ) , query ) . execute ( ) ;
if ( ! result ) {
error = " failed to auto update permission " + permission + " for type " + to_string ( update_type ) + " : " + result . fmtStr ( ) ;
return false ;
}
return true ;
} ;
switch ( this - > _permissions_version ) {
case - 1 :
/* initial setup, or first introduce of 1.4.0. Default stuff will be loaded from the template file so we only run updates here */
if ( ! auto_update ( permission : : update : : QUERY_ADMIN , " b_client_is_priority_speaker " , { - 2 , false } , false , false , { 100 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : QUERY_ADMIN , " b_virtualserver_modify_country_code " , { 1 , true } , false , false , { 100 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : QUERY_ADMIN , " b_channel_ignore_subscribe_power " , { 1 , true } , false , false , { 100 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : QUERY_ADMIN , " b_channel_ignore_description_view_power " , { 1 , true } , false , false , { 100 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : QUERY_ADMIN , " i_max_playlist_size " , { 1 , false } , false , false , { 100 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : QUERY_ADMIN , " i_max_playlists " , { 1 , false } , false , false , { 100 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : QUERY_ADMIN , " i_channel_create_modify_conversation_history_length " , { 1 , false } , false , false , { 100 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : QUERY_ADMIN , " b_channel_create_modify_conversation_history_unlimited " , { 1 , true } , false , false , { 100 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : QUERY_ADMIN , " b_channel_create_modify_conversation_private " , { 1 , true } , false , false , { 100 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : QUERY_ADMIN , " b_channel_conversation_message_delete " , { 1 , true } , false , false , { 100 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : SERVER_ADMIN , " b_client_is_priority_speaker " , { - 2 , false } , false , false , { 75 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : SERVER_ADMIN , " b_virtualserver_modify_country_code " , { 1 , true } , false , false , { 75 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : SERVER_ADMIN , " b_channel_ignore_subscribe_power " , { 1 , true } , false , false , { 75 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : SERVER_ADMIN , " b_channel_ignore_description_view_power " , { 1 , true } , false , false , { 75 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : SERVER_ADMIN , " i_max_playlist_size " , { 1 , false } , false , false , { 75 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : SERVER_ADMIN , " i_max_playlists " , { 1 , false } , false , false , { 75 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : SERVER_ADMIN , " i_channel_create_modify_conversation_history_length " , { 1 , false } , false , false , { 75 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : SERVER_ADMIN , " b_channel_create_modify_conversation_history_unlimited " , { 1 , true } , false , false , { 75 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : SERVER_ADMIN , " b_channel_create_modify_conversation_private " , { 1 , true } , false , false , { 75 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : SERVER_ADMIN , " b_channel_conversation_message_delete " , { 1 , true } , false , false , { 75 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : SERVER_NORMAL , " i_max_playlist_size " , { 50 , true } , false , false , { - 2 , false } ) )
return false ;
if ( ! auto_update ( permission : : update : : SERVER_NORMAL , " i_channel_create_modify_conversation_history_length " , { 15000 , true } , false , false , { - 2 , false } ) )
return false ;
if ( ! auto_update ( permission : : update : : SERVER_GUEST , " i_max_playlist_size " , { 10 , true } , false , false , { - 2 , false } ) )
return false ;
perm_version ( 0 ) ;
case 0 :
result = sql : : command ( this - > sql ( ) , " DELETE FROM `permissions` WHERE `permId` = :permid " , variable { " :permid " , " b_client_music_create " } ) . execute ( ) ;
if ( ! result ) {
LOG_SQL_CMD ( result ) ;
return false ;
}
result = sql : : command ( this - > sql ( ) , " DELETE FROM `permissions` WHERE `permId` = :permid " , variable { " :permid " , " b_client_music_delete_own " } ) . execute ( ) ;
if ( ! result ) {
LOG_SQL_CMD ( result ) ;
return false ;
}
perm_version ( 1 ) ;
2020-02-21 20:32:25 +01:00
case 1 :
if ( ! auto_update ( permission : : update : : SERVER_ADMIN , " i_playlist_song_move_power " , { 75 , true } , false , false , { 75 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : QUERY_ADMIN , " i_playlist_song_move_power " , { 100 , true } , false , false , { 100 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : SERVER_ADMIN , " i_playlist_song_needed_move_power " , { 0 , false } , false , false , { 75 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : QUERY_ADMIN , " i_playlist_song_needed_move_power " , { 0 , false } , false , false , { 100 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : SERVER_ADMIN , " b_channel_conversation_message_delete " , { 1 , true } , false , false , { 75 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : QUERY_ADMIN , " b_channel_conversation_message_delete " , { 1 , true } , false , false , { 100 , true } ) )
return false ;
perm_version ( 2 ) ;
2020-03-30 22:53:15 +02:00
case 2 :
if ( ! auto_update ( permission : : update : : SERVER_ADMIN , " b_client_query_create_own " , { 1 , true } , false , false , { 75 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : QUERY_ADMIN , " b_client_query_create_own " , { 1 , true } , false , false , { 100 , true } ) )
return false ;
/* for some reason some users haven't received these updates from last time */
if ( ! auto_update ( permission : : update : : SERVER_ADMIN , " i_playlist_song_move_power " , { 75 , true } , false , false , { 75 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : QUERY_ADMIN , " i_playlist_song_move_power " , { 100 , true } , false , false , { 100 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : SERVER_ADMIN , " i_playlist_song_needed_move_power " , { 0 , false } , false , false , { 75 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : QUERY_ADMIN , " i_playlist_song_needed_move_power " , { 0 , false } , false , false , { 100 , true } ) )
return false ;
perm_version ( 3 ) ;
2020-04-24 22:04:07 +02:00
case 3 :
if ( ! auto_update ( permission : : update : : SERVER_ADMIN , " i_client_poke_max_clients " , { 20 , true } , false , false , { 75 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : QUERY_ADMIN , " i_client_poke_max_clients " , { 50 , true } , false , false , { 100 , true } ) )
return false ;
if ( ! auto_update ( permission : : update : : SERVER_NORMAL , " i_client_poke_max_clients " , { 5 , true } , false , false , { 0 , false } ) )
return false ;
perm_version ( 4 ) ;
2020-01-24 02:57:58 +01:00
default :
break ;
}
auto timestamp_end = system_clock : : now ( ) ;
logMessage ( LOG_GENERAL , " Permission upgrade took {}ms " , duration_cast < milliseconds > ( timestamp_end - timestamp_start ) . count ( ) ) ;
}
return true ;
2019-07-17 19:37:18 +02:00
}
void SqlDataManager : : finalize ( ) {
2020-01-24 02:57:58 +01:00
if ( this - > manager ) this - > manager - > disconnect ( ) ;
delete this - > manager ;
this - > manager = nullptr ;
2019-07-17 19:37:18 +02:00
}
2019-08-16 16:13:52 +02:00
bool SqlDataManager : : detect_versions ( ) {
2020-01-24 02:57:58 +01:00
auto result = sql : : command ( this - > manager , " SELECT `value` FROM `general` WHERE `key`= :key " , variable { " :key " , " data_version " } ) . query ( [ & ] ( int length , char * * values , char * * ) {
this - > _database_version = atoi ( values [ 0 ] ) ;
this - > database_version_present = true ;
return 0 ;
} ) ;
result = sql : : command ( this - > manager , " SELECT `value` FROM `general` WHERE `key`= :key " , variable { " :key " , " permissions_version " } ) . query ( [ & ] ( int length , char * * values , char * * ) {
this - > _permissions_version = atoi ( values [ 0 ] ) ;
this - > permissions_version_present = true ;
return 0 ;
} ) ;
return true ;
2019-07-17 19:37:18 +02:00
}
2019-08-16 16:13:52 +02:00
bool SqlDataManager : : change_database_version ( int version ) {
2020-01-24 02:57:58 +01:00
string command ;
if ( this - > database_version_present )
command = " UPDATE `general` SET `value`= :version WHERE `key`= :key; " ;
else
command = " INSERT INTO `general` (`key`, `value`) VALUES (:key, :version); " ;
auto result = sql : : command ( this - > manager , command , variable { " :version " , version } , variable { " :key " , " data_version " } ) . execute ( ) ;
if ( ! result ) {
logError ( LOG_INSTANCE , " Could not update SQL database version. ( " + result . fmtStr ( ) + " ) " ) ;
return false ;
}
this - > database_version_present = true ;
this - > _database_version = version ;
return true ;
2019-08-16 16:13:52 +02:00
}
bool SqlDataManager : : change_permission_version ( int version ) {
2020-01-24 02:57:58 +01:00
string command ;
if ( this - > permissions_version_present )
command = " UPDATE `general` SET `value`= :version WHERE `key`= :key; " ;
else
command = " INSERT INTO `general` (`key`, `value`) VALUES (:key, :version); " ;
auto result = sql : : command ( this - > manager , command , variable { " :version " , version } , variable { " :key " , " permissions_version " } ) . execute ( ) ;
if ( ! result ) {
logError ( LOG_INSTANCE , " Could not update SQL permissions version. ( " + result . fmtStr ( ) + " ) " ) ;
return false ;
}
this - > permissions_version_present = true ;
this - > _permissions_version = version ;
return true ;
2019-07-17 19:37:18 +02:00
}