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