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