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 | }