You have _way_ too much free time Steffen!
The only things that comes to mind are that there's a specific api
call for require'ing a file that should be used to avoid static's
and threading issues. And the return value probably needs to be
made mortal (sv_2mortal(...)).
Tim.
On Wed, Nov 28, 2001 at 02:09:55PM +0100, Steffen Goeldner wrote:
> Tim Bunce wrote:
> >
> > On Mon, Nov 26, 2001 at 04:25:16PM +0100, Steffen Goeldner wrote:
> > > >
> > > else if (htype==DBIt_DB && strnEQ(key, "SQL_", 4)) {
> > > /* XXX DBIt_ST ? */
> > > valuesv = dbih_get_info(h, key, keylen);
> >
> > That presumes that _all_ attributes begining with SQL_ are
> > 'get_info' attributes. That may not be the case. I'd suggest
> >
> > else if (htype==DBIt_DB && strnEQ(key, "SQL_", 4) && gi_code =
>get_info_name2code(key))
> >
>
> That's right! My brain was focused on get_info. However,
> dbih_get_attr_k is big enough, I renamed dbih_get_info to
> the more generic dbih_get_attr_k_sql_:
>
> else if (htype==DBIt_DB && strnEQ(key, "SQL_", 4)) {
> valuesv = dbih_get_attr_k_sql_(h, keysv, key, keylen);
>
> and let it handle all SQL_* requests:
>
> static SV *
> dbih_get_attr_k_sql_(SV *h, SV *keysv, char *key, STRLEN keylen)
> {
> dPERINTERP;
> dSP;
> HV *hv;
> char *meth_name;
> SV *valuesv;
> static bool loaded = FALSE;
>
> if (!loaded) {
> eval_pv("require DBI::Const", TRUE);
> loaded = TRUE;
> }
> if ((hv = get_hv("DBI::Const::GetInfo", FALSE)) && hv_exists(hv, key, keylen)) {
> meth_name = "get_info";
> }
> /*
> other SQL_* requests:
> else if ((hv = get_hv("DBI::Const::Get???", FALSE)) && hv_exists(hv, key,
>keylen)) {
> meth_name = "get_???";
> }
> */
> else {
> croak("Can't get %s->{%s}: unrecognised attribute", neatsvpv(h,0), key);
> }
>
> PUSHMARK(SP);
> XPUSHs(h);
> XPUSHs(keysv);
> PUTBACK;
> if (call_method(meth_name, G_SCALAR) != 1)
> croak("Can't locate DBI object method \"%s\"", meth_name);
> SPAGAIN;
> valuesv = POPs;
> PUTBACK;
>
> return newSVsv(valuesv);
> }
>
> Comments are highly appreciated!
>
> > > Of course, dbih_get_info needs to be written. I think, it should
> > >
> > > 1) map the symbolic name to the numeric code
> > > (via %DBI::Const::GetInfo?)
> > > 2) call $dbh->get_info($code)
> >
> > There's also the question of whether each particular item of 'info'
> > can be cached for the handle it's being called on (see cacheit in
> > dbih_get_attr_k).
> >
>
> Here I need further investigation ...
>
> > Yeap. Though you could argue that using hash fetching should be the
> > primary API to get_info and just not bother supporting importing
> > numeric constants. And I don't think there's a good performance
> > argument for numeric constants. So lets just skip the import :)
>
> Great!
>
> For testing purposes, I added a few more lines of code to DBI,
> see my attachment.
>
>
> Steffen
> diff -Nrc DBI-1.20.orig/DBI.xs DBI-1.20/DBI.xs
> *** DBI-1.20.orig/DBI.xs Sat Aug 25 00:10:48 2001
> --- DBI-1.20/DBI.xs Wed Nov 28 10:33:59 2001
> ***************
> *** 1243,1248 ****
> --- 1243,1283 ----
>
>
> static SV *
> + dbih_get_attr_k_sql_(SV *h, SV *keysv, char *key, STRLEN keylen)
> + {
> + dPERINTERP;
> + dSP;
> + HV *hv;
> + char *meth_name;
> + SV *valuesv;
> + static bool loaded = FALSE;
> +
> + if (!loaded) {
> + eval_pv("require DBI::Const", TRUE);
> + loaded = TRUE;
> + }
> + if ((hv = get_hv("DBI::Const::GetInfo", FALSE)) && hv_exists(hv, key, keylen))
>{
> + meth_name = "get_info";
> + }
> + else {
> + croak("Can't get %s->{%s}: unrecognised attribute", neatsvpv(h,0), key);
> + }
> +
> + PUSHMARK(SP);
> + XPUSHs(h);
> + XPUSHs(keysv);
> + PUTBACK;
> + if (call_method(meth_name, G_SCALAR) != 1)
> + croak("Can't locate DBI object method \"%s\"", meth_name);
> + SPAGAIN;
> + valuesv = POPs;
> + PUTBACK;
> +
> + return newSVsv(valuesv);
> + }
> +
> +
> + static SV *
> dbih_get_attr_k(h, keysv, dbikey) /* XXX split into dr/db/st
>funcs */
> SV *h;
> SV *keysv;
> ***************
> *** 1406,1411 ****
> --- 1441,1449 ----
> }
> else if (keylen==9 && strEQ(key, "BegunWork")) {
> valuesv = boolSV(DBIc_has(imp_xxh,DBIcf_BegunWork));
> + }
> + else if (htype==DBIt_DB && strnEQ(key, "SQL_", 4)) {
> + valuesv = dbih_get_attr_k_sql_(h, keysv, key, keylen);
> }
> else { /* finally check the actual hash just in case */
> svp = hv_fetch((HV*)SvRV(h), key, keylen, FALSE);
> diff -Nrc DBI-1.20.orig/lib/DBD/NullP.pm DBI-1.20/lib/DBD/NullP.pm
> *** DBI-1.20.orig/lib/DBD/NullP.pm Sat Aug 25 00:10:50 2001
> --- DBI-1.20/lib/DBD/NullP.pm Wed Nov 28 10:30:41 2001
> ***************
> *** 58,63 ****
> --- 58,69 ----
> $outer;
> }
>
> + sub get_info {
> + my $dbh = shift;
> + my $git = shift;
> + return 'GetInfo: ' . $git;
> + }
> +
> sub FETCH {
> my ($dbh, $attrib) = @_;
> # In reality this would interrogate the database engine to
> diff -Nrc DBI-1.20.orig/lib/DBI/Const.pm DBI-1.20/lib/DBI/Const.pm
> *** DBI-1.20.orig/lib/DBI/Const.pm Thu Jan 01 01:00:00 1970
> --- DBI-1.20/lib/DBI/Const.pm Wed Nov 28 10:28:48 2001
> ***************
> *** 0 ****
> --- 1,238 ----
> + package DBI::Const;
> +
> + =head1 NAME
> +
> + DBI::Const - DBI constants
> +
> + =cut
> +
> + $VERSION = '0.01';
> +
> + %GetInfo =
> + ( # ODBC SQL
> + SQL_ACTIVE_CONNECTIONS => 0 # 0
> + , SQL_MAXIMUM_DRIVER_CONNECTIONS => 0 # 0 0
> + , SQL_MAX_DRIVER_CONNECTIONS => 0 # 0
> + , SQL_INFO_FIRST => 0 # 0
> + , SQL_ACTIVE_STATEMENTS => 1 # 1
> + , SQL_MAX_CONCURRENT_ACTIVITIES => 1 # 1
> + , SQL_MAXIMUM_CONCURRENT_ACTIVITIES => 1 # 1 1
> + , SQL_DATA_SOURCE_NAME => 2 # 2 2
> + , SQL_DRIVER_HDBC => 3 # 3
> + , SQL_DRIVER_HENV => 4 # 4
> + , SQL_DRIVER_HSTMT => 5 # 5
> + , SQL_DRIVER_NAME => 6 # 6
> + , SQL_DRIVER_VER => 7 # 7
> + , SQL_FETCH_DIRECTION => 8 # 8 8
> + , SQL_ODBC_API_CONFORMANCE => 9 # 9
> + , SQL_ODBC_VER => 10 # 10
> + , SQL_ROW_UPDATES => 11 # 11
> + , SQL_ODBC_SAG_CLI_CONFORMANCE => 12 # 12
> + , SQL_SERVER_NAME => 13 # 13 13
> + , SQL_SEARCH_PATTERN_ESCAPE => 14 # 14 14
> + , SQL_ODBC_SQL_CONFORMANCE => 15 # 15
> + , SQL_DBMS_NAME => 17 # 17 17
> + , SQL_DBMS_VER => 18 # 18
> + , SQL_DBMS_VERSION => 18 # 18
> + , SQL_ACCESSIBLE_TABLES => 19 # 19
> + , SQL_ACCESSIBLE_PROCEDURES => 20 # 20
> + , SQL_PROCEDURES => 21 # 21
> + , SQL_CONCAT_NULL_BEHAVIOR => 22 # 22
> + , SQL_CURSOR_COMMIT_BEHAVIOR => 23 # 23 23
> + , SQL_CURSOR_ROLLBACK_BEHAVIOR => 24 # 24
> + , SQL_DATA_SOURCE_READ_ONLY => 25 # 25 25
> + , SQL_DEFAULT_TXN_ISOLATION => 26 # 26
> + , SQL_DEFAULT_TRANSACTION_ISOLATION => 26 # 26
> + , SQL_EXPRESSIONS_IN_ORDERBY => 27 # 27
> + , SQL_IDENTIFIER_CASE => 28 # 28 28
> + , SQL_IDENTIFIER_QUOTE_CHAR => 29 # 29
> + , SQL_MAXIMUM_COLUMN_NAME_LENGTH => 30 # 30 30
> + , SQL_MAX_COLUMN_NAME_LEN => 30 # 30
> + , SQL_MAXIMUM_CURSOR_NAME_LENGTH => 31 # 31 31
> + , SQL_MAX_CURSOR_NAME_LEN => 31 # 31
> + , SQL_MAX_OWNER_NAME_LEN => 32 # 32
> + , SQL_MAXIMUM_SCHEMA_NAME_LENGTH => 32 # 32 32
> + , SQL_MAX_SCHEMA_NAME_LEN => 32 # 32
> + , SQL_MAX_PROCEDURE_NAME_LEN => 33 # 33
> + , SQL_MAX_CATALOG_NAME_LEN => 34 # 34
> + , SQL_MAXIMUM_CATALOG_NAME_LENGTH => 34 # 34 34
> + , SQL_MAX_QUALIFIER_NAME_LEN => 34 # 34
> + , SQL_MAX_TABLE_NAME_LEN => 35 # 35
> + , SQL_MAXIMUM_TABLE_NAME_LENGTH => 35 # 35
> + , SQL_MULT_RESULT_SETS => 36 # 36
> + , SQL_MULTIPLE_ACTIVE_TXN => 37 # 37
> + , SQL_OUTER_JOINS => 38 # 38
> + , SQL_OWNER_TERM => 39 # 39
> + , SQL_SCHEMA_TERM => 39 # 39
> + , SQL_PROCEDURE_TERM => 40 # 40
> + , SQL_CATALOG_NAME_SEPARATOR => 41 # 41
> + , SQL_QUALIFIER_NAME_SEPARATOR => 41 # 41
> + , SQL_QUALIFIER_TERM => 42 # 42
> + , SQL_CATALOG_TERM => 42 # 42
> + , SQL_SCROLL_CONCURRENCY => 43 # 43 43
> + , SQL_SCROLL_OPTIONS => 44 # 44
> + , SQL_TABLE_TERM => 45 # 45
> + , SQL_TXN_CAPABLE => 46 # 46
> + , SQL_TRANSACTION_CAPABLE => 46 # 46 46
> + , SQL_USER_NAME => 47 # 47 47
> + , SQL_CONVERT_FUNCTIONS => 48 # 48
> + , SQL_NUMERIC_FUNCTIONS => 49 # 49
> + , SQL_STRING_FUNCTIONS => 50 # 50
> + , SQL_SYSTEM_FUNCTIONS => 51 # 51
> + , SQL_TIMEDATE_FUNCTIONS => 52 # 52
> + , SQL_CONVERT_BIGINT => 53 # 53
> + , SQL_CONVERT_BINARY => 54 # 54
> + , SQL_CONVERT_BIT => 55 # 55
> + , SQL_CONVERT_CHAR => 56 # 56
> + , SQL_CONVERT_DATE => 57 # 57
> + , SQL_CONVERT_DECIMAL => 58 # 58
> + , SQL_CONVERT_DOUBLE => 59 # 59
> + , SQL_CONVERT_FLOAT => 60 # 60
> + , SQL_CONVERT_INTEGER => 61 # 61
> + , SQL_CONVERT_LONGVARCHAR => 62 # 62
> + , SQL_CONVERT_NUMERIC => 63 # 63
> + , SQL_CONVERT_REAL => 64 # 64
> + , SQL_CONVERT_SMALLINT => 65 # 65
> + , SQL_CONVERT_TIME => 66 # 66
> + , SQL_CONVERT_TIMESTAMP => 67 # 67
> + , SQL_CONVERT_TINYINT => 68 # 68
> + , SQL_CONVERT_VARBINARY => 69 # 69
> + , SQL_CONVERT_VARCHAR => 70 # 70
> + , SQL_CONVERT_LONGVARBINARY => 71 # 71
> + , SQL_TXN_ISOLATION_OPTION => 72 # 72
> + , SQL_TRANSACTION_ISOLATION_OPTION => 72 # 72 72
> + , SQL_INTEGRITY => 73 # 73 73
> + , SQL_ODBC_SQL_OPT_IEF => 73 # 73
> + , SQL_CORRELATION_NAME => 74 # 74
> + , SQL_NON_NULLABLE_COLUMNS => 75 # 75
> + , SQL_DRIVER_HLIB => 76 # 76
> + , SQL_DRIVER_ODBC_VER => 77 # 77
> + , SQL_LOCK_TYPES => 78 # 78
> + , SQL_POS_OPERATIONS => 79 # 79
> + , SQL_POSITIONED_STATEMENTS => 80 # 80
> + , SQL_GETDATA_EXTENSIONS => 81 # 81 81
> + , SQL_BOOKMARK_PERSISTENCE => 82 # 82
> + , SQL_STATIC_SENSITIVITY => 83 # 83
> + , SQL_FILE_USAGE => 84 # 84
> + , SQL_NULL_COLLATION => 85 # 85 85
> + , SQL_ALTER_TABLE => 86 # 86 86
> + , SQL_COLUMN_ALIAS => 87 # 87
> + , SQL_GROUP_BY => 88 # 88
> + , SQL_KEYWORDS => 89 # 89
> + , SQL_ORDER_BY_COLUMNS_IN_SELECT => 90 # 90 90
> + , SQL_OWNER_USAGE => 91 # 91
> + , SQL_SCHEMA_USAGE => 91 # 91
> + , SQL_QUALIFIER_USAGE => 92 # 92
> + , SQL_CATALOG_USAGE => 92 # 92
> + , SQL_QUOTED_IDENTIFIER_CASE => 93 # 93
> + , SQL_SPECIAL_CHARACTERS => 94 # 94 94
> + , SQL_SUBQUERIES => 95 # 95
> + , SQL_UNION_STATEMENT => 96 # 96
> + , SQL_UNION => 96 # 96
> + , SQL_MAXIMUM_COLUMNS_IN_GROUP_BY => 97 # 97 97
> + , SQL_MAX_COLUMNS_IN_GROUP_BY => 97 # 97
> + , SQL_MAXIMUM_COLUMNS_IN_INDEX => 98 # 98
> + , SQL_MAX_COLUMNS_IN_INDEX => 98 # 98
> + , SQL_MAX_COLUMNS_IN_ORDER_BY => 99 # 99
> + , SQL_MAXIMUM_COLUMNS_IN_ORDER_BY => 99 # 99 99
> + , SQL_MAX_COLUMNS_IN_SELECT => 100 # 100
> + , SQL_MAXIMUM_COLUMNS_IN_SELECT => 100 # 100 100
> + , SQL_MAXIMUM_COLUMNS_IN_TABLE => 101 # 101
> + , SQL_MAX_COLUMNS_IN_TABLE => 101 # 101
> + , SQL_MAXIMUM_INDEX_SIZE => 102 # 102
> + , SQL_MAX_INDEX_SIZE => 102 # 102
> + , SQL_MAX_ROW_SIZE_INCLUDES_LONG => 103 # 103
> + , SQL_MAX_ROW_SIZE => 104 # 104
> + , SQL_MAXIMUM_ROW_SIZE => 104 # 104
> + , SQL_MAX_STATEMENT_LEN => 105 # 105
> + , SQL_MAXIMUM_STATEMENT_LENGTH => 105 # 105
> + , SQL_MAXIMUM_TABLES_IN_SELECT => 106 # 106 106
> + , SQL_MAX_TABLES_IN_SELECT => 106 # 106
> + , SQL_MAX_USER_NAME_LEN => 107 # 107
> + , SQL_MAXIMUM_USER_NAME_LENGTH => 107 # 107 107
> + , SQL_MAX_CHAR_LITERAL_LEN => 108 # 108
> + , SQL_TIMEDATE_ADD_INTERVALS => 109 # 109
> + , SQL_TIMEDATE_DIFF_INTERVALS => 110 # 110
> + , SQL_NEED_LONG_DATA_LEN => 111 # 111
> + , SQL_MAX_BINARY_LITERAL_LEN => 112 # 112
> + , SQL_LIKE_ESCAPE_CLAUSE => 113 # 113
> + , SQL_INFO_LAST => 114 # 114
> + , SQL_QUALIFIER_LOCATION => 114 # 114
> + , SQL_CATALOG_LOCATION => 114 # 114
> + , SQL_OUTER_JOIN_CAPABILITIES => 115 # 115 115
> + , SQL_ACTIVE_ENVIRONMENTS => 116 # 116
> + , SQL_ALTER_DOMAIN => 117 # 117
> + , SQL_SQL_CONFORMANCE => 118 # 118
> + , SQL_DATETIME_LITERALS => 119 # 119
> + , SQL_BATCH_ROW_COUNT => 120 # 120
> + , SQL_BATCH_SUPPORT => 121 # 121
> + , SQL_CONVERT_WCHAR => 122 # 122
> + , SQL_CONVERT_INTERVAL_DAY_TIME => 123 # 123
> + , SQL_CONVERT_INTERVAL_YEAR_MONTH => 124 # 124
> + , SQL_CONVERT_WLONGVARCHAR => 125 # 125
> + , SQL_CONVERT_WVARCHAR => 126 # 126
> + , SQL_CREATE_ASSERTION => 127 # 127
> + , SQL_CREATE_CHARACTER_SET => 128 # 128
> + , SQL_CREATE_COLLATION => 129 # 129
> + , SQL_CREATE_DOMAIN => 130 # 130
> + , SQL_CREATE_SCHEMA => 131 # 131
> + , SQL_CREATE_TABLE => 132 # 132
> + , SQL_CREATE_TRANSLATION => 133 # 133
> + , SQL_CREATE_VIEW => 134 # 134
> + , SQL_DRIVER_HDESC => 135 # 135
> + , SQL_DROP_ASSERTION => 136 # 136
> + , SQL_DROP_CHARACTER_SET => 137 # 137
> + , SQL_DROP_COLLATION => 138 # 138
> + , SQL_DROP_DOMAIN => 139 # 139
> + , SQL_DROP_SCHEMA => 140 # 140
> + , SQL_DROP_TABLE => 141 # 141
> + , SQL_DROP_TRANSLATION => 142 # 142
> + , SQL_DROP_VIEW => 143 # 143
> + , SQL_DYNAMIC_CURSOR_ATTRIBUTES1 => 144 # 144
> + , SQL_DYNAMIC_CURSOR_ATTRIBUTES2 => 145 # 145
> + , SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1 => 146 # 146
> + , SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2 => 147 # 147
> + , SQL_INDEX_KEYWORDS => 148 # 148
> + , SQL_INFO_SCHEMA_VIEWS => 149 # 149
> + , SQL_KEYSET_CURSOR_ATTRIBUTES1 => 150 # 150
> + , SQL_KEYSET_CURSOR_ATTRIBUTES2 => 151 # 151
> + , SQL_ODBC_INTERFACE_CONFORMANCE => 152 # 152
> + , SQL_PARAM_ARRAY_ROW_COUNTS => 153 # 153
> + , SQL_PARAM_ARRAY_SELECTS => 154 # 154
> + , SQL_SQL92_DATETIME_FUNCTIONS => 155 # 155
> + , SQL_SQL92_FOREIGN_KEY_DELETE_RULE => 156 # 156
> + , SQL_SQL92_FOREIGN_KEY_UPDATE_RULE => 157 # 157
> + , SQL_SQL92_GRANT => 158 # 158
> + , SQL_SQL92_NUMERIC_VALUE_FUNCTIONS => 159 # 159
> + , SQL_SQL92_PREDICATES => 160 # 160
> + , SQL_SQL92_RELATIONAL_JOIN_OPERATORS => 161 # 161
> + , SQL_SQL92_REVOKE => 162 # 162
> + , SQL_SQL92_ROW_VALUE_CONSTRUCTOR => 163 # 163
> + , SQL_SQL92_STRING_FUNCTIONS => 164 # 164
> + , SQL_SQL92_VALUE_EXPRESSIONS => 165 # 165
> + , SQL_STANDARD_CLI_CONFORMANCE => 166 # 166
> + , SQL_STATIC_CURSOR_ATTRIBUTES1 => 167 # 167
> + , SQL_STATIC_CURSOR_ATTRIBUTES2 => 168 # 168
> + , SQL_AGGREGATE_FUNCTIONS => 169 # 169
> + , SQL_DDL_INDEX => 170 # 170
> + , SQL_DM_VER => 171 # 171
> + , SQL_INSERT_STATEMENT => 172 # 172
> + , SQL_CONVERT_GUID => 173 # 173
> + , SQL_INFO_DRIVER_START => 1000 # 1000
> + , SQL_XOPEN_CLI_YEAR => 10000 # 10000
> + , SQL_CURSOR_SENSITIVITY => 10001 # 10001 10001
> + , SQL_DESCRIBE_PARAMETER => 10002 # 10002 10002
> + , SQL_CATALOG_NAME => 10003 # 10003 10003
> + , SQL_COLLATING_SEQUENCE => 10004 # 10004
> + , SQL_COLLATION_SEQ => 10004 # 10004
> + , SQL_MAXIMUM_IDENTIFIER_LENGTH => 10005 # 10005 10005
> + , SQL_MAX_IDENTIFIER_LEN => 10005 # 10005
> + , SQL_ASYNC_MODE => 10021 # 10021
> + , SQL_MAX_ASYNC_CONCURRENT_STATEMENTS => 10022 # 10022
> + , SQL_MAXIMUM_STMT_OCTETS => 20000 # 20000
> + , SQL_MAXIMUM_STMT_OCTETS_DATA => 20001 # 20001
> + , SQL_MAXIMUM_STMT_OCTETS_SCHEMA => 20002 # 20002
> + , SQL_OJ_CAPABILITIES => 65003 # 65003
> + );
> +
> + 1;
> diff -Nrc DBI-1.20.orig/t/getinfo.t DBI-1.20/t/getinfo.t
> *** DBI-1.20.orig/t/getinfo.t Thu Jan 01 01:00:00 1970
> --- DBI-1.20/t/getinfo.t Wed Nov 28 11:08:48 2001
> ***************
> *** 0 ****
> --- 1,58 ----
> +
> + $| = 1;
> +
> + use strict;
> +
> + use Test::More tests => 7;
> +
> + BEGIN { use_ok('DBI') }
> +
> + my $dbh;
> +
> + # -----------------------------------------------------------------------------
> + {
> + $dbh = DBI->connect('dbi:NullP:') or die $DBI::errstr;
> + $dbh->{ RaiseError } = 1;
> + $dbh->{ PrintError } = 1;
> +
> + ok( defined $dbh,'Database handle defined');
> +
> + ok( $DBD::NullP::VERSION,'$DBD::NullP::VERSION');
> +
> + is( $dbh->{ RaiseError }, 1,'$dbh->{ RaiseError }');
> + }
> + # -----------------------------------------------------------------------------
> + {
> + no strict 'subs';
> +
> + eval { my $v = $dbh->{ SQL_XXX }; };
> + like( $@, qr/unrecognised attribute/
> + ,'unrecognised attribute');
> +
> + # $dbh->trace( 9 );
> + is( $dbh->{ SQL_DBMS_VER },'GetInfo: SQL_DBMS_VER'
> + ,'Fetch: $dbh->{ SQL_DBMS_VER }');
> + # $dbh->trace( 0 );
> +
> + is( $dbh->get_info( SQL_DBMS_NAME ),'GetInfo: SQL_DBMS_NAME'
> + ,'Call: $dbh->get_info( SQL_DBMS_NAME )');
> +
> + }
> + # -----------------------------------------------------------------------------
> + __END__
> +
> + # -----------------------------------------------------------------------------
> + {
> + local $\ = "\n";
> + use DBI::Const();
> + use Benchmark();
> + my $t0 = new Benchmark;
> + while ( my ( $k, $v ) = each %DBI::Const::GetInfo )
> + { # x86 200 MHz 64Mb
> + # $dbh->get_info( $k ); # 0 wallclock secs ( 0.04 usr +
>0.00 sys = 0.04 CPU)
> + # print $k, ' => ', $dbh->get_info( $k ); # 0 wallclock secs ( 0.09 usr +
>0.06 sys = 0.15 CPU)
> + # $dbh->{ $k }; # 0 wallclock secs ( 0.10 usr +
>0.00 sys = 0.10 CPU)
> + # print $k, ' => ', $dbh->{ $k }; # 0 wallclock secs ( 0.14 usr +
>0.07 sys = 0.21 CPU)
> + }
> + print Benchmark::timestr( Benchmark::timediff( Benchmark->new, $t0 ) );
> + }