| CODENOTIFIER | HelpYou are not signed inSign in |
Project: DBSlayer
Revision: 59
Author: dgottfrid
Date: 19 Mar 2008 19:07:16
Changes:update dbaccess to allow for naming the database in the request; and switch to json_skip_list instead od apr_hash; delete dbaccess.c since it wasn't kept up todate
Files:| ... | ...@@ -1,20 +0,0 @@ | |
| 1 | #include "dbaccess.h" | |
| 2 | /* $Id: dbdriver.c,v 1.4 2007/05/28 15:17:58 derek Exp $ */ | |
| 3 | ||
| 4 | int main(int argc, char **argv) { | |
| 5 | apr_pool_t *mpool; | |
| 6 | apr_pool_initialize(); | |
| 7 | apr_pool_create(&mpool,NULL); | |
| 8 | db_handle_t *handle = db_handle_init(argv[1]/*user*/,argv[2]/*pass*/,argv[3]/*server*/,argv[4]/*config*/,&argc); | |
| 9 | json_value *query= decode_json(argv[5],mpool); | |
| 10 | if(query) { | |
| 11 | encode_json(query); | |
| 12 | printf("\n"); | |
| 13 | json_value *result = dbexecute(handle,query,mpool); | |
| 14 | encode_json(result); | |
| 15 | printf("\n"); | |
| 16 | } | |
| 17 | apr_pool_destroy(mpool); | |
| 18 | apr_pool_terminate(); | |
| 19 | return 0; | |
| 20 | } |
| ... | ...@@ -1,38 +1,52 @@ | |
| 1 | 1 | #include "dbaccess.h" |
| 2 | /* $Id: dbaccess.c,v 1.10 2007/06/12 03:20:53 derek Exp $ */ | |
| 2 | /* $Id: dbaccess.c,v 1.14 2008/03/06 01:50:58 derek Exp $ */ | |
| 3 | 3 | |
| 4 | db_handle_t * db_handle_reattach(db_handle_t *handle) { | |
| 5 | int ct = handle->server_offset; | |
| 6 | for(ct = handle->server_offset ; ct < handle->server_count; ct++) { | |
| 7 | if(handle->db) mysql_close(handle->db); | |
| 8 | handle->db = mysql_init(NULL); | |
| 9 | mysql_options(handle->db,MYSQL_READ_DEFAULT_FILE,handle->config); | |
| 10 | mysql_options(handle->db,MYSQL_READ_DEFAULT_GROUP,handle->server[ct]); | |
| 11 | if(mysql_real_connect(handle->db,NULL,handle->user,handle->pass,NULL,0,NULL,CLIENT_MULTI_STATEMENTS) != NULL){ | |
| 12 | handle->server_offset = ct; | |
| 13 | return handle; | |
| 4 | db_handle_t * db_handle_reattach(db_handle_t *handle,const char *dbserver_name) { | |
| 5 | if(handle->dblookup == NULL) { | |
| 6 | int ct = handle->server_offset; | |
| 7 | for(ct = handle->server_offset ; ct < handle->server_count; ct++) { | |
| 8 | if(handle->db) mysql_close(handle->db); | |
| 9 | handle->db = mysql_init(NULL); | |
| 10 | mysql_options(handle->db,MYSQL_READ_DEFAULT_FILE,handle->config); | |
| 11 | mysql_options(handle->db,MYSQL_READ_DEFAULT_GROUP,handle->server[ct]); | |
| 12 | if(mysql_real_connect(handle->db,NULL,handle->user,handle->pass,NULL,0,NULL,CLIENT_MULTI_STATEMENTS) != NULL){ | |
| 13 | handle->server_offset = ct; | |
| 14 | return handle; | |
| 15 | } | |
| 14 | 16 | } |
| 15 | } | |
| 16 | for(ct = 0; ct < handle->server_offset; ct++) { | |
| 17 | if(handle->db) mysql_close(handle->db); | |
| 18 | handle->db = mysql_init(NULL); | |
| 19 | mysql_options(handle->db,MYSQL_READ_DEFAULT_FILE,handle->config); | |
| 20 | mysql_options(handle->db,MYSQL_READ_DEFAULT_GROUP,handle->server[ct]); | |
| 21 | if(mysql_real_connect(handle->db,NULL,handle->user,handle->pass,NULL,0,NULL,CLIENT_MULTI_STATEMENTS) != NULL){ | |
| 22 | handle->server_offset = ct; | |
| 23 | return handle; | |
| 17 | for(ct = 0; ct < handle->server_offset; ct++) { | |
| 18 | if(handle->db) mysql_close(handle->db); | |
| 19 | handle->db = mysql_init(NULL); | |
| 20 | mysql_options(handle->db,MYSQL_READ_DEFAULT_FILE,handle->config); | |
| 21 | mysql_options(handle->db,MYSQL_READ_DEFAULT_GROUP,handle->server[ct]); | |
| 22 | if(mysql_real_connect(handle->db,NULL,handle->user,handle->pass,NULL,0,NULL,CLIENT_MULTI_STATEMENTS) != NULL){ | |
| 23 | handle->server_offset = ct; | |
| 24 | return handle; | |
| 25 | } | |
| 26 | } | |
| 27 | } else { | |
| 28 | MYSQL *db = json_skip_get(handle->dblookup,(void*) dbserver_name); | |
| 29 | if(db) { mysql_close(db); } | |
| 30 | db = mysql_init(NULL); | |
| 31 | mysql_options(db,MYSQL_READ_DEFAULT_FILE,handle->config); | |
| 32 | mysql_options(db,MYSQL_READ_DEFAULT_GROUP,dbserver_name); | |
| 33 | json_skip_replace(handle->dblookup,(void*)dbserver_name,db); | |
| 34 | if(mysql_real_connect(db,NULL,NULL,NULL,NULL,0,NULL,CLIENT_MULTI_STATEMENTS) != NULL){ | |
| 35 | return handle; | |
| 24 | 36 | } |
| 25 | 37 | } |
| 26 | 38 | return NULL; |
| 27 | 39 | } |
| 28 | 40 | |
| 29 | db_handle_t * db_handle_init(const char *_user, const char *_pass, const char *_server, const char *_config, void *userarg){ | |
| 41 | db_handle_t * db_handle_init(const char *_user, const char *_pass, const char *_server, const char *_config, void *userarg,int multidb){ | |
| 30 | 42 | db_handle_t *dbhandle= malloc(sizeof(db_handle_t)); |
| 31 | 43 | //should then be defined in the config if the user/pass is NULL |
| 32 | 44 | dbhandle->user = _user ? strdup(_user) : NULL; |
| 33 | 45 | dbhandle->pass = _pass ? strdup(_pass) : NULL; |
| 34 | 46 | dbhandle->config = strdup(_config); |
| 35 | 47 | dbhandle->db = NULL; |
| 48 | dbhandle->dblookup = NULL; | |
| 49 | dbhandle->mpool = NULL; | |
| 36 | 50 | |
| 37 | 51 | //chop up the server string |
| 38 | 52 | int i = 0; |
| ... | ...@@ -52,14 +66,30 @@ | |
| 52 | 66 | unsigned int seed = *((unsigned int*)userarg); |
| 53 | 67 | free(server); |
| 54 | 68 | dbhandle->server_offset = seed % dbhandle->server_count; |
| 55 | db_handle_reattach(dbhandle); | |
| 69 | if(multidb == 0) { | |
| 70 | db_handle_reattach(dbhandle,""); | |
| 71 | } else { | |
| 72 | apr_pool_create(&(dbhandle->mpool),NULL); | |
| 73 | dbhandle->dblookup = json_skip_create(dbhandle->mpool,4,(json_skip_cmp_t)strcmp); | |
| 74 | for(i=0;i < dbhandle->server_count; i++) { | |
| 75 | db_handle_reattach(dbhandle,dbhandle->server[i]); | |
| 76 | } | |
| 77 | } | |
| 56 | 78 | return dbhandle; |
| 57 | 79 | } |
| 58 | 80 | |
| 59 | 81 | void db_handle_destroy(db_handle_t *dbhandle) { |
| 60 | mysql_close(dbhandle->db); | |
| 61 | mysql_thread_end(); | |
| 62 | 82 | int i; |
| 83 | if(dbhandle->dblookup == NULL) { | |
| 84 | mysql_close(dbhandle->db); | |
| 85 | } else { | |
| 86 | for(i = 0; i < dbhandle->server_count; i++) { | |
| 87 | mysql_close((MYSQL*)json_skip_get(dbhandle->dblookup,dbhandle->server[i])); | |
| 88 | } | |
| 89 | apr_pool_destroy(dbhandle->mpool); | |
| 90 | } | |
| 91 | ||
| 92 | mysql_thread_end(); | |
| 63 | 93 | for(i = 0; i < dbhandle->server_count; i++) { |
| 64 | 94 | free(dbhandle->server[i]); |
| 65 | 95 | } |
| ... | ...@@ -235,13 +265,53 @@ | |
| 235 | 265 | json_value * dbexecute(db_handle_t *dbhandle, json_value *injson, apr_pool_t *mpool) { |
| 236 | 266 | json_value *out = json_object_create(mpool); |
| 237 | 267 | json_value *sql = NULL; |
| 238 | if(injson->type == JSON_OBJECT && (sql = (json_value*)apr_hash_get(injson->value.object,"SQL",APR_HASH_KEY_STRING)) !=NULL && sql->type == JSON_STRING) { | |
| 239 | if(mysql_query(dbhandle->db,sql->value.string)) { | |
| 268 | MYSQL *db = NULL; //dbhandle->db; | |
| 269 | const char *dbserver_name = NULL;//dbhandle->server[xdbhandle->server_offset]; | |
| 270 | json_value *request_server = NULL; | |
| 271 | ||
| 272 | // CHECK FOR SERVER in the incoming JSON - and pick out flag - | |
| 273 | if(injson->type == JSON_OBJECT && (request_server = (json_value*)json_skip_get(injson->value.object,"SERVER")) !=NULL && request_server->type == JSON_STRING) { | |
| 274 | if(dbhandle->dblookup == NULL) { | |
| 275 | json_object_add(out,"ERROR",json_string_create(mpool,"Provided a SERVER argument but dbslayer is not configure for named server access - perhaps you want the -m config option")); | |
| 276 | return out; | |
| 277 | } | |
| 278 | dbserver_name = request_server->value.string; | |
| 279 | db = (MYSQL*) json_skip_get(dbhandle->dblookup,(void*)dbserver_name); | |
| 280 | if(db == NULL) { | |
| 281 | json_object_add(out,"ERROR",json_string_create(mpool,"Couldn't find the database handle for SERVER requested")); | |
| 282 | json_object_add(out,"SERVER",request_server); | |
| 283 | return out; | |
| 284 | } | |
| 285 | ||
| 286 | } else if(dbhandle->dblookup !=NULL) { | |
| 287 | json_object_add(out,"ERROR",json_string_create(mpool,"dbslayer is configured to take a SERVER argument - perhaps you want the -s config option")); | |
| 288 | return out; | |
| 289 | } else { | |
| 290 | db = dbhandle->db; | |
| 291 | dbserver_name = dbhandle->server[dbhandle->server_offset]; | |
| 292 | } | |
| 293 | ||
| 294 | if(injson->type == JSON_OBJECT && (sql = (json_value*)json_skip_get(injson->value.object,"SQL")) !=NULL && sql->type == JSON_STRING) { | |
| 295 | if(mysql_query(db,sql->value.string)) { | |
| 240 | 296 | /** NEED TO CHECK FOR BETTER ERROR TO MAKE SURE IT IS A CONNECTION ISSUE **/ |
| 241 | if(db_handle_reattach(dbhandle) == NULL || mysql_query(dbhandle->db,sql->value.string)){ | |
| 242 | json_object_add(out,"MYSQL_ERROR",json_string_create(mpool,mysql_error(dbhandle->db))); | |
| 243 | json_object_add(out,"MYSQL_ERRNO",json_long_create(mpool,mysql_errno(dbhandle->db))); | |
| 244 | json_object_add(out,"SERVER" , json_string_create(mpool,dbhandle->server[dbhandle->server_offset])); | |
| 297 | if(db_handle_reattach(dbhandle,dbserver_name) == NULL || mysql_query((db = dbhandle->dblookup == NULL ? dbhandle->db : json_skip_get(dbhandle->dblookup,(void*)dbserver_name)) ,sql->value.string)){ | |
| 298 | ||
| 299 | dbserver_name = dbhandle->dblookup == NULL ? dbhandle->server[dbhandle->server_offset] : dbserver_name; | |
| 300 | json_object_add(out,"MYSQL_ERROR",json_string_create(mpool,mysql_error(db))); | |
| 301 | json_object_add(out,"MYSQL_ERRNO",json_long_create(mpool,mysql_errno(db))); | |
| 302 | json_object_add(out,"SERVER" , json_string_create(mpool,dbserver_name)); | |
| 303 | ||
| 304 | /** issue a rollback if caller asked for it **/ | |
| 305 | if ((injson->type == JSON_OBJECT) | |
| 306 | && ((sql = (json_value*)json_skip_get(injson->value.object, "ROLLBACK_ON_ERROR" )) != NULL) | |
| 307 | && (sql->type == JSON_BOOLEAN) | |
| 308 | && sql->value.boolean) { | |
| 309 | ||
| 310 | json_object_add(out, "ROLLBACK_ON_ERROR", json_boolean_create(mpool, 1)); | |
| 311 | json_object_add(out, "ROLLBACK_ON_ERROR_SUCCESS", json_boolean_create(mpool, !mysql_rollback(db))); | |
| 312 | ||
| 313 | } | |
| 314 | ||
| 245 | 315 | return out; |
| 246 | 316 | } |
| 247 | 317 | } |
| ... | ...@@ -249,14 +319,26 @@ | |
| 249 | 319 | json_value *sql_result = NULL; |
| 250 | 320 | int status = 0; |
| 251 | 321 | do { |
| 252 | MYSQL_RES *myresult = mysql_store_result(dbhandle->db); | |
| 322 | MYSQL_RES *myresult = mysql_store_result(db); | |
| 253 | 323 | if(myresult == NULL ) { |
| 254 | 324 | /** ERROR OCCURED ***/ |
| 255 | if(mysql_errno(dbhandle->db)) { | |
| 325 | if(mysql_errno(db)) { | |
| 256 | 326 | json_object_add(out,"SUCCESS",json_boolean_create(mpool,0)); |
| 257 | json_object_add(out,"MYSQL_ERROR",json_string_create(mpool,mysql_error(dbhandle->db))); | |
| 258 | json_object_add(out,"MYSQL_ERRNO",json_long_create(mpool,mysql_errno(dbhandle->db))); | |
| 259 | json_object_add(out,"SERVER" , json_string_create(mpool,dbhandle->server[dbhandle->server_offset])); | |
| 327 | json_object_add(out,"MYSQL_ERROR",json_string_create(mpool,mysql_error(db))); | |
| 328 | json_object_add(out,"MYSQL_ERRNO",json_long_create(mpool,mysql_errno(db))); | |
| 329 | json_object_add(out,"SERVER" , json_string_create(mpool,dbserver_name)); | |
| 330 | ||
| 331 | /** issue a rollback if caller asked for it **/ | |
| 332 | if ((injson->type == JSON_OBJECT) | |
| 333 | && ((sql = (json_value*)json_skip_get(injson->value.object, "ROLLBACK_ON_ERROR")) != NULL) | |
| 334 | && (sql->type == JSON_BOOLEAN) | |
| 335 | && sql->value.boolean) { | |
| 336 | ||
| 337 | json_object_add(out, "ROLLBACK_ON_ERROR", json_boolean_create(mpool, 1)); | |
| 338 | json_object_add(out, "ROLLBACK_ON_ERROR_SUCCESS", json_boolean_create(mpool, !mysql_rollback(db))); | |
| 339 | ||
| 340 | } | |
| 341 | ||
| 260 | 342 | } else { |
| 261 | 343 | /** SUCCESS NO RESULT RETURNED ie UPDATE | DELETE | INSERT ***/ |
| 262 | 344 | ; |
| ... | ...@@ -289,36 +371,36 @@ | |
| 289 | 371 | } |
| 290 | 372 | mysql_free_result(myresult); |
| 291 | 373 | } |
| 292 | if ((status = mysql_next_result(dbhandle->db)) > 0) printf("Could not execute statement\n"); | |
| 374 | if ((status = mysql_next_result(db)) > 0) printf("Could not execute statement\n"); | |
| 293 | 375 | }while(status ==0); |
| 294 | 376 | |
| 295 | 377 | if(sql_result && !all_result) { |
| 296 | 378 | json_object_add(out,"RESULT",sql_result); |
| 297 | 379 | } |
| 298 | json_object_add(out,"SERVER" , json_string_create(mpool,dbhandle->server[dbhandle->server_offset])); | |
| 380 | json_object_add(out,"SERVER" , json_string_create(mpool,dbserver_name)); | |
| 299 | 381 | } |
| 300 | if(injson->type == JSON_OBJECT && (sql = (json_value*)apr_hash_get(injson->value.object,"STAT",APR_HASH_KEY_STRING)) !=NULL && sql->type == JSON_BOOLEAN && sql->value.boolean) { | |
| 301 | json_object_add(out,"STAT",json_string_create(mpool,mysql_stat(dbhandle->db))); | |
| 382 | if(injson->type == JSON_OBJECT && (sql = (json_value*)json_skip_get(injson->value.object,"STAT")) !=NULL && sql->type == JSON_BOOLEAN && sql->value.boolean) { | |
| 383 | json_object_add(out,"STAT",json_string_create(mpool,mysql_stat(db))); | |
| 302 | 384 | } |
| 303 | if(injson->type == JSON_OBJECT && (sql = (json_value*)apr_hash_get(injson->value.object,"CLIENT_INFO",APR_HASH_KEY_STRING)) !=NULL && sql->type == JSON_BOOLEAN && sql->value.boolean) { | |
| 385 | if(injson->type == JSON_OBJECT && (sql = (json_value*)json_skip_get(injson->value.object,"CLIENT_INFO")) !=NULL && sql->type == JSON_BOOLEAN && sql->value.boolean) { | |
| 304 | 386 | json_object_add(out,"CLIENT_INFO",json_string_create(mpool,mysql_get_client_info())); |
| 305 | 387 | } |
| 306 | if(injson->type == JSON_OBJECT && (sql = (json_value*)apr_hash_get(injson->value.object,"HOST_INFO",APR_HASH_KEY_STRING)) !=NULL && sql->type == JSON_BOOLEAN && sql->value.boolean) { | |
| 307 | json_object_add(out,"HOST_INFO",json_string_create(mpool,mysql_get_host_info(dbhandle->db))); | |
| 388 | if(injson->type == JSON_OBJECT && (sql = (json_value*)json_skip_get(injson->value.object,"HOST_INFO")) !=NULL && sql->type == JSON_BOOLEAN && sql->value.boolean) { | |
| 389 | json_object_add(out,"HOST_INFO",json_string_create(mpool,mysql_get_host_info(db))); | |
| 308 | 390 | } |
| 309 | if(injson->type == JSON_OBJECT && (sql = (json_value*)apr_hash_get(injson->value.object,"SERVER_VERSION",APR_HASH_KEY_STRING)) !=NULL && sql->type == JSON_BOOLEAN && sql->value.boolean) { | |
| 310 | json_object_add(out,"SERVER_VERSION",json_long_create(mpool,mysql_get_server_version(dbhandle->db))); | |
| 391 | if(injson->type == JSON_OBJECT && (sql = (json_value*)json_skip_get(injson->value.object,"SERVER_VERSION")) !=NULL && sql->type == JSON_BOOLEAN && sql->value.boolean) { | |
| 392 | json_object_add(out,"SERVER_VERSION",json_long_create(mpool,mysql_get_server_version(db))); | |
| 311 | 393 | } |
| 312 | if(injson->type == JSON_OBJECT && (sql = (json_value*)apr_hash_get(injson->value.object,"CLIENT_VERSION",APR_HASH_KEY_STRING)) !=NULL && sql->type == JSON_BOOLEAN && sql->value.boolean) { | |
| 394 | if(injson->type == JSON_OBJECT && (sql = (json_value*)json_skip_get(injson->value.object,"CLIENT_VERSION")) !=NULL && sql->type == JSON_BOOLEAN && sql->value.boolean) { | |
| 313 | 395 | json_object_add(out,"CLIENT_VERSION",json_long_create(mpool,mysql_get_client_version())); |
| 314 | 396 | } |
| 315 | if(injson->type == JSON_OBJECT && (sql = (json_value*)apr_hash_get(injson->value.object,"SLAYER_DEBUG_RETURN_INPUT",APR_HASH_KEY_STRING)) !=NULL && sql->type == JSON_BOOLEAN && sql->value.boolean) { | |
| 397 | if(injson->type == JSON_OBJECT && (sql = (json_value*)json_skip_get(injson->value.object,"SLAYER_DEBUG_RETURN_INPUT")) !=NULL && sql->type == JSON_BOOLEAN && sql->value.boolean) { | |
| 316 | 398 | json_object_add(out,"SLAYER_DEBUG_RETURN_INPUT",injson); |
| 317 | 399 | } |
| 318 | if(injson->type == JSON_OBJECT && (sql = (json_value*)apr_hash_get(injson->value.object,"SERVER_NAME",APR_HASH_KEY_STRING)) !=NULL && sql->type == JSON_BOOLEAN && sql->value.boolean) { | |
| 319 | json_object_add(out,"SERVER_NAME",json_string_create(mpool,dbhandle->server[dbhandle->server_offset])); | |
| 400 | if(injson->type == JSON_OBJECT && (sql = (json_value*)json_skip_get(injson->value.object,"SERVER_NAME")) !=NULL && sql->type == JSON_BOOLEAN && sql->value.boolean) { | |
| 401 | json_object_add(out,"SERVER_NAME",json_string_create(mpool,dbserver_name)); | |
| 320 | 402 | } |
| 321 | if(injson->type == JSON_OBJECT && (sql = (json_value*)apr_hash_get(injson->value.object,"SLAYER_HELP",APR_HASH_KEY_STRING)) !=NULL && sql->type == JSON_BOOLEAN && sql->value.boolean) { | |
| 403 | if(injson->type == JSON_OBJECT && (sql = (json_value*)json_skip_get(injson->value.object,"SLAYER_HELP")) !=NULL && sql->type == JSON_BOOLEAN && sql->value.boolean) { | |
| 322 | 404 | json_value *commands = json_object_create(mpool); |
| 323 | 405 | json_object_add(out,"SLAYER_HELP",commands); |
| 324 | 406 | json_object_add(commands,"SQL",json_string_create(mpool,"in(string)[sql statement to execute] : out()eturns results in RESULTS node")); |
| ... | ...@@ -331,7 +413,7 @@ | |
| 331 | 413 | json_object_add(commands,"SLAYER_DEBUG_RETURN_INPUT",json_string_create(mpool,"in(boolean) : true ? returns this result")); |
| 332 | 414 | json_object_add(commands,"SERVER_NAME",json_string_create(mpool,"in(boolean) : true ? returns stanza from the -s option that was used")); |
| 333 | 415 | } |
| 334 | if(out->type == JSON_OBJECT && apr_hash_count(out->value.object) == 0) { | |
| 416 | if(out->type == JSON_OBJECT && out->value.object->node_count == 0) { | |
| 335 | 417 | json_object_add(out,"ERROR",json_string_create(mpool,"TRY {\"SLAYER_HELP\":true } ")); |
| 336 | 418 | } |
| 337 | 419 | return out; |
| ... | ...@@ -11,7 +11,7 @@ | |
| 11 | 11 | * |
| 12 | 12 | **/ |
| 13 | 13 | |
| 14 | /* $Id: dbaccess.h,v 1.5 2007/05/28 15:07:17 derek Exp $ */ | |
| 14 | /* $Id: dbaccess.h,v 1.6 2008/03/04 15:59:12 derek Exp $ */ | |
| 15 | 15 | |
| 16 | 16 | typedef struct _db_handle_t { |
| 17 | 17 | char *user; |
| ... | ...@@ -21,10 +21,12 @@ | |
| 21 | 21 | int server_count; |
| 22 | 22 | int server_offset; |
| 23 | 23 | MYSQL *db; |
| 24 | json_skip_head_t *dblookup; | |
| 25 | apr_pool_t *mpool; | |
| 24 | 26 | } db_handle_t; |
| 25 | 27 | |
| 26 | 28 | db_handle_t * db_handle_init(const char *_user, const char *_pass, |
| 27 | const char *_server, const char *_config,void *userarg); | |
| 29 | const char *_server, const char *_config,void *userarg, int multidb); | |
| 28 | 30 | void db_handle_destroy(db_handle_t *); |
| 29 | 31 | json_value * dbexecute(db_handle_t *dbh, json_value *injson, apr_pool_t *mpool); |
| 30 | 32 |