tools/lazy-connect.ss
;; Run code in an environment that only creates a connection if the
;; object is accessed, and closes after execution in the case a
;; connection was created.

#lang scheme/base

(provide
 with-lazy-connect
 lazy-connection   
 )

;; Abstract type to distinguish parameter from delayed connect.

(define-struct lazy-connect (thunk))

(define connection
  (make-parameter
   (make-lazy-connect
    (lambda ()
      (error 'no-lazy-connection)))))

(define (with-lazy-connect connect-thunk thunk close)
  (parameterize
      ((connection #f))
    (dynamic-wind
        (lambda ()
          (connection
           (make-lazy-connect connect-thunk)))
        thunk
        (lambda ()
          (unless (lazy-connect? (connection))
            (close (connection)))))))


;; a thunk evaluating to the object.
(define (lazy-connection)
  (let ((c (connection)))
    (when (lazy-connect? c)
      (connection ((lazy-connect-thunk c)))))
  (connection))