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