;;;; *************************************************************************
;;;; FILE IDENTIFICATION
;;;;
-;;;; Name: mysql.cl
+;;;; 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.1 2002/09/30 10:19:23 kevin Exp $
+;;;; $Id$
;;;;
;;;; This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg
;;;; and Copyright (c) 1999-2001 by Pierre R. Mai
;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL.
;;;; *************************************************************************
-(declaim (optimize (debug 3) (speed 3) (safety 1) (compilation-speed 0)))
-
-(in-package :mysql)
+(in-package #:mysql)
;;;; Modifications from original code
;;;; - Updated C-structures to conform to structures in MySQL 3.23.46
;;;; 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
(:long-blob 251)
(:blob 252)
(:var-string 253)
- (:string 254)))
-
+ (:string 254)
+ (:geometry 255)))
+
+#+mysql-client-v3
(uffi:def-struct mysql-field
(name (* :char))
(table (* :char))
(flags :unsigned-int)
(decimals :unsigned-int))
+;; structure changed in mysql 4 client
+#+(and mysql-client-v4 (not mysql-client-v4.1))
+(uffi:def-struct mysql-field
+ (name (* :char))
+ (table (* :char))
+ (org_table (* :char))
+ (db (* :char))
+ (def (* :char))
+ (length :unsigned-long)
+ (max-length :unsigned-long)
+ (flags :unsigned-int)
+ (decimals :unsigned-int)
+ (type mysql-field-types))
+
+#+(or mysql-client-v4.1 mysql-client-v5)
+(uffi:def-struct mysql-field
+ (name (* :char))
+ (org_name (* :char))
+ (table (* :char))
+ (org_table (* :char))
+ (db (* :char))
+ (catalog_db (* :char))
+ (def (* :char))
+ (length :unsigned-long)
+ (max-length :unsigned-long)
+ (name-length :unsigned-int)
+ (org-name-length :unsigned-int)
+ (table-length :unsigned-int)
+ (org-table-length :unsigned-int)
+ (db-length :unsigned-int)
+ (catalog-length :unsigned-int)
+ (def-length :unsigned-int)
+ (flags :unsigned-int)
+ (decimals :unsigned-int)
+ (charsetnr :unsigned-int)
+ (type mysql-field-types))
+
+
+(uffi:def-struct mysql-time
+ (year :unsigned-int)
+ (month :unsigned-int)
+ (day :unsigned-int)
+ (hour :unsigned-int)
+ (minute :unsigned-int)
+ (second :unsigned-int)
+ (second-part :unsigned-long)
+ (neg mysql-bool)
+ (time-type :int))
+
;;; MYSQL-ROWS
(uffi:def-array-pointer mysql-row (* :unsigned-char))
:read-default-group))
(uffi:def-enum mysql-status
- (:ready
+ (:ready
:get-result
:use-result))
(handle (:struct-pointer mysql-mysql))
(eof mysql-bool))
+#+(or mysql-client-v4.1 mysql-client-v5)
+(uffi:def-enum mysql-field-types
+ (:ready
+ :get-result
+ :use-result))
+
+#+(or mysql-client-v4.1 mysql-client-v5)
+(uffi:def-struct mysql-bind
+ (length (* :unsigned-long))
+ (is-null (* mysql-bool))
+ (buffer :pointer-void)
+ (buffer-type :int)
+ (buffer-length :unsigned-long)
+ ;; internal use
+ (inter_buffer (* :unsigned-char))
+ (offset :unsigned-long)
+ (internal-length :unsigned-long)
+ (param-number :unsigned-int)
+ (pack-length :unsigned-int)
+ (is-signed mysql-bool)
+ (long-data-used mysql-bool)
+ (internal-is-null mysql-bool)
+ (store-param-func :pointer-void)
+ (fetch-result :pointer-void)
+ (skip-result :pointer-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))
:module "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))
(host :cstring)
(db :cstring)
(port :unsigned-int)
(unix-socket :cstring)
- (clientflag :unsigned-int))
+ (clientflag :unsigned-long))
:module "mysql"
:returning (* mysql-mysql))
: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)))
:module "mysql"
:returning :cstring)
-(declaim (inline mysql-get-client-info))
-(uffi:def-function "mysql_get_client_info"
- ()
- :module "mysql"
- :returning :cstring)
-
(declaim (inline mysql-get-host-info))
(uffi:def-function "mysql_get_host_info"
((mysql (* mysql-mysql)))
(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)
: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
(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))
(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))
(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"
+(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)))
:module "clsql-mysql"
:returning :void)
-
(defun mysql-data-seek (res offset)
(multiple-value-bind (high32 low32) (split-64-bit-integer offset)
(clsql-mysql-data-seek res high32 low32)))