X-Git-Url: http://git.kpe.io/?p=clsql.git;a=blobdiff_plain;f=db-mysql%2Fmysql-api.lisp;h=91fc3c5a6998807f31520f94bee61b0f7a2b8aea;hp=cff8da4a98dd9a175d8c6eac7c6ab2689f30b027;hb=e7a577db720298ca6152c2da92f4aed647ee43c8;hpb=f890314907bc4add4b0f24ad6883da9838a056b7 diff --git a/db-mysql/mysql-api.lisp b/db-mysql/mysql-api.lisp index cff8da4..91fc3c5 100644 --- a/db-mysql/mysql-api.lisp +++ b/db-mysql/mysql-api.lisp @@ -4,13 +4,11 @@ ;;;; ;;;; Name: mysql-api.lisp ;;;; Purpose: Low-level MySQL interface using UFFI -;;;; Programmers: Kevin M. Rosenberg based on -;;;; Original code by Pierre R. Mai +;;;; Programmers: Kevin M. Rosenberg based on +;;;; Original code by Pierre R. Mai ;;;; Date Started: Feb 2002 ;;;; -;;;; $Id: mysql-api.lisp,v 1.6 2003/07/21 01:45:45 kevin Exp $ -;;;; -;;;; This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg +;;;; This file, part of CLSQL, is Copyright (c) 2002-2009 by Kevin M. Rosenberg ;;;; and Copyright (c) 1999-2001 by Pierre R. Mai ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software @@ -27,13 +25,13 @@ ;;;; that are used in a few routines. ;;;; - Removed all references to interiors of C-structions, this will ;;;; increase robustness when MySQL's internal structures change. - + ;;;; Type definitions ;;; Basic Types (uffi:def-foreign-type mysql-socket :int) -(uffi:def-foreign-type mysql-bool :char) +(uffi:def-foreign-type mysql-bool :byte) (uffi:def-foreign-type mysql-byte :unsigned-char) (uffi:def-enum mysql-net-type @@ -41,44 +39,7 @@ :socket :named-pipe)) -(uffi:def-struct mysql-net - (vio :pointer-void) - (fd mysql-socket) - (fcntl :int) - (buff (* :unsigned-char)) - (buff-end (* :unsigned-char)) - (write-pos (* :unsigned-char)) - (read-pos (* :unsigned-char)) - (last-error (:array :char 200)) - (last-errno :unsigned-int) - (max-packet :unsigned-int) - (timeout :unsigned-int) - (pkt-nr :unsigned-int) - (error mysql-bool) - (return-errno mysql-bool) - (compress mysql-bool) - (no-send-ok mysql-bool) - (remain-in-buf :unsigned-long) - (length :unsigned-long) - (buf-length :unsigned-long) - (where-b :unsigned-long) - (return-status (* :unsigned-int)) - (reading-or-writing :unsigned-char) - (save-char :char)) - -;;; Mem-Root -(uffi:def-struct mysql-used-mem - (next :pointer-self) - (left :unsigned-int) - (size :unsigned-int)) - -(uffi:def-struct mysql-mem-root - (free (:struct-pointer mysql-used-mem)) - (used (:struct-pointer mysql-used-mem)) - (pre-alloc (:struct-pointer mysql-used-mem)) - (min-alloc :unsigned-int) - (block-size :unsigned-int) - (error-handler :pointer-void)) +(uffi:def-array-pointer mysql-row (* :unsigned-char)) ;;; MYSQL-FIELD (uffi:def-enum mysql-field-types @@ -104,80 +65,8 @@ (:long-blob 251) (:blob 252) (:var-string 253) - (:string 254))) - -#-(or mysql-client-v3 mysql-client-v4) -(eval-when (:compile-toplevel :load-toplevel :execute) - (pushnew :mysql-client-v3 cl:*features*)) - -#+mysql-client-v3 -(uffi:def-struct mysql-field - (name (* :char)) - (table (* :char)) - (def (* :char)) - (type mysql-field-types) - (length :unsigned-int) - (max-length :unsigned-int) - (flags :unsigned-int) - (decimals :unsigned-int)) - -;; structure changed in mysql 4 client -#+mysql-client-v4 -(uffi:def-struct mysql-field - (name (* :char)) - (table (* :char)) - (org_table (* :char)) - (db (* :char)) - (def (* :char)) - (length :unsigned-int) - (max-length :unsigned-int) - (flags :unsigned-int) - (decimals :unsigned-int) - (type mysql-field-types)) - -;;; MYSQL-ROWS - -(uffi:def-array-pointer mysql-row (* :unsigned-char)) - -(uffi:def-array-pointer mysql-field-vector (* mysql-field)) - -(uffi:def-foreign-type mysql-field-offset :unsigned-int) - -(uffi:def-struct mysql-rows - (next :pointer-self) - (data mysql-row)) - -(uffi:def-foreign-type mysql-row-offset (:struct-pointer mysql-rows)) - -(uffi:def-struct mysql-data - (rows-high32 :unsigned-long) - (rows-low32 :unsigned-long) - (fields :unsigned-int) - (data (:struct-pointer mysql-rows)) - (alloc (:struct mysql-mem-root))) - -;;; MYSQL -(uffi:def-struct mysql-options - (connect-timeout :unsigned-int) - (client-flag :unsigned-int) - (compress mysql-bool) - (named-pipe mysql-bool) - (port :unsigned-int) - (host (* :char)) - (init-command (* :char)) - (user (* :char)) - (password (* :char)) - (unix-socket (* :char)) - (db (* :char)) - (my-cnf-file (* :char)) - (my-cnf-group (* :char)) - (charset-dir (* :char)) - (charset-name (* :char)) - (use-ssl mysql-bool) - (ssl-key (* :char)) - (ssl-cert (* :char)) - (ssl-ca (* :char)) - (ssl-capath (* :char))) + (:string 254) + (:geometry 255))) (uffi:def-enum mysql-option (:connect-timeout @@ -188,109 +77,60 @@ :read-default-group)) (uffi:def-enum mysql-status - (:ready + (:ready + :get-result + :use-result)) + +#+(or mysql-client-v4.1 mysql-client-v5) +(uffi:def-enum mysql-field-types + (:ready :get-result :use-result)) -(uffi:def-struct mysql-mysql - (net (:struct mysql-net)) - (connected-fd (* :char)) - (host (* :char)) - (user (* :char)) - (passwd (* :char)) - (unix-socket (* :char)) - (server-version (* :char)) - (host-info (* :char)) - (info (* :char)) - (db (* :char)) - (port :unsigned-int) - (client-flag :unsigned-int) - (server-capabilities :unsigned-int) - (protocol-version :unsigned-int) - (field-count :unsigned-int) - (server-status :unsigned-int) - (thread-id :unsigned-long) - (affected-rows-high32 :unsigned-long) - (affected-rows-low32 :unsigned-long) - (insert-id-high32 :unsigned-long) - (insert-id-low32 :unsigned-long) - (extra-info-high32 :unsigned-long) - (extra-info-low32 :unsigned-long) - (packet-length :unsigned-long) - (status mysql-status) - (fields (:struct-pointer mysql-field)) - (field-alloc (:struct mysql-mem-root)) - (free-me mysql-bool) - (reconnect mysql-bool) - (options (:struct mysql-options)) - (scramble-buff (:array :char 9)) - (charset :pointer-void) - (server-language :unsigned-int)) - - -;;; MYSQL-RES -(uffi:def-struct mysql-mysql-res - (row-count-high32 :unsigned-long) - (row-count-low32 :unsigned-long) - (field-count :unsigned-int) - (current-field :unsigned-int) - (fields (:struct-pointer mysql-field)) - (data (:struct-pointer mysql-data)) - (data-cursor (:struct-pointer mysql-rows)) - (field-alloc (:struct mysql-mem-root)) - (row mysql-row) - (current-row mysql-row) - (lengths (* :unsigned-long)) - (handle (:struct-pointer mysql-mysql)) - (eof mysql-bool)) +;;; Opaque pointers to mysql C-defined structures +(uffi:def-foreign-type mysql-mysql (* :void)) +(uffi:def-foreign-type mysql-mysql-res (* :void)) +(uffi:def-foreign-type mysql-field (* :void)) +(uffi:def-foreign-type mysql-bind (* :void)) ;;;; The Foreign C routines (declaim (inline mysql-init)) (uffi:def-function "mysql_init" - ((mysql (* mysql-mysql))) - :module "mysql" - :returning (* mysql-mysql)) - -(declaim (inline mysql-connect)) -(uffi:def-function "mysql_connect" - ((mysql (* mysql-mysql)) - (host :cstring) - (user :cstring) - (passwd :cstring)) + ((mysql mysql-mysql)) :module "mysql" - :returning (* mysql-mysql)) + :returning mysql-mysql) ;; Need to comment this out for LW 4.2.6 ;; ? bug in LW version -;;(declaim (inline mysql-real-connect)) +#-lispworks (declaim (inline mysql-real-connect)) (uffi:def-function "mysql_real_connect" - ((mysql (* mysql-mysql)) + ((mysql mysql-mysql) (host :cstring) (user :cstring) (passwd :cstring) (db :cstring) (port :unsigned-int) (unix-socket :cstring) - (clientflag :unsigned-int)) + (clientflag :unsigned-long)) :module "mysql" - :returning (* mysql-mysql)) + :returning mysql-mysql) (declaim (inline mysql-close)) (uffi:def-function "mysql_close" - ((sock (* mysql-mysql))) + ((sock mysql-mysql)) :module "mysql" :returning :void) (declaim (inline mysql-select-db)) (uffi:def-function "mysql_select_db" - ((mysql (* mysql-mysql)) + ((mysql mysql-mysql) (db :cstring)) :module "mysql" :returning :int) (declaim (inline mysql-query)) (uffi:def-function "mysql_query" - ((mysql (* mysql-mysql)) + ((mysql mysql-mysql) (query :cstring)) :module "mysql" :returning :int) @@ -300,131 +140,111 @@ (declaim (inline mysql-real-query)) (uffi:def-function "mysql_real_query" - ((mysql (* mysql-mysql)) + ((mysql mysql-mysql) (query :cstring) (length :unsigned-int)) :module "mysql" :returning :int) -(declaim (inline mysql-create-db)) -(uffi:def-function "mysql_create_db" - ((mysql (* mysql-mysql)) - (db :cstring)) - :module "mysql" - :returning :int) - -(declaim (inline mysql-drop-db)) -(uffi:def-function "mysql_drop_db" - ((mysql (* mysql-mysql)) - (db :cstring)) - :module "mysql" - :returning :int) - (declaim (inline mysql-shutdown)) (uffi:def-function "mysql_shutdown" - ((mysql (* mysql-mysql))) + ((mysql mysql-mysql)) :module "mysql" :returning :int) (declaim (inline mysql-dump-debug-info)) (uffi:def-function "mysql_dump_debug_info" - ((mysql (* mysql-mysql))) + ((mysql mysql-mysql)) :module "mysql" :returning :int) (declaim (inline mysql-refresh)) (uffi:def-function "mysql_refresh" - ((mysql (* mysql-mysql)) + ((mysql mysql-mysql) (refresh-options :unsigned-int)) :module "mysql" :returning :int) (declaim (inline mysql-kill)) (uffi:def-function "mysql_kill" - ((mysql (* mysql-mysql)) + ((mysql mysql-mysql) (pid :unsigned-long)) :module "mysql" :returning :int) (declaim (inline mysql-ping)) (uffi:def-function "mysql_ping" - ((mysql (* mysql-mysql))) + ((mysql mysql-mysql)) :module "mysql" :returning :int) (declaim (inline mysql-stat)) (uffi:def-function "mysql_stat" - ((mysql (* mysql-mysql))) + ((mysql mysql-mysql)) :module "mysql" :returning :cstring) (declaim (inline mysql-get-server-info)) (uffi:def-function "mysql_get_server_info" - ((mysql (* mysql-mysql))) - :module "mysql" - :returning :cstring) - -(declaim (inline mysql-get-client-info)) -(uffi:def-function "mysql_get_client_info" - () + ((mysql mysql-mysql)) :module "mysql" :returning :cstring) (declaim (inline mysql-get-host-info)) (uffi:def-function "mysql_get_host_info" - ((mysql (* mysql-mysql))) + ((mysql mysql-mysql)) :module "mysql" :returning :cstring) (declaim (inline mysql-get-proto-info)) (uffi:def-function "mysql_get_proto_info" - ((mysql (* mysql-mysql))) + ((mysql mysql-mysql)) :module "mysql" :returning :unsigned-int) (declaim (inline mysql-list-dbs)) (uffi:def-function "mysql_list_dbs" - ((mysql (* mysql-mysql)) + ((mysql mysql-mysql) (wild :cstring)) :module "mysql" - :returning (* mysql-mysql-res)) + :returning mysql-mysql-res) (declaim (inline mysql-list-tables)) (uffi:def-function "mysql_list_tables" - ((mysql (* mysql-mysql)) + ((mysql mysql-mysql) (wild :cstring)) :module "mysql" - :returning (* mysql-mysql-res)) + :returning mysql-mysql-res) (declaim (inline mysql-list-fields)) (uffi:def-function "mysql_list_fields" - ((mysql (* mysql-mysql)) + ((mysql mysql-mysql) (table :cstring) (wild :cstring)) :module "mysql" - :returning (* mysql-mysql-res)) + :returning mysql-mysql-res) (declaim (inline mysql-list-processes)) (uffi:def-function "mysql_list_processes" - ((mysql (* mysql-mysql))) + ((mysql mysql-mysql)) :module "mysql" - :returning (* mysql-mysql-res)) + :returning mysql-mysql-res) (declaim (inline mysql-store-result)) (uffi:def-function "mysql_store_result" - ((mysql (* mysql-mysql))) + ((mysql mysql-mysql)) :module "mysql" - :returning (* mysql-mysql-res)) + :returning mysql-mysql-res) (declaim (inline mysql-use-result)) (uffi:def-function "mysql_use_result" - ((mysql (* mysql-mysql))) + ((mysql mysql-mysql)) :module "mysql" - :returning (* mysql-mysql-res)) + :returning mysql-mysql-res) (declaim (inline mysql-options)) (uffi:def-function "mysql_options" - ((mysql (* mysql-mysql)) + ((mysql mysql-mysql) (option mysql-option) (arg :cstring)) :module "mysql" @@ -432,59 +252,52 @@ (declaim (inline mysql-free-result)) (uffi:def-function "mysql_free_result" - ((res (* mysql-mysql-res))) + ((res mysql-mysql-res)) :module "mysql" :returning :void) -(declaim (inline mysql-row-seek)) -(uffi:def-function "mysql_row_seek" - ((res (* mysql-mysql-res)) - (offset mysql-row-offset)) - :module "mysql" - :returning mysql-row-offset) - -(declaim (inline mysql-field-seek)) -(uffi:def-function "mysql_field_seek" - ((res (* mysql-mysql-res)) - (offset mysql-field-offset)) - :module "mysql" - :returning mysql-field-offset) - (declaim (inline mysql-fetch-row)) (uffi:def-function "mysql_fetch_row" - ((res (* mysql-mysql-res))) + ((res mysql-mysql-res)) :module "mysql" :returning (* (* :unsigned-char))) (declaim (inline mysql-fetch-lengths)) (uffi:def-function "mysql_fetch_lengths" - ((res (* mysql-mysql-res))) + ((res mysql-mysql-res)) :module "mysql" :returning (* :unsigned-long)) (declaim (inline mysql-fetch-field)) (uffi:def-function "mysql_fetch_field" - ((res (* mysql-mysql-res))) + ((res mysql-mysql-res)) + :module "mysql" + :returning mysql-field) + +(declaim (inline mysql-field-seek)) +(uffi:def-function "mysql_field_seek" + ((res mysql-mysql-res) + (offset :unsigned-int)) :module "mysql" - :returning (* mysql-field)) + :returning :unsigned-int) (declaim (inline mysql-fetch-fields)) (uffi:def-function "mysql_fetch_fields" - ((res (* mysql-mysql-res))) + ((res mysql-mysql-res)) :module "mysql" - :returning (* mysql-field)) + :returning mysql-field) (declaim (inline mysql-fetch-field-direct)) (uffi:def-function "mysql_fetch_field_direct" - ((res (* mysql-mysql-res)) + ((res mysql-mysql-res) (field-num :unsigned-int)) :module "mysql" - :returning (* mysql-field)) + :returning mysql-field) (declaim (inline mysql-escape-string)) (uffi:def-function "mysql_escape_string" - ((to :cstring) - (from :cstring) + ((to (* :unsigned-char)) + (from (* :unsigned-char)) (length :unsigned-int)) :module "mysql" :returning :unsigned-int) @@ -497,11 +310,97 @@ (declaim (inline clsql-mysql-num-rows)) (uffi:def-function "clsql_mysql_num_rows" - ((res (* mysql-mysql-res)) + ((res mysql-mysql-res) (p-high32 (* :unsigned-int))) :module "clsql-mysql" :returning :unsigned-int) +#+(or mysql-client-v4.1 mysql-client-v5) +(uffi:def-foreign-type mysql-stmt-ptr :pointer-void) + +#+(or mysql-client-v4.1 mysql-client-v5) +(uffi:def-function "mysql_stmt_init" + ((res mysql-mysql-res)) + :module "clsql-mysql" + :returning mysql-stmt-ptr) + +#+(or mysql-client-v4.1 mysql-client-v5) +(uffi:def-function "mysql_stmt_prepare" + ((stmt mysql-stmt-ptr) + (query :cstring) + (length :unsigned-long)) + :module "clsql-mysql" + :returning :int) + +#+(or mysql-client-v4.1 mysql-client-v5) +(uffi:def-function "mysql_stmt_param_count" + ((stmt mysql-stmt-ptr)) + :module "clsql-mysql" + :returning :unsigned-int) + +#+(or mysql-client-v4.1 mysql-client-v5) +(uffi:def-function "mysql_stmt_bind_param" + ((stmt mysql-stmt-ptr) + (bind mysql-bind)) + :module "clsql-mysql" + :returning :short) + +#+(or mysql-client-v4.1 mysql-client-v5) +(uffi:def-function "mysql_stmt_bind_result" + ((stmt mysql-stmt-ptr) + (bind mysql-bind)) + :module "clsql-mysql" + :returning :short) + +#+(or mysql-client-v4.1 mysql-client-v5) +(uffi:def-function "mysql_stmt_result_metadata" + ((stmt mysql-stmt-ptr)) + :module "clsql-mysql" + :returning mysql-mysql-res) + + +#+(or mysql-client-v4.1 mysql-client-v5) +(uffi:def-function "mysql_stmt_execute" + ((stmt mysql-stmt-ptr)) + :module "clsql-mysql" + :returning :int) + +#+(or mysql-client-v4.1 mysql-client-v5) +(uffi:def-function "mysql_stmt_store_result" + ((stmt mysql-stmt-ptr)) + :module "clsql-mysql" + :returning :int) + +#+(or mysql-client-v4.1 mysql-client-v5) +(uffi:def-function "mysql_stmt_fetch" + ((stmt mysql-stmt-ptr)) + :module "clsql-mysql" + :returning :int) + +#+(or mysql-client-v4.1 mysql-client-v5) +(uffi:def-function "mysql_stmt_free_result" + ((stmt mysql-stmt-ptr)) + :module "clsql-mysql" + :returning :short) + +#+(or mysql-client-v4.1 mysql-client-v5) +(uffi:def-function "mysql_stmt_close" + ((stmt mysql-stmt-ptr)) + :module "clsql-mysql" + :returning :short) + +#+(or mysql-client-v4.1 mysql-client-v5) +(uffi:def-function "mysql_stmt_errno" + ((stmt mysql-stmt-ptr)) + :module "clsql-mysql" + :returning :unsigned-int) + +#+(or mysql-client-v4.1 mysql-client-v5) +(uffi:def-function "mysql_stmt_error" + ((stmt mysql-stmt-ptr)) + :module "clsql-mysql" + :returning :cstring) + ;;;; Equivalents of C Macro definitions for accessing various fields ;;;; in the internal MySQL Datastructures @@ -511,13 +410,13 @@ (defun mysql-num-rows (res) (uffi:with-foreign-object (p-high32 :unsigned-int) (let ((low32 (clsql-mysql-num-rows res p-high32)) - (high32 (uffi:deref-pointer p-high32 :unsigned-int))) + (high32 (uffi:deref-pointer p-high32 :unsigned-int))) (if (zerop high32) - low32 - (make-64-bit-integer high32 low32))))) + low32 + (make-64-bit-integer high32 low32))))) (uffi:def-function "clsql_mysql_affected_rows" - ((mysql (* mysql-mysql)) + ((mysql mysql-mysql) (p-high32 (* :unsigned-int))) :returning :unsigned-int :module "clsql-mysql") @@ -525,13 +424,13 @@ (defun mysql-affected-rows (mysql) (uffi:with-foreign-object (p-high32 :unsigned-int) (let ((low32 (clsql-mysql-affected-rows mysql p-high32)) - (high32 (uffi:deref-pointer p-high32 :unsigned-int))) + (high32 (uffi:deref-pointer p-high32 :unsigned-int))) (if (zerop high32) - low32 - (make-64-bit-integer high32 low32))))) + low32 + (make-64-bit-integer high32 low32))))) (uffi:def-function "clsql_mysql_insert_id" - ((res (* mysql-mysql)) + ((res mysql-mysql) (p-high32 (* :unsigned-int))) :returning :unsigned-int :module "clsql-mysql") @@ -539,21 +438,21 @@ (defun mysql-insert-id (mysql) (uffi:with-foreign-object (p-high32 :unsigned-int) (let ((low32 (clsql-mysql-insert-id mysql p-high32)) - (high32 (uffi:deref-pointer p-high32 :unsigned-int))) + (high32 (uffi:deref-pointer p-high32 :unsigned-int))) (if (zerop high32) - low32 + low32 (make-64-bit-integer high32 low32))))) (declaim (inline mysql-num-fields)) -(uffi:def-function "mysql_num_fields" - ((res (* mysql-mysql-res))) +(uffi:def-function "mysql_num_fields" + ((res mysql-mysql-res)) :returning :unsigned-int :module "mysql") - + (declaim (inline clsql-mysql-eof)) (uffi:def-function ("mysql_eof" clsql-mysql-eof) - ((res (* mysql-mysql-res))) + ((res mysql-mysql-res)) :returning :char :module "mysql") @@ -565,7 +464,7 @@ (declaim (inline mysql-error)) (uffi:def-function ("mysql_error" mysql-error) - ((mysql (* mysql-mysql))) + ((mysql mysql-mysql)) :returning :cstring :module "mysql") @@ -575,13 +474,13 @@ (declaim (inline mysql-errno)) (uffi:def-function "mysql_errno" - ((mysql (* mysql-mysql))) + ((mysql mysql-mysql)) :returning :unsigned-int :module "mysql") (declaim (inline mysql-info)) (uffi:def-function ("mysql_info" mysql-info) - ((mysql (* mysql-mysql))) + ((mysql mysql-mysql)) :returning :cstring :module "mysql") @@ -591,12 +490,29 @@ (declaim (inline clsql-mysql-data-seek)) (uffi:def-function "clsql_mysql_data_seek" - ((res (* mysql-mysql-res)) + ((res mysql-mysql-res) (offset-high32 :unsigned-int) (offset-low32 :unsigned-int)) :module "clsql-mysql" :returning :void) +(declaim (inline clsql-mysql-field-name)) +(uffi:def-function "clsql_mysql_field_name" + ((res mysql-field)) + :module "clsql-mysql" + :returning :cstring) + +(declaim (inline clsql-mysql-field-flags)) +(uffi:def-function "clsql_mysql_field_flags" + ((res mysql-field)) + :module "clsql-mysql" + :returning :unsigned-int) + +(declaim (inline clsql-mysql-field-type)) +(uffi:def-function "clsql_mysql_field_type" + ((res mysql-field)) + :module "clsql-mysql" + :returning :unsigned-int) (defun mysql-data-seek (res offset) (multiple-value-bind (high32 low32) (split-64-bit-integer offset)