clsqlの勉強 その1

clsqlをいじってみる。

(require :clsql)
;;クエリ
(clsql-sys:with-database (con '("localhost" "xxx" "xxx" nil) :if-exists :old :database-type :postgresql-socket)
			 (pprint (clsql-sys:query "select * from tb0" :database con)))

;;prepared statementを使用
(clsql-sys:with-database (con '("localhost" "xxx" "xxx" nil) :if-exists :old :database-type :postgresql-socket)
			 (let ((stmt (clsql-sys:prepare-sql "select * from tb0 where id = ?" '(:int) :database con)))
			   (clsql-sys:bind-parameter stmt 1 1)
			   (let ((r (clsql-sys:run-prepared-sql stmt)))
			     (pprint r))))

;;prepared statementを使用(文字列) (stirng n)ではダメで(varchar n)ならいけた
(clsql-sys:with-database (con '("localhost" "xxx" "xxx" nil) :if-exists :old :database-type :postgresql-socket)
			 (let ((stmt (clsql-sys:prepare-sql "select * from tb0 where data1  = ?" '((:varchar 10)) :database con)))
			   (clsql-sys:bind-parameter stmt 1 "更新")
			   (let ((r (clsql-sys:run-prepared-sql stmt)))
			     (pprint r))))

;;prepaerd statementによる更新(うまくいかない)
;;戻りのresultsetがないときにうまくいっていない??
;; (clsql-sys:with-database (con '("localhost" "xxx" "xxx" nil) :if-exists :old :database-type :postgresql-socket)
;; 			 (let ((stmt (clsql-sys:prepare-sql "insert into tb0 values (?,?,?)" '(:int (:varchar 20) (:varchar 20)) :database con)))
;; 			   (clsql-sys:bind-parameter stmt 1 5)
;; 			   (clsql-sys:bind-parameter stmt 2 "日本語")
;; 			   (clsql-sys:bind-parameter stmt 3 "日本語")
;; 			   (clsql-sys:database-run-prepared stmt)
;; 			   nil)))
;; While accessing database #<POSTGRESQL-SOCKET-DATABASE localhost/xxx/xxx OPEN {1004E70461}>
;;   with expression "EXECUTE CLSQL_PS_22 (5,'日本語','日本語')":
;;   Error missing-result / Didn't receive result cursor for query.
;;   has occurred.
;;    [Condition of type CLSQL-SYS:SQL-DATABASE-DATA-ERROR]

;;DAO定義
(clsql:def-view-class test0()
		      ((test0-id 
			:accessor test0-id 
			:initarg :test0-id 
			:type integer 
			:db-kind :key 
			:db-constraints (:not-null :unique))
		       (test0-string
			:accessor test0-string
			:initarg :test0-string
			:type (clsql:varchar 10))
		       (test0-bool
			:accessor test0-bool
			:initarg :test0-bool
			:type boolean)))

;;テーブルの作成
(clsql:with-database (con '("localhost" "xxx" "xxx" nil) :if-exists :old :database-type :postgresql-socket)
			 (ignore-errors (clsql:create-view-from-class 'test0 :database con)))


;;insert
;; (clsql:with-database (con '("localhost" "xxx" "xxx" nil) :if-exists :old :database-type :postgresql-socket)
;; 		     (let ((test0 (make-instance 'test0 
;; 					     :test0-id 0
;; 					     :test0-string "初期値0"
;; 					     :test0-bool nil)))
;; 		       (clsql:update-records-from-instance test0 :database con))
;; 		     (let ((test0 (make-instance 'test0 
;; 					     :test0-id 1
;; 					     :test0-string "初期値1"
;; 					     :test0-bool nil)))
;; 		       (clsql:update-records-from-instance test0 :database con)))

;;select
(clsql:file-enable-sql-reader-syntax)

(clsql:with-database (con '("localhost" "xxx" "xxx" nil) :if-exists :old :database-type :postgresql-socket)
 		     (let ((result (clsql:select 'test0 :where [or 
						 [= [slot-value 'test0 'test0-id] 0]
						 [= [slot-value 'test0 'test0-id] 1]]
						 :database con :flatp t)))
		       (mapcar #'(lambda (o)
				   (pprint (test0-id o))
				   (pprint (test0-string o)))
			       result)))

;;insert
;;'を入れても大丈夫だった。
;; (clsql:with-database (con '("localhost" "xxx" "xxx" nil) :if-exists :old :database-type :postgresql-socket)
;;   		     (let ((test0 (make-instance 'test0 
;;  					     :test0-id 2
;;   					     :test0-string "aaa'bbb"
;;   					     :test0-bool nil)))
;;   		       (clsql:update-records-from-instance test0 :database con)))

;;更新		     
(clsql:with-database (con '("localhost" "xxx" "xxx" nil) :if-exists :old :database-type :postgresql-socket)
 		     (let ((result (clsql:select 'test0 :where [= [slot-value 'test0 'test0-id] 0]
						 :database con :flatp t)))
		       (mapcar #'(lambda (o)
				   (pprint (test0-id o))
				   (pprint (test0-string o))
				   (setf (slot-value o 'test0-string) "更新'@_\更新")
				   (clsql:update-records-from-instance o :database con))
			       result)))

;;クエリ 型付けして返す。でもbooleanがうまくいってない。
(clsql-sys:with-database (con '("localhost" "xxx" "xxx" nil) :if-exists :old :database-type :postgresql-socket)
			 (pprint (clsql-sys:query "select * from test0" :database con :flatp nil :result-types '(:int (:varchar 10) :boolean))))

プリペアドステートメントでクエリはできるんだけど、更新がうまくいかない。
def-view-classでORMを使ったときもプリペアドステートメントは使っていないみた。(ポスグレのログで確認)
:result-typesで型を指定してみたんだけど、booleanと書いても文字列で戻ってきちゃう。謎。