~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle/client.c

  • Committer: Monty Taylor
  • Date: 2008-09-16 01:37:05 UTC
  • mto: This revision was merged to the branch mainline in revision 391.
  • Revision ID: monty@inaugust.com-20080916013705-772d1t7rh9ah9j1x
Moved more functions into drizzle.c as part of the split of code.
Added accessor function for drizzle_port.

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
 
42
42
#include <drizzled/global.h>
43
43
 
44
 
#include "libdrizzle.h"
 
44
#include <libdrizzle/libdrizzle.h>
 
45
#include "libdrizzle_priv.h"
45
46
 
46
47
#include <sys/poll.h>
47
48
#include <sys/ioctl.h>
80
81
#include <errno.h>
81
82
#define SOCKET_ERROR -1
82
83
 
83
 
#define CONNECT_TIMEOUT 0
84
84
 
85
85
#include <drizzled/version.h>
86
86
#include <libdrizzle/sql_common.h>
91
91
                             CLIENT_TRANSACTIONS |                      \
92
92
                             CLIENT_SECURE_CONNECTION)
93
93
 
94
 
uint    drizzle_port=0;
95
 
const char  *unknown_sqlstate= "HY000";
96
 
const char  *not_error_sqlstate= "00000";
97
 
const char  *cant_connect_sqlstate= "08001";
98
94
 
99
 
static bool drizzle_client_init= false;
100
 
static bool org_my_init_done= false;
101
95
 
102
96
static void drizzle_close_free_options(DRIZZLE *drizzle);
103
97
static void drizzle_close_free(DRIZZLE *drizzle);
105
99
static int wait_for_data(int fd, int32_t timeout);
106
100
int connect_with_timeout(int fd, const struct sockaddr *name, uint namelen, int32_t timeout);
107
101
 
108
 
/* Server error code and message */
109
 
unsigned int drizzle_server_last_errno;
110
 
char drizzle_server_last_error[DRIZZLE_ERRMSG_SIZE];
111
102
 
112
103
/****************************************************************************
113
104
  A modified version of connect().  connect_with_timeout() allows you to specify
209
200
}
210
201
 
211
202
 
212
 
/**
213
 
  Set the internal error message to DRIZZLE handler
214
 
 
215
 
  @param drizzle connection handle (client side)
216
 
  @param errcode  CR_ error code, passed to ER macro to get
217
 
                  error text
218
 
  @parma sqlstate SQL standard sqlstate
219
 
*/
220
 
 
221
 
void set_drizzle_error(DRIZZLE *drizzle, int errcode, const char *sqlstate)
222
 
{
223
 
  NET *net;
224
 
  assert(drizzle != 0);
225
 
 
226
 
  if (drizzle)
227
 
  {
228
 
    net= &drizzle->net;
229
 
    net->last_errno= errcode;
230
 
    strcpy(net->last_error, ER(errcode));
231
 
    strcpy(net->sqlstate, sqlstate);
232
 
  }
233
 
  else
234
 
  {
235
 
    drizzle_server_last_errno= errcode;
236
 
    strcpy(drizzle_server_last_error, ER(errcode));
237
 
  }
238
 
  return;
239
 
}
240
203
 
241
204
/**
242
205
  Clear possible error state of struct NET
251
214
  strcpy(net->sqlstate, not_error_sqlstate);
252
215
}
253
216
 
254
 
/**
255
 
  Set an error message on the client.
256
 
 
257
 
  @param drizzle connection handle
258
 
  @param errcode   CR_* errcode, for client errors
259
 
  @param sqlstate  SQL standard sql state, unknown_sqlstate for the
260
 
                   majority of client errors.
261
 
  @param format    error message template, in sprintf format
262
 
  @param ...       variable number of arguments
263
 
*/
264
 
 
265
 
static void set_drizzle_extended_error(DRIZZLE *drizzle, int errcode,
266
 
                                     const char *sqlstate,
267
 
                                     const char *format, ...)
268
 
{
269
 
  NET *net;
270
 
  va_list args;
271
 
  assert(drizzle != 0);
272
 
 
273
 
  net= &drizzle->net;
274
 
  net->last_errno= errcode;
275
 
  va_start(args, format);
276
 
  vsnprintf(net->last_error, sizeof(net->last_error)-1,
277
 
               format, args);
278
 
  va_end(args);
279
 
  strcpy(net->sqlstate, sqlstate);
280
 
 
281
 
  return;
282
 
}
283
217
 
284
218
/*****************************************************************************
285
219
  Read a packet from server. Give error message if socket was down
300
234
    if (net->vio && vio_was_interrupted(net->vio))
301
235
      return (packet_error);
302
236
#endif /*DRIZZLE_SERVER*/
303
 
    end_server(drizzle);
304
 
    set_drizzle_error(drizzle, net->last_errno == CR_NET_PACKET_TOO_LARGE ?
 
237
    drizzle_disconnect(drizzle);
 
238
    drizzle_set_error(drizzle, net->last_errno == CR_NET_PACKET_TOO_LARGE ?
305
239
                      CR_NET_PACKET_TOO_LARGE : CR_SERVER_LOST,
306
240
                      unknown_sqlstate);
307
241
    return (packet_error);
333
267
              (uint32_t) sizeof(net->last_error)-1));
334
268
    }
335
269
    else
336
 
      set_drizzle_error(drizzle, CR_UNKNOWN_ERROR, unknown_sqlstate);
 
270
      drizzle_set_error(drizzle, CR_UNKNOWN_ERROR, unknown_sqlstate);
337
271
    /*
338
272
      Cover a protocol design error: error packet does not
339
273
      contain the server status. Therefore, the client has no way
386
320
  if (drizzle->status != DRIZZLE_STATUS_READY ||
387
321
      drizzle->server_status & SERVER_MORE_RESULTS_EXISTS)
388
322
  {
389
 
    set_drizzle_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
 
323
    drizzle_set_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
390
324
    return(1);
391
325
  }
392
326
 
405
339
  {
406
340
    if (net->last_errno == CR_NET_PACKET_TOO_LARGE)
407
341
    {
408
 
      set_drizzle_error(drizzle, CR_NET_PACKET_TOO_LARGE, unknown_sqlstate);
 
342
      drizzle_set_error(drizzle, CR_NET_PACKET_TOO_LARGE, unknown_sqlstate);
409
343
      goto end;
410
344
    }
411
 
    end_server(drizzle);
 
345
    drizzle_disconnect(drizzle);
412
346
    if (drizzle_reconnect(drizzle) || stmt_skip)
413
347
      goto end;
414
348
    if (net_write_command(net,(uchar) command, header, header_length,
415
349
        arg, arg_length))
416
350
    {
417
 
      set_drizzle_error(drizzle, CR_SERVER_GONE_ERROR, unknown_sqlstate);
 
351
      drizzle_set_error(drizzle, CR_SERVER_GONE_ERROR, unknown_sqlstate);
418
352
      goto end;
419
353
    }
420
354
  }
474
408
}
475
409
 
476
410
 
477
 
/**************************************************************************
478
 
  Shut down connection
479
 
**************************************************************************/
480
 
 
481
 
void end_server(DRIZZLE *drizzle)
482
 
{
483
 
  int save_errno= errno;
484
 
  if (drizzle->net.vio != 0)
485
 
  {
486
 
    vio_delete(drizzle->net.vio);
487
 
    drizzle->net.vio= 0;          /* Marker */
488
 
  }
489
 
  net_end(&drizzle->net);
490
 
  free_old_query(drizzle);
491
 
  errno= save_errno;
492
 
}
493
411
 
494
412
 
495
413
void
632
550
    return(0);
633
551
  if (!(result=(DRIZZLE_DATA*) malloc(sizeof(DRIZZLE_DATA))))
634
552
  {
635
 
    set_drizzle_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
 
553
    drizzle_set_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
636
554
    return(0);
637
555
  }
638
556
  memset(result, 0, sizeof(DRIZZLE_DATA));
654
572
        !(cur->data= ((DRIZZLE_ROW) malloc((fields+1)*sizeof(char *)+pkt_len))))
655
573
    {
656
574
      free_rows(result);
657
 
      set_drizzle_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
 
575
      drizzle_set_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
658
576
      return(0);
659
577
    }
660
578
    *prev_ptr=cur;
673
591
        if (len > (uint32_t) (end_to - to))
674
592
        {
675
593
          free_rows(result);
676
 
          set_drizzle_error(drizzle, CR_MALFORMED_PACKET, unknown_sqlstate);
 
594
          drizzle_set_error(drizzle, CR_MALFORMED_PACKET, unknown_sqlstate);
677
595
          return(0);
678
596
        }
679
597
        memcpy(to, cp, len);
742
660
    {
743
661
      if (len > (uint32_t) (end_pos - pos))
744
662
      {
745
 
        set_drizzle_error(drizzle, CR_UNKNOWN_ERROR, unknown_sqlstate);
 
663
        drizzle_set_error(drizzle, CR_UNKNOWN_ERROR, unknown_sqlstate);
746
664
        return -1;
747
665
      }
748
666
      row[field] = (char*) pos;
759
677
}
760
678
 
761
679
 
762
 
/****************************************************************************
763
 
  Init DRIZZLE structure or allocate one
764
 
****************************************************************************/
765
 
 
766
 
DRIZZLE *
767
 
drizzle_create(DRIZZLE *ptr)
768
 
{
769
 
 
770
 
  if (!drizzle_client_init)
771
 
  {
772
 
    drizzle_client_init=true;
773
 
 
774
 
    if (!drizzle_port)
775
 
    {
776
 
      drizzle_port = DRIZZLE_PORT;
777
 
      {
778
 
        struct servent *serv_ptr;
779
 
        char *env;
780
 
 
781
 
        /*
782
 
          if builder specifically requested a default port, use that
783
 
          (even if it coincides with our factory default).
784
 
          only if they didn't do we check /etc/services (and, failing
785
 
          on that, fall back to the factory default of 4427).
786
 
          either default can be overridden by the environment variable
787
 
          DRIZZLE_TCP_PORT, which in turn can be overridden with command
788
 
          line options.
789
 
        */
790
 
 
791
 
#if DRIZZLE_PORT_DEFAULT == 0
792
 
        if ((serv_ptr = getservbyname("drizzle", "tcp")))
793
 
          drizzle_port = (uint) ntohs((ushort) serv_ptr->s_port);
794
 
#endif
795
 
        if ((env = getenv("DRIZZLE_TCP_PORT")))
796
 
          drizzle_port =(uint) atoi(env);
797
 
      }
798
 
    }
799
 
#if defined(SIGPIPE)
800
 
    (void) signal(SIGPIPE, SIG_IGN);
801
 
#endif
802
 
  }
803
 
 
804
 
  if (ptr == NULL)
805
 
  {
806
 
    ptr= (DRIZZLE *) malloc(sizeof(DRIZZLE));
807
 
 
808
 
    if (ptr == NULL)
809
 
    {
810
 
      set_drizzle_error(NULL, CR_OUT_OF_MEMORY, unknown_sqlstate);
811
 
      return 0;
812
 
    }
813
 
    memset(ptr, 0, sizeof(DRIZZLE));
814
 
    ptr->free_me=1;
815
 
  }
816
 
  else
817
 
  {
818
 
    memset(ptr, 0, sizeof(DRIZZLE)); 
819
 
  }
820
 
 
821
 
  ptr->options.connect_timeout= CONNECT_TIMEOUT;
822
 
  strcpy(ptr->net.sqlstate, not_error_sqlstate);
823
 
 
824
 
  /*
825
 
    Only enable LOAD DATA INFILE by default if configured with
826
 
    --enable-local-infile
827
 
  */
828
 
 
829
 
#if defined(ENABLED_LOCAL_INFILE) && !defined(DRIZZLE_SERVER)
830
 
  ptr->options.client_flag|= CLIENT_LOCAL_FILES;
831
 
#endif
832
 
 
833
 
  ptr->options.methods_to_use= DRIZZLE_OPT_GUESS_CONNECTION;
834
 
  ptr->options.report_data_truncation= true;  /* default */
835
 
 
836
 
  /*
837
 
    By default we don't reconnect because it could silently corrupt data (after
838
 
    reconnection you potentially lose table locks, user variables, session
839
 
    variables (transactions but they are specifically dealt with in
840
 
    drizzle_reconnect()).
841
 
    This is a change: < 5.0.3 drizzle->reconnect was set to 1 by default.
842
 
    How this change impacts existing apps:
843
 
    - existing apps which relyed on the default will see a behaviour change;
844
 
    they will have to set reconnect=1 after drizzle_connect().
845
 
    - existing apps which explicitely asked for reconnection (the only way they
846
 
    could do it was by setting drizzle.reconnect to 1 after drizzle_connect())
847
 
    will not see a behaviour change.
848
 
    - existing apps which explicitely asked for no reconnection
849
 
    (drizzle.reconnect=0) will not see a behaviour change.
850
 
  */
851
 
  ptr->reconnect= 0;
852
 
 
853
 
  return ptr;
854
 
}
855
 
 
856
 
 
857
 
/*
858
 
  Free all memory and resources used by the client library
859
 
 
860
 
  NOTES
861
 
    When calling this there should not be any other threads using
862
 
    the library.
863
 
 
864
 
    To make things simpler when used with windows dll's (which calls this
865
 
    function automaticly), it's safe to call this function multiple times.
866
 
*/
867
 
 
868
 
 
869
 
void drizzle_server_end()
870
 
{
871
 
  if (!drizzle_client_init)
872
 
    return;
873
 
 
874
 
  vio_end();
875
 
 
876
 
  drizzle_client_init= org_my_init_done= 0;
877
 
}
878
 
 
879
 
 
880
680
/*
881
681
  Note that the drizzle argument must be initialized with drizzle_init()
882
682
  before calling drizzle_connect !
964
764
 
965
765
    if (gai_errno != 0)
966
766
    {
967
 
      set_drizzle_extended_error(drizzle, CR_UNKNOWN_HOST, unknown_sqlstate,
 
767
      drizzle_set_extended_error(drizzle, CR_UNKNOWN_HOST, unknown_sqlstate,
968
768
                                 ER(CR_UNKNOWN_HOST), host, errno);
969
769
 
970
770
      goto error;
998
798
 
999
799
  if (!net->vio)
1000
800
  {
1001
 
    set_drizzle_extended_error(drizzle, CR_CONN_HOST_ERROR, unknown_sqlstate,
 
801
    drizzle_set_extended_error(drizzle, CR_CONN_HOST_ERROR, unknown_sqlstate,
1002
802
                               ER(CR_CONN_HOST_ERROR), host, socket_errno);
1003
803
    goto error;
1004
804
  }
1007
807
  {
1008
808
    vio_delete(net->vio);
1009
809
    net->vio = 0;
1010
 
    set_drizzle_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
 
810
    drizzle_set_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
1011
811
    goto error;
1012
812
  }
1013
813
  vio_keepalive(net->vio,true);
1028
828
  if (drizzle->options.connect_timeout &&
1029
829
      vio_poll_read(net->vio, drizzle->options.connect_timeout))
1030
830
  {
1031
 
    set_drizzle_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
 
831
    drizzle_set_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
1032
832
                             ER(CR_SERVER_LOST_INITIAL_COMM_WAIT),
1033
833
                             errno);
1034
834
    goto error;
1041
841
  if ((pkt_length=cli_safe_read(drizzle)) == packet_error)
1042
842
  {
1043
843
    if (drizzle->net.last_errno == CR_SERVER_LOST)
1044
 
      set_drizzle_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
 
844
      drizzle_set_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
1045
845
                               ER(CR_SERVER_LOST_INITIAL_COMM_READ),
1046
846
                               errno);
1047
847
    goto error;
1051
851
  drizzle->protocol_version= net->read_pos[0];
1052
852
  if (drizzle->protocol_version != PROTOCOL_VERSION)
1053
853
  {
1054
 
    set_drizzle_extended_error(drizzle, CR_VERSION_ERROR, unknown_sqlstate,
 
854
    drizzle_set_extended_error(drizzle, CR_VERSION_ERROR, unknown_sqlstate,
1055
855
                             ER(CR_VERSION_ERROR), drizzle->protocol_version,
1056
856
                             PROTOCOL_VERSION);
1057
857
    goto error;
1085
885
  if (drizzle->options.secure_auth && passwd[0] &&
1086
886
      !(drizzle->server_capabilities & CLIENT_SECURE_CONNECTION))
1087
887
  {
1088
 
    set_drizzle_error(drizzle, CR_SECURE_AUTH, unknown_sqlstate);
 
888
    drizzle_set_error(drizzle, CR_SECURE_AUTH, unknown_sqlstate);
1089
889
    goto error;
1090
890
  }
1091
891
 
1095
895
      !(drizzle->user=strdup(user)) ||
1096
896
      !(drizzle->passwd=strdup(passwd)))
1097
897
  {
1098
 
    set_drizzle_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
 
898
    drizzle_set_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
1099
899
    goto error;
1100
900
  }
1101
901
  drizzle->host= drizzle->host_info+strlen(host_info)+1;
1161
961
  /* Write authentication package */
1162
962
  if (my_net_write(net, (uchar*) buff, (size_t) (end-buff)) || net_flush(net))
1163
963
  {
1164
 
    set_drizzle_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
 
964
    drizzle_set_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
1165
965
                             ER(CR_SERVER_LOST_SEND_AUTH),
1166
966
                             errno);
1167
967
    goto error;
1175
975
  if ((pkt_length=cli_safe_read(drizzle)) == packet_error)
1176
976
  {
1177
977
    if (drizzle->net.last_errno == CR_SERVER_LOST)
1178
 
      set_drizzle_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
 
978
      drizzle_set_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
1179
979
                               ER(CR_SERVER_LOST_READ_AUTH),
1180
980
                               errno);
1181
981
    goto error;
1188
988
  if (db && drizzle_select_db(drizzle, db))
1189
989
  {
1190
990
    if (drizzle->net.last_errno == CR_SERVER_LOST)
1191
 
        set_drizzle_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
 
991
        drizzle_set_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
1192
992
                                 ER(CR_SERVER_LOST_SETTING_DB),
1193
993
                                 errno);
1194
994
    goto error;
1200
1000
error:
1201
1001
  {
1202
1002
    /* Free alloced memory */
1203
 
    end_server(drizzle);
 
1003
    drizzle_disconnect(drizzle);
1204
1004
    drizzle_close_free(drizzle);
1205
1005
    if (!(((uint32_t) client_flag) & CLIENT_REMEMBER_OPTIONS))
1206
1006
      drizzle_close_free_options(drizzle);
1219
1019
  {
1220
1020
    /* Allow reconnect next time */
1221
1021
    drizzle->server_status&= ~SERVER_STATUS_IN_TRANS;
1222
 
    set_drizzle_error(drizzle, CR_SERVER_GONE_ERROR, unknown_sqlstate);
 
1022
    drizzle_set_error(drizzle, CR_SERVER_GONE_ERROR, unknown_sqlstate);
1223
1023
    return(1);
1224
1024
  }
1225
1025
  drizzle_create(&tmp_drizzle);
1325
1125
      drizzle->status=DRIZZLE_STATUS_READY; /* Force command */
1326
1126
      drizzle->reconnect=0;
1327
1127
      simple_command(drizzle,COM_QUIT,(uchar*) 0,0,1);
1328
 
      end_server(drizzle);      /* Sets drizzle->net.vio= 0 */
 
1128
      drizzle_disconnect(drizzle);      /* Sets drizzle->net.vio= 0 */
1329
1129
    }
1330
1130
    drizzle_close_free_options(drizzle);
1331
1131
    drizzle_close_free(drizzle);
1366
1166
 
1367
1167
    if (!(drizzle->options.client_flag & CLIENT_LOCAL_FILES))
1368
1168
    {
1369
 
      set_drizzle_error(drizzle, CR_MALFORMED_PACKET, unknown_sqlstate);
 
1169
      drizzle_set_error(drizzle, CR_MALFORMED_PACKET, unknown_sqlstate);
1370
1170
      return(1);
1371
1171
    }  
1372
1172
 
1423
1223
    return(0);
1424
1224
  if (drizzle->status != DRIZZLE_STATUS_GET_RESULT)
1425
1225
  {
1426
 
    set_drizzle_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
 
1226
    drizzle_set_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
1427
1227
    return(0);
1428
1228
  }
1429
1229
  drizzle->status=DRIZZLE_STATUS_READY;    /* server is ready */
1431
1231
                sizeof(uint32_t) *
1432
1232
                drizzle->field_count))))
1433
1233
  {
1434
 
    set_drizzle_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
 
1234
    drizzle_set_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
1435
1235
    return(0);
1436
1236
  }
1437
1237
  memset(result, 0,(sizeof(DRIZZLE_RES)+ sizeof(uint32_t) *
1475
1275
    return(0);
1476
1276
  if (drizzle->status != DRIZZLE_STATUS_GET_RESULT)
1477
1277
  {
1478
 
    set_drizzle_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
 
1278
    drizzle_set_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
1479
1279
    return(0);
1480
1280
  }
1481
1281
  if (!(result=(DRIZZLE_RES*) malloc(sizeof(*result)+
1516
1316
      DRIZZLE *drizzle= res->handle;
1517
1317
      if (drizzle->status != DRIZZLE_STATUS_USE_RESULT)
1518
1318
      {
1519
 
        set_drizzle_error(drizzle,
 
1319
        drizzle_set_error(drizzle,
1520
1320
                        res->unbuffered_fetch_cancelled ?
1521
1321
                        CR_FETCH_CANCELED : CR_COMMANDS_OUT_OF_SYNC,
1522
1322
                        unknown_sqlstate);
1651
1451
  return res->field_count;
1652
1452
}
1653
1453
 
1654
 
uint drizzle_errno(const DRIZZLE *drizzle)
1655
 
{
1656
 
  return drizzle ? drizzle->net.last_errno : drizzle_server_last_errno;
1657
 
}
1658
 
 
1659
 
 
1660
 
const char * drizzle_error(const DRIZZLE *drizzle)
1661
 
{
1662
 
  return drizzle ? _(drizzle->net.last_error) : _(drizzle_server_last_error);
1663
 
}
1664
 
 
1665
1454
 
1666
1455
/*
1667
1456
  Get version number for server in a form easy to test on