1 | /*************************************** 2 | $Revision: 1.8 $ 3 | 4 | SQL module (sq) - this is a MySQL implementation of the SQL module. 5 | 6 | Status: NOT REVUED, NOT TESTED 7 | 8 | ******************/ /****************** 9 | Filename : mysql_driver.c 10 | Author : ottrey@ripe.net 11 | OSs Tested : Solaris 12 | ******************/ /****************** 13 | Copyright (c) 1999 RIPE NCC 14 | 15 | All Rights Reserved 16 | 17 | Permission to use, copy, modify, and distribute this software and its 18 | documentation for any purpose and without fee is hereby granted, 19 | provided that the above copyright notice appear in all copies and that 20 | both that copyright notice and this permission notice appear in 21 | supporting documentation, and that the name of the author not be 22 | used in advertising or publicity pertaining to distribution of the 23 | software without specific, written prior permission. 24 | 25 | THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 26 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL 27 | AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 28 | DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 29 | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 30 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 31 | ***************************************/ 32 | #include <stdlib.h> 33 | #include <stdio.h> 34 | #include "mysql_driver.h" 35 | #include "constants.h" 36 | #include <sys/timeb.h> 37 | 38 | /* XXX NB. The changes to SQ_row_next() and the removal of the Global variable Current_row */ 39 | 40 | 41 | /*+ String sizes +*/ 42 | #define STR_S 63 43 | #define STR_M 255 44 | #define STR_L 1023 45 | #define STR_XL 4095 46 | #define STR_XXL 16383 47 | 48 | 49 | /* log_query() */ 50 | /*++++++++++++++++++++++++++++++++++++++ 51 | Log the query. This should/will get merged with a tracing module. 52 | 53 | More: 54 | +html+ <PRE> 55 | Authors: 56 | ottrey 57 | +html+ </PRE><DL COMPACT> 58 | +html+ <DT>Online References: 59 | +html+ <DD><UL> 60 | +html+ </UL></DL> 61 | 62 | ++++++++++++++++++++++++++++++++++++++*/ 63 | static void log_query(const char *logfile, const char *query, struct timeb *start, struct timeb *stop) { 64 | FILE *logf; 65 | int seconds; 66 | int milliseconds; 67 | 68 | seconds = (int)(stop->time - start->time); 69 | milliseconds = (int)(stop->millitm - start->millitm); 70 | if (milliseconds < 0) { 71 | milliseconds += 1000; 72 | seconds--; 73 | } 74 | 75 | if (strcmp(logfile, "stdout") == 0) { 76 | printf("query=[%s] took %d sec %d msec\n", query, seconds, milliseconds); 77 | } 78 | else { 79 | logf = fopen(logfile, "a"); 80 | fprintf(logf, "query=[%s] took %d sec %d msec\n", query, seconds, milliseconds); 81 | fclose(logf); 82 | } 83 | 84 | } /* log_query() */ 85 | 86 | /* SQ_get_connection() */ 87 | /*++++++++++++++++++++++++++++++++++++++ 88 | Get a connection to the database. 89 | 90 | const char *host 91 | 92 | unsigned int port 93 | 94 | const char *db 95 | 96 | const char *user 97 | 98 | const char *password 99 | 100 | More: 101 | +html+ <PRE> 102 | Authors: 103 | ottrey 104 | +html+ </PRE><DL COMPACT> 105 | +html+ <DT>Online References: 106 | +html+ <DD><UL> 107 | +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_init">mysql_init()</A> 108 | +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_real_connect">mysql_real_connect()</A> 109 | +html+ </UL></DL> 110 | 111 | ++++++++++++++++++++++++++++++++++++++*/ 112 | SQ_connection_t *SQ_get_connection(const char *host, unsigned int port, const char *db, const char *user, const char *password) { 113 | 114 | SQ_connection_t *sql_connection; 115 | 116 | sql_connection = mysql_init(NULL); 117 | if (!sql_connection) { 118 | /* Check for errors */ 119 | printf("Connection init error\n"); 120 | } 121 | 122 | sql_connection = mysql_real_connect(sql_connection, host, user, password, db, port, NULL, 0); 123 | if (!sql_connection) { 124 | /* Check for errors */ 125 | printf("Connection error: Failed to connect to database....\n"); 126 | exit(-1); 127 | } 128 | 129 | return sql_connection; 130 | 131 | } /* SQ_get_connection() */ 132 | 133 | /* SQ_execute_query() */ 134 | /*++++++++++++++++++++++++++++++++++++++ 135 | Execute the sql query. 136 | 137 | SQ_connection_t *sql_connection Connection to database. 138 | 139 | const char *query SQL query. 140 | 141 | More: 142 | +html+ <PRE> 143 | Authors: 144 | ottrey 145 | +html+ </PRE><DL COMPACT> 146 | +html+ <DT>Online References: 147 | +html+ <DD><UL> 148 | +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_query">mysql_query()</A> 149 | +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_use_result">mysql_use_result()</A> 150 | +html+ </UL></DL> 151 | 152 | ++++++++++++++++++++++++++++++++++++++*/ 153 | SQ_result_set_t *SQ_execute_query(SQ_connection_t *sql_connection, const char *query) { 154 | struct timeb *start_time; 155 | struct timeb *stop_time; 156 | int err; 157 | SQ_result_set_t *result; 158 | 159 | if (CO_get_query_logging() == 1) { 160 | start_time=(struct timeb *)calloc(1, sizeof(struct timeb)+1); 161 | stop_time=(struct timeb *)calloc(1, sizeof(struct timeb)+1); 162 | 163 | ftime(start_time); 164 | err = mysql_query(sql_connection, query); 165 | ftime(stop_time); 166 | 167 | log_query(CO_get_query_logfile(), query, start_time, stop_time); 168 | 169 | free(start_time); 170 | free(stop_time); 171 | } 172 | else { 173 | err = mysql_query(sql_connection, query); 174 | } 175 | 176 | if (err == 0) { 177 | result = mysql_use_result(sql_connection); 178 | } 179 | else { 180 | result = NULL; 181 | } 182 | 183 | return result; 184 | 185 | } /* SQ_execute_query() */ 186 | 187 | /* SQ_get_column_count() */ 188 | /*++++++++++++++++++++++++++++++++++++++ 189 | Get the column count. 190 | 191 | SQ_result_set_t *result The results from the query. 192 | 193 | More: 194 | +html+ <PRE> 195 | Authors: 196 | ottrey 197 | +html+ </PRE><DL COMPACT> 198 | +html+ <DT>Online References: 199 | +html+ <DD><UL> 200 | +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_num_fields">mysql_num_fields()</A> 201 | +html+ </UL></DL> 202 | 203 | ++++++++++++++++++++++++++++++++++++++*/ 204 | int SQ_get_column_count(SQ_result_set_t *result) { 205 | int cols; 206 | 207 | cols = mysql_num_fields(result); 208 | 209 | return cols; 210 | 211 | } /* SQ_get_column_count() */ 212 | 213 | /* SQ_get_column_label() */ 214 | /*++++++++++++++++++++++++++++++++++++++ 215 | Get the column label. 216 | 217 | SQ_result_set_t *result The results from the query. 218 | 219 | unsigned int column The column index. 220 | 221 | More: 222 | +html+ <PRE> 223 | Authors: 224 | ottrey 225 | +html+ </PRE><DL COMPACT> 226 | +html+ <DT>Online References: 227 | +html+ <DD><UL> 228 | +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_fetch_field_direct">mysql_fetch_field_direct()</A> 229 | +html+ </UL></DL> 230 | 231 | ++++++++++++++++++++++++++++++++++++++*/ 232 | char *SQ_get_column_label(SQ_result_set_t *result, unsigned int column) { 233 | char *str; 234 | MYSQL_FIELD field; 235 | 236 | field = mysql_fetch_field_direct(result, column); 237 | 238 | /* 239 | printf("column=%d\n", column); 240 | printf("field.name=%s\n", field.name); 241 | printf("field.table=%s\n", field.table); 242 | */ 243 | /* 244 | printf("field.def=%s\n", field.def); 245 | */ 246 | /* 247 | printf("field.type=%d\n", field.type); 248 | printf("field.length=%d\n", field.length); 249 | printf("field.max_length=%d\n", field.max_length); 250 | printf("field.flags=%d\n", field.flags); 251 | printf("field.decimals=%d\n", field.decimals); 252 | */ 253 | 254 | str = (char *)calloc(1, strlen(field.name)+1); 255 | strcpy(str, field.name); 256 | 257 | return str; 258 | 259 | } /* SQ_get_column_label() */ 260 | 261 | /* SQ_get_column_max_length() */ 262 | /*++++++++++++++++++++++++++++++++++++++ 263 | Get the max length of the column. 264 | 265 | SQ_result_set_t *result The results from the query. 266 | 267 | unsigned int column The column index. 268 | 269 | More: 270 | +html+ <PRE> 271 | Authors: 272 | ottrey 273 | +html+ </PRE><DL COMPACT> 274 | +html+ <DT>Online References: 275 | +html+ <DD><UL> 276 | +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_fetch_field_direct">mysql_fetch_field_direct()</A> 277 | +html+ </UL></DL> 278 | 279 | ++++++++++++++++++++++++++++++++++++++*/ 280 | unsigned int SQ_get_column_max_length(SQ_result_set_t *result, unsigned int column) { 281 | MYSQL_FIELD field; 282 | 283 | field = mysql_fetch_field_direct(result, column); 284 | 285 | return field.length; 286 | 287 | } /* SQ_get_column_max_length() */ 288 | 289 | /* SQ_row_next() */ 290 | /*++++++++++++++++++++++++++++++++++++++ 291 | Get the next row. 292 | 293 | SQ_result_set_t *result The results from the query. 294 | 295 | unsigned int column The column index. 296 | 297 | More: 298 | +html+ <PRE> 299 | Authors: 300 | ottrey 301 | +html+ </PRE><DL COMPACT> 302 | +html+ <DT>Online References: 303 | +html+ <DD><UL> 304 | +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_fetch_row">mysql_fetch_row()</A> 305 | +html+ </UL></DL> 306 | 307 | ++++++++++++++++++++++++++++++++++++++*/ 308 | SQ_row_t *SQ_row_next(SQ_result_set_t *result) { 309 | 310 | return (SQ_row_t *)mysql_fetch_row(result); 311 | 312 | } /* SQ_row_next() */ 313 | 314 | /* SQ_get_column_string() */ 315 | /*++++++++++++++++++++++++++++++++++++++ 316 | Get the column string. 317 | 318 | SQ_row_t *current_row The current row (obtained from a SQ_row_next() ). 319 | 320 | unsigned int column The column index. 321 | 322 | More: 323 | +html+ <PRE> 324 | Authors: 325 | ottrey 326 | +html+ </PRE><DL COMPACT> 327 | +html+ <DT>Online References: 328 | +html+ <DD><UL> 329 | +html+ </UL></DL> 330 | 331 | ++++++++++++++++++++++++++++++++++++++*/ 332 | char *SQ_get_column_string(SQ_row_t *current_row, unsigned int column) { 333 | char *str=NULL; 334 | 335 | if (current_row[column] != NULL) { 336 | str = (char *)calloc(1, strlen(current_row[column])+1); 337 | if (str != NULL) { 338 | strcpy(str, current_row[column]); 339 | } 340 | } 341 | 342 | return str; 343 | 344 | } /* SQ_get_column_string() */ 345 | 346 | /* SQ_get_column_string() */ 347 | /*++++++++++++++++++++++++++++++++++++++ 348 | Get the all the strings in one column. 349 | 350 | SQ_result_set_t *result The results. 351 | 352 | unsigned int column The column index. 353 | 354 | More: 355 | +html+ <PRE> 356 | Authors: 357 | ottrey 358 | +html+ </PRE><DL COMPACT> 359 | +html+ <DT>Online References: 360 | +html+ <DD><UL> 361 | +html+ </UL></DL> 362 | 363 | ++++++++++++++++++++++++++++++++++++++*/ 364 | char *SQ_get_column_strings(SQ_result_set_t *result, unsigned int column) { 365 | MYSQL_ROW row; 366 | char str_buffer[STR_XXL]; 367 | char str_buffer_tmp[STR_L]; 368 | char *str; 369 | 370 | int l; 371 | 372 | strcpy(str_buffer, ""); 373 | 374 | while ((row = mysql_fetch_row(result)) != NULL) { 375 | if (row[column] != NULL) { 376 | sprintf(str_buffer_tmp, "%s\n", row[column]); 377 | } 378 | strcat(str_buffer, str_buffer_tmp); 379 | 380 | if (strlen(str_buffer) >= (STR_XXL - STR_XL) ) { 381 | strcat(str_buffer, "And some more stuff...\n"); 382 | break; 383 | } 384 | } 385 | 386 | if (strcmp(str_buffer, "") != 0) { 387 | str = (char *)calloc(1, strlen(str_buffer)+1); 388 | strcpy(str, str_buffer); 389 | } 390 | else { 391 | str = NULL; 392 | } 393 | 394 | return str; 395 | 396 | } /* SQ_get_column_strings() */ 397 | 398 | /* SQ_get_column_int() */ 399 | /*++++++++++++++++++++++++++++++++++++++ 400 | Get an integer from the column. 401 | 402 | SQ_result_set_t *result The results. 403 | 404 | SQ_row_t *current_row The current row. 405 | 406 | unsigned int column The column index. 407 | 408 | This uses atoi. So it may be advisable not to use it. 409 | 410 | More: 411 | +html+ <PRE> 412 | Authors: 413 | ottrey 414 | +html+ </PRE><DL COMPACT> 415 | +html+ <DT>Online References: 416 | +html+ <DD><UL> 417 | +html+ </UL></DL> 418 | 419 | ++++++++++++++++++++++++++++++++++++++*/ 420 | int SQ_get_column_int(SQ_result_set_t *result, SQ_row_t *current_row, unsigned int column) { 421 | int ret_val=-1; 422 | 423 | if (*current_row[column] != NULL) { 424 | ret_val = atoi(*current_row[column]); 425 | } 426 | else { 427 | ; 428 | } 429 | 430 | return ret_val; 431 | 432 | } /* SQ_get_column_int() */ 433 | 434 | 435 | /* SQ_result_to_string() */ 436 | /*++++++++++++++++++++++++++++++++++++++ 437 | Convert the result set to a string. 438 | 439 | SQ_result_set_t *result The results. 440 | 441 | More: 442 | +html+ <PRE> 443 | Authors: 444 | ottrey 445 | +html+ </PRE><DL COMPACT> 446 | +html+ <DT>Online References: 447 | +html+ <DD><UL> 448 | +html+ </UL></DL> 449 | 450 | ++++++++++++++++++++++++++++++++++++++*/ 451 | char *SQ_result_to_string(SQ_result_set_t *result) { 452 | MYSQL_ROW row; 453 | unsigned int no_cols; 454 | unsigned int i, j; 455 | char str_buffer[STR_XXL]; 456 | char str_buffer_tmp[STR_L]; 457 | char border[STR_L]; 458 | char *str; 459 | 460 | char *label; 461 | 462 | unsigned int length[STR_S]; 463 | int l; 464 | 465 | strcpy(str_buffer, ""); 466 | 467 | no_cols = mysql_num_fields(result); 468 | 469 | /* Determine the maximum column widths */ 470 | /* XXX Surely MySQL should keep note of this for me! */ 471 | strcpy(border, ""); 472 | for (i=0; i < no_cols; i++) { 473 | length[i] = SQ_get_column_max_length(result, i); 474 | /* Make sure the lenghts don't get too long */ 475 | if (length[i] > STR_M) { 476 | length[i] = STR_M; 477 | } 478 | strcat(border, "*"); 479 | for (j=0; (j <= length[i]) && (j < STR_L); j++) { 480 | strcat(border, "-"); 481 | } 482 | } 483 | strcat(border, "*\n"); 484 | /* 485 | for (i=0; i < no_cols; i++) { 486 | printf("length[%d]=%d\n", i, length[i]); 487 | } 488 | */ 489 | 490 | strcat(str_buffer, border); 491 | 492 | for (i=0; i < no_cols; i++) { 493 | label = SQ_get_column_label(result, i); 494 | if (label != NULL) { 495 | sprintf(str_buffer_tmp, "| %-*s", length[i], label); 496 | strcat(str_buffer, str_buffer_tmp); 497 | } 498 | } 499 | strcat(str_buffer, "|\n"); 500 | 501 | strcat(str_buffer, border); 502 | 503 | 504 | while ((row = mysql_fetch_row(result)) != NULL) { 505 | for (i=0; i < no_cols; i++) { 506 | if (row[i] != NULL) { 507 | sprintf(str_buffer_tmp, "| %-*s", length[i], row[i]); 508 | } 509 | else { 510 | sprintf(str_buffer_tmp, "| %-*s", length[i], "NuLL"); 511 | } 512 | strcat(str_buffer, str_buffer_tmp); 513 | } 514 | strcat(str_buffer, "|\n"); 515 | 516 | if (strlen(str_buffer) >= (STR_XXL - STR_XL) ) { 517 | strcat(str_buffer, "And some more stuff...\n"); 518 | break; 519 | } 520 | } 521 | 522 | strcat(str_buffer, border); 523 | 524 | str = (char *)calloc(1, strlen(str_buffer)+1); 525 | strcpy(str, str_buffer); 526 | 527 | return str; 528 | 529 | } /* SQ_result_to_string() */ 530 | 531 | /* SQ_free_result() */ 532 | /*++++++++++++++++++++++++++++++++++++++ 533 | Free the result set. 534 | 535 | SQ_result_set_t *result The results. 536 | 537 | More: 538 | +html+ <PRE> 539 | Authors: 540 | ottrey 541 | +html+ </PRE><DL COMPACT> 542 | +html+ <DT>Online References: 543 | +html+ <DD><UL> 544 | +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_free_result">mysql_free_result()</A> 545 | +html+ </UL></DL> 546 | 547 | ++++++++++++++++++++++++++++++++++++++*/ 548 | void SQ_free_result(SQ_result_set_t *result) { 549 | mysql_free_result(result); 550 | } /* SQ_free_result() */ 551 | 552 | 553 | /* SQ_close_connection() */ 554 | /*++++++++++++++++++++++++++++++++++++++ 555 | Call this function to close a connection to the server 556 | 557 | SQ_connection_t *sql_connection The connection to the database. 558 | 559 | More: 560 | +html+ <PRE> 561 | Authors: 562 | ottrey 563 | +html+ </PRE><DL COMPACT> 564 | +html+ <DT>Online References: 565 | +html+ <DD><UL> 566 | +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_close">mysql_close()</A> 567 | +html+ </UL></DL> 568 | 569 | ++++++++++++++++++++++++++++++++++++++*/ 570 | void SQ_close_connection(SQ_connection_t *sql_connection) { 571 | 572 | mysql_close(sql_connection); 573 | 574 | } 575 | 576 | /* SQ_get_column_string() */ 577 | /*++++++++++++++++++++++++++++++++++++++ 578 | Call this function to find out how many rows are in a query result 579 | 580 | SQ_result_set_t *result The results. 581 | 582 | More: 583 | +html+ <PRE> 584 | Authors: 585 | ottrey 586 | +html+ </PRE><DL COMPACT> 587 | +html+ <DT>Online References: 588 | +html+ <DD><UL> 589 | +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_num_rows">mysql_num_rows()</A> 590 | +html+ </UL></DL> 591 | 592 | ++++++++++++++++++++++++++++++++++++++*/ 593 | int SQ_num_rows(SQ_result_set_t *result) { 594 | 595 | int rows; 596 | 597 | rows = mysql_num_rows(result); 598 | 599 | return rows; 600 | } 601 | 602 | /* SQ_info_to_string() */ 603 | /*++++++++++++++++++++++++++++++++++++++ 604 | Convert all available information about the sql server into a string. 605 | 606 | SQ_connection_t *sql_connection The connection to the database. 607 | 608 | More: 609 | +html+ <PRE> 610 | Authors: 611 | ottrey 612 | +html+ </PRE><DL COMPACT> 613 | +html+ <DT>Online References: 614 | +html+ <DD><UL> 615 | +html+ </UL></DL> 616 | 617 | ++++++++++++++++++++++++++++++++++++++*/ 618 | char *SQ_info_to_string(SQ_connection_t *sql_connection) { 619 | char str_buffer[STR_XXL]; 620 | char str_buffer_tmp[STR_L]; 621 | char *str; 622 | char *str_tmp; 623 | 624 | strcpy(str_buffer, ""); 625 | 626 | /* Makes the server dump debug information to the log. */ 627 | sprintf(str_buffer_tmp, "mysql_dump_debug_info()=%d\n", mysql_dump_debug_info(sql_connection)); 628 | strcat(str_buffer, str_buffer_tmp); 629 | 630 | /* Returns the error number from the last MySQL function. */ 631 | sprintf(str_buffer_tmp, "mysql_errno()=%d\n", mysql_errno(sql_connection)); 632 | strcat(str_buffer, str_buffer_tmp); 633 | 634 | /* Returns the error message from the last MySQL function. */ 635 | sprintf(str_buffer_tmp, "mysql_error()=%s\n", mysql_error(sql_connection)); 636 | strcat(str_buffer, str_buffer_tmp); 637 | 638 | /* Returns client version information. */ 639 | sprintf(str_buffer_tmp, "mysql_get_client_info()=%s\n", mysql_get_client_info() ); 640 | strcat(str_buffer, str_buffer_tmp); 641 | 642 | /* Returns a string describing the connection. */ 643 | sprintf(str_buffer_tmp, "mysql_get_host_info()=%s\n", mysql_get_host_info(sql_connection)); 644 | strcat(str_buffer, str_buffer_tmp); 645 | 646 | /* Returns the protocol version used by the connection. */ 647 | sprintf(str_buffer_tmp, "mysql_get_proto_info()=%d\n", mysql_get_proto_info(sql_connection)); 648 | strcat(str_buffer, str_buffer_tmp); 649 | 650 | /* Returns the server version number. */ 651 | sprintf(str_buffer_tmp, "mysql_get_server_info()=%s\n", mysql_get_server_info(sql_connection)); 652 | strcat(str_buffer, str_buffer_tmp); 653 | 654 | /* Information about the most recently executed query. */ 655 | /* XXX Check for NULL */ 656 | str_tmp = mysql_info(sql_connection); 657 | if (str_tmp != NULL) { 658 | sprintf(str_buffer_tmp, "mysql_info()=%s\n", str_tmp); 659 | } 660 | else { 661 | sprintf(str_buffer_tmp, "mysql_info()=%s\n", "NulL"); 662 | } 663 | strcat(str_buffer, str_buffer_tmp); 664 | 665 | 666 | /* Returns a list of the current server threads. */ 667 | sprintf(str_buffer_tmp, "mysql_list_processes()=%d\n", mysql_list_processes(sql_connection)); 668 | strcat(str_buffer, str_buffer_tmp); 669 | 670 | /* Checks if the connection to the server is working. */ 671 | sprintf(str_buffer_tmp, "mysql_ping()=%d\n", mysql_ping(sql_connection)); 672 | strcat(str_buffer, str_buffer_tmp); 673 | 674 | /* Returns the server status as a string. */ 675 | sprintf(str_buffer_tmp, "mysql_stat()=%s\n", mysql_stat(sql_connection)); 676 | strcat(str_buffer, str_buffer_tmp); 677 | 678 | /* Returns the current thread id. */ 679 | sprintf(str_buffer_tmp, "mysql_thread_id()=%d\n", mysql_thread_id(sql_connection)); 680 | strcat(str_buffer, str_buffer_tmp); 681 | 682 | 683 | str = (char *)calloc(1, strlen(str_buffer)+1); 684 | strcpy(str, str_buffer); 685 | 686 | return str; 687 | 688 | } /* SQ_info_to_string() */ 689 | 690 | /* SQ_error() */ 691 | /*++++++++++++++++++++++++++++++++++++++ 692 | Get the error string for the last error. 693 | 694 | SQ_connection_t *sql_connection The connection to the database. 695 | 696 | More: 697 | +html+ <PRE> 698 | Authors: 699 | ottrey 700 | +html+ </PRE><DL COMPACT> 701 | +html+ <DT>Online References: 702 | +html+ <DD><UL> 703 | +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_error">mysql_error()</A> 704 | +html+ </UL></DL> 705 | 706 | ++++++++++++++++++++++++++++++++++++++*/ 707 | char *SQ_error(SQ_connection_t *sql_connection) { 708 | 709 | return mysql_error(sql_connection); 710 | 711 | } /* SQ_error() */ 712 | 713 | /* SQ_errno() */ 714 | /*++++++++++++++++++++++++++++++++++++++ 715 | Get the error number for the last error. 716 | 717 | SQ_connection_t *sql_connection The connection to the database. 718 | 719 | More: 720 | +html+ <PRE> 721 | Authors: 722 | ottrey 723 | +html+ </PRE><DL COMPACT> 724 | +html+ <DT>Online References: 725 | +html+ <DD><UL> 726 | +html+ <LI><A HREF="http://www.tcx.se/Manual/manual.html#mysql_free_result">mysql_free_result()</A> 727 | +html+ </UL></DL> 728 | 729 | ++++++++++++++++++++++++++++++++++++++*/ 730 | int SQ_errno(SQ_connection_t *sql_connection) { 731 | 732 | return mysql_errno(sql_connection); 733 | 734 | } /* SQ_errno() */ 735 |