026bde07744211ace6735979ac06b812203152d7
[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 #+(or mysql-client-v4.1 mysql-client-v5)
136 (uffi:def-struct mysql-field
137     (name (* :char))
138   (org_name (* :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
159 (uffi:def-struct mysql-time
160     (year :unsigned-int)
161   (month :unsigned-int)
162   (day :unsigned-int)
163   (hour :unsigned-int)
164   (minute :unsigned-int)
165   (second :unsigned-int)
166   (second-part :unsigned-long)
167   (neg mysql-bool)
168   (time-type :int))
169
170 ;;; MYSQL-ROWS
171
172 (uffi:def-array-pointer mysql-row (* :unsigned-char))
173
174 (uffi:def-array-pointer mysql-field-vector (* mysql-field))
175
176 (uffi:def-foreign-type mysql-field-offset :unsigned-int)
177
178 (uffi:def-struct mysql-rows
179     (next :pointer-self)
180   (data mysql-row))
181
182 (uffi:def-foreign-type mysql-row-offset (:struct-pointer mysql-rows))
183
184 (uffi:def-struct mysql-data
185     (rows-high32 :unsigned-long)
186   (rows-low32 :unsigned-long)
187   (fields :unsigned-int)
188   (data (:struct-pointer mysql-rows))
189   (alloc (:struct mysql-mem-root)))
190
191 ;;; MYSQL
192 (uffi:def-struct mysql-options
193     (connect-timeout :unsigned-int)
194   (client-flag :unsigned-int)
195   (compress mysql-bool)
196   (named-pipe mysql-bool)
197   (port :unsigned-int)
198   (host (* :char))
199   (init-command (* :char))
200   (user (* :char))
201   (password (* :char))
202   (unix-socket (* :char))
203   (db (* :char))
204   (my-cnf-file (* :char))
205   (my-cnf-group (* :char))
206   (charset-dir (* :char))
207   (charset-name (* :char))
208   (use-ssl mysql-bool)
209   (ssl-key (* :char))
210   (ssl-cert (* :char))
211   (ssl-ca (* :char))
212   (ssl-capath (* :char)))
213
214 (uffi:def-enum mysql-option
215     (:connect-timeout
216      :compress
217      :named-pipe
218      :init-command
219      :read-default-file
220      :read-default-group))
221
222 (uffi:def-enum mysql-status
223     (:ready
224      :get-result
225      :use-result))
226
227 (uffi:def-struct mysql-mysql
228     (net (:struct mysql-net))
229   (connected-fd (* :char))
230   (host (* :char))
231   (user (* :char))
232   (passwd (* :char))
233   (unix-socket (* :char))
234   (server-version (* :char))
235   (host-info (* :char))
236   (info (* :char))
237   (db (* :char))
238   (port :unsigned-int)
239   (client-flag :unsigned-int)
240   (server-capabilities :unsigned-int)
241   (protocol-version :unsigned-int)
242   (field-count :unsigned-int)
243   (server-status :unsigned-int)
244   (thread-id :unsigned-long)
245   (affected-rows-high32 :unsigned-long)
246   (affected-rows-low32 :unsigned-long)
247   (insert-id-high32 :unsigned-long)
248   (insert-id-low32 :unsigned-long)
249   (extra-info-high32 :unsigned-long)
250   (extra-info-low32 :unsigned-long)
251   (packet-length :unsigned-long)
252   (status mysql-status)
253   (fields (:struct-pointer mysql-field))
254   (field-alloc (:struct mysql-mem-root))
255   (free-me mysql-bool)
256   (reconnect mysql-bool)
257   (options (:struct mysql-options))
258   (scramble-buff (:array :char 9))
259   (charset :pointer-void)
260   (server-language :unsigned-int))
261
262
263 ;;; MYSQL-RES
264 (uffi:def-struct mysql-mysql-res
265     (row-count-high32 :unsigned-long)
266   (row-count-low32 :unsigned-long)
267   (field-count :unsigned-int)
268   (current-field :unsigned-int)
269   (fields (:struct-pointer mysql-field))
270   (data (:struct-pointer mysql-data))
271   (data-cursor (:struct-pointer mysql-rows))
272   (field-alloc (:struct mysql-mem-root))
273   (row mysql-row)
274   (current-row mysql-row)
275   (lengths (* :unsigned-long))
276   (handle (:struct-pointer mysql-mysql))
277   (eof mysql-bool))
278
279 #+(or mysql-client-v4.1 mysql-client-v5)
280 (uffi:def-enum mysql-field-types
281     (:ready
282      :get-result
283      :use-result))
284
285 #+(or mysql-client-v4.1 mysql-client-v5)
286 (uffi:def-struct mysql-bind
287     (length (* :unsigned-long))
288   (is-null (* mysql-bool))
289   (buffer :pointer-void)
290   (buffer-type :int)
291   (buffer-length :unsigned-long)
292   ;; internal use
293   (inter_buffer (* :unsigned-char))
294   (offset :unsigned-long)
295   (internal-length :unsigned-long)
296   (param-number :unsigned-int)
297   (pack-length :unsigned-int)
298   (is-signed mysql-bool)
299   (long-data-used mysql-bool)
300   (internal-is-null mysql-bool)
301   (store-param-func :pointer-void)
302   (fetch-result :pointer-void)
303   (skip-result :pointer-void))
304
305 ;;;; The Foreign C routines
306 (declaim (inline mysql-init))
307 (uffi:def-function "mysql_init"
308   ((mysql (* mysql-mysql)))
309   :module "mysql"
310   :returning (* mysql-mysql))
311
312 #-mysql-client-v4
313 (declaim (inline mysql-connect))
314 #-mysql-client-v4
315 (uffi:def-function "mysql_connect"
316     ((mysql (* mysql-mysql))
317      (host :cstring)
318      (user :cstring)
319      (passwd :cstring))
320   :module "mysql"
321   :returning (* mysql-mysql))
322
323 ;; Need to comment this out for LW 4.2.6
324 ;; ? bug in LW version
325 #-lispworks (declaim (inline mysql-real-connect))
326 (uffi:def-function "mysql_real_connect"
327     ((mysql (* mysql-mysql))
328      (host :cstring)
329      (user :cstring)
330      (passwd :cstring)
331      (db :cstring)
332      (port :unsigned-int)
333      (unix-socket :cstring)
334      (clientflag :unsigned-long))
335   :module "mysql"
336   :returning (* mysql-mysql))
337
338 (declaim (inline mysql-close))
339 (uffi:def-function "mysql_close"
340     ((sock (* mysql-mysql)))
341   :module "mysql"
342   :returning :void)
343
344 (declaim (inline mysql-select-db))
345 (uffi:def-function "mysql_select_db"
346   ((mysql (* mysql-mysql))
347    (db :cstring))
348   :module "mysql"
349   :returning :int)
350
351 (declaim (inline mysql-query))
352 (uffi:def-function "mysql_query"
353     ((mysql (* mysql-mysql))
354      (query :cstring))
355   :module "mysql"
356   :returning :int)
357
358  ;;; I doubt that this function is really useful for direct Lisp usage,
359 ;;; but it is here for completeness...
360
361 (declaim (inline mysql-real-query))
362 (uffi:def-function "mysql_real_query"
363     ((mysql (* mysql-mysql))
364      (query :cstring)
365      (length :unsigned-int))
366   :module "mysql"
367   :returning :int)
368
369 #-mysql-client-v4
370 (declaim (inline mysql-create-db))
371 #-mysql-client-v4
372 (uffi:def-function "mysql_create_db"
373   ((mysql (* mysql-mysql))
374    (db :cstring))
375   :module "mysql"
376   :returning :int)
377
378 #-mysql-client-v4
379 (declaim (inline mysql-drop-db))
380 #-mysql-client-v4
381 (uffi:def-function "mysql_drop_db"
382     ((mysql (* mysql-mysql))
383      (db :cstring))
384   :module "mysql"
385   :returning :int)
386
387 (declaim (inline mysql-shutdown))
388 (uffi:def-function "mysql_shutdown"
389   ((mysql (* mysql-mysql)))
390   :module "mysql"
391   :returning :int)
392
393 (declaim (inline mysql-dump-debug-info))
394 (uffi:def-function "mysql_dump_debug_info"
395   ((mysql (* mysql-mysql)))
396   :module "mysql"
397   :returning :int)
398
399 (declaim (inline mysql-refresh))
400 (uffi:def-function "mysql_refresh"
401   ((mysql (* mysql-mysql))
402    (refresh-options :unsigned-int))
403   :module "mysql"
404   :returning :int)
405
406 (declaim (inline mysql-kill))
407 (uffi:def-function "mysql_kill"
408     ((mysql (* mysql-mysql))
409      (pid :unsigned-long))
410   :module "mysql"
411   :returning :int)
412
413 (declaim (inline mysql-ping))
414 (uffi:def-function "mysql_ping"
415     ((mysql (* mysql-mysql)))
416   :module "mysql"
417   :returning :int)
418
419 (declaim (inline mysql-stat))
420 (uffi:def-function "mysql_stat"
421   ((mysql (* mysql-mysql)))
422   :module "mysql"
423   :returning :cstring)
424
425 (declaim (inline mysql-get-server-info))
426 (uffi:def-function "mysql_get_server_info"
427     ((mysql (* mysql-mysql)))
428   :module "mysql"
429   :returning :cstring)
430
431 (declaim (inline mysql-get-host-info))
432 (uffi:def-function "mysql_get_host_info"
433     ((mysql (* mysql-mysql)))
434   :module "mysql"
435   :returning :cstring)
436
437 (declaim (inline mysql-get-proto-info))
438 (uffi:def-function "mysql_get_proto_info"
439   ((mysql (* mysql-mysql)))
440   :module "mysql"
441   :returning :unsigned-int)
442
443 (declaim (inline mysql-list-dbs))
444 (uffi:def-function "mysql_list_dbs"
445   ((mysql (* mysql-mysql))
446    (wild :cstring))
447   :module "mysql"
448   :returning (* mysql-mysql-res))
449
450 (declaim (inline mysql-list-tables))
451 (uffi:def-function "mysql_list_tables"
452   ((mysql (* mysql-mysql))
453    (wild :cstring))
454   :module "mysql"
455   :returning (* mysql-mysql-res))
456
457 (declaim (inline mysql-list-fields))
458 (uffi:def-function "mysql_list_fields"
459   ((mysql (* mysql-mysql))
460    (table :cstring)
461    (wild :cstring))
462   :module "mysql"
463   :returning (* mysql-mysql-res))
464
465 (declaim (inline mysql-list-processes))
466 (uffi:def-function "mysql_list_processes"
467   ((mysql (* mysql-mysql)))
468   :module "mysql"
469   :returning (* mysql-mysql-res))
470
471 (declaim (inline mysql-store-result))
472 (uffi:def-function "mysql_store_result"
473   ((mysql (* mysql-mysql)))
474   :module "mysql"
475   :returning (* mysql-mysql-res))
476
477 (declaim (inline mysql-use-result))
478 (uffi:def-function "mysql_use_result"
479   ((mysql (* mysql-mysql)))
480   :module "mysql"
481   :returning (* mysql-mysql-res))
482
483 (declaim (inline mysql-options))
484 (uffi:def-function "mysql_options"
485   ((mysql (* mysql-mysql))
486    (option mysql-option)
487    (arg :cstring))
488   :module "mysql"
489   :returning :int)
490
491 (declaim (inline mysql-free-result))
492 (uffi:def-function "mysql_free_result"
493     ((res (* mysql-mysql-res)))
494   :module "mysql"
495   :returning :void)
496
497 (declaim (inline mysql-row-seek))
498 (uffi:def-function "mysql_row_seek"
499   ((res (* mysql-mysql-res))
500    (offset mysql-row-offset))
501   :module "mysql"
502   :returning mysql-row-offset)
503
504 (declaim (inline mysql-field-seek))
505 (uffi:def-function "mysql_field_seek"
506   ((res (* mysql-mysql-res))
507   (offset mysql-field-offset))
508   :module "mysql"
509   :returning mysql-field-offset)
510
511 (declaim (inline mysql-fetch-row))
512 (uffi:def-function "mysql_fetch_row"
513     ((res (* mysql-mysql-res)))
514   :module "mysql"
515   :returning (* (* :unsigned-char)))
516
517 (declaim (inline mysql-fetch-lengths))
518 (uffi:def-function "mysql_fetch_lengths"
519   ((res (* mysql-mysql-res)))
520   :module "mysql"
521   :returning (* :unsigned-long))
522
523 (declaim (inline mysql-fetch-field))
524 (uffi:def-function "mysql_fetch_field"
525   ((res (* mysql-mysql-res)))
526   :module "mysql"
527   :returning (* mysql-field))
528
529 (declaim (inline mysql-fetch-fields))
530 (uffi:def-function "mysql_fetch_fields"
531   ((res (* mysql-mysql-res)))
532   :module "mysql"
533   :returning (* mysql-field))
534
535 (declaim (inline mysql-fetch-field-direct))
536 (uffi:def-function "mysql_fetch_field_direct"
537   ((res (* mysql-mysql-res))
538    (field-num :unsigned-int))
539   :module "mysql"
540   :returning (* mysql-field))
541
542 (declaim (inline mysql-escape-string))
543 (uffi:def-function "mysql_escape_string"
544     ((to (* :unsigned-char))
545      (from (* :unsigned-char))
546      (length :unsigned-int))
547   :module "mysql"
548   :returning :unsigned-int)
549
550 (declaim (inline mysql-debug))
551 (uffi:def-function "mysql_debug"
552     ((debug :cstring))
553   :module "mysql"
554   :returning :void)
555
556 (declaim (inline clsql-mysql-num-rows))
557 (uffi:def-function "clsql_mysql_num_rows"
558     ((res (* mysql-mysql-res))
559      (p-high32 (* :unsigned-int)))
560   :module "clsql-mysql"
561   :returning :unsigned-int)
562
563 #+(or mysql-client-v4.1 mysql-client-v5)
564 (uffi:def-foreign-type mysql-stmt-ptr :pointer-void)
565
566 #+(or mysql-client-v4.1 mysql-client-v5)
567 (uffi:def-function "mysql_stmt_init"
568     ((res (* mysql-mysql-res)))
569   :module "clsql-mysql"
570   :returning mysql-stmt-ptr)
571
572 #+(or mysql-client-v4.1 mysql-client-v5)
573 (uffi:def-function "mysql_stmt_prepare"
574     ((stmt mysql-stmt-ptr)
575      (query :cstring)
576      (length :unsigned-long))
577   :module "clsql-mysql"
578   :returning :int)
579
580 #+(or mysql-client-v4.1 mysql-client-v5)
581 (uffi:def-function "mysql_stmt_param_count"
582     ((stmt mysql-stmt-ptr))
583   :module "clsql-mysql"
584   :returning :unsigned-int)
585
586 #+(or mysql-client-v4.1 mysql-client-v5)
587 (uffi:def-function "mysql_stmt_bind_param"
588     ((stmt mysql-stmt-ptr)
589      (bind (* mysql-bind)))
590   :module "clsql-mysql"
591   :returning :short)
592
593 #+(or mysql-client-v4.1 mysql-client-v5)
594 (uffi:def-function "mysql_stmt_bind_result"
595     ((stmt mysql-stmt-ptr)
596      (bind (* mysql-bind)))
597   :module "clsql-mysql"
598   :returning :short)
599
600 #+(or mysql-client-v4.1 mysql-client-v5)
601 (uffi:def-function "mysql_stmt_result_metadata"
602     ((stmt mysql-stmt-ptr))
603   :module "clsql-mysql"
604   :returning (* mysql-mysql-res))
605
606
607 #+(or mysql-client-v4.1 mysql-client-v5)
608 (uffi:def-function "mysql_stmt_execute"
609     ((stmt mysql-stmt-ptr))
610   :module "clsql-mysql"
611   :returning :int)
612
613 #+(or mysql-client-v4.1 mysql-client-v5)
614 (uffi:def-function "mysql_stmt_store_result"
615     ((stmt mysql-stmt-ptr))
616   :module "clsql-mysql"
617   :returning :int)
618
619 #+(or mysql-client-v4.1 mysql-client-v5)
620 (uffi:def-function "mysql_stmt_fetch"
621     ((stmt mysql-stmt-ptr))
622   :module "clsql-mysql"
623   :returning :int)
624
625 #+(or mysql-client-v4.1 mysql-client-v5)
626 (uffi:def-function "mysql_stmt_free_result"
627     ((stmt mysql-stmt-ptr))
628   :module "clsql-mysql"
629   :returning :short)
630
631 #+(or mysql-client-v4.1 mysql-client-v5)
632 (uffi:def-function "mysql_stmt_close"
633     ((stmt mysql-stmt-ptr))
634   :module "clsql-mysql"
635   :returning :short)
636
637 #+(or mysql-client-v4.1 mysql-client-v5)
638 (uffi:def-function "mysql_stmt_errno"
639     ((stmt mysql-stmt-ptr))
640   :module "clsql-mysql"
641   :returning :unsigned-int)
642
643 #+(or mysql-client-v4.1 mysql-client-v5)
644 (uffi:def-function "mysql_stmt_error"
645     ((stmt mysql-stmt-ptr))
646   :module "clsql-mysql"
647   :returning :cstring)
648
649
650 ;;;; Equivalents of C Macro definitions for accessing various fields
651 ;;;; in the internal MySQL Datastructures
652
653
654 (declaim (inline mysql-num-rows))
655 (defun mysql-num-rows (res)
656   (uffi:with-foreign-object (p-high32 :unsigned-int)
657     (let ((low32 (clsql-mysql-num-rows res p-high32))
658           (high32 (uffi:deref-pointer p-high32 :unsigned-int)))
659       (if (zerop high32)
660           low32
661         (make-64-bit-integer high32 low32)))))
662
663 (uffi:def-function "clsql_mysql_affected_rows"
664     ((mysql (* mysql-mysql))
665      (p-high32 (* :unsigned-int)))
666   :returning :unsigned-int
667   :module "clsql-mysql")
668
669 (defun mysql-affected-rows (mysql)
670   (uffi:with-foreign-object (p-high32 :unsigned-int)
671     (let ((low32 (clsql-mysql-affected-rows mysql p-high32))
672           (high32 (uffi:deref-pointer p-high32 :unsigned-int)))
673       (if (zerop high32)
674           low32
675         (make-64-bit-integer high32 low32)))))
676
677 (uffi:def-function "clsql_mysql_insert_id"
678     ((res (* mysql-mysql))
679      (p-high32 (* :unsigned-int)))
680   :returning :unsigned-int
681   :module "clsql-mysql")
682
683 (defun mysql-insert-id (mysql)
684   (uffi:with-foreign-object (p-high32 :unsigned-int)
685   (let ((low32 (clsql-mysql-insert-id mysql p-high32))
686         (high32 (uffi:deref-pointer p-high32 :unsigned-int)))
687     (if (zerop high32)
688         low32
689       (make-64-bit-integer high32 low32)))))
690
691
692 (declaim (inline mysql-num-fields))
693 (uffi:def-function "mysql_num_fields"
694   ((res (* mysql-mysql-res)))
695   :returning :unsigned-int
696   :module "mysql")
697
698 (declaim (inline clsql-mysql-eof))
699 (uffi:def-function ("mysql_eof" clsql-mysql-eof)
700   ((res (* mysql-mysql-res)))
701   :returning :char
702   :module "mysql")
703
704 (declaim (inline mysql-eof))
705 (defun mysql-eof (res)
706   (if (zerop (clsql-mysql-eof res))
707       nil
708     t))
709
710 (declaim (inline mysql-error))
711 (uffi:def-function ("mysql_error" mysql-error)
712   ((mysql (* mysql-mysql)))
713   :returning :cstring
714   :module "mysql")
715
716 (declaim (inline mysql-error-string))
717 (defun mysql-error-string (mysql)
718   (uffi:convert-from-cstring (mysql-error mysql)))
719
720 (declaim (inline mysql-errno))
721 (uffi:def-function "mysql_errno"
722   ((mysql (* mysql-mysql)))
723   :returning :unsigned-int
724   :module "mysql")
725
726 (declaim (inline mysql-info))
727 (uffi:def-function ("mysql_info" mysql-info)
728   ((mysql (* mysql-mysql)))
729   :returning :cstring
730   :module "mysql")
731
732 (declaim (inline mysql-info-string))
733 (defun mysql-info-string (mysql)
734   (uffi:convert-from-cstring (mysql-info mysql)))
735
736 (declaim (inline clsql-mysql-data-seek))
737 (uffi:def-function "clsql_mysql_data_seek"
738   ((res (* mysql-mysql-res))
739    (offset-high32 :unsigned-int)
740    (offset-low32 :unsigned-int))
741   :module "clsql-mysql"
742   :returning :void)
743
744 (defun mysql-data-seek (res offset)
745   (multiple-value-bind (high32 low32) (split-64-bit-integer offset)
746     (clsql-mysql-data-seek res high32 low32)))