r10039: * BUGS: New file. Document suspected SIGPIPE
[clsql.git] / db-mysql / mysql-api.lisp
1 ;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*-
2 ;;;; *************************************************************************
3 ;;;; FILE IDENTIFICATION
4 ;;;;
5 ;;;; Name:          mysql-api.lisp
6 ;;;; Purpose:       Low-level MySQL interface using UFFI
7 ;;;; Programmers:   Kevin M. Rosenberg based on 
8 ;;;;                Original code by Pierre R. Mai 
9 ;;;; Date Started:  Feb 2002
10 ;;;;
11 ;;;; $Id$
12 ;;;;
13 ;;;; This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg
14 ;;;; and Copyright (c) 1999-2001 by Pierre R. Mai
15 ;;;;
16 ;;;; CLSQL users are granted the rights to distribute and use this software
17 ;;;; as governed by the terms of the Lisp Lesser GNU Public License
18 ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL.
19 ;;;; *************************************************************************
20
21 (in-package #:mysql)
22
23 ;;;; Modifications from original code
24 ;;;;  - Updated C-structures to conform to structures in MySQL 3.23.46
25 ;;;;  - Changed from CMUCL interface to UFFI
26 ;;;;  - Added and call a C-helper file to support 64-bit integers
27 ;;;;    that are used in a few routines.
28 ;;;;  - Removed all references to interiors of C-structions, this will
29 ;;;;    increase robustness when MySQL's internal structures change.
30  
31 ;;;; Type definitions
32
33 ;;; Basic Types
34
35 (uffi:def-foreign-type mysql-socket :int)
36 (uffi:def-foreign-type mysql-bool :byte)
37 (uffi:def-foreign-type mysql-byte :unsigned-char)
38
39 (uffi:def-enum mysql-net-type
40     (:tcp-ip
41      :socket
42      :named-pipe))
43
44 (uffi:def-struct mysql-net
45     (vio :pointer-void)
46   (fd mysql-socket)
47   (fcntl :int)
48   (buff (* :unsigned-char))
49   (buff-end (* :unsigned-char))
50   (write-pos (* :unsigned-char))
51   (read-pos (* :unsigned-char))
52   (last-error (:array :char 200))
53   (last-errno :unsigned-int)
54   (max-packet :unsigned-int)
55   (timeout :unsigned-int)
56   (pkt-nr :unsigned-int)
57   (error mysql-bool)
58   (return-errno mysql-bool)
59   (compress mysql-bool)
60   (no-send-ok mysql-bool)
61   (remain-in-buf :unsigned-long)
62   (length :unsigned-long)
63   (buf-length :unsigned-long)
64   (where-b :unsigned-long)
65   (return-status (* :unsigned-int))
66   (reading-or-writing :unsigned-char)
67   (save-char :char))
68
69 ;;; Mem-Root
70 (uffi:def-struct mysql-used-mem
71     (next :pointer-self)
72   (left :unsigned-int)
73   (size :unsigned-int))
74
75 (uffi:def-struct mysql-mem-root
76     (free (:struct-pointer mysql-used-mem))
77   (used (:struct-pointer mysql-used-mem))
78   (pre-alloc (:struct-pointer mysql-used-mem))
79   (min-alloc :unsigned-int)
80   (block-size :unsigned-int)
81   (error-handler :pointer-void))
82
83 ;;; MYSQL-FIELD
84 (uffi:def-enum mysql-field-types
85     (:decimal
86      :tiny
87      :short
88      :long
89      :float
90      :double
91      :null
92      :timestamp
93      :longlong
94      :int24
95      :date
96      :time
97      :datetime
98      :year
99      :newdate
100      (:enum 247)
101      (:set 248)
102      (:tiny-blob 249)
103      (:medium-blob 250)
104      (:long-blob 251)
105      (:blob 252)
106      (:var-string 253)
107      (:string 254)
108      (:geometry 255)))
109
110 #+mysql-client-v3
111 (uffi:def-struct mysql-field
112     (name (* :char))
113   (table (* :char))
114   (def (* :char))
115   (type mysql-field-types)
116   (length :unsigned-int)
117   (max-length :unsigned-int)
118   (flags :unsigned-int)
119   (decimals :unsigned-int))
120
121 ;; structure changed in mysql 4 client
122 #+(and mysql-client-v4 (not mysql-client-v4.1))
123 (uffi:def-struct mysql-field
124     (name (* :char))
125   (table (* :char))
126   (org_table (* :char))
127   (db (* :char))
128   (def (* :char))
129   (length :unsigned-long)
130   (max-length :unsigned-long)
131   (flags :unsigned-int)
132   (decimals :unsigned-int)
133   (type mysql-field-types))
134
135 #+mysql-client-v4.1
136 (uffi:def-struct mysql-field
137     (name (* :char))
138   (org_table (* :char))
139   (table (* :char))
140   (org_table (* :char))
141   (db (* :char))
142   (catalog_db (* :char))
143   (def (* :char))
144   (length :unsigned-long)
145   (max-length :unsigned-long)
146   (name-length :unsigned-int)
147   (org-name-length :unsigned-int)
148   (table-length :unsigned-int)
149   (org-table-length :unsigned-int)
150   (db-length :unsigned-int)
151   (catalog-length :unsigned-int)
152   (def-length :unsigned-int)
153   (flags :unsigned-int)
154   (decimals :unsigned-int)
155   (charsetnr :unsigned-int)
156   (type mysql-field-types))
157
158 (uffi:def-struct mysql-time
159     (year :unsigned-int)
160   (month :unsigned-int)
161   (day :unsigned-int)
162   (hour :unsigned-int)
163   (minute :unsigned-int)
164   (second :unsigned-int)
165   (second-part :unsigned-long)
166   (neg mysql-bool)
167   (time-type :int))
168
169 ;;; MYSQL-ROWS
170
171 (uffi:def-array-pointer mysql-row (* :unsigned-char))
172
173 (uffi:def-array-pointer mysql-field-vector (* mysql-field))
174
175 (uffi:def-foreign-type mysql-field-offset :unsigned-int)
176
177 (uffi:def-struct mysql-rows
178     (next :pointer-self)
179   (data mysql-row))
180
181 (uffi:def-foreign-type mysql-row-offset (:struct-pointer mysql-rows))
182
183 (uffi:def-struct mysql-data
184     (rows-high32 :unsigned-long)
185   (rows-low32 :unsigned-long)
186   (fields :unsigned-int)
187   (data (:struct-pointer mysql-rows))
188   (alloc (:struct mysql-mem-root)))
189
190 ;;; MYSQL
191 (uffi:def-struct mysql-options
192     (connect-timeout :unsigned-int)
193   (client-flag :unsigned-int)
194   (compress mysql-bool)
195   (named-pipe mysql-bool)
196   (port :unsigned-int)
197   (host (* :char))
198   (init-command (* :char))
199   (user (* :char))
200   (password (* :char))
201   (unix-socket (* :char))
202   (db (* :char))
203   (my-cnf-file (* :char))
204   (my-cnf-group (* :char))
205   (charset-dir (* :char))
206   (charset-name (* :char))
207   (use-ssl mysql-bool)
208   (ssl-key (* :char))
209   (ssl-cert (* :char))
210   (ssl-ca (* :char))
211   (ssl-capath (* :char)))
212
213 (uffi:def-enum mysql-option
214     (:connect-timeout
215      :compress
216      :named-pipe
217      :init-command
218      :read-default-file
219      :read-default-group))
220
221 (uffi:def-enum mysql-status
222     (:ready 
223      :get-result
224      :use-result))
225
226 (uffi:def-struct mysql-mysql
227     (net (:struct mysql-net))
228   (connected-fd (* :char))
229   (host (* :char))
230   (user (* :char))
231   (passwd (* :char))
232   (unix-socket (* :char))
233   (server-version (* :char))
234   (host-info (* :char))
235   (info (* :char))
236   (db (* :char))
237   (port :unsigned-int)
238   (client-flag :unsigned-int)
239   (server-capabilities :unsigned-int)
240   (protocol-version :unsigned-int)
241   (field-count :unsigned-int)
242   (server-status :unsigned-int)
243   (thread-id :unsigned-long)
244   (affected-rows-high32 :unsigned-long)
245   (affected-rows-low32 :unsigned-long)
246   (insert-id-high32 :unsigned-long)
247   (insert-id-low32 :unsigned-long)
248   (extra-info-high32 :unsigned-long)
249   (extra-info-low32 :unsigned-long)
250   (packet-length :unsigned-long)
251   (status mysql-status)
252   (fields (:struct-pointer mysql-field))
253   (field-alloc (:struct mysql-mem-root))
254   (free-me mysql-bool)
255   (reconnect mysql-bool)
256   (options (:struct mysql-options))
257   (scramble-buff (:array :char 9))
258   (charset :pointer-void)
259   (server-language :unsigned-int))
260
261
262 ;;; MYSQL-RES
263 (uffi:def-struct mysql-mysql-res
264     (row-count-high32 :unsigned-long)
265   (row-count-low32 :unsigned-long)
266   (field-count :unsigned-int)
267   (current-field :unsigned-int)
268   (fields (:struct-pointer mysql-field))
269   (data (:struct-pointer mysql-data))
270   (data-cursor (:struct-pointer mysql-rows))
271   (field-alloc (:struct mysql-mem-root))
272   (row mysql-row)
273   (current-row mysql-row)
274   (lengths (* :unsigned-long))
275   (handle (:struct-pointer mysql-mysql))
276   (eof mysql-bool))
277
278 #+mysql-client-4.1
279 (uffi:def-enum mysql-field-types
280     (:ready 
281      :get-result
282      :use-result))
283
284 #+mysql-client-v4.1
285 (uffi:def-struct mysql-bind
286     (length (* :unsigned-long))
287   (is-null (* mysql-bool))
288   (buffer :pointer-void)
289   (buffer-type :int)
290   (buffer-length :unsigned-long)
291   ;; internal use
292   (inter_buffer (* :unsigned-char))
293   (offset :unsigned-long)
294   (internal-length :unsigned-long)
295   (param-number :unsigned-int)
296   (pack-length :unsigned-int)
297   (is-signed mysql-bool)
298   (long-data-used mysql-bool)
299   (internal-is-null mysql-bool)
300   (store-param-func :pointer-void)
301   (fetch-result :pointer-void)
302   (skip-result :pointer-void))
303
304 ;;;; The Foreign C routines
305 (declaim (inline mysql-init))
306 (uffi:def-function "mysql_init"
307   ((mysql (* mysql-mysql)))
308   :module "mysql" 
309   :returning (* mysql-mysql))
310
311 #-mysql-client-v4
312 (declaim (inline mysql-connect))
313 #-mysql-client-v4
314 (uffi:def-function "mysql_connect"
315     ((mysql (* mysql-mysql))
316      (host :cstring)
317      (user :cstring)
318      (passwd :cstring))
319   :module "mysql"
320   :returning (* mysql-mysql))
321
322 ;; Need to comment this out for LW 4.2.6
323 ;; ? bug in LW version
324 #-lispworks (declaim (inline mysql-real-connect))
325 (uffi:def-function "mysql_real_connect"
326     ((mysql (* mysql-mysql))
327      (host :cstring)
328      (user :cstring)
329      (passwd :cstring)
330      (db :cstring)
331      (port :unsigned-int)
332      (unix-socket :cstring)
333      (clientflag :unsigned-long))
334   :module "mysql"
335   :returning (* mysql-mysql))
336
337 (declaim (inline mysql-close))
338 (uffi:def-function "mysql_close"
339     ((sock (* mysql-mysql)))
340   :module "mysql"
341   :returning :void)
342
343 (declaim (inline mysql-select-db))
344 (uffi:def-function "mysql_select_db"
345   ((mysql (* mysql-mysql))
346    (db :cstring))
347   :module "mysql"
348   :returning :int)
349
350 (declaim (inline mysql-query))
351 (uffi:def-function "mysql_query"
352     ((mysql (* mysql-mysql))
353      (query :cstring))
354   :module "mysql"
355   :returning :int)
356
357  ;;; I doubt that this function is really useful for direct Lisp usage,
358 ;;; but it is here for completeness...
359
360 (declaim (inline mysql-real-query))
361 (uffi:def-function "mysql_real_query"
362     ((mysql (* mysql-mysql))
363      (query :cstring)
364      (length :unsigned-int))
365   :module "mysql"
366   :returning :int)
367
368 #-mysql-client-v4
369 (declaim (inline mysql-create-db))
370 #-mysql-client-v4
371 (uffi:def-function "mysql_create_db"
372   ((mysql (* mysql-mysql))
373    (db :cstring))
374   :module "mysql"
375   :returning :int)
376
377 #-mysql-client-v4
378 (declaim (inline mysql-drop-db))
379 #-mysql-client-v4
380 (uffi:def-function "mysql_drop_db"
381     ((mysql (* mysql-mysql))
382      (db :cstring))
383   :module "mysql"
384   :returning :int)
385
386 (declaim (inline mysql-shutdown))
387 (uffi:def-function "mysql_shutdown"
388   ((mysql (* mysql-mysql)))
389   :module "mysql"
390   :returning :int)
391
392 (declaim (inline mysql-dump-debug-info))
393 (uffi:def-function "mysql_dump_debug_info"
394   ((mysql (* mysql-mysql)))
395   :module "mysql"
396   :returning :int)
397
398 (declaim (inline mysql-refresh))
399 (uffi:def-function "mysql_refresh"
400   ((mysql (* mysql-mysql))
401    (refresh-options :unsigned-int))
402   :module "mysql"
403   :returning :int)
404
405 (declaim (inline mysql-kill))
406 (uffi:def-function "mysql_kill"
407     ((mysql (* mysql-mysql))
408      (pid :unsigned-long))
409   :module "mysql"
410   :returning :int)
411
412 (declaim (inline mysql-ping))
413 (uffi:def-function "mysql_ping"
414     ((mysql (* mysql-mysql)))
415   :module "mysql"
416   :returning :int)
417
418 (declaim (inline mysql-stat))
419 (uffi:def-function "mysql_stat"
420   ((mysql (* mysql-mysql)))
421   :module "mysql"
422   :returning :cstring)
423
424 (declaim (inline mysql-get-server-info))
425 (uffi:def-function "mysql_get_server_info"
426     ((mysql (* mysql-mysql)))
427   :module "mysql"
428   :returning :cstring)
429
430 (declaim (inline mysql-get-host-info))
431 (uffi:def-function "mysql_get_host_info"
432     ((mysql (* mysql-mysql)))
433   :module "mysql"
434   :returning :cstring)
435
436 (declaim (inline mysql-get-proto-info))
437 (uffi:def-function "mysql_get_proto_info"
438   ((mysql (* mysql-mysql)))
439   :module "mysql"
440   :returning :unsigned-int)
441
442 (declaim (inline mysql-list-dbs))
443 (uffi:def-function "mysql_list_dbs"
444   ((mysql (* mysql-mysql))
445    (wild :cstring))
446   :module "mysql"
447   :returning (* mysql-mysql-res))
448
449 (declaim (inline mysql-list-tables))
450 (uffi:def-function "mysql_list_tables"
451   ((mysql (* mysql-mysql))
452    (wild :cstring))
453   :module "mysql"
454   :returning (* mysql-mysql-res))
455
456 (declaim (inline mysql-list-fields))
457 (uffi:def-function "mysql_list_fields"
458   ((mysql (* mysql-mysql))
459    (table :cstring)
460    (wild :cstring))
461   :module "mysql"
462   :returning (* mysql-mysql-res))
463
464 (declaim (inline mysql-list-processes))
465 (uffi:def-function "mysql_list_processes"
466   ((mysql (* mysql-mysql)))
467   :module "mysql"
468   :returning (* mysql-mysql-res))
469
470 (declaim (inline mysql-store-result))
471 (uffi:def-function "mysql_store_result"
472   ((mysql (* mysql-mysql)))
473   :module "mysql"
474   :returning (* mysql-mysql-res))
475
476 (declaim (inline mysql-use-result))
477 (uffi:def-function "mysql_use_result"
478   ((mysql (* mysql-mysql)))
479   :module "mysql"
480   :returning (* mysql-mysql-res))
481
482 (declaim (inline mysql-options))
483 (uffi:def-function "mysql_options"
484   ((mysql (* mysql-mysql))
485    (option mysql-option)
486    (arg :cstring))
487   :module "mysql"
488   :returning :int)
489
490 (declaim (inline mysql-free-result))
491 (uffi:def-function "mysql_free_result"
492     ((res (* mysql-mysql-res)))
493   :module "mysql"
494   :returning :void)
495
496 (declaim (inline mysql-row-seek))
497 (uffi:def-function "mysql_row_seek"
498   ((res (* mysql-mysql-res))
499    (offset mysql-row-offset))
500   :module "mysql"
501   :returning mysql-row-offset)
502
503 (declaim (inline mysql-field-seek))
504 (uffi:def-function "mysql_field_seek"
505   ((res (* mysql-mysql-res))
506   (offset mysql-field-offset))
507   :module "mysql"
508   :returning mysql-field-offset)
509
510 (declaim (inline mysql-fetch-row))
511 (uffi:def-function "mysql_fetch_row"
512     ((res (* mysql-mysql-res)))
513   :module "mysql"
514   :returning (* (* :unsigned-char)))
515
516 (declaim (inline mysql-fetch-lengths))
517 (uffi:def-function "mysql_fetch_lengths"
518   ((res (* mysql-mysql-res)))
519   :module "mysql"
520   :returning (* :unsigned-long))
521
522 (declaim (inline mysql-fetch-field))
523 (uffi:def-function "mysql_fetch_field"
524   ((res (* mysql-mysql-res)))
525   :module "mysql"
526   :returning (* mysql-field))
527
528 (declaim (inline mysql-fetch-fields))
529 (uffi:def-function "mysql_fetch_fields"
530   ((res (* mysql-mysql-res)))
531   :module "mysql"
532   :returning (* mysql-field))
533
534 (declaim (inline mysql-fetch-field-direct))
535 (uffi:def-function "mysql_fetch_field_direct"
536   ((res (* mysql-mysql-res))
537    (field-num :unsigned-int))
538   :module "mysql"
539   :returning (* mysql-field))
540
541 (declaim (inline mysql-escape-string))
542 (uffi:def-function "mysql_escape_string"
543     ((to :cstring)
544      (from :cstring)
545      (length :unsigned-int))
546   :module "mysql"
547   :returning :unsigned-int)
548
549 (declaim (inline mysql-debug))
550 (uffi:def-function "mysql_debug"
551     ((debug :cstring))
552   :module "mysql"
553   :returning :void)
554
555 (declaim (inline clsql-mysql-num-rows))
556 (uffi:def-function "clsql_mysql_num_rows"
557     ((res (* mysql-mysql-res))
558      (p-high32 (* :unsigned-int)))
559   :module "clsql-mysql"
560   :returning :unsigned-int)
561
562 #+mysql-client-v4.1
563 (uffi:def-foreign-type mysql-stmt-ptr :pointer-void)
564
565 #+mysql-client-v4.1
566 (uffi:def-function "mysql_stmt_init"
567     ((res (* mysql-mysql-res)))
568   :module "clsql-mysql"
569   :returning mysql-stmt-ptr)
570
571 #+mysql-client-v4.1
572 (uffi:def-function "mysql_stmt_prepare"
573     ((stmt mysql-stmt-ptr)
574      (query :cstring)
575      (length :unsigned-long))
576   :module "clsql-mysql"
577   :returning :int)
578
579 #+mysql-client-v4.1
580 (uffi:def-function "mysql_stmt_param_count"
581     ((stmt mysql-stmt-ptr))
582   :module "clsql-mysql"
583   :returning :unsigned-int)
584
585 #+mysql-client-v4.1
586 (uffi:def-function "mysql_stmt_bind_param"
587     ((stmt mysql-stmt-ptr)
588      (bind (* mysql-bind)))
589   :module "clsql-mysql"
590   :returning :short)
591
592 #+mysql-client-v4.1
593 (uffi:def-function "mysql_stmt_bind_result"
594     ((stmt mysql-stmt-ptr)
595      (bind (* mysql-bind)))
596   :module "clsql-mysql"
597   :returning :short)
598
599 #+mysql-client-v4.1
600 (uffi:def-function "mysql_stmt_result_metadata"
601     ((stmt mysql-stmt-ptr))
602   :module "clsql-mysql"
603   :returning (* mysql-mysql-res))
604
605
606 #+mysql-client-v4.1
607 (uffi:def-function "mysql_stmt_execute"
608     ((stmt mysql-stmt-ptr))
609   :module "clsql-mysql"
610   :returning :int)
611
612 #+mysql-client-v4.1
613 (uffi:def-function "mysql_stmt_store_result"
614     ((stmt mysql-stmt-ptr))
615   :module "clsql-mysql"
616   :returning :int)
617
618 #+mysql-client-v4.1
619 (uffi:def-function "mysql_stmt_fetch"
620     ((stmt mysql-stmt-ptr))
621   :module "clsql-mysql"
622   :returning :int)
623
624 #+mysql-client-v4.1
625 (uffi:def-function "mysql_stmt_free_result"
626     ((stmt mysql-stmt-ptr))
627   :module "clsql-mysql"
628   :returning :short)
629
630 #+mysql-client-v4.1
631 (uffi:def-function "mysql_stmt_close"
632     ((stmt mysql-stmt-ptr))
633   :module "clsql-mysql"
634   :returning :short)
635
636 #+mysql-client-v4.1
637 (uffi:def-function "mysql_stmt_errno"
638     ((stmt mysql-stmt-ptr))
639   :module "clsql-mysql"
640   :returning :unsigned-int)
641
642 #+mysql-client-v4.1
643 (uffi:def-function "mysql_stmt_error"
644     ((stmt mysql-stmt-ptr))
645   :module "clsql-mysql"
646   :returning :cstring)
647
648
649 ;;;; Equivalents of C Macro definitions for accessing various fields
650 ;;;; in the internal MySQL Datastructures
651
652
653 (declaim (inline mysql-num-rows))
654 (defun mysql-num-rows (res)
655   (uffi:with-foreign-object (p-high32 :unsigned-int)
656     (let ((low32 (clsql-mysql-num-rows res p-high32))
657           (high32 (uffi:deref-pointer p-high32 :unsigned-int)))
658       (if (zerop high32)
659           low32
660         (make-64-bit-integer high32 low32)))))
661
662 (uffi:def-function "clsql_mysql_affected_rows"
663     ((mysql (* mysql-mysql))
664      (p-high32 (* :unsigned-int)))
665   :returning :unsigned-int
666   :module "clsql-mysql")
667
668 (defun mysql-affected-rows (mysql)
669   (uffi:with-foreign-object (p-high32 :unsigned-int)
670     (let ((low32 (clsql-mysql-affected-rows mysql p-high32))
671           (high32 (uffi:deref-pointer p-high32 :unsigned-int)))
672       (if (zerop high32)
673           low32
674         (make-64-bit-integer high32 low32)))))
675
676 (uffi:def-function "clsql_mysql_insert_id"
677     ((res (* mysql-mysql))
678      (p-high32 (* :unsigned-int)))
679   :returning :unsigned-int
680   :module "clsql-mysql")
681
682 (defun mysql-insert-id (mysql)
683   (uffi:with-foreign-object (p-high32 :unsigned-int)
684   (let ((low32 (clsql-mysql-insert-id mysql p-high32))
685         (high32 (uffi:deref-pointer p-high32 :unsigned-int)))
686     (if (zerop high32)
687         low32
688       (make-64-bit-integer high32 low32)))))
689
690
691 (declaim (inline mysql-num-fields))
692 (uffi:def-function "mysql_num_fields" 
693   ((res (* mysql-mysql-res)))
694   :returning :unsigned-int
695   :module "mysql")
696                  
697 (declaim (inline clsql-mysql-eof))
698 (uffi:def-function ("mysql_eof" clsql-mysql-eof)
699   ((res (* mysql-mysql-res)))
700   :returning :char
701   :module "mysql")
702
703 (declaim (inline mysql-eof))
704 (defun mysql-eof (res)
705   (if (zerop (clsql-mysql-eof res))
706       nil
707     t))
708
709 (declaim (inline mysql-error))
710 (uffi:def-function ("mysql_error" mysql-error)
711   ((mysql (* mysql-mysql)))
712   :returning :cstring
713   :module "mysql")
714
715 (declaim (inline mysql-error-string))
716 (defun mysql-error-string (mysql)
717   (uffi:convert-from-cstring (mysql-error mysql)))
718
719 (declaim (inline mysql-errno))
720 (uffi:def-function "mysql_errno"
721   ((mysql (* mysql-mysql)))
722   :returning :unsigned-int
723   :module "mysql")
724
725 (declaim (inline mysql-info))
726 (uffi:def-function ("mysql_info" mysql-info)
727   ((mysql (* mysql-mysql)))
728   :returning :cstring
729   :module "mysql")
730
731 (declaim (inline mysql-info-string))
732 (defun mysql-info-string (mysql)
733   (uffi:convert-from-cstring (mysql-info mysql)))
734
735 (declaim (inline clsql-mysql-data-seek))
736 (uffi:def-function "clsql_mysql_data_seek"
737   ((res (* mysql-mysql-res))
738    (offset-high32 :unsigned-int)
739    (offset-low32 :unsigned-int))
740   :module "clsql-mysql"
741   :returning :void)
742
743 (defun mysql-data-seek (res offset)
744   (multiple-value-bind (high32 low32) (split-64-bit-integer offset)
745     (clsql-mysql-data-seek res high32 low32)))