Files
MaxScale/protocol_1.0/skysql_backend.c
Massimiliano Pinto 2359b2bb19 GPL Header added
2013-04-15 18:16:02 +02:00

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;
}
}
//////////////////