tests.scm
(require (planet "unit-test.scm" ("oesterholt" "ho-utils.plt" 1 0)))
(require (planet "sqli.scm" ("oesterholt" "sqlid.plt" 1 0)))
(require "sqld-sqlite.scm")

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define CONNSTR "test.db")

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(unit-tests
 ("connstr"          (lambda () (if (eq? CONNSTR #f)
                                    "Environment variable CONNSTR must be set to a valid PostgreSQL connection string"
                                    #t)))
 ("basic connection" (lambda () (let ((sqld (sqld-sqlite-new CONNSTR)))
                                  (let ((sqli (sqli-connect sqld)))
                                    (if (or (eq? sqli #f) (sqli-error? sqli))
                                        (sqli-error-message sqli)
                                        #t)))))
 ("create table"     (lambda () (let ((sqld (sqld-sqlite-new CONNSTR)))
                                  (let ((sqli (sqli-connect sqld)))
                                    (sqli-query sqli "create table test (a varchar,b integer)")
                                    (not (sqli-error? sqli))))))
 ("insert"           (lambda () (let ((sqld (sqld-sqlite-new CONNSTR)))
                                  (let ((sqli (sqli-connect sqld)))
                                    (sqli-query sqli "insert into test values($1,$2)" "hello" 1)
                                    (not (sqli-error? sqli))))))
 ("inserts (transaction)" 
                     (lambda () (let ((sqld (sqld-sqlite-new CONNSTR)))
                                  (let ((sqli (sqli-connect sqld)))
                                    (sqli-begin sqli)
                                    (sqli-register sqli 'inserter "insert into test values($1,$2)")
                                    (letrec ((f (lambda (i)
                                                  (if (< i 1000)
                                                      (begin
                                                        (sqli-exec sqli 'inserter (format "this is line ~a" i) i)
                                                        (if (sqli-error? sqli)
                                                            (sqli-error-message sqli)
                                                            (f (+ i 1))))
                                                      (begin
                                                        (sqli-commit sqli)
                                                        (not (sqli-error? sqli)))))))
                                      (f 0))))))
 ("select count=1001" (lambda () (let ((sqld (sqld-sqlite-new CONNSTR)))
                                   (let ((sqli (sqli-connect sqld)))
                                     (sqli-query sqli "select count(*) from test")
                                     (let ((c (string->number (car (sqli-fetchrow sqli)))))
                                       (= c 1001))))))
 ("select all"        (lambda () (let ((sqld (sqld-sqlite-new CONNSTR)))
                                   (let ((sqli (sqli-connect sqld)))
                                     (sqli-query sqli "select * from test")
                                     (let ((rows (sqli-fetchall sqli)))
                                       (if (not (= (length rows) 1001))
                                           (length rows)
                                           #t))))))
 ("threaded inserts"  (lambda () (let ((sqld (sqld-sqlite-new CONNSTR)))
                                   (let* ((g (lambda (pre setter)
                                               (with-handlers ((exn:fail? (lambda (exn) (setter (exn-message exn)))))
                                                 (let ((sqli (sqli-connect sqld)))
                                                   (sqli-begin sqli)
                                                   (sqli-register sqli 'inserter "insert into test values($1,$2)")
                                                   (letrec ((f (lambda (i)
                                                                 (if (< i 20000)
                                                                     (begin
                                                                       (sqli-exec sqli 'inserter (format "~a:~a" pre i) i)
                                                                       (if (sqli-error? sqli)
                                                                           (sqli-error-message sqli)
                                                                           (f (+ i 1))))
                                                                     (begin
                                                                       (sqli-commit sqli)
                                                                       (if (sqli-error? sqli)
                                                                           (sqli-error-message sqli)
                                                                           #t))))))
                                                     (setter (f 0))))))))
                                     (let ((r1 'nil)
                                           (r2 'nil))
                                       (let ((id1 (thread (lambda () (g "thread1" (lambda (r) (set! r1 r))))))
                                             (id2 (thread (lambda () (g "thread2" (lambda (r) (set! r2 r)))))))
                                         (thread-wait id1)
                                         (thread-wait id2)
                                         (if (and (eq? r1 #t) (eq? r2 #t))
                                             #t
                                             (if (eq? r1 #t)
                                                 r2
                                                 r1))))))))
 ("select count=41001" (lambda () (let ((sqld (sqld-sqlite-new CONNSTR)))
                                   (let ((sqli (sqli-connect sqld)))
                                     (sqli-query sqli "select count(*) from test")
                                     (let ((R (let ((c (string->number (car (sqli-fetchrow sqli)))))
                                                (= c 41001))))
                                       (sqli-disconnect sqli)
                                       R)))))
 ("rollback"         (lambda () (let ((sqld (sqld-sqlite-new CONNSTR)))
                                  (let ((sqli (sqli-connect sqld)))
                                    (sqli-begin sqli)
                                    (sqli-register sqli 'inserter "insert into test values($1,$2)")
                                    (letrec ((f (lambda (i)
                                                  (if (< i 1000)
                                                      (begin
                                                        (sqli-exec sqli 'inserter (format "this is line ~a" i) i)
                                                        (if (sqli-error? sqli)
                                                            (sqli-error-message sqli)
                                                            (f (+ i 1))))
                                                      (begin
                                                        (sqli-rollback sqli)
                                                        (not (sqli-error? sqli)))))))
                                      (f 0))))))
 ("select count=41001" (lambda () (let ((sqld (sqld-sqlite-new CONNSTR)))
                                   (let ((sqli (sqli-connect sqld)))
                                     (sqli-query sqli "select count(*) from test")
                                     (let ((R (let ((c (string->number (car (sqli-fetchrow sqli)))))
                                                (= c 41001))))
                                       (sqli-disconnect sqli)
                                       R)))))
 ("drop table test"  (lambda () (let ((sqld (sqld-sqlite-new CONNSTR)))
                                  (let ((sqli (sqli-connect sqld)))
                                    (sqli-query sqli "drop table test")
                                    (if (sqli-error? sqli)
                                        (sqli-error-message sqli)
                                        #t)))))
 )