[Gauche-devel-jp] dbi-make-driver

Back to archive index

Tatsuya BIZENN bizen****@arthu*****
2006年 6月 13日 (火) 07:56:23 JST


備前です。

DBIのドキュメントの<dbi-driver>のサブクラスを実装
しなければならないという説明の一部として

Usually this class produces a singleton instance,
and is only used to dispatch dbi-make-connection
method below.

と書かれています。で、それもそうだということで、
<mysql-driver> を次のようにしてみました。

(define-class <mysql-driver>
   (<dbi-driver> <singleton-mixin>)
   ())

が、dbi-make-driver は毎回違うオブジェクトを返し、
シングルトンインスタンスにならないようです。

gosh> (use dbi)
#<undef>
gosh> (dbi-make-driver "mysql")
#<<mysql-driver> 0x60e050>
gosh> (dbi-make-driver "mysql")
#<<mysql-driver> 0x6c8c40>
gosh> (dbi-make-driver "mysql")
#<<mysql-driver> 0x56d410>
gosh>

そこで、次のようなパッチをdbi.scm に当ててみたところ、
今度はシングルトンになりました。

Index: lib/dbi.scm
===================================================================
RCS file: /cvsroot/gauche/Gauche/lib/dbi.scm,v
retrieving revision 1.32
diff -u -r1.32 dbi.scm
--- lib/dbi.scm 9 Mar 2006 21:53:06 -0000       1.32
+++ lib/dbi.scm 12 Jun 2006 22:51:12 -0000
@@ -218,22 +218,14 @@
;; Loads a concrete driver module, and returns an instance of
;; the driver.
(define (dbi-make-driver driver-name)
-  (or (and-let* ((module&path (library-fold
-                               (string->symbol #`"dbd.,driver-name")
-                               (lambda (m p s) (cons m p)) #f))
-                 (module      (car module&path))
-                 (path        (cdr module&path))
-                 (class-name  (string->symbol #`"<,|driver-name|- 
driver>"))
-
-                 (driver-class
-                  (begin (eval `(require ,(path-sans-extension path))
-                               (current-module))
-                         (global-variable-ref module class-name #f)))
-                 )
-        (make driver-class :driver-name driver-name))
-      (errorf <dbi-nonexistent-driver-error>
-              :driver-name driver-name
-              "couldn't load driver dbd.~a" driver-name)))
+  (guard (e (else (errorf <dbi-nonexistent-driver-error>
+                         :driver-name driver-name
+                         "couldn't load driver dbd.~a" driver-name)))
+    (let* ((module (string->symbol #`"dbd.,driver-name"))
+          (path (module-name->path module))
+          (class-name (string->symbol #`"<,|driver-name|-driver>")))
+      (eval `(require ,path) (current-module))
+      (eval `(with-module ,module (make ,class-name :driver- 
name ,driver-name)) (current-module)))))
;; Default prepared-SQL handler
;; dbi-prepare-sql returns a procedure, which generates a complete sql

実行結果
gosh> (use dbi)
#<undef>
gosh> (dbi-make-driver "mysql")
#<<mysql-driver> 0x689630>
gosh> (dbi-make-driver "mysql")
#<<mysql-driver> 0x689630>
gosh> (dbi-make-driver "mysql")
#<<mysql-driver> 0x689630>
gosh>

何かわたしが勘違いしている可能性もありますが、こちらの方が
いいんじゃないかと思うので、一応提案させていただきます。

-- 
備前 達矢





Gauche-devel-jp メーリングリストの案内
Back to archive index