modules/sq/mysql_driver.c

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

FUNCTIONS

This source file includes following functions.
  1. SQ_try_connection
  2. SQ_get_connection
  3. SQ_execute_query
  4. SQ_execute_query_nostore
  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
  23. SQ_duplicate_connection
  24. SQ_abort_query

   1 /***************************************
   2   $Revision: 1.32 $
   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 #include "timediff.h"
  42 
  43 /*+ String sizes +*/
  44 #define STR_S   63
  45 #define STR_M   255
  46 #define STR_L   1023
  47 #define STR_XL  4095
  48 #define STR_XXL 16383
  49 
  50 /* 
  51 Description:
  52 
  53   Connect to the the MySQL database, returning an error if unsuccessful.
  54 
  55 Arguments:
  56 
  57   SQ_connection_t **conn; used to return pointer to connection structure
  58 
  59   const char *host; database server host to connect to, may be NULL or 
  60     "localhost", in which case Unix sockets may be used
  61 
  62   unsigned int port; port to connect to database server on, may be 0 to use  
  63     default
  64 
  65   const char *db; name of database to use, may be NULL
  66 
  67   const char *user; name of user to connect as, if NULL then the current Unix 
  68     user login is used
  69 
  70   const char *password; password to send, may be NULL to not use a password
  71 
  72 Returns:
  73   
  74   SQ_OK on success
  75 
  76   SQ_CTCONN on error; the exact reason may be determined by using SQ_error() 
  77     on the value returned in *conn - this structure should be properly via
  78     SQ_close_connection(), even on error
  79 
  80 Notes:
  81 
  82   Most parameters are passed straight through to the MySQL connect function,
  83   so the MySQL documentation should be checked for current meaning.
  84 */
  85 
  86 er_ret_t 
  87 SQ_try_connection (SQ_connection_t **conn, const char *host,
     /* [<][>][^][v][top][bottom][index][help] */
  88                    unsigned int port, const char *db,
  89                    const char *user, const char *password)
  90 {
  91     SQ_connection_t *res;
  92     
  93     *conn = mysql_init(NULL);
  94     dieif(*conn == NULL);  /* XXX SK - need to call "out of memory handler" */
  95 
  96     res = mysql_real_connect(*conn, host, user, password, db, port, NULL, 0);
  97     if (res == NULL) {
  98         return SQ_CTCONN;
  99     } else {
 100         return SQ_OK;
 101     }
 102 }
 103 
 104 /* SQ_get_connection() */
 105 /*++++++++++++++++++++++++++++++++++++++
 106   Get a connection to the database.
 107 
 108   const char *host
 109   
 110   unsigned int port
 111 
 112   const char *db
 113   
 114   const char *user
 115   
 116   const char *password
 117    
 118   More:
 119   +html+ <PRE>
 120   Authors:
 121         ottrey
 122   +html+ </PRE><DL COMPACT>
 123   +html+ <DT>Online References:
 124   +html+ <DD><UL>
 125   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_init">mysql_init()</A>
 126   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_real_connect">mysql_real_connect()</A>
 127   +html+ </UL></DL>
 128 
 129   ++++++++++++++++++++++++++++++++++++++*/
 130 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] */
 131 
 132   SQ_connection_t *sql_connection;
 133   er_ret_t res;
 134   int try;
 135 
 136   /* XXX MB.
 137      This is really kludgy! 
 138      For some (unknown yet) reason, sometimes the connection does not
 139      work the first time. So we try up to 3 times here, and give up only
 140      then.
 141 
 142      Check the logfiles for warnings, especially with newer mysql version,
 143      like 3.23. The problem may or may not go away.
 144 
 145      SK - I added a sleep() to avoid crushing the poor server.
 146   */
 147 
 148   try=0;
 149   for (;;) {
 150     /* try to connect */
 151     res = SQ_try_connection(&sql_connection, host, port, db, user, password);
 152 
 153     /* on success, return our result */
 154     if (NOERR(res)) {
 155         return sql_connection;
 156     }
 157 
 158     /* if we've tried enough, exit with error */
 159     if (try >= 3) {
 160         ER_perror(FAC_SQ, SQ_CTCONN, " %s; %s", db, SQ_error(sql_connection));
 161         die;
 162     }
 163 
 164     /* otherwise, prepare to try again */
 165     SQ_close_connection(sql_connection);
 166     ER_perror(FAC_SQ, SQ_CNCT, " %s; %s", db, SQ_error(sql_connection));
 167     if (try > 0) {
 168         sleep(try);
 169     }
 170     try++;
 171   }
 172 
 173 } /* SQ_get_connection() */
 174 
 175 /* SQ_execute_query() */
 176 /*++++++++++++++++++++++++++++++++++++++
 177   Execute the sql query.
 178 
 179   SQ_connection_t *sql_connection Connection to database.
 180   
 181   const char *query SQL query.
 182 
 183   SQ_result_set_t *result ptr to the structure to hold result. 
 184   May be NULL if no result is needed.
 185 
 186   Returns: 
 187     0 if the query was successful.
 188     Non-zero if an error occured.
 189   
 190   More:
 191   +html+ <PRE>
 192   Authors:
 193         ottrey, andrei, marek
 194   +html+ </PRE><DL COMPACT>
 195   +html+ <DT>Online References:
 196   +html+ <DD><UL>
 197   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_query">mysql_query()</A>
 198   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_use_result">mysql_use_result()</A>
 199   +html+ </UL></DL>
 200 
 201   ++++++++++++++++++++++++++++++++++++++*/
 202 int SQ_execute_query(SQ_connection_t *sql_connection, 
     /* [<][>][^][v][top][bottom][index][help] */
 203                      const char *query, SQ_result_set_t **result_ptr) 
 204 {
 205   int err;
 206   SQ_result_set_t *result;
 207 
 208   ut_timer_t start_time, stop_time; 
 209   
 210   UT_timeget(&start_time);
 211   
 212   err = mysql_query(sql_connection, query);
 213 
 214   /* log the time and result of the query */
 215   if (err == 0) {
 216     result = mysql_store_result(sql_connection);
 217     
 218     if (ER_is_traced(FAC_SQ, ASP_SQ_QRYTIME)) {
 219       float seconds;
 220 
 221       UT_timeget(&stop_time);      
 222       seconds = UT_timediff( &start_time, &stop_time );
 223   
 224       ER_dbg_va(FAC_SQ, ASP_SQ_QRYTIME,
 225                 "spent %.2f sec; got %d rows from [%s: %s]", 
 226                 seconds, 
 227                 SQ_get_affected_rows(sql_connection),
 228                 sql_connection->db, 
 229                 query);
 230     }
 231     
 232     if(result_ptr) *result_ptr=result;
 233     else if(result) mysql_free_result(result);
 234     return(0);
 235   }
 236   else return(-1);  
 237   
 238 } /* SQ_execute_query() */
 239 
 240 /* 
 241 Description:
 242  
 243     Performs identially to SQ_execute_query(), except that it does not read the
 244     entire query into memory.
 245 
 246 Notes:
 247 
 248     No data may be written to the table until the entire result set is read,
 249     so this should only be used in cases where:
 250 
 251     1. an unacceptably large amount of memory will be returned by the query
 252     2. there is no chance that a user can accidentally or maliciously 
 253        prevent the result set from being read in a expedicious manner
 254 */
 255 
 256 int 
 257 SQ_execute_query_nostore(SQ_connection_t *sql_connection, 
     /* [<][>][^][v][top][bottom][index][help] */
 258                          const char *query, SQ_result_set_t **result_ptr) 
 259 {
 260   int err;
 261   SQ_result_set_t *result;
 262 
 263   err = mysql_query(sql_connection, query);
 264   if (err != 0) {
 265       return -1;
 266   }
 267   result = mysql_use_result(sql_connection);
 268   if (result == NULL) {
 269       return -1;
 270   } 
 271   *result_ptr = result;
 272   return 0;
 273 } /* SQ_execute_query_nostore() */
 274 
 275 /* SQ_get_column_count() */
 276 /*++++++++++++++++++++++++++++++++++++++
 277   Get the column count.
 278 
 279   SQ_result_set_t *result The results from the query.
 280   
 281   More:
 282   +html+ <PRE>
 283   Authors:
 284         ottrey
 285   +html+ </PRE><DL COMPACT>
 286   +html+ <DT>Online References:
 287   +html+ <DD><UL>
 288   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_num_fields">mysql_num_fields()</A>
 289   +html+ </UL></DL>
 290 
 291   ++++++++++++++++++++++++++++++++++++++*/
 292 int SQ_get_column_count(SQ_result_set_t *result) {
     /* [<][>][^][v][top][bottom][index][help] */
 293   int cols;
 294 
 295   cols = mysql_num_fields(result);
 296 
 297   return cols;
 298 
 299 } /* SQ_get_column_count() */
 300 
 301 /* SQ_get_table_size() */
 302 /*++++++++++++++++++++++++++++++++++++++
 303   Get the row count of a table
 304 
 305   char *table   The table to be examined
 306   
 307   More:
 308   +html+ <PRE>
 309   Authors:
 310         marek
 311   +html+ </PRE>
 312 
 313   ++++++++++++++++++++++++++++++++++++++*/
 314 int SQ_get_table_size(SQ_connection_t *sql_connection,
     /* [<][>][^][v][top][bottom][index][help] */
 315                      char *table) {  
 316   int count;
 317   char sql_command[128];
 318   SQ_result_set_t *result;
 319   SQ_row_t *row;
 320   char *countstr;
 321   
 322   sprintf(sql_command, "SELECT COUNT(*) FROM %s", table);
 323   dieif(SQ_execute_query(sql_connection, sql_command, &result) == -1 );
 324   row = SQ_row_next(result);
 325   
 326   countstr = SQ_get_column_string(result, row, 0);
 327   sscanf(countstr, "%d", &count);       
 328   wr_free(countstr);
 329   
 330   SQ_free_result(result);
 331         
 332   return count;  
 333 } /* SQ_get_table_size() */
 334 
 335 /* SQ_get_affected_rows() */
 336 /*++++++++++++++++++++++++++++++++++++++
 337   Get the row count of a table
 338 
 339   char *table   The table to be examined
 340   
 341   More:
 342   +html+ <PRE>
 343   Authors:
 344         marek
 345   +html+ </PRE>
 346 
 347   ++++++++++++++++++++++++++++++++++++++*/
 348 int SQ_get_affected_rows(SQ_connection_t *sql_connection)
     /* [<][>][^][v][top][bottom][index][help] */
 349 {
 350   return mysql_affected_rows(sql_connection);
 351 }/* SQ_get_affected_rows() */
 352                       
 353 
 354 /* SQ_get_column_label() */
 355 /*++++++++++++++++++++++++++++++++++++++
 356   Get the column label.
 357 
 358   SQ_result_set_t *result The results from the query.
 359   
 360   unsigned int column The column index.
 361 
 362   More:
 363   +html+ <PRE>
 364   Authors:
 365         ottrey
 366   +html+ </PRE><DL COMPACT>
 367   +html+ <DT>Online References:
 368   +html+ <DD><UL>
 369   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_fetch_field_direct">mysql_fetch_field_direct()</A>
 370   +html+ </UL></DL>
 371 
 372   ++++++++++++++++++++++++++++++++++++++*/
 373 char *SQ_get_column_label(SQ_result_set_t *result, unsigned int column) {
     /* [<][>][^][v][top][bottom][index][help] */
 374   char *str;
 375 /* MySQL decided to change their interface.  Doh! */
 376 #ifdef OLDMYSQL
 377   MYSQL_FIELD field;
 378 
 379   field = mysql_fetch_field_direct(result, column);
 380 
 381   /*str = (char *)calloc(1, strlen(field.name)+1);*/
 382   dieif( wr_malloc((void **)&str, strlen(field.name)+1) != UT_OK);  
 383   strcpy(str, field.name);
 384 #else
 385   MYSQL_FIELD *field;
 386 
 387   field = mysql_fetch_field_direct(result, column);
 388 
 389   /*str = (char *)calloc(1, strlen(field->name)+1);*/
 390   dieif( wr_malloc((void **)&str, strlen(field->name)+1) != UT_OK); 
 391   strcpy(str, field->name);
 392 #endif
 393 
 394 /*
 395   printf("column=%d\n", column);
 396   printf("field.name=%s\n", field.name);
 397   printf("field.table=%s\n", field.table);
 398 
 399   printf("field.def=%s\n", field.def);
 400 
 401   printf("field.type=%d\n", field.type);
 402   printf("field.length=%d\n", field.length);
 403   printf("field.max_length=%d\n", field.max_length);
 404   printf("field.flags=%d\n", field.flags);
 405   printf("field.decimals=%d\n", field.decimals);
 406 */
 407 
 408   return str;
 409 
 410 } /* SQ_get_column_label() */
 411 
 412 /* SQ_get_column_max_length() */
 413 /*++++++++++++++++++++++++++++++++++++++
 414   Get the max length of the column.
 415 
 416   SQ_result_set_t *result The results from the query.
 417   
 418   unsigned int column The column index.
 419 
 420   More:
 421   +html+ <PRE>
 422   Authors:
 423         ottrey
 424   +html+ </PRE><DL COMPACT>
 425   +html+ <DT>Online References:
 426   +html+ <DD><UL>
 427   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_fetch_field_direct">mysql_fetch_field_direct()</A>
 428   +html+ </UL></DL>
 429 
 430   ++++++++++++++++++++++++++++++++++++++*/
 431 unsigned int SQ_get_column_max_length(SQ_result_set_t *result, unsigned int column) {
     /* [<][>][^][v][top][bottom][index][help] */
 432 /* MySQL decided to change their interface.  Doh! */
 433 #ifdef OLDMYSQL
 434   MYSQL_FIELD field;
 435 
 436   field = mysql_fetch_field_direct(result, column);
 437 
 438   return field.length;
 439 #else
 440   MYSQL_FIELD *field;
 441 
 442   field = mysql_fetch_field_direct(result, column);
 443 
 444   return field->length;
 445 #endif
 446 
 447 } /* SQ_get_column_max_length() */
 448 
 449 /* SQ_row_next() */
 450 /*++++++++++++++++++++++++++++++++++++++
 451   Get the next row.
 452 
 453   SQ_result_set_t *result The results from the query.
 454   
 455   unsigned int column The column index.
 456 
 457   More:
 458   +html+ <PRE>
 459   Authors:
 460         ottrey
 461   +html+ </PRE><DL COMPACT>
 462   +html+ <DT>Online References:
 463   +html+ <DD><UL>
 464   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_fetch_row">mysql_fetch_row()</A>
 465   +html+ </UL></DL>
 466 
 467   ++++++++++++++++++++++++++++++++++++++*/
 468 SQ_row_t *SQ_row_next(SQ_result_set_t *result) {
     /* [<][>][^][v][top][bottom][index][help] */
 469 
 470   return (SQ_row_t *)mysql_fetch_row(result);
 471 
 472 } /* SQ_row_next() */
 473 
 474 /* SQ_get_column_string() */
 475 /*++++++++++++++++++++++++++++++++++++++
 476   Get the column string.
 477 
 478   SQ_row_t *current_row The current row (obtained from a SQ_row_next() ).
 479   
 480   unsigned int column The column index.
 481 
 482   More:
 483   +html+ <PRE>
 484   Authors:
 485         ottrey
 486   +html+ </PRE><DL COMPACT>
 487   +html+ <DT>Online References:
 488   +html+ <DD><UL>
 489   +html+ </UL></DL>
 490 
 491   ++++++++++++++++++++++++++++++++++++++*/
 492 char *SQ_get_column_string(SQ_result_set_t *result, SQ_row_t *current_row, unsigned int column) {
     /* [<][>][^][v][top][bottom][index][help] */
 493   char *str=NULL;
 494   int length = mysql_fetch_lengths(result)[column];
 495   
 496   if (current_row != NULL && current_row[column] != NULL) {
 497     /*str = (char *)malloc(length + 1);*/
 498     dieif( wr_malloc((void **)&str, length + 1) != UT_OK);  
 499     if (str != NULL) {
 500       memcpy(str, current_row[column], length );
 501       str[length] = '\0';
 502     }
 503   }
 504 
 505   return str;
 506   
 507 } /* SQ_get_column_string() */
 508 
 509 /* SQ_get_column_string_nocopy - return pointer to the column string
 510    without making a copy of it */
 511 char *SQ_get_column_string_nocopy(SQ_result_set_t *result, 
     /* [<][>][^][v][top][bottom][index][help] */
 512                                   SQ_row_t *current_row, 
 513                                   unsigned int column) 
 514 {
 515   if (current_row != NULL && current_row[column] != NULL) {
 516     return (char *)current_row[column];
 517   }
 518   return NULL;
 519 }/* SQ_get_column_string_nocopy */
 520 
 521 
 522 
 523 /* SQ_get_column_strings() */
 524 /*++++++++++++++++++++++++++++++++++++++
 525   Get the all the strings in one column.
 526 
 527   SQ_result_set_t *result The results.
 528   
 529   unsigned int column The column index.
 530 
 531   More:
 532   +html+ <PRE>
 533   Authors:
 534         ottrey
 535   +html+ </PRE><DL COMPACT>
 536   +html+ <DT>Online References:
 537   +html+ <DD><UL>
 538   +html+ </UL></DL>
 539 
 540   ++++++++++++++++++++++++++++++++++++++*/
 541 char *SQ_get_column_strings(SQ_result_set_t *result, unsigned int column) {
     /* [<][>][^][v][top][bottom][index][help] */
 542   MYSQL_ROW row;
 543   char str_buffer[STR_XXL];
 544   char str_buffer_tmp[STR_L];
 545   char *str;
 546 
 547   strcpy(str_buffer, "");
 548 
 549   while ((row = mysql_fetch_row(result)) != NULL) {
 550     if (row[column] != NULL) {
 551       sprintf(str_buffer_tmp, "%s\n", row[column]);
 552     }
 553     strcat(str_buffer, str_buffer_tmp);
 554 
 555     if (strlen(str_buffer) >= (STR_XXL - STR_XL) ) {
 556       strcat(str_buffer, "And some more stuff...\n");
 557       break;
 558     }
 559   }
 560 
 561   if (strcmp(str_buffer, "") != 0) {
 562     /*str = (char *)calloc(1, strlen(str_buffer)+1);*/
 563     dieif( wr_malloc((void **)&str, strlen(str_buffer)+1) != UT_OK);  
 564     strcpy(str, str_buffer);
 565   }
 566   else {
 567     str = NULL;
 568   }
 569 
 570   return str;
 571 
 572 } /* SQ_get_column_strings() */
 573 
 574 /* SQ_get_column_int() */
 575 /*++++++++++++++++++++++++++++++++++++++
 576   Get an integer from the column.
 577 
 578   SQ_result_set_t *result The results.
 579   
 580   SQ_row_t *current_row The current row.
 581 
 582   unsigned int column The column index.
 583 
 584   long *resultptr     pointer where the result should be stored
 585 
 586   returns -1 if error occurs, 0 otherwise.
 587   Note - it never says what error occured....
 588 
 589   More:
 590   +html+ <PRE>
 591   Authors:
 592         ottrey
 593   +html+ </PRE><DL COMPACT>
 594   +html+ <DT>Online References:
 595   +html+ <DD><UL>
 596   +html+ </UL></DL>
 597 
 598   ++++++++++++++++++++++++++++++++++++++*/
 599 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] */
 600   int ret_val=-1;
 601 
 602   if (*current_row[column] != NULL) {
 603       if( sscanf( *current_row[column], "%ld", resultptr) > 0 ) {
 604         ret_val = 0;
 605       }
 606   }
 607   return ret_val;
 608   
 609 } /* SQ_get_column_int() */
 610 
 611 
 612 /* SQ_result_to_string() */
 613 /*++++++++++++++++++++++++++++++++++++++
 614   Convert the result set to a string.
 615 
 616   SQ_result_set_t *result The results.
 617   
 618   More:
 619   +html+ <PRE>
 620   Authors:
 621         ottrey
 622   +html+ </PRE><DL COMPACT>
 623   +html+ <DT>Online References:
 624   +html+ <DD><UL>
 625   +html+ </UL></DL>
 626 
 627   ++++++++++++++++++++++++++++++++++++++*/
 628 char *SQ_result_to_string(SQ_result_set_t *result) {
     /* [<][>][^][v][top][bottom][index][help] */
 629   MYSQL_ROW row;
 630   unsigned int no_cols;
 631   unsigned int i, j;
 632   char str_buffer[STR_XXL];
 633   char str_buffer_tmp[STR_L];
 634   char border[STR_L];
 635   char *str;
 636 
 637   char *label;
 638 
 639   unsigned int length[STR_S];
 640 
 641   strcpy(str_buffer, "");
 642 
 643   no_cols = mysql_num_fields(result);
 644 
 645   /* Determine the maximum column widths */
 646   /* XXX Surely MySQL should keep note of this for me! */
 647   strcpy(border, "");
 648   for (i=0; i < no_cols; i++) {
 649     length[i] = SQ_get_column_max_length(result, i);
 650     /* Make sure the lenghts don't get too long */
 651     if (length[i] > STR_M) {
 652       length[i] = STR_M;
 653     }
 654     strcat(border, "*");
 655     for (j=0; (j <= length[i]) && (j < STR_L); j++) {
 656       strcat(border, "-");
 657     }
 658   }
 659   strcat(border, "*\n");
 660   /*
 661   for (i=0; i < no_cols; i++) {
 662     printf("length[%d]=%d\n", i, length[i]);
 663   }
 664   */
 665 
 666   strcat(str_buffer, border);
 667 
 668   for (i=0; i < no_cols; i++) {
 669     label = SQ_get_column_label(result, i);
 670     if (label != NULL) {
 671       sprintf(str_buffer_tmp, "| %-*s", length[i], label);
 672       strcat(str_buffer, str_buffer_tmp);
 673     }
 674   }
 675   strcat(str_buffer, "|\n");
 676   
 677   strcat(str_buffer, border);
 678 
 679 
 680   while ((row = mysql_fetch_row(result)) != NULL) {
 681     for (i=0; i < no_cols; i++) {
 682       if (row[i] != NULL) {
 683         sprintf(str_buffer_tmp, "| %-*s", length[i], row[i]);
 684       }
 685       else {
 686         sprintf(str_buffer_tmp, "| %-*s", length[i], "NuLL");
 687       }
 688       strcat(str_buffer, str_buffer_tmp);
 689     }
 690     strcat(str_buffer, "|\n");
 691 
 692     if (strlen(str_buffer) >= (STR_XXL - STR_XL) ) {
 693       strcat(str_buffer, "And some more stuff...\n");
 694       break;
 695     }
 696   }
 697 
 698   strcat(str_buffer, border);
 699   
 700   /* str = (char *)calloc(1, strlen(str_buffer)+1);*/
 701   dieif( wr_malloc((void **)&str, strlen(str_buffer)+1) != UT_OK);  
 702   strcpy(str, str_buffer);
 703 
 704   return str;
 705 
 706 } /* SQ_result_to_string() */
 707 
 708 /* SQ_free_result() */
 709 /*++++++++++++++++++++++++++++++++++++++
 710   Free the result set.
 711 
 712   SQ_result_set_t *result The results.
 713   
 714   More:
 715   +html+ <PRE>
 716   Authors:
 717         ottrey
 718   +html+ </PRE><DL COMPACT>
 719   +html+ <DT>Online References:
 720   +html+ <DD><UL>
 721   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_free_result">mysql_free_result()</A>
 722   +html+ </UL></DL>
 723 
 724   ++++++++++++++++++++++++++++++++++++++*/
 725 void SQ_free_result(SQ_result_set_t *result) {
     /* [<][>][^][v][top][bottom][index][help] */
 726   mysql_free_result(result);
 727 } /* SQ_free_result() */
 728 
 729 
 730 /* SQ_close_connection() */
 731 /*++++++++++++++++++++++++++++++++++++++
 732   Call this function to close a connection to the server
 733 
 734   SQ_connection_t *sql_connection The connection to the database.
 735   
 736   More:
 737   +html+ <PRE>
 738   Authors:
 739         ottrey
 740   +html+ </PRE><DL COMPACT>
 741   +html+ <DT>Online References:
 742   +html+ <DD><UL>
 743   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_close">mysql_close()</A>
 744   +html+ </UL></DL>
 745 
 746   ++++++++++++++++++++++++++++++++++++++*/
 747 void SQ_close_connection(SQ_connection_t *sql_connection) {
     /* [<][>][^][v][top][bottom][index][help] */
 748 
 749   mysql_close(sql_connection);
 750 
 751 }
 752 
 753 /* SQ_num_rows() */
 754 /*++++++++++++++++++++++++++++++++++++++
 755   Call this function to find out how many rows are in a query result
 756 
 757   SQ_result_set_t *result The results.
 758   
 759   More:
 760   +html+ <PRE>
 761   Authors:
 762         ottrey
 763   +html+ </PRE><DL COMPACT>
 764   +html+ <DT>Online References:
 765   +html+ <DD><UL>
 766   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_num_rows">mysql_num_rows()</A>
 767   +html+ </UL></DL>
 768 
 769   ++++++++++++++++++++++++++++++++++++++*/
 770 int SQ_num_rows(SQ_result_set_t *result) {
     /* [<][>][^][v][top][bottom][index][help] */
 771   int rows=-1;
 772 
 773   if (result != NULL) {
 774     rows = mysql_num_rows(result);
 775   }
 776 
 777   return rows;
 778 }
 779 
 780 /* SQ_info_to_string() */
 781 /*++++++++++++++++++++++++++++++++++++++
 782   Convert all available information about the sql server into a string.
 783 
 784   SQ_connection_t *sql_connection The connection to the database.
 785 
 786   More:
 787   +html+ <PRE>
 788   Authors:
 789         ottrey
 790   +html+ </PRE><DL COMPACT>
 791   +html+ <DT>Online References:
 792   +html+ <DD><UL>
 793   +html+ </UL></DL>
 794 
 795   ++++++++++++++++++++++++++++++++++++++*/
 796 char *SQ_info_to_string(SQ_connection_t *sql_connection) {
     /* [<][>][^][v][top][bottom][index][help] */
 797   char str_buffer[STR_XXL];
 798   char str_buffer_tmp[STR_L];
 799   char *str;
 800   char *str_tmp;
 801 
 802   strcpy(str_buffer, "");
 803 
 804   /* Makes the server dump debug information to the log. */
 805   sprintf(str_buffer_tmp, "mysql_dump_debug_info()=%d\n", mysql_dump_debug_info(sql_connection));
 806   strcat(str_buffer, str_buffer_tmp);
 807 
 808   /* Returns the error number from the last MySQL function. */
 809   sprintf(str_buffer_tmp, "mysql_errno()=%d\n", mysql_errno(sql_connection));
 810   strcat(str_buffer, str_buffer_tmp);
 811 
 812   /* Returns the error message from the last MySQL function. */
 813   sprintf(str_buffer_tmp, "mysql_error()=%s\n", mysql_error(sql_connection));
 814   strcat(str_buffer, str_buffer_tmp);
 815 
 816   /* Returns client version information. */
 817   sprintf(str_buffer_tmp, "mysql_get_client_info()=%s\n", mysql_get_client_info() );
 818   strcat(str_buffer, str_buffer_tmp);
 819 
 820   /* Returns a string describing the connection. */
 821   sprintf(str_buffer_tmp, "mysql_get_host_info()=%s\n", mysql_get_host_info(sql_connection));
 822   strcat(str_buffer, str_buffer_tmp);
 823 
 824   /* Returns the protocol version used by the connection. */
 825   sprintf(str_buffer_tmp, "mysql_get_proto_info()=%d\n", mysql_get_proto_info(sql_connection));
 826   strcat(str_buffer, str_buffer_tmp);
 827 
 828   /* Returns the server version number. */
 829   sprintf(str_buffer_tmp, "mysql_get_server_info()=%s\n", mysql_get_server_info(sql_connection));
 830   strcat(str_buffer, str_buffer_tmp);
 831 
 832   /* Information about the most recently executed query. */
 833   /* XXX Check for NULL */
 834   str_tmp = mysql_info(sql_connection);
 835   if (str_tmp != NULL) {
 836     sprintf(str_buffer_tmp, "mysql_info()=%s\n", str_tmp);
 837   }
 838   else {
 839     sprintf(str_buffer_tmp, "mysql_info()=%s\n", "NulL");
 840   }
 841   strcat(str_buffer, str_buffer_tmp);
 842 
 843 
 844   /* Returns a list of the current server threads. 
 845 
 846      NOT Used here, because it returns a RESULT struct that must be 
 847      iterated through.
 848      
 849      sprintf(str_buffer_tmp, "mysql_list_processes()=%x\n", mysql_list_processes(sql_connection));
 850      strcat(str_buffer, str_buffer_tmp);
 851      
 852   */
 853 
 854   /* Checks if the connection to the server is working. */
 855   sprintf(str_buffer_tmp, "mysql_ping()=%d\n", mysql_ping(sql_connection));
 856   strcat(str_buffer, str_buffer_tmp);
 857 
 858   /* Returns the server status as a string. */
 859   sprintf(str_buffer_tmp, "mysql_stat()=%s\n", mysql_stat(sql_connection));
 860   strcat(str_buffer, str_buffer_tmp);
 861 
 862   /* Returns the current thread id. */
 863   sprintf(str_buffer_tmp, "mysql_thread_id()=%ld\n", mysql_thread_id(sql_connection));
 864   strcat(str_buffer, str_buffer_tmp);
 865 
 866 
 867   /*str = (char *)calloc(1, strlen(str_buffer)+1);*/
 868   dieif( wr_malloc((void **)&str, strlen(str_buffer)+1) != UT_OK);  
 869   strcpy(str, str_buffer);
 870 
 871   return str;
 872 
 873 } /* SQ_info_to_string() */
 874 
 875 /* SQ_error() */
 876 /*++++++++++++++++++++++++++++++++++++++
 877   Get the error string for the last error.
 878 
 879   SQ_connection_t *sql_connection The connection to the database.
 880 
 881   More:
 882   +html+ <PRE>
 883   Authors:
 884         ottrey
 885   +html+ </PRE><DL COMPACT>
 886   +html+ <DT>Online References:
 887   +html+ <DD><UL>
 888   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_error">mysql_error()</A>
 889   +html+ </UL></DL>
 890 
 891   ++++++++++++++++++++++++++++++++++++++*/
 892 char *SQ_error(SQ_connection_t *sql_connection) {
     /* [<][>][^][v][top][bottom][index][help] */
 893 
 894   return mysql_error(sql_connection);
 895 
 896 } /* SQ_error() */
 897 
 898 /* SQ_errno() */
 899 /*++++++++++++++++++++++++++++++++++++++
 900   Get the error number for the last error.
 901 
 902   SQ_connection_t *sql_connection The connection to the database.
 903 
 904   More:
 905   +html+ <PRE>
 906   Authors:
 907         ottrey
 908   +html+ </PRE><DL COMPACT>
 909   +html+ <DT>Online References:
 910   +html+ <DD><UL>
 911   +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_free_result">mysql_free_result()</A>
 912   +html+ </UL></DL>
 913 
 914   ++++++++++++++++++++++++++++++++++++++*/
 915 int SQ_errno(SQ_connection_t *sql_connection) {
     /* [<][>][^][v][top][bottom][index][help] */
 916 
 917   return mysql_errno(sql_connection);
 918 
 919 } /* SQ_errno() */
 920 
 921 /* SQ_get_info() */
 922 /*++++++++++++++++++++++++++++++++++++++
 923   Get additional information about the most 
 924   recently executed query.
 925   
 926   SQ_connection_t *sql_connection The connection to the database.
 927   int info[3] array of integers where information is stored
 928   
 929   The meaning of the numbers returned depends on the query type:
 930   
 931   info[SQL_RECORDS] - # of Records for INSERT
 932   info[SQL_MATCHES] - # of Matches for UPDATE
 933   info[SQL_DUPLICATES] - # of Duplicates
 934   info[SQL_WARNINGS] - # of Warnings
 935   
 936   More:
 937  +html+ <PRE>
 938  Authors:
 939   andrei
 940  +html+ </PRE><DL COMPACT>
 941  +html+ <DT>Online References:
 942  +html+ <DD><UL>
 943  +html+     <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_info">mysql_info()</A>
 944  +html+ </UL></DL>
 945 
 946 ++++++++++++++++++++++++++++++++++++++*/  
 947   
 948 int SQ_get_info(SQ_connection_t *sql_connection, int info[3])
     /* [<][>][^][v][top][bottom][index][help] */
 949 {
 950 int ii;
 951 char *colon, *buf_ptr, buf[20]; 
 952 char *infoline;
 953 
 954   infoline=mysql_info(sql_connection); 
 955   ii=0;
 956   colon = infoline;
 957   while (*colon != '\0') {
 958    colon++;
 959    buf_ptr=buf;
 960    if(isdigit((int)*colon)){
 961     while(isdigit((int)*colon)){
 962      *buf_ptr=*colon; buf_ptr++; colon++;
 963     }
 964     *buf_ptr='\0';
 965     info[ii]=atoi(buf); ii++;
 966    } 
 967   }
 968  return(0);
 969 }
 970 
 971 
 972 /* 
 973    open a connection with the same parameters
 974 
 975    by marek
 976 */
 977 SQ_connection_t *
 978 SQ_duplicate_connection(SQ_connection_t *orig)
     /* [<][>][^][v][top][bottom][index][help] */
 979 {
 980   return SQ_get_connection(orig->host, orig->port, orig->db, 
 981                            orig->user, orig->passwd);
 982 }
 983 
 984 /* 
 985    abort the current query on the given connection
 986 
 987    by marek
 988 */
 989 int
 990 SQ_abort_query(SQ_connection_t *sql_connection)
     /* [<][>][^][v][top][bottom][index][help] */
 991 {
 992   SQ_connection_t *contemp = SQ_duplicate_connection(sql_connection);
 993   int res = mysql_kill(contemp, sql_connection->thread_id);
 994 
 995   ER_dbg_va(FAC_SQ, ASP_SQ_ABORT,
 996             "connection %d aborted by tmp thread %d",
 997             sql_connection->thread_id,
 998             contemp->thread_id);
 999 
1000   SQ_close_connection(contemp);
1001 
1002   return res;
1003 }

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