X-Git-Url: http://git.kpe.io/?a=blobdiff_plain;f=interfaces%2Fpostgresql-socket%2Fpostgresql-socket-api.cl;h=23d391b912c90f4748ece84534241b0a15b3a170;hb=210a13e0da4ddd46ef23d9bca1bb77da98fa4487;hp=e8706805e9236c1f6b7584586af442c0c08ad0b1;hpb=9d53eaaae02609b0d7076be0853ff0f0ab06b644;p=clsql.git diff --git a/interfaces/postgresql-socket/postgresql-socket-api.cl b/interfaces/postgresql-socket/postgresql-socket-api.cl index e870680..23d391b 100644 --- a/interfaces/postgresql-socket/postgresql-socket-api.cl +++ b/interfaces/postgresql-socket/postgresql-socket-api.cl @@ -9,7 +9,7 @@ ;;;; ;;;; Date Started: Feb 2002 ;;;; -;;;; $Id: postgresql-socket-api.cl,v 1.4 2002/03/25 23:30:49 kevin Exp $ +;;;; $Id: postgresql-socket-api.cl,v 1.6 2002/03/26 14:12:12 kevin Exp $ ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg ;;;; and Copyright (c) 1999-2001 by Pierre R. Mai @@ -208,7 +208,8 @@ socket interface" (defun read-socket-sequence (string stream) "KMR -- Added to support reading from binary stream into a string" - (declare (optimize (speed 3) (safety 0))) + (declare (optimize (speed 3) (safety 0)) + (string string)) (dotimes (i (length string)) (declare (fixnum i)) (setf (char string i) (code-char (read-byte stream)))) @@ -563,20 +564,103 @@ connection, if it is still open." do (setf (aref result index) (ldb (byte 1 weight) byte)))) result)) + (defun read-field (socket type) - (let* ((length (read-socket-value 'int32 socket)) - (result (make-string (- length 4)))) - (read-socket-sequence result socket) + (let* ((length (- (read-socket-value 'int32 socket) 4))) (case type (:int - (parse-integer result)) + (read-integer-from-socket socket length)) (:double - (let ((*read-default-float-format* 'double-float)) - (read-from-string result))) + (read-double-from-socket socket length)) (t - result)))) + (let ((result (make-string length))) + (read-socket-sequence result socket) + result))))) + +(uffi:def-constant +char-code-zero+ (char-code #\0)) +(uffi:def-constant +char-code-minus+ (char-code #\-)) +(uffi:def-constant +char-code-plus+ (char-code #\+)) +(uffi:def-constant +char-code-period+ (char-code #\.)) + +(defun read-integer-from-socket (socket length) + (let ((val 0) + (first-char (read-byte socket)) + (minusp nil)) + (declare (fixnum first-char)) + (if (eql first-char +char-code-minus+) + (setq minusp t) + (setq val (- first-char +char-code-zero+))) + (dotimes (i (1- length)) + (declare (fixnum i)) + (setq val (+ + (* 10 val) + (- (read-byte socket) +char-code-zero+)))) + (if minusp + (- 0 val) + val))) + +(defmacro ascii-digit (int) + (let ((offset (gensym))) + `(let ((,offset (- ,int +char-code-zero+))) + (declare (fixnum ,int ,offset)) + (if (and (plusp ,offset) + (< ,offset 10)) + ,offset + nil)))) + +#+ignore +(defun read-double-from-socket (socket length) + (let ((before-decimal 0) + (after-decimal 0) + (decimal-count 0) + (exponent 0) + (char (read-byte socket)) + (decimalp nil) + (minusp nil)) + (declare (fixnum first-char)) + (cond + ((eql char +char-code-minus+) + (setq minusp t) + (setq char (read-byte socket)) + (decf length)) + ((eql char +char-code-plus+) + (setq char (read-byte socket)) + (decf length))) + + (dotimes (i (1- length)) + (let ((weight (ascii-digit char))) + (cond + ((and weight (not decimalp)) ;; before decimal point + (setq before-decimal (+ weight (* 10 before-decimal)))) + ((and weight decimalp) ;; after decimal point + (setq after-decimal (+ weight (* 10 after-decimal))) + (incf decimal-count)) + ((and (eql char +char-code-period+) decimalp) + (setq decimalp t)) + ((or (eql char +char-code-e+) ;; E is for exponent + (eql char +char-code-upper-e+)) + (multiple-value-bind (num idx) + (parse-integer string :start (1+ index) :end end + :radix radix :junk-allowed junk-allowed) + (setq exponent (or num 0) + index idx) + (when (= index end) (return nil)))) + ) + (setq char (read-byte socket)))) + + + + + )) + + +(defun read-double-from-socket (socket length) + (let ((result (make-string length))) + (read-socket-sequence result socket) + (let ((*read-default-float-format* 'double-float)) + (read-from-string result)))) -(defun read-cursor-row (cursor field-types) +(defun read-cursor-row (cursor types) (let* ((connection (postgresql-cursor-connection cursor)) (socket (postgresql-connection-socket connection)) (fields (postgresql-cursor-fields cursor))) @@ -596,7 +680,7 @@ connection, if it is still open." collect nil else collect - (read-field socket (nth i field-types))))) + (read-field socket (nth i types))))) (#.+binary-row-message+ (error "NYI")) (#.+completed-response-message+ @@ -627,7 +711,7 @@ connection, if it is still open." (funcall func (elt seq i) i))) result-seq) -(defun copy-cursor-row (cursor sequence field-types) +(defun copy-cursor-row (cursor sequence types) (let* ((connection (postgresql-cursor-connection cursor)) (socket (postgresql-connection-socket connection)) (fields (postgresql-cursor-fields cursor))) @@ -644,14 +728,14 @@ connection, if it is still open." (declare (fixnum i)) (if (zerop (elt null-vector i)) (setf (elt sequence i) nil) - (let ((value (read-field socket (nth i field-types)))) + (let ((value (read-field socket (nth i types)))) (setf (elt sequence i) value))))) (map-into-indexed sequence #'(lambda (null-bit i) (if (zerop null-bit) nil - (read-field socket (nth i field-types)))) + (read-field socket (nth i types)))) (read-null-bit-vector socket (length sequence))))) (#.+binary-row-message+ (error "NYI")) @@ -714,12 +798,12 @@ connection, if it is still open." (error 'postgresql-fatal-error :connection connection :message "Received garbled message from backend"))))))) -(defun run-query (connection query &optional (field-types nil)) +(defun run-query (connection query &optional (types nil)) (start-query-execution connection query) (multiple-value-bind (status cursor) (wait-for-query-results connection) (assert (eq status :cursor)) - (loop for row = (read-cursor-row cursor field-types) + (loop for row = (read-cursor-row cursor types) while row collect row finally