modules/sq/mysql_driver.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- SQ_try_connection
- SQ_get_connection
- SQ_execute_query
- SQ_execute_query_nostore
- SQ_get_column_count
- SQ_get_table_size
- SQ_get_affected_rows
- SQ_get_insert_id
- SQ_get_column_label
- SQ_get_column_max_length
- SQ_row_next
- SQ_get_column_string
- SQ_get_column_string_nocopy
- SQ_get_column_strings
- SQ_get_column_int
- SQ_result_to_string
- SQ_free_result
- SQ_close_connection
- SQ_num_rows
- SQ_info_to_string
- SQ_error
- SQ_errno
- SQ_get_info
- SQ_duplicate_connection
- SQ_abort_query
- SQ_ping
1 /***************************************
2 $Revision: 1.36 $
3
4 SQL module (sq) - this is a MySQL implementation of the SQL module.
5
6 Status: NOT REVUED, TESTED
7
8 ******************/ /******************
9 Filename : mysql_driver.c
10 Authors : ottrey@ripe.net
11 marek@ripe.net
12 OSs Tested : Solaris 7 / sun4u / sparc
13 ******************/ /******************
14 Copyright (c) 1999 RIPE NCC
15
16 All Rights Reserved
17
18 Permission to use, copy, modify, and distribute this software and its
19 documentation for any purpose and without fee is hereby granted,
20 provided that the above copyright notice appear in all copies and that
21 both that copyright notice and this permission notice appear in
22 supporting documentation, and that the name of the author not be
23 used in advertising or publicity pertaining to distribution of the
24 software without specific, written prior permission.
25
26 THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
27 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
28 AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
29 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
30 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
31 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
32 ***************************************/
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <time.h>
36 #include <sys/timeb.h>
37 #include <strings.h>
38 #include <sys/types.h>
39 #include <limits.h>
40 #include <errno.h>
41
42 #include "mysql_driver.h"
43 #include "constants.h"
44 #include "memwrap.h"
45 #include "timediff.h"
46
47 /*+ String sizes +*/
48 #define STR_S 63
49 #define STR_M 255
50 #define STR_L 1023
51 #define STR_XL 4095
52 #define STR_XXL 16383
53
54 /*
55 Description:
56
57 Connect to the the MySQL database, returning an error if unsuccessful.
58
59 Arguments:
60
61 SQ_connection_t **conn; used to return pointer to connection structure
62
63 const char *host; database server host to connect to, may be NULL or
64 "localhost", in which case Unix sockets may be used
65
66 unsigned int port; port to connect to database server on, may be 0 to use
67 default
68
69 const char *db; name of database to use, may be NULL
70
71 const char *user; name of user to connect as, if NULL then the current Unix
72 user login is used
73
74 const char *password; password to send, may be NULL to not use a password
75
76 Returns:
77
78 SQ_OK on success
79
80 SQ_CTCONN on error; the exact reason may be determined by using SQ_error()
81 on the value returned in *conn - this structure should be properly via
82 SQ_close_connection(), even on error
83
84 Notes:
85
86 Most parameters are passed straight through to the MySQL connect function,
87 so the MySQL documentation should be checked for current meaning.
88 */
89
90 er_ret_t
91 SQ_try_connection (SQ_connection_t **conn, const char *host,
/* [<][>][^][v][top][bottom][index][help] */
92 unsigned int port, const char *db,
93 const char *user, const char *password)
94 {
95 SQ_connection_t *res;
96
97 *conn = mysql_init(NULL);
98 dieif(*conn == NULL); /* XXX SK - need to call "out of memory handler" */
99
100 res = mysql_real_connect(*conn, host, user, password, db, port, NULL, 0);
101 if (res == NULL) {
102 return SQ_CTCONN;
103 } else {
104 return SQ_OK;
105 }
106 }
107
108 /* SQ_get_connection() */
109 /*++++++++++++++++++++++++++++++++++++++
110 Get a connection to the database.
111
112 const char *host
113
114 unsigned int port
115
116 const char *db
117
118 const char *user
119
120 const char *password
121
122 More:
123 +html+ <PRE>
124 Authors:
125 ottrey
126 +html+ </PRE><DL COMPACT>
127 +html+ <DT>Online References:
128 +html+ <DD><UL>
129 +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_init">mysql_init()</A>
130 +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_real_connect">mysql_real_connect()</A>
131 +html+ </UL></DL>
132
133 ++++++++++++++++++++++++++++++++++++++*/
134 SQ_connection_t *SQ_get_connection(const char *host, unsigned int port, const char *db, const char *user, const char *password) {
/* [<][>][^][v][top][bottom][index][help] */
135
136 SQ_connection_t *sql_connection;
137 er_ret_t res;
138 unsigned try = 0;
139
140 /* XXX MB.
141 This is really kludgy!
142 For some (unknown yet) reason, sometimes the connection does not
143 work the first time. So we try up to 3 times here, and give up only
144 then.
145
146 Check the logfiles for warnings, especially with newer mysql version,
147 like 3.23. The problem may or may not go away.
148
149 SK - I added a sleep() to avoid crushing the poor server.
150 */
151
152 for (;;) {
153 /* try to connect */
154 res = SQ_try_connection(&sql_connection, host, port, db, user, password);
155
156 /* on success, return our result */
157 if (NOERR(res)) {
158 return sql_connection;
159 }
160 else {
161
162 /* if we've tried enough, exit with error */
163 if (try >= 3) {
164 ER_perror(FAC_SQ, SQ_CTCONN, " %s; %s", db,
165 sql_connection ? SQ_error(sql_connection) : "-?");
166 die;
167 }
168
169 /* otherwise, prepare to try again */
170 ER_perror(FAC_SQ, SQ_CNCT, " %s; %s", db,
171 sql_connection ? SQ_error(sql_connection) : "-?");
172
173 if (try > 0) {
174 sleep(try);
175 }
176 try++;
177
178 if( sql_connection ) {
179 SQ_close_connection(sql_connection);
180 }
181 }
182 }/* for(;;) */
183 } /* SQ_get_connection() */
184
185 /* SQ_execute_query() */
186 /*++++++++++++++++++++++++++++++++++++++
187 Execute the sql query.
188
189 SQ_connection_t *sql_connection Connection to database.
190
191 const char *query SQL query.
192
193 SQ_result_set_t *result ptr to the structure to hold result.
194 May be NULL if no result is needed.
195
196 Returns:
197 0 if the query was successful.
198 Non-zero if an error occured.
199
200 More:
201 +html+ <PRE>
202 Authors:
203 ottrey, andrei, marek
204 +html+ </PRE><DL COMPACT>
205 +html+ <DT>Online References:
206 +html+ <DD><UL>
207 +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_query">mysql_query()</A>
208 +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_use_result">mysql_use_result()</A>
209 +html+ </UL></DL>
210
211 ++++++++++++++++++++++++++++++++++++++*/
212 int SQ_execute_query(SQ_connection_t *sql_connection,
/* [<][>][^][v][top][bottom][index][help] */
213 const char *query, SQ_result_set_t **result_ptr)
214 {
215 int err;
216 SQ_result_set_t *result;
217
218 ut_timer_t start_time, stop_time;
219
220 UT_timeget(&start_time);
221
222 err = mysql_query(sql_connection, query);
223
224 /* log the time and result of the query */
225 if (err == 0) {
226 result = mysql_store_result(sql_connection);
227
228 if (ER_is_traced(FAC_SQ, ASP_SQ_QRYTIME)) {
229 float seconds;
230
231 UT_timeget(&stop_time);
232 seconds = UT_timediff( &start_time, &stop_time );
233
234 ER_dbg_va(FAC_SQ, ASP_SQ_QRYTIME,
235 "spent %.2f sec; got %d rows from [%s: %s]",
236 seconds,
237 SQ_get_affected_rows(sql_connection),
238 sql_connection->db,
239 query);
240 }
241
242 if(result_ptr) *result_ptr=result;
243 else if(result) mysql_free_result(result);
244 return(0);
245 }
246 else return(-1);
247
248 } /* SQ_execute_query() */
249
250 /*
251 Description:
252
253 Performs identially to SQ_execute_query(), except that it does not read the
254 entire query into memory.
255
256 Notes:
257
258 No data may be written to the table until the entire result set is read,
259 so this should only be used in cases where:
260
261 1. an unacceptably large amount of memory will be returned by the query
262 2. there is no chance that a user can accidentally or maliciously
263 prevent the result set from being read in a expedicious manner
264 */
265
266 int
267 SQ_execute_query_nostore(SQ_connection_t *sql_connection,
/* [<][>][^][v][top][bottom][index][help] */
268 const char *query, SQ_result_set_t **result_ptr)
269 {
270 int err;
271 SQ_result_set_t *result;
272
273 err = mysql_query(sql_connection, query);
274 if (err != 0) {
275 return -1;
276 }
277 result = mysql_use_result(sql_connection);
278 if (result == NULL) {
279 return -1;
280 }
281 *result_ptr = result;
282 return 0;
283 } /* SQ_execute_query_nostore() */
284
285 /* SQ_get_column_count() */
286 /*++++++++++++++++++++++++++++++++++++++
287 Get the column count.
288
289 SQ_result_set_t *result The results from the query.
290
291 More:
292 +html+ <PRE>
293 Authors:
294 ottrey
295 +html+ </PRE><DL COMPACT>
296 +html+ <DT>Online References:
297 +html+ <DD><UL>
298 +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_num_fields">mysql_num_fields()</A>
299 +html+ </UL></DL>
300
301 ++++++++++++++++++++++++++++++++++++++*/
302 int SQ_get_column_count(SQ_result_set_t *result) {
/* [<][>][^][v][top][bottom][index][help] */
303 int cols;
304
305 cols = mysql_num_fields(result);
306
307 return cols;
308
309 } /* SQ_get_column_count() */
310
311 /* SQ_get_table_size() */
312 /*++++++++++++++++++++++++++++++++++++++
313 Get the row count of a table
314
315 char *table The table to be examined
316
317 More:
318 +html+ <PRE>
319 Authors:
320 marek
321 +html+ </PRE>
322
323 ++++++++++++++++++++++++++++++++++++++*/
324 int SQ_get_table_size(SQ_connection_t *sql_connection,
/* [<][>][^][v][top][bottom][index][help] */
325 char *table) {
326 int count;
327 char sql_command[128];
328 SQ_result_set_t *result;
329 SQ_row_t *row;
330 char *countstr;
331
332 sprintf(sql_command, "SELECT COUNT(*) FROM %s", table);
333 dieif(SQ_execute_query(sql_connection, sql_command, &result) == -1 );
334 row = SQ_row_next(result);
335
336 countstr = SQ_get_column_string(result, row, 0);
337 sscanf(countstr, "%d", &count);
338 wr_free(countstr);
339
340 SQ_free_result(result);
341
342 return count;
343 } /* SQ_get_table_size() */
344
345 /* SQ_get_affected_rows() */
346 /*++++++++++++++++++++++++++++++++++++++
347 Get the row count of a table
348
349 char *table The table to be examined
350
351 More:
352 +html+ <PRE>
353 Authors:
354 marek
355 +html+ </PRE>
356
357 ++++++++++++++++++++++++++++++++++++++*/
358 int SQ_get_affected_rows(SQ_connection_t *sql_connection)
/* [<][>][^][v][top][bottom][index][help] */
359 {
360 return (int)mysql_affected_rows(sql_connection);
361 }/* SQ_get_affected_rows() */
362
363 /* SQ_get_insert_id() */
364 /*++++++++++++++++++++++++++++++++++++++
365 Get the ID that was most recently generated for an AUTO_INCREMENT field
366
367
368 More:
369 +html+ <PRE>
370 Authors:
371 andrei
372 +html+ </PRE>
373
374 ++++++++++++++++++++++++++++++++++++++*/
375 long SQ_get_insert_id(SQ_connection_t *sql_connection)
/* [<][>][^][v][top][bottom][index][help] */
376 {
377 return (long)mysql_insert_id(sql_connection);
378 }/* SQ_get_insert_id() */
379
380 /* SQ_get_column_label() */
381 /*++++++++++++++++++++++++++++++++++++++
382 Get the column label.
383
384 SQ_result_set_t *result The results from the query.
385
386 unsigned int column The column index.
387
388 More:
389 +html+ <PRE>
390 Authors:
391 ottrey
392 +html+ </PRE><DL COMPACT>
393 +html+ <DT>Online References:
394 +html+ <DD><UL>
395 +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_fetch_field_direct">mysql_fetch_field_direct()</A>
396 +html+ </UL></DL>
397
398 ++++++++++++++++++++++++++++++++++++++*/
399 char *SQ_get_column_label(SQ_result_set_t *result, unsigned int column) {
/* [<][>][^][v][top][bottom][index][help] */
400 char *str;
401 /* MySQL decided to change their interface. Doh! */
402 #ifdef OLDMYSQL
403 MYSQL_FIELD field;
404
405 field = mysql_fetch_field_direct(result, column);
406
407 /*str = (char *)calloc(1, strlen(field.name)+1);*/
408 dieif( wr_malloc((void **)&str, strlen(field.name)+1) != UT_OK);
409 strcpy(str, field.name);
410 #else
411 MYSQL_FIELD *field;
412
413 field = mysql_fetch_field_direct(result, column);
414
415 /*str = (char *)calloc(1, strlen(field->name)+1);*/
416 dieif( wr_malloc((void **)&str, strlen(field->name)+1) != UT_OK);
417 strcpy(str, field->name);
418 #endif
419
420 /*
421 printf("column=%d\n", column);
422 printf("field.name=%s\n", field.name);
423 printf("field.table=%s\n", field.table);
424
425 printf("field.def=%s\n", field.def);
426
427 printf("field.type=%d\n", field.type);
428 printf("field.length=%d\n", field.length);
429 printf("field.max_length=%d\n", field.max_length);
430 printf("field.flags=%d\n", field.flags);
431 printf("field.decimals=%d\n", field.decimals);
432 */
433
434 return str;
435
436 } /* SQ_get_column_label() */
437
438 /* SQ_get_column_max_length() */
439 /*++++++++++++++++++++++++++++++++++++++
440 Get the max length of the column.
441
442 SQ_result_set_t *result The results from the query.
443
444 unsigned int column The column index.
445
446 More:
447 +html+ <PRE>
448 Authors:
449 ottrey
450 +html+ </PRE><DL COMPACT>
451 +html+ <DT>Online References:
452 +html+ <DD><UL>
453 +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_fetch_field_direct">mysql_fetch_field_direct()</A>
454 +html+ </UL></DL>
455
456 ++++++++++++++++++++++++++++++++++++++*/
457 unsigned int SQ_get_column_max_length(SQ_result_set_t *result, unsigned int column) {
/* [<][>][^][v][top][bottom][index][help] */
458 /* MySQL decided to change their interface. Doh! */
459 #ifdef OLDMYSQL
460 MYSQL_FIELD field;
461
462 field = mysql_fetch_field_direct(result, column);
463
464 return field.length;
465 #else
466 MYSQL_FIELD *field;
467
468 field = mysql_fetch_field_direct(result, column);
469
470 return field->length;
471 #endif
472
473 } /* SQ_get_column_max_length() */
474
475 /* SQ_row_next() */
476 /*++++++++++++++++++++++++++++++++++++++
477 Get the next row.
478
479 SQ_result_set_t *result The results from the query.
480
481 unsigned int column The column index.
482
483 More:
484 +html+ <PRE>
485 Authors:
486 ottrey
487 +html+ </PRE><DL COMPACT>
488 +html+ <DT>Online References:
489 +html+ <DD><UL>
490 +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_fetch_row">mysql_fetch_row()</A>
491 +html+ </UL></DL>
492
493 ++++++++++++++++++++++++++++++++++++++*/
494 SQ_row_t *SQ_row_next(SQ_result_set_t *result) {
/* [<][>][^][v][top][bottom][index][help] */
495
496 return (SQ_row_t *)mysql_fetch_row(result);
497
498 } /* SQ_row_next() */
499
500 /* SQ_get_column_string() */
501 /*++++++++++++++++++++++++++++++++++++++
502 Get the column string.
503
504 SQ_row_t *current_row The current row (obtained from a SQ_row_next() ).
505
506 unsigned int column The column index.
507
508 More:
509 +html+ <PRE>
510 Authors:
511 ottrey
512 +html+ </PRE><DL COMPACT>
513 +html+ <DT>Online References:
514 +html+ <DD><UL>
515 +html+ </UL></DL>
516
517 ++++++++++++++++++++++++++++++++++++++*/
518 char *SQ_get_column_string(SQ_result_set_t *result, SQ_row_t *current_row, unsigned int column) {
/* [<][>][^][v][top][bottom][index][help] */
519 char *str=NULL;
520 unsigned length = mysql_fetch_lengths(result)[column];
521
522 if (current_row != NULL && current_row[column] != NULL) {
523 /*str = (char *)malloc(length + 1);*/
524 dieif( wr_malloc((void **)&str, length + 1) != UT_OK);
525 if (str != NULL) {
526 memcpy(str, current_row[column], length );
527 str[length] = '\0';
528 }
529 }
530
531 return str;
532
533 } /* SQ_get_column_string() */
534
535 /* SQ_get_column_string_nocopy - return pointer to the column string
536 without making a copy of it */
537 char *SQ_get_column_string_nocopy(SQ_result_set_t *result,
/* [<][>][^][v][top][bottom][index][help] */
538 SQ_row_t *current_row,
539 unsigned int column)
540 {
541 if (current_row != NULL && current_row[column] != NULL) {
542 return (char *)current_row[column];
543 }
544 return NULL;
545 }/* SQ_get_column_string_nocopy */
546
547
548
549 /* SQ_get_column_strings() */
550 /*++++++++++++++++++++++++++++++++++++++
551 Get the all the strings in one column.
552
553 SQ_result_set_t *result The results.
554
555 unsigned int column The column index.
556
557 More:
558 +html+ <PRE>
559 Authors:
560 ottrey
561 +html+ </PRE><DL COMPACT>
562 +html+ <DT>Online References:
563 +html+ <DD><UL>
564 +html+ </UL></DL>
565
566 ++++++++++++++++++++++++++++++++++++++*/
567 char *SQ_get_column_strings(SQ_result_set_t *result, unsigned int column) {
/* [<][>][^][v][top][bottom][index][help] */
568 MYSQL_ROW row;
569 char str_buffer[STR_XXL];
570 char str_buffer_tmp[STR_L];
571 char *str;
572
573 strcpy(str_buffer, "");
574
575 while ((row = mysql_fetch_row(result)) != NULL) {
576 if (row[column] != NULL) {
577 sprintf(str_buffer_tmp, "%s\n", row[column]);
578 }
579 strcat(str_buffer, str_buffer_tmp);
580
581 if (strlen(str_buffer) >= (STR_XXL - STR_XL) ) {
582 strcat(str_buffer, "And some more stuff...\n");
583 break;
584 }
585 }
586
587 if (strcmp(str_buffer, "") != 0) {
588 /*str = (char *)calloc(1, strlen(str_buffer)+1);*/
589 dieif( wr_malloc((void **)&str, strlen(str_buffer)+1) != UT_OK);
590 strcpy(str, str_buffer);
591 }
592 else {
593 str = NULL;
594 }
595
596 return str;
597
598 } /* SQ_get_column_strings() */
599
600 /* SQ_get_column_int() */
601 /*++++++++++++++++++++++++++++++++++++++
602 Get an integer from the column.
603
604 SQ_result_set_t *result The results.
605
606 SQ_row_t *current_row The current row.
607
608 unsigned int column The column index.
609
610 long *resultptr pointer where the result should be stored
611
612 returns -1 if error occurs, 0 otherwise.
613 Note - it never says what error occured....
614
615 More:
616 +html+ <PRE>
617 Authors:
618 ottrey
619 +html+ </PRE><DL COMPACT>
620 +html+ <DT>Online References:
621 +html+ <DD><UL>
622 +html+ </UL></DL>
623
624 ++++++++++++++++++++++++++++++++++++++*/
625 int SQ_get_column_int(SQ_result_set_t *result, SQ_row_t *current_row, unsigned int column, long *resultptr) {
/* [<][>][^][v][top][bottom][index][help] */
626 int ret_val;
627 long col_val;
628 char *endptr;
629
630 if (current_row[column] != NULL) {
631 col_val = strtol((char *)current_row[column], &endptr, 10);
632
633 /* under- or over-flow */
634 if (((col_val==LONG_MIN) || (col_val==LONG_MAX)) && (errno==ERANGE)) {
635 ret_val = -1;
636
637 /* unrecognized characters in string */
638 } else if (*endptr != '\0') {
639 ret_val = -1;
640
641 /* good parse */
642 } else {
643 *resultptr = col_val;
644 ret_val = 0;
645 }
646 } else {
647 ret_val = -1;
648 }
649 return ret_val;
650
651 } /* SQ_get_column_int() */
652
653
654 /* SQ_result_to_string() */
655 /*++++++++++++++++++++++++++++++++++++++
656 Convert the result set to a string.
657
658 SQ_result_set_t *result The results.
659
660 More:
661 +html+ <PRE>
662 Authors:
663 ottrey
664 +html+ </PRE><DL COMPACT>
665 +html+ <DT>Online References:
666 +html+ <DD><UL>
667 +html+ </UL></DL>
668
669 ++++++++++++++++++++++++++++++++++++++*/
670 char *SQ_result_to_string(SQ_result_set_t *result) {
/* [<][>][^][v][top][bottom][index][help] */
671 MYSQL_ROW row;
672 unsigned int no_cols;
673 unsigned int i, j;
674 char str_buffer[STR_XXL];
675 char str_buffer_tmp[STR_L];
676 char border[STR_L];
677 char *str;
678
679 char *label;
680
681 unsigned int length[STR_S];
682
683 strcpy(str_buffer, "");
684
685 no_cols = mysql_num_fields(result);
686
687 /* Determine the maximum column widths */
688 /* XXX Surely MySQL should keep note of this for me! */
689 strcpy(border, "");
690 for (i=0; i < no_cols; i++) {
691 length[i] = SQ_get_column_max_length(result, i);
692 /* Make sure the lenghts don't get too long */
693 if (length[i] > STR_M) {
694 length[i] = STR_M;
695 }
696 strcat(border, "*");
697 for (j=0; (j <= length[i]) && (j < STR_L); j++) {
698 strcat(border, "-");
699 }
700 }
701 strcat(border, "*\n");
702 /*
703 for (i=0; i < no_cols; i++) {
704 printf("length[%d]=%d\n", i, length[i]);
705 }
706 */
707
708 strcat(str_buffer, border);
709
710 for (i=0; i < no_cols; i++) {
711 label = SQ_get_column_label(result, i);
712 if (label != NULL) {
713 sprintf(str_buffer_tmp, "| %-*s", length[i], label);
714 strcat(str_buffer, str_buffer_tmp);
715 }
716 }
717 strcat(str_buffer, "|\n");
718
719 strcat(str_buffer, border);
720
721
722 while ((row = mysql_fetch_row(result)) != NULL) {
723 for (i=0; i < no_cols; i++) {
724 if (row[i] != NULL) {
725 sprintf(str_buffer_tmp, "| %-*s", length[i], row[i]);
726 }
727 else {
728 sprintf(str_buffer_tmp, "| %-*s", length[i], "NuLL");
729 }
730 strcat(str_buffer, str_buffer_tmp);
731 }
732 strcat(str_buffer, "|\n");
733
734 if (strlen(str_buffer) >= (STR_XXL - STR_XL) ) {
735 strcat(str_buffer, "And some more stuff...\n");
736 break;
737 }
738 }
739
740 strcat(str_buffer, border);
741
742 /* str = (char *)calloc(1, strlen(str_buffer)+1);*/
743 dieif( wr_malloc((void **)&str, strlen(str_buffer)+1) != UT_OK);
744 strcpy(str, str_buffer);
745
746 return str;
747
748 } /* SQ_result_to_string() */
749
750 /* SQ_free_result() */
751 /*++++++++++++++++++++++++++++++++++++++
752 Free the result set.
753
754 SQ_result_set_t *result The results.
755
756 More:
757 +html+ <PRE>
758 Authors:
759 ottrey
760 +html+ </PRE><DL COMPACT>
761 +html+ <DT>Online References:
762 +html+ <DD><UL>
763 +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_free_result">mysql_free_result()</A>
764 +html+ </UL></DL>
765
766 ++++++++++++++++++++++++++++++++++++++*/
767 void SQ_free_result(SQ_result_set_t *result) {
/* [<][>][^][v][top][bottom][index][help] */
768 mysql_free_result(result);
769 } /* SQ_free_result() */
770
771
772 /* SQ_close_connection() */
773 /*++++++++++++++++++++++++++++++++++++++
774 Call this function to close a connection to the server
775
776 SQ_connection_t *sql_connection The connection to the database.
777
778 More:
779 +html+ <PRE>
780 Authors:
781 ottrey
782 +html+ </PRE><DL COMPACT>
783 +html+ <DT>Online References:
784 +html+ <DD><UL>
785 +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_close">mysql_close()</A>
786 +html+ </UL></DL>
787
788 ++++++++++++++++++++++++++++++++++++++*/
789 void SQ_close_connection(SQ_connection_t *sql_connection) {
/* [<][>][^][v][top][bottom][index][help] */
790
791 mysql_close(sql_connection);
792
793 }
794
795 /* SQ_num_rows() */
796 /*++++++++++++++++++++++++++++++++++++++
797 Call this function to find out how many rows are in a query result
798
799 SQ_result_set_t *result The results.
800
801 More:
802 +html+ <PRE>
803 Authors:
804 ottrey
805 +html+ </PRE><DL COMPACT>
806 +html+ <DT>Online References:
807 +html+ <DD><UL>
808 +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_num_rows">mysql_num_rows()</A>
809 +html+ </UL></DL>
810
811 ++++++++++++++++++++++++++++++++++++++*/
812 int SQ_num_rows(SQ_result_set_t *result) {
/* [<][>][^][v][top][bottom][index][help] */
813 int rows=-1;
814
815 if (result != NULL) {
816 rows = mysql_num_rows(result);
817 }
818
819 return rows;
820 }
821
822 /* SQ_info_to_string() */
823 /*++++++++++++++++++++++++++++++++++++++
824 Convert all available information about the sql server into a string.
825
826 SQ_connection_t *sql_connection The connection to the database.
827
828 More:
829 +html+ <PRE>
830 Authors:
831 ottrey
832 +html+ </PRE><DL COMPACT>
833 +html+ <DT>Online References:
834 +html+ <DD><UL>
835 +html+ </UL></DL>
836
837 ++++++++++++++++++++++++++++++++++++++*/
838 char *SQ_info_to_string(SQ_connection_t *sql_connection) {
/* [<][>][^][v][top][bottom][index][help] */
839 char str_buffer[STR_XXL];
840 char str_buffer_tmp[STR_L];
841 char *str;
842 char *str_tmp;
843
844 strcpy(str_buffer, "");
845
846 /* Makes the server dump debug information to the log. */
847 sprintf(str_buffer_tmp, "mysql_dump_debug_info()=%d\n", mysql_dump_debug_info(sql_connection));
848 strcat(str_buffer, str_buffer_tmp);
849
850 /* Returns the error number from the last MySQL function. */
851 sprintf(str_buffer_tmp, "mysql_errno()=%d\n", mysql_errno(sql_connection));
852 strcat(str_buffer, str_buffer_tmp);
853
854 /* Returns the error message from the last MySQL function. */
855 sprintf(str_buffer_tmp, "mysql_error()=%s\n", mysql_error(sql_connection));
856 strcat(str_buffer, str_buffer_tmp);
857
858 /* Returns client version information. */
859 sprintf(str_buffer_tmp, "mysql_get_client_info()=%s\n", mysql_get_client_info() );
860 strcat(str_buffer, str_buffer_tmp);
861
862 /* Returns a string describing the connection. */
863 sprintf(str_buffer_tmp, "mysql_get_host_info()=%s\n", mysql_get_host_info(sql_connection));
864 strcat(str_buffer, str_buffer_tmp);
865
866 /* Returns the protocol version used by the connection. */
867 sprintf(str_buffer_tmp, "mysql_get_proto_info()=%d\n", mysql_get_proto_info(sql_connection));
868 strcat(str_buffer, str_buffer_tmp);
869
870 /* Returns the server version number. */
871 sprintf(str_buffer_tmp, "mysql_get_server_info()=%s\n", mysql_get_server_info(sql_connection));
872 strcat(str_buffer, str_buffer_tmp);
873
874 /* Information about the most recently executed query. */
875 /* XXX Check for NULL */
876 str_tmp = mysql_info(sql_connection);
877 if (str_tmp != NULL) {
878 sprintf(str_buffer_tmp, "mysql_info()=%s\n", str_tmp);
879 }
880 else {
881 sprintf(str_buffer_tmp, "mysql_info()=%s\n", "NulL");
882 }
883 strcat(str_buffer, str_buffer_tmp);
884
885
886 /* Returns a list of the current server threads.
887
888 NOT Used here, because it returns a RESULT struct that must be
889 iterated through.
890
891 sprintf(str_buffer_tmp, "mysql_list_processes()=%x\n", mysql_list_processes(sql_connection));
892 strcat(str_buffer, str_buffer_tmp);
893
894 */
895
896 /* Checks if the connection to the server is working. */
897 sprintf(str_buffer_tmp, "mysql_ping()=%d\n", mysql_ping(sql_connection));
898 strcat(str_buffer, str_buffer_tmp);
899
900 /* Returns the server status as a string. */
901 sprintf(str_buffer_tmp, "mysql_stat()=%s\n", mysql_stat(sql_connection));
902 strcat(str_buffer, str_buffer_tmp);
903
904 /* Returns the current thread id. */
905 sprintf(str_buffer_tmp, "mysql_thread_id()=%ld\n", mysql_thread_id(sql_connection));
906 strcat(str_buffer, str_buffer_tmp);
907
908
909 /*str = (char *)calloc(1, strlen(str_buffer)+1);*/
910 dieif( wr_malloc((void **)&str, strlen(str_buffer)+1) != UT_OK);
911 strcpy(str, str_buffer);
912
913 return str;
914
915 } /* SQ_info_to_string() */
916
917 /* SQ_error() */
918 /*++++++++++++++++++++++++++++++++++++++
919 Get the error string for the last error.
920
921 SQ_connection_t *sql_connection The connection to the database.
922
923 More:
924 +html+ <PRE>
925 Authors:
926 ottrey
927 +html+ </PRE><DL COMPACT>
928 +html+ <DT>Online References:
929 +html+ <DD><UL>
930 +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_error">mysql_error()</A>
931 +html+ </UL></DL>
932
933 ++++++++++++++++++++++++++++++++++++++*/
934 char *SQ_error(SQ_connection_t *sql_connection) {
/* [<][>][^][v][top][bottom][index][help] */
935
936 return mysql_error(sql_connection);
937
938 } /* SQ_error() */
939
940 /* SQ_errno() */
941 /*++++++++++++++++++++++++++++++++++++++
942 Get the error number for the last error.
943
944 SQ_connection_t *sql_connection The connection to the database.
945
946 More:
947 +html+ <PRE>
948 Authors:
949 ottrey
950 +html+ </PRE><DL COMPACT>
951 +html+ <DT>Online References:
952 +html+ <DD><UL>
953 +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_free_result">mysql_free_result()</A>
954 +html+ </UL></DL>
955
956 ++++++++++++++++++++++++++++++++++++++*/
957 int SQ_errno(SQ_connection_t *sql_connection) {
/* [<][>][^][v][top][bottom][index][help] */
958
959 return mysql_errno(sql_connection);
960
961 } /* SQ_errno() */
962
963 /* SQ_get_info() */
964 /*++++++++++++++++++++++++++++++++++++++
965 Get additional information about the most
966 recently executed query.
967
968 SQ_connection_t *sql_connection The connection to the database.
969 int info[3] array of integers where information is stored
970
971 The meaning of the numbers returned depends on the query type:
972
973 info[SQL_RECORDS] - # of Records for INSERT
974 info[SQL_MATCHES] - # of Matches for UPDATE
975 info[SQL_DUPLICATES] - # of Duplicates
976 info[SQL_WARNINGS] - # of Warnings
977
978 More:
979 +html+ <PRE>
980 Authors:
981 andrei
982 +html+ </PRE><DL COMPACT>
983 +html+ <DT>Online References:
984 +html+ <DD><UL>
985 +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_info">mysql_info()</A>
986 +html+ </UL></DL>
987
988 ++++++++++++++++++++++++++++++++++++++*/
989
990 int SQ_get_info(SQ_connection_t *sql_connection, int info[3])
/* [<][>][^][v][top][bottom][index][help] */
991 {
992 int ii;
993 char *colon, *buf_ptr, buf[20];
994 char *infoline;
995
996 infoline=mysql_info(sql_connection);
997 ii=0;
998 colon = infoline;
999 while (*colon != '\0') {
1000 colon++;
1001 buf_ptr=buf;
1002 if(isdigit((int)*colon)){
1003 while(isdigit((int)*colon)){
1004 *buf_ptr=*colon; buf_ptr++; colon++;
1005 }
1006 *buf_ptr='\0';
1007 info[ii]=atoi(buf); ii++;
1008 }
1009 }
1010 return(0);
1011 }
1012
1013
1014 /*
1015 open a connection with the same parameters
1016
1017 by marek
1018 */
1019 SQ_connection_t *
1020 SQ_duplicate_connection(SQ_connection_t *orig)
/* [<][>][^][v][top][bottom][index][help] */
1021 {
1022 return SQ_get_connection(orig->host, orig->port, orig->db,
1023 orig->user, orig->passwd);
1024 }
1025
1026 /*
1027 abort the current query on the given connection
1028
1029 by marek
1030 */
1031 int
1032 SQ_abort_query(SQ_connection_t *sql_connection)
/* [<][>][^][v][top][bottom][index][help] */
1033 {
1034 SQ_connection_t *contemp = SQ_duplicate_connection(sql_connection);
1035 int res = mysql_kill(contemp, sql_connection->thread_id);
1036
1037 ER_dbg_va(FAC_SQ, ASP_SQ_ABORT,
1038 "connection %d aborted by tmp thread %d",
1039 sql_connection->thread_id,
1040 contemp->thread_id);
1041
1042 SQ_close_connection(contemp);
1043
1044 return res;
1045 }
1046
1047 /* SQ_ping() */
1048 /*++++++++++++++++++++++++++++++++++++++
1049 Checks whether or not the connection to the server is working.
1050 If it has gone down, an automatic reconnection is attempted.
1051
1052 Return values
1053
1054 Zero if the server is alive. Non-zero if an error occurred.
1055
1056 More:
1057 +html+ <PRE>
1058 Authors:
1059 andrei
1060 +html+ </PRE><DL COMPACT>
1061 +html+ <DT>Online References:
1062 +html+ <DD><UL>
1063 +html+ </UL></DL>
1064
1065 ++++++++++++++++++++++++++++++++++++++*/
1066 int SQ_ping(SQ_connection_t *sql_connection)
/* [<][>][^][v][top][bottom][index][help] */
1067 {
1068 return(mysql_ping(sql_connection));
1069 }
1070