144 lines
3.7 KiB
C
144 lines
3.7 KiB
C
/*
|
|
This file is distributed as part of the SkySQL Gateway. It is free
|
|
software: you can redistribute it and/or modify it under the terms of the
|
|
GNU General Public License as published by the Free Software Foundation,
|
|
version 2.
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
details.
|
|
|
|
You should have received a copy of the GNU General Public License along with
|
|
this program; if not, write to the Free Software Foundation, Inc., 51
|
|
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
Copyright SkySQL Ab
|
|
|
|
*/
|
|
|
|
////////////////////////////////////////
|
|
// SKYSQL Backend
|
|
// By Massimiliano Pinto 2012/2013
|
|
////////////////////////////////////////
|
|
|
|
#include "skysql_gw.h"
|
|
|
|
int skysql_ext_file_ver(void) {
|
|
int ret = 13;
|
|
return ret;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////
|
|
// The function takes the server list,
|
|
// find the total server number
|
|
// and return a random selection for slaves (from total -1)
|
|
//////////////////////////////////////////////////////////////
|
|
int select_random_slave_server(const char *server_list, int *num_slaves) {
|
|
int nslaves = 0;
|
|
int random_balancer = 0;
|
|
char *p = (char *)server_list;
|
|
while( (p = strchr(p, ',')) != NULL) {
|
|
p++;
|
|
nslaves++;
|
|
}
|
|
|
|
memcpy(num_slaves, &nslaves, sizeof(int));
|
|
|
|
if (nslaves == 1) {
|
|
return 1;
|
|
}
|
|
|
|
// random selection
|
|
random_balancer = (int) ((nslaves+1) * (rand() / (RAND_MAX + 1.0)));
|
|
|
|
return random_balancer;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
// This takes a server from the list
|
|
// index 0 is always the Master
|
|
// the others refer to the salve,
|
|
// the slave number comes from: select_random_slave_server()
|
|
///////////////////////////////////////////////////////////////
|
|
int get_server_from_list(char **selected_host, int *selected_port, char *server_list, int num, apr_pool_t *p) {
|
|
int ret = -1;
|
|
int curr_srv = 0;
|
|
char *next = NULL;
|
|
char *tmp = NULL;
|
|
int port;
|
|
|
|
if (num == 0) {
|
|
port = atoi(strchr(server_list, ':') + 1), sizeof(port);
|
|
memcpy(selected_port, &port, sizeof(int));
|
|
*selected_host = apr_pstrndup(p, server_list, strchr(server_list, ':') - server_list);
|
|
|
|
return 1;
|
|
}
|
|
|
|
next = server_list;
|
|
|
|
while (curr_srv < num) {
|
|
|
|
tmp = strchr(next, ',');
|
|
if (tmp != NULL) {
|
|
curr_srv++;
|
|
next = tmp+1;
|
|
} else {
|
|
return -1;
|
|
}
|
|
|
|
if (curr_srv == num) {
|
|
port = atoi(strchr(next, ':') + 1);
|
|
|
|
memcpy(selected_port, &port, sizeof(port));
|
|
|
|
// the host string must be allocated in the memory pool!
|
|
*selected_host = apr_pstrndup(p, next, strchr(next, ':') - next);
|
|
ret = 0;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////
|
|
// This funcion take the master from the list
|
|
// The index is always 0
|
|
//////////////////////////////////////////////
|
|
int get_master_from_list(char **selected_host, int *selected_port, char *server_list, apr_pool_t *p) {
|
|
int ret = -1;
|
|
int curr_srv = 0;
|
|
char *next = NULL;
|
|
char *tmp = NULL;
|
|
int port;
|
|
|
|
port = atoi(strchr(server_list, ':') + 1), sizeof(port);
|
|
memcpy(selected_port, &port, sizeof(int));
|
|
|
|
// the host string must be allocated in the memory pool!
|
|
*selected_host = apr_pstrndup(p, server_list, strchr(server_list, ':') - server_list);
|
|
|
|
return 1;
|
|
}
|
|
|
|
///////////////////////////////////////
|
|
// Query Routing basic implementation
|
|
///////////////////////////////////////
|
|
|
|
int query_routing(const char *server_list, const char *sql_command, int procotol_command, int current_slave) {
|
|
|
|
if (strstr(sql_command, "select ")) {
|
|
// to the slave
|
|
return SKYSQL_READ;
|
|
} else {
|
|
// to the master
|
|
return SKYSQL_WRITE;
|
|
}
|
|
}
|
|
|
|
//////////////////
|