Source File modules/sq/mysql_driver.c

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