~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle/query.c

  • Committer: Monty Taylor
  • Date: 2008-08-05 19:01:20 UTC
  • mto: (266.1.1 codestyle)
  • mto: This revision was merged to the branch mainline in revision 266.
  • Revision ID: monty@inaugust.com-20080805190120-tsuziqz2mfqcw7pe
Removed libmysyslt.la, made mysys a noinst_ and made everything use it. It's
not a standalone lib, there's no reason to pretend otherwise.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Drizzle Client & Protocol Library
3
 
 *
4
 
 * Copyright (C) 2008 Eric Day (eday@oddments.org)
5
 
 * All rights reserved.
6
 
 *
7
 
 * Use and distribution licensed under the BSD license.  See
8
 
 * the COPYING file in this directory for full text.
9
 
 */
10
 
 
11
 
/**
12
 
 * @file
13
 
 * @brief Query definitions
14
 
 */
15
 
 
16
 
#include "common.h"
17
 
 
18
 
drizzle_result_st *drizzle_query(drizzle_con_st *con, drizzle_result_st *result,
19
 
                                 const char *query, size_t size,
20
 
                                 drizzle_return_t *ret_ptr)
21
 
{
22
 
  return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_QUERY,
23
 
                                   (uint8_t *)query, size, size, ret_ptr);
24
 
}
25
 
 
26
 
drizzle_result_st *drizzle_query_str(drizzle_con_st *con,
27
 
                                     drizzle_result_st *result,
28
 
                                     const char *query, 
29
 
                                     drizzle_return_t *ret_ptr)
30
 
{
31
 
  size_t size;
32
 
 
33
 
  size= strlen(query);
34
 
 
35
 
  return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_QUERY,
36
 
                                   (uint8_t *)query, size, size, ret_ptr);
37
 
}
38
 
 
39
 
drizzle_result_st *drizzle_query_inc(drizzle_con_st *con,
40
 
                                     drizzle_result_st *result,
41
 
                                     const char *query, size_t size,
42
 
                                     size_t total, drizzle_return_t *ret_ptr)
43
 
{
44
 
  return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_QUERY,
45
 
                                   (uint8_t *)query, size, total, ret_ptr);
46
 
}
47
 
 
48
 
drizzle_query_st *drizzle_query_add(drizzle_st *drizzle,
49
 
                                    drizzle_query_st *query,
50
 
                                    drizzle_con_st *con,
51
 
                                    drizzle_result_st *result,
52
 
                                    const char *query_string, size_t size,
53
 
                                    drizzle_query_options_t options,
54
 
                                    void *context)
55
 
{
56
 
  query= drizzle_query_create(drizzle, query);
57
 
  if (query == NULL)
58
 
    return NULL;
59
 
 
60
 
  drizzle_query_set_con(query, con);
61
 
  drizzle_query_set_result(query, result);
62
 
  drizzle_query_set_string(query, query_string, size);
63
 
  drizzle_query_add_options(query, options);
64
 
  drizzle_query_set_context(query, context);
65
 
 
66
 
  return query;
67
 
}
68
 
 
69
 
drizzle_query_st *drizzle_query_create(drizzle_st *drizzle,
70
 
                                       drizzle_query_st *query)
71
 
{
72
 
  if (query == NULL)
73
 
  {
74
 
    query= malloc(sizeof(drizzle_query_st));
75
 
    if (query == NULL)
76
 
    {
77
 
      drizzle_set_error(drizzle, "drizzle_query_create", "malloc");
78
 
      return NULL;
79
 
    }
80
 
 
81
 
    memset(query, 0, sizeof(drizzle_query_st));
82
 
    query->options|= DRIZZLE_CON_ALLOCATED;
83
 
  }
84
 
  else
85
 
    memset(query, 0, sizeof(drizzle_query_st));
86
 
 
87
 
  query->drizzle= drizzle;
88
 
 
89
 
  if (drizzle->query_list)
90
 
    drizzle->query_list->prev= query;
91
 
  query->next= drizzle->query_list;
92
 
  drizzle->query_list= query;
93
 
  drizzle->query_count++;
94
 
  drizzle->query_new++;
95
 
 
96
 
  return query;
97
 
}
98
 
 
99
 
void drizzle_query_free(drizzle_query_st *query)
100
 
{
101
 
  if (query->context != NULL && query->context_free_fn != NULL)
102
 
    query->context_free_fn(query, query->context);
103
 
 
104
 
  if (query->drizzle->query_list == query)
105
 
    query->drizzle->query_list= query->next;
106
 
  if (query->prev)
107
 
    query->prev->next= query->next;
108
 
  if (query->next)
109
 
    query->next->prev= query->prev;
110
 
  query->drizzle->query_count--;
111
 
 
112
 
  if (query->options & DRIZZLE_QUERY_ALLOCATED)
113
 
    free(query);
114
 
}
115
 
 
116
 
void drizzle_query_free_all(drizzle_st *drizzle)
117
 
{
118
 
  while (drizzle->query_list != NULL)
119
 
    drizzle_query_free(drizzle->query_list);
120
 
}
121
 
 
122
 
drizzle_con_st *drizzle_query_con(drizzle_query_st *query)
123
 
{
124
 
  return query->con;
125
 
}
126
 
 
127
 
void drizzle_query_set_con(drizzle_query_st *query, drizzle_con_st *con)
128
 
{
129
 
  query->con= con;
130
 
}
131
 
 
132
 
drizzle_result_st *drizzle_query_result(drizzle_query_st *query)
133
 
{
134
 
  return query->result;
135
 
}
136
 
 
137
 
void drizzle_query_set_result(drizzle_query_st *query,
138
 
                              drizzle_result_st *result)
139
 
{
140
 
  query->result= result;
141
 
}
142
 
 
143
 
char *drizzle_query_string(drizzle_query_st *query, size_t *size)
144
 
{
145
 
  *size= query->size;
146
 
  return (char *)(query->string);
147
 
}
148
 
 
149
 
void drizzle_query_set_string(drizzle_query_st *query, const char *string,
150
 
                              size_t size)
151
 
{
152
 
  query->string= string;
153
 
  query->size= size;
154
 
}
155
 
 
156
 
drizzle_query_options_t drizzle_query_options(drizzle_query_st *query)
157
 
{
158
 
  return query->options;
159
 
}
160
 
 
161
 
void drizzle_query_set_options(drizzle_query_st *query,
162
 
                               drizzle_query_options_t options)
163
 
{
164
 
  query->options= options;
165
 
}
166
 
 
167
 
void drizzle_query_add_options(drizzle_query_st *query,
168
 
                               drizzle_query_options_t options)
169
 
{
170
 
  query->options|= options;
171
 
}
172
 
 
173
 
void drizzle_query_remove_options(drizzle_query_st *query,
174
 
                                  drizzle_query_options_t options)
175
 
{
176
 
  query->options&= ~options;
177
 
}
178
 
 
179
 
void *drizzle_query_context(drizzle_query_st *query)
180
 
{
181
 
  return query->context;
182
 
}
183
 
 
184
 
void drizzle_query_set_context(drizzle_query_st *query, void *context)
185
 
{
186
 
  query->context= context;
187
 
}
188
 
 
189
 
void drizzle_query_set_context_free_fn(drizzle_query_st *query,
190
 
                                       drizzle_query_context_free_fn *function)
191
 
{
192
 
  query->context_free_fn= function;
193
 
}
194
 
 
195
 
static void drizzle_query_run_state(drizzle_query_st* query,
196
 
                                    drizzle_return_t* ret_ptr)
197
 
{
198
 
  switch (query->state)
199
 
  {
200
 
  case DRIZZLE_QUERY_STATE_INIT:
201
 
    query->state= DRIZZLE_QUERY_STATE_QUERY;
202
 
  case DRIZZLE_QUERY_STATE_QUERY:
203
 
    query->result= drizzle_query(query->con, query->result, query->string,
204
 
                                 query->size, ret_ptr);
205
 
    if (*ret_ptr == DRIZZLE_RETURN_IO_WAIT)
206
 
    {
207
 
      return;
208
 
    }
209
 
    else if (*ret_ptr != DRIZZLE_RETURN_OK)
210
 
    {
211
 
      query->state= DRIZZLE_QUERY_STATE_DONE;
212
 
      return;
213
 
    }
214
 
 
215
 
    query->state= DRIZZLE_QUERY_STATE_RESULT;
216
 
 
217
 
  case DRIZZLE_QUERY_STATE_RESULT:
218
 
    *ret_ptr= drizzle_result_buffer(query->result);
219
 
    if (*ret_ptr == DRIZZLE_RETURN_IO_WAIT)
220
 
    {
221
 
      return;
222
 
    }
223
 
 
224
 
    query->state= DRIZZLE_QUERY_STATE_DONE;
225
 
    return;
226
 
 
227
 
  default:
228
 
  case DRIZZLE_QUERY_STATE_DONE:
229
 
    return;
230
 
  }
231
 
}
232
 
 
233
 
drizzle_query_st *drizzle_query_run(drizzle_st *drizzle,
234
 
                                    drizzle_return_t *ret_ptr)
235
 
{
236
 
  drizzle_options_t options;
237
 
  drizzle_query_st *query;
238
 
  drizzle_con_st *con;
239
 
 
240
 
  if (drizzle->query_new == 0 && drizzle->query_running == 0)
241
 
  {
242
 
    *ret_ptr= DRIZZLE_RETURN_OK;
243
 
    return NULL;
244
 
  }
245
 
 
246
 
  options= drizzle->options;
247
 
  drizzle->options|= DRIZZLE_NON_BLOCKING;
248
 
 
249
 
  /* Check to see if any queries need to be started. */
250
 
  if (drizzle->query_new > 0)
251
 
  {
252
 
    for (query= drizzle->query_list; query != NULL; query= query->next)
253
 
    {
254
 
      if (query->state != DRIZZLE_QUERY_STATE_INIT)
255
 
        continue;
256
 
 
257
 
      drizzle->query_new--;
258
 
      drizzle->query_running++;
259
 
      assert(query->con->query == NULL);
260
 
      query->con->query= query;
261
 
 
262
 
      drizzle_query_run_state(query, ret_ptr);
263
 
      if (*ret_ptr != DRIZZLE_RETURN_IO_WAIT)
264
 
      {
265
 
        assert(query->state == DRIZZLE_QUERY_STATE_DONE);
266
 
        drizzle->query_running--;
267
 
        drizzle->options= options;
268
 
        query->con->query= NULL;
269
 
        if (*ret_ptr == DRIZZLE_RETURN_ERROR_CODE || *ret_ptr == DRIZZLE_RETURN_OK)
270
 
        {
271
 
          return query;
272
 
        }
273
 
        return NULL;
274
 
      }
275
 
    }
276
 
    assert(drizzle->query_new == 0);
277
 
  }
278
 
 
279
 
  while (1)
280
 
  {
281
 
    /* Loop through each active connection. */
282
 
    while ((con= drizzle_con_ready(drizzle)) != NULL)
283
 
    {
284
 
      query= con->query;
285
 
      drizzle_query_run_state(query, ret_ptr);
286
 
      if (query->state == DRIZZLE_QUERY_STATE_DONE)
287
 
      {
288
 
        drizzle->query_running--;
289
 
        drizzle->options= options;
290
 
        con->query= NULL;
291
 
        return query;
292
 
      }
293
 
      assert(*ret_ptr == DRIZZLE_RETURN_IO_WAIT);
294
 
    }
295
 
 
296
 
    if (options & DRIZZLE_NON_BLOCKING)
297
 
    {
298
 
      *ret_ptr= DRIZZLE_RETURN_IO_WAIT;
299
 
      return NULL;
300
 
    }
301
 
 
302
 
    *ret_ptr= drizzle_con_wait(drizzle);
303
 
    if (*ret_ptr != DRIZZLE_RETURN_OK)
304
 
    {
305
 
      drizzle->options= options;
306
 
      return NULL;
307
 
    }
308
 
  }
309
 
}
310
 
 
311
 
drizzle_return_t drizzle_query_run_all(drizzle_st *drizzle)
312
 
{
313
 
  drizzle_return_t ret;
314
 
 
315
 
  while (drizzle->query_new > 0 || drizzle->query_running > 0)
316
 
  {
317
 
    (void)drizzle_query_run(drizzle, &ret);
318
 
    if (ret != DRIZZLE_RETURN_OK && ret != DRIZZLE_RETURN_ERROR_CODE)
319
 
      return ret;
320
 
  }
321
 
 
322
 
  return DRIZZLE_RETURN_OK;
323
 
}
324
 
 
325
 
size_t drizzle_escape_string(char *to, const char *from, size_t from_size)
326
 
{
327
 
  size_t to_size= 0;
328
 
 
329
 
  while (from_size > 0)
330
 
  {
331
 
    /* All multi-byte UTF8 characters have the high bit set for all bytes. */
332
 
    if (!(*from & 0x80))
333
 
    {
334
 
      switch (*from)
335
 
      {
336
 
      case 0:
337
 
      case '\n':
338
 
      case '\r':
339
 
      case '\\':
340
 
      case '\'':
341
 
      case '"':
342
 
      case '\032':
343
 
        *to++= '\\';
344
 
        to_size++;
345
 
      default:
346
 
        break;
347
 
      }
348
 
    }
349
 
 
350
 
    *to++= *from++;
351
 
    from_size--;
352
 
    to_size++;
353
 
  }
354
 
 
355
 
  *to= 0;
356
 
 
357
 
  return to_size;
358
 
}
359
 
 
360
 
size_t drizzle_hex_string(char *to, const char *from, size_t from_size)
361
 
{
362
 
  static const char hex_map[]= "0123456789ABCDEF";
363
 
  const char *from_end;
364
 
 
365
 
  for (from_end= from + from_size; from != from_end; from++)
366
 
  {
367
 
    *to++= hex_map[((unsigned char) *from) >> 4];
368
 
    *to++= hex_map[((unsigned char) *from) & 0xF];
369
 
  }
370
 
 
371
 
  *to= 0;
372
 
 
373
 
  return from_size * 2;
374
 
}
375
 
 
376
 
void drizzle_mysql_password_hash(char *to, const char *from, size_t from_size)
377
 
{
378
 
  SHA1_CTX ctx;
379
 
  uint8_t hash_tmp1[SHA1_DIGEST_LENGTH];
380
 
  uint8_t hash_tmp2[SHA1_DIGEST_LENGTH];
381
 
 
382
 
  SHA1Init(&ctx);
383
 
  SHA1Update(&ctx, (const uint8_t*)from, from_size);
384
 
  SHA1Final(hash_tmp1, &ctx);
385
 
 
386
 
  SHA1Init(&ctx);
387
 
  SHA1Update(&ctx, hash_tmp1, SHA1_DIGEST_LENGTH);
388
 
  SHA1Final(hash_tmp2, &ctx);
389
 
 
390
 
  (void)drizzle_hex_string(to, (char*)hash_tmp2, SHA1_DIGEST_LENGTH);
391
 
}