1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems, Inc.
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.
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.
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
20
#include <drizzled/global.h>
24
#include <drizzled/common.h>
25
#include <libdrizzle/libdrizzle.h>
26
#include <libdrizzle/pack.h>
27
#include <libdrizzle/errmsg.h>
28
#include <libdrizzle/drizzle.h>
29
#include <drizzled/gettext.h>
30
#include <libdrizzle/net_serv.h>
31
#include <libdrizzle/drizzle_data.h>
32
#include <libdrizzle/local_infile.h>
34
#include "libdrizzle_priv.h"
43
#include <sys/socket.h>
46
#define CONNECT_TIMEOUT 0
48
static bool drizzle_client_init= false;
49
unsigned int drizzle_server_last_errno;
51
/* Server error code and message */
52
char drizzle_server_last_error[LIBDRIZZLE_ERRMSG_SIZE];
55
Note that the drizzle argument must be initialized with drizzle_init()
56
before calling drizzle_connect !
61
static DRIZZLE_METHODS client_methods=
63
cli_read_query_result, /* read_query_result */
64
cli_advanced_command, /* advanced_command */
65
cli_read_rows, /* read_rows */
66
cli_use_result, /* use_result */
67
cli_fetch_lengths, /* fetch_lengths */
68
cli_flush_use_result, /* flush_use_result */
69
cli_list_fields, /* list_fields */
70
cli_unbuffered_fetch, /* unbuffered_fetch */
71
cli_read_statistics, /* read_statistics */
72
cli_read_query_result, /* next_result */
73
cli_read_change_user_result, /* read_change_user_result */
78
/****************************************************************************
79
Init DRIZZLE structure or allocate one
80
****************************************************************************/
83
drizzle_create(DRIZZLE *ptr)
86
if (!drizzle_client_init)
88
drizzle_client_init=true;
90
if (!drizzle_get_default_port())
92
drizzle_set_default_port(DRIZZLE_PORT);
94
struct servent *serv_ptr;
98
if builder specifically requested a default port, use that
99
(even if it coincides with our factory default).
100
only if they didn't do we check /etc/services (and, failing
101
on that, fall back to the factory default of 4427).
102
either default can be overridden by the environment variable
103
DRIZZLE_TCP_PORT, which in turn can be overridden with command
107
#if DRIZZLE_PORT_DEFAULT == 0
108
if ((serv_ptr = getservbyname("drizzle", "tcp")))
109
drizzle_set_default_port((uint32_t) ntohs((uint16_t) serv_ptr->s_port));
111
if ((env = getenv("DRIZZLE_TCP_PORT")))
112
drizzle_set_default_port((uint32_t) atoi(env));
116
(void) signal(SIGPIPE, SIG_IGN);
122
ptr= (DRIZZLE *) malloc(sizeof(DRIZZLE));
126
drizzle_set_error(NULL, CR_OUT_OF_MEMORY, sqlstate_get_unknown());
129
memset(ptr, 0, sizeof(DRIZZLE));
134
memset(ptr, 0, sizeof(DRIZZLE));
137
ptr->options.connect_timeout= CONNECT_TIMEOUT;
138
strcpy(ptr->net.sqlstate, sqlstate_get_not_error());
141
Only enable LOAD DATA INFILE by default if configured with
142
--enable-local-infile
145
#if defined(ENABLED_LOCAL_INFILE)
146
ptr->options.client_flag|= CLIENT_LOCAL_FILES;
149
ptr->options.methods_to_use= DRIZZLE_OPT_GUESS_CONNECTION;
150
ptr->options.report_data_truncation= true; /* default */
153
By default we don't reconnect because it could silently corrupt data (after
154
reconnection you potentially lose table locks, user variables, session
155
variables (transactions but they are specifically dealt with in
156
drizzle_reconnect()).
157
This is a change: < 5.0.3 drizzle->reconnect was set to 1 by default.
158
How this change impacts existing apps:
159
- existing apps which relyed on the default will see a behaviour change;
160
they will have to set reconnect=1 after drizzle_connect().
161
- existing apps which explicitely asked for reconnection (the only way they
162
could do it was by setting drizzle.reconnect to 1 after drizzle_connect())
163
will not see a behaviour change.
164
- existing apps which explicitely asked for no reconnection
165
(drizzle.reconnect=0) will not see a behaviour change.
173
static void read_user_name(char *name)
176
strcpy(name,"root"); /* allow use of surun */
182
if ((str=getlogin()) == NULL)
184
if ((skr=getpwuid(geteuid())) != NULL)
186
else if (!(str=getenv("USER")) && !(str=getenv("LOGNAME")) &&
187
!(str=getenv("LOGIN")))
190
strncpy(name,str,USERNAME_LENGTH);
192
(void) cuserid(name);
194
strcpy(name,"UNKNOWN_USER");
201
drizzle_connect(DRIZZLE *drizzle,const char *host, const char *user,
202
const char *passwd, const char *db,
204
const char * unix_port __attribute__((__unused__)),
205
uint32_t client_flag)
207
char buff[NAME_LEN+USERNAME_LENGTH+100];
208
char *end,*host_info=NULL;
210
NET *net= &drizzle->net;
212
drizzle->methods= &client_methods;
213
net->vio = 0; /* If something goes wrong */
214
drizzle->client_flag=0; /* For handshake */
216
/* Some empty-string-tests are done because of ODBC */
217
if (!host || !host[0])
218
host=drizzle->options.host;
219
if (!user || !user[0])
221
user=drizzle->options.user;
227
passwd=drizzle->options.password;
232
db=drizzle->options.db;
234
port=drizzle->options.port;
236
drizzle->server_status=SERVER_STATUS_AUTOCOMMIT;
239
Part 0: Grab a socket and connect it to the server
243
struct addrinfo *res_lst, hints, *t_res;
245
char port_buf[NI_MAXSERV];
248
port= drizzle_get_default_port();
253
snprintf(host_info=buff, sizeof(buff)-1, ER(CR_TCP_CONNECTION), host);
255
memset(&hints, 0, sizeof(hints));
256
hints.ai_socktype= SOCK_STREAM;
258
snprintf(port_buf, NI_MAXSERV, "%d", port);
259
gai_errno= getaddrinfo(host, port_buf, &hints, &res_lst);
263
drizzle_set_extended_error(drizzle, CR_UNKNOWN_HOST, sqlstate_get_unknown(),
264
ER(CR_UNKNOWN_HOST), host, errno);
269
for (t_res= res_lst; t_res != NULL; t_res= t_res->ai_next)
271
int sock= socket(t_res->ai_family, t_res->ai_socktype,
276
net->vio= vio_new(sock, VIO_TYPE_TCPIP, VIO_BUFFERED_READ);
283
if (connect_with_timeout(sock, t_res->ai_addr, t_res->ai_addrlen, drizzle->options.connect_timeout))
285
vio_delete(net->vio);
292
freeaddrinfo(res_lst);
297
drizzle_set_extended_error(drizzle, CR_CONN_HOST_ERROR, sqlstate_get_unknown(),
298
ER(CR_CONN_HOST_ERROR), host, errno);
302
if (my_net_init(net, net->vio))
304
vio_delete(net->vio);
306
drizzle_set_error(drizzle, CR_OUT_OF_MEMORY, sqlstate_get_unknown());
309
vio_keepalive(net->vio,true);
311
/* If user set read_timeout, let it override the default */
312
if (drizzle->options.read_timeout)
313
my_net_set_read_timeout(net, drizzle->options.read_timeout);
315
/* If user set write_timeout, let it override the default */
316
if (drizzle->options.write_timeout)
317
my_net_set_write_timeout(net, drizzle->options.write_timeout);
319
if (drizzle->options.max_allowed_packet)
320
net->max_packet_size= drizzle->options.max_allowed_packet;
322
/* Get version info */
323
drizzle->protocol_version= PROTOCOL_VERSION; /* Assume this */
324
if (drizzle->options.connect_timeout &&
325
vio_poll_read(net->vio, drizzle->options.connect_timeout))
327
drizzle_set_extended_error(drizzle, CR_SERVER_LOST, sqlstate_get_unknown(),
328
ER(CR_SERVER_LOST_INITIAL_COMM_WAIT),
334
Part 1: Connection established, read and parse first packet
337
if ((pkt_length=cli_safe_read(drizzle)) == packet_error)
339
if (drizzle->net.last_errno == CR_SERVER_LOST)
340
drizzle_set_extended_error(drizzle, CR_SERVER_LOST, sqlstate_get_unknown(),
341
ER(CR_SERVER_LOST_INITIAL_COMM_READ),
345
/* Check if version of protocol matches current one */
347
drizzle->protocol_version= net->read_pos[0];
348
if (drizzle->protocol_version != PROTOCOL_VERSION)
350
drizzle_set_extended_error(drizzle, CR_VERSION_ERROR, sqlstate_get_unknown(),
351
ER(CR_VERSION_ERROR), drizzle->protocol_version,
355
end= strchr((char*) net->read_pos+1, '\0');
356
drizzle->thread_id=uint4korr(end+1);
359
Scramble is split into two parts because old clients does not understand
360
long scrambles; here goes the first part.
362
strncpy(drizzle->scramble, end, SCRAMBLE_LENGTH_323);
363
end+= SCRAMBLE_LENGTH_323+1;
365
if (pkt_length >= (uint32_t) (end+1 - (char*) net->read_pos))
366
drizzle->server_capabilities=uint2korr(end);
367
if (pkt_length >= (uint32_t) (end+18 - (char*) net->read_pos))
369
/* New protocol with 16 bytes to describe server characteristics */
370
drizzle->server_language=end[2];
371
drizzle->server_status=uint2korr(end+3);
374
if (pkt_length >= (uint32_t) (end + SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323 + 1 -
375
(char *) net->read_pos))
376
strncpy(drizzle->scramble+SCRAMBLE_LENGTH_323, end,
377
SCRAMBLE_LENGTH-SCRAMBLE_LENGTH_323);
379
drizzle->server_capabilities&= ~CLIENT_SECURE_CONNECTION;
381
if (drizzle->options.secure_auth && passwd[0] &&
382
!(drizzle->server_capabilities & CLIENT_SECURE_CONNECTION))
384
drizzle_set_error(drizzle, CR_SECURE_AUTH, sqlstate_get_unknown());
388
/* Save connection information */
389
if (!(drizzle->host_info= (char *)malloc(strlen(host_info)+1+strlen(host)+1
390
+(end - (char*) net->read_pos))) ||
391
!(drizzle->user=strdup(user)) ||
392
!(drizzle->passwd=strdup(passwd)))
394
drizzle_set_error(drizzle, CR_OUT_OF_MEMORY, sqlstate_get_unknown());
397
drizzle->host= drizzle->host_info+strlen(host_info)+1;
398
drizzle->server_version= drizzle->host+strlen(host)+1;
399
strcpy(drizzle->host_info,host_info);
400
strcpy(drizzle->host,host);
401
strcpy(drizzle->server_version,(char*) net->read_pos+1);
405
Part 2: format and send client info to the server for access check
408
client_flag|=drizzle->options.client_flag;
409
client_flag|=CLIENT_CAPABILITIES;
410
if (client_flag & CLIENT_MULTI_STATEMENTS)
411
client_flag|= CLIENT_MULTI_RESULTS;
414
client_flag|=CLIENT_CONNECT_WITH_DB;
416
/* Remove options that server doesn't support */
417
client_flag= ((client_flag &
418
~(CLIENT_COMPRESS | CLIENT_SSL)) |
419
(client_flag & drizzle->server_capabilities));
420
client_flag&= ~CLIENT_COMPRESS;
422
int4store(buff, client_flag);
423
int4store(buff+4, net->max_packet_size);
424
buff[8]= (char) 45; // utf8 charset number
425
memset(buff+9, 0, 32-9);
428
drizzle->client_flag=client_flag;
430
/* This needs to be changed as it's not useful with big packets */
432
strncpy(end,user,USERNAME_LENGTH); /* Max user name */
434
read_user_name((char*) end);
436
/* We have to handle different version of handshake here */
437
end= strchr(end, '\0') + 1;
441
*end++= SCRAMBLE_LENGTH;
442
memset(end, 0, SCRAMBLE_LENGTH-1);
443
memcpy(end, passwd, strlen(passwd));
444
end+= SCRAMBLE_LENGTH;
448
*end++= '\0'; /* empty password */
450
/* Add database if needed */
451
if (db && (drizzle->server_capabilities & CLIENT_CONNECT_WITH_DB))
453
end= strncpy(end, db, NAME_LEN) + NAME_LEN + 1;
454
drizzle->db= strdup(db);
457
/* Write authentication package */
458
if (my_net_write(net, (unsigned char*) buff, (size_t) (end-buff)) || net_flush(net))
460
drizzle_set_extended_error(drizzle, CR_SERVER_LOST, sqlstate_get_unknown(),
461
ER(CR_SERVER_LOST_SEND_AUTH),
467
Part 3: Authorization data's been sent. Now server can reply with
468
OK-packet, or re-request scrambled password.
471
if ((pkt_length=cli_safe_read(drizzle)) == packet_error)
473
if (drizzle->net.last_errno == CR_SERVER_LOST)
474
drizzle_set_extended_error(drizzle, CR_SERVER_LOST, sqlstate_get_unknown(),
475
ER(CR_SERVER_LOST_READ_AUTH),
480
if (client_flag & CLIENT_COMPRESS) /* We will use compression */
484
if (db && drizzle_select_db(drizzle, db))
486
if (drizzle->net.last_errno == CR_SERVER_LOST)
487
drizzle_set_extended_error(drizzle, CR_SERVER_LOST, sqlstate_get_unknown(),
488
ER(CR_SERVER_LOST_SETTING_DB),
498
/* Free alloced memory */
499
drizzle_disconnect(drizzle);
500
drizzle_close_free(drizzle);
501
if (!(((uint32_t) client_flag) & CLIENT_REMEMBER_OPTIONS))
502
drizzle_close_free_options(drizzle);
510
/**************************************************************************
512
**************************************************************************/
515
drizzle_select_db(DRIZZLE *drizzle, const char *db)
519
if ((error=simple_command(drizzle,COM_INIT_DB, (const unsigned char*) db,
520
(uint32_t) strlen(db),0)))
522
if (drizzle->db != NULL)
524
drizzle->db=strdup(db);
528
bool drizzle_reconnect(DRIZZLE *drizzle)
533
if (!drizzle->reconnect ||
534
(drizzle->server_status & SERVER_STATUS_IN_TRANS) || !drizzle->host_info)
536
/* Allow reconnect next time */
537
drizzle->server_status&= ~SERVER_STATUS_IN_TRANS;
538
drizzle_set_error(drizzle, CR_SERVER_GONE_ERROR, sqlstate_get_unknown());
541
drizzle_create(&tmp_drizzle);
542
tmp_drizzle.options= drizzle->options;
543
tmp_drizzle.options.my_cnf_file= tmp_drizzle.options.my_cnf_group= 0;
545
if (!drizzle_connect(&tmp_drizzle,drizzle->host,drizzle->user,drizzle->passwd,
546
drizzle->db, drizzle->port, 0,
547
drizzle->client_flag | CLIENT_REMEMBER_OPTIONS))
549
drizzle->net.last_errno= tmp_drizzle.net.last_errno;
550
strcpy(drizzle->net.last_error, tmp_drizzle.net.last_error);
551
strcpy(drizzle->net.sqlstate, tmp_drizzle.net.sqlstate);
555
tmp_drizzle.reconnect= 1;
556
tmp_drizzle.free_me= drizzle->free_me;
558
/* Don't free options as these are now used in tmp_drizzle */
559
memset(&drizzle->options, 0, sizeof(drizzle->options));
561
drizzle_close(drizzle);
562
*drizzle=tmp_drizzle;
563
net_clear(&drizzle->net, 1);
564
drizzle->affected_rows= ~(uint64_t) 0;
568
/**************************************************************************
570
**************************************************************************/
572
void drizzle_disconnect(DRIZZLE *drizzle)
574
int save_errno= errno;
575
if (drizzle->net.vio != 0)
577
vio_delete(drizzle->net.vio);
578
drizzle->net.vio= 0; /* Marker */
580
net_end(&drizzle->net);
581
free_old_query(drizzle);
586
/*************************************************************************
587
Send a QUIT to the server and close the connection
588
If handle is alloced by DRIZZLE connect free it.
589
*************************************************************************/
591
void drizzle_close_free_options(DRIZZLE *drizzle)
593
if (drizzle->options.user != NULL)
594
free(drizzle->options.user);
595
if (drizzle->options.host != NULL)
596
free(drizzle->options.host);
597
if (drizzle->options.password != NULL)
598
free(drizzle->options.password);
599
if (drizzle->options.db != NULL)
600
free(drizzle->options.db);
601
if (drizzle->options.my_cnf_file != NULL)
602
free(drizzle->options.my_cnf_file);
603
if (drizzle->options.my_cnf_group != NULL)
604
free(drizzle->options.my_cnf_group);
605
if (drizzle->options.client_ip != NULL)
606
free(drizzle->options.client_ip);
607
memset(&drizzle->options, 0, sizeof(drizzle->options));
612
void drizzle_close_free(DRIZZLE *drizzle)
614
if (drizzle->host_info != NULL)
615
free((unsigned char*) drizzle->host_info);
616
if (drizzle->user != NULL)
618
if (drizzle->passwd != NULL)
619
free(drizzle->passwd);
620
if (drizzle->db != NULL)
622
if (drizzle->info_buffer != NULL)
623
free(drizzle->info_buffer);
624
drizzle->info_buffer= 0;
626
/* Clear pointers for better safety */
627
drizzle->host_info= drizzle->user= drizzle->passwd= drizzle->db= 0;
631
void drizzle_close(DRIZZLE *drizzle)
633
if (drizzle) /* Some simple safety */
635
/* If connection is still up, send a QUIT message */
636
if (drizzle->net.vio != 0)
638
free_old_query(drizzle);
639
drizzle->status=DRIZZLE_STATUS_READY; /* Force command */
640
drizzle->reconnect=0;
641
simple_command(drizzle,COM_QUIT,(unsigned char*) 0,0,1);
642
drizzle_disconnect(drizzle); /* Sets drizzle->net.vio= 0 */
644
drizzle_close_free_options(drizzle);
645
drizzle_close_free(drizzle);
646
if (drizzle->free_me)
647
free((unsigned char*) drizzle);
653
bool cli_read_query_result(DRIZZLE *drizzle)
656
uint32_t field_count;
657
DRIZZLE_DATA *fields;
660
if ((length = cli_safe_read(drizzle)) == packet_error)
662
free_old_query(drizzle); /* Free old result */
664
pos=(unsigned char*) drizzle->net.read_pos;
665
if ((field_count= net_field_length(&pos)) == 0)
667
drizzle->affected_rows= net_field_length_ll(&pos);
668
drizzle->insert_id= net_field_length_ll(&pos);
670
drizzle->server_status= uint2korr(pos); pos+=2;
671
drizzle->warning_count= uint2korr(pos); pos+=2;
673
if (pos < drizzle->net.read_pos+length && net_field_length(&pos))
674
drizzle->info=(char*) pos;
677
if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */
681
if (!(drizzle->options.client_flag & CLIENT_LOCAL_FILES))
683
drizzle_set_error(drizzle, CR_MALFORMED_PACKET, sqlstate_get_unknown());
687
error= handle_local_infile(drizzle,(char*) pos);
688
if ((length= cli_safe_read(drizzle)) == packet_error || error)
690
goto get_info; /* Get info packet */
692
if (!(drizzle->server_status & SERVER_STATUS_AUTOCOMMIT))
693
drizzle->server_status|= SERVER_STATUS_IN_TRANS;
695
if (!(fields=cli_read_rows(drizzle,(DRIZZLE_FIELD*)0, 7)))
697
if (!(drizzle->fields= unpack_fields(fields, (uint32_t) field_count, 0)))
699
drizzle->status= DRIZZLE_STATUS_GET_RESULT;
700
drizzle->field_count= (uint32_t) field_count;
706
Send the query and return so we can do something else.
707
Needs to be followed by drizzle_read_query_result() when we want to
708
finish processing it.
712
drizzle_send_query(DRIZZLE *drizzle, const char* query, uint32_t length)
714
return(simple_command(drizzle, COM_QUERY, (unsigned char*) query, length, 1));
719
drizzle_real_query(DRIZZLE *drizzle, const char *query, uint32_t length)
721
if (drizzle_send_query(drizzle,query,length))
723
return((int) (*drizzle->methods->read_query_result)(drizzle));
727
/**************************************************************************
728
Alloc result struct for buffered results. All rows are read to buffer.
729
drizzle_data_seek may be used.
730
**************************************************************************/
732
DRIZZLE_RES * drizzle_store_result(DRIZZLE *drizzle)
736
if (!drizzle->fields)
738
if (drizzle->status != DRIZZLE_STATUS_GET_RESULT)
740
drizzle_set_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, sqlstate_get_unknown());
743
drizzle->status=DRIZZLE_STATUS_READY; /* server is ready */
744
if (!(result=(DRIZZLE_RES*) malloc((uint32_t) (sizeof(DRIZZLE_RES)+
746
drizzle->field_count))))
748
drizzle_set_error(drizzle, CR_OUT_OF_MEMORY, sqlstate_get_unknown());
751
memset(result, 0,(sizeof(DRIZZLE_RES)+ sizeof(uint32_t) *
752
drizzle->field_count));
753
result->methods= drizzle->methods;
754
result->eof= 1; /* Marker for buffered */
755
result->lengths= (uint32_t*) (result+1);
757
(*drizzle->methods->read_rows)(drizzle,drizzle->fields,drizzle->field_count)))
759
free((unsigned char*) result);
762
drizzle->affected_rows= result->row_count= result->data->rows;
763
result->data_cursor= result->data->data;
764
result->fields= drizzle->fields;
765
result->field_count= drizzle->field_count;
766
/* The rest of result members is zeroed in malloc */
767
drizzle->fields=0; /* fields is now in result */
768
/* just in case this was mistakenly called after drizzle_stmt_execute() */
769
drizzle->unbuffered_fetch_owner= 0;
770
return(result); /* Data fetched */
774
/**************************************************************************
775
Alloc struct for use with unbuffered reads. Data is fetched by domand
776
when calling to drizzle_fetch_row.
777
DRIZZLE_DATA_seek is a noop.
779
No other queries may be specified with the same DRIZZLE handle.
780
There shouldn't be much processing per row because DRIZZLE server shouldn't
781
have to wait for the client (and will not wait more than 30 sec/packet).
782
**************************************************************************/
784
DRIZZLE_RES * cli_use_result(DRIZZLE *drizzle)
788
if (!drizzle->fields)
790
if (drizzle->status != DRIZZLE_STATUS_GET_RESULT)
792
drizzle_set_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, sqlstate_get_unknown());
795
if (!(result=(DRIZZLE_RES*) malloc(sizeof(*result)+
796
sizeof(uint32_t)*drizzle->field_count)))
798
memset(result, 0, sizeof(*result)+ sizeof(uint32_t)*drizzle->field_count);
799
result->lengths=(uint32_t*) (result+1);
800
result->methods= drizzle->methods;
801
if (!(result->row=(DRIZZLE_ROW)
802
malloc(sizeof(result->row[0])*(drizzle->field_count+1))))
803
{ /* Ptrs: to one row */
804
free((unsigned char*) result);
807
result->fields= drizzle->fields;
808
result->field_count= drizzle->field_count;
809
result->current_field=0;
810
result->handle= drizzle;
811
result->current_row= 0;
812
drizzle->fields=0; /* fields is now in result */
813
drizzle->status=DRIZZLE_STATUS_USE_RESULT;
814
drizzle->unbuffered_fetch_owner= &result->unbuffered_fetch_cancelled;
815
return(result); /* Data is read to be fetched */
821
Set the internal error message to DRIZZLE handler
823
@param drizzle connection handle (client side)
824
@param errcode CR_ error code, passed to ER macro to get
826
@parma sqlstate SQL standard sqlstate
829
void drizzle_set_error(DRIZZLE *drizzle, int errcode, const char *sqlstate)
832
assert(drizzle != 0);
837
net->last_errno= errcode;
838
strcpy(net->last_error, ER(errcode));
839
strcpy(net->sqlstate, sqlstate);
843
drizzle_server_last_errno= errcode;
844
strcpy(drizzle_server_last_error, ER(errcode));
850
unsigned int drizzle_errno(const DRIZZLE *drizzle)
852
return drizzle ? drizzle->net.last_errno : drizzle_server_last_errno;
856
const char * drizzle_error(const DRIZZLE *drizzle)
858
return drizzle ? _(drizzle->net.last_error) : _(drizzle_server_last_error);
862
Set an error message on the client.
864
@param drizzle connection handle
865
@param errcode CR_* errcode, for client errors
866
@param sqlstate SQL standard sql state, sqlstate_get_unknown() for the
867
majority of client errors.
868
@param format error message template, in sprintf format
869
@param ... variable number of arguments
872
void drizzle_set_extended_error(DRIZZLE *drizzle, int errcode,
873
const char *sqlstate,
874
const char *format, ...)
878
assert(drizzle != 0);
881
net->last_errno= errcode;
882
va_start(args, format);
883
vsnprintf(net->last_error, sizeof(net->last_error)-1,
886
strcpy(net->sqlstate, sqlstate);
894
Flush result set sent from server
897
void cli_flush_use_result(DRIZZLE *drizzle)
899
/* Clear the current execution status */
903
if ((pkt_len=cli_safe_read(drizzle)) == packet_error)
905
if (pkt_len <= 8 && drizzle->net.read_pos[0] == DRIZZLE_PROTOCOL_NO_MORE_DATA)
907
char *pos= (char*) drizzle->net.read_pos + 1;
908
drizzle->warning_count=uint2korr(pos); pos+=2;
909
drizzle->server_status=uint2korr(pos); pos+=2;
911
break; /* End of data */
917
/**************************************************************************
918
Get column lengths of the current row
919
If one uses drizzle_use_result, res->lengths contains the length information,
920
else the lengths are calculated from the offset between pointers.
921
**************************************************************************/
923
void cli_fetch_lengths(uint32_t *to, DRIZZLE_ROW column, uint32_t field_count)
925
uint32_t *prev_length;
929
prev_length=0; /* Keep gcc happy */
930
for (end=column + field_count + 1 ; column != end ; column++, to++)
937
if (start) /* Found end of prev string */
938
*prev_length= (uint32_t) (*column-start-1);