Show
Ignore:
Timestamp:
08/20/09 04:03:09 (13 months ago)
Author:
sjamaan
Message:

Implement transaction support (including nested transactions)

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • release/4/postgresql/trunk/postgresql.scm

    r14796 r15517  
    2727  connect reset-connection disconnect connection? 
    2828   
    29   multi-query query query* 
     29  multi-query query query* with-transaction in-transaction? 
    3030   
    3131  result? clear-result! row-count column-count 
     
    218218;;;;;;;;;;;;;;;;;;;; 
    219219 
    220 (define-record pg-connection ptr type-parsers oid-parsers type-unparsers) 
     220(define-record 
     221  pg-connection ptr 
     222  type-parsers oid-parsers type-unparsers 
     223  transaction-depth) 
    221224(define connection? pg-connection?) 
    222225 
     
    275278     (else 
    276279      (let ((conn (make-pg-connection conn-ptr type-parsers 
    277                                       (make-hash-table) type-unparsers))) 
     280                                      (make-hash-table) type-unparsers 0))) 
    278281        ;; We don't want libpq to piss in our stderr stream 
    279282        ((foreign-lambda* void ((pgconn* conn)) 
     
    621624                         conn query params format)))) 
    622625 
     626;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
     627;;;; Transaction management 
     628;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
     629 
     630(define (with-transaction conn thunk) 
     631  (let* ((old-depth (pg-connection-transaction-depth conn)) 
     632         (rollback! 
     633          (lambda () 
     634            (if (= old-depth 0) 
     635                (query conn "ROLLBACK") 
     636                ;; We do not *need* to give savepoints unique names, 
     637                ;; but it aids debugging and we know the depth anyway. 
     638                (query conn (conc "ROLLBACK TO SAVEPOINT s_" old-depth))))) 
     639         (commit! 
     640          (lambda () 
     641            (if (= old-depth 0) 
     642                (query conn "COMMIT") 
     643                (query conn (conc "RELEASE SAVEPOINT s_" old-depth)))))) 
     644    (if (= old-depth 0) 
     645        (query conn "BEGIN") 
     646        (query conn (conc "SAVEPOINT s_" old-depth))) 
     647    (pg-connection-transaction-depth-set! conn (add1 old-depth)) 
     648    ;; TODO: Add a warning mechanism (using dynamic-wind) for when the 
     649    ;; user tries to jump into/out of transactions with continuations? 
     650    (handle-exceptions exn 
     651      (begin 
     652        (pg-connection-transaction-depth-set! conn old-depth) 
     653        (rollback!) 
     654        (raise exn)) 
     655      (let ((res (thunk))) 
     656        (pg-connection-transaction-depth-set! conn old-depth) 
     657        (if res (commit!) (rollback!)) 
     658        res)))) 
     659 
     660(define (in-transaction? conn) 
     661  (> (pg-connection-transaction-depth conn) 0)) 
     662 
    623663;;;;;;;;;;;;;;;;;;;;;; 
    624664;;;; Value escaping