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