On Mon, Mar 13, 2017 at 2:04 PM, Ryan Culpepper <ry...@ccs.neu.edu> wrote:

> 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))
>>             a-handle))
>>     (define sth (prepare dbh "select foo from bar where baz = $1"))
>>     ...stuff...
>> )
>>
>> 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`?
>

<goes and experiments>

Looks like inside a transaction all statements are prepared.  Cool.  If so,
that's very nearly perfect -- it adds and removes all the concerns that
transactions always add/remove, but offhand I can't think of a case where
doing it in a transaction would be a problem.

Thanks, Ryan.




>
> Ryan
>
> --
> 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.
>

-- 
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