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