1    | /***************************************
2    |   $Revision: 1.8 $
3    | 
4    |   SQL module (sq) - this is a MySQL implementation of the SQL module.
5    | 
6    |   Status: NOT REVUED, NOT TESTED
7    | 
8    |   ******************/ /******************
9    |   Filename            : mysql_driver.c
10   |   Author              : ottrey@ripe.net
11   |   OSs Tested          : Solaris
12   |   ******************/ /******************
13   |   Copyright (c) 1999                              RIPE NCC
14   |  
15   |   All Rights Reserved
16   |   
17   |   Permission to use, copy, modify, and distribute this software and its
18   |   documentation for any purpose and without fee is hereby granted,
19   |   provided that the above copyright notice appear in all copies and that
20   |   both that copyright notice and this permission notice appear in
21   |   supporting documentation, and that the name of the author not be
22   |   used in advertising or publicity pertaining to distribution of the
23   |   software without specific, written prior permission.
24   |   
25   |   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
26   |   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
27   |   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
28   |   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
29   |   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
30   |   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
31   |   ***************************************/
32   | #include <stdlib.h>
33   | #include <stdio.h>
34   | #include "mysql_driver.h"
35   | #include "constants.h"
36   | #include <sys/timeb.h>
37   | 
38   | /* XXX NB.  The changes to SQ_row_next() and the removal of the Global variable Current_row */
39   | 
40   | 
41   | /*+ String sizes +*/
42   | #define STR_S   63
43   | #define STR_M   255
44   | #define STR_L   1023
45   | #define STR_XL  4095
46   | #define STR_XXL 16383
47   | 
48   | 
49   | /* log_query() */
50   | /*++++++++++++++++++++++++++++++++++++++
51   |   Log the query.  This should/will get merged with a tracing module.
52   | 
53   |   More:
54   |   +html+ <PRE>
55   |   Authors:
56   |         ottrey
57   |   +html+ </PRE><DL COMPACT>
58   |   +html+ <DT>Online References:
59   |   +html+ <DD><UL>
60   |   +html+ </UL></DL>
61   | 
62   |   ++++++++++++++++++++++++++++++++++++++*/
63   | static void log_query(const char *logfile, const char *query, struct timeb *start, struct timeb *stop) {
64   |   FILE *logf;
65   |   int seconds;
66   |   int milliseconds;
67   | 
68   |   seconds = (int)(stop->time - start->time);
69   |   milliseconds = (int)(stop->millitm - start->millitm);
70   |   if (milliseconds < 0) {
71   |     milliseconds += 1000;
72   |     seconds--;
73   |   }
74   | 
75   |   if (strcmp(logfile, "stdout") == 0) {
76   |     printf("query=[%s] took %d sec %d msec\n", query, seconds, milliseconds);
77   |   }
78   |   else {
79   |     logf = fopen(logfile, "a");
80   |     fprintf(logf, "query=[%s] took %d sec %d msec\n", query, seconds, milliseconds);
81   |     fclose(logf);
82   |   }
83   | 
84   | } /* log_query() */
85   | 
86   | /* SQ_get_connection() */
87   | /*++++++++++++++++++++++++++++++++++++++
88   |   Get a connection to the database.
89   | 
90   |   const char *host
91   |   
92   |   unsigned int port
93   | 
94   |   const char *db
95   |   
96   |   const char *user
97   |   
98   |   const char *password
99   |    
100  |   More:
101  |   +html+ <PRE>
102  |   Authors:
103  |         ottrey
104  |   +html+ </PRE><DL COMPACT>
105  |   +html+ <DT>Online References:
106  |   +html+ <DD><UL>
107  |   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_init">mysql_init()</A>
108  |   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_real_connect">mysql_real_connect()</A>
109  |   +html+ </UL></DL>
110  | 
111  |   ++++++++++++++++++++++++++++++++++++++*/
112  | SQ_connection_t *SQ_get_connection(const char *host, unsigned int port, const char *db, const char *user, const char *password) {
113  | 
114  |   SQ_connection_t *sql_connection;
115  | 
116  |   sql_connection = mysql_init(NULL);
117  |   if (!sql_connection) {
118  | /* Check for errors */
119  | 	  printf("Connection init error\n");
120  |   }
121  | 
122  |   sql_connection = mysql_real_connect(sql_connection, host, user, password, db, port, NULL, 0);
123  |   if (!sql_connection) {
124  | /* Check for errors */
125  | 	  printf("Connection error: Failed to connect to database....\n");
126  |     exit(-1);
127  |   }
128  | 
129  |   return sql_connection;
130  | 
131  | } /* SQ_get_connection() */
132  | 
133  | /* SQ_execute_query() */
134  | /*++++++++++++++++++++++++++++++++++++++
135  |   Execute the sql query.
136  | 
137  |   SQ_connection_t *sql_connection Connection to database.
138  |   
139  |   const char *query SQL query.
140  |   
141  |   More:
142  |   +html+ <PRE>
143  |   Authors:
144  |         ottrey
145  |   +html+ </PRE><DL COMPACT>
146  |   +html+ <DT>Online References:
147  |   +html+ <DD><UL>
148  |   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_query">mysql_query()</A>
149  |   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_use_result">mysql_use_result()</A>
150  |   +html+ </UL></DL>
151  | 
152  |   ++++++++++++++++++++++++++++++++++++++*/
153  | SQ_result_set_t *SQ_execute_query(SQ_connection_t *sql_connection, const char *query) {
154  |   struct timeb *start_time;
155  |   struct timeb *stop_time;
156  |   int err;
157  |   SQ_result_set_t *result;
158  | 
159  |   if (CO_get_query_logging() == 1) {
160  |     start_time=(struct timeb *)calloc(1, sizeof(struct timeb)+1);
161  |     stop_time=(struct timeb *)calloc(1, sizeof(struct timeb)+1);
162  | 
163  |     ftime(start_time);
164  |     err = mysql_query(sql_connection, query);
165  |     ftime(stop_time);
166  | 
167  |     log_query(CO_get_query_logfile(), query, start_time, stop_time);
168  |     
169  |     free(start_time);
170  |     free(stop_time);
171  |   }
172  |   else {
173  |     err = mysql_query(sql_connection, query);
174  |   }
175  | 
176  |   if (err == 0) {
177  |     result = mysql_use_result(sql_connection);
178  |   }
179  |   else {
180  |     result = NULL;
181  |   }
182  | 
183  |   return result;
184  | 
185  | } /* SQ_execute_query() */
186  | 
187  | /* SQ_get_column_count() */
188  | /*++++++++++++++++++++++++++++++++++++++
189  |   Get the column count.
190  | 
191  |   SQ_result_set_t *result The results from the query.
192  |   
193  |   More:
194  |   +html+ <PRE>
195  |   Authors:
196  |         ottrey
197  |   +html+ </PRE><DL COMPACT>
198  |   +html+ <DT>Online References:
199  |   +html+ <DD><UL>
200  |   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_num_fields">mysql_num_fields()</A>
201  |   +html+ </UL></DL>
202  | 
203  |   ++++++++++++++++++++++++++++++++++++++*/
204  | int SQ_get_column_count(SQ_result_set_t *result) {
205  |   int cols;
206  | 
207  |   cols = mysql_num_fields(result);
208  | 
209  |   return cols;
210  | 
211  | } /* SQ_get_column_count() */
212  | 
213  | /* SQ_get_column_label() */
214  | /*++++++++++++++++++++++++++++++++++++++
215  |   Get the column label.
216  | 
217  |   SQ_result_set_t *result The results from the query.
218  |   
219  |   unsigned int column The column index.
220  | 
221  |   More:
222  |   +html+ <PRE>
223  |   Authors:
224  |         ottrey
225  |   +html+ </PRE><DL COMPACT>
226  |   +html+ <DT>Online References:
227  |   +html+ <DD><UL>
228  |   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_fetch_field_direct">mysql_fetch_field_direct()</A>
229  |   +html+ </UL></DL>
230  | 
231  |   ++++++++++++++++++++++++++++++++++++++*/
232  | char *SQ_get_column_label(SQ_result_set_t *result, unsigned int column) {
233  |   char *str;
234  |   MYSQL_FIELD field;
235  | 
236  |   field = mysql_fetch_field_direct(result, column);
237  | 
238  | /*
239  |   printf("column=%d\n", column);
240  |   printf("field.name=%s\n", field.name);
241  |   printf("field.table=%s\n", field.table);
242  | */
243  |   /*
244  |   printf("field.def=%s\n", field.def);
245  |   */
246  | /*
247  |   printf("field.type=%d\n", field.type);
248  |   printf("field.length=%d\n", field.length);
249  |   printf("field.max_length=%d\n", field.max_length);
250  |   printf("field.flags=%d\n", field.flags);
251  |   printf("field.decimals=%d\n", field.decimals);
252  | */
253  | 
254  |   str = (char *)calloc(1, strlen(field.name)+1);
255  |   strcpy(str, field.name);
256  | 
257  |   return str;
258  | 
259  | } /* SQ_get_column_label() */
260  | 
261  | /* SQ_get_column_max_length() */
262  | /*++++++++++++++++++++++++++++++++++++++
263  |   Get the max length of the column.
264  | 
265  |   SQ_result_set_t *result The results from the query.
266  |   
267  |   unsigned int column The column index.
268  | 
269  |   More:
270  |   +html+ <PRE>
271  |   Authors:
272  |         ottrey
273  |   +html+ </PRE><DL COMPACT>
274  |   +html+ <DT>Online References:
275  |   +html+ <DD><UL>
276  |   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_fetch_field_direct">mysql_fetch_field_direct()</A>
277  |   +html+ </UL></DL>
278  | 
279  |   ++++++++++++++++++++++++++++++++++++++*/
280  | unsigned int SQ_get_column_max_length(SQ_result_set_t *result, unsigned int column) {
281  |   MYSQL_FIELD field;
282  | 
283  |   field = mysql_fetch_field_direct(result, column);
284  | 
285  |   return field.length;
286  | 
287  | } /* SQ_get_column_max_length() */
288  | 
289  | /* SQ_row_next() */
290  | /*++++++++++++++++++++++++++++++++++++++
291  |   Get the next row.
292  | 
293  |   SQ_result_set_t *result The results from the query.
294  |   
295  |   unsigned int column The column index.
296  | 
297  |   More:
298  |   +html+ <PRE>
299  |   Authors:
300  |         ottrey
301  |   +html+ </PRE><DL COMPACT>
302  |   +html+ <DT>Online References:
303  |   +html+ <DD><UL>
304  |   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_fetch_row">mysql_fetch_row()</A>
305  |   +html+ </UL></DL>
306  | 
307  |   ++++++++++++++++++++++++++++++++++++++*/
308  | SQ_row_t *SQ_row_next(SQ_result_set_t *result) {
309  | 
310  |   return (SQ_row_t *)mysql_fetch_row(result);
311  | 
312  | } /* SQ_row_next() */
313  | 
314  | /* SQ_get_column_string() */
315  | /*++++++++++++++++++++++++++++++++++++++
316  |   Get the column string.
317  | 
318  |   SQ_row_t *current_row The current row (obtained from a SQ_row_next() ).
319  |   
320  |   unsigned int column The column index.
321  | 
322  |   More:
323  |   +html+ <PRE>
324  |   Authors:
325  |         ottrey
326  |   +html+ </PRE><DL COMPACT>
327  |   +html+ <DT>Online References:
328  |   +html+ <DD><UL>
329  |   +html+ </UL></DL>
330  | 
331  |   ++++++++++++++++++++++++++++++++++++++*/
332  | char *SQ_get_column_string(SQ_row_t *current_row, unsigned int column) {
333  |   char *str=NULL;
334  | 
335  |   if (current_row[column] != NULL) {
336  |     str = (char *)calloc(1, strlen(current_row[column])+1);
337  |     if (str != NULL) {
338  |       strcpy(str, current_row[column]);
339  |     }
340  |   }
341  | 
342  |   return str;
343  |   
344  | } /* SQ_get_column_string() */
345  | 
346  | /* SQ_get_column_string() */
347  | /*++++++++++++++++++++++++++++++++++++++
348  |   Get the all the strings in one column.
349  | 
350  |   SQ_result_set_t *result The results.
351  |   
352  |   unsigned int column The column index.
353  | 
354  |   More:
355  |   +html+ <PRE>
356  |   Authors:
357  |         ottrey
358  |   +html+ </PRE><DL COMPACT>
359  |   +html+ <DT>Online References:
360  |   +html+ <DD><UL>
361  |   +html+ </UL></DL>
362  | 
363  |   ++++++++++++++++++++++++++++++++++++++*/
364  | char *SQ_get_column_strings(SQ_result_set_t *result, unsigned int column) {
365  |   MYSQL_ROW row;
366  |   char str_buffer[STR_XXL];
367  |   char str_buffer_tmp[STR_L];
368  |   char *str;
369  | 
370  |   int l;
371  | 
372  |   strcpy(str_buffer, "");
373  | 
374  |   while ((row = mysql_fetch_row(result)) != NULL) {
375  |     if (row[column] != NULL) {
376  |       sprintf(str_buffer_tmp, "%s\n", row[column]);
377  |     }
378  |     strcat(str_buffer, str_buffer_tmp);
379  | 
380  |     if (strlen(str_buffer) >= (STR_XXL - STR_XL) ) {
381  |       strcat(str_buffer, "And some more stuff...\n");
382  |       break;
383  |     }
384  |   }
385  | 
386  |   if (strcmp(str_buffer, "") != 0) {
387  |     str = (char *)calloc(1, strlen(str_buffer)+1);
388  |     strcpy(str, str_buffer);
389  |   }
390  |   else {
391  |     str = NULL;
392  |   }
393  | 
394  |   return str;
395  | 
396  | } /* SQ_get_column_strings() */
397  | 
398  | /* SQ_get_column_int() */
399  | /*++++++++++++++++++++++++++++++++++++++
400  |   Get an integer from the column.
401  | 
402  |   SQ_result_set_t *result The results.
403  |   
404  |   SQ_row_t *current_row The current row.
405  | 
406  |   unsigned int column The column index.
407  | 
408  |   This uses atoi.  So it may be advisable not to use it.
409  | 
410  |   More:
411  |   +html+ <PRE>
412  |   Authors:
413  |         ottrey
414  |   +html+ </PRE><DL COMPACT>
415  |   +html+ <DT>Online References:
416  |   +html+ <DD><UL>
417  |   +html+ </UL></DL>
418  | 
419  |   ++++++++++++++++++++++++++++++++++++++*/
420  | int SQ_get_column_int(SQ_result_set_t *result, SQ_row_t *current_row, unsigned int column) {
421  |   int ret_val=-1;
422  | 
423  |   if (*current_row[column] != NULL) {
424  |     ret_val = atoi(*current_row[column]);
425  |   }
426  |   else {
427  |     ;
428  |   }
429  | 
430  |   return ret_val;
431  |   
432  | } /* SQ_get_column_int() */
433  | 
434  | 
435  | /* SQ_result_to_string() */
436  | /*++++++++++++++++++++++++++++++++++++++
437  |   Convert the result set to a string.
438  | 
439  |   SQ_result_set_t *result The results.
440  |   
441  |   More:
442  |   +html+ <PRE>
443  |   Authors:
444  |         ottrey
445  |   +html+ </PRE><DL COMPACT>
446  |   +html+ <DT>Online References:
447  |   +html+ <DD><UL>
448  |   +html+ </UL></DL>
449  | 
450  |   ++++++++++++++++++++++++++++++++++++++*/
451  | char *SQ_result_to_string(SQ_result_set_t *result) {
452  |   MYSQL_ROW row;
453  |   unsigned int no_cols;
454  |   unsigned int i, j;
455  |   char str_buffer[STR_XXL];
456  |   char str_buffer_tmp[STR_L];
457  |   char border[STR_L];
458  |   char *str;
459  | 
460  |   char *label;
461  | 
462  |   unsigned int length[STR_S];
463  |   int l;
464  | 
465  |   strcpy(str_buffer, "");
466  | 
467  |   no_cols = mysql_num_fields(result);
468  | 
469  |   /* Determine the maximum column widths */
470  |   /* XXX Surely MySQL should keep note of this for me! */
471  |   strcpy(border, "");
472  |   for (i=0; i < no_cols; i++) {
473  |     length[i] = SQ_get_column_max_length(result, i);
474  |     /* Make sure the lenghts don't get too long */
475  |     if (length[i] > STR_M) {
476  |       length[i] = STR_M;
477  |     }
478  |     strcat(border, "*");
479  |     for (j=0; (j <= length[i]) && (j < STR_L); j++) {
480  |       strcat(border, "-");
481  |     }
482  |   }
483  |   strcat(border, "*\n");
484  |   /*
485  |   for (i=0; i < no_cols; i++) {
486  |     printf("length[%d]=%d\n", i, length[i]);
487  |   }
488  |   */
489  | 
490  |   strcat(str_buffer, border);
491  | 
492  |   for (i=0; i < no_cols; i++) {
493  |     label = SQ_get_column_label(result, i);
494  |     if (label != NULL) {
495  |       sprintf(str_buffer_tmp, "| %-*s", length[i], label);
496  |       strcat(str_buffer, str_buffer_tmp);
497  |     }
498  |   }
499  |   strcat(str_buffer, "|\n");
500  |   
501  |   strcat(str_buffer, border);
502  | 
503  | 
504  |   while ((row = mysql_fetch_row(result)) != NULL) {
505  |     for (i=0; i < no_cols; i++) {
506  |       if (row[i] != NULL) {
507  |         sprintf(str_buffer_tmp, "| %-*s", length[i], row[i]);
508  |       }
509  |       else {
510  |         sprintf(str_buffer_tmp, "| %-*s", length[i], "NuLL");
511  |       }
512  |       strcat(str_buffer, str_buffer_tmp);
513  |     }
514  |     strcat(str_buffer, "|\n");
515  | 
516  |     if (strlen(str_buffer) >= (STR_XXL - STR_XL) ) {
517  |       strcat(str_buffer, "And some more stuff...\n");
518  |       break;
519  |     }
520  |   }
521  | 
522  |   strcat(str_buffer, border);
523  |   
524  |   str = (char *)calloc(1, strlen(str_buffer)+1);
525  |   strcpy(str, str_buffer);
526  | 
527  |   return str;
528  | 
529  | } /* SQ_result_to_string() */
530  | 
531  | /* SQ_free_result() */
532  | /*++++++++++++++++++++++++++++++++++++++
533  |   Free the result set.
534  | 
535  |   SQ_result_set_t *result The results.
536  |   
537  |   More:
538  |   +html+ <PRE>
539  |   Authors:
540  |         ottrey
541  |   +html+ </PRE><DL COMPACT>
542  |   +html+ <DT>Online References:
543  |   +html+ <DD><UL>
544  |   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_free_result">mysql_free_result()</A>
545  |   +html+ </UL></DL>
546  | 
547  |   ++++++++++++++++++++++++++++++++++++++*/
548  | void SQ_free_result(SQ_result_set_t *result) {
549  |   mysql_free_result(result);
550  | } /* SQ_free_result() */
551  | 
552  | 
553  | /* SQ_close_connection() */
554  | /*++++++++++++++++++++++++++++++++++++++
555  |   Call this function to close a connection to the server
556  | 
557  |   SQ_connection_t *sql_connection The connection to the database.
558  |   
559  |   More:
560  |   +html+ <PRE>
561  |   Authors:
562  |         ottrey
563  |   +html+ </PRE><DL COMPACT>
564  |   +html+ <DT>Online References:
565  |   +html+ <DD><UL>
566  |   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_close">mysql_close()</A>
567  |   +html+ </UL></DL>
568  | 
569  |   ++++++++++++++++++++++++++++++++++++++*/
570  | void SQ_close_connection(SQ_connection_t *sql_connection) {
571  | 
572  |   mysql_close(sql_connection);
573  | 
574  | }
575  | 
576  | /* SQ_get_column_string() */
577  | /*++++++++++++++++++++++++++++++++++++++
578  |   Call this function to find out how many rows are in a query result
579  | 
580  |   SQ_result_set_t *result The results.
581  |   
582  |   More:
583  |   +html+ <PRE>
584  |   Authors:
585  |         ottrey
586  |   +html+ </PRE><DL COMPACT>
587  |   +html+ <DT>Online References:
588  |   +html+ <DD><UL>
589  |   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_num_rows">mysql_num_rows()</A>
590  |   +html+ </UL></DL>
591  | 
592  |   ++++++++++++++++++++++++++++++++++++++*/
593  | int SQ_num_rows(SQ_result_set_t *result) {
594  | 
595  |   int rows;
596  | 
597  |   rows = mysql_num_rows(result);
598  | 
599  |   return rows;
600  | }
601  | 
602  | /* SQ_info_to_string() */
603  | /*++++++++++++++++++++++++++++++++++++++
604  |   Convert all available information about the sql server into a string.
605  | 
606  |   SQ_connection_t *sql_connection The connection to the database.
607  | 
608  |   More:
609  |   +html+ <PRE>
610  |   Authors:
611  |         ottrey
612  |   +html+ </PRE><DL COMPACT>
613  |   +html+ <DT>Online References:
614  |   +html+ <DD><UL>
615  |   +html+ </UL></DL>
616  | 
617  |   ++++++++++++++++++++++++++++++++++++++*/
618  | char *SQ_info_to_string(SQ_connection_t *sql_connection) {
619  |   char str_buffer[STR_XXL];
620  |   char str_buffer_tmp[STR_L];
621  |   char *str;
622  |   char *str_tmp;
623  | 
624  |   strcpy(str_buffer, "");
625  | 
626  |   /* Makes the server dump debug information to the log. */
627  |   sprintf(str_buffer_tmp, "mysql_dump_debug_info()=%d\n", mysql_dump_debug_info(sql_connection));
628  |   strcat(str_buffer, str_buffer_tmp);
629  | 
630  |   /* Returns the error number from the last MySQL function. */
631  |   sprintf(str_buffer_tmp, "mysql_errno()=%d\n", mysql_errno(sql_connection));
632  |   strcat(str_buffer, str_buffer_tmp);
633  | 
634  |   /* Returns the error message from the last MySQL function. */
635  |   sprintf(str_buffer_tmp, "mysql_error()=%s\n", mysql_error(sql_connection));
636  |   strcat(str_buffer, str_buffer_tmp);
637  | 
638  |   /* Returns client version information. */
639  |   sprintf(str_buffer_tmp, "mysql_get_client_info()=%s\n", mysql_get_client_info() );
640  |   strcat(str_buffer, str_buffer_tmp);
641  | 
642  |   /* Returns a string describing the connection. */
643  |   sprintf(str_buffer_tmp, "mysql_get_host_info()=%s\n", mysql_get_host_info(sql_connection));
644  |   strcat(str_buffer, str_buffer_tmp);
645  | 
646  |   /* Returns the protocol version used by the connection. */
647  |   sprintf(str_buffer_tmp, "mysql_get_proto_info()=%d\n", mysql_get_proto_info(sql_connection));
648  |   strcat(str_buffer, str_buffer_tmp);
649  | 
650  |   /* Returns the server version number. */
651  |   sprintf(str_buffer_tmp, "mysql_get_server_info()=%s\n", mysql_get_server_info(sql_connection));
652  |   strcat(str_buffer, str_buffer_tmp);
653  | 
654  |   /* Information about the most recently executed query. */
655  |   /* XXX Check for NULL */
656  |   str_tmp = mysql_info(sql_connection);
657  |   if (str_tmp != NULL) {
658  |     sprintf(str_buffer_tmp, "mysql_info()=%s\n", str_tmp);
659  |   }
660  |   else {
661  |     sprintf(str_buffer_tmp, "mysql_info()=%s\n", "NulL");
662  |   }
663  |   strcat(str_buffer, str_buffer_tmp);
664  | 
665  | 
666  |   /* Returns a list of the current server threads. */
667  |   sprintf(str_buffer_tmp, "mysql_list_processes()=%d\n", mysql_list_processes(sql_connection));
668  |   strcat(str_buffer, str_buffer_tmp);
669  | 
670  |   /* Checks if the connection to the server is working. */
671  |   sprintf(str_buffer_tmp, "mysql_ping()=%d\n", mysql_ping(sql_connection));
672  |   strcat(str_buffer, str_buffer_tmp);
673  | 
674  |   /* Returns the server status as a string. */
675  |   sprintf(str_buffer_tmp, "mysql_stat()=%s\n", mysql_stat(sql_connection));
676  |   strcat(str_buffer, str_buffer_tmp);
677  | 
678  |   /* Returns the current thread id. */
679  |   sprintf(str_buffer_tmp, "mysql_thread_id()=%d\n", mysql_thread_id(sql_connection));
680  |   strcat(str_buffer, str_buffer_tmp);
681  | 
682  | 
683  |   str = (char *)calloc(1, strlen(str_buffer)+1);
684  |   strcpy(str, str_buffer);
685  | 
686  |   return str;
687  | 
688  | } /* SQ_info_to_string() */
689  | 
690  | /* SQ_error() */
691  | /*++++++++++++++++++++++++++++++++++++++
692  |   Get the error string for the last error.
693  | 
694  |   SQ_connection_t *sql_connection The connection to the database.
695  | 
696  |   More:
697  |   +html+ <PRE>
698  |   Authors:
699  |         ottrey
700  |   +html+ </PRE><DL COMPACT>
701  |   +html+ <DT>Online References:
702  |   +html+ <DD><UL>
703  |   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_error">mysql_error()</A>
704  |   +html+ </UL></DL>
705  | 
706  |   ++++++++++++++++++++++++++++++++++++++*/
707  | char *SQ_error(SQ_connection_t *sql_connection) {
708  | 
709  |   return mysql_error(sql_connection);
710  | 
711  | } /* SQ_error() */
712  | 
713  | /* SQ_errno() */
714  | /*++++++++++++++++++++++++++++++++++++++
715  |   Get the error number for the last error.
716  | 
717  |   SQ_connection_t *sql_connection The connection to the database.
718  | 
719  |   More:
720  |   +html+ <PRE>
721  |   Authors:
722  |         ottrey
723  |   +html+ </PRE><DL COMPACT>
724  |   +html+ <DT>Online References:
725  |   +html+ <DD><UL>
726  |   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_free_result">mysql_free_result()</A>
727  |   +html+ </UL></DL>
728  | 
729  |   ++++++++++++++++++++++++++++++++++++++*/
730  | int SQ_errno(SQ_connection_t *sql_connection) {
731  | 
732  |   return mysql_errno(sql_connection);
733  | 
734  | } /* SQ_errno() */
735  |