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