[pg-cvs] CVS pg
emarsden
emarsden at common-lisp.net
Sun Oct 22 19:29:48 UTC 2006
Update of /project/pg/cvsroot/pg
In directory clnet:/tmp/cvs-serv12033
Modified Files:
parsers.lisp
Log Message:
- implement basic parsing support for the PostgreSQL record type
- supply a utility function to escape binary data into a format that
can be used within an SQL string to initialize a field of type
BYTEA
- add optimize declarations for improved performance
--- /project/pg/cvsroot/pg/parsers.lisp 2005/12/19 22:29:59 1.8
+++ /project/pg/cvsroot/pg/parsers.lisp 2006/10/22 19:29:47 1.9
@@ -36,6 +36,9 @@
;;
+(declaim (optimize (speed 3) (safety 1)))
+
+
(in-package :postgresql)
@@ -82,6 +85,10 @@
;; oidvector
;; bit
;; varbit
+ ;; record
+ ;; cstring
+ ;; any
+ ("row" . ,'row-parser)
("float4" . ,'float-parser)
("float8" . ,'float-parser)
("money" . ,'text-parser) ; "$12.34"
@@ -225,6 +232,19 @@
(day (parse-integer str :start 8 :end 10)))
(encode-universal-time 0 0 0 day month year)))
+
+;; http://www.postgresql.org/docs/8.1/interactive/sql-expressions.html#SQL-SYNTAX-ROW-CONSTRUCTORS
+;;
+;; these are in the format "(foo,bar,baz)"
+(defun row-parser (str)
+ (assert (char= #\( (char str 0)))
+ (loop :with start = 1
+ :with last = (- (length str) 1)
+ :for end = (or (position #\, str :start start) last)
+ :collect (subseq str start end)
+ :do (setq start (1+ end))
+ :until (>= end last)))
+
(defun initialize-parsers (connection)
(let* ((pgtypes (pg-exec connection "SELECT typname,oid FROM pg_type"))
(tuples (pg-result pgtypes :tuples)))
@@ -265,4 +285,29 @@
(intern type :keyword)))))
(gethash type *type-to-oid*)))
+
+
+;; PQescapeBytea - converts from binary string to the
+;; minimal encoding necessary to include the string in an SQL
+;; INSERT statement with a bytea type column as the target.
+;;
+;; The following transformations are applied
+;; '\0' == ASCII 0 == \000
+;; '\'' == ASCII 39 == ''
+;; '\\' == ASCII 92 == \\
+;; anything < 0x20, or > 0x7e ---> \ooo
+;; (where ooo is an octal expression)
+;; If not std_strings, all backslashes sent to the output are doubled.
+;;
+;; http://www.postgresql.org/docs/8.1/static/datatype-binary.html
+(defun bytea->string (data)
+ (declare (type (vector (unsigned-byte 8) *) data))
+ (with-output-to-string (out)
+ (loop :for octet :across data :do
+ (cond ((<= 32 octet 126)
+ (write-char (code-char octet) out))
+ (t
+ (format out "\\~3,'0O" octet))))))
+
+
;; EOF
More information about the Pg-cvs
mailing list