~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle/libdrizzle.c

  • Committer: Monty Taylor
  • Date: 2008-08-02 01:03:15 UTC
  • mto: (236.1.42 codestyle)
  • mto: This revision was merged to the branch mainline in revision 261.
  • Revision ID: monty@inaugust.com-20080802010315-65h5938pymg9d99z
Moved m4 macros to top-level m4 dir, per GNU standards (and where gettext wanted it :)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems, Inc.
5
 
 *
6
 
 *  This program is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation; version 2 of the License.
9
 
 *
10
 
 *  This program is distributed in the hope that it will be useful,
11
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *  GNU General Public License for more details.
14
 
 *
15
 
 *  You should have received a copy of the GNU General Public License
16
 
 *  along with this program; if not, write to the Free Software
17
 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 
 */
 
1
/* Copyright (C) 2000-2004 DRIZZLE AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation.
 
6
 
 
7
   There are special exceptions to the terms and conditions of the GPL as it
 
8
   is applied to this software. View the full text of the exception in file
 
9
   EXCEPTIONS-CLIENT in the directory of this software distribution.
 
10
 
 
11
   This program is distributed in the hope that it will be useful,
 
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
   GNU General Public License for more details.
 
15
 
 
16
   You should have received a copy of the GNU General Public License
 
17
   along with this program; if not, write to the Free Software
 
18
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
19
19
 
20
20
#include <drizzled/global.h>
21
 
#include "libdrizzle_priv.h"
22
 
 
23
 
#include <libdrizzle/libdrizzle.h>
24
 
#include <libdrizzle/pack.h>
25
 
#include <libdrizzle/errmsg.h>
 
21
#include <mysys/my_sys.h>
 
22
#include "my_time.h"
 
23
#include <mysys/mysys_err.h>
 
24
#include <mystrings/m_string.h>
 
25
#include <mystrings/m_ctype.h>
 
26
#include "drizzle.h"
 
27
#include "errmsg.h"
 
28
#include <vio/violite.h>
26
29
#include <sys/stat.h>
27
30
#include <signal.h>
28
31
#include <time.h>
47
50
#ifdef HAVE_SYS_UN_H
48
51
#include <sys/un.h>
49
52
#endif
 
53
#include <mysys/my_pthread.h>        /* because of signal()  */
50
54
#ifndef INADDR_NONE
51
55
#define INADDR_NONE  -1
52
56
#endif
53
57
 
54
 
#include <stdlib.h>
55
 
#include <string.h>
56
 
 
57
 
/* Borrowed from libicu header */
58
 
 
59
 
#define U8_IS_SINGLE(c) (((c)&0x80)==0)
60
 
#define U8_LENGTH(c) \
61
 
    ((uint32_t)(c)<=0x7f ? 1 : \
62
 
        ((uint32_t)(c)<=0x7ff ? 2 : \
63
 
            ((uint32_t)(c)<=0xd7ff ? 3 : \
64
 
                ((uint32_t)(c)<=0xdfff || (uint32_t)(c)>0x10ffff ? 0 : \
65
 
                    ((uint32_t)(c)<=0xffff ? 3 : 4)\
66
 
                ) \
67
 
            ) \
68
 
        ) \
69
 
    )
70
 
 
 
58
#include <sql_common.h>
 
59
#include "client_settings.h"
71
60
 
72
61
#undef net_buffer_length
73
62
#undef max_allowed_packet
75
64
uint32_t     net_buffer_length= 8192;
76
65
uint32_t    max_allowed_packet= 1024L*1024L*1024L;
77
66
 
78
 
unsigned int drizzle_port=0;
79
 
 
80
67
#include <errno.h>
 
68
#define SOCKET_ERROR -1
 
69
 
 
70
/*
 
71
  If allowed through some configuration, then this needs to
 
72
  be changed
 
73
*/
 
74
#define MAX_LONG_DATA_LENGTH 8192
 
75
#define unsigned_field(A) ((A)->flags & UNSIGNED_FLAG)
 
76
 
 
77
static void append_wild(char *to,char *end,const char *wild);
81
78
 
82
79
 
83
80
static DRIZZLE_PARAMETERS drizzle_internal_parameters=
84
81
{&max_allowed_packet, &net_buffer_length, 0};
85
82
 
86
 
const DRIZZLE_PARAMETERS * drizzle_get_parameters(void)
 
83
const DRIZZLE_PARAMETERS *STDCALL drizzle_get_parameters(void)
87
84
{
88
85
  return &drizzle_internal_parameters;
89
86
}
90
87
 
91
 
unsigned int drizzle_get_default_port(void)
92
 
{
93
 
  return drizzle_port;
94
 
}
95
 
 
96
 
void drizzle_set_default_port(unsigned int port)
97
 
{
98
 
  drizzle_port= port;
99
 
}
 
88
bool STDCALL drizzle_thread_init()
 
89
{
 
90
  return my_thread_init();
 
91
}
 
92
 
 
93
void STDCALL drizzle_thread_end()
 
94
{
 
95
  my_thread_end();
 
96
}
 
97
 
100
98
 
101
99
/*
102
100
  Expand wildcard to a sql string
108
106
  end-=5;          /* Some extra */
109
107
  if (wild && wild[0])
110
108
  {
111
 
    to= strcpy(to," like '");
112
 
    to+= 7; /* strlen(" like '"); */
113
 
 
 
109
    to=strmov(to," like '");
114
110
    while (*wild && to < end)
115
111
    {
116
112
      if (*wild == '\\' || *wild == '\'')
125
121
}
126
122
 
127
123
/**************************************************************************
 
124
  Ignore SIGPIPE handler
 
125
   ARGSUSED
 
126
**************************************************************************/
 
127
 
 
128
sig_handler
 
129
my_pipe_sig_handler(int sig __attribute__((unused)))
 
130
{
 
131
#ifdef DONT_REMEMBER_SIGNAL
 
132
  (void) signal(SIGPIPE, my_pipe_sig_handler);
 
133
#endif
 
134
}
 
135
 
 
136
 
 
137
/**************************************************************************
128
138
  Change user and database
129
139
**************************************************************************/
130
140
 
131
141
int cli_read_change_user_result(DRIZZLE *drizzle)
132
142
{
133
 
  uint32_t pkt_length;
 
143
  ulong pkt_length;
134
144
 
135
145
  pkt_length= cli_safe_read(drizzle);
136
 
 
 
146
  
137
147
  if (pkt_length == packet_error)
138
148
    return 1;
139
149
 
140
150
  return 0;
141
151
}
142
152
 
143
 
bool drizzle_change_user(DRIZZLE *drizzle, const char *user,
144
 
                                 const char *passwd, const char *db)
 
153
bool STDCALL drizzle_change_user(DRIZZLE *drizzle, const char *user,
 
154
          const char *passwd, const char *db)
145
155
{
146
156
  char buff[USERNAME_LENGTH+SCRAMBLED_PASSWORD_CHAR_LENGTH+NAME_LEN+2];
147
157
  char *end= buff;
148
158
  int rc;
 
159
  const CHARSET_INFO *saved_cs= drizzle->charset;
 
160
 
 
161
  /* Get the connection-default character set. */
 
162
 
 
163
  if (drizzle_init_character_set(drizzle))
 
164
  {
 
165
    drizzle->charset= saved_cs;
 
166
    return(true);
 
167
  }
149
168
 
150
169
  /* Use an empty string instead of NULL. */
151
170
 
155
174
    passwd="";
156
175
 
157
176
  /* Store user into the buffer */
158
 
  end= strncpy(end, user, USERNAME_LENGTH) + USERNAME_LENGTH + 1;
 
177
  end= strmake(end, user, USERNAME_LENGTH) + 1;
159
178
 
160
179
  /* write scrambled password according to server capabilities */
161
180
  if (passwd[0])
162
181
  {
163
182
    {
164
183
      *end++= SCRAMBLE_LENGTH;
 
184
      scramble(end, drizzle->scramble, passwd);
165
185
      end+= SCRAMBLE_LENGTH;
166
186
    }
167
187
  }
168
188
  else
169
189
    *end++= '\0';                               /* empty password */
170
190
  /* Add database if needed */
171
 
  end= strncpy(end, db ? db : "", NAME_LEN) + NAME_LEN + 1;
 
191
  end= strmake(end, db ? db : "", NAME_LEN) + 1;
172
192
 
173
193
  /* Add character set number. */
 
194
 
174
195
  if (drizzle->server_capabilities & CLIENT_SECURE_CONNECTION)
175
196
  {
176
 
    int2store(end, (uint16_t) 45); // utf8mb4 number from mystrings/ctype-utf8.c
 
197
    int2store(end, (ushort) drizzle->charset->number);
177
198
    end+= 2;
178
199
  }
179
200
 
180
201
  /* Write authentication package */
181
 
  (void)simple_command(drizzle,COM_CHANGE_USER, (unsigned char*) buff, (uint32_t) (end-buff), 1);
 
202
  (void)simple_command(drizzle,COM_CHANGE_USER, (uchar*) buff, (ulong) (end-buff), 1);
182
203
 
183
204
  rc= (*drizzle->methods->read_change_user_result)(drizzle);
184
205
 
193
214
      free(drizzle->db);
194
215
 
195
216
    /* alloc new connect information */
196
 
    drizzle->user= strdup(user);
197
 
    drizzle->passwd= strdup(passwd);
198
 
    drizzle->db= db ? strdup(db) : 0;
 
217
    drizzle->user=  my_strdup(user,MYF(MY_WME));
 
218
    drizzle->passwd=my_strdup(passwd,MYF(MY_WME));
 
219
    drizzle->db=    db ? my_strdup(db,MYF(MY_WME)) : 0;
 
220
  }
 
221
  else
 
222
  {
 
223
    drizzle->charset= saved_cs;
199
224
  }
200
225
 
201
226
  return(rc);
202
227
}
203
228
 
204
 
#if defined(HAVE_GETPWUID) && defined(NO_GETPWUID_DECL)
205
 
struct passwd *getpwuid(uid_t);
206
 
char* getlogin(void);
207
 
#endif
208
229
 
209
230
/**************************************************************************
210
231
  Do a query. If query returned rows, free old rows.
211
232
  Read data by drizzle_store_result or by repeat call of drizzle_fetch_row
212
233
**************************************************************************/
213
234
 
214
 
int
 
235
int STDCALL
215
236
drizzle_query(DRIZZLE *drizzle, const char *query)
216
237
{
217
 
  return drizzle_real_query(drizzle,query, (uint32_t) strlen(query));
 
238
  return drizzle_real_query(drizzle,query, (uint) strlen(query));
218
239
}
219
240
 
220
241
 
222
243
  Return next field of the query results
223
244
**************************************************************************/
224
245
 
225
 
DRIZZLE_FIELD *
 
246
DRIZZLE_FIELD * STDCALL
226
247
drizzle_fetch_field(DRIZZLE_RES *result)
227
248
{
228
249
  if (result->current_field >= result->field_count)
235
256
  Move to a specific row and column
236
257
**************************************************************************/
237
258
 
238
 
void
 
259
void STDCALL
239
260
drizzle_data_seek(DRIZZLE_RES *result, uint64_t row)
240
261
{
241
262
  DRIZZLE_ROWS  *tmp=0;
252
273
  drizzle_fetch_field will return the next row or field after the last used
253
274
*************************************************************************/
254
275
 
255
 
DRIZZLE_ROW_OFFSET
 
276
DRIZZLE_ROW_OFFSET STDCALL
256
277
drizzle_row_seek(DRIZZLE_RES *result, DRIZZLE_ROW_OFFSET row)
257
278
{
258
279
  DRIZZLE_ROW_OFFSET return_value=result->data_cursor;
262
283
}
263
284
 
264
285
 
265
 
DRIZZLE_FIELD_OFFSET
 
286
DRIZZLE_FIELD_OFFSET STDCALL
266
287
drizzle_field_seek(DRIZZLE_RES *result, DRIZZLE_FIELD_OFFSET field_offset)
267
288
{
268
289
  DRIZZLE_FIELD_OFFSET return_value=result->current_field;
272
293
 
273
294
 
274
295
/*****************************************************************************
 
296
  List all databases
 
297
*****************************************************************************/
 
298
 
 
299
DRIZZLE_RES * STDCALL
 
300
drizzle_list_dbs(DRIZZLE *drizzle, const char *wild)
 
301
{
 
302
  char buff[255];
 
303
 
 
304
  append_wild(strmov(buff,"show databases"),buff+sizeof(buff),wild);
 
305
  if (drizzle_query(drizzle,buff))
 
306
    return(0);
 
307
  return (drizzle_store_result(drizzle));
 
308
}
 
309
 
 
310
 
 
311
/*****************************************************************************
275
312
  List all tables in a database
276
313
  If wild is given then only the tables matching wild is returned
277
314
*****************************************************************************/
278
315
 
279
 
DRIZZLE_RES *
 
316
DRIZZLE_RES * STDCALL
280
317
drizzle_list_tables(DRIZZLE *drizzle, const char *wild)
281
318
{
282
319
  char buff[255];
283
 
  char *ptr= strcpy(buff, "show tables");
284
 
  ptr+= 11; /* strlen("show tables"); */
285
320
 
286
 
  append_wild(ptr,buff+sizeof(buff),wild);
 
321
  append_wild(strmov(buff,"show tables"),buff+sizeof(buff),wild);
287
322
  if (drizzle_query(drizzle,buff))
288
323
    return(0);
289
324
  return (drizzle_store_result(drizzle));
293
328
DRIZZLE_FIELD *cli_list_fields(DRIZZLE *drizzle)
294
329
{
295
330
  DRIZZLE_DATA *query;
296
 
  if (!(query= cli_read_rows(drizzle,(DRIZZLE_FIELD*) 0, 8)))
 
331
  if (!(query= cli_read_rows(drizzle,(DRIZZLE_FIELD*) 0, 
 
332
           protocol_41(drizzle) ? 8 : 6)))
297
333
    return NULL;
298
334
 
299
 
  drizzle->field_count= (uint32_t) query->rows;
300
 
  return unpack_fields(query, drizzle->field_count, 1);
 
335
  drizzle->field_count= (uint) query->rows;
 
336
  return unpack_fields(query,&drizzle->field_alloc,
 
337
           drizzle->field_count, 1, drizzle->server_capabilities);
301
338
}
302
339
 
303
340
 
308
345
  show fields in 'table' like "wild"
309
346
**************************************************************************/
310
347
 
311
 
DRIZZLE_RES *
 
348
DRIZZLE_RES * STDCALL
312
349
drizzle_list_fields(DRIZZLE *drizzle, const char *table, const char *wild)
313
350
{
314
351
  DRIZZLE_RES   *result;
315
352
  DRIZZLE_FIELD *fields;
316
 
  char buff[257], *end;
317
 
 
318
 
  end= strncpy(buff, table, 128) + 128;
319
 
  end= strncpy(end+1, wild ? wild : "", 128) + 128;
320
 
 
 
353
  char       buff[257],*end;
 
354
 
 
355
  end=strmake(strmake(buff, table,128)+1,wild ? wild : "",128);
321
356
  free_old_query(drizzle);
322
 
  if (simple_command(drizzle, COM_FIELD_LIST, (unsigned char*) buff,
323
 
                     (uint32_t) (end-buff), 1) ||
 
357
  if (simple_command(drizzle, COM_FIELD_LIST, (uchar*) buff,
 
358
                     (ulong) (end-buff), 1) ||
324
359
      !(fields= (*drizzle->methods->list_fields)(drizzle)))
325
360
    return(NULL);
326
361
 
327
362
  if (!(result = (DRIZZLE_RES *) malloc(sizeof(DRIZZLE_RES))))
328
363
    return(NULL);
329
364
 
330
 
  memset(result, 0, sizeof(DRIZZLE_RES));
331
 
 
332
365
  result->methods= drizzle->methods;
 
366
  result->field_alloc=drizzle->field_alloc;
333
367
  drizzle->fields=0;
334
368
  result->field_count = drizzle->field_count;
335
369
  result->fields= fields;
339
373
 
340
374
/* List all running processes (threads) in server */
341
375
 
342
 
DRIZZLE_RES *
 
376
DRIZZLE_RES * STDCALL
343
377
drizzle_list_processes(DRIZZLE *drizzle)
344
378
{
345
379
  DRIZZLE_DATA *fields;
346
 
  uint32_t field_count;
347
 
  unsigned char *pos;
 
380
  uint field_count;
 
381
  uchar *pos;
348
382
 
349
383
  if (simple_command(drizzle,COM_PROCESS_INFO,0,0,0))
350
384
    return(0);
351
385
  free_old_query(drizzle);
352
 
  pos=(unsigned char*) drizzle->net.read_pos;
353
 
  field_count=(uint32_t) net_field_length(&pos);
354
 
  if (!(fields = (*drizzle->methods->read_rows)(drizzle,(DRIZZLE_FIELD*) 0, 7)))
 
386
  pos=(uchar*) drizzle->net.read_pos;
 
387
  field_count=(uint) net_field_length(&pos);
 
388
  if (!(fields = (*drizzle->methods->read_rows)(drizzle,(DRIZZLE_FIELD*) 0,
 
389
                protocol_41(drizzle) ? 7 : 5)))
355
390
    return(NULL);
356
 
  if (!(drizzle->fields=unpack_fields(fields, field_count, 0)))
 
391
  if (!(drizzle->fields=unpack_fields(fields,&drizzle->field_alloc,field_count,0,
 
392
            drizzle->server_capabilities)))
357
393
    return(0);
358
394
  drizzle->status=DRIZZLE_STATUS_GET_RESULT;
359
395
  drizzle->field_count=field_count;
361
397
}
362
398
 
363
399
 
364
 
int
365
 
drizzle_shutdown(DRIZZLE *drizzle)
 
400
int STDCALL
 
401
drizzle_shutdown(DRIZZLE *drizzle, enum drizzle_enum_shutdown_level shutdown_level)
366
402
{
367
 
  return(simple_command(drizzle, COM_SHUTDOWN, 0, 0, 0));
 
403
  uchar level[1];
 
404
  level[0]= (uchar) shutdown_level;
 
405
  return(simple_command(drizzle, COM_SHUTDOWN, level, 1, 0));
368
406
}
369
407
 
370
408
 
371
 
int
372
 
drizzle_refresh(DRIZZLE *drizzle, uint32_t options)
 
409
int STDCALL
 
410
drizzle_refresh(DRIZZLE *drizzle,uint options)
373
411
{
374
 
  unsigned char bits[1];
375
 
  bits[0]= (unsigned char) options;
 
412
  uchar bits[1];
 
413
  bits[0]= (uchar) options;
376
414
  return(simple_command(drizzle, COM_REFRESH, bits, 1, 0));
377
415
}
378
416
 
379
417
 
380
 
int32_t
 
418
int32_t STDCALL
381
419
drizzle_kill(DRIZZLE *drizzle, uint32_t pid)
382
420
{
383
 
  unsigned char buff[4];
 
421
  uchar buff[4];
384
422
  int4store(buff,pid);
385
423
  return(simple_command(drizzle,COM_PROCESS_KILL,buff,sizeof(buff),0));
386
424
}
387
425
 
388
426
 
389
 
int
 
427
int STDCALL
390
428
drizzle_set_server_option(DRIZZLE *drizzle, enum enum_drizzle_set_option option)
391
429
{
392
 
  unsigned char buff[2];
393
 
  int2store(buff, (uint32_t) option);
 
430
  uchar buff[2];
 
431
  int2store(buff, (uint) option);
394
432
  return(simple_command(drizzle, COM_SET_OPTION, buff, sizeof(buff), 0));
395
433
}
396
434
 
400
438
  drizzle->net.read_pos[drizzle->packet_length]=0;  /* End of stat string */
401
439
  if (!drizzle->net.read_pos[0])
402
440
  {
403
 
    drizzle_set_error(drizzle, CR_WRONG_HOST_INFO, sqlstate_get_unknown());
 
441
    set_drizzle_error(drizzle, CR_WRONG_HOST_INFO, unknown_sqlstate);
404
442
    return drizzle->net.last_error;
405
443
  }
406
444
  return (char*) drizzle->net.read_pos;
407
445
}
408
446
 
409
447
 
410
 
int
 
448
const char * STDCALL
 
449
drizzle_stat(DRIZZLE *drizzle)
 
450
{
 
451
  if (simple_command(drizzle,COM_STATISTICS,0,0,0))
 
452
    return(drizzle->net.last_error);
 
453
  return((*drizzle->methods->read_statistics)(drizzle));
 
454
}
 
455
 
 
456
 
 
457
int STDCALL
411
458
drizzle_ping(DRIZZLE *drizzle)
412
459
{
413
460
  int res;
418
465
}
419
466
 
420
467
 
421
 
const char *
 
468
const char * STDCALL
422
469
drizzle_get_server_info(const DRIZZLE *drizzle)
423
470
{
424
471
  return((char*) drizzle->server_version);
425
472
}
426
473
 
427
474
 
428
 
const char *
 
475
const char * STDCALL
429
476
drizzle_get_host_info(const DRIZZLE *drizzle)
430
477
{
431
478
  return(drizzle->host_info);
432
479
}
433
480
 
434
481
 
435
 
uint32_t
 
482
uint STDCALL
436
483
drizzle_get_proto_info(const DRIZZLE *drizzle)
437
484
{
438
485
  return (drizzle->protocol_version);
439
486
}
440
487
 
441
 
const char *
 
488
const char * STDCALL
442
489
drizzle_get_client_info(void)
443
490
{
444
 
  return (char*) VERSION;
 
491
  return (char*) MYSQL_SERVER_VERSION;
445
492
}
446
493
 
447
 
uint32_t drizzle_get_client_version(void)
 
494
uint32_t STDCALL drizzle_get_client_version(void)
448
495
{
449
 
  return DRIZZLE_VERSION_ID;
 
496
  return MYSQL_VERSION_ID;
450
497
}
451
498
 
452
 
bool drizzle_eof(const DRIZZLE_RES *res)
 
499
bool STDCALL drizzle_eof(const DRIZZLE_RES *res)
453
500
{
454
501
  return res->eof;
455
502
}
456
503
 
457
 
const DRIZZLE_FIELD * drizzle_fetch_field_direct(const DRIZZLE_RES *res, unsigned int fieldnr)
 
504
const DRIZZLE_FIELD * STDCALL drizzle_fetch_field_direct(const DRIZZLE_RES *res, unsigned int fieldnr)
458
505
{
459
506
  return &(res)->fields[fieldnr];
460
507
}
461
508
 
462
 
const DRIZZLE_FIELD * drizzle_fetch_fields(const DRIZZLE_RES *res)
 
509
const DRIZZLE_FIELD * STDCALL drizzle_fetch_fields(const DRIZZLE_RES *res)
463
510
{
464
511
  return res->fields;
465
512
}
466
513
 
467
 
DRIZZLE_ROW_OFFSET drizzle_row_tell(const DRIZZLE_RES *res)
 
514
DRIZZLE_ROW_OFFSET STDCALL drizzle_row_tell(const DRIZZLE_RES *res)
468
515
{
469
516
  return res->data_cursor;
470
517
}
471
518
 
472
 
DRIZZLE_FIELD_OFFSET drizzle_field_tell(const DRIZZLE_RES *res)
 
519
DRIZZLE_FIELD_OFFSET STDCALL drizzle_field_tell(const DRIZZLE_RES *res)
473
520
{
474
521
  return res->current_field;
475
522
}
476
523
 
477
524
/* DRIZZLE */
478
525
 
479
 
unsigned int drizzle_field_count(const DRIZZLE *drizzle)
 
526
unsigned int STDCALL drizzle_field_count(const DRIZZLE *drizzle)
480
527
{
481
528
  return drizzle->field_count;
482
529
}
483
530
 
484
 
uint64_t drizzle_affected_rows(const DRIZZLE *drizzle)
 
531
uint64_t STDCALL drizzle_affected_rows(const DRIZZLE *drizzle)
485
532
{
486
533
  return drizzle->affected_rows;
487
534
}
488
535
 
489
 
uint64_t drizzle_insert_id(const DRIZZLE *drizzle)
 
536
uint64_t STDCALL drizzle_insert_id(const DRIZZLE *drizzle)
490
537
{
491
538
  return drizzle->insert_id;
492
539
}
493
540
 
494
 
const char * drizzle_sqlstate(const DRIZZLE *drizzle)
 
541
const char *STDCALL drizzle_sqlstate(const DRIZZLE *drizzle)
495
542
{
496
 
  return drizzle ? drizzle->net.sqlstate : sqlstate_get_cant_connect();
 
543
  return drizzle ? drizzle->net.sqlstate : cant_connect_sqlstate;
497
544
}
498
545
 
499
 
uint32_t drizzle_warning_count(const DRIZZLE *drizzle)
 
546
uint32_t STDCALL drizzle_warning_count(const DRIZZLE *drizzle)
500
547
{
501
548
  return drizzle->warning_count;
502
549
}
503
550
 
504
 
const char * drizzle_info(const DRIZZLE *drizzle)
 
551
const char *STDCALL drizzle_info(const DRIZZLE *drizzle)
505
552
{
506
553
  return drizzle->info;
507
554
}
508
555
 
509
 
uint32_t drizzle_thread_id(const DRIZZLE *drizzle)
 
556
uint32_t STDCALL drizzle_thread_id(const DRIZZLE *drizzle)
510
557
{
511
558
  return drizzle->thread_id;
512
559
}
513
560
 
 
561
const char * STDCALL drizzle_character_set_name(const DRIZZLE *drizzle)
 
562
{
 
563
  return drizzle->charset->csname;
 
564
}
 
565
 
 
566
void STDCALL drizzle_get_character_set_info(const DRIZZLE *drizzle, MY_CHARSET_INFO *csinfo)
 
567
{
 
568
  csinfo->number   = drizzle->charset->number;
 
569
  csinfo->state    = drizzle->charset->state;
 
570
  csinfo->csname   = drizzle->charset->csname;
 
571
  csinfo->name     = drizzle->charset->name;
 
572
  csinfo->comment  = drizzle->charset->comment;
 
573
  csinfo->mbminlen = drizzle->charset->mbminlen;
 
574
  csinfo->mbmaxlen = drizzle->charset->mbmaxlen;
 
575
 
 
576
  if (drizzle->options.charset_dir)
 
577
    csinfo->dir = drizzle->options.charset_dir;
 
578
  else
 
579
    csinfo->dir = charsets_dir;
 
580
}
 
581
 
 
582
uint STDCALL drizzle_thread_safe(void)
 
583
{
 
584
  return 1;
 
585
}
 
586
 
 
587
 
 
588
bool STDCALL drizzle_embedded(void)
 
589
{
 
590
#ifdef EMBEDDED_LIBRARY
 
591
  return true;
 
592
#else
 
593
  return false;
 
594
#endif
 
595
}
 
596
 
514
597
/****************************************************************************
515
598
  Some support functions
516
599
****************************************************************************/
521
604
 
522
605
void my_net_local_init(NET *net)
523
606
{
524
 
  net->max_packet=   (uint32_t) net_buffer_length;
 
607
  net->max_packet=   (uint) net_buffer_length;
525
608
  my_net_set_read_timeout(net, CLIENT_NET_READ_TIMEOUT);
526
609
  my_net_set_write_timeout(net, CLIENT_NET_WRITE_TIMEOUT);
527
610
  net->retry_count=  1;
528
 
  net->max_packet_size= (net_buffer_length > max_allowed_packet) ?
529
 
    net_buffer_length : max_allowed_packet;
 
611
  net->max_packet_size= max(net_buffer_length, max_allowed_packet);
 
612
}
 
613
 
 
614
/*
 
615
  This function is used to create HEX string that you
 
616
  can use in a SQL statement in of the either ways:
 
617
    INSERT INTO blob_column VALUES (0xAABBCC);  (any DRIZZLE version)
 
618
    INSERT INTO blob_column VALUES (X'AABBCC'); (4.1 and higher)
 
619
  
 
620
  The string in "from" is encoded to a HEX string.
 
621
  The result is placed in "to" and a terminating null byte is appended.
 
622
  
 
623
  The string pointed to by "from" must be "length" bytes long.
 
624
  You must allocate the "to" buffer to be at least length*2+1 bytes long.
 
625
  Each character needs two bytes, and you need room for the terminating
 
626
  null byte. When drizzle_hex_string() returns, the contents of "to" will
 
627
  be a null-terminated string. The return value is the length of the
 
628
  encoded string, not including the terminating null character.
 
629
 
 
630
  The return value does not contain any leading 0x or a leading X' and
 
631
  trailing '. The caller must supply whichever of those is desired.
 
632
*/
 
633
 
 
634
uint32_t STDCALL
 
635
drizzle_hex_string(char *to, const char *from, uint32_t length)
 
636
{
 
637
  char *to0= to;
 
638
  const char *end;
 
639
            
 
640
  for (end= from + length; from < end; from++)
 
641
  {
 
642
    *to++= _dig_vec_upper[((unsigned char) *from) >> 4];
 
643
    *to++= _dig_vec_upper[((unsigned char) *from) & 0x0F];
 
644
  }
 
645
  *to= '\0';
 
646
  return (uint32_t) (to-to0);
530
647
}
531
648
 
532
649
/*
535
652
  Returns the length of the to string
536
653
*/
537
654
 
538
 
uint32_t
 
655
uint32_t STDCALL
539
656
drizzle_escape_string(char *to,const char *from, uint32_t length)
540
657
{
541
 
  const char *to_start= to;
542
 
  const char *end, *to_end=to_start + 2*length;
543
 
  bool overflow= false;
544
 
  for (end= from + length; from < end; from++)
 
658
  return escape_string_for_drizzle(default_charset_info, to, 0, from, length);
 
659
}
 
660
 
 
661
uint32_t STDCALL
 
662
drizzle_real_escape_string(DRIZZLE *drizzle, char *to,const char *from,
 
663
       uint32_t length)
 
664
{
 
665
  if (drizzle->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES)
 
666
    return escape_quotes_for_drizzle(drizzle->charset, to, 0, from, length);
 
667
  return escape_string_for_drizzle(drizzle->charset, to, 0, from, length);
 
668
}
 
669
 
 
670
void STDCALL
 
671
myodbc_remove_escape(const DRIZZLE *drizzle, char *name)
 
672
{
 
673
  char *to;
 
674
#ifdef USE_MB
 
675
  bool use_mb_flag= use_mb(drizzle->charset);
 
676
  char *end=NULL;
 
677
  if (use_mb_flag)
 
678
    for (end=name; *end ; end++) ;
 
679
#endif
 
680
 
 
681
  for (to=name ; *name ; name++)
545
682
  {
546
 
    uint32_t tmp_length;
547
 
    char escape= 0;
548
 
    if (!U8_IS_SINGLE(*from))
 
683
#ifdef USE_MB
 
684
    int l;
 
685
    if (use_mb_flag && (l = my_ismbchar( drizzle->charset, name , end ) ) )
549
686
    {
550
 
      tmp_length= U8_LENGTH(*from);
551
 
      if (to + tmp_length > to_end)
552
 
      {
553
 
        overflow= true;
554
 
        break;
555
 
      }
556
 
      while (tmp_length--)
557
 
        *to++= *from++;
558
 
      from--;
 
687
      while (l--)
 
688
        *to++ = *name++;
 
689
      name--;
559
690
      continue;
560
691
    }
561
 
    switch (*from) {
562
 
    case 0:                             /* Must be escaped for 'mysql' */
563
 
      escape= '0';
564
 
      break;
565
 
    case '\n':                          /* Must be escaped for logs */
566
 
      escape= 'n';
567
 
      break;
568
 
    case '\r':
569
 
      escape= 'r';
570
 
      break;
571
 
    case '\\':
572
 
      escape= '\\';
573
 
      break;
574
 
    case '\'':
575
 
      escape= '\'';
576
 
      break;
577
 
    case '"':                           /* Better safe than sorry */
578
 
      escape= '"';
579
 
      break;
580
 
    case '\032':                        /* This gives problems on Win32 */
581
 
      escape= 'Z';
582
 
      break;
583
 
    }
584
 
    if (escape)
585
 
    {
586
 
      if (to + 2 > to_end)
587
 
      {
588
 
        overflow= true;
589
 
        break;
590
 
      }
591
 
      *to++= '\\';
592
 
      *to++= escape;
593
 
    }
594
 
    else
595
 
    {
596
 
      if (to + 1 > to_end)
597
 
      {
598
 
        overflow= true;
599
 
        break;
600
 
      }
601
 
      *to++= *from;
602
 
    }
 
692
#endif
 
693
    if (*name == '\\' && name[1])
 
694
      name++;
 
695
    *to++= *name;
603
696
  }
604
 
  *to= 0;
605
 
  return overflow ? (size_t) -1 : (size_t) (to - to_start);
 
697
  *to=0;
606
698
}
607
699
 
608
700
int cli_unbuffered_fetch(DRIZZLE *drizzle, char **row)
623
715
  Commit the current transaction
624
716
*/
625
717
 
626
 
bool drizzle_commit(DRIZZLE *drizzle)
 
718
bool STDCALL drizzle_commit(DRIZZLE *drizzle)
627
719
{
628
720
  return((bool) drizzle_real_query(drizzle, "commit", 6));
629
721
}
632
724
  Rollback the current transaction
633
725
*/
634
726
 
635
 
bool drizzle_rollback(DRIZZLE *drizzle)
 
727
bool STDCALL drizzle_rollback(DRIZZLE *drizzle)
636
728
{
637
729
  return((bool) drizzle_real_query(drizzle, "rollback", 8));
638
730
}
642
734
  Set autocommit to either true or false
643
735
*/
644
736
 
645
 
bool drizzle_autocommit(DRIZZLE *drizzle, bool auto_mode)
 
737
bool STDCALL drizzle_autocommit(DRIZZLE *drizzle, bool auto_mode)
646
738
{
647
739
  return((bool) drizzle_real_query(drizzle, auto_mode ?
648
740
                                         "set autocommit=1":"set autocommit=0",
659
751
  to be read using drizzle_next_result()
660
752
*/
661
753
 
662
 
bool drizzle_more_results(const DRIZZLE *drizzle)
 
754
bool STDCALL drizzle_more_results(const DRIZZLE *drizzle)
663
755
{
664
756
  return (drizzle->server_status & SERVER_MORE_RESULTS_EXISTS) ? true:false;
665
757
}
668
760
/*
669
761
  Reads and returns the next query results
670
762
*/
671
 
int drizzle_next_result(DRIZZLE *drizzle)
 
763
int STDCALL drizzle_next_result(DRIZZLE *drizzle)
672
764
{
673
765
  if (drizzle->status != DRIZZLE_STATUS_READY)
674
766
  {
675
 
    drizzle_set_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, sqlstate_get_unknown());
 
767
    set_drizzle_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
676
768
    return(1);
677
769
  }
678
770
 
686
778
}
687
779
 
688
780
 
689
 
DRIZZLE_RES * drizzle_use_result(DRIZZLE *drizzle)
 
781
DRIZZLE_RES * STDCALL drizzle_use_result(DRIZZLE *drizzle)
690
782
{
691
783
  return (*drizzle->methods->use_result)(drizzle);
692
784
}
693
785
 
694
 
bool drizzle_read_query_result(DRIZZLE *drizzle)
 
786
bool STDCALL drizzle_read_query_result(DRIZZLE *drizzle)
695
787
{
696
788
  return (*drizzle->methods->read_query_result)(drizzle);
697
789
}