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