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