diff --git a/FU.xs b/FU.xs index ff02104..f2aee9e 100644 --- a/FU.xs +++ b/FU.xs @@ -205,6 +205,7 @@ void cache(fupg_st *x, ...) FU::Pg::st::text_results = FUPG_TEXT_RESULTS FU::Pg::st::text = FUPG_TEXT CODE: + if (ix == 0 && x->prepared) fu_confess("Invalid attempt to change statement configuration after it has already been prepared or executed"); FUPG_STFLAGS; void param_types(fupg_st *st) diff --git a/FU/Pg.pm b/FU/Pg.pm index 33055c4..f3d15e0 100644 --- a/FU/Pg.pm +++ b/FU/Pg.pm @@ -105,6 +105,15 @@ Connection is dead or otherwise unusable. Set the default settings for new statements created with B<< $conn->q() >>. +=item B<< $conn->cache_size($num) >> + +Set the number of prepared statements to keep in the cache. Defaults to 256. + +Setting this (temporarily) to 0 will immediately reclaim all cached statements. +Prepared statements that still have an active C<$st> object are not counted +towards this number. The cache works as an LRU: when it's full, the statement +that hasn't been used for the longest time is reclaimed. + =item B<< $conn->disconnect >> Close the connection. Any active transactions are rolled back and any further @@ -455,7 +464,7 @@ as well. Much older versions will certainly not work fine. =item * Only supports the UTF-8 encoding for all text strings sent to and received from the PostgreSQL server. The encoding is assumed to be UTF-8 by default, but if this may not be the case in your situation, setting -`client_encoding=utf8` as part of the connection string or manually switching +C as part of the connection string or manually switching to it after C is always safe: my $conn = FU::Pg->connect(''); diff --git a/t/pgconnect.t b/t/pgconnect.t index fe3f11b..ad16537 100644 --- a/t/pgconnect.t +++ b/t/pgconnect.t @@ -47,8 +47,15 @@ subtest '$st prepare & exec', sub { my $st = $conn->q('SELECT 1'); is_deeply $st->param_types, []; is_deeply $st->columns, [{ name => '?column?', oid => 23 }]; + + ok !eval { $st->cache; 1 }; + like $@, qr/Invalid attempt to change statement configuration/; + $st = $st->text; + is $conn->exec('SELECT 1 FROM pg_prepared_statements'), 1; + is $st->exec, 1; + ok !eval { $st->exec; 1 }; like $@, qr/Invalid attempt to execute statement multiple times/; } @@ -79,6 +86,19 @@ subtest '$st prepare & exec', sub { okerr FATAL => exec => qr/unexpected status code/; is $conn->q('SET client_encoding=utf8')->exec, undef; + + ok !eval { $conn->q('select 1; select 2')->exec; 1 }; + okerr ERROR => prepare => qr/cannot insert multiple commands into a prepared statement/; + + # Interleaved + { + my $a = $conn->q('SELECT 1 as a'); + my $b = $conn->q('SELECT 2 as b'); + is_deeply $a->columns, [ { oid => 23, name => 'a' } ]; + is_deeply $b->columns, [ { oid => 23, name => 'b' } ]; + is $a->val, 1; + is $b->val, 2; + } }; subtest '$st->val', sub {