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