Drafting Scheduler

Scheduler is being implemented as part of the Admin module.
Added table scheduler
Added table runtime_scheduler
Implemented commands:
- [LAD|SAVE] SCHEDULER [FROM|TO] [DISK|MEMORY|RUNTIME]
connleak
René Cannaò 10 years ago
parent 817a92b260
commit bda2cf4350

@ -6,6 +6,37 @@
typedef struct { uint32_t hash; uint32_t key; } t_symstruct;
class Scheduler_Row {
public:
unsigned int id;
unsigned int interval_ms;
unsigned long long last;
unsigned long long next;
char *filename;
// char *arg1;
// char *arg2;
// char *arg3;
// char *arg4;
// char *arg5;
char **args;
Scheduler_Row(unsigned int _id, unsigned int _in, char *_f, char *a1, char *a2, char *a3, char *a4, char *a5);
~Scheduler_Row();
};
class ProxySQL_External_Scheduler {
public:
rwlock_t rwlock;
std::vector<Scheduler_Row *> Scheduler_Rows;
ProxySQL_External_Scheduler();
~ProxySQL_External_Scheduler();
void run_once();
void update_table(SQLite3_result *result);
};
class ProxySQL_Admin {
private:
volatile int main_shutdown;
@ -39,6 +70,8 @@ class ProxySQL_Admin {
#endif /* DEBUG */
} variables;
ProxySQL_External_Scheduler *scheduler;
void dump_mysql_collations();
void insert_into_tables_defs(std::vector<table_def_t *> *, const char *table_name, const char *table_def);
void drop_tables_defs(std::vector<table_def_t *> *tables_defs);
@ -122,6 +155,11 @@ class ProxySQL_Admin {
char * load_mysql_query_rules_to_runtime();
void save_mysql_query_rules_from_runtime(bool);
void load_scheduler_to_runtime();
void save_scheduler_runtime_to_database(bool);
void flush_scheduler__from_memory_to_disk();
void flush_scheduler__from_disk_to_memory();
void load_admin_variables_to_runtime() { flush_admin_variables___database_to_runtime(admindb, true); }
void save_admin_variables_from_runtime() { flush_admin_variables___runtime_to_database(admindb, true, true, false); }

@ -96,12 +96,16 @@ pthread_mutex_t admin_mutex = PTHREAD_MUTEX_INITIALIZER;
#define ADMIN_SQLITE_TABLE_MYSQL_COLLATIONS "CREATE TABLE mysql_collations (Id INTEGER NOT NULL PRIMARY KEY , Collation VARCHAR NOT NULL , Charset VARCHAR NOT NULL , `Default` VARCHAR NOT NULL)"
#define ADMIN_SQLITE_TABLE_SCHEDULER "CREATE TABLE scheduler (id INTEGER NOT NULL , interval_ms INTEGER CHECK (interval_ms>=100 AND interval_ms<=100000000) NOT NULL , filename VARCHAR NOT NULL , arg1 VARCHAR , arg2 VARCHAR , arg3 VARCHAR , arg4 VARCHAR , arg5 VARCHAR , PRIMARY KEY(id))"
#define ADMIN_SQLITE_TABLE_RUNTIME_MYSQL_SERVERS "CREATE TABLE runtime_mysql_servers (hostgroup_id INT NOT NULL DEFAULT 0 , hostname VARCHAR NOT NULL , port INT NOT NULL DEFAULT 3306 , status VARCHAR CHECK (UPPER(status) IN ('ONLINE','SHUNNED','OFFLINE_SOFT', 'OFFLINE_HARD')) NOT NULL DEFAULT 'ONLINE' , weight INT CHECK (weight >= 0) NOT NULL DEFAULT 1 , compression INT CHECK (compression >=0 AND compression <= 102400) NOT NULL DEFAULT 0 , max_connections INT CHECK (max_connections >=0) NOT NULL DEFAULT 1000 , max_replication_lag INT CHECK (max_replication_lag >= 0 AND max_replication_lag <= 126144000) NOT NULL DEFAULT 0 , use_ssl INT CHECK (use_ssl IN(0,1)) NOT NULL DEFAULT 0 , max_latency_ms INT UNSIGNED CHECK (max_latency_ms>=0) NOT NULL DEFAULT 0 , PRIMARY KEY (hostgroup_id, hostname, port) )"
#define ADMIN_SQLITE_TABLE_RUNTIME_MYSQL_REPLICATION_HOSTGROUPS "CREATE TABLE runtime_mysql_replication_hostgroups (writer_hostgroup INT CHECK (writer_hostgroup>=0) NOT NULL PRIMARY KEY , reader_hostgroup INT NOT NULL CHECK (reader_hostgroup<>writer_hostgroup AND reader_hostgroup>0) , UNIQUE (reader_hostgroup))"
#define ADMIN_SQLITE_TABLE_RUNTIME_MYSQL_QUERY_RULES "CREATE TABLE runtime_mysql_query_rules (rule_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL , active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 0 , username VARCHAR , schemaname VARCHAR , flagIN INT NOT NULL DEFAULT 0 , client_addr VARCHAR , proxy_addr VARCHAR , proxy_port INT , digest VARCHAR , match_digest VARCHAR , match_pattern VARCHAR , negate_match_pattern INT CHECK (negate_match_pattern IN (0,1)) NOT NULL DEFAULT 0 , flagOUT INT , replace_pattern VARCHAR , destination_hostgroup INT DEFAULT NULL , cache_ttl INT CHECK(cache_ttl > 0) , reconnect INT CHECK (reconnect IN (0,1)) DEFAULT NULL , timeout INT UNSIGNED , retries INT CHECK (retries>=0 AND retries <=1000) , delay INT UNSIGNED , mirror_flagOUT INT UNSIGNED , mirror_hostgroup INT UNSIGNED , error_msg VARCHAR , log INT CHECK (log IN (0,1)) , apply INT CHECK(apply IN (0,1)) NOT NULL DEFAULT 0)"
#define ADMIN_SQLITE_TABLE_RUNTIME_SCHEDULER "CREATE TABLE runtime_scheduler (id INTEGER NOT NULL , interval_ms INTEGER CHECK (interval_ms>=100 AND interval_ms<=100000000) NOT NULL , filename VARCHAR NOT NULL , arg1 VARCHAR , arg2 VARCHAR , arg3 VARCHAR , arg4 VARCHAR , arg5 VARCHAR , PRIMARY KEY(id))"
#define STATS_SQLITE_TABLE_MYSQL_QUERY_RULES "CREATE TABLE stats_mysql_query_rules (rule_id INTEGER PRIMARY KEY , hits INT NOT NULL)"
#define STATS_SQLITE_TABLE_MYSQL_COMMANDS_COUNTERS "CREATE TABLE stats_mysql_commands_counters (Command VARCHAR NOT NULL PRIMARY KEY , Total_Time_us INT NOT NULL , Total_cnt INT NOT NULL , cnt_100us INT NOT NULL , cnt_500us INT NOT NULL , cnt_1ms INT NOT NULL , cnt_5ms INT NOT NULL , cnt_10ms INT NOT NULL , cnt_50ms INT NOT NULL , cnt_100ms INT NOT NULL , cnt_500ms INT NOT NULL , cnt_1s INT NOT NULL , cnt_5s INT NOT NULL , cnt_10s INT NOT NULL , cnt_INFs)"
#define STATS_SQLITE_TABLE_MYSQL_PROCESSLIST "CREATE TABLE stats_mysql_processlist (ThreadID INT NOT NULL , SessionID INTEGER PRIMARY KEY , user VARCHAR , db VARCHAR , cli_host VARCHAR , cli_port VARCHAR , hostgroup VARCHAR , l_srv_host VARCHAR , l_srv_port VARCHAR , srv_host VARCHAR , srv_port VARCHAR , command VARCHAR , time_ms INT NOT NULL , info VARCHAR)"
@ -599,6 +603,102 @@ bool admin_handler_command_load_or_save(char *query_no_space, unsigned int query
}
#endif /* DEBUG */
if ((query_no_space_length>15) && ( (!strncasecmp("SAVE SCHEDULER ", query_no_space, 15)) || (!strncasecmp("LOAD SCHEDULER ", query_no_space, 15))) ) {
if (
(query_no_space_length==strlen("LOAD SCHEDULER TO MEMORY") && !strncasecmp("LOAD SCHEDULER TO MEMORY",query_no_space, query_no_space_length))
||
(query_no_space_length==strlen("LOAD SCHEDULER TO MEM") && !strncasecmp("LOAD SCHEDULER TO MEM",query_no_space, query_no_space_length))
||
(query_no_space_length==strlen("LOAD SCHEDULER FROM DISK") && !strncasecmp("LOAD SCHEDULER FROM DISK",query_no_space, query_no_space_length))
) {
proxy_info("Received %s command\n", query_no_space);
ProxySQL_Admin *SPA=(ProxySQL_Admin *)pa;
SPA->flush_scheduler__from_disk_to_memory();
proxy_debug(PROXY_DEBUG_ADMIN, 4, "Loading scheduler to to MEMORY\n");
SPA->send_MySQL_OK(&sess->client_myds->myprot, NULL);
return false;
}
if (
(query_no_space_length==strlen("SAVE SCHEDULER FROM MEMORY") && !strncasecmp("SAVE SCHEDULER FROM MEMORY",query_no_space, query_no_space_length))
||
(query_no_space_length==strlen("SAVE SCHEDULER FROM MEM") && !strncasecmp("SAVE SCHEDULER FROM MEM",query_no_space, query_no_space_length))
||
(query_no_space_length==strlen("SAVE SCHEDULER TO DISK") && !strncasecmp("SAVE SCHEDULER TO DISK",query_no_space, query_no_space_length))
) {
proxy_info("Received %s command\n", query_no_space);
ProxySQL_Admin *SPA=(ProxySQL_Admin *)pa;
SPA->flush_scheduler__from_memory_to_disk();
proxy_debug(PROXY_DEBUG_ADMIN, 4, "Saving scheduler to DISK\n");
SPA->send_MySQL_OK(&sess->client_myds->myprot, NULL);
return false;
}
if (
(query_no_space_length==strlen("LOAD SCHEDULER FROM MEMORY") && !strncasecmp("LOAD SCHEDULER FROM MEMORY",query_no_space, query_no_space_length))
||
(query_no_space_length==strlen("LOAD SCHEDULER FROM MEM") && !strncasecmp("LOAD SCHEDULER FROM MEM",query_no_space, query_no_space_length))
||
(query_no_space_length==strlen("LOAD SCHEDULER TO RUNTIME") && !strncasecmp("LOAD SCHEDULER TO RUNTIME",query_no_space, query_no_space_length))
||
(query_no_space_length==strlen("LOAD SCHEDULER TO RUN") && !strncasecmp("LOAD SCHEDULER TO RUN",query_no_space, query_no_space_length))
) {
proxy_info("Received %s command\n", query_no_space);
ProxySQL_Admin *SPA=(ProxySQL_Admin *)pa;
SPA->load_scheduler_to_runtime();
proxy_debug(PROXY_DEBUG_ADMIN, 4, "Loaded scheduler to RUNTIME\n");
SPA->send_MySQL_OK(&sess->client_myds->myprot, NULL);
return false;
}
/* FIXME: not implemented yet!!
if (
(query_no_space_length==strlen("LOAD SCHEDULER FROM CONFIG") && !strncasecmp("LOAD SCHEDULER FROM CONFIG",query_no_space, query_no_space_length))
) {
proxy_info("Received %s command\n", query_no_space);
if (GloVars.configfile_open) {
proxy_debug(PROXY_DEBUG_ADMIN, 4, "Loading from file %s\n", GloVars.config_file);
if (GloVars.confFile->OpenFile(NULL)==true) {
ProxySQL_Admin *SPA=(ProxySQL_Admin *)pa;
int rows=0;
rows=SPA->Read_Scheduler_from_configfile();
proxy_debug(PROXY_DEBUG_ADMIN, 4, "Loaded scheduler from CONFIG\n");
SPA->send_MySQL_OK(&sess->client_myds->myprot, NULL, rows);
GloVars.confFile->CloseFile();
} else {
proxy_debug(PROXY_DEBUG_ADMIN, 4, "Unable to open or parse config file %s\n", GloVars.config_file);
char *s=(char *)"Unable to open or parse config file %s";
char *m=(char *)malloc(strlen(s)+strlen(GloVars.config_file)+1);
sprintf(m,s,GloVars.config_file);
SPA->send_MySQL_ERR(&sess->client_myds->myprot, m);
free(m);
}
} else {
proxy_debug(PROXY_DEBUG_ADMIN, 4, "Unknown config file\n");
SPA->send_MySQL_ERR(&sess->client_myds->myprot, (char *)"Config file unknown");
}
return false;
}
*/
if (
(query_no_space_length==strlen("SAVE SCHEDULER TO MEMORY") && !strncasecmp("SAVE SCHEDULER TO MEMORY",query_no_space, query_no_space_length))
||
(query_no_space_length==strlen("SAVE SCHEDULER TO MEM") && !strncasecmp("SAVE SCHEDULER TO MEM",query_no_space, query_no_space_length))
||
(query_no_space_length==strlen("SAVE SCHEDULER FROM RUNTIME") && !strncasecmp("SAVE SCHEDULER FROM RUNTIME",query_no_space, query_no_space_length))
||
(query_no_space_length==strlen("SAVE SCHEDULER FROM RUN") && !strncasecmp("SAVE SCHEDULER FROM RUN",query_no_space, query_no_space_length))
) {
proxy_info("Received %s command\n", query_no_space);
ProxySQL_Admin *SPA=(ProxySQL_Admin *)pa;
SPA->save_scheduler_runtime_to_database(false);
proxy_debug(PROXY_DEBUG_ADMIN, 4, "Saved scheduler from RUNTIME\n");
SPA->send_MySQL_OK(&sess->client_myds->myprot, NULL);
return false;
}
}
if ((query_no_space_length>17) && ( (!strncasecmp("SAVE MYSQL USERS ", query_no_space, 17)) || (!strncasecmp("LOAD MYSQL USERS ", query_no_space, 17))) ) {
if (
@ -1065,6 +1165,7 @@ void ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign
bool stats_mysql_global=false;
bool dump_global_variables=false;
bool runtime_scheduler=false;
bool runtime_mysql_servers=false;
bool runtime_mysql_query_rules=false;
@ -1096,6 +1197,9 @@ void ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign
if (strstr(query_no_space,"runtime_mysql_query_rules")) {
runtime_mysql_query_rules=true; refresh=true;
}
if (strstr(query_no_space,"runtime_scheduler")) {
runtime_scheduler=true; refresh=true;
}
}
}
// if (stats_mysql_processlist || stats_mysql_connection_pool || stats_mysql_query_digest || stats_mysql_query_digest_reset) {
@ -1125,6 +1229,9 @@ void ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign
if (runtime_mysql_query_rules) {
save_mysql_query_rules_from_runtime(true);
}
if (runtime_scheduler) {
save_scheduler_runtime_to_database(true);
}
}
pthread_mutex_unlock(&admin_mutex);
}
@ -2166,6 +2273,8 @@ ProxySQL_Admin::ProxySQL_Admin() {
#ifdef DEBUG
variables.debug=GloVars.global.gdbg;
#endif /* DEBUG */
// create the scheduler
scheduler=new ProxySQL_External_Scheduler();
};
void ProxySQL_Admin::wrlock() {
@ -2240,6 +2349,8 @@ bool ProxySQL_Admin::init() {
insert_into_tables_defs(tables_defs_admin,"runtime_mysql_query_rules", ADMIN_SQLITE_TABLE_RUNTIME_MYSQL_QUERY_RULES);
insert_into_tables_defs(tables_defs_admin,"global_variables", ADMIN_SQLITE_TABLE_GLOBAL_VARIABLES);
insert_into_tables_defs(tables_defs_admin,"mysql_collations", ADMIN_SQLITE_TABLE_MYSQL_COLLATIONS);
insert_into_tables_defs(tables_defs_admin,"scheduler", ADMIN_SQLITE_TABLE_SCHEDULER);
insert_into_tables_defs(tables_defs_admin,"runtime_scheduler", ADMIN_SQLITE_TABLE_RUNTIME_SCHEDULER);
#ifdef DEBUG
insert_into_tables_defs(tables_defs_admin,"debug_levels", ADMIN_SQLITE_TABLE_DEBUG_LEVELS);
#endif /* DEBUG */
@ -2250,6 +2361,7 @@ bool ProxySQL_Admin::init() {
insert_into_tables_defs(tables_defs_config,"mysql_query_rules", ADMIN_SQLITE_TABLE_MYSQL_QUERY_RULES);
insert_into_tables_defs(tables_defs_config,"global_variables", ADMIN_SQLITE_TABLE_GLOBAL_VARIABLES);
insert_into_tables_defs(tables_defs_config,"mysql_collations", ADMIN_SQLITE_TABLE_MYSQL_COLLATIONS);
insert_into_tables_defs(tables_defs_config,"scheduler", ADMIN_SQLITE_TABLE_SCHEDULER);
#ifdef DEBUG
insert_into_tables_defs(tables_defs_config,"debug_levels", ADMIN_SQLITE_TABLE_DEBUG_LEVELS);
#endif /* DEBUG */
@ -2381,6 +2493,10 @@ void ProxySQL_Admin::admin_shutdown() {
shutdown(pipefd[1],SHUT_RDWR);
close(pipefd[0]);
close(pipefd[1]);
// delete the scheduler
delete scheduler;
scheduler=NULL;
};
ProxySQL_Admin::~ProxySQL_Admin() {
@ -3203,6 +3319,7 @@ void ProxySQL_Admin::__insert_or_ignore_maintable_select_disktable() {
admindb->execute("INSERT OR IGNORE INTO main.mysql_users SELECT * FROM disk.mysql_users");
admindb->execute("INSERT OR IGNORE INTO main.mysql_query_rules SELECT * FROM disk.mysql_query_rules");
admindb->execute("INSERT OR IGNORE INTO main.global_variables SELECT * FROM disk.global_variables");
admindb->execute("INSERT OR IGNORE INTO main.scheduler SELECT * FROM disk.scheduler");
#ifdef DEBUG
admindb->execute("INSERT OR IGNORE INTO main.debug_levels SELECT * FROM disk.debug_levels");
#endif /* DEBUG */
@ -3216,6 +3333,7 @@ void ProxySQL_Admin::__insert_or_replace_maintable_select_disktable() {
admindb->execute("INSERT OR REPLACE INTO main.mysql_users SELECT * FROM disk.mysql_users");
admindb->execute("INSERT OR REPLACE INTO main.mysql_query_rules SELECT * FROM disk.mysql_query_rules");
admindb->execute("INSERT OR REPLACE INTO main.global_variables SELECT * FROM disk.global_variables");
admindb->execute("INSERT OR REPLACE INTO main.scheduler SELECT * FROM disk.scheduler");
#ifdef DEBUG
admindb->execute("INSERT OR IGNORE INTO main.debug_levels SELECT * FROM disk.debug_levels");
#endif /* DEBUG */
@ -3228,6 +3346,7 @@ void ProxySQL_Admin::__delete_disktable() {
admindb->execute("DELETE FROM disk.mysql_users");
admindb->execute("DELETE FROM disk.mysql_query_rules");
admindb->execute("DELETE FROM disk.global_variables");
admindb->execute("DELETE FROM disk.scheduler");
#ifdef DEBUG
admindb->execute("DELETE FROM disk.debug_levels");
#endif /* DEBUG */
@ -3240,6 +3359,7 @@ void ProxySQL_Admin::__insert_or_replace_disktable_select_maintable() {
admindb->execute("INSERT OR REPLACE INTO disk.mysql_users SELECT * FROM main.mysql_users");
admindb->execute("INSERT OR REPLACE INTO disk.mysql_query_rules SELECT * FROM main.mysql_query_rules");
admindb->execute("INSERT OR REPLACE INTO disk.global_variables SELECT * FROM main.global_variables");
admindb->execute("INSERT OR REPLACE INTO disk.scheduler SELECT * FROM main.scheduler");
#ifdef DEBUG
admindb->execute("INSERT OR REPLACE INTO disk.debug_levels SELECT * FROM main.debug_levels");
#endif /* DEBUG */
@ -3264,6 +3384,20 @@ void ProxySQL_Admin::flush_mysql_users__from_memory_to_disk() {
admindb->wrunlock();
}
void ProxySQL_Admin::flush_scheduler__from_disk_to_memory() {
admindb->wrlock();
admindb->execute("DELETE FROM main.scheduler");
admindb->execute("INSERT INTO main.scheduler SELECT * FROM disk.scheduler");
admindb->wrunlock();
}
void ProxySQL_Admin::flush_scheduler__from_memory_to_disk() {
admindb->wrlock();
admindb->execute("DELETE FROM disk.scheduler");
admindb->execute("INSERT INTO disk.scheduler SELECT * FROM main.scheduler");
admindb->wrunlock();
}
void ProxySQL_Admin::flush_mysql_servers__from_disk_to_memory() {
admindb->wrlock();
admindb->execute("PRAGMA foreign_keys = OFF");
@ -3471,6 +3605,76 @@ void ProxySQL_Admin::save_mysql_users_runtime_to_database() {
free(ads);
}
void ProxySQL_Admin::save_scheduler_runtime_to_database(bool _runtime) {
char *query=NULL;
// dump mysql_servers
if (_runtime) {
query=(char *)"DELETE FROM main.runtime_scheduler";
} else {
query=(char *)"DELETE FROM main.scheduler";
}
proxy_debug(PROXY_DEBUG_ADMIN, 4, "%s\n", query);
admindb->execute(query);
// allocate args only once
char **args=(char **)malloc(5*sizeof(char *));
// read lock the scheduler
spin_rdlock(&scheduler->rwlock);
char *q=NULL;
if (_runtime) {
q=(char *)"INSERT INTO runtime_scheduler VALUES(%lu,%lu,\"%s\" ,%s,%s,%s,%s,%s)";
} else {
q=(char *)"INSERT INTO scheduler VALUES(%lu,%lu,\"%s\" ,%s,%s,%s,%s,%s)";
}
for (std::vector<Scheduler_Row *>::iterator it = scheduler->Scheduler_Rows.begin() ; it != scheduler->Scheduler_Rows.end(); ++it) {
Scheduler_Row *sr=*it;
int i;
int l=strlen(q);
l+=strlen(sr->filename);
for (i=0; i<5; i++) {
if (sr->args[i]) {
args[i]=(char *)malloc(strlen(sr->args[i])+4);
sprintf(args[i],"\"%s\"",sr->args[i]);
} else {
args[i]=(char *)"NULL";
}
l+=strlen(args[i]);
}
l+=32; //padding
char *query=(char *)malloc(l);
sprintf(query, q,
sr->id, sr->interval_ms,
sr->filename, args[0],
args[1], args[2],
args[3], args[4]
);
for (i=0; i<5; i++) {
if (sr->args[i]) {
free(args[i]); // free only if we allocated memory
}
}
admindb->execute(query);
free(query);
}
// unlock the scheduler
spin_rdunlock(&scheduler->rwlock);
// deallocate args
free(args);
}
void ProxySQL_Admin::save_mysql_servers_runtime_to_database(bool _runtime) {
// make sure that the caller has called mysql_servers_wrlock()
char *query=NULL;
@ -3539,6 +3743,22 @@ void ProxySQL_Admin::save_mysql_servers_runtime_to_database(bool _runtime) {
}
void ProxySQL_Admin::load_scheduler_to_runtime() {
char *error=NULL;
int cols=0;
int affected_rows=0;
SQLite3_result *resultset=NULL;
char *query=(char *)"SELECT * FROM scheduler";
admindb->execute_statement(query, &error , &cols , &affected_rows , &resultset);
if (error) {
proxy_error("Error on %s : %s\n", query, error);
} else {
scheduler->update_table(resultset);
}
if (resultset) delete resultset;
resultset=NULL;
}
void ProxySQL_Admin::load_mysql_servers_to_runtime() {
// make sure that the caller has called mysql_servers_wrlock()
char *error=NULL;
@ -4078,3 +4298,79 @@ void ProxySQL_Admin::disk_upgrade_mysql_servers() {
}
configdb->execute("PRAGMA foreign_keys = ON");
}
Scheduler_Row::Scheduler_Row(unsigned int _id, unsigned int _in, char *_f, char *a1, char *a2, char *a3, char *a4, char *a5) {
int i;
id=_id;
interval_ms=_in;
filename=strdup(_f);
args=(char **)malloc(6*sizeof(char *));
for (i=0;i<6;i++) {
args[i]=NULL;
}
// only copy fields if the previous one is not null
if (a1) {
args[0]=strdup(a1);
if (a2) {
args[1]=strdup(a2);
if (a3) {
args[2]=strdup(a3);
if (a4) {
args[3]=strdup(a4);
if (a5) {
args[4]=strdup(a5);
}
}
}
}
}
}
Scheduler_Row::~Scheduler_Row() {
int i;
for (i=0;i<6;i++) {
if (args[i]) {
free(args[i]);
}
args[i]=NULL;
}
free(args);
args=NULL;
}
ProxySQL_External_Scheduler::ProxySQL_External_Scheduler() {
spinlock_rwlock_init(&rwlock);
}
ProxySQL_External_Scheduler::~ProxySQL_External_Scheduler() {
}
void ProxySQL_External_Scheduler::update_table(SQLite3_result *resultset) {
spin_wrlock(&rwlock);
// delete all current rows
Scheduler_Row *sr;
for (std::vector<Scheduler_Row *>::iterator it=Scheduler_Rows.begin(); it!=Scheduler_Rows.end(); ++it) {
sr=*it;
delete sr;
}
Scheduler_Rows.clear();
for (std::vector<SQLite3_row *>::iterator it = resultset->rows.begin() ; it != resultset->rows.end(); ++it) {
SQLite3_row *r=*it;
unsigned int id=strtoul(r->fields[0], NULL, 10);
unsigned int interval_ms=strtoul(r->fields[1], NULL, 10);
Scheduler_Row *sr=new Scheduler_Row(id, interval_ms,
r->fields[2], r->fields[3],
r->fields[4], r->fields[5],
r->fields[6], r->fields[7]
);
Scheduler_Rows.push_back(sr);
}
spin_wrunlock(&rwlock);
}

Loading…
Cancel
Save