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] */