Source File modules/sq/mysql_driver.c

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