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