Changeset 10508 for lang/scheme

Show
Ignore:
Timestamp:
04/27/08 02:55:57 (7 months ago)
Author:
hayamiz
Message:

add error handling and so on. Test-pass rate was improved.

Location:
lang/scheme/gauche-tokyocabinet/trunk
Files:
1 added
1 removed
5 modified

Legend:

Unmodified
Added
Removed
  • lang/scheme/gauche-tokyocabinet/trunk/dbm/tokyocabinet.scm

    r10453 r10508  
    44 
    55(define-module dbm.tokyocabinet 
    6   (use dbm) 
     6  (extend dbm) 
    77  (export <tcbdb> 
    88 
    99          ;; low level interface 
    10 ;;        tcbdb-new 
    11 ;;        tcbdb-open tcbdb-close 
    12 ;;        tcbdb-put2 tcbdb-get2 
    13 ;;        tcbdbcur-new 
    14 ;;        tcbdbcur-first tcbdbcur-last 
    15 ;;        tcbdbcur-prev tcbdbcur-next 
    16 ;;        tcbdbcur-key2 tcbdbcur-val2 
    17 ;;        tcbdb-fold tcbdb-map tcbdb-for-each 
     10          tcbdb-new tcbdb-ecode 
     11          tcbdb-open tcbdb-close 
     12          tcbdb-put2 tcbdb-get2 tcbdb-out2 
     13          tcbdbcur-new 
     14          tcbdbcur-first tcbdbcur-last 
     15          tcbdbcur-prev tcbdbcur-next 
     16          tcbdbcur-key2 tcbdbcur-val2 
     17          tcbdb-fold tcbdb-map tcbdb-for-each 
    1818           
    1919          |BDBOREADER| |BDBOWRITER| |BDBOCREAT| 
    2020          |BDBOTRUNC| |BDBONOLCK| |BDBOLCKNB| 
     21 
     22          |TCESUCCESS| |TCETHREAD| |TCEINVALID| 
     23          |TCENOFILE| |TCENOPERM| |TCEMETA| 
     24          |TCERHEAD| |TCEOPEN| |TCECLOSE| 
     25          |TCETRUNC| |TCESYNC| |TCESTAT| 
     26          |TCESEEK| |TCEREAD| |TCEWRITE| 
     27          |TCEMMAP| |TCELOCK| |TCEUNLINK| 
     28          |TCERENAME| |TCEMKDIR| |TCERMDIR| 
     29          |TCEKEEP| |TCENOREC| |TCEMISC| 
    2130          ) 
    2231  ) 
     
    6978(define-method dbm-open ((self <tcbdb>)) 
    7079  (next-method) 
     80  self 
    7181  (unless (slot-bound? self 'path) 
    7282    (error "path must be set to open TokyoCabinet BDB database")) 
     
    8191                                    (if nolock |BDBONOLCK| 0) 
    8292                                    (if noblock-lock |BDBOLCKNB| 0))) 
    83                    ((:create) (logior |BDBOWRITER| |BDBOTRUNC| 
     93                   ((:create) (logior |BDBOWRITER| |BDBOTRUNC| |BDBOCREAT| 
    8494                                     (if nolock |BDBONOLCK| 0) 
    8595                                     (if noblock-lock |BDBOLCKNB| 0))))) 
     
    93103(define-method dbm-close ((self <tcbdb>)) 
    94104  (let ((raw-tcbdb (raw-tcbdb-of self))) 
    95     (and raw-tcbdb (tcbdb-close tcbdb) 
     105    (and raw-tcbdb (tcbdb-close raw-tcbdb) 
    96106         (begin (slot-set! self 'raw-tcbdb #f) 
    97107                #t)))) 
    98108 
    99 (define-method dbm-put! ((self <tcbdb> key value)) 
    100   (tcbdb-put2 (raw-tcbdb-of self) key value)) 
     109(define-method dbm-closed? ((self <tcbdb>)) 
     110  (not (slot-ref self 'raw-tcbdb))) 
     111 
     112(define-method dbm-put! ((self <tcbdb>) key value) 
     113  (next-method) 
     114  (let ((key (%dbm-k2s self key)) 
     115        (value (%dbm-v2s self value))) 
     116    (let1 ret (tcbdb-put2 (raw-tcbdb-of self) key value) 
     117    (if ret 
     118        ret 
     119        (if (eq? :read (slot-ref self 'rw-mode)) 
     120            (error "tokyocabinet bdb: database is opened as read only") 
     121            #f))))) 
    101122 
    102123(define-method dbm-get ((self <tcbdb>) key . args) 
    103   (and (tcbdb-get2 (raw-tcbdb-of self) key) 
    104        (if (null? args) 
    105            (errorf "tokyocabinet bdb: not data for key ~s in database ~s" 
    106                    key self)))) 
     124  (next-method) 
     125  (let ((key (%dbm-k2s self key))) 
     126    (let1 ret (tcbdb-get2 (raw-tcbdb-of self) key) 
     127      (if ret 
     128          ret 
     129          (if (null? args) 
     130              (errorf "tokyocabinet bdb: not data for key ~s in database ~s" 
     131                      key self) 
     132              (car args)))))) 
     133 
     134(define-method dbm-exists? ((self <tcbdb>) key) 
     135  (and (tcbdb-get2 (raw-tcbdb-of self) (%dbm-k2s self key)) #t)) 
     136 
     137(define-method dbm-delete! ((self <tcbdb>) key) 
     138  (or (tcbdb-out2 (raw-tcbdb-of self) (%dbm-k2s self key)) 
     139      (if (eq? :read (slot-ref self 'rw-mode)) 
     140          (error "tokyocabinet bdb: database is opened as read only") 
     141          #f))) 
    107142 
    108143(define-method dbm-fold ((self <tcbdb>) proc knil) 
     
    115150(provide "dbm/tokyocabinet") 
    116151 
    117  
  • lang/scheme/gauche-tokyocabinet/trunk/test.scm

    r10453 r10508  
    44 
    55(use gauche.test) 
     6(use srfi-1) 
     7(use gauche.collection) 
    68 
    79(test-start "dbm.tokyocabinet") 
     10(use dbm) 
    811(use dbm.tokyocabinet) 
    912(test-module 'dbm.tokyocabinet) 
     
    1114;; The following is a dummy test code. 
    1215;; Replace it for your tests. 
    13 (test* "test-tokyocabinet" "tokyocabinet is working" 
    14        (test-tokyocabinet)) 
     16 
     17;; 
     18;; Common test suite 
     19;; 
     20 
     21(define-syntax catch 
     22  (syntax-rules () 
     23    ((_ body ...) 
     24     (with-error-handler 
     25      (lambda (e) #t) 
     26      (lambda () body ... #f))))) 
     27 
     28(define *test-dbm* "test.dbm") 
     29(define *current-dbm* #f) 
     30 
     31;; prepair dataset 
     32(define *test1-dataset* (make-hash-table 'equal?)) ;string only 
     33(define *test2-dataset* (make-hash-table 'equal?)) ;other objects 
     34 
     35(define (generate-test-set size) 
     36  (do ((i   0 (+ i 1)) 
     37       (key (sys-random) (sys-random)) 
     38       (val (cons (sys-random) (sys-random)) (cons (sys-random) (sys-random)))) 
     39      ((>= i size)) 
     40    (hash-table-put! *test1-dataset* 
     41                     (x->string key) 
     42                     (x->string val)) 
     43    (hash-table-put! *test2-dataset* key val))) 
     44 
     45(generate-test-set 1000) 
     46 
     47;; create test 
     48(define (test:make class rw-mode serializer) 
     49  (set! *current-dbm* 
     50        (dbm-open class 
     51                  :path *test-dbm* :rw-mode rw-mode 
     52                  :key-convert serializer 
     53                  :value-convert serializer)) 
     54  #t) 
     55 
     56;; put everything to the database 
     57(define (test:put! dataset) 
     58  (hash-table-for-each 
     59   dataset 
     60   (lambda (k v) 
     61     (dbm-put! *current-dbm* k v))) 
     62  #t) 
     63 
     64;; does database has all of them? 
     65(define (test:get dataset) 
     66  (call/cc 
     67   (lambda (return) 
     68     (hash-table-for-each 
     69      dataset 
     70      (lambda (k v) 
     71        (unless (dbm-exists? *current-dbm* k) 
     72          (return #f)) 
     73        (unless (equal? v (dbm-get *current-dbm* k)) 
     74          (return #f)))) 
     75     #t))) 
     76 
     77;; does database properly deal with exceptional case? 
     78(define (test:get-exceptional) 
     79  (and 
     80   ;; must raise an error 
     81   (catch (dbm-get *current-dbm* "this_is_not_a_key")) 
     82   ;; use default 
     83   (dbm-get *current-dbm* "this_is_not_a_key" #t))) 
     84 
     85;; does for-each and map do a right thing? 
     86(define (test:for-each dataset) 
     87  (call/cc 
     88   (lambda (return) 
     89     (let ((r '())) 
     90       (dbm-for-each *current-dbm* 
     91                     (lambda (k v) 
     92                       (unless (equal? v (hash-table-get dataset k #f)) 
     93                         (return #f)) 
     94                       (set! r (cons v r)))) 
     95       (equal? (reverse r) 
     96               (dbm-map *current-dbm* 
     97                        (lambda (k v) v))))))) 
     98 
     99;; does collection framework works? 
     100(define (test:collection-read dataset) 
     101  (call/cc 
     102   (lambda (return) 
     103     (for-each (lambda (entry) 
     104                 (unless (equal? (hash-table-get dataset (car entry)) 
     105                                 (cdr entry)) 
     106                   (return #f))) 
     107               *current-dbm*) 
     108     #t))) 
     109 
     110;; does delete work? 
     111(define (test:delete dataset) 
     112  (call/cc 
     113   (lambda (return) 
     114     (hash-table-for-each 
     115      dataset 
     116      (lambda (k v) 
     117        (unless (and (dbm-exists? *current-dbm* k) 
     118                     (begin (dbm-delete! *current-dbm* k) 
     119                            (not (dbm-exists? *current-dbm* k)))) 
     120          (return #f)))) 
     121     #t))) 
     122 
     123;; does read-only work? 
     124(define (test:read-only) 
     125  ;; if db is read-only, following procedures must throw an error. 
     126  (and (catch (dbm-put! *current-dbm* "" "")) 
     127       (catch (dbm-delete! *current-dbm* "")))) 
     128 
     129;; does close work? 
     130(define (test:close) 
     131  (dbm-close *current-dbm*) 
     132  (and (dbm-closed? *current-dbm*) 
     133       ;; following procedures must throw an error. 
     134       (catch (dbm-get *current-dbm* "" #f)) 
     135       (catch (dbm-exists? *current-dbm* "")) 
     136       (catch (dbm-put! *current-dbm* "" "")) 
     137       (catch (dbm-delete! *current-dbm* "")) 
     138       (catch (dbm-for-each *current-dbm* (lambda _ #f))) 
     139       (catch (dbm-map *current-dbm* (lambda _ #f))))) 
     140 
     141;; clean up files 
     142(define (clean-up) 
     143  (when (file-exists? *test-dbm*) (sys-system #`"rm -rf ,*test-dbm*")) 
     144  (when (file-exists? (string-append *test-dbm* ".dir")) 
     145    (sys-unlink (string-append *test-dbm* ".dir"))) 
     146  (when (file-exists? (string-append *test-dbm* ".pag")) 
     147    (sys-unlink (string-append *test-dbm* ".pag"))) 
     148  (when (file-exists? (string-append *test-dbm* ".db")) 
     149    (sys-unlink (string-append *test-dbm* ".db")))) 
     150 
     151;; a series of test per dataset and class 
     152(define (run-through-test class dataset serializer) 
     153  (define (tag msg) (format #f "~s ~a" class msg)) 
     154  (dynamic-wind 
     155   clean-up 
     156   (lambda () 
     157     ;; create read/write db 
     158     (test (tag "make") #t (lambda () (test:make class :create serializer))) 
     159     ;; put stuffs 
     160     (test (tag "put!") #t (lambda () (test:put! dataset))) 
     161     ;; get stuffs 
     162     (test (tag "get") #t (lambda () (test:get dataset))) 
     163     (test (tag "get-exceptional") #t (lambda () (test:get-exceptional))) 
     164     ;; traverse 
     165     (test (tag "for-each") #t (lambda () (test:for-each dataset))) 
     166     ;(test (tag "collection-read") #t 
     167     ;      (lambda () (test:collection-read dataset))) 
     168     ;; close 
     169     (test (tag "close") #t (lambda () (test:close))) 
     170     ;; open again with read only 
     171     (test (tag "read-only open") #t (lambda () (test:make class :read serializer))) 
     172     ;; does it still have stuffs? 
     173     (test (tag "get again") #t (lambda () (test:get dataset))) 
     174     ;; does it work as read-only? 
     175     (test (tag "read-only") #t (lambda () (test:read-only))) 
     176     ;; close and open it again 
     177     (test (tag "close again") #t 
     178           (lambda () 
     179             (dbm-close *current-dbm*) 
     180             (test:make class :write serializer))) 
     181     ;; delete stuffs 
     182     (test (tag "delete") #t (lambda () (test:delete dataset))) 
     183     ;; close again 
     184     (test (tag "close again") #t (lambda () (test:close)))) 
     185   clean-up)) 
     186 
     187 
     188;; Do test for two datasets 
     189(define (full-test class) 
     190  (test-section (format #f "~a dataset 1" (class-name class))) 
     191  (run-through-test class *test1-dataset* #f) 
     192  (test-section (format #f "~a dataset 2" (class-name class))) 
     193  (run-through-test class *test2-dataset* #t) 
     194  ) 
     195 
     196;; conditionally test 
     197(define-macro (test-if-exists file module class) 
     198  (when (file-exists? (string-append file "." (gauche-dso-suffix))) 
     199    `(begin (use ,module) 
     200            (test-module ',module) 
     201            (full-test ,class)) 
     202    )) 
     203 
     204;; 
     205;; run test 
     206;; 
     207 
     208(full-test <tcbdb>) 
    15209 
    16210;; epilogue 
  • lang/scheme/gauche-tokyocabinet/trunk/tokyocabinet.c

    r10453 r10508  
    2525{ 
    2626    return SCM_MAKE_STR("tokyocabinet is working"); 
     27} 
     28 
     29ScmObj Scm_tcbdb_ecode(ScmRawTcbdb* bdb){ 
     30    return SCM_MAKE_INT(tcbdbecode(SCM_RAW_TCBDB(bdb)->bdb)); 
    2731} 
    2832 
     
    5963    ScmObj ret = SCM_MAKE_STR(val); 
    6064    return ret; 
     65} 
     66 
     67ScmObj Scm_tcbdb_out2(ScmRawTcbdb* bdb, ScmString* key){ 
     68    return TCCALL(tcbdbout2(bdb->bdb 
     69                            , Scm_GetString(key))); 
    6170} 
    6271 
  • lang/scheme/gauche-tokyocabinet/trunk/tokyocabinet.h

    r10453 r10508  
    8181 
    8282extern ScmObj test_tokyocabinet(void); 
     83extern ScmObj Scm_tcbdb_ecode(ScmRawTcbdb* bdb); 
    8384extern ScmObj Scm_tcbdb_new(void); 
    8485extern ScmObj Scm_tcbdb_open(ScmRawTcbdb* bdb, ScmString* path, int omode); 
     
    8687extern ScmObj Scm_tcbdb_put2(ScmRawTcbdb* bdb, ScmString* key, ScmString* val); 
    8788extern ScmObj Scm_tcbdb_get2(ScmRawTcbdb* bdb, ScmString* key); 
     89extern ScmObj Scm_tcbdb_out2(ScmRawTcbdb* bdb, ScmString* key); 
    8890extern ScmObj Scm_tcbdbcur_new(ScmRawTcbdb* bdb); 
    8991extern ScmObj Scm_tcbdbcur_del(ScmTcbdbcur* cur); 
  • lang/scheme/gauche-tokyocabinet/trunk/tokyocabinetlib.stub

    r10453 r10508  
    2222  (return "test_tokyocabinet")) 
    2323 
     24(define-cproc tcbdb-ecode (bdb::<raw-tcbdb>) 
     25  (return "Scm_tcbdb_ecode")) 
     26 
    2427(define-cproc tcbdb-new () 
    2528  (call "Scm_tcbdb_new")) 
     
    4245 
    4346  (call "Scm_tcbdb_get2")) 
     47 
     48(define-cproc tcbdb-out2 (bdb::<raw-tcbdb> 
     49                          key::<string>) 
     50 
     51  (call "Scm_tcbdb_out2")) 
    4452 
    4553(define-cproc tcbdbcur-new (bdb::<raw-tcbdb>) 
     
    7179(define-enum BDBOLCKNB) 
    7280 
     81(define-enum TCESUCCESS) 
     82(define-enum TCETHREAD) 
     83(define-enum TCEINVALID) 
     84(define-enum TCENOFILE) 
     85(define-enum TCENOPERM) 
     86(define-enum TCEMETA) 
     87(define-enum TCERHEAD) 
     88(define-enum TCEOPEN) 
     89(define-enum TCECLOSE) 
     90(define-enum TCETRUNC) 
     91(define-enum TCESYNC) 
     92(define-enum TCESTAT) 
     93(define-enum TCESEEK) 
     94(define-enum TCEREAD) 
     95(define-enum TCEWRITE) 
     96(define-enum TCEMMAP) 
     97(define-enum TCELOCK) 
     98(define-enum TCEUNLINK) 
     99(define-enum TCERENAME) 
     100(define-enum TCEMKDIR) 
     101(define-enum TCERMDIR) 
     102(define-enum TCEKEEP) 
     103(define-enum TCENOREC) 
     104(define-enum TCEMISC) 
     105 
    73106;; (use srfi-13) 
    74107;; (dolist (var '(reader writer creat trunc nolck lcknb)) (format #t "(define-enum BDBO~a)\n" (string-upcase (x->string var))))