~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzleclient/libdrizzle.c

  • Committer: Monty Taylor
  • Date: 2009-02-05 21:07:57 UTC
  • mto: This revision was merged to the branch mainline in revision 840.
  • Revision ID: mordred@inaugust.com-20090205210757-6487lf69y3mndcds
Fixed warnings badness in csv_alter_table test.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 */
 
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
 */
19
19
 
20
20
#include <drizzled/global.h>
21
 
#include <mysys/my_sys.h>
22
 
#include "my_time.h"
23
 
#include "drizzle.h"
 
21
#include "libdrizzle_priv.h"
 
22
 
 
23
#include "libdrizzle.h"
24
24
#include "errmsg.h"
25
 
#include <vio/violite.h>
 
25
#include "pack.h"
 
26
 
26
27
#include <sys/stat.h>
27
28
#include <signal.h>
28
29
#include <time.h>
51
52
#define INADDR_NONE  -1
52
53
#endif
53
54
 
54
 
#include <sql_common.h>
55
 
#include "client_settings.h"
56
 
#include <drizzled/version.h>
 
55
#include <stdlib.h>
 
56
#include <string.h>
 
57
#include <mystrings/utf8.h>
 
58
 
57
59
 
58
60
#undef net_buffer_length
59
61
#undef max_allowed_packet
61
63
uint32_t     net_buffer_length= 8192;
62
64
uint32_t    max_allowed_packet= 1024L*1024L*1024L;
63
65
 
 
66
unsigned int drizzle_port=0;
 
67
 
64
68
#include <errno.h>
65
 
#define SOCKET_ERROR -1
66
 
 
67
 
/*
68
 
  If allowed through some configuration, then this needs to
69
 
  be changed
70
 
*/
71
 
#define MAX_LONG_DATA_LENGTH 8192
72
 
#define unsigned_field(A) ((A)->flags & UNSIGNED_FLAG)
73
69
 
74
70
 
75
71
static DRIZZLE_PARAMETERS drizzle_internal_parameters=
80
76
  return &drizzle_internal_parameters;
81
77
}
82
78
 
83
 
bool drizzle_thread_init()
84
 
{
85
 
  return my_thread_init();
86
 
}
87
 
 
88
 
void drizzle_thread_end()
89
 
{
90
 
  my_thread_end();
91
 
}
92
 
 
 
79
unsigned int drizzle_get_default_port(void)
 
80
{
 
81
  return drizzle_port;
 
82
}
 
83
 
 
84
void drizzle_set_default_port(unsigned int port)
 
85
{
 
86
  drizzle_port= port;
 
87
}
93
88
 
94
89
/*
95
90
  Expand wildcard to a sql string
118
113
}
119
114
 
120
115
/**************************************************************************
121
 
  Ignore SIGPIPE handler
122
 
   ARGSUSED
123
 
**************************************************************************/
124
 
 
125
 
sig_handler
126
 
my_pipe_sig_handler(int sig __attribute__((unused)))
127
 
{
128
 
#ifdef DONT_REMEMBER_SIGNAL
129
 
  (void) signal(SIGPIPE, my_pipe_sig_handler);
130
 
#endif
131
 
}
132
 
 
133
 
 
134
 
/**************************************************************************
135
116
  Change user and database
136
117
**************************************************************************/
137
118
 
140
121
  uint32_t pkt_length;
141
122
 
142
123
  pkt_length= cli_safe_read(drizzle);
143
 
  
 
124
 
144
125
  if (pkt_length == packet_error)
145
126
    return 1;
146
127
 
153
134
  char buff[USERNAME_LENGTH+SCRAMBLED_PASSWORD_CHAR_LENGTH+NAME_LEN+2];
154
135
  char *end= buff;
155
136
  int rc;
156
 
  const CHARSET_INFO *saved_cs= drizzle->charset;
157
 
 
158
 
  /* Get the connection-default character set. */
159
 
 
160
 
  if (drizzle_init_character_set(drizzle))
161
 
  {
162
 
    drizzle->charset= saved_cs;
163
 
    return(true);
164
 
  }
165
137
 
166
138
  /* Use an empty string instead of NULL. */
167
139
 
187
159
  end= strncpy(end, db ? db : "", NAME_LEN) + NAME_LEN + 1;
188
160
 
189
161
  /* Add character set number. */
190
 
 
191
162
  if (drizzle->server_capabilities & CLIENT_SECURE_CONNECTION)
192
163
  {
193
 
    int2store(end, (ushort) drizzle->charset->number);
 
164
    int2store(end, (uint16_t) 45); // utf8mb4 number from mystrings/ctype-utf8.c
194
165
    end+= 2;
195
166
  }
196
167
 
197
168
  /* Write authentication package */
198
 
  (void)simple_command(drizzle,COM_CHANGE_USER, (uchar*) buff, (uint32_t) (end-buff), 1);
 
169
  (void)simple_command(drizzle,COM_CHANGE_USER, (unsigned char*) buff, (uint32_t) (end-buff), 1);
199
170
 
200
171
  rc= (*drizzle->methods->read_change_user_result)(drizzle);
201
172
 
214
185
    drizzle->passwd= strdup(passwd);
215
186
    drizzle->db= db ? strdup(db) : 0;
216
187
  }
217
 
  else
218
 
  {
219
 
    drizzle->charset= saved_cs;
220
 
  }
221
188
 
222
189
  return(rc);
223
190
}
235
202
int
236
203
drizzle_query(DRIZZLE *drizzle, const char *query)
237
204
{
238
 
  return drizzle_real_query(drizzle,query, (uint) strlen(query));
 
205
  return drizzle_real_query(drizzle,query, (uint32_t) strlen(query));
239
206
}
240
207
 
241
208
 
317
284
  if (!(query= cli_read_rows(drizzle,(DRIZZLE_FIELD*) 0, 8)))
318
285
    return NULL;
319
286
 
320
 
  drizzle->field_count= (uint) query->rows;
321
 
  return unpack_fields(query,&drizzle->field_alloc, drizzle->field_count, 1);
 
287
  drizzle->field_count= (uint32_t) query->rows;
 
288
  return unpack_fields(query, drizzle->field_count, 1);
322
289
}
323
290
 
324
291
 
340
307
  end= strncpy(end+1, wild ? wild : "", 128) + 128;
341
308
 
342
309
  free_old_query(drizzle);
343
 
  if (simple_command(drizzle, COM_FIELD_LIST, (uchar*) buff,
 
310
  if (simple_command(drizzle, COM_FIELD_LIST, (unsigned char*) buff,
344
311
                     (uint32_t) (end-buff), 1) ||
345
312
      !(fields= (*drizzle->methods->list_fields)(drizzle)))
346
313
    return(NULL);
351
318
  memset(result, 0, sizeof(DRIZZLE_RES));
352
319
 
353
320
  result->methods= drizzle->methods;
354
 
  result->field_alloc=drizzle->field_alloc;
355
321
  drizzle->fields=0;
356
322
  result->field_count = drizzle->field_count;
357
323
  result->fields= fields;
365
331
drizzle_list_processes(DRIZZLE *drizzle)
366
332
{
367
333
  DRIZZLE_DATA *fields;
368
 
  uint field_count;
369
 
  uchar *pos;
 
334
  uint32_t field_count;
 
335
  unsigned char *pos;
370
336
 
371
337
  if (simple_command(drizzle,COM_PROCESS_INFO,0,0,0))
372
338
    return(0);
373
339
  free_old_query(drizzle);
374
 
  pos=(uchar*) drizzle->net.read_pos;
375
 
  field_count=(uint) net_field_length(&pos);
 
340
  pos=(unsigned char*) drizzle->net.read_pos;
 
341
  field_count=(uint32_t) net_field_length(&pos);
376
342
  if (!(fields = (*drizzle->methods->read_rows)(drizzle,(DRIZZLE_FIELD*) 0, 7)))
377
343
    return(NULL);
378
 
  if (!(drizzle->fields=unpack_fields(fields,&drizzle->field_alloc,field_count,0)))
 
344
  if (!(drizzle->fields=unpack_fields(fields, field_count, 0)))
379
345
    return(0);
380
346
  drizzle->status=DRIZZLE_STATUS_GET_RESULT;
381
347
  drizzle->field_count=field_count;
384
350
 
385
351
 
386
352
int
387
 
drizzle_shutdown(DRIZZLE *drizzle, enum drizzle_enum_shutdown_level shutdown_level)
 
353
drizzle_shutdown(DRIZZLE *drizzle)
388
354
{
389
 
  uchar level[1];
390
 
  level[0]= (uchar) shutdown_level;
391
 
  return(simple_command(drizzle, COM_SHUTDOWN, level, 1, 0));
 
355
  return(simple_command(drizzle, COM_SHUTDOWN, 0, 0, 0));
392
356
}
393
357
 
394
358
 
395
359
int
396
 
drizzle_refresh(DRIZZLE *drizzle,uint options)
 
360
drizzle_refresh(DRIZZLE *drizzle, uint32_t options)
397
361
{
398
 
  uchar bits[1];
399
 
  bits[0]= (uchar) options;
 
362
  unsigned char bits[1];
 
363
  bits[0]= (unsigned char) options;
400
364
  return(simple_command(drizzle, COM_REFRESH, bits, 1, 0));
401
365
}
402
366
 
404
368
int32_t
405
369
drizzle_kill(DRIZZLE *drizzle, uint32_t pid)
406
370
{
407
 
  uchar buff[4];
 
371
  unsigned char buff[4];
408
372
  int4store(buff,pid);
409
373
  return(simple_command(drizzle,COM_PROCESS_KILL,buff,sizeof(buff),0));
410
374
}
413
377
int
414
378
drizzle_set_server_option(DRIZZLE *drizzle, enum enum_drizzle_set_option option)
415
379
{
416
 
  uchar buff[2];
417
 
  int2store(buff, (uint) option);
 
380
  unsigned char buff[2];
 
381
  int2store(buff, (uint32_t) option);
418
382
  return(simple_command(drizzle, COM_SET_OPTION, buff, sizeof(buff), 0));
419
383
}
420
384
 
424
388
  drizzle->net.read_pos[drizzle->packet_length]=0;  /* End of stat string */
425
389
  if (!drizzle->net.read_pos[0])
426
390
  {
427
 
    set_drizzle_error(drizzle, CR_WRONG_HOST_INFO, unknown_sqlstate);
 
391
    drizzle_set_error(drizzle, CR_WRONG_HOST_INFO, sqlstate_get_unknown());
428
392
    return drizzle->net.last_error;
429
393
  }
430
394
  return (char*) drizzle->net.read_pos;
456
420
}
457
421
 
458
422
 
459
 
uint
 
423
uint32_t
460
424
drizzle_get_proto_info(const DRIZZLE *drizzle)
461
425
{
462
426
  return (drizzle->protocol_version);
465
429
const char *
466
430
drizzle_get_client_info(void)
467
431
{
468
 
  return (char*) DRIZZLE_SERVER_VERSION;
 
432
  return (char*) VERSION;
469
433
}
470
434
 
471
435
uint32_t drizzle_get_client_version(void)
517
481
 
518
482
const char * drizzle_sqlstate(const DRIZZLE *drizzle)
519
483
{
520
 
  return drizzle ? drizzle->net.sqlstate : cant_connect_sqlstate;
 
484
  return drizzle ? drizzle->net.sqlstate : sqlstate_get_cant_connect();
521
485
}
522
486
 
523
487
uint32_t drizzle_warning_count(const DRIZZLE *drizzle)
535
499
  return drizzle->thread_id;
536
500
}
537
501
 
538
 
const char * drizzle_character_set_name(const DRIZZLE *drizzle)
539
 
{
540
 
  return drizzle->charset->csname;
541
 
}
542
 
 
543
 
void drizzle_get_character_set_info(const DRIZZLE *drizzle, MY_CHARSET_INFO *csinfo)
544
 
{
545
 
  csinfo->number   = drizzle->charset->number;
546
 
  csinfo->state    = drizzle->charset->state;
547
 
  csinfo->csname   = drizzle->charset->csname;
548
 
  csinfo->name     = drizzle->charset->name;
549
 
  csinfo->comment  = drizzle->charset->comment;
550
 
  csinfo->mbminlen = drizzle->charset->mbminlen;
551
 
  csinfo->mbmaxlen = drizzle->charset->mbmaxlen;
552
 
 
553
 
  if (drizzle->options.charset_dir)
554
 
    csinfo->dir = drizzle->options.charset_dir;
555
 
  else
556
 
    csinfo->dir = charsets_dir;
557
 
}
558
 
 
559
 
uint drizzle_thread_safe(void)
560
 
{
561
 
  return 1;
562
 
}
563
 
 
564
 
 
565
 
bool drizzle_embedded(void)
566
 
{
567
 
#ifdef EMBEDDED_LIBRARY
568
 
  return true;
569
 
#else
570
 
  return false;
571
 
#endif
572
 
}
573
 
 
574
502
/****************************************************************************
575
503
  Some support functions
576
504
****************************************************************************/
581
509
 
582
510
void my_net_local_init(NET *net)
583
511
{
584
 
  net->max_packet=   (uint) net_buffer_length;
 
512
  net->max_packet=   (uint32_t) net_buffer_length;
585
513
  my_net_set_read_timeout(net, CLIENT_NET_READ_TIMEOUT);
586
514
  my_net_set_write_timeout(net, CLIENT_NET_WRITE_TIMEOUT);
587
515
  net->retry_count=  1;
588
 
  net->max_packet_size= max(net_buffer_length, max_allowed_packet);
589
 
}
590
 
 
591
 
/*
592
 
  This function is used to create HEX string that you
593
 
  can use in a SQL statement in of the either ways:
594
 
    INSERT INTO blob_column VALUES (0xAABBCC);  (any DRIZZLE version)
595
 
    INSERT INTO blob_column VALUES (X'AABBCC'); 
596
 
  
597
 
  The string in "from" is encoded to a HEX string.
598
 
  The result is placed in "to" and a terminating null byte is appended.
599
 
  
600
 
  The string pointed to by "from" must be "length" bytes long.
601
 
  You must allocate the "to" buffer to be at least length*2+1 bytes long.
602
 
  Each character needs two bytes, and you need room for the terminating
603
 
  null byte. When drizzle_hex_string() returns, the contents of "to" will
604
 
  be a null-terminated string. The return value is the length of the
605
 
  encoded string, not including the terminating null character.
606
 
 
607
 
  The return value does not contain any leading 0x or a leading X' and
608
 
  trailing '. The caller must supply whichever of those is desired.
609
 
*/
610
 
 
611
 
uint32_t
612
 
drizzle_hex_string(char *to, const char *from, uint32_t length)
613
 
{
614
 
  char *to0= to;
615
 
  const char *end;
616
 
            
617
 
  for (end= from + length; from < end; from++)
618
 
  {
619
 
    *to++= _dig_vec_upper[((unsigned char) *from) >> 4];
620
 
    *to++= _dig_vec_upper[((unsigned char) *from) & 0x0F];
621
 
  }
622
 
  *to= '\0';
623
 
  return (uint32_t) (to-to0);
 
516
  net->max_packet_size= (net_buffer_length > max_allowed_packet) ?
 
517
    net_buffer_length : max_allowed_packet;
624
518
}
625
519
 
626
520
/*
632
526
uint32_t
633
527
drizzle_escape_string(char *to,const char *from, uint32_t length)
634
528
{
635
 
  return escape_string_for_drizzle(default_charset_info, to, 0, from, length);
636
 
}
637
 
 
638
 
uint32_t
639
 
drizzle_real_escape_string(DRIZZLE *drizzle, char *to,const char *from,
640
 
       uint32_t length)
641
 
{
642
 
  if (drizzle->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES)
643
 
    return escape_quotes_for_drizzle(drizzle->charset, to, 0, from, length);
644
 
  return escape_string_for_drizzle(drizzle->charset, to, 0, from, length);
645
 
}
646
 
 
647
 
void
648
 
myodbc_remove_escape(const DRIZZLE *drizzle, char *name)
649
 
{
650
 
  char *to;
651
 
#ifdef USE_MB
652
 
  bool use_mb_flag= use_mb(drizzle->charset);
653
 
  char *end=NULL;
654
 
  if (use_mb_flag)
655
 
    for (end=name; *end ; end++) ;
656
 
#endif
657
 
 
658
 
  for (to=name ; *name ; name++)
 
529
  const char *to_start= to;
 
530
  const char *end, *to_end=to_start + 2*length;
 
531
  bool overflow= false;
 
532
  for (end= from + length; from < end; from++)
659
533
  {
660
 
#ifdef USE_MB
661
 
    int l;
662
 
    if (use_mb_flag && (l = my_ismbchar( drizzle->charset, name , end ) ) )
 
534
    uint32_t tmp_length;
 
535
    char escape= 0;
 
536
    if (!U8_IS_SINGLE(*from))
663
537
    {
664
 
      while (l--)
665
 
        *to++ = *name++;
666
 
      name--;
 
538
      tmp_length= U8_LENGTH(*(uint32_t*)from);
 
539
      if (to + tmp_length > to_end)
 
540
      {
 
541
        overflow= true;
 
542
        break;
 
543
      }
 
544
      while (tmp_length--)
 
545
        *to++= *from++;
 
546
      from--;
667
547
      continue;
668
548
    }
669
 
#endif
670
 
    if (*name == '\\' && name[1])
671
 
      name++;
672
 
    *to++= *name;
 
549
    switch (*from) {
 
550
    case 0:                             /* Must be escaped for 'mysql' */
 
551
      escape= '0';
 
552
      break;
 
553
    case '\n':                          /* Must be escaped for logs */
 
554
      escape= 'n';
 
555
      break;
 
556
    case '\r':
 
557
      escape= 'r';
 
558
      break;
 
559
    case '\\':
 
560
      escape= '\\';
 
561
      break;
 
562
    case '\'':
 
563
      escape= '\'';
 
564
      break;
 
565
    case '"':                           /* Better safe than sorry */
 
566
      escape= '"';
 
567
      break;
 
568
    case '\032':                        /* This gives problems on Win32 */
 
569
      escape= 'Z';
 
570
      break;
 
571
    }
 
572
    if (escape)
 
573
    {
 
574
      if (to + 2 > to_end)
 
575
      {
 
576
        overflow= true;
 
577
        break;
 
578
      }
 
579
      *to++= '\\';
 
580
      *to++= escape;
 
581
    }
 
582
    else
 
583
    {
 
584
      if (to + 1 > to_end)
 
585
      {
 
586
        overflow= true;
 
587
        break;
 
588
      }
 
589
      *to++= *from;
 
590
    }
673
591
  }
674
 
  *to=0;
 
592
  *to= 0;
 
593
  return overflow ? (size_t) -1 : (size_t) (to - to_start);
675
594
}
676
595
 
677
596
int cli_unbuffered_fetch(DRIZZLE *drizzle, char **row)
741
660
{
742
661
  if (drizzle->status != DRIZZLE_STATUS_READY)
743
662
  {
744
 
    set_drizzle_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
 
663
    drizzle_set_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, sqlstate_get_unknown());
745
664
    return(1);
746
665
  }
747
666