#lang scheme/base
(require "base.ss"
"query.ss"
(planet bzlib/thread)
(planet bzlib/base)
)
(define (worker conn cmd . args)
(define (helper)
(case cmd
((connect) connect)
((disconnect) disconnect)
((prepare) prepare)
((query) query)
((begin-trans) begin-trans)
((commit) commit)
((rollback) rollback)
(else (error 'async-handle "unknown command ~a" cmd))))
(apply (helper) conn args))
(define (call-worker thd args state)
(cons (apply worker state args)
state))
(define (make-handler-app conn pool)
(define (helper conn)
(receive/match
((list (? thread? thd) args)
(with-handlers ((exn?
(lambda (e)
(send-exn-to e thd)
(helper conn))))
(let ((v (call-worker thd args conn)))
(thread-reply thd (car v))
(helper (cdr v)))))
((list (list (? thread? thd) args)) (with-handlers ((exn?
(lambda (e)
(send-exn-to e thd pool)
(helper conn))))
(let ((v (call-worker thd args conn)))
(thread-reply thd (car v) pool)
(helper (cdr v)))))
((list (list 'reset! (? thread? thd)))
(while (> (handle-trans conn) 0)
(rollback conn))
(helper conn))
))
(make-app (thread
(lambda ()
(helper conn)))))
(define (app-connect driver pool key . attrs)
(make-handle driver
(make-handler-app (apply connect key attrs) pool)
#f
0))
(define (app-disconnect handle)
(app-call (handle-conn handle) 'disconnect))
(define (app-prepare handle key stmt)
(app-call (handle-conn handle) 'prepare key stmt))
(define (app-query handle stmt args)
(app-call (handle-conn handle) 'query stmt args))
(define (app-begin handle)
(app-call (handle-conn handle) 'begin-trans))
(define (app-rollback handle)
(app-call (handle-conn handle) 'rollback))
(define (app-commit handle)
(app-call (handle-conn handle) 'commit))
(registry-set! drivers 'app
(make-driver app-connect
app-disconnect
app-query
app-prepare
app-begin
app-commit
app-rollback))