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 |