On 03/13/2017 12:49 PM, David Storrs wrote:

Assuming I've understood all that correctly, my last question would be
how to get around the 'can't do prepare with a virtual connection' issue
for situations where I've been passed a connection (perhaps from third
party code) and it might or might not be virtual. First, to dispose of
some quibbles:

- One answer is "well, don't do that."  Write a contract on the function
that mandates the connection being non-virtual.

- Another is "well, don't do that."  Test if the connection is virtual
and, if so, don't use prepare.

- Another is "well, don't do that."  Pass around a dsn instead of a VC
and generate connections as needed.

None of these is terribly satisfying.  The first violates the principle
of "be generous in what you accept and strict in what you emit", the
second gives up a lot of speed if we were in a situation where we wanted
to use 'prepare' in the first place, and the third isn't feasible since
I won't always have control over what a third-party library emits.

My ideal solution would be something like this:

(define (myfunc a-handle)
    (define dbh
        (if (virtual-connection? a-handle)
            (my-function-to-do-connect-with-dsn (get-dsn-from a-handle))
    (define sth (prepare dbh "select foo from bar where baz = $1"))

In other words, check if the connection is virtual and, if so, extract
the dsn from it and use that to create a non-virtual connection.

Is there a way to do that?  I've been through the db module docs and
Google but not found a way.  Did I miss something?

There's no way to do that at the moment.

If you are using `prepare` just for speed, it might help to know that most base connections have an internal statement cache that maps SQL strings to prepared statement objects. The cache is only used inside of transactions, though, to avoid issues with concurrent schema changes.

You can check on statement caching by setting the #:debug? argument when connecting. Aside from lots of other noise, queries will print out whether they are using the statement cache. Here's an example:

  > (define c (dsn-connect 'pg #:debug? #t))
  > (start-transaction c)
  ** in managed transaction
  > (query c "select 1")
  ** caching statement
  > (query c "select 1")
  ** using cached statement

Could that replace your use of `prepare`?


You received this message because you are subscribed to the Google Groups "Racket 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to