1    | /***************************************
2    |   $Revision: 1.15 $
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.... %s\n", db);
126  |     /* XXX Don't be so harsh!
127  |     exit(-1);
128  |     */
129  |   }
130  | 
131  |   return sql_connection;
132  | 
133  | } /* SQ_get_connection() */
134  | 
135  | SQ_connection_t *SQ_get_connection2(void) {
136  |   return SQ_get_connection(CO_get_host(),
137  |                            CO_get_database_port(),
138  |                            CO_get_database(),
139  |                            CO_get_user(),
140  |                            CO_get_password()
141  |                           );
142  | } /* SQ_get_connection() */
143  | 
144  | /* SQ_execute_query() */
145  | /*++++++++++++++++++++++++++++++++++++++
146  |   Execute the sql query.
147  | 
148  |   SQ_connection_t *sql_connection Connection to database.
149  |   
150  |   const char *query SQL query.
151  |   
152  |   More:
153  |   +html+ <PRE>
154  |   Authors:
155  |         ottrey
156  |   +html+ </PRE><DL COMPACT>
157  |   +html+ <DT>Online References:
158  |   +html+ <DD><UL>
159  |   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_query">mysql_query()</A>
160  |   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_use_result">mysql_use_result()</A>
161  |   +html+ </UL></DL>
162  | 
163  |   ++++++++++++++++++++++++++++++++++++++*/
164  | SQ_result_set_t *SQ_execute_query(int store_or_not,
165  | 				  SQ_connection_t *sql_connection, 
166  | 				  const char *query) {
167  |   struct timeb *start_time;
168  |   struct timeb *stop_time;
169  |   int err;
170  |   SQ_result_set_t *result;
171  | 
172  |   if (CO_get_query_logging() == 1) {
173  |     start_time=(struct timeb *)calloc(1, sizeof(struct timeb)+1);
174  |     stop_time=(struct timeb *)calloc(1, sizeof(struct timeb)+1);
175  | 
176  |     ftime(start_time);
177  |     err = mysql_query(sql_connection, query);
178  |     ftime(stop_time);
179  | 
180  |     log_query(CO_get_query_logfile(), query, start_time, stop_time);
181  |     
182  |     free(start_time);
183  |     free(stop_time);
184  |   }
185  |   else {
186  |     err = mysql_query(sql_connection, query);
187  |   }
188  | 
189  |   if (err == 0) {
190  |     result = mysql_store_result(sql_connection);
191  |     if(store_or_not == SQ_NOSTORE) {
192  |       mysql_free_result(result);
193  |       result = NULL;
194  |     }
195  |   }
196  |   else {
197  |     result = NULL;
198  |   }
199  | 
200  |   return result;
201  | 
202  | } /* SQ_execute_query() */
203  | 
204  | /* SQ_get_column_count() */
205  | /*++++++++++++++++++++++++++++++++++++++
206  |   Get the column count.
207  | 
208  |   SQ_result_set_t *result The results from the query.
209  |   
210  |   More:
211  |   +html+ <PRE>
212  |   Authors:
213  |         ottrey
214  |   +html+ </PRE><DL COMPACT>
215  |   +html+ <DT>Online References:
216  |   +html+ <DD><UL>
217  |   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_num_fields">mysql_num_fields()</A>
218  |   +html+ </UL></DL>
219  | 
220  |   ++++++++++++++++++++++++++++++++++++++*/
221  | int SQ_get_column_count(SQ_result_set_t *result) {
222  |   int cols;
223  | 
224  |   cols = mysql_num_fields(result);
225  | 
226  |   return cols;
227  | 
228  | } /* SQ_get_column_count() */
229  | 
230  | /* SQ_get_column_label() */
231  | /*++++++++++++++++++++++++++++++++++++++
232  |   Get the column label.
233  | 
234  |   SQ_result_set_t *result The results from the query.
235  |   
236  |   unsigned int column The column index.
237  | 
238  |   More:
239  |   +html+ <PRE>
240  |   Authors:
241  |         ottrey
242  |   +html+ </PRE><DL COMPACT>
243  |   +html+ <DT>Online References:
244  |   +html+ <DD><UL>
245  |   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_fetch_field_direct">mysql_fetch_field_direct()</A>
246  |   +html+ </UL></DL>
247  | 
248  |   ++++++++++++++++++++++++++++++++++++++*/
249  | char *SQ_get_column_label(SQ_result_set_t *result, unsigned int column) {
250  |   char *str;
251  | /* MySQL decided to change their interface.  Doh! */
252  | #ifdef OLDMYSQL
253  |   MYSQL_FIELD field;
254  | 
255  |   field = mysql_fetch_field_direct(result, column);
256  | 
257  |   str = (char *)calloc(1, strlen(field.name)+1);
258  |   strcpy(str, field.name);
259  | #else
260  |   MYSQL_FIELD *field;
261  | 
262  |   field = mysql_fetch_field_direct(result, column);
263  | 
264  |   str = (char *)calloc(1, strlen(field->name)+1);
265  |   strcpy(str, field->name);
266  | #endif
267  | 
268  | /*
269  |   printf("column=%d\n", column);
270  |   printf("field.name=%s\n", field.name);
271  |   printf("field.table=%s\n", field.table);
272  | 
273  |   printf("field.def=%s\n", field.def);
274  | 
275  |   printf("field.type=%d\n", field.type);
276  |   printf("field.length=%d\n", field.length);
277  |   printf("field.max_length=%d\n", field.max_length);
278  |   printf("field.flags=%d\n", field.flags);
279  |   printf("field.decimals=%d\n", field.decimals);
280  | */
281  | 
282  |   return str;
283  | 
284  | } /* SQ_get_column_label() */
285  | 
286  | /* SQ_get_column_max_length() */
287  | /*++++++++++++++++++++++++++++++++++++++
288  |   Get the max length of the column.
289  | 
290  |   SQ_result_set_t *result The results from the query.
291  |   
292  |   unsigned int column The column index.
293  | 
294  |   More:
295  |   +html+ <PRE>
296  |   Authors:
297  |         ottrey
298  |   +html+ </PRE><DL COMPACT>
299  |   +html+ <DT>Online References:
300  |   +html+ <DD><UL>
301  |   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_fetch_field_direct">mysql_fetch_field_direct()</A>
302  |   +html+ </UL></DL>
303  | 
304  |   ++++++++++++++++++++++++++++++++++++++*/
305  | unsigned int SQ_get_column_max_length(SQ_result_set_t *result, unsigned int column) {
306  | /* MySQL decided to change their interface.  Doh! */
307  | #ifdef OLDMYSQL
308  |   MYSQL_FIELD field;
309  | 
310  |   field = mysql_fetch_field_direct(result, column);
311  | 
312  |   return field.length;
313  | #else
314  |   MYSQL_FIELD *field;
315  | 
316  |   field = mysql_fetch_field_direct(result, column);
317  | 
318  |   return field->length;
319  | #endif
320  | 
321  | } /* SQ_get_column_max_length() */
322  | 
323  | /* SQ_row_next() */
324  | /*++++++++++++++++++++++++++++++++++++++
325  |   Get the next row.
326  | 
327  |   SQ_result_set_t *result The results from the query.
328  |   
329  |   unsigned int column The column index.
330  | 
331  |   More:
332  |   +html+ <PRE>
333  |   Authors:
334  |         ottrey
335  |   +html+ </PRE><DL COMPACT>
336  |   +html+ <DT>Online References:
337  |   +html+ <DD><UL>
338  |   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_fetch_row">mysql_fetch_row()</A>
339  |   +html+ </UL></DL>
340  | 
341  |   ++++++++++++++++++++++++++++++++++++++*/
342  | SQ_row_t *SQ_row_next(SQ_result_set_t *result) {
343  | 
344  |   return (SQ_row_t *)mysql_fetch_row(result);
345  | 
346  | } /* SQ_row_next() */
347  | 
348  | /* SQ_get_column_string() */
349  | /*++++++++++++++++++++++++++++++++++++++
350  |   Get the column string.
351  | 
352  |   SQ_row_t *current_row The current row (obtained from a SQ_row_next() ).
353  |   
354  |   unsigned int column The column index.
355  | 
356  |   More:
357  |   +html+ <PRE>
358  |   Authors:
359  |         ottrey
360  |   +html+ </PRE><DL COMPACT>
361  |   +html+ <DT>Online References:
362  |   +html+ <DD><UL>
363  |   +html+ </UL></DL>
364  | 
365  |   ++++++++++++++++++++++++++++++++++++++*/
366  | char *SQ_get_column_string(SQ_result_set_t *result, SQ_row_t *current_row, unsigned int column) {
367  |   char *str=NULL;
368  |   int length = mysql_fetch_lengths(result)[column];
369  | 
370  | 
371  |   if (current_row != NULL && current_row[column] != NULL) {
372  |     str = (char *)malloc(length + 1);
373  |     if (str != NULL) {
374  |       memcpy(str, current_row[column], length );
375  |       str[length] = '\0';
376  |     }
377  |   }
378  | 
379  |   return str;
380  |   
381  | } /* SQ_get_column_string() */
382  | 
383  | /* SQ_get_column_strings() */
384  | /*++++++++++++++++++++++++++++++++++++++
385  |   Get the all the strings in one column.
386  | 
387  |   SQ_result_set_t *result The results.
388  |   
389  |   unsigned int column The column index.
390  | 
391  |   More:
392  |   +html+ <PRE>
393  |   Authors:
394  |         ottrey
395  |   +html+ </PRE><DL COMPACT>
396  |   +html+ <DT>Online References:
397  |   +html+ <DD><UL>
398  |   +html+ </UL></DL>
399  | 
400  |   ++++++++++++++++++++++++++++++++++++++*/
401  | char *SQ_get_column_strings(SQ_result_set_t *result, unsigned int column) {
402  |   MYSQL_ROW row;
403  |   char str_buffer[STR_XXL];
404  |   char str_buffer_tmp[STR_L];
405  |   char *str;
406  | 
407  |   int l;
408  | 
409  |   strcpy(str_buffer, "");
410  | 
411  |   while ((row = mysql_fetch_row(result)) != NULL) {
412  |     if (row[column] != NULL) {
413  |       sprintf(str_buffer_tmp, "%s\n", row[column]);
414  |     }
415  |     strcat(str_buffer, str_buffer_tmp);
416  | 
417  |     if (strlen(str_buffer) >= (STR_XXL - STR_XL) ) {
418  |       strcat(str_buffer, "And some more stuff...\n");
419  |       break;
420  |     }
421  |   }
422  | 
423  |   if (strcmp(str_buffer, "") != 0) {
424  |     str = (char *)calloc(1, strlen(str_buffer)+1);
425  |     strcpy(str, str_buffer);
426  |   }
427  |   else {
428  |     str = NULL;
429  |   }
430  | 
431  |   return str;
432  | 
433  | } /* SQ_get_column_strings() */
434  | 
435  | /* SQ_get_column_int() */
436  | /*++++++++++++++++++++++++++++++++++++++
437  |   Get an integer from the column.
438  | 
439  |   SQ_result_set_t *result The results.
440  |   
441  |   SQ_row_t *current_row The current row.
442  | 
443  |   unsigned int column The column index.
444  | 
445  |   This uses atoi.  So it may be advisable not to use it.
446  | 
447  |   More:
448  |   +html+ <PRE>
449  |   Authors:
450  |         ottrey
451  |   +html+ </PRE><DL COMPACT>
452  |   +html+ <DT>Online References:
453  |   +html+ <DD><UL>
454  |   +html+ </UL></DL>
455  | 
456  |   ++++++++++++++++++++++++++++++++++++++*/
457  | int SQ_get_column_int(SQ_result_set_t *result, SQ_row_t *current_row, unsigned int column) {
458  |   int ret_val=-1;
459  | 
460  |   if (*current_row[column] != NULL) {
461  |     ret_val = atoi(*current_row[column]);
462  |   }
463  |   else {
464  |     ;
465  |   }
466  | 
467  |   return ret_val;
468  |   
469  | } /* SQ_get_column_int() */
470  | 
471  | 
472  | /* SQ_result_to_string() */
473  | /*++++++++++++++++++++++++++++++++++++++
474  |   Convert the result set to a string.
475  | 
476  |   SQ_result_set_t *result The results.
477  |   
478  |   More:
479  |   +html+ <PRE>
480  |   Authors:
481  |         ottrey
482  |   +html+ </PRE><DL COMPACT>
483  |   +html+ <DT>Online References:
484  |   +html+ <DD><UL>
485  |   +html+ </UL></DL>
486  | 
487  |   ++++++++++++++++++++++++++++++++++++++*/
488  | char *SQ_result_to_string(SQ_result_set_t *result) {
489  |   MYSQL_ROW row;
490  |   unsigned int no_cols;
491  |   unsigned int i, j;
492  |   char str_buffer[STR_XXL];
493  |   char str_buffer_tmp[STR_L];
494  |   char border[STR_L];
495  |   char *str;
496  | 
497  |   char *label;
498  | 
499  |   unsigned int length[STR_S];
500  |   int l;
501  | 
502  |   strcpy(str_buffer, "");
503  | 
504  |   no_cols = mysql_num_fields(result);
505  | 
506  |   /* Determine the maximum column widths */
507  |   /* XXX Surely MySQL should keep note of this for me! */
508  |   strcpy(border, "");
509  |   for (i=0; i < no_cols; i++) {
510  |     length[i] = SQ_get_column_max_length(result, i);
511  |     /* Make sure the lenghts don't get too long */
512  |     if (length[i] > STR_M) {
513  |       length[i] = STR_M;
514  |     }
515  |     strcat(border, "*");
516  |     for (j=0; (j <= length[i]) && (j < STR_L); j++) {
517  |       strcat(border, "-");
518  |     }
519  |   }
520  |   strcat(border, "*\n");
521  |   /*
522  |   for (i=0; i < no_cols; i++) {
523  |     printf("length[%d]=%d\n", i, length[i]);
524  |   }
525  |   */
526  | 
527  |   strcat(str_buffer, border);
528  | 
529  |   for (i=0; i < no_cols; i++) {
530  |     label = SQ_get_column_label(result, i);
531  |     if (label != NULL) {
532  |       sprintf(str_buffer_tmp, "| %-*s", length[i], label);
533  |       strcat(str_buffer, str_buffer_tmp);
534  |     }
535  |   }
536  |   strcat(str_buffer, "|\n");
537  |   
538  |   strcat(str_buffer, border);
539  | 
540  | 
541  |   while ((row = mysql_fetch_row(result)) != NULL) {
542  |     for (i=0; i < no_cols; i++) {
543  |       if (row[i] != NULL) {
544  |         sprintf(str_buffer_tmp, "| %-*s", length[i], row[i]);
545  |       }
546  |       else {
547  |         sprintf(str_buffer_tmp, "| %-*s", length[i], "NuLL");
548  |       }
549  |       strcat(str_buffer, str_buffer_tmp);
550  |     }
551  |     strcat(str_buffer, "|\n");
552  | 
553  |     if (strlen(str_buffer) >= (STR_XXL - STR_XL) ) {
554  |       strcat(str_buffer, "And some more stuff...\n");
555  |       break;
556  |     }
557  |   }
558  | 
559  |   strcat(str_buffer, border);
560  |   
561  |   str = (char *)calloc(1, strlen(str_buffer)+1);
562  |   strcpy(str, str_buffer);
563  | 
564  |   return str;
565  | 
566  | } /* SQ_result_to_string() */
567  | 
568  | /* SQ_free_result() */
569  | /*++++++++++++++++++++++++++++++++++++++
570  |   Free the result set.
571  | 
572  |   SQ_result_set_t *result The results.
573  |   
574  |   More:
575  |   +html+ <PRE>
576  |   Authors:
577  |         ottrey
578  |   +html+ </PRE><DL COMPACT>
579  |   +html+ <DT>Online References:
580  |   +html+ <DD><UL>
581  |   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_free_result">mysql_free_result()</A>
582  |   +html+ </UL></DL>
583  | 
584  |   ++++++++++++++++++++++++++++++++++++++*/
585  | void SQ_free_result(SQ_result_set_t *result) {
586  |   mysql_free_result(result);
587  | } /* SQ_free_result() */
588  | 
589  | 
590  | /* SQ_close_connection() */
591  | /*++++++++++++++++++++++++++++++++++++++
592  |   Call this function to close a connection to the server
593  | 
594  |   SQ_connection_t *sql_connection The connection to the database.
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+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_close">mysql_close()</A>
604  |   +html+ </UL></DL>
605  | 
606  |   ++++++++++++++++++++++++++++++++++++++*/
607  | void SQ_close_connection(SQ_connection_t *sql_connection) {
608  | 
609  |   mysql_close(sql_connection);
610  | 
611  | }
612  | 
613  | /* SQ_num_rows() */
614  | /*++++++++++++++++++++++++++++++++++++++
615  |   Call this function to find out how many rows are in a query result
616  | 
617  |   SQ_result_set_t *result The results.
618  |   
619  |   More:
620  |   +html+ <PRE>
621  |   Authors:
622  |         ottrey
623  |   +html+ </PRE><DL COMPACT>
624  |   +html+ <DT>Online References:
625  |   +html+ <DD><UL>
626  |   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_num_rows">mysql_num_rows()</A>
627  |   +html+ </UL></DL>
628  | 
629  |   ++++++++++++++++++++++++++++++++++++++*/
630  | int SQ_num_rows(SQ_result_set_t *result) {
631  |   int rows=-1;
632  | 
633  |   if (result != NULL) {
634  |     rows = mysql_num_rows(result);
635  |   }
636  | 
637  |   return rows;
638  | }
639  | 
640  | /* SQ_info_to_string() */
641  | /*++++++++++++++++++++++++++++++++++++++
642  |   Convert all available information about the sql server into a string.
643  | 
644  |   SQ_connection_t *sql_connection The connection to the database.
645  | 
646  |   More:
647  |   +html+ <PRE>
648  |   Authors:
649  |         ottrey
650  |   +html+ </PRE><DL COMPACT>
651  |   +html+ <DT>Online References:
652  |   +html+ <DD><UL>
653  |   +html+ </UL></DL>
654  | 
655  |   ++++++++++++++++++++++++++++++++++++++*/
656  | char *SQ_info_to_string(SQ_connection_t *sql_connection) {
657  |   char str_buffer[STR_XXL];
658  |   char str_buffer_tmp[STR_L];
659  |   char *str;
660  |   char *str_tmp;
661  | 
662  |   strcpy(str_buffer, "");
663  | 
664  |   /* Makes the server dump debug information to the log. */
665  |   sprintf(str_buffer_tmp, "mysql_dump_debug_info()=%d\n", mysql_dump_debug_info(sql_connection));
666  |   strcat(str_buffer, str_buffer_tmp);
667  | 
668  |   /* Returns the error number from the last MySQL function. */
669  |   sprintf(str_buffer_tmp, "mysql_errno()=%d\n", mysql_errno(sql_connection));
670  |   strcat(str_buffer, str_buffer_tmp);
671  | 
672  |   /* Returns the error message from the last MySQL function. */
673  |   sprintf(str_buffer_tmp, "mysql_error()=%s\n", mysql_error(sql_connection));
674  |   strcat(str_buffer, str_buffer_tmp);
675  | 
676  |   /* Returns client version information. */
677  |   sprintf(str_buffer_tmp, "mysql_get_client_info()=%s\n", mysql_get_client_info() );
678  |   strcat(str_buffer, str_buffer_tmp);
679  | 
680  |   /* Returns a string describing the connection. */
681  |   sprintf(str_buffer_tmp, "mysql_get_host_info()=%s\n", mysql_get_host_info(sql_connection));
682  |   strcat(str_buffer, str_buffer_tmp);
683  | 
684  |   /* Returns the protocol version used by the connection. */
685  |   sprintf(str_buffer_tmp, "mysql_get_proto_info()=%d\n", mysql_get_proto_info(sql_connection));
686  |   strcat(str_buffer, str_buffer_tmp);
687  | 
688  |   /* Returns the server version number. */
689  |   sprintf(str_buffer_tmp, "mysql_get_server_info()=%s\n", mysql_get_server_info(sql_connection));
690  |   strcat(str_buffer, str_buffer_tmp);
691  | 
692  |   /* Information about the most recently executed query. */
693  |   /* XXX Check for NULL */
694  |   str_tmp = mysql_info(sql_connection);
695  |   if (str_tmp != NULL) {
696  |     sprintf(str_buffer_tmp, "mysql_info()=%s\n", str_tmp);
697  |   }
698  |   else {
699  |     sprintf(str_buffer_tmp, "mysql_info()=%s\n", "NulL");
700  |   }
701  |   strcat(str_buffer, str_buffer_tmp);
702  | 
703  | 
704  |   /* Returns a list of the current server threads. */
705  |   sprintf(str_buffer_tmp, "mysql_list_processes()=%d\n", mysql_list_processes(sql_connection));
706  |   strcat(str_buffer, str_buffer_tmp);
707  | 
708  |   /* Checks if the connection to the server is working. */
709  |   sprintf(str_buffer_tmp, "mysql_ping()=%d\n", mysql_ping(sql_connection));
710  |   strcat(str_buffer, str_buffer_tmp);
711  | 
712  |   /* Returns the server status as a string. */
713  |   sprintf(str_buffer_tmp, "mysql_stat()=%s\n", mysql_stat(sql_connection));
714  |   strcat(str_buffer, str_buffer_tmp);
715  | 
716  |   /* Returns the current thread id. */
717  |   sprintf(str_buffer_tmp, "mysql_thread_id()=%d\n", mysql_thread_id(sql_connection));
718  |   strcat(str_buffer, str_buffer_tmp);
719  | 
720  | 
721  |   str = (char *)calloc(1, strlen(str_buffer)+1);
722  |   strcpy(str, str_buffer);
723  | 
724  |   return str;
725  | 
726  | } /* SQ_info_to_string() */
727  | 
728  | /* SQ_error() */
729  | /*++++++++++++++++++++++++++++++++++++++
730  |   Get the error string for the last error.
731  | 
732  |   SQ_connection_t *sql_connection The connection to the database.
733  | 
734  |   More:
735  |   +html+ <PRE>
736  |   Authors:
737  |         ottrey
738  |   +html+ </PRE><DL COMPACT>
739  |   +html+ <DT>Online References:
740  |   +html+ <DD><UL>
741  |   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_error">mysql_error()</A>
742  |   +html+ </UL></DL>
743  | 
744  |   ++++++++++++++++++++++++++++++++++++++*/
745  | char *SQ_error(SQ_connection_t *sql_connection) {
746  | 
747  |   return mysql_error(sql_connection);
748  | 
749  | } /* SQ_error() */
750  | 
751  | /* SQ_errno() */
752  | /*++++++++++++++++++++++++++++++++++++++
753  |   Get the error number for the last error.
754  | 
755  |   SQ_connection_t *sql_connection The connection to the database.
756  | 
757  |   More:
758  |   +html+ <PRE>
759  |   Authors:
760  |         ottrey
761  |   +html+ </PRE><DL COMPACT>
762  |   +html+ <DT>Online References:
763  |   +html+ <DD><UL>
764  |   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_free_result">mysql_free_result()</A>
765  |   +html+ </UL></DL>
766  | 
767  |   ++++++++++++++++++++++++++++++++++++++*/
768  | int SQ_errno(SQ_connection_t *sql_connection) {
769  | 
770  |   return mysql_errno(sql_connection);
771  | 
772  | } /* SQ_errno() */
773  |