00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00042 #include "common.h"
00043
00044 drizzle_result_st *drizzle_query(drizzle_con_st *con, drizzle_result_st *result,
00045 const char *query, size_t size,
00046 drizzle_return_t *ret_ptr)
00047 {
00048 return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_QUERY,
00049 (uint8_t *)query, size, size, ret_ptr);
00050 }
00051
00052 drizzle_result_st *drizzle_query_str(drizzle_con_st *con,
00053 drizzle_result_st *result,
00054 const char *query,
00055 drizzle_return_t *ret_ptr)
00056 {
00057 size_t size;
00058
00059 size= strlen(query);
00060
00061 return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_QUERY,
00062 (uint8_t *)query, size, size, ret_ptr);
00063 }
00064
00065 drizzle_result_st *drizzle_query_inc(drizzle_con_st *con,
00066 drizzle_result_st *result,
00067 const char *query, size_t size,
00068 size_t total, drizzle_return_t *ret_ptr)
00069 {
00070 return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_QUERY,
00071 (uint8_t *)query, size, total, ret_ptr);
00072 }
00073
00074 drizzle_query_st *drizzle_query_add(drizzle_st *drizzle,
00075 drizzle_query_st *query,
00076 drizzle_con_st *con,
00077 drizzle_result_st *result,
00078 const char *query_string, size_t size,
00079 drizzle_query_options_t options,
00080 void *context)
00081 {
00082 query= drizzle_query_create(drizzle, query);
00083 if (query == NULL)
00084 return NULL;
00085
00086 drizzle_query_set_con(query, con);
00087 drizzle_query_set_result(query, result);
00088 drizzle_query_set_string(query, query_string, size);
00089 drizzle_query_add_options(query, options);
00090 drizzle_query_set_context(query, context);
00091
00092 return query;
00093 }
00094
00095 drizzle_query_st *drizzle_query_create(drizzle_st *drizzle,
00096 drizzle_query_st *query)
00097 {
00098 if (query == NULL)
00099 {
00100 query= malloc(sizeof(drizzle_query_st));
00101 if (query == NULL)
00102 {
00103 drizzle_set_error(drizzle, "drizzle_query_create", "malloc");
00104 return NULL;
00105 }
00106
00107 memset(query, 0, sizeof(drizzle_query_st));
00108 query->options|= DRIZZLE_CON_ALLOCATED;
00109 }
00110 else
00111 memset(query, 0, sizeof(drizzle_query_st));
00112
00113 query->drizzle= drizzle;
00114
00115 if (drizzle->query_list)
00116 drizzle->query_list->prev= query;
00117 query->next= drizzle->query_list;
00118 drizzle->query_list= query;
00119 drizzle->query_count++;
00120 drizzle->query_new++;
00121
00122 return query;
00123 }
00124
00125 void drizzle_query_free(drizzle_query_st *query)
00126 {
00127 if (query->context != NULL && query->context_free_fn != NULL)
00128 query->context_free_fn(query, query->context);
00129
00130 if (query->drizzle->query_list == query)
00131 query->drizzle->query_list= query->next;
00132 if (query->prev)
00133 query->prev->next= query->next;
00134 if (query->next)
00135 query->next->prev= query->prev;
00136 query->drizzle->query_count--;
00137
00138 if (query->options & DRIZZLE_QUERY_ALLOCATED)
00139 free(query);
00140 }
00141
00142 void drizzle_query_free_all(drizzle_st *drizzle)
00143 {
00144 while (drizzle->query_list != NULL)
00145 drizzle_query_free(drizzle->query_list);
00146 }
00147
00148 drizzle_con_st *drizzle_query_con(drizzle_query_st *query)
00149 {
00150 return query->con;
00151 }
00152
00153 void drizzle_query_set_con(drizzle_query_st *query, drizzle_con_st *con)
00154 {
00155 query->con= con;
00156 }
00157
00158 drizzle_result_st *drizzle_query_result(drizzle_query_st *query)
00159 {
00160 return query->result;
00161 }
00162
00163 void drizzle_query_set_result(drizzle_query_st *query,
00164 drizzle_result_st *result)
00165 {
00166 query->result= result;
00167 }
00168
00169 char *drizzle_query_string(drizzle_query_st *query, size_t *size)
00170 {
00171 *size= query->size;
00172 return (char *)(query->string);
00173 }
00174
00175 void drizzle_query_set_string(drizzle_query_st *query, const char *string,
00176 size_t size)
00177 {
00178 query->string= string;
00179 query->size= size;
00180 }
00181
00182 drizzle_query_options_t drizzle_query_options(drizzle_query_st *query)
00183 {
00184 return query->options;
00185 }
00186
00187 void drizzle_query_set_options(drizzle_query_st *query,
00188 drizzle_query_options_t options)
00189 {
00190 query->options= options;
00191 }
00192
00193 void drizzle_query_add_options(drizzle_query_st *query,
00194 drizzle_query_options_t options)
00195 {
00196 query->options|= options;
00197 }
00198
00199 void drizzle_query_remove_options(drizzle_query_st *query,
00200 drizzle_query_options_t options)
00201 {
00202 query->options&= ~options;
00203 }
00204
00205 void *drizzle_query_context(drizzle_query_st *query)
00206 {
00207 return query->context;
00208 }
00209
00210 void drizzle_query_set_context(drizzle_query_st *query, void *context)
00211 {
00212 query->context= context;
00213 }
00214
00215 void drizzle_query_set_context_free_fn(drizzle_query_st *query,
00216 drizzle_query_context_free_fn *function)
00217 {
00218 query->context_free_fn= function;
00219 }
00220
00221 static void drizzle_query_run_state(drizzle_query_st* query,
00222 drizzle_return_t* ret_ptr)
00223 {
00224 switch (query->state)
00225 {
00226 case DRIZZLE_QUERY_STATE_INIT:
00227 query->state= DRIZZLE_QUERY_STATE_QUERY;
00228 case DRIZZLE_QUERY_STATE_QUERY:
00229 query->result= drizzle_query(query->con, query->result, query->string,
00230 query->size, ret_ptr);
00231 if (*ret_ptr == DRIZZLE_RETURN_IO_WAIT)
00232 {
00233 return;
00234 }
00235 else if (*ret_ptr != DRIZZLE_RETURN_OK)
00236 {
00237 query->state= DRIZZLE_QUERY_STATE_DONE;
00238 return;
00239 }
00240
00241 query->state= DRIZZLE_QUERY_STATE_RESULT;
00242
00243 case DRIZZLE_QUERY_STATE_RESULT:
00244 *ret_ptr= drizzle_result_buffer(query->result);
00245 if (*ret_ptr == DRIZZLE_RETURN_IO_WAIT)
00246 {
00247 return;
00248 }
00249
00250 query->state= DRIZZLE_QUERY_STATE_DONE;
00251 return;
00252
00253 default:
00254 case DRIZZLE_QUERY_STATE_DONE:
00255 return;
00256 }
00257 }
00258
00259 drizzle_query_st *drizzle_query_run(drizzle_st *drizzle,
00260 drizzle_return_t *ret_ptr)
00261 {
00262 drizzle_options_t options;
00263 drizzle_query_st *query;
00264 drizzle_con_st *con;
00265
00266 if (drizzle->query_new == 0 && drizzle->query_running == 0)
00267 {
00268 *ret_ptr= DRIZZLE_RETURN_OK;
00269 return NULL;
00270 }
00271
00272 options= drizzle->options;
00273 drizzle->options|= DRIZZLE_NON_BLOCKING;
00274
00275
00276 if (drizzle->query_new > 0)
00277 {
00278 for (query= drizzle->query_list; query != NULL; query= query->next)
00279 {
00280 if (query->state != DRIZZLE_QUERY_STATE_INIT)
00281 continue;
00282
00283 drizzle->query_new--;
00284 drizzle->query_running++;
00285 assert(query->con->query == NULL);
00286 query->con->query= query;
00287
00288 drizzle_query_run_state(query, ret_ptr);
00289 if (*ret_ptr != DRIZZLE_RETURN_IO_WAIT)
00290 {
00291 assert(query->state == DRIZZLE_QUERY_STATE_DONE);
00292 drizzle->query_running--;
00293 drizzle->options= options;
00294 query->con->query= NULL;
00295 if (*ret_ptr == DRIZZLE_RETURN_ERROR_CODE || *ret_ptr == DRIZZLE_RETURN_OK)
00296 {
00297 return query;
00298 }
00299 return NULL;
00300 }
00301 }
00302 assert(drizzle->query_new == 0);
00303 }
00304
00305 while (1)
00306 {
00307
00308 while ((con= drizzle_con_ready(drizzle)) != NULL)
00309 {
00310 query= con->query;
00311 drizzle_query_run_state(query, ret_ptr);
00312 if (query->state == DRIZZLE_QUERY_STATE_DONE)
00313 {
00314 drizzle->query_running--;
00315 drizzle->options= options;
00316 con->query= NULL;
00317 return query;
00318 }
00319 assert(*ret_ptr == DRIZZLE_RETURN_IO_WAIT);
00320 }
00321
00322 if (options & DRIZZLE_NON_BLOCKING)
00323 {
00324 *ret_ptr= DRIZZLE_RETURN_IO_WAIT;
00325 return NULL;
00326 }
00327
00328 *ret_ptr= drizzle_con_wait(drizzle);
00329 if (*ret_ptr != DRIZZLE_RETURN_OK)
00330 {
00331 drizzle->options= options;
00332 return NULL;
00333 }
00334 }
00335 }
00336
00337 drizzle_return_t drizzle_query_run_all(drizzle_st *drizzle)
00338 {
00339 drizzle_return_t ret;
00340
00341 while (drizzle->query_new > 0 || drizzle->query_running > 0)
00342 {
00343 (void)drizzle_query_run(drizzle, &ret);
00344 if (ret != DRIZZLE_RETURN_OK && ret != DRIZZLE_RETURN_ERROR_CODE)
00345 return ret;
00346 }
00347
00348 return DRIZZLE_RETURN_OK;
00349 }
00350
00351 ssize_t drizzle_safe_escape_string(char *to, size_t max_to_size, const char *from, size_t from_size)
00352 {
00353 ssize_t to_size= 0;
00354 char newchar;
00355 const char *end;
00356
00357 for (end= from + from_size; from < end; from++)
00358 {
00359 newchar= 0;
00360
00361 if (!(*from & 0x80))
00362 {
00363 switch (*from)
00364 {
00365 case 0:
00366 newchar= '0';
00367 break;
00368 case '\n':
00369 newchar= 'n';
00370 break;
00371 case '\r':
00372 newchar= 'r';
00373 break;
00374 case '\032':
00375 newchar= 'Z';
00376 break;
00377 case '\\':
00378 newchar= '\\';
00379 break;
00380 case '\'':
00381 newchar= '\'';
00382 break;
00383 case '"':
00384 newchar= '"';
00385 break;
00386 default:
00387 break;
00388 }
00389 }
00390 if (newchar != '\0')
00391 {
00392 if ((size_t)to_size + 2 > max_to_size)
00393 return -1;
00394
00395 *to++= '\\';
00396 *to++= newchar;
00397 to_size++;
00398 }
00399 else
00400 {
00401 if ((size_t)to_size + 1 > max_to_size)
00402 return -1;
00403
00404 *to++= *from;
00405 }
00406 to_size++;
00407 }
00408
00409 *to= 0;
00410
00411 return to_size;
00412 }
00413
00414 size_t drizzle_escape_string(char *to, const char *from, size_t from_size)
00415 {
00416 return (size_t) drizzle_safe_escape_string(to, (from_size * 2), from, from_size);
00417 }
00418
00419 size_t drizzle_hex_string(char *to, const char *from, size_t from_size)
00420 {
00421 static const char hex_map[]= "0123456789ABCDEF";
00422 const char *from_end;
00423
00424 for (from_end= from + from_size; from != from_end; from++)
00425 {
00426 *to++= hex_map[((unsigned char) *from) >> 4];
00427 *to++= hex_map[((unsigned char) *from) & 0xF];
00428 }
00429
00430 *to= 0;
00431
00432 return from_size * 2;
00433 }
00434
00435 void drizzle_mysql_password_hash(char *to, const char *from, size_t from_size)
00436 {
00437 SHA1_CTX ctx;
00438 uint8_t hash_tmp1[SHA1_DIGEST_LENGTH];
00439 uint8_t hash_tmp2[SHA1_DIGEST_LENGTH];
00440
00441 SHA1Init(&ctx);
00442 SHA1Update(&ctx, (const uint8_t*)from, from_size);
00443 SHA1Final(hash_tmp1, &ctx);
00444
00445 SHA1Init(&ctx);
00446 SHA1Update(&ctx, hash_tmp1, SHA1_DIGEST_LENGTH);
00447 SHA1Final(hash_tmp2, &ctx);
00448
00449 (void)drizzle_hex_string(to, (char*)hash_tmp2, SHA1_DIGEST_LENGTH);
00450 }