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 drizzle_query_st *drizzle_query_run(drizzle_st *drizzle,
00196 drizzle_return_t *ret_ptr)
00197 {
00198 drizzle_options_t options;
00199 drizzle_query_st *query;
00200 drizzle_con_st *con;
00201
00202 if (drizzle->query_new == 0 && drizzle->query_running == 0)
00203 {
00204 *ret_ptr= DRIZZLE_RETURN_OK;
00205 return NULL;
00206 }
00207
00208 options= drizzle->options;
00209 drizzle->options|= DRIZZLE_NON_BLOCKING;
00210
00211
00212 if (drizzle->query_new > 0)
00213 {
00214 for (query= drizzle->query_list; query != NULL; query= query->next)
00215 {
00216 if (query->state != DRIZZLE_QUERY_STATE_INIT)
00217 continue;
00218
00219 query->result= drizzle_query(query->con, query->result, query->string,
00220 query->size, ret_ptr);
00221 if (*ret_ptr != DRIZZLE_RETURN_IO_WAIT && *ret_ptr != DRIZZLE_RETURN_OK)
00222 {
00223 drizzle->options= options;
00224
00225 if (*ret_ptr == DRIZZLE_RETURN_ERROR_CODE)
00226 {
00227 query->state= DRIZZLE_QUERY_STATE_DONE;
00228 drizzle->query_new--;
00229 return query;
00230 }
00231
00232 return NULL;
00233 }
00234
00235 query->state= DRIZZLE_QUERY_STATE_QUERY;
00236 drizzle->query_running++;
00237 query->con->query= query;
00238 drizzle->query_new--;
00239 }
00240 }
00241
00242 while (1)
00243 {
00244
00245 while ((con= drizzle_con_ready(drizzle)) != NULL)
00246 {
00247 query= con->query;
00248
00249 switch (query->state)
00250 {
00251 case DRIZZLE_QUERY_STATE_INIT:
00252 case DRIZZLE_QUERY_STATE_QUERY:
00253 query->result= drizzle_query(query->con, query->result, query->string,
00254 query->size, ret_ptr);
00255 if (*ret_ptr == DRIZZLE_RETURN_IO_WAIT)
00256 break;
00257 else if (*ret_ptr == DRIZZLE_RETURN_ERROR_CODE)
00258 {
00259 query->state= DRIZZLE_QUERY_STATE_DONE;
00260 drizzle->query_running--;
00261 drizzle->options= options;
00262 return query;
00263 }
00264 else if (*ret_ptr != DRIZZLE_RETURN_OK)
00265 {
00266 drizzle->options= options;
00267 return NULL;
00268 }
00269
00270 query->state= DRIZZLE_QUERY_STATE_RESULT;
00271
00272 case DRIZZLE_QUERY_STATE_RESULT:
00273 *ret_ptr= drizzle_result_buffer(query->result);
00274 if (*ret_ptr == DRIZZLE_RETURN_IO_WAIT)
00275 break;
00276 if (*ret_ptr != DRIZZLE_RETURN_OK)
00277 {
00278 drizzle->options= options;
00279 return NULL;
00280 }
00281
00282 query->state= DRIZZLE_QUERY_STATE_DONE;
00283 drizzle->query_running--;
00284 drizzle->options= options;
00285 return query;
00286
00287 default:
00288 case DRIZZLE_QUERY_STATE_DONE:
00289 break;
00290 }
00291 }
00292
00293 if (options & DRIZZLE_NON_BLOCKING)
00294 {
00295 *ret_ptr= DRIZZLE_RETURN_IO_WAIT;
00296 return NULL;
00297 }
00298
00299 *ret_ptr= drizzle_con_wait(drizzle);
00300 if (*ret_ptr != DRIZZLE_RETURN_OK)
00301 {
00302 drizzle->options= options;
00303 return NULL;
00304 }
00305 }
00306 }
00307
00308 drizzle_return_t drizzle_query_run_all(drizzle_st *drizzle)
00309 {
00310 drizzle_return_t ret;
00311
00312 while (drizzle->query_new > 0 || drizzle->query_running > 0)
00313 {
00314 (void)drizzle_query_run(drizzle, &ret);
00315 if (ret != DRIZZLE_RETURN_OK && ret != DRIZZLE_RETURN_ERROR_CODE)
00316 return ret;
00317 }
00318
00319 return DRIZZLE_RETURN_OK;
00320 }
00321
00322 size_t drizzle_escape_string(char *to, const char *from, size_t from_size)
00323 {
00324 size_t to_size= 0;
00325
00326 while (from_size > 0)
00327 {
00328
00329 if (!(*from & 0x80))
00330 {
00331 switch (*from)
00332 {
00333 case 0:
00334 case '\n':
00335 case '\r':
00336 case '\\':
00337 case '\'':
00338 case '"':
00339 case '\032':
00340 *to++= '\\';
00341 to_size++;
00342 default:
00343 break;
00344 }
00345 }
00346
00347 *to++= *from++;
00348 from_size--;
00349 to_size++;
00350 }
00351
00352 *to= 0;
00353
00354 return to_size;
00355 }
00356
00357 size_t drizzle_hex_string(char *to, const char *from, size_t from_size)
00358 {
00359 static const char hex_map[]= "0123456789ABCDEF";
00360 const char *from_end;
00361
00362 for (from_end= from + from_size; from != from_end; from++)
00363 {
00364 *to++= hex_map[((unsigned char) *from) >> 4];
00365 *to++= hex_map[((unsigned char) *from) & 0xF];
00366 }
00367
00368 *to= 0;
00369
00370 return from_size * 2;
00371 }