## modules/sq/mysql_driver.c

/* [<][>][^][v][top][bottom][index][help] */

## FUNCTIONS

This source file includes following functions.

1. log_query
2. SQ_get_connection
3. SQ_get_connection2
4. SQ_execute_query
5. SQ_get_column_count
6. SQ_get_table_size
7. SQ_get_affected_rows
8. SQ_get_column_label
9. SQ_get_column_max_length
10. SQ_row_next
11. SQ_get_column_string
12. SQ_get_column_string_nocopy
13. SQ_get_column_strings
14. SQ_get_column_int
15. SQ_result_to_string
16. SQ_free_result
17. SQ_close_connection
18. SQ_num_rows
19. SQ_info_to_string
20. SQ_error
21. SQ_errno
22. SQ_get_info

       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,
         /* [<][>][^][v][top][bottom][index][help] */
      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) {
         /* [<][>][^][v][top][bottom][index][help] */
     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) {
         /* [<][>][^][v][top][bottom][index][help] */
     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,
         /* [<][>][^][v][top][bottom][index][help] */
     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) {
         /* [<][>][^][v][top][bottom][index][help] */
     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,
         /* [<][>][^][v][top][bottom][index][help] */
     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)
         /* [<][>][^][v][top][bottom][index][help] */
     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) {
         /* [<][>][^][v][top][bottom][index][help] */
     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) {
         /* [<][>][^][v][top][bottom][index][help] */
     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) {
         /* [<][>][^][v][top][bottom][index][help] */
     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) {
         /* [<][>][^][v][top][bottom][index][help] */
     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,
         /* [<][>][^][v][top][bottom][index][help] */
     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) {
         /* [<][>][^][v][top][bottom][index][help] */
     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) {
         /* [<][>][^][v][top][bottom][index][help] */
     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) {
         /* [<][>][^][v][top][bottom][index][help] */
     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) {
         /* [<][>][^][v][top][bottom][index][help] */
     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) {
         /* [<][>][^][v][top][bottom][index][help] */
     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) {
         /* [<][>][^][v][top][bottom][index][help] */
     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) {
         /* [<][>][^][v][top][bottom][index][help] */
     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) {
         /* [<][>][^][v][top][bottom][index][help] */
     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) {
         /* [<][>][^][v][top][bottom][index][help] */
     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])
         /* [<][>][^][v][top][bottom][index][help] */
     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 }

/* [<][>][^][v][top][bottom][index][help] */