H.Merijn Brand wrote:
On Fri, 10 Oct 2008 16:19:20 +0100, Martin Evans
<[EMAIL PROTECTED]> wrote:
Hi,
The DBI specification for ParamTypes taken from the DBI pod says the
following for ParamTypes:
Returns a reference to a hash containing the type information currently
bound to placeholders. The keys of the hash are the ’names’ of the
placeholders: either integers starting at 1, or, for drivers that
support named placeholders, the actual parameter name string. The hash
values are hashrefs of type information in the same form as that
provided to the various bind_param() methods (See "bind_param" for the
format and values), plus anything else that was passed as the third
argument to bind_param(). Returns undef if not supported by the driver.
I'm not sure why the values of the keys are hash references unless
because if only the numeric values were supported, it would have been a
list, not a hash, but when placeholder names come in sight, a list
would not do
$sth = $dbh->prepare ("select * from xx where xs between ? and ? or xc = ?");
$sth->execute (4, 7, "0");
ParamValues => { 1 => 4, 2 => 7, 3 => "0" },
ParamTypes => { 1 => 5, 2 => 5, 3 => 1 },
If param names are supported, that might look like
ParamValues => { foo => 4, bar => 7, baz => "0" },
ParamTypes => { foo => 5, bar => 5, baz => 1 },
but here the keys 1, 2, 3 or foo, bar and baz do not have hash
references as values as per "the hash values are hashrefs" they have
scalars as values. What I understood "the hash values are hashrefs" to
mean was:
ParamTypes => {1 => {something => x, somethingelse => y},
2 => {something => x, somethingelse => y}}
and I was questioning what the "something" and "somethingelse" were
since I am only aware of a "type".
multiple values are to be stored. If multiple values per key are stored
what are they typically? I can only find one DBD which implements
ParamTypes (DBD::Pg) and unless I am mistaken it sets the values of the
I implemented it in DBD::Unify as of 0.75 in a bigger patch to
implement as much as possible of the DBI defenition:
thanks for that pointer - I missed DBD::Unify
*** Release 0.75 - Tue 23 Sep 2008 <[EMAIL PROTECTED]>
- Three-level dbd_verbose and documentation
- $ENV{DBD_TRACE} sets $dbh->{dbd_verbose} on/before connect
- New tests for $h->trace (...) and $h->{dbd_verbose}
- Added type_info_all (), get_info (), and parse_trace_flag ()
- Note that identifiers are now quoted
- Override quote_identifier () (UNIFY has no CATALOGS)
- Accept 2-arg and 3-arg ->do ()
- Accept %attr to ->prepare ()
- Raised all verbose levels by 1. 1 and 2 are now DBI only
- Removed 05-reauth.t
- NULLABLE now always 2, as it doesn't work
- Implemented CursorName sth attribute
- Implemented ParamValues sth attribute
- Implemented ParamTypes sth attribute
- Implemented RowsInCache sth attribute (always 0)
- Tested with Unify 6.3AB on HP-UX 10.20 with perl 5.8.8
- Tested with Unify 8.2BC on HP-UX 11.00 with perl 5.8.8
- Tested with Unify 8.3I on HP-UX 11.23 with perl 5.10.0
- Tested with Unify 8.3K on AIX 5.2.0.0 with perl 5.8.8
Tests will fail on older perls, as the test cases use scalarIO
keys to a scalar value - the type of the parameter.
in dbd_st_FETCH_aatrib ()
if (kl == 10 && strEQ (key, "ParamTypes")) {
HV *hv = newHV ();
retsv = newRV (sv_2mortal ((SV *)hv));
while (--p >= 0) {
char key[8];
sprintf (key, "%d", p + 1);
hv_store (hv, key, strlen (key), newSViv (imp_sth->prm[p].ftp), 0);
}
}
So you seem to have implemented it like DBD::Pg but that does not seem
to agree with how ParamTypes is documented.
Reason I'm asking is it is on my to do list for DBD::ODBC.
The test case in t/20-uni-basic.t now looks like
ok ($sth = $dbh->prepare ("select * from xx where xs between ? and ? or xc = ?"),
"sel prepare");
ok ($sth->execute (4, 7, "0"), "execute");
ok (1, "-- Check the internals");
{ my %attr = ( # $sth attributes as documented in DBI-1.607
NAME => [qw( xs xl xc xf xr xa xh xT xd xe )],
NAME_lc => [qw( xs xl xc xf xr xa xh xt xd xe )],
NAME_uc => [qw( XS XL XC XF XR XA XH XT XD XE )],
NAME_hash => {qw( xs 0 xl 1 xc 2 xf 3 xr 4 xa 5 xh 6 xT 7 xd 8 xe 9
)},
NAME_lc_hash => {qw( xs 0 xl 1 xc 2 xf 3 xr 4 xa 5 xh 6 xt 7 xd 8 xe 9
)},
NAME_uc_hash => {qw( XS 0 XL 1 XC 2 XF 3 XR 4 XA 5 XH 6 XT 7 XD 8 XE 9
)},
uni_types => [ 5, 2, 1, 8, 7, -4, -6, -7, -3, -11],
TYPE => [ 5, 2, 1, 8, 7, 6, 7, 10, 9, 11],
PRECISION => [ 4, 9, 5, 64, 32, 9, 15, 0, 0, 0],
SCALE => [ 0, 0, 0, 0, 0, 2, 2, 0, 0, 0],
# NULLABLE => [ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1], # Does not work in
Unify (yet)
NULLABLE => [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
CursorName => "c_sql_00_000001",
NUM_OF_FIELDS => 10,
NUM_OF_PARAMS => 3,
Database => $dbh,
ParamValues => { 1 => 4, 2 => 7, 3 => "0" },
ParamTypes => { 1 => 5, 2 => 5, 3 => 1 },
ParamArrays => undef, # NYI
RowsInCache => 0,
);
foreach my $attr (sort keys %attr) {
#printf STDERR "\n%-20s %s\n", $attr, "@{$sth->{$attr}}";
my $av = exists $sth->{$attr} ? $sth->{$attr} : undef;
is_deeply ($av, $attr{$attr}, "attr $attr");
}
}
Martin
--
Martin J. Evans
Easysoft Limited
http://www.easysoft.com