From 62a54a4610aceac11ebeff41a22d807feb00ce1e Mon Sep 17 00:00:00 2001 From: Brendan Byrd Date: Mon, 30 Apr 2018 12:51:43 -0400 Subject: [PATCH] Create DBD::SQLite::GetInfo with a more verbose set of data --- lib/DBD/SQLite.pm | 16 +-- lib/DBD/SQLite/GetInfo.pm | 288 ++++++++++++++++++++++++++++++++++++++ t/11_get_info.t | 55 ++++++++ 3 files changed, 347 insertions(+), 12 deletions(-) create mode 100644 lib/DBD/SQLite/GetInfo.pm create mode 100644 t/11_get_info.t diff --git a/lib/DBD/SQLite.pm b/lib/DBD/SQLite.pm index b9d04a7..48a02fb 100644 --- a/lib/DBD/SQLite.pm +++ b/lib/DBD/SQLite.pm @@ -245,19 +245,11 @@ sub ping { return $dbh->FETCH('Active') ? 1 : 0; } -sub _get_version { - return ( DBD::SQLite::db::FETCH($_[0], 'sqlite_version') ); -} - -my %info = ( - 17 => 'SQLite', # SQL_DBMS_NAME - 18 => \&_get_version, # SQL_DBMS_VER - 29 => '"', # SQL_IDENTIFIER_QUOTE_CHAR -); - sub get_info { - my($dbh, $info_type) = @_; - my $v = $info{int($info_type)}; + my ($dbh, $info_type) = @_; + + require DBD::SQLite::GetInfo; + my $v = $DBD::SQLite::GetInfo::info{int($info_type)}; $v = $v->($dbh) if ref $v eq 'CODE'; return $v; } diff --git a/lib/DBD/SQLite/GetInfo.pm b/lib/DBD/SQLite/GetInfo.pm new file mode 100644 index 0000000..083bfa4 --- /dev/null +++ b/lib/DBD/SQLite/GetInfo.pm @@ -0,0 +1,288 @@ +package DBD::SQLite::GetInfo; + +use 5.006; +use strict; +use warnings; + +use DBD::SQLite; + +# SQL_DRIVER_VER should be formatted as dd.dd.dddd +my $dbdversion = $DBD::SQLite::VERSION; +$dbdversion .= '_00' if $dbdversion =~ /^\d+\.\d+$/; +my $sql_driver_ver = sprintf("%02d.%02d.%04d", split(/[\._]/, $dbdversion)); + +# Full list of keys and their return types: DBI::Const::GetInfo::ODBC + +# Most of the key definitions can be gleaned from: +# +# https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetinfo-function + +our %info = ( + 20 => 'N', # SQL_ACCESSIBLE_PROCEDURES - No stored procedures to access + 19 => 'Y', # SQL_ACCESSIBLE_TABLES - SELECT access to all tables in table_info + 0 => 0, # SQL_ACTIVE_CONNECTIONS - No maximum connection limit + 116 => 0, # SQL_ACTIVE_ENVIRONMENTS - No "active environment" limit + 1 => 0, # SQL_ACTIVE_STATEMENTS - No concurrent activity limit + 169 => 127, # SQL_AGGREGATE_FUNCTIONS - Supports all SQL-92 aggregrate functions + 117 => 0, # SQL_ALTER_DOMAIN - No ALTER DOMAIN support + 86 => 1, # SQL_ALTER_TABLE - Only supports ADD COLUMN and table rename (not listed in enum) in ALTER TABLE statements + 10021 => 0, # SQL_ASYNC_MODE - No asynchronous support (in vanilla SQLite) + 120 => 0, # SQL_BATCH_ROW_COUNT - No special row counting access + 121 => 0, # SQL_BATCH_SUPPORT - No batches + 82 => 0, # SQL_BOOKMARK_PERSISTENCE - No bookmark support + 114 => 1, # SQL_CATALOG_LOCATION - Database comes first in identifiers + 10003 => 'Y', # SQL_CATALOG_NAME - Supports database names + 41 => '.', # SQL_CATALOG_NAME_SEPARATOR - Separated by dot + 42 => 'database', # SQL_CATALOG_TERM - SQLite calls catalogs databases + 92 => 1+4+8, # SQL_CATALOG_USAGE - Supported in calls to DML & table/index definiton (no procedures or permissions) + 10004 => 'UTF-8', # SQL_COLLATION_SEQ - SQLite 3 uses UTF-8 by default + 87 => 'Y', # SQL_COLUMN_ALIAS - Supports column aliases + 22 => 0, # SQL_CONCAT_NULL_BEHAVIOR - 'a'||NULL = NULL + +# SQLite has no CONVERT function, only CAST. However, it converts to every "affinity" it supports. +# +# The only SQL_CVT_* types it doesn't support are date/time types, as it has no concept of +# date/time values once inserted. These are only convertable to text-like types. GUIDs are in +# the same boat, having no real means of switching to a numeric format. +# +# text/binary types = 31723265 +# numeric types = 28926 +# date/time types = 1802240 +# total = 33554431 + + 48 => 1, # SQL_CONVERT_FUNCTIONS - CAST only + + 53 => 31723265+28926, # SQL_CONVERT_BIGINT + 54 => 31723265+28926, # SQL_CONVERT_BINARY + 55 => 31723265+28926, # SQL_CONVERT_BIT + 56 => 33554431, # SQL_CONVERT_CHAR + 57 => 31723265+1802240, # SQL_CONVERT_DATE + 58 => 31723265+28926, # SQL_CONVERT_DECIMAL + 59 => 31723265+28926, # SQL_CONVERT_DOUBLE + 60 => 31723265+28926, # SQL_CONVERT_FLOAT + 173 => 31723265, # SQL_CONVERT_GUID + 61 => 31723265+28926, # SQL_CONVERT_INTEGER + 123 => 31723265+1802240, # SQL_CONVERT_INTERVAL_DAY_TIME + 124 => 31723265+1802240, # SQL_CONVERT_INTERVAL_YEAR_MONTH + 71 => 31723265+28926, # SQL_CONVERT_LONGVARBINARY + 62 => 31723265+28926, # SQL_CONVERT_LONGVARCHAR + 63 => 31723265+28926, # SQL_CONVERT_NUMERIC + 64 => 31723265+28926, # SQL_CONVERT_REAL + 65 => 31723265+28926, # SQL_CONVERT_SMALLINT + 66 => 31723265+1802240, # SQL_CONVERT_TIME + 67 => 31723265+1802240, # SQL_CONVERT_TIMESTAMP + 68 => 31723265+28926, # SQL_CONVERT_TINYINT + 69 => 33554431, # SQL_CONVERT_VARBINARY + 70 => 33554431, # SQL_CONVERT_VARCHAR + 122 => 33554431, # SQL_CONVERT_WCHAR + 125 => 33554431, # SQL_CONVERT_WLONGVARCHAR + 126 => 33554431, # SQL_CONVERT_WVARCHAR + + 74 => 1, # SQL_CORRELATION_NAME - Table aliases are supported, but must be named differently + 127 => 0, # SQL_CREATE_ASSERTION - No CREATE ASSERTION support + 128 => 0, # SQL_CREATE_CHARACTER_SET - No CREATE CHARACTER SET support + 129 => 0, # SQL_CREATE_COLLATION - No CREATE COLLATION support + 130 => 0, # SQL_CREATE_DOMAIN - No CREATE DOMAIN support + 131 => 0, # SQL_CREATE_SCHEMA - No CREATE SCHEMA support + 132 => 16383-2-8-4096, # SQL_CREATE_TABLE - Most of the functionality of CREATE TABLE support + 133 => 0, # SQL_CREATE_TRANSLATION - No CREATE TRANSLATION support + 134 => 1, # SQL_CREATE_VIEW - CREATE VIEW, no WITH CHECK OPTION support + + 23 => 2, # SQL_CURSOR_COMMIT_BEHAVIOR - Cursors are preserved + 24 => 2, # SQL_CURSOR_ROLLBACK_BEHAVIOR - Cursors are preserved + 10001 => 0, # SQL_CURSOR_SENSITIVITY - Cursors have a concept of snapshots, though this depends on the transaction type + + 2 => \&sql_data_source_name, # SQL_DATA_SOURCE_NAME - The DSN + 25 => \&sql_data_source_read_only, # SQL_DATA_SOURCE_READ_ONLY - Might have a SQLITE_OPEN_READONLY flag + 16 => \&sql_database_name, # SQL_DATABASE_NAME - Self-explanatory + 119 => 0, # SQL_DATETIME_LITERALS - No support for SQL-92's super weird date/time literal format (ie: {d '2999-12-12'}) + 17 => 'SQLite', # SQL_DBMS_NAME - You are here + 18 => \&sql_dbms_ver, # SQL_DBMS_VER - This driver version + 170 => 1+2, # SQL_DDL_INDEX - Supports CREATE/DROP INDEX + 26 => 8, # SQL_DEFAULT_TXN_ISOLATION - Default is SERIALIZABLE (See "PRAGMA read_uncommitted") + 10002 => 'N', # SQL_DESCRIBE_PARAMETER - No DESCRIBE INPUT support + +# XXX: MySQL/Oracle fills in HDBC and HENV, but information on what should actually go there is +# hard to acquire. + +# 171 => undef, # SQL_DM_VER - Not a Driver Manager +# 3 => undef, # SQL_DRIVER_HDBC - Not a Driver Manager +# 135 => undef, # SQL_DRIVER_HDESC - Not a Driver Manager +# 4 => undef, # SQL_DRIVER_HENV - Not a Driver Manager +# 76 => undef, # SQL_DRIVER_HLIB - Not a Driver Manager +# 5 => undef, # SQL_DRIVER_HSTMT - Not a Driver Manager + 6 => 'libsqlite3odbc.so', # SQL_DRIVER_NAME - SQLite3 ODBC driver (if installed) + 77 => '03.00', # SQL_DRIVER_ODBC_VER - Same as sqlite3odbc.c + 7 => $sql_driver_ver, # SQL_DRIVER_VER - Self-explanatory + + 136 => 0, # SQL_DROP_ASSERTION - No DROP ASSERTION support + 137 => 0, # SQL_DROP_CHARACTER_SET - No DROP CHARACTER SET support + 138 => 0, # SQL_DROP_COLLATION - No DROP COLLATION support + 139 => 0, # SQL_DROP_DOMAIN - No DROP DOMAIN support + 140 => 0, # SQL_DROP_SCHEMA - No DROP SCHEMA support + 141 => 1, # SQL_DROP_TABLE - DROP TABLE support, no RESTRICT/CASCADE + 142 => 0, # SQL_DROP_TRANSLATION - No DROP TRANSLATION support + 143 => 1, # SQL_DROP_VIEW - DROP VIEW support, no RESTRICT/CASCADE + +# NOTE: This is based purely on what sqlite3odbc supports. +# +# Static CA1: NEXT, ABSOLUTE, RELATIVE, BOOKMARK, LOCK_NO_CHANGE, POSITION, UPDATE, DELETE, REFRESH, +# BULK_ADD, BULK_UPDATE_BY_BOOKMARK, BULK_DELETE_BY_BOOKMARK = 466511 +# +# Forward-only CA1: NEXT, BOOKMARK +# +# CA2: READ_ONLY_CONCURRENCY, LOCK_CONCURRENCY + + 144 => 0, # SQL_DYNAMIC_CURSOR_ATTRIBUTES1 - No dynamic cursor support + 145 => 0, # SQL_DYNAMIC_CURSOR_ATTRIBUTES2 - No dynamic cursor support + 146 => 1+8, # SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1 + 147 => 1+2, # SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2 + 150 => 0, # SQL_KEYSET_CURSOR_ATTRIBUTES1 - No keyset cursor support + 151 => 0, # SQL_KEYSET_CURSOR_ATTRIBUTES2 - No keyset cursor support + 167 => 466511, # SQL_STATIC_CURSOR_ATTRIBUTES1 + 168 => 1+2, # SQL_STATIC_CURSOR_ATTRIBUTES2 + + 27 => 'Y', # SQL_EXPRESSIONS_IN_ORDERBY - ORDER BY allows expressions + 8 => 63, # SQL_FETCH_DIRECTION - Cursors support next, first, last, prior, absolute, relative + 84 => 2, # SQL_FILE_USAGE - Single-tier driver, treats files as databases + 81 => 1+2+8, # SQL_GETDATA_EXTENSIONS - Same as sqlite3odbc.c + 88 => 3, # SQL_GROUP_BY - SELECT columns are independent of GROUP BY columns + 28 => 4, # SQL_IDENTIFIER_CASE - Not case-sensitive, stored in mixed case + 29 => '"', # SQL_IDENTIFIER_QUOTE_CHAR - Uses " for identifiers, though supports [] and ` as well + 148 => 0, # SQL_INDEX_KEYWORDS - No support for ASC/DESC/ALL for CREATE INDEX + 149 => 0, # SQL_INFO_SCHEMA_VIEWS - No support for INFORMATION_SCHEMA + 172 => 1+2, # SQL_INSERT_STATEMENT - INSERT...VALUES & INSERT...SELECT + 73 => 'N', # SQL_INTEGRITY - No support for "Integrity Enhancement Facility" + 89 => \&sql_keywords, # SQL_KEYWORDS - List of non-ODBC keywords + 113 => 'Y', # SQL_LIKE_ESCAPE_CLAUSE - Supports LIKE...ESCAPE + 78 => 1, # SQL_LOCK_TYPES - Only NO_CHANGE + + 10022 => 0, # SQL_MAX_ASYNC_CONCURRENT_STATEMENTS - No async mode + 112 => 1_000_000, # SQL_MAX_BINARY_LITERAL_LEN - SQLITE_MAX_SQL_LENGTH + 34 => 1_000_000, # SQL_MAX_CATALOG_NAME_LEN - SQLITE_MAX_SQL_LENGTH + 108 => 1_000_000, # SQL_MAX_CHAR_LITERAL_LEN - SQLITE_MAX_SQL_LENGTH + 97 => 2000, # SQL_MAX_COLUMNS_IN_GROUP_BY - SQLITE_MAX_COLUMN + 98 => 2000, # SQL_MAX_COLUMNS_IN_INDEX - SQLITE_MAX_COLUMN + 99 => 2000, # SQL_MAX_COLUMNS_IN_ORDER_BY - SQLITE_MAX_COLUMN + 100 => 2000, # SQL_MAX_COLUMNS_IN_SELECT - SQLITE_MAX_COLUMN + 101 => 2000, # SQL_MAX_COLUMNS_IN_TABLE - SQLITE_MAX_COLUMN + 30 => 1_000_000, # SQL_MAX_COLUMN_NAME_LEN - SQLITE_MAX_SQL_LENGTH + 1 => 1021, # SQL_MAX_CONCURRENT_ACTIVITIES - Typical filehandle limits + 31 => 1_000_000, # SQL_MAX_CURSOR_NAME_LEN - SQLITE_MAX_SQL_LENGTH + 0 => 1021, # SQL_MAX_DRIVER_CONNECTIONS - Typical filehandle limits + 10005 => 1_000_000, # SQL_MAX_IDENTIFIER_LEN - SQLITE_MAX_SQL_LENGTH + 102 => 2147483646*65536, # SQL_MAX_INDEX_SIZE - Tied to DB size, which is theortically 140TB + 32 => 1_000_000, # SQL_MAX_OWNER_NAME_LEN - SQLITE_MAX_SQL_LENGTH + 33 => 1_000_000, # SQL_MAX_PROCEDURE_NAME_LEN - SQLITE_MAX_SQL_LENGTH + 34 => 1_000_000, # SQL_MAX_QUALIFIER_NAME_LEN - SQLITE_MAX_SQL_LENGTH + 104 => 1_000_000, # SQL_MAX_ROW_SIZE - SQLITE_MAX_SQL_LENGTH (since INSERT has to be used) + 103 => 'Y', # SQL_MAX_ROW_SIZE_INCLUDES_LONG + 32 => 1_000_000, # SQL_MAX_SCHEMA_NAME_LEN - SQLITE_MAX_SQL_LENGTH + 105 => 1_000_000, # SQL_MAX_STATEMENT_LEN - SQLITE_MAX_SQL_LENGTH + 106 => 64, # SQL_MAX_TABLES_IN_SELECT - 64 tables, because of the bitmap in the query optimizer + 35 => 1_000_000, # SQL_MAX_TABLE_NAME_LEN - SQLITE_MAX_SQL_LENGTH + 107 => 0, # SQL_MAX_USER_NAME_LEN - No user support + + 37 => 'Y', # SQL_MULTIPLE_ACTIVE_TXN - Supports mulitple txns, though not nested + 36 => 'N', # SQL_MULT_RESULT_SETS - No batches + 111 => 'N', # SQL_NEED_LONG_DATA_LEN - Doesn't care about LONG + 75 => 1, # SQL_NON_NULLABLE_COLUMNS - Supports NOT NULL + 85 => 1, # SQL_NULL_COLLATION - NULLs first on ASC (low end) + 49 => 4194304+1, # SQL_NUMERIC_FUNCTIONS - Just ABS & ROUND (has RANDOM, but not RAND) + + 9 => 1, # SQL_ODBC_API_CONFORMANCE - Same as sqlite3odbc.c + 152 => 1, # SQL_ODBC_INTERFACE_CONFORMANCE - Same as sqlite3odbc.c + 12 => 0, # SQL_ODBC_SAG_CLI_CONFORMANCE - Same as sqlite3odbc.c + 15 => 0, # SQL_ODBC_SQL_CONFORMANCE - Same as sqlite3odbc.c + 10 => '03.00', # SQL_ODBC_VER - Same as sqlite3odbc.c + + 115 => 1+8+16+32+64, # SQL_OJ_CAPABILITIES - Supports all OUTER JOINs except RIGHT & FULL + 90 => 'N', # SQL_ORDER_BY_COLUMNS_IN_SELECT - ORDER BY columns don't have to be in the SELECT list + 38 => 'Y', # SQL_OUTER_JOINS - Supports OUTER JOINs + 153 => 2, # SQL_PARAM_ARRAY_ROW_COUNTS - Only has row counts for executed statements + 154 => 3, # SQL_PARAM_ARRAY_SELECTS - No support for arrays of parameters + 80 => 0, # SQL_POSITIONED_STATEMENTS - No support for positioned statements (WHERE CURRENT OF or SELECT FOR UPDATE) + 79 => 31, # SQL_POS_OPERATIONS - Supports all SQLSetPos operations + 21 => 'N', # SQL_PROCEDURES - No procedures + 40 => '', # SQL_PROCEDURE_TERM - No procedures + 93 => 4, # SQL_QUOTED_IDENTIFIER_CASE - Even quoted identifiers are case-insensitive + 11 => 'N', # SQL_ROW_UPDATES - No fancy cursor update support + 39 => '', # SQL_SCHEMA_TERM - No schemas + 91 => 0, # SQL_SCHEMA_USAGE - No schemas + 43 => 2, # SQL_SCROLL_CONCURRENCY - Updates/deletes on cursors lock the database + 44 => 1+16, # SQL_SCROLL_OPTIONS - Only supports static & forward-only cursors + 14 => '\\', # SQL_SEARCH_PATTERN_ESCAPE - Default escape character for LIKE is \ + 13 => \&sql_server_name, # SQL_SERVER_NAME - Just $dbh->{Name} + 94 => '', # SQL_SPECIAL_CHARACTERS - Other drivers tend to stick to the ASCII/Latin-1 range, and SQLite uses all of + # the lower 7-bit punctuation for other things + + 155 => 7, # SQL_SQL92_DATETIME_FUNCTIONS - Supports CURRENT_(DATE|TIME|TIMESTAMP) + 156 => 1+2+4+8, # SQL_SQL92_FOREIGN_KEY_DELETE_RULE - Support all ON DELETE options + 157 => 1+2+4+8, # SQL_SQL92_FOREIGN_KEY_UPDATE_RULE - Support all ON UPDATE options + 158 => 0, # SQL_SQL92_GRANT - No users; no support for GRANT + 159 => 0, # SQL_SQL92_NUMERIC_VALUE_FUNCTIONS - No support for any of the listed functions + 160 => 1+2+4+512+1024+2048+4096+8192, # SQL_SQL92_PREDICATES - Supports the important comparison operators + 161 => 2+16+64+128, # SQL_SQL92_RELATIONAL_JOIN_OPERATORS - Supports the important ones except RIGHT/FULL OUTER JOINs + 162 => 0, # SQL_SQL92_REVOKE - No users; no support for REVOKE + 163 => 1+2+8, # SQL_SQL92_ROW_VALUE_CONSTRUCTOR - Supports most row value constructors + 164 => 2+4, # SQL_SQL92_STRING_FUNCTIONS - Just UPPER & LOWER (has SUBSTR, but not SUBSTRING and SQL-92's weird TRIM syntax) + 165 => 1+2+4+8, # SQL_SQL92_VALUE_EXPRESSIONS - Supports all SQL-92 value expressions + + 118 => 1, # SQL_SQL_CONFORMANCE - SQL-92 Entry level + 83 => 0, # SQL_STATIC_SENSITIVITY - Cursors would lock the DB, so only old data is visible + 50 => 8+16+256+1024+16384+131072, # SQL_STRING_FUNCTIONS - LTRIM, LENGTH, REPLACE, RTRIM, CHAR, SOUNDEX + 95 => 1+2+4+8+16, # SQL_SUBQUERIES - Supports all of the subquery types + 51 => 4, # SQL_SYSTEM_FUNCTIONS - Only IFNULL + 45 => 'table', # SQL_TABLE_TERM - Tables are called tables + 109 => 0, # SQL_TIMEDATE_ADD_INTERVALS - No support for INTERVAL + 110 => 0, # SQL_TIMEDATE_DIFF_INTERVALS - No support for INTERVAL + 52 => 0x20000+0x40000+0x80000, # SQL_TIMEDATE_FUNCTIONS - Only supports CURRENT_(DATE|TIME|TIMESTAMP) + 46 => 2, # SQL_TXN_CAPABLE - Full transaction support for both DML & DDL + 72 => 1+8, # SQL_TXN_ISOLATION_OPTION - Supports read uncommitted and serializable + 96 => 1+2, # SQL_UNION - Supports UNION and UNION ALL + 47 => '', # SQL_USER_NAME - No users + + 166 => 1, # SQL_STANDARD_CLI_CONFORMANCE - X/Open CLI Version 1.0 + 10000 => 1992, # SQL_XOPEN_CLI_YEAR - Year for V1.0 +); + +sub sql_dbms_ver { + my $dbh = shift; + return $dbh->FETCH('sqlite_version'); +} + +sub sql_data_source_name { + my $dbh = shift; + return "dbi:SQLite:".$dbh->{Name}; +} + +sub sql_data_source_read_only { + my $dbh = shift; + my $flags = $dbh->FETCH('sqlite_open_flags') || 0; + return $dbh->{ReadOnly} || ($flags & DBD::SQLite::OPEN_READONLY()) ? 'Y' : 'N'; +} + +sub sql_database_name { + my $dbh = shift; + my $databases = $dbh->selectall_hashref('PRAGMA database_list', 'seq'); + return $databases->{0}{name}; +} + +sub sql_keywords { + # SQLite keywords minus ODBC keywords + return join ',', (qw< + ABORT AFTER ANALYZE ATTACH AUTOINCREMENT BEFORE CONFLICT DATABASE DETACH EACH EXCLUSIVE + EXPLAIN FAIL GLOB IF IGNORE INDEXED INSTEAD ISNULL LIMIT NOTNULL OFFSET + PLAN PRAGMA QUERY RAISE RECURSIVE REGEXP REINDEX RELEASE RENAME REPLACE ROW + SAVEPOINT TEMP TRIGGER VACUUM VIRTUAL WITHOUT + >); +} + +sub sql_server_name { + my $dbh = shift; + return $dbh->{Name}; +} + +1; + +__END__ diff --git a/t/11_get_info.t b/t/11_get_info.t new file mode 100644 index 0000000..3477ff4 --- /dev/null +++ b/t/11_get_info.t @@ -0,0 +1,55 @@ +#!/usr/bin/perl + +use strict; +BEGIN { + $| = 1; + $^W = 1; +} + +use lib "t/lib"; +use SQLiteTest; +use Test::More; +use Test::NoWarnings; + +use DBI::Const::GetInfoType; + +# NOTE: These are tests for just a very basic set of get_info variables. + +my %info = ( + SQL_CATALOG_LOCATION => 1, + SQL_CATALOG_NAME => 'Y', + SQL_CATALOG_NAME_SEPARATOR => '.', + SQL_CATALOG_TERM => 'database', + + # some of these are dynamic, but always the same for connect_ok + SQL_DATA_SOURCE_NAME => qr/^dbi:SQLite:dbname=/, + SQL_DATA_SOURCE_READ_ONLY => 'N', + SQL_DATABASE_NAME => 'main', + SQL_DBMS_NAME => 'SQLite', + SQL_DBMS_VER => qr/^[1-9]+\.\d+\.\d+$/, + + SQL_IDENTIFIER_QUOTE_CHAR => '"', + + SQL_MAX_IDENTIFIER_LEN => qr/^[1-9]\d+$/, + SQL_MAX_TABLE_NAME_LEN => qr/^[1-9]\d+$/, + + SQL_KEYWORDS => qr/^(?:\w+,)+\w+$/, + + SQL_SEARCH_PATTERN_ESCAPE => '\\', + SQL_SERVER_NAME => qr/^dbname=/, + + SQL_TABLE_TERM => 'table', +); + +plan tests => scalar(keys %info) + 2; + +my $dbh = connect_ok( RaiseError => 1 ); + +foreach my $option ( sort keys %info ) { + my $value = $dbh->get_info( $GetInfoType{$option} ); + my $check = $info{$option}; + if (ref $check eq 'Regexp') { like($value, $check, $option); } + else { is ($value, $check, $option); } +} + +$dbh->disconnect;