mirror of
https://github.com/DBD-SQLite/DBD-SQLite
synced 2025-06-08 06:38:12 -04:00
Compare commits
No commits in common. "master" and "1.63_05" have entirely different histories.
40 changed files with 31884 additions and 69018 deletions
35
.github/workflows/build.yml
vendored
35
.github/workflows/build.yml
vendored
|
@ -1,35 +0,0 @@
|
|||
name: build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
tags-ignore:
|
||||
- '*'
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
perl:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
perl-version:
|
||||
- '5.8-buster'
|
||||
- '5.10-buster'
|
||||
- '5.18-buster'
|
||||
- '5.20-buster'
|
||||
- '5.26'
|
||||
- 'latest'
|
||||
|
||||
container:
|
||||
image: perl:${{ matrix.perl-version }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: perl -V
|
||||
run: perl -V
|
||||
- name: Install dependencies
|
||||
run: curl -sL https://git.io/cpm | perl - install -g --with-recommends --with-test --with-configure --show-build-log-on-failure
|
||||
- name: Run tests
|
||||
run: perl Makefile.PL && make && make test
|
24
.github/workflows/build_mac.yml
vendored
24
.github/workflows/build_mac.yml
vendored
|
@ -1,24 +0,0 @@
|
|||
name: build_mac
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
tags-ignore:
|
||||
- '*'
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
perl:
|
||||
runs-on: macOS-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: perl -V
|
||||
run: perl -V
|
||||
- name: Install dependencies with develop
|
||||
run: curl -sL https://git.io/cpm | perl - install -g --with-recommends --with-test --with-configure --with-develop --show-build-log-on-failure
|
||||
- name: Run Makefile.PL
|
||||
run: perl Makefile.PL
|
||||
- name: Run tests
|
||||
run: make && make test
|
28
.github/workflows/build_windows.yml
vendored
28
.github/workflows/build_windows.yml
vendored
|
@ -1,28 +0,0 @@
|
|||
name: build_windows
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
tags-ignore:
|
||||
- '*'
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
perl:
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
# - name: Set up Perl
|
||||
# run: |
|
||||
# choco install strawberryperl
|
||||
# echo "##[add-path]C:\strawberry\c\bin;C:\strawberry\perl\site\bin;C:\strawberry\perl\bin"
|
||||
- name: perl -V
|
||||
run: perl -V
|
||||
- name: Install dependencies with develop
|
||||
run: curl -sL https://git.io/cpm | perl - install -g --with-recommends --with-test --with-configure --with-develop --show-build-log-on-failure
|
||||
- name: Run Makefile.PL
|
||||
run: perl Makefile.PL
|
||||
- name: Run tests
|
||||
run: gmake test
|
|
@ -1,4 +1,3 @@
|
|||
dist: trusty
|
||||
language: perl
|
||||
perl:
|
||||
# - "5.8.1"
|
||||
|
|
117
Changes
117
Changes
|
@ -1,122 +1,5 @@
|
|||
Changes for Perl extension DBD-SQLite
|
||||
|
||||
1.76 2024-10-19
|
||||
- Switched to a production version
|
||||
|
||||
1.75_01 2024-09-17
|
||||
- Upgraded SQLite to 3.46.1
|
||||
- Fix for Windows quadmath builds (GH#115, sisyphus++)
|
||||
- Omit load_extension if static build
|
||||
|
||||
1.74 2023-09-20
|
||||
- Switched to a production version
|
||||
|
||||
1.73_01 2023-07-09
|
||||
- Upgraded SQLite to 3.42.0
|
||||
- Add missing possible table_type values to POD (GH#105, dboehmer++)
|
||||
|
||||
1.72 2022-11-04
|
||||
- Switched to a production version
|
||||
|
||||
1.71_07 2022-10-26
|
||||
- Upgraded SQLite to 3.39.4
|
||||
|
||||
1.71_06 2022-03-12
|
||||
- Set UTF8CACHE to avoid slowdown with -DDEBUGGING (andk, Leont, FGasper)
|
||||
|
||||
1.71_05 2022-02-26
|
||||
- Fix another test failure on perl built with -DDEBUGGING
|
||||
- Lowercase datatype in table column metadata for backcompat
|
||||
|
||||
1.71_04 2022-02-26
|
||||
- Fix test failure on perl built with -DDEBUGGING (andk++)
|
||||
|
||||
1.71_03 2022-02-23
|
||||
- Upgraded SQLite to 3.38.0
|
||||
- Expose sqlite_error_offset introduced in 3.38.0
|
||||
|
||||
1.71_02 2022-01-07
|
||||
- Upgraded SQLite to 3.37.2
|
||||
- Improve sqlite_load_extension doc (GH#94, Derek Lamb++)
|
||||
|
||||
1.71_01 2021-12-02
|
||||
- Upgraded SQLite to 3.37.0
|
||||
- Add a feature to unregister a created function
|
||||
- Fix accented characters in POD (GH#90, HaraldJoerg++)
|
||||
|
||||
1.70 2021-08-01
|
||||
- Switched to a production version
|
||||
|
||||
1.69_02 2021-07-30
|
||||
- Fix doc to use the correct attribute with sqlite_ (GH#86, eekboek++)
|
||||
- Modify the fix to silence the sqlite_unicode warning not to check
|
||||
the attribute twice
|
||||
- Fix an encoding issue of naive (GH#83, HaraldJoerg++)
|
||||
|
||||
1.69_01 2021-07-30
|
||||
- Typo (GH#85, grr++)
|
||||
- Silenced deprecation warning of sqlite_unicode not to break
|
||||
tests of existing applications
|
||||
|
||||
1.68 2021-07-22
|
||||
- Switched to a production version
|
||||
|
||||
1.67_07 2021-06-19
|
||||
- Upgraded SQLite to 3.36.0
|
||||
|
||||
1.67_06 2021-06-14
|
||||
- Experiment with another quadmath patch to see if it works
|
||||
with an older version of FreeBSD
|
||||
|
||||
1.67_05 2021-06-13
|
||||
- Made DBD_SQLITE_STRING_MODE constants exportable
|
||||
|
||||
1.67_04 2021-05-31
|
||||
- Upgraded SQLite to 3.35.5
|
||||
- Stop setting THREADSAFE=0 if perl has pthread (ie. 5.20+)
|
||||
(Bjoern Hoehrmann++, GH#69, #72)
|
||||
- Fixed a memory leak in ::VirtualTable
|
||||
- Introduced "string_mode" handle attribute (Felipe Gasper++)
|
||||
to fix long-standing issues of sqlite_unicode (GH#78, #68)
|
||||
- Added a dependency from dbdimp.o to the *.inc files included
|
||||
into dbdimp.c (Laurent Dami++, GH#74)
|
||||
- Fixed an offset issue of VirtualTable (Laurent Dami++, GH#75)
|
||||
|
||||
1.67_03 2021-03-31
|
||||
- Upgraded SQLite to 3.35.3
|
||||
- Enabled math functions introduced in SQLite 3.35
|
||||
- Fix quadmath issues (Tux++, leont++)
|
||||
|
||||
1.67_02 2020-12-06
|
||||
- Upgraded SQLite to 3.34.0
|
||||
- Added a few new constants
|
||||
- Added sqlite_txn_state method to see internal state
|
||||
of the backend
|
||||
|
||||
1.67_01 2020-11-24
|
||||
- Switched to XSLoader (GH#63; toddr++)
|
||||
- Use quadmath_snprintf if USE_QUADMATH is defined
|
||||
- Use av_fetch instead of av_shift (norimy++)
|
||||
|
||||
1.66 2020-08-30
|
||||
- Switched to a production version
|
||||
|
||||
1.65_03 2020-07-27
|
||||
- Upgraded SQLite to 3.32.3
|
||||
|
||||
1.65_02 2020-02-08
|
||||
- Upgraded SQLite to 3.31.1
|
||||
|
||||
1.65_01 2020-01-18
|
||||
- Upgraded SQLite to 3.30.1
|
||||
- Added several SQL_ types as alias (pali++)
|
||||
- Fixed two initialization issues (ppisar++)
|
||||
- Allowed create_function to return an array reference
|
||||
to specify the type of the value
|
||||
|
||||
1.64 2019-08-12
|
||||
- Switched to a production version
|
||||
|
||||
1.63_05 2019-07-12
|
||||
- Upgraded SQLite to 3.29.0
|
||||
- Added sqlite_get_autocommit private method (GH#52)
|
||||
|
|
16
Makefile.PL
16
Makefile.PL
|
@ -236,7 +236,6 @@ my @CC_DEFINE = (
|
|||
# '-DSQLITE_ENABLE_STAT4', # for sqlite >= 3.8.3.1
|
||||
'-DSQLITE_ENABLE_JSON1', # for sqlite >= 3.9.0
|
||||
'-DSQLITE_ENABLE_FTS5', # for sqlite >= 3.9.0
|
||||
'-DSQLITE_ENABLE_MATH_FUNCTIONS', # for sqlite >= 3.35.0
|
||||
'-DNDEBUG=1',
|
||||
);
|
||||
|
||||
|
@ -262,7 +261,7 @@ if ( $^O eq 'cygwin') {
|
|||
if ( $Config{d_usleep} || $Config{osname} =~ m/linux/ ) {
|
||||
push @CC_DEFINE, '-DHAVE_USLEEP=1';
|
||||
}
|
||||
if ( !$Config{usethreads} and $Config{libs} !~ /pthread/ ) {
|
||||
unless ( $Config{usethreads} ) {
|
||||
push @CC_DEFINE, '-DTHREADSAFE=0';
|
||||
}
|
||||
if ($^O eq 'hpux' and $Config{osvers} <= 10.20) {
|
||||
|
@ -288,18 +287,8 @@ if ($^O =~ /bsd/i && $^O !~ /(?:open|net)bsd/) {
|
|||
push @CC_DEFINE, '-D_XOPEN_SOURCE';
|
||||
}
|
||||
|
||||
if (!$Config{usedl}) {
|
||||
push @CC_DEFINE, '-DSQLITE_OMIT_LOAD_EXTENSION';
|
||||
}
|
||||
|
||||
my (@CCFLAGS, @LDFLAGS, @LDDLFLAGS);
|
||||
|
||||
if ($ENV{TEST_DBD_SQLITE_WITH_ASAN}) {
|
||||
push @CCFLAGS, '-fsanitize=address -static-libasan -fuse-ld=gold -fno-omit-frame-pointer -g -O2';
|
||||
push @LDFLAGS, '-fsanitize=address -static-libasan -fuse-ld=gold -fno-omit-frame-pointer -g -O2';
|
||||
push @LDDLFLAGS, '-fsanitize=address -static-libasan -fuse-ld=gold -fno-omit-frame-pointer -g -O2';
|
||||
}
|
||||
|
||||
# RT #70135: See if ld supports Bsymbolic;
|
||||
unless ($^O eq 'MSWin32' && $Config{ld} =~ /link/) {
|
||||
for my $path (File::Spec->path) {
|
||||
|
@ -404,9 +393,6 @@ WriteMakefile(
|
|||
? '$(O_FILES)'
|
||||
: 'SQLite.o dbdimp.o'
|
||||
),
|
||||
depend => {
|
||||
'dbdimp.o' => 'dbdimp_tokenizer.inc dbdimp_virtual_table.inc',
|
||||
},
|
||||
clean => {
|
||||
FILES => 'SQLite.xsi config.h tv.log *.old',
|
||||
},
|
||||
|
|
29
SQLite.xs
29
SQLite.xs
|
@ -380,35 +380,6 @@ get_autocommit(dbh)
|
|||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
static int
|
||||
txn_state(SV* dbh, SV *schema = &PL_sv_undef)
|
||||
ALIAS:
|
||||
DBD::SQLite::db::sqlite_txn_state = 1
|
||||
CODE:
|
||||
{
|
||||
RETVAL = sqlite_db_txn_state(aTHX_ dbh, schema);
|
||||
}
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
static int
|
||||
error_offset(dbh)
|
||||
SV *dbh
|
||||
ALIAS:
|
||||
DBD::SQLite::db::sqlite_error_offset = 1
|
||||
CODE:
|
||||
{
|
||||
#if SQLITE_VERSION_NUMBER >= 3038000
|
||||
D_imp_dbh(dbh);
|
||||
RETVAL = sqlite3_error_offset(imp_dbh->db);
|
||||
#else
|
||||
RETVAL = -1;
|
||||
#endif
|
||||
}
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
|
||||
MODULE = DBD::SQLite PACKAGE = DBD::SQLite::st
|
||||
|
||||
PROTOTYPES: DISABLE
|
||||
|
|
482
constants.inc
482
constants.inc
|
@ -5,41 +5,6 @@ MODULE = DBD::SQLite PACKAGE = DBD::SQLite::Constants
|
|||
|
||||
PROTOTYPES: ENABLE
|
||||
|
||||
BOOT:
|
||||
newCONSTSUB( gv_stashpv("DBD::SQLite::Constants", FALSE), "DBD_SQLITE_STRING_MODE_PV", newSVuv(DBD_SQLITE_STRING_MODE_PV) );
|
||||
newCONSTSUB( gv_stashpv("DBD::SQLite::Constants", FALSE), "DBD_SQLITE_STRING_MODE_BYTES", newSVuv(DBD_SQLITE_STRING_MODE_BYTES) );
|
||||
newCONSTSUB( gv_stashpv("DBD::SQLite::Constants", FALSE), "DBD_SQLITE_STRING_MODE_UNICODE_NAIVE", newSVuv(DBD_SQLITE_STRING_MODE_UNICODE_NAIVE) );
|
||||
newCONSTSUB( gv_stashpv("DBD::SQLite::Constants", FALSE), "DBD_SQLITE_STRING_MODE_UNICODE_FALLBACK", newSVuv(DBD_SQLITE_STRING_MODE_UNICODE_FALLBACK) );
|
||||
newCONSTSUB( gv_stashpv("DBD::SQLite::Constants", FALSE), "DBD_SQLITE_STRING_MODE_UNICODE_STRICT", newSVuv(DBD_SQLITE_STRING_MODE_UNICODE_STRICT) );
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3034000
|
||||
|
||||
IV
|
||||
_const_allowed_return_values_from_sqlite3_txn_state_3034000()
|
||||
ALIAS:
|
||||
SQLITE_TXN_NONE = SQLITE_TXN_NONE
|
||||
SQLITE_TXN_READ = SQLITE_TXN_READ
|
||||
SQLITE_TXN_WRITE = SQLITE_TXN_WRITE
|
||||
CODE:
|
||||
RETVAL = ix;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#else
|
||||
|
||||
IV
|
||||
_const_allowed_return_values_from_sqlite3_txn_state_3034000_zero()
|
||||
ALIAS:
|
||||
SQLITE_TXN_NONE = 1
|
||||
SQLITE_TXN_READ = 2
|
||||
SQLITE_TXN_WRITE = 3
|
||||
CODE:
|
||||
RETVAL = 0;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#endif
|
||||
|
||||
IV
|
||||
_const_authorizer_action_codes()
|
||||
ALIAS:
|
||||
|
@ -443,82 +408,6 @@ _const_database_connection_configuration_options_3029000_zero()
|
|||
|
||||
#endif
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3030000
|
||||
|
||||
IV
|
||||
_const_database_connection_configuration_options_3030000()
|
||||
ALIAS:
|
||||
SQLITE_DBCONFIG_ENABLE_VIEW = SQLITE_DBCONFIG_ENABLE_VIEW
|
||||
CODE:
|
||||
RETVAL = ix;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#else
|
||||
|
||||
IV
|
||||
_const_database_connection_configuration_options_3030000_zero()
|
||||
ALIAS:
|
||||
SQLITE_DBCONFIG_ENABLE_VIEW = 1
|
||||
CODE:
|
||||
RETVAL = 0;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#endif
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3031000
|
||||
|
||||
IV
|
||||
_const_database_connection_configuration_options_3031000()
|
||||
ALIAS:
|
||||
SQLITE_DBCONFIG_LEGACY_FILE_FORMAT = SQLITE_DBCONFIG_LEGACY_FILE_FORMAT
|
||||
SQLITE_DBCONFIG_TRUSTED_SCHEMA = SQLITE_DBCONFIG_TRUSTED_SCHEMA
|
||||
CODE:
|
||||
RETVAL = ix;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#else
|
||||
|
||||
IV
|
||||
_const_database_connection_configuration_options_3031000_zero()
|
||||
ALIAS:
|
||||
SQLITE_DBCONFIG_LEGACY_FILE_FORMAT = 1
|
||||
SQLITE_DBCONFIG_TRUSTED_SCHEMA = 2
|
||||
CODE:
|
||||
RETVAL = 0;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#endif
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3042000
|
||||
|
||||
IV
|
||||
_const_database_connection_configuration_options_3042000()
|
||||
ALIAS:
|
||||
SQLITE_DBCONFIG_STMT_SCANSTATUS = SQLITE_DBCONFIG_STMT_SCANSTATUS
|
||||
SQLITE_DBCONFIG_REVERSE_SCANORDER = SQLITE_DBCONFIG_REVERSE_SCANORDER
|
||||
CODE:
|
||||
RETVAL = ix;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#else
|
||||
|
||||
IV
|
||||
_const_database_connection_configuration_options_3042000_zero()
|
||||
ALIAS:
|
||||
SQLITE_DBCONFIG_STMT_SCANSTATUS = 1
|
||||
SQLITE_DBCONFIG_REVERSE_SCANORDER = 2
|
||||
CODE:
|
||||
RETVAL = 0;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#endif
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3006002
|
||||
|
||||
IV
|
||||
|
@ -1135,158 +1024,6 @@ _const_extended_result_codes_3025000_zero()
|
|||
|
||||
#endif
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3031000
|
||||
|
||||
IV
|
||||
_const_extended_result_codes_3031000()
|
||||
ALIAS:
|
||||
SQLITE_CANTOPEN_SYMLINK = SQLITE_CANTOPEN_SYMLINK
|
||||
SQLITE_CONSTRAINT_PINNED = SQLITE_CONSTRAINT_PINNED
|
||||
SQLITE_OK_SYMLINK = SQLITE_OK_SYMLINK
|
||||
CODE:
|
||||
RETVAL = ix;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#else
|
||||
|
||||
IV
|
||||
_const_extended_result_codes_3031000_zero()
|
||||
ALIAS:
|
||||
SQLITE_CANTOPEN_SYMLINK = 1
|
||||
SQLITE_CONSTRAINT_PINNED = 2
|
||||
SQLITE_OK_SYMLINK = 3
|
||||
CODE:
|
||||
RETVAL = 0;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#endif
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3032000
|
||||
|
||||
IV
|
||||
_const_extended_result_codes_3032000()
|
||||
ALIAS:
|
||||
SQLITE_IOERR_DATA = SQLITE_IOERR_DATA
|
||||
SQLITE_BUSY_TIMEOUT = SQLITE_BUSY_TIMEOUT
|
||||
SQLITE_CORRUPT_INDEX = SQLITE_CORRUPT_INDEX
|
||||
CODE:
|
||||
RETVAL = ix;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#else
|
||||
|
||||
IV
|
||||
_const_extended_result_codes_3032000_zero()
|
||||
ALIAS:
|
||||
SQLITE_IOERR_DATA = 1
|
||||
SQLITE_BUSY_TIMEOUT = 2
|
||||
SQLITE_CORRUPT_INDEX = 3
|
||||
CODE:
|
||||
RETVAL = 0;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#endif
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3034000
|
||||
|
||||
IV
|
||||
_const_extended_result_codes_3034000()
|
||||
ALIAS:
|
||||
SQLITE_IOERR_CORRUPTFS = SQLITE_IOERR_CORRUPTFS
|
||||
CODE:
|
||||
RETVAL = ix;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#else
|
||||
|
||||
IV
|
||||
_const_extended_result_codes_3034000_zero()
|
||||
ALIAS:
|
||||
SQLITE_IOERR_CORRUPTFS = 1
|
||||
CODE:
|
||||
RETVAL = 0;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#endif
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3037000
|
||||
|
||||
IV
|
||||
_const_extended_result_codes_3037000()
|
||||
ALIAS:
|
||||
SQLITE_CONSTRAINT_DATATYPE = SQLITE_CONSTRAINT_DATATYPE
|
||||
CODE:
|
||||
RETVAL = ix;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#else
|
||||
|
||||
IV
|
||||
_const_extended_result_codes_3037000_zero()
|
||||
ALIAS:
|
||||
SQLITE_CONSTRAINT_DATATYPE = 1
|
||||
CODE:
|
||||
RETVAL = 0;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#endif
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3041000
|
||||
|
||||
IV
|
||||
_const_extended_result_codes_3041000()
|
||||
ALIAS:
|
||||
SQLITE_NOTICE_RBU = SQLITE_NOTICE_RBU
|
||||
CODE:
|
||||
RETVAL = ix;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#else
|
||||
|
||||
IV
|
||||
_const_extended_result_codes_3041000_zero()
|
||||
ALIAS:
|
||||
SQLITE_NOTICE_RBU = 1
|
||||
CODE:
|
||||
RETVAL = 0;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#endif
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3043000
|
||||
|
||||
IV
|
||||
_const_extended_result_codes_3043000()
|
||||
ALIAS:
|
||||
SQLITE_IOERR_IN_PAGE = SQLITE_IOERR_IN_PAGE
|
||||
CODE:
|
||||
RETVAL = ix;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#else
|
||||
|
||||
IV
|
||||
_const_extended_result_codes_3043000_zero()
|
||||
ALIAS:
|
||||
SQLITE_IOERR_IN_PAGE = 1
|
||||
CODE:
|
||||
RETVAL = 0;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#endif
|
||||
|
||||
IV
|
||||
_const_flags_for_file_open_operations()
|
||||
ALIAS:
|
||||
|
@ -1397,78 +1134,6 @@ _const_flags_for_file_open_operations_3007013_zero()
|
|||
|
||||
#endif
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3031000
|
||||
|
||||
IV
|
||||
_const_flags_for_file_open_operations_3031000()
|
||||
ALIAS:
|
||||
SQLITE_OPEN_NOFOLLOW = SQLITE_OPEN_NOFOLLOW
|
||||
CODE:
|
||||
RETVAL = ix;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#else
|
||||
|
||||
IV
|
||||
_const_flags_for_file_open_operations_3031000_zero()
|
||||
ALIAS:
|
||||
SQLITE_OPEN_NOFOLLOW = 1
|
||||
CODE:
|
||||
RETVAL = 0;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#endif
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3033000
|
||||
|
||||
IV
|
||||
_const_flags_for_file_open_operations_3033000()
|
||||
ALIAS:
|
||||
SQLITE_OPEN_SUPER_JOURNAL = SQLITE_OPEN_SUPER_JOURNAL
|
||||
CODE:
|
||||
RETVAL = ix;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#else
|
||||
|
||||
IV
|
||||
_const_flags_for_file_open_operations_3033000_zero()
|
||||
ALIAS:
|
||||
SQLITE_OPEN_SUPER_JOURNAL = 1
|
||||
CODE:
|
||||
RETVAL = 0;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#endif
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3037000
|
||||
|
||||
IV
|
||||
_const_flags_for_file_open_operations_3037000()
|
||||
ALIAS:
|
||||
SQLITE_OPEN_EXRESCODE = SQLITE_OPEN_EXRESCODE
|
||||
CODE:
|
||||
RETVAL = ix;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#else
|
||||
|
||||
IV
|
||||
_const_flags_for_file_open_operations_3037000_zero()
|
||||
ALIAS:
|
||||
SQLITE_OPEN_EXRESCODE = 1
|
||||
CODE:
|
||||
RETVAL = 0;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#endif
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3008003
|
||||
|
||||
IV
|
||||
|
@ -1493,80 +1158,6 @@ _const_function_flags_3008003_zero()
|
|||
|
||||
#endif
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3030000
|
||||
|
||||
IV
|
||||
_const_function_flags_3030000()
|
||||
ALIAS:
|
||||
SQLITE_DIRECTONLY = SQLITE_DIRECTONLY
|
||||
SQLITE_SUBTYPE = SQLITE_SUBTYPE
|
||||
CODE:
|
||||
RETVAL = ix;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#else
|
||||
|
||||
IV
|
||||
_const_function_flags_3030000_zero()
|
||||
ALIAS:
|
||||
SQLITE_DIRECTONLY = 1
|
||||
SQLITE_SUBTYPE = 2
|
||||
CODE:
|
||||
RETVAL = 0;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#endif
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3031000
|
||||
|
||||
IV
|
||||
_const_function_flags_3031000()
|
||||
ALIAS:
|
||||
SQLITE_INNOCUOUS = SQLITE_INNOCUOUS
|
||||
CODE:
|
||||
RETVAL = ix;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#else
|
||||
|
||||
IV
|
||||
_const_function_flags_3031000_zero()
|
||||
ALIAS:
|
||||
SQLITE_INNOCUOUS = 1
|
||||
CODE:
|
||||
RETVAL = 0;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#endif
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3044001
|
||||
|
||||
IV
|
||||
_const_function_flags_3044001()
|
||||
ALIAS:
|
||||
SQLITE_RESULT_SUBTYPE = SQLITE_RESULT_SUBTYPE
|
||||
CODE:
|
||||
RETVAL = ix;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#else
|
||||
|
||||
IV
|
||||
_const_function_flags_3044001_zero()
|
||||
ALIAS:
|
||||
SQLITE_RESULT_SUBTYPE = 1
|
||||
CODE:
|
||||
RETVAL = 0;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#endif
|
||||
|
||||
IV
|
||||
_const_fundamental_datatypes()
|
||||
ALIAS:
|
||||
|
@ -1574,7 +1165,6 @@ _const_fundamental_datatypes()
|
|||
SQLITE_FLOAT = SQLITE_FLOAT
|
||||
SQLITE_BLOB = SQLITE_BLOB
|
||||
SQLITE_NULL = SQLITE_NULL
|
||||
SQLITE_TEXT = SQLITE_TEXT
|
||||
CODE:
|
||||
RETVAL = ix;
|
||||
OUTPUT:
|
||||
|
@ -1924,75 +1514,3 @@ _const__flags_for_file_open_operations_3007013_zero()
|
|||
|
||||
#endif
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3031000
|
||||
|
||||
IV
|
||||
_const__flags_for_file_open_operations_3031000()
|
||||
ALIAS:
|
||||
OPEN_NOFOLLOW = SQLITE_OPEN_NOFOLLOW
|
||||
CODE:
|
||||
RETVAL = ix;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#else
|
||||
|
||||
IV
|
||||
_const__flags_for_file_open_operations_3031000_zero()
|
||||
ALIAS:
|
||||
OPEN_NOFOLLOW = 1
|
||||
CODE:
|
||||
RETVAL = 0;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#endif
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3033000
|
||||
|
||||
IV
|
||||
_const__flags_for_file_open_operations_3033000()
|
||||
ALIAS:
|
||||
OPEN_SUPER_JOURNAL = SQLITE_OPEN_SUPER_JOURNAL
|
||||
CODE:
|
||||
RETVAL = ix;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#else
|
||||
|
||||
IV
|
||||
_const__flags_for_file_open_operations_3033000_zero()
|
||||
ALIAS:
|
||||
OPEN_SUPER_JOURNAL = 1
|
||||
CODE:
|
||||
RETVAL = 0;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#endif
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3037000
|
||||
|
||||
IV
|
||||
_const__flags_for_file_open_operations_3037000()
|
||||
ALIAS:
|
||||
OPEN_EXRESCODE = SQLITE_OPEN_EXRESCODE
|
||||
CODE:
|
||||
RETVAL = ix;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#else
|
||||
|
||||
IV
|
||||
_const__flags_for_file_open_operations_3037000_zero()
|
||||
ALIAS:
|
||||
OPEN_EXRESCODE = 1
|
||||
CODE:
|
||||
RETVAL = 0;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
#endif
|
||||
|
||||
|
|
5
cpanfile
5
cpanfile
|
@ -1,5 +0,0 @@
|
|||
requires 'DBI', '1.57';
|
||||
|
||||
on test => sub {
|
||||
requires 'Test::More', '0.88';
|
||||
};
|
398
dbdimp.c
398
dbdimp.c
|
@ -214,7 +214,6 @@ sqlite_type_from_odbc_type(int type)
|
|||
switch(type) {
|
||||
case SQL_UNKNOWN_TYPE:
|
||||
return SQLITE_NULL;
|
||||
case SQL_BOOLEAN:
|
||||
case SQL_INTEGER:
|
||||
case SQL_SMALLINT:
|
||||
case SQL_TINYINT:
|
||||
|
@ -224,11 +223,7 @@ sqlite_type_from_odbc_type(int type)
|
|||
case SQL_REAL:
|
||||
case SQL_DOUBLE:
|
||||
return SQLITE_FLOAT;
|
||||
case SQL_BIT:
|
||||
case SQL_BLOB:
|
||||
case SQL_BINARY:
|
||||
case SQL_VARBINARY:
|
||||
case SQL_LONGVARBINARY:
|
||||
return SQLITE_BLOB;
|
||||
default:
|
||||
return SQLITE_TEXT;
|
||||
|
@ -239,11 +234,11 @@ void
|
|||
init_cxt() {
|
||||
dTHX;
|
||||
MY_CXT_INIT;
|
||||
MY_CXT.last_dbh_string_mode = DBD_SQLITE_STRING_MODE_PV;
|
||||
MY_CXT.last_dbh_is_unicode = 0;
|
||||
}
|
||||
|
||||
SV *
|
||||
stacked_sv_from_sqlite3_value(pTHX_ sqlite3_value *value, dbd_sqlite_string_mode_t string_mode)
|
||||
stacked_sv_from_sqlite3_value(pTHX_ sqlite3_value *value, int is_unicode)
|
||||
{
|
||||
STRLEN len;
|
||||
sqlite_int64 iv;
|
||||
|
@ -271,7 +266,9 @@ stacked_sv_from_sqlite3_value(pTHX_ sqlite3_value *value, dbd_sqlite_string_mode
|
|||
case SQLITE_TEXT:
|
||||
len = sqlite3_value_bytes(value);
|
||||
sv = newSVpvn((const char *)sqlite3_value_text(value), len);
|
||||
DBD_SQLITE_UTF8_DECODE_IF_NEEDED(sv, string_mode);
|
||||
if (is_unicode) {
|
||||
SvUTF8_on(sv);
|
||||
}
|
||||
return sv_2mortal(sv);
|
||||
case SQLITE_BLOB:
|
||||
len = sqlite3_value_bytes(value);
|
||||
|
@ -292,9 +289,6 @@ sqlite_set_result(pTHX_ sqlite3_context *context, SV *result, int is_error)
|
|||
STRLEN len;
|
||||
char *s;
|
||||
sqlite3_int64 iv;
|
||||
AV *av;
|
||||
SV *result2, *type;
|
||||
SV **presult2, **ptype;
|
||||
|
||||
if ( is_error ) {
|
||||
s = SvPV(result, len);
|
||||
|
@ -305,33 +299,6 @@ sqlite_set_result(pTHX_ sqlite3_context *context, SV *result, int is_error)
|
|||
/* warn("result: %s\n", SvPV_nolen(result)); */
|
||||
if ( !SvOK(result) ) {
|
||||
sqlite3_result_null( context );
|
||||
} else if( SvROK(result) && SvTYPE(SvRV(result)) == SVt_PVAV ) {
|
||||
av = (AV*)SvRV(result);
|
||||
if ( av_len(av) == 1 ) {
|
||||
presult2 = av_fetch(av, 0, 0);
|
||||
ptype = av_fetch(av, 1, 0);
|
||||
result2 = presult2 ? *presult2 : &PL_sv_undef;
|
||||
type = ptype ? *ptype : &PL_sv_undef;
|
||||
if ( SvIOK(type) ) {
|
||||
switch(sqlite_type_from_odbc_type(SvIV(type))) {
|
||||
case SQLITE_INTEGER:
|
||||
sqlite3_result_int64( context, SvIV(result2) );
|
||||
return;
|
||||
case SQLITE_FLOAT:
|
||||
sqlite3_result_double( context, SvNV(result2) );
|
||||
return;
|
||||
case SQLITE_BLOB:
|
||||
s = SvPV(result2, len);
|
||||
sqlite3_result_blob( context, s, len, SQLITE_TRANSIENT );
|
||||
return;
|
||||
case SQLITE_TEXT:
|
||||
s = SvPV(result2, len);
|
||||
sqlite3_result_text( context, s, len, SQLITE_TRANSIENT );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlite3_result_error( context, "unexpected arrayref", 19 );
|
||||
} else if( SvIOK_UV(result) ) {
|
||||
if ((UV)(sqlite3_int64)UV_MAX == UV_MAX)
|
||||
sqlite3_result_int64( context, (sqlite3_int64)SvUV(result));
|
||||
|
@ -405,18 +372,8 @@ sqlite_is_number(pTHX_ const char *v, int sql_type)
|
|||
if (!_sqlite_atoi64(v, &iv)) return 1;
|
||||
}
|
||||
if (sql_type != SQLITE_INTEGER) {
|
||||
#ifdef USE_QUADMATH
|
||||
sprintf(format, (has_plus ? "+%%.%dQf" : "%%.%dQf"), precision);
|
||||
# if defined(WIN32)
|
||||
/* On Windows quadmath, we need to use strtoflt128(), not atov() */
|
||||
if (strEQ(form(format, strtoflt128(v, NULL)), v)) return 2;
|
||||
# else
|
||||
sprintf(format, (has_plus ? "+%%.%df" : "%%.%df"), precision);
|
||||
if (strEQ(form(format, atof(v)), v)) return 2;
|
||||
# endif
|
||||
#else
|
||||
sprintf(format, (has_plus ? "+%%.%df" : "%%.%df" ), precision);
|
||||
if (strEQ(form(format, atof(v)), v)) return 2;
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -439,44 +396,6 @@ sqlite_discon_all(SV *drh, imp_drh_t *imp_drh)
|
|||
return FALSE; /* no way to do this */
|
||||
}
|
||||
|
||||
#define _croak_invalid_value(name, value) \
|
||||
croak("Invalid value (%s) given for %s", value, name);
|
||||
|
||||
/* Like SvUV but croaks on anything other than an unsigned int. */
|
||||
static inline int
|
||||
my_SvUV_strict(pTHX_ SV *input, const char* name)
|
||||
{
|
||||
if (SvUOK(input)) {
|
||||
return SvUV(input);
|
||||
}
|
||||
|
||||
const char* pv = SvPVbyte_nolen(input);
|
||||
|
||||
UV uv;
|
||||
int numtype = grok_number(pv, strlen(pv), &uv);
|
||||
|
||||
/* Anything else is invalid: */
|
||||
if (numtype != IS_NUMBER_IN_UV) _croak_invalid_value(name, pv);
|
||||
|
||||
return uv;
|
||||
}
|
||||
|
||||
static inline dbd_sqlite_string_mode_t
|
||||
_extract_sqlite_string_mode_from_sv( pTHX_ SV* input )
|
||||
{
|
||||
if (SvOK(input)) {
|
||||
UV val = my_SvUV_strict(aTHX_ input, "sqlite_string_mode");
|
||||
|
||||
if (val >= _DBD_SQLITE_STRING_MODE_COUNT) {
|
||||
_croak_invalid_value("sqlite_string_mode", SvPVbyte_nolen(input));
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
return DBD_SQLITE_STRING_MODE_PV;
|
||||
}
|
||||
|
||||
int
|
||||
sqlite_db_login6(SV *dbh, imp_dbh_t *imp_dbh, char *dbname, char *user, char *pass, SV *attr)
|
||||
{
|
||||
|
@ -486,7 +405,7 @@ sqlite_db_login6(SV *dbh, imp_dbh_t *imp_dbh, char *dbname, char *user, char *pa
|
|||
SV **val;
|
||||
int extended = 0;
|
||||
int flag = 0;
|
||||
dbd_sqlite_string_mode_t string_mode = DBD_SQLITE_STRING_MODE_PV;
|
||||
int unicode = 0;
|
||||
|
||||
sqlite_trace(dbh, imp_dbh, 3, form("login '%s' (version %s)", dbname, sqlite3_version));
|
||||
|
||||
|
@ -509,24 +428,13 @@ sqlite_db_login6(SV *dbh, imp_dbh_t *imp_dbh, char *dbname, char *user, char *pa
|
|||
hv_stores(hv, "ReadOnly", newSViv(1));
|
||||
}
|
||||
}
|
||||
|
||||
/* sqlite_string_mode should be detected earlier, to register default functions correctly */
|
||||
|
||||
SV** string_mode_svp = hv_fetchs(hv, "sqlite_string_mode", 0);
|
||||
if (string_mode_svp != NULL && SvOK(*string_mode_svp)) {
|
||||
string_mode = _extract_sqlite_string_mode_from_sv(aTHX_ *string_mode_svp);
|
||||
|
||||
/* Legacy alternatives to sqlite_string_mode: */
|
||||
} else if (hv_exists(hv, "sqlite_unicode", 14)) {
|
||||
/* sqlite_unicode should be detected earlier, to register default functions correctly */
|
||||
if (hv_exists(hv, "sqlite_unicode", 14)) {
|
||||
val = hv_fetch(hv, "sqlite_unicode", 14, 0);
|
||||
if ( (val && SvOK(*val)) ? SvIV(*val) : 0 ) {
|
||||
string_mode = DBD_SQLITE_STRING_MODE_UNICODE_NAIVE;
|
||||
}
|
||||
unicode = (val && SvOK(*val)) ? SvIV(*val) : 0;
|
||||
} else if (hv_exists(hv, "unicode", 7)) {
|
||||
val = hv_fetch(hv, "unicode", 7, 0);
|
||||
if ( (val && SvOK(*val)) ? SvIV(*val) : 0 ) {
|
||||
string_mode = DBD_SQLITE_STRING_MODE_UNICODE_NAIVE;
|
||||
}
|
||||
unicode = (val && SvOK(*val)) ? SvIV(*val) : 0;
|
||||
}
|
||||
}
|
||||
rc = sqlite_open2(dbname, &(imp_dbh->db), flag, extended);
|
||||
|
@ -535,7 +443,7 @@ sqlite_db_login6(SV *dbh, imp_dbh_t *imp_dbh, char *dbname, char *user, char *pa
|
|||
}
|
||||
DBIc_IMPSET_on(imp_dbh);
|
||||
|
||||
imp_dbh->string_mode = string_mode;
|
||||
imp_dbh->unicode = unicode;
|
||||
imp_dbh->functions = newAV();
|
||||
imp_dbh->aggregates = newAV();
|
||||
imp_dbh->collation_needed_callback = newSVsv( &PL_sv_undef );
|
||||
|
@ -603,7 +511,9 @@ sqlite_db_do_sv(SV *dbh, imp_dbh_t *imp_dbh, SV *sv_statement)
|
|||
}
|
||||
|
||||
/* sqlite3_prepare wants an utf8-encoded SQL statement */
|
||||
DBD_SQLITE_PREP_SV_FOR_SQLITE(sv_statement, imp_dbh->string_mode);
|
||||
if (imp_dbh->unicode) {
|
||||
sv_utf8_upgrade(sv_statement);
|
||||
}
|
||||
|
||||
statement = SvPV_nolen(sv_statement);
|
||||
|
||||
|
@ -790,10 +700,6 @@ sqlite_db_destroy(SV *dbh, imp_dbh_t *imp_dbh)
|
|||
DBIc_IMPSET_off(imp_dbh);
|
||||
}
|
||||
|
||||
#define _warn_deprecated_if_possible(old, new) \
|
||||
if (DBIc_has(imp_dbh, DBIcf_WARN)) \
|
||||
warn("\"%s\" attribute will be deprecated. Use \"%s\" instead.", old, new);
|
||||
|
||||
int
|
||||
sqlite_db_STORE_attrib(SV *dbh, imp_dbh_t *imp_dbh, SV *keysv, SV *valuesv)
|
||||
{
|
||||
|
@ -846,44 +752,26 @@ sqlite_db_STORE_attrib(SV *dbh, imp_dbh_t *imp_dbh, SV *keysv, SV *valuesv)
|
|||
imp_dbh->prefer_numeric_type = !(! SvTRUE(valuesv));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (strEQ(key, "sqlite_string_mode")) {
|
||||
dbd_sqlite_string_mode_t string_mode = _extract_sqlite_string_mode_from_sv(aTHX_ valuesv);
|
||||
|
||||
#if PERL_UNICODE_DOES_NOT_WORK_WELL
|
||||
if (string_mode & DBD_SQLITE_STRING_MODE_UNICODE_ANY) {
|
||||
sqlite_trace(dbh, imp_dbh, 3, form("Unicode support is disabled for this version of perl."));
|
||||
string_mode = DBD_SQLITE_STRING_MODE_PV;
|
||||
}
|
||||
#endif
|
||||
|
||||
imp_dbh->string_mode = string_mode;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (strEQ(key, "sqlite_unicode")) {
|
||||
/* it's too early to warn the deprecation of sqlite_unicode as it's widely used */
|
||||
#if PERL_UNICODE_DOES_NOT_WORK_WELL
|
||||
sqlite_trace(dbh, imp_dbh, 3, form("Unicode support is disabled for this version of perl."));
|
||||
imp_dbh->string_mode = DBD_SQLITE_STRING_MODE_PV;
|
||||
imp_dbh->unicode = 0;
|
||||
#else
|
||||
imp_dbh->string_mode = SvTRUE(valuesv) ? DBD_SQLITE_STRING_MODE_UNICODE_NAIVE : DBD_SQLITE_STRING_MODE_PV;
|
||||
imp_dbh->unicode = !(! SvTRUE(valuesv));
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (strEQ(key, "unicode")) {
|
||||
_warn_deprecated_if_possible(key, "sqlite_string_mode");
|
||||
if (DBIc_has(imp_dbh, DBIcf_WARN))
|
||||
warn("\"unicode\" attribute will be deprecated. Use \"sqlite_unicode\" instead.");
|
||||
#if PERL_UNICODE_DOES_NOT_WORK_WELL
|
||||
sqlite_trace(dbh, imp_dbh, 3, form("Unicode support is disabled for this version of perl."));
|
||||
imp_dbh->string_mode = DBD_SQLITE_STRING_MODE_PV;
|
||||
imp_dbh->unicode = 0;
|
||||
#else
|
||||
imp_dbh->string_mode = SvTRUE(valuesv) ? DBD_SQLITE_STRING_MODE_UNICODE_NAIVE : DBD_SQLITE_STRING_MODE_PV;
|
||||
imp_dbh->unicode = !(! SvTRUE(valuesv));
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -911,18 +799,22 @@ sqlite_db_FETCH_attrib(SV *dbh, imp_dbh_t *imp_dbh, SV *keysv)
|
|||
if (strEQ(key, "sqlite_prefer_numeric_type")) {
|
||||
return sv_2mortal(newSViv(imp_dbh->prefer_numeric_type ? 1 : 0));
|
||||
}
|
||||
|
||||
if (strEQ(key, "sqlite_string_mode")) {
|
||||
return sv_2mortal(newSVuv(imp_dbh->string_mode));
|
||||
}
|
||||
|
||||
if (strEQ(key, "sqlite_unicode") || strEQ(key, "unicode")) {
|
||||
_warn_deprecated_if_possible(key, "sqlite_string_mode");
|
||||
if (strEQ(key, "sqlite_unicode")) {
|
||||
#if PERL_UNICODE_DOES_NOT_WORK_WELL
|
||||
sqlite_trace(dbh, imp_dbh, 3, "Unicode support is disabled for this version of perl.");
|
||||
return sv_2mortal(newSViv(0));
|
||||
#else
|
||||
return sv_2mortal(newSViv(imp_dbh->string_mode == DBD_SQLITE_STRING_MODE_UNICODE_NAIVE ? 1 : 0));
|
||||
return sv_2mortal(newSViv(imp_dbh->unicode ? 1 : 0));
|
||||
#endif
|
||||
}
|
||||
if (strEQ(key, "unicode")) {
|
||||
if (DBIc_has(imp_dbh, DBIcf_WARN))
|
||||
warn("\"unicode\" attribute will be deprecated. Use \"sqlite_unicode\" instead.");
|
||||
#if PERL_UNICODE_DOES_NOT_WORK_WELL
|
||||
sqlite_trace(dbh, imp_dbh, 3, "Unicode support is disabled for this version of perl.");
|
||||
return sv_2mortal(newSViv(0));
|
||||
#else
|
||||
return sv_2mortal(newSViv(imp_dbh->unicode ? 1 : 0));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -955,7 +847,7 @@ sqlite_st_prepare_sv(SV *sth, imp_sth_t *imp_sth, SV *sv_statement, SV *attribs)
|
|||
stmt_list_s * new_stmt;
|
||||
D_imp_dbh_from_sth;
|
||||
|
||||
MY_CXT.last_dbh_string_mode = imp_dbh->string_mode;
|
||||
MY_CXT.last_dbh_is_unicode = imp_dbh->unicode;
|
||||
|
||||
if (!DBIc_ACTIVE(imp_dbh)) {
|
||||
sqlite_error(sth, -2, "attempt to prepare on inactive database handle");
|
||||
|
@ -963,7 +855,9 @@ sqlite_st_prepare_sv(SV *sth, imp_sth_t *imp_sth, SV *sv_statement, SV *attribs)
|
|||
}
|
||||
|
||||
/* sqlite3_prepare wants an utf8-encoded SQL statement */
|
||||
DBD_SQLITE_PREP_SV_FOR_SQLITE(sv_statement, imp_dbh->string_mode);
|
||||
if (imp_dbh->unicode) {
|
||||
sv_utf8_upgrade(sv_statement);
|
||||
}
|
||||
|
||||
statement = SvPV_nolen(sv_statement);
|
||||
|
||||
|
@ -1077,15 +971,10 @@ sqlite_st_execute(SV *sth, imp_sth_t *imp_sth)
|
|||
const char *data;
|
||||
int numtype = 0;
|
||||
|
||||
if (imp_dbh->string_mode & DBD_SQLITE_STRING_MODE_UNICODE_ANY) {
|
||||
data = SvPVutf8(value, len);
|
||||
if (imp_dbh->unicode) {
|
||||
sv_utf8_upgrade(value);
|
||||
}
|
||||
else if (imp_dbh->string_mode == DBD_SQLITE_STRING_MODE_BYTES) {
|
||||
data = SvPVbyte(value, len);
|
||||
}
|
||||
else {
|
||||
data = SvPV(value, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: For backward compatibility, it'd be better to
|
||||
|
@ -1296,9 +1185,11 @@ sqlite_st_fetch(SV *sth, imp_sth_t *imp_sth)
|
|||
}
|
||||
}
|
||||
sv_setpvn(AvARRAY(av)[i], val, len);
|
||||
|
||||
DBD_SQLITE_UTF8_DECODE_IF_NEEDED(AvARRAY(av)[i], imp_dbh->string_mode);
|
||||
|
||||
if (imp_dbh->unicode) {
|
||||
SvUTF8_on(AvARRAY(av)[i]);
|
||||
} else {
|
||||
SvUTF8_off(AvARRAY(av)[i]);
|
||||
}
|
||||
break;
|
||||
case SQLITE_BLOB:
|
||||
sqlite_trace(sth, imp_sth, 5, form("fetch column %d as blob", i));
|
||||
|
@ -1470,9 +1361,8 @@ sqlite_st_FETCH_attrib(SV *sth, imp_sth_t *imp_sth, SV *keysv)
|
|||
/* if (dot) drop table name from field name */
|
||||
/* fieldname = ++dot; */
|
||||
SV *sv_fieldname = newSVpv(fieldname, 0);
|
||||
|
||||
DBD_SQLITE_UTF8_DECODE_IF_NEEDED(sv_fieldname, imp_dbh->string_mode);
|
||||
|
||||
if (imp_dbh->unicode)
|
||||
SvUTF8_on(sv_fieldname);
|
||||
av_store(av, n, sv_fieldname);
|
||||
}
|
||||
}
|
||||
|
@ -1733,7 +1623,7 @@ SV *
|
|||
sqlite_db_filename(pTHX_ SV *dbh)
|
||||
{
|
||||
D_imp_dbh(dbh);
|
||||
const char *filename = NULL;
|
||||
const char *filename;
|
||||
|
||||
if (!imp_dbh->db) {
|
||||
return &PL_sv_undef;
|
||||
|
@ -1766,7 +1656,7 @@ sqlite_db_busy_timeout(pTHX_ SV *dbh, SV *timeout )
|
|||
}
|
||||
|
||||
static void
|
||||
sqlite_db_func_dispatcher(dbd_sqlite_string_mode_t string_mode, sqlite3_context *context, int argc, sqlite3_value **value)
|
||||
sqlite_db_func_dispatcher(int is_unicode, sqlite3_context *context, int argc, sqlite3_value **value)
|
||||
{
|
||||
dTHX;
|
||||
dSP;
|
||||
|
@ -1781,7 +1671,7 @@ sqlite_db_func_dispatcher(dbd_sqlite_string_mode_t string_mode, sqlite3_context
|
|||
|
||||
PUSHMARK(SP);
|
||||
for ( i=0; i < argc; i++ ) {
|
||||
XPUSHs(stacked_sv_from_sqlite3_value(aTHX_ value[i], string_mode));
|
||||
XPUSHs(stacked_sv_from_sqlite3_value(aTHX_ value[i], is_unicode));
|
||||
}
|
||||
PUTBACK;
|
||||
|
||||
|
@ -1812,46 +1702,17 @@ sqlite_db_func_dispatcher(dbd_sqlite_string_mode_t string_mode, sqlite3_context
|
|||
}
|
||||
|
||||
static void
|
||||
sqlite_db_func_dispatcher_unicode_naive(sqlite3_context *context, int argc, sqlite3_value **value)
|
||||
sqlite_db_func_dispatcher_unicode(sqlite3_context *context, int argc, sqlite3_value **value)
|
||||
{
|
||||
sqlite_db_func_dispatcher(DBD_SQLITE_STRING_MODE_UNICODE_NAIVE, context, argc, value);
|
||||
sqlite_db_func_dispatcher(1, context, argc, value);
|
||||
}
|
||||
|
||||
static void
|
||||
sqlite_db_func_dispatcher_unicode_fallback(sqlite3_context *context, int argc, sqlite3_value **value)
|
||||
sqlite_db_func_dispatcher_no_unicode(sqlite3_context *context, int argc, sqlite3_value **value)
|
||||
{
|
||||
sqlite_db_func_dispatcher(DBD_SQLITE_STRING_MODE_UNICODE_FALLBACK, context, argc, value);
|
||||
sqlite_db_func_dispatcher(0, context, argc, value);
|
||||
}
|
||||
|
||||
static void
|
||||
sqlite_db_func_dispatcher_unicode_strict(sqlite3_context *context, int argc, sqlite3_value **value)
|
||||
{
|
||||
sqlite_db_func_dispatcher(DBD_SQLITE_STRING_MODE_UNICODE_STRICT, context, argc, value);
|
||||
}
|
||||
|
||||
static void
|
||||
sqlite_db_func_dispatcher_bytes(sqlite3_context *context, int argc, sqlite3_value **value)
|
||||
{
|
||||
sqlite_db_func_dispatcher(DBD_SQLITE_STRING_MODE_BYTES, context, argc, value);
|
||||
}
|
||||
|
||||
static void
|
||||
sqlite_db_func_dispatcher_pv(sqlite3_context *context, int argc, sqlite3_value **value)
|
||||
{
|
||||
sqlite_db_func_dispatcher(DBD_SQLITE_STRING_MODE_PV, context, argc, value);
|
||||
}
|
||||
|
||||
typedef void (*dispatch_func_t)(sqlite3_context*, int, sqlite3_value**);
|
||||
|
||||
static dispatch_func_t _FUNC_DISPATCHER[_DBD_SQLITE_STRING_MODE_COUNT] = {
|
||||
sqlite_db_func_dispatcher_pv,
|
||||
sqlite_db_func_dispatcher_bytes,
|
||||
NULL, NULL,
|
||||
sqlite_db_func_dispatcher_unicode_naive,
|
||||
sqlite_db_func_dispatcher_unicode_fallback,
|
||||
sqlite_db_func_dispatcher_unicode_strict,
|
||||
};
|
||||
|
||||
int
|
||||
sqlite_db_create_function(pTHX_ SV *dbh, const char *name, int argc, SV *func, int flags)
|
||||
{
|
||||
|
@ -1865,20 +1726,17 @@ sqlite_db_create_function(pTHX_ SV *dbh, const char *name, int argc, SV *func, i
|
|||
}
|
||||
|
||||
/* Copy the function reference */
|
||||
if (SvOK(func)) {
|
||||
func_sv = newSVsv(func);
|
||||
av_push( imp_dbh->functions, func_sv );
|
||||
}
|
||||
|
||||
croak_if_db_is_null();
|
||||
|
||||
/* warn("create_function %s with %d args\n", name, argc); */
|
||||
if (SvOK(func)) {
|
||||
rc = sqlite3_create_function( imp_dbh->db, name, argc, SQLITE_UTF8|flags,
|
||||
func_sv, _FUNC_DISPATCHER[imp_dbh->string_mode], NULL, NULL );
|
||||
} else {
|
||||
rc = sqlite3_create_function( imp_dbh->db, name, argc, SQLITE_UTF8|flags, NULL, NULL, NULL, NULL );
|
||||
}
|
||||
func_sv,
|
||||
imp_dbh->unicode ? sqlite_db_func_dispatcher_unicode
|
||||
: sqlite_db_func_dispatcher_no_unicode,
|
||||
NULL, NULL );
|
||||
if ( rc != SQLITE_OK ) {
|
||||
sqlite_error(dbh, rc, form("sqlite_create_function failed with error %s", sqlite3_errmsg(imp_dbh->db)));
|
||||
return FALSE;
|
||||
|
@ -1934,21 +1792,6 @@ sqlite_db_load_extension(pTHX_ SV *dbh, const char *file, const char *proc)
|
|||
|
||||
#endif
|
||||
|
||||
SV* _lc(pTHX_ SV* sv) {
|
||||
int i, l;
|
||||
char* pv;
|
||||
if (SvPOK(sv)) {
|
||||
pv = SvPV_nolen(sv);
|
||||
l = strlen(pv);
|
||||
for(i = 0; i < l; i++) {
|
||||
if (pv[i] >= 'A' && pv[i] <= 'Z') {
|
||||
pv[i] = pv[i] - 'A' + 'a';
|
||||
}
|
||||
}
|
||||
}
|
||||
return sv;
|
||||
}
|
||||
|
||||
HV*
|
||||
sqlite_db_table_column_metadata(pTHX_ SV *dbh, SV *dbname, SV *tablename, SV *columnname)
|
||||
{
|
||||
|
@ -1985,7 +1828,7 @@ sqlite_db_table_column_metadata(pTHX_ SV *dbh, SV *dbname, SV *tablename, SV *co
|
|||
#endif
|
||||
|
||||
if (rc == SQLITE_OK) {
|
||||
hv_stores(metadata, "data_type", datatype ? _lc(aTHX_ newSVpv(datatype, 0)) : newSV(0));
|
||||
hv_stores(metadata, "data_type", datatype ? newSVpv(datatype, 0) : newSV(0));
|
||||
hv_stores(metadata, "collation_name", collseq ? newSVpv(collseq, 0) : newSV(0));
|
||||
hv_stores(metadata, "not_null", newSViv(notnull));
|
||||
hv_stores(metadata, "primary", newSViv(primary));
|
||||
|
@ -2057,7 +1900,7 @@ sqlite_db_aggr_step_dispatcher(sqlite3_context *context,
|
|||
{
|
||||
dTHX;
|
||||
dSP;
|
||||
int i, string_mode = DBD_SQLITE_STRING_MODE_PV; /* TODO : find out from db handle */
|
||||
int i, is_unicode = 0; /* TODO : find out from db handle */
|
||||
aggrInfo *aggr;
|
||||
|
||||
aggr = sqlite3_aggregate_context(context, sizeof (aggrInfo));
|
||||
|
@ -2079,7 +1922,7 @@ sqlite_db_aggr_step_dispatcher(sqlite3_context *context,
|
|||
PUSHMARK(SP);
|
||||
XPUSHs( sv_2mortal( newSVsv( aggr->aggr_inst ) ));
|
||||
for ( i=0; i < argc; i++ ) {
|
||||
XPUSHs(stacked_sv_from_sqlite3_value(aTHX_ value[i], string_mode));
|
||||
XPUSHs(stacked_sv_from_sqlite3_value(aTHX_ value[i], is_unicode));
|
||||
}
|
||||
PUTBACK;
|
||||
|
||||
|
@ -2195,78 +2038,71 @@ sqlite_db_create_aggregate(pTHX_ SV *dbh, const char *name, int argc, SV *aggr_p
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#define SQLITE_DB_COLLATION_BASE(func, sv1, sv2) STMT_START { \
|
||||
int cmp = 0; \
|
||||
int n_retval, i; \
|
||||
\
|
||||
ENTER; \
|
||||
SAVETMPS; \
|
||||
PUSHMARK(SP); \
|
||||
XPUSHs( sv_2mortal( sv1 ) ); \
|
||||
XPUSHs( sv_2mortal( sv2 ) ); \
|
||||
PUTBACK; \
|
||||
n_retval = call_sv(func, G_SCALAR); \
|
||||
SPAGAIN; \
|
||||
if (n_retval != 1) { \
|
||||
warn("collation function returned %d arguments", n_retval); \
|
||||
} \
|
||||
for(i = 0; i < n_retval; i++) { \
|
||||
cmp = POPi; \
|
||||
} \
|
||||
PUTBACK; \
|
||||
FREETMPS; \
|
||||
LEAVE; \
|
||||
\
|
||||
return cmp; \
|
||||
} STMT_END
|
||||
|
||||
int
|
||||
sqlite_db_collation_dispatcher(void *func, int len1, const void *string1,
|
||||
int len2, const void *string2)
|
||||
{
|
||||
dTHX;
|
||||
dSP;
|
||||
int cmp = 0;
|
||||
int n_retval, i;
|
||||
|
||||
SQLITE_DB_COLLATION_BASE(func, newSVpvn( string1, len1), newSVpvn( string2, len2));
|
||||
ENTER;
|
||||
SAVETMPS;
|
||||
PUSHMARK(SP);
|
||||
XPUSHs( sv_2mortal( newSVpvn( string1, len1) ) );
|
||||
XPUSHs( sv_2mortal( newSVpvn( string2, len2) ) );
|
||||
PUTBACK;
|
||||
n_retval = call_sv(func, G_SCALAR);
|
||||
SPAGAIN;
|
||||
if (n_retval != 1) {
|
||||
warn("collation function returned %d arguments", n_retval);
|
||||
}
|
||||
for(i = 0; i < n_retval; i++) {
|
||||
cmp = POPi;
|
||||
}
|
||||
PUTBACK;
|
||||
FREETMPS;
|
||||
LEAVE;
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
int
|
||||
sqlite_db_collation_dispatcher_utf8_naive(void *func, int len1, const void *string1,
|
||||
sqlite_db_collation_dispatcher_utf8(void *func, int len1, const void *string1,
|
||||
int len2, const void *string2)
|
||||
{
|
||||
dTHX;
|
||||
dSP;
|
||||
int cmp = 0;
|
||||
int n_retval, i;
|
||||
SV *sv1, *sv2;
|
||||
|
||||
SQLITE_DB_COLLATION_BASE(func, newSVpvn_flags( string1, len1, SVf_UTF8), newSVpvn_flags( string2, len2, SVf_UTF8));
|
||||
ENTER;
|
||||
SAVETMPS;
|
||||
PUSHMARK(SP);
|
||||
sv1 = newSVpvn(string1, len1);
|
||||
SvUTF8_on(sv1);
|
||||
sv2 = newSVpvn(string2, len2);
|
||||
SvUTF8_on(sv2);
|
||||
XPUSHs( sv_2mortal( sv1 ) );
|
||||
XPUSHs( sv_2mortal( sv2 ) );
|
||||
PUTBACK;
|
||||
n_retval = call_sv(func, G_SCALAR);
|
||||
SPAGAIN;
|
||||
if (n_retval != 1) {
|
||||
warn("collation function returned %d arguments", n_retval);
|
||||
}
|
||||
for(i = 0; i < n_retval; i++) {
|
||||
cmp = POPi;
|
||||
}
|
||||
PUTBACK;
|
||||
FREETMPS;
|
||||
LEAVE;
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
int
|
||||
sqlite_db_collation_dispatcher_utf8_fallback(void *func, int len1, const void *string1,
|
||||
int len2, const void *string2)
|
||||
{
|
||||
dTHX;
|
||||
dSP;
|
||||
|
||||
SV* sv1 = newSVpvn( string1, len1);
|
||||
SV* sv2 = newSVpvn( string2, len2);
|
||||
|
||||
DBD_SQLITE_UTF8_DECODE_WITH_FALLBACK(sv1);
|
||||
DBD_SQLITE_UTF8_DECODE_WITH_FALLBACK(sv2);
|
||||
|
||||
SQLITE_DB_COLLATION_BASE(func, sv1, sv2);
|
||||
}
|
||||
|
||||
typedef int (*collation_dispatch_func_t)(void *, int, const void *, int, const void *);
|
||||
|
||||
static collation_dispatch_func_t _COLLATION_DISPATCHER[_DBD_SQLITE_STRING_MODE_COUNT] = {
|
||||
sqlite_db_collation_dispatcher,
|
||||
sqlite_db_collation_dispatcher,
|
||||
NULL, NULL,
|
||||
sqlite_db_collation_dispatcher_utf8_naive,
|
||||
sqlite_db_collation_dispatcher_utf8_fallback,
|
||||
sqlite_db_collation_dispatcher_utf8_fallback,
|
||||
};
|
||||
|
||||
int
|
||||
sqlite_db_create_collation(pTHX_ SV *dbh, const char *name, SV *func)
|
||||
{
|
||||
|
@ -2302,7 +2138,8 @@ sqlite_db_create_collation(pTHX_ SV *dbh, const char *name, SV *func)
|
|||
rv = sqlite3_create_collation(
|
||||
imp_dbh->db, name, SQLITE_UTF8,
|
||||
func_sv,
|
||||
_COLLATION_DISPATCHER[imp_dbh->string_mode]
|
||||
imp_dbh->unicode ? sqlite_db_collation_dispatcher_utf8
|
||||
: sqlite_db_collation_dispatcher
|
||||
);
|
||||
|
||||
if ( rv != SQLITE_OK ) {
|
||||
|
@ -2975,21 +2812,6 @@ sqlite_db_get_autocommit(pTHX_ SV *dbh)
|
|||
return sqlite3_get_autocommit(imp_dbh->db);
|
||||
}
|
||||
|
||||
int
|
||||
sqlite_db_txn_state(pTHX_ SV *dbh, SV *schema)
|
||||
{
|
||||
#if SQLITE_VERSION_NUMBER >= 3034000
|
||||
D_imp_dbh(dbh);
|
||||
if (SvOK(schema) && SvPOK(schema)) {
|
||||
return sqlite3_txn_state(imp_dbh->db, SvPV_nolen(schema));
|
||||
} else {
|
||||
return sqlite3_txn_state(imp_dbh->db, NULL);
|
||||
}
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#include "dbdimp_tokenizer.inc"
|
||||
#include "dbdimp_virtual_table.inc"
|
||||
|
||||
|
|
56
dbdimp.h
56
dbdimp.h
|
@ -7,24 +7,8 @@
|
|||
|
||||
#define MY_CXT_KEY "DBD::SQLite::_guts" XS_VERSION
|
||||
|
||||
typedef enum {
|
||||
DBD_SQLITE_STRING_MODE_PV,
|
||||
DBD_SQLITE_STRING_MODE_BYTES,
|
||||
|
||||
/* Leave space here so that we can use DBD_SQLITE_STRING_MODE_UNICODE_ANY
|
||||
as a means of checking for any unicode mode. */
|
||||
|
||||
DBD_SQLITE_STRING_MODE_UNICODE_NAIVE = 4,
|
||||
DBD_SQLITE_STRING_MODE_UNICODE_FALLBACK,
|
||||
DBD_SQLITE_STRING_MODE_UNICODE_STRICT,
|
||||
|
||||
_DBD_SQLITE_STRING_MODE_COUNT,
|
||||
} dbd_sqlite_string_mode_t;
|
||||
|
||||
#define DBD_SQLITE_STRING_MODE_UNICODE_ANY DBD_SQLITE_STRING_MODE_UNICODE_NAIVE
|
||||
|
||||
typedef struct {
|
||||
dbd_sqlite_string_mode_t last_dbh_string_mode;
|
||||
int last_dbh_is_unicode;
|
||||
} my_cxt_t;
|
||||
|
||||
#define PERL_UNICODE_DOES_NOT_WORK_WELL \
|
||||
|
@ -38,41 +22,6 @@ typedef struct {
|
|||
#define sqlite3_int64 sqlite_int64
|
||||
#endif
|
||||
|
||||
#define DBD_SQLITE_UTF8_DECODE_NAIVE(sv) SvUTF8_on(sv)
|
||||
|
||||
#define DBD_SQLITE_UTF8_DECODE_CHECKED(sv, onfail) ( \
|
||||
is_utf8_string((U8*) SvPVX(sv), SvCUR(sv)) \
|
||||
? SvUTF8_on(sv) \
|
||||
: onfail("Received invalid UTF-8 from SQLite; cannot decode!") \
|
||||
)
|
||||
|
||||
#define DBD_SQLITE_UTF8_DECODE_WITH_FALLBACK(sv) ( \
|
||||
DBD_SQLITE_UTF8_DECODE_CHECKED(sv, warn) \
|
||||
)
|
||||
|
||||
#define DBD_SQLITE_UTF8_DECODE_STRICT(sv) ( \
|
||||
DBD_SQLITE_UTF8_DECODE_CHECKED(sv, croak) \
|
||||
)
|
||||
|
||||
#define DBD_SQLITE_PREP_SV_FOR_SQLITE(sv, string_mode) STMT_START { \
|
||||
if (string_mode & DBD_SQLITE_STRING_MODE_UNICODE_ANY) { \
|
||||
sv_utf8_upgrade(sv); \
|
||||
} \
|
||||
else if (string_mode == DBD_SQLITE_STRING_MODE_BYTES) { \
|
||||
sv_utf8_downgrade(sv, 0); \
|
||||
} \
|
||||
} STMT_END
|
||||
|
||||
#define DBD_SQLITE_UTF8_DECODE_IF_NEEDED(sv, string_mode) ( \
|
||||
string_mode == DBD_SQLITE_STRING_MODE_UNICODE_NAIVE \
|
||||
? DBD_SQLITE_UTF8_DECODE_NAIVE(sv) \
|
||||
: string_mode == DBD_SQLITE_STRING_MODE_UNICODE_FALLBACK \
|
||||
? DBD_SQLITE_UTF8_DECODE_WITH_FALLBACK(sv) \
|
||||
: string_mode == DBD_SQLITE_STRING_MODE_UNICODE_STRICT \
|
||||
? DBD_SQLITE_UTF8_DECODE_STRICT(sv) \
|
||||
: 0 \
|
||||
)
|
||||
|
||||
/* A linked list of statements prepared by this module */
|
||||
typedef struct stmt_list_s stmt_list_s;
|
||||
|
||||
|
@ -92,7 +41,7 @@ struct imp_dbh_st {
|
|||
dbih_dbc_t com;
|
||||
/* sqlite specific bits */
|
||||
sqlite3 *db;
|
||||
dbd_sqlite_string_mode_t string_mode;
|
||||
bool unicode;
|
||||
bool handle_binary_nulls;
|
||||
int timeout;
|
||||
AV *functions;
|
||||
|
@ -188,7 +137,6 @@ int sqlite_db_create_module(pTHX_ SV *dbh, const char *name, const char *perl_cl
|
|||
int sqlite_db_limit(pTHX_ SV *dbh, int id, int new_value);
|
||||
int sqlite_db_config(pTHX_ SV *dbh, int id, int new_value);
|
||||
int sqlite_db_get_autocommit(pTHX_ SV *dbh);
|
||||
int sqlite_db_txn_state(pTHX_ SV *dbh, SV *schema);
|
||||
int sqlite_db_do_sv(SV *dbh, imp_dbh_t *imp_dbh, SV *sv_statement);
|
||||
void init_cxt();
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@ typedef struct perl_tokenizer_cursor {
|
|||
|
||||
/* members below are only used if the input string is in utf8 */
|
||||
const char *pInput; /* input we are tokenizing */
|
||||
const char *currentByte; /* pointer into pInput */
|
||||
int currentChar; /* char position corresponding to currentByte */
|
||||
const char *lastByteOffset; /* offset into pInput */
|
||||
int lastCharOffset; /* char offset corresponding to lastByteOffset */
|
||||
} perl_tokenizer_cursor;
|
||||
|
||||
/*
|
||||
|
@ -94,30 +94,6 @@ static int perl_tokenizer_Open(
|
|||
SV *perl_string;
|
||||
int n_retval;
|
||||
|
||||
/* build a Perl copy of the input string */
|
||||
if (nBytes < 0) { /* we get -1 from fts3. Don't know why ! */
|
||||
nBytes = strlen(pInput);
|
||||
}
|
||||
|
||||
/* SVs_TEMP will call sv_2mortal */
|
||||
perl_string = newSVpvn_flags(pInput, nBytes, SVs_TEMP);
|
||||
|
||||
switch (MY_CXT.last_dbh_string_mode) {
|
||||
DBD_SQLITE_STRING_MODE_UNICODE_NAIVE:
|
||||
DBD_SQLITE_UTF8_DECODE_NAIVE(perl_string);
|
||||
break;
|
||||
|
||||
DBD_SQLITE_STRING_MODE_UNICODE_FALLBACK:
|
||||
DBD_SQLITE_STRING_MODE_UNICODE_STRICT:
|
||||
DBD_SQLITE_UTF8_DECODE_WITH_FALLBACK(perl_string);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
DBD_SQLITE_UTF8_DECODE_IF_NEEDED(perl_string, MY_CXT.last_dbh_string_mode);
|
||||
|
||||
perl_tokenizer *t = (perl_tokenizer *)pTokenizer;
|
||||
|
||||
/* allocate and initialize the cursor struct */
|
||||
|
@ -126,17 +102,29 @@ static int perl_tokenizer_Open(
|
|||
memset(c, 0, sizeof(*c));
|
||||
*ppCursor = &c->base;
|
||||
|
||||
/* special handling if working with utf8 strings */
|
||||
if (MY_CXT.last_dbh_string_mode & DBD_SQLITE_STRING_MODE_UNICODE_ANY) {
|
||||
/* flags for creating the Perl SV containing the input string */
|
||||
flags = SVs_TEMP; /* will call sv_2mortal */
|
||||
|
||||
/* data to keep track of byte positions */
|
||||
c->currentByte = c->pInput = pInput;
|
||||
c->currentChar = 0;
|
||||
/* special handling if working with utf8 strings */
|
||||
if (MY_CXT.last_dbh_is_unicode) {
|
||||
|
||||
/* data to keep track of byte offsets */
|
||||
c->lastByteOffset = c->pInput = pInput;
|
||||
c->lastCharOffset = 0;
|
||||
|
||||
/* string passed to Perl needs to be flagged as utf8 */
|
||||
flags |= SVf_UTF8;
|
||||
}
|
||||
|
||||
ENTER;
|
||||
SAVETMPS;
|
||||
|
||||
/* build a Perl copy of the input string */
|
||||
if (nBytes < 0) { /* we get -1 from fts3. Don't know why ! */
|
||||
nBytes = strlen(pInput);
|
||||
}
|
||||
perl_string = newSVpvn_flags(pInput, nBytes, flags);
|
||||
|
||||
/* call the tokenizer coderef */
|
||||
PUSHMARK(SP);
|
||||
XPUSHs(perl_string);
|
||||
|
@ -146,7 +134,7 @@ static int perl_tokenizer_Open(
|
|||
|
||||
/* store the cursor coderef returned by the tokenizer */
|
||||
if (n_retval != 1) {
|
||||
warn("tokenizer returned %d arguments, expected 1", n_retval);
|
||||
warn("tokenizer returned %d arguments", n_retval);
|
||||
}
|
||||
c->coderef = newSVsv(POPs);
|
||||
|
||||
|
@ -176,17 +164,17 @@ static int perl_tokenizer_Close(sqlite3_tokenizer_cursor *pCursor){
|
|||
*/
|
||||
static int perl_tokenizer_Next(
|
||||
sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by perl_tokenizer_Open */
|
||||
const char **ppToken, /* OUT: Normalized text for token */
|
||||
int *pnBytes, /* OUT: Number of bytes in normalized text */
|
||||
int *piStartOffset, /* Starting offset of token. IN : char offset; OUT : byte offset */
|
||||
int *piEndOffset, /* Ending offset of token. IN : char offset; OUT : byte offset */
|
||||
int *piPosition /* OUT: Number of tokens returned before this one */
|
||||
const char **ppToken, /* OUT: *ppToken is the token text */
|
||||
int *pnBytes, /* OUT: Number of bytes in token */
|
||||
int *piStartOffset, /* OUT: Starting offset of token */
|
||||
int *piEndOffset, /* OUT: Ending offset of token */
|
||||
int *piPosition /* OUT: Position integer of token */
|
||||
){
|
||||
perl_tokenizer_cursor *c = (perl_tokenizer_cursor *) pCursor;
|
||||
int result;
|
||||
int n_retval;
|
||||
char *token;
|
||||
char *nextByte;
|
||||
char *byteOffset;
|
||||
STRLEN n_a; /* this is required for older perls < 5.8.8 */
|
||||
I32 hop;
|
||||
|
||||
|
@ -209,7 +197,7 @@ static int perl_tokenizer_Next(
|
|||
/* otherwise, get token details from the return list */
|
||||
else {
|
||||
if (n_retval != 5) {
|
||||
warn("tokenizer cursor returned %d arguments, expected 5", n_retval);
|
||||
warn("tokenizer cursor returned %d arguments", n_retval);
|
||||
}
|
||||
*piPosition = POPi;
|
||||
*piEndOffset = POPi;
|
||||
|
@ -218,30 +206,21 @@ static int perl_tokenizer_Next(
|
|||
token = POPpx;
|
||||
|
||||
if (c->pInput) { /* if working with utf8 data */
|
||||
/* compute first hop : nb of chars from last position to the start of the token */
|
||||
hop = *piStartOffset - c->currentChar;
|
||||
|
||||
/* hop: advance to the first byte in token */
|
||||
nextByte = (char*)utf8_hop((U8*)c->currentByte, hop);
|
||||
|
||||
/* compute 2nd hop : nb of chars from start of the token to end of token */
|
||||
hop = *piEndOffset - *piStartOffset;
|
||||
|
||||
/* now recompute the start offset in bytes, not in chars */
|
||||
*piStartOffset = nextByte - c->pInput;
|
||||
|
||||
/* 2nd hop: advance past to the last byte in token */
|
||||
nextByte = (char*)utf8_hop((U8*)nextByte, hop);
|
||||
|
||||
/* remember current position (useful for the next invocation) */
|
||||
c->currentChar = *piEndOffset;
|
||||
c->currentByte = nextByte;
|
||||
|
||||
/* now recompute the end offset in bytes, not in chars */
|
||||
*piEndOffset = nextByte - c->pInput;
|
||||
|
||||
/* compute the size of the normalized token in bytes, not in chars */
|
||||
/* recompute *pnBytes in bytes, not in chars */
|
||||
*pnBytes = strlen(token);
|
||||
|
||||
/* recompute start/end offsets in bytes, not in chars */
|
||||
hop = *piStartOffset - c->lastCharOffset;
|
||||
byteOffset = (char*)utf8_hop((U8*)c->lastByteOffset, hop);
|
||||
hop = *piEndOffset - *piStartOffset;
|
||||
*piStartOffset = byteOffset - c->pInput;
|
||||
byteOffset = (char*)utf8_hop((U8*)byteOffset, hop);
|
||||
*piEndOffset = byteOffset - c->pInput;
|
||||
|
||||
/* remember where we are for next round */
|
||||
c->lastCharOffset = *piEndOffset,
|
||||
c->lastByteOffset = byteOffset;
|
||||
}
|
||||
|
||||
/* make sure we have enough storage for copying the token */
|
||||
|
@ -253,7 +232,8 @@ static int perl_tokenizer_Next(
|
|||
c->pToken = pNew;
|
||||
}
|
||||
|
||||
/* need to copy the token into the C cursor before perl frees that memory */
|
||||
/* need to copy the token into the C cursor before perl frees that
|
||||
memory */
|
||||
memcpy(c->pToken, token, *pnBytes);
|
||||
*ppToken = c->pToken;
|
||||
|
||||
|
|
|
@ -432,7 +432,7 @@ static int perl_vt_Filter( sqlite3_vtab_cursor *pVtabCursor,
|
|||
dSP;
|
||||
dMY_CXT;
|
||||
int i, count;
|
||||
dbd_sqlite_string_mode_t string_mode = MY_CXT.last_dbh_string_mode;
|
||||
int is_unicode = MY_CXT.last_dbh_is_unicode;
|
||||
|
||||
ENTER;
|
||||
SAVETMPS;
|
||||
|
@ -443,7 +443,7 @@ static int perl_vt_Filter( sqlite3_vtab_cursor *pVtabCursor,
|
|||
XPUSHs(sv_2mortal(newSViv(idxNum)));
|
||||
XPUSHs(sv_2mortal(newSVpv(idxStr, 0)));
|
||||
for(i = 0; i < argc; i++) {
|
||||
XPUSHs(stacked_sv_from_sqlite3_value(aTHX_ argv[i], string_mode));
|
||||
XPUSHs(stacked_sv_from_sqlite3_value(aTHX_ argv[i], is_unicode));
|
||||
}
|
||||
PUTBACK;
|
||||
count = call_method("FILTER", G_VOID);
|
||||
|
@ -484,8 +484,7 @@ static int perl_vt_Next(sqlite3_vtab_cursor *pVtabCursor){
|
|||
static int perl_vt_Eof(sqlite3_vtab_cursor *pVtabCursor){
|
||||
dTHX;
|
||||
dSP;
|
||||
int count;
|
||||
int eof = 1;
|
||||
int count, eof;
|
||||
|
||||
ENTER;
|
||||
SAVETMPS;
|
||||
|
@ -588,7 +587,7 @@ static int perl_vt_Update( sqlite3_vtab *pVTab,
|
|||
dSP;
|
||||
dMY_CXT;
|
||||
int count, i;
|
||||
dbd_sqlite_string_mode_t string_mode = MY_CXT.last_dbh_string_mode;
|
||||
int is_unicode = MY_CXT.last_dbh_is_unicode;
|
||||
int rc = SQLITE_ERROR;
|
||||
SV *rowidsv;
|
||||
|
||||
|
@ -599,7 +598,7 @@ static int perl_vt_Update( sqlite3_vtab *pVTab,
|
|||
PUSHMARK(SP);
|
||||
XPUSHs(((perl_vtab *) pVTab)->perl_vtab_obj);
|
||||
for(i = 0; i < argc; i++) {
|
||||
XPUSHs(stacked_sv_from_sqlite3_value(aTHX_ argv[i], string_mode));
|
||||
XPUSHs(stacked_sv_from_sqlite3_value(aTHX_ argv[i], is_unicode));
|
||||
}
|
||||
PUTBACK;
|
||||
count = call_method ("_SQLITE_UPDATE", G_SCALAR);
|
||||
|
@ -704,9 +703,8 @@ static int perl_vt_FindFunction(sqlite3_vtab *pVTab,
|
|||
/* return function information for sqlite3 within *pxFunc and *ppArg */
|
||||
is_overloaded = coderef && SvTRUE(coderef);
|
||||
if (is_overloaded) {
|
||||
|
||||
*pxFunc = _FUNC_DISPATCHER[MY_CXT.last_dbh_string_mode];
|
||||
|
||||
*pxFunc = MY_CXT.last_dbh_is_unicode ? sqlite_db_func_dispatcher_unicode
|
||||
: sqlite_db_func_dispatcher_no_unicode;
|
||||
*ppArg = coderef;
|
||||
}
|
||||
|
||||
|
@ -815,7 +813,6 @@ sqlite_db_destroy_module_data(void *pAux)
|
|||
/* free module memory */
|
||||
SvREFCNT_dec(init_data->dbh);
|
||||
sqlite3_free((char *)init_data->perl_class);
|
||||
sqlite3_free(init_data);
|
||||
|
||||
PUTBACK;
|
||||
FREETMPS;
|
||||
|
|
|
@ -3,9 +3,10 @@ package DBD::SQLite;
|
|||
use 5.006;
|
||||
use strict;
|
||||
use DBI 1.57 ();
|
||||
use XSLoader ();
|
||||
use DynaLoader ();
|
||||
|
||||
our $VERSION = '1.76';
|
||||
our $VERSION = '1.63_05';
|
||||
our @ISA = 'DynaLoader';
|
||||
|
||||
# sqlite_version cache (set in the XS bootstrap)
|
||||
our ($sqlite_version, $sqlite_version_number);
|
||||
|
@ -13,7 +14,7 @@ our ($sqlite_version, $sqlite_version_number);
|
|||
# not sure if we still need these...
|
||||
our ($err, $errstr);
|
||||
|
||||
XSLoader::load('DBD::SQLite', $VERSION);
|
||||
__PACKAGE__->bootstrap($VERSION);
|
||||
|
||||
# New or old API?
|
||||
use constant NEWAPI => ($DBI::VERSION >= 1.608);
|
||||
|
@ -61,8 +62,6 @@ sub driver {
|
|||
DBD::SQLite::db->install_method('sqlite_limit');
|
||||
DBD::SQLite::db->install_method('sqlite_db_config');
|
||||
DBD::SQLite::db->install_method('sqlite_get_autocommit');
|
||||
DBD::SQLite::db->install_method('sqlite_txn_state');
|
||||
DBD::SQLite::db->install_method('sqlite_error_offset');
|
||||
|
||||
$methods_are_installed++;
|
||||
}
|
||||
|
@ -256,12 +255,7 @@ sub ping {
|
|||
sub quote {
|
||||
my ($self, $value, $data_type) = @_;
|
||||
return "NULL" unless defined $value;
|
||||
if (defined $data_type and (
|
||||
$data_type == DBI::SQL_BIT ||
|
||||
$data_type == DBI::SQL_BLOB ||
|
||||
$data_type == DBI::SQL_BINARY ||
|
||||
$data_type == DBI::SQL_VARBINARY ||
|
||||
$data_type == DBI::SQL_LONGVARBINARY)) {
|
||||
if ($data_type and $data_type == DBI::SQL_BLOB) {
|
||||
return q(X') . unpack('H*', $value) . q(');
|
||||
}
|
||||
$value =~ s/'/''/g;
|
||||
|
@ -1074,7 +1068,7 @@ are limited by the typeless nature of the SQLite database.
|
|||
=head1 SQLITE VERSION
|
||||
|
||||
DBD::SQLite is usually compiled with a bundled SQLite library
|
||||
(SQLite version S<3.46.1> as of this release) for consistency.
|
||||
(SQLite version S<3.29.0> as of this release) for consistency.
|
||||
However, a different version of SQLite may sometimes be used for
|
||||
some reasons like security, or some new experimental features.
|
||||
|
||||
|
@ -1623,40 +1617,22 @@ Your sweet spot probably lies somewhere in between.
|
|||
Returns the version of the SQLite library which B<DBD::SQLite> is using,
|
||||
e.g., "3.26.0". Can only be read.
|
||||
|
||||
=item sqlite_string_mode
|
||||
=item sqlite_unicode
|
||||
|
||||
SQLite strings are simple arrays of bytes, but Perl strings can store any
|
||||
arbitrary Unicode code point. Thus, DBD::SQLite has to adopt some method
|
||||
of translating between those two models. This parameter defines that
|
||||
translation.
|
||||
If set to a true value, B<DBD::SQLite> will turn the UTF-8 flag on for all
|
||||
text strings coming out of the database (this feature is currently disabled
|
||||
for perl < 5.8.5). For more details on the UTF-8 flag see
|
||||
L<perlunicode>. The default is for the UTF-8 flag to be turned off.
|
||||
|
||||
Accepted values are the following constants:
|
||||
|
||||
=over
|
||||
|
||||
=item * DBD_SQLITE_STRING_MODE_BYTES: All strings are assumed to
|
||||
represent bytes. A Perl string that contains any code point above 255
|
||||
will trigger an exception. This is appropriate for Latin-1 strings,
|
||||
binary data, pre-encoded UTF-8 strings, etc.
|
||||
|
||||
=item * DBD_SQLITE_STRING_MODE_UNICODE_FALLBACK: All Perl strings are encoded
|
||||
to UTF-8 before being given to SQLite. Perl will B<try> to decode SQLite
|
||||
strings as UTF-8 when giving them to Perl. Should any such string not be
|
||||
valid UTF-8, a warning is thrown, and the string is left undecoded.
|
||||
|
||||
This is appropriate for strings that are decoded to characters via,
|
||||
e.g., L<Encode/decode>.
|
||||
|
||||
Also note that, due to some bizarreness in SQLite's type system (see
|
||||
Also note that due to some bizarreness in SQLite's type system (see
|
||||
L<https://www.sqlite.org/datatype3.html>), if you want to retain
|
||||
blob-style behavior for B<some> columns under DBD_SQLITE_STRING_MODE_UNICODE_FALLBACK
|
||||
(say, to store images in the database), you have to state so
|
||||
blob-style behavior for B<some> columns under C<< $dbh->{sqlite_unicode} = 1
|
||||
>> (say, to store images in the database), you have to state so
|
||||
explicitly using the 3-argument form of L<DBI/bind_param> when doing
|
||||
updates:
|
||||
|
||||
use DBI qw(:sql_types);
|
||||
use DBD::SQLite::Constants ':dbd_sqlite_string_mode';
|
||||
$dbh->{sqlite_string_mode} = DBD_SQLITE_STRING_MODE_UNICODE_FALLBACK;
|
||||
$dbh->{sqlite_unicode} = 1;
|
||||
my $sth = $dbh->prepare("INSERT INTO mytable (blobcolumn) VALUES (?)");
|
||||
|
||||
# Binary_data will be stored as is.
|
||||
|
@ -1664,31 +1640,9 @@ updates:
|
|||
|
||||
Defining the column type as C<BLOB> in the DDL is B<not> sufficient.
|
||||
|
||||
=item * DBD_SQLITE_STRING_MODE_UNICODE_STRICT: Like
|
||||
DBD_SQLITE_STRING_MODE_UNICODE_FALLBACK but usually throws an exception
|
||||
rather than a warning if SQLite sends invalid UTF-8. (In Perl callbacks
|
||||
from SQLite we still warn instead.)
|
||||
|
||||
=item * DBD_SQLITE_STRING_MODE_UNICODE_NAIVE: Like
|
||||
DBD_SQLITE_STRING_MODE_UNICODE_FALLBACK but uses a "naïve" UTF-8 decoding
|
||||
method that forgoes validation. This is marginally faster than a validated
|
||||
decode, but it can also B<corrupt> B<Perl> B<itself!>
|
||||
|
||||
=item * DBD_SQLITE_STRING_MODE_PV (default, but B<DO> B<NOT> B<USE>): Like
|
||||
DBD_SQLITE_STRING_MODE_BYTES, but when translating Perl strings to SQLite
|
||||
the Perl string's internal byte buffer is given to SQLite. B<This> B<is>
|
||||
B<bad>, but it's been the default for many years, and changing that would
|
||||
break existing applications.
|
||||
|
||||
=back
|
||||
|
||||
=item C<sqlite_unicode> or C<unicode> (deprecated)
|
||||
|
||||
If truthy, equivalent to setting C<sqlite_string_mode> to
|
||||
DBD_SQLITE_STRING_MODE_UNICODE_NAIVE; if falsy, equivalent to
|
||||
DBD_SQLITE_STRING_MODE_PV.
|
||||
|
||||
Prefer C<sqlite_string_mode> in all new code.
|
||||
This attribute was originally named as C<unicode>, and renamed to
|
||||
C<sqlite_unicode> for integrity since version 1.26_06. Old C<unicode>
|
||||
attribute is still accessible but will be deprecated in the near future.
|
||||
|
||||
=item sqlite_allow_multiple_statements
|
||||
|
||||
|
@ -1749,8 +1703,7 @@ Returns all tables and schemas (databases) as specified in L<DBI/table_info>.
|
|||
The schema and table arguments will do a C<LIKE> search. You can specify an
|
||||
ESCAPE character by including an 'Escape' attribute in \%attr. The C<$type>
|
||||
argument accepts a comma separated list of the following types 'TABLE',
|
||||
'INDEX', 'VIEW', 'TRIGGER', 'LOCAL TEMPORARY' and 'SYSTEM TABLE'
|
||||
(by default all are returned).
|
||||
'VIEW', 'LOCAL TEMPORARY' and 'SYSTEM TABLE' (by default all are returned).
|
||||
Note that a statement handle is returned, and not a direct list of tables.
|
||||
|
||||
The following fields are returned:
|
||||
|
@ -1763,8 +1716,8 @@ databases will be in the name given when the database was attached.
|
|||
|
||||
B<TABLE_NAME>: The name of the table or view.
|
||||
|
||||
B<TABLE_TYPE>: The type of object returned. Will be one of 'TABLE', 'INDEX',
|
||||
'VIEW', 'TRIGGER', 'LOCAL TEMPORARY' or 'SYSTEM TABLE'.
|
||||
B<TABLE_TYPE>: The type of object returned. Will be one of 'TABLE', 'VIEW',
|
||||
'LOCAL TEMPORARY' or 'SYSTEM TABLE'.
|
||||
|
||||
=head2 primary_key, primary_key_info
|
||||
|
||||
|
@ -1969,13 +1922,6 @@ After this, it could be used from SQL as:
|
|||
|
||||
INSERT INTO mytable ( now() );
|
||||
|
||||
The function should return a scalar value, and the value is treated as a text
|
||||
(or a number if appropriate) by default. If you do need to specify a type
|
||||
of the return value (like BLOB), you can return a reference to an array that
|
||||
contains the value and the type, as of 1.65_01.
|
||||
|
||||
$dbh->sqlite_create_function( 'md5', 1, sub { return [md5($_[0]), SQL_BLOB] } );
|
||||
|
||||
=head3 REGEXP function
|
||||
|
||||
SQLite includes syntactic support for an infix operator 'REGEXP', but
|
||||
|
@ -2299,20 +2245,12 @@ Calling this method with a true value enables loading (external)
|
|||
SQLite3 extensions. After the call, you can load extensions like this:
|
||||
|
||||
$dbh->sqlite_enable_load_extension(1);
|
||||
$sth = $dbh->prepare("select load_extension('libmemvfs.so')")
|
||||
$sth = $dbh->prepare("select load_extension('libsqlitefunctions.so')")
|
||||
or die "Cannot prepare: " . $dbh->errstr();
|
||||
|
||||
=head2 $dbh->sqlite_load_extension( $file, $proc )
|
||||
|
||||
Loading an extension by a select statement (with the "load_extension" SQLite3 function like above) has some limitations. If the extension you want to use creates other functions that are not native to SQLite, use this method instead. $file (a path to the extension) is mandatory, and $proc (an entry point name) is optional. You need to call C<sqlite_enable_load_extension> before calling C<sqlite_load_extension>:
|
||||
|
||||
$dbh->sqlite_enable_load_extension(1);
|
||||
$dbh->sqlite_load_extension('libsqlitefunctions.so')
|
||||
or die "Cannot load extension: " . $dbh->errstr();
|
||||
|
||||
If the extension uses SQLite mutex functions like C<sqlite3_mutex_enter>, then
|
||||
the extension should be compiled with the same C<SQLITE_THREADSAFE> compile-time
|
||||
setting as this module, see C<DBD::SQLite::compile_options()>.
|
||||
Loading an extension by a select statement (with the "load_extension" SQLite3 function like above) has some limitations. If you need to, say, create other functions from an extension, use this method. $file (a path to the extension) is mandatory, and $proc (an entry point name) is optional. You need to call C<sqlite_enable_load_extension> before calling C<sqlite_load_extension>.
|
||||
|
||||
=head2 $dbh->sqlite_trace( $code_ref )
|
||||
|
||||
|
@ -2425,20 +2363,6 @@ Returns true if the internal SQLite connection is in an autocommit mode.
|
|||
This does not always return the same value as C<< $dbh->{AutoCommit} >>.
|
||||
This returns false if you explicitly issue a C<<BEGIN>> statement.
|
||||
|
||||
=head2 $dbh->sqlite_txn_state()
|
||||
|
||||
Returns the internal transaction status of SQLite (not of DBI).
|
||||
Return values (SQLITE_TXN_NONE, SQLITE_TXN_READ, SQLITE_TXN_WRITE)
|
||||
can be imported from DBD::SQLite::Constants. You may pass an optional
|
||||
schema name (usually "main"). If SQLite does not support this function,
|
||||
or if you pass a wrong schema name, -1 is returned.
|
||||
|
||||
=head2 $dbh->sqlite_error_offset()
|
||||
|
||||
Returns the byte offset of the start of a problematic input SQL token
|
||||
or -1 if the most recent error does not reference a specific token in
|
||||
the input SQL (or DBD::SQLite is built with an older version of SQLite).
|
||||
|
||||
=head1 DRIVER FUNCTIONS
|
||||
|
||||
=head2 DBD::SQLite::compile_options()
|
||||
|
@ -2601,17 +2525,18 @@ or
|
|||
|
||||
=head2 Unicode handling
|
||||
|
||||
Depending on the C<< $dbh->{sqlite_string_mode} >> value, strings coming
|
||||
from the database and passed to the collation function may be decoded as
|
||||
UTF-8. This only works, though, if the C<sqlite_string_mode> attribute is
|
||||
set B<before> the first call to a perl collation sequence. The recommended
|
||||
way to activate unicode is to set C<sqlite_string_mode> at connection time:
|
||||
If the attribute C<< $dbh->{sqlite_unicode} >> is set, strings coming from
|
||||
the database and passed to the collation function will be properly
|
||||
tagged with the utf8 flag; but this only works if the
|
||||
C<sqlite_unicode> attribute is set B<before> the first call to
|
||||
a perl collation sequence . The recommended way to activate unicode
|
||||
is to set the parameter at connection time :
|
||||
|
||||
my $dbh = DBI->connect(
|
||||
"dbi:SQLite:dbname=foo", "", "",
|
||||
{
|
||||
RaiseError => 1,
|
||||
sqlite_string_mode => DBD_SQLITE_STRING_MODE_UNICODE_STRICT,
|
||||
sqlite_unicode => 1,
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -2633,7 +2558,7 @@ characters :
|
|||
use DBD::SQLite;
|
||||
$DBD::SQLite::COLLATION{no_accents} = sub {
|
||||
my ( $a, $b ) = map lc, @_;
|
||||
tr[àâáäåãçðèêéëìîíïñòôóöõøùûúüý]
|
||||
tr[àâáäåãçðèêéëìîíïñòôóöõøùûúüý]
|
||||
[aaaaaacdeeeeiiiinoooooouuuuy] for $a, $b;
|
||||
$a cmp $b;
|
||||
};
|
||||
|
|
|
@ -8,18 +8,6 @@ use warnings;
|
|||
use base 'Exporter';
|
||||
use DBD::SQLite;
|
||||
our @EXPORT_OK = (
|
||||
'DBD_SQLITE_STRING_MODE_PV',
|
||||
'DBD_SQLITE_STRING_MODE_BYTES',
|
||||
'DBD_SQLITE_STRING_MODE_UNICODE_NAIVE',
|
||||
'DBD_SQLITE_STRING_MODE_UNICODE_FALLBACK',
|
||||
'DBD_SQLITE_STRING_MODE_UNICODE_STRICT',
|
||||
# allowed_return_values_from_sqlite3_txn_state
|
||||
qw/
|
||||
SQLITE_TXN_NONE
|
||||
SQLITE_TXN_READ
|
||||
SQLITE_TXN_WRITE
|
||||
/,
|
||||
|
||||
# authorizer_action_codes
|
||||
qw/
|
||||
SQLITE_ALTER_TABLE
|
||||
|
@ -79,18 +67,13 @@ our @EXPORT_OK = (
|
|||
SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION
|
||||
SQLITE_DBCONFIG_ENABLE_QPSG
|
||||
SQLITE_DBCONFIG_ENABLE_TRIGGER
|
||||
SQLITE_DBCONFIG_ENABLE_VIEW
|
||||
SQLITE_DBCONFIG_LEGACY_ALTER_TABLE
|
||||
SQLITE_DBCONFIG_LEGACY_FILE_FORMAT
|
||||
SQLITE_DBCONFIG_LOOKASIDE
|
||||
SQLITE_DBCONFIG_MAINDBNAME
|
||||
SQLITE_DBCONFIG_MAX
|
||||
SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE
|
||||
SQLITE_DBCONFIG_RESET_DATABASE
|
||||
SQLITE_DBCONFIG_REVERSE_SCANORDER
|
||||
SQLITE_DBCONFIG_STMT_SCANSTATUS
|
||||
SQLITE_DBCONFIG_TRIGGER_EQP
|
||||
SQLITE_DBCONFIG_TRUSTED_SCHEMA
|
||||
SQLITE_DBCONFIG_WRITABLE_SCHEMA
|
||||
/,
|
||||
|
||||
|
@ -100,26 +83,21 @@ our @EXPORT_OK = (
|
|||
SQLITE_AUTH_USER
|
||||
SQLITE_BUSY_RECOVERY
|
||||
SQLITE_BUSY_SNAPSHOT
|
||||
SQLITE_BUSY_TIMEOUT
|
||||
SQLITE_CANTOPEN_CONVPATH
|
||||
SQLITE_CANTOPEN_DIRTYWAL
|
||||
SQLITE_CANTOPEN_FULLPATH
|
||||
SQLITE_CANTOPEN_ISDIR
|
||||
SQLITE_CANTOPEN_NOTEMPDIR
|
||||
SQLITE_CANTOPEN_SYMLINK
|
||||
SQLITE_CONSTRAINT_CHECK
|
||||
SQLITE_CONSTRAINT_COMMITHOOK
|
||||
SQLITE_CONSTRAINT_DATATYPE
|
||||
SQLITE_CONSTRAINT_FOREIGNKEY
|
||||
SQLITE_CONSTRAINT_FUNCTION
|
||||
SQLITE_CONSTRAINT_NOTNULL
|
||||
SQLITE_CONSTRAINT_PINNED
|
||||
SQLITE_CONSTRAINT_PRIMARYKEY
|
||||
SQLITE_CONSTRAINT_ROWID
|
||||
SQLITE_CONSTRAINT_TRIGGER
|
||||
SQLITE_CONSTRAINT_UNIQUE
|
||||
SQLITE_CONSTRAINT_VTAB
|
||||
SQLITE_CORRUPT_INDEX
|
||||
SQLITE_CORRUPT_SEQUENCE
|
||||
SQLITE_CORRUPT_VTAB
|
||||
SQLITE_ERROR_MISSING_COLLSEQ
|
||||
|
@ -133,8 +111,6 @@ our @EXPORT_OK = (
|
|||
SQLITE_IOERR_CLOSE
|
||||
SQLITE_IOERR_COMMIT_ATOMIC
|
||||
SQLITE_IOERR_CONVPATH
|
||||
SQLITE_IOERR_CORRUPTFS
|
||||
SQLITE_IOERR_DATA
|
||||
SQLITE_IOERR_DELETE
|
||||
SQLITE_IOERR_DELETE_NOENT
|
||||
SQLITE_IOERR_DIR_CLOSE
|
||||
|
@ -142,7 +118,6 @@ our @EXPORT_OK = (
|
|||
SQLITE_IOERR_FSTAT
|
||||
SQLITE_IOERR_FSYNC
|
||||
SQLITE_IOERR_GETTEMPPATH
|
||||
SQLITE_IOERR_IN_PAGE
|
||||
SQLITE_IOERR_LOCK
|
||||
SQLITE_IOERR_MMAP
|
||||
SQLITE_IOERR_NOMEM
|
||||
|
@ -161,10 +136,8 @@ our @EXPORT_OK = (
|
|||
SQLITE_IOERR_WRITE
|
||||
SQLITE_LOCKED_SHAREDCACHE
|
||||
SQLITE_LOCKED_VTAB
|
||||
SQLITE_NOTICE_RBU
|
||||
SQLITE_NOTICE_RECOVER_ROLLBACK
|
||||
SQLITE_NOTICE_RECOVER_WAL
|
||||
SQLITE_OK_SYMLINK
|
||||
SQLITE_READONLY_CANTINIT
|
||||
SQLITE_READONLY_CANTLOCK
|
||||
SQLITE_READONLY_DBMOVED
|
||||
|
@ -177,26 +150,19 @@ our @EXPORT_OK = (
|
|||
# flags_for_file_open_operations
|
||||
qw/
|
||||
SQLITE_OPEN_CREATE
|
||||
SQLITE_OPEN_EXRESCODE
|
||||
SQLITE_OPEN_FULLMUTEX
|
||||
SQLITE_OPEN_MEMORY
|
||||
SQLITE_OPEN_NOFOLLOW
|
||||
SQLITE_OPEN_NOMUTEX
|
||||
SQLITE_OPEN_PRIVATECACHE
|
||||
SQLITE_OPEN_READONLY
|
||||
SQLITE_OPEN_READWRITE
|
||||
SQLITE_OPEN_SHAREDCACHE
|
||||
SQLITE_OPEN_SUPER_JOURNAL
|
||||
SQLITE_OPEN_URI
|
||||
/,
|
||||
|
||||
# function_flags
|
||||
qw/
|
||||
SQLITE_DETERMINISTIC
|
||||
SQLITE_DIRECTONLY
|
||||
SQLITE_INNOCUOUS
|
||||
SQLITE_RESULT_SUBTYPE
|
||||
SQLITE_SUBTYPE
|
||||
/,
|
||||
|
||||
# fundamental_datatypes
|
||||
|
@ -205,7 +171,6 @@ our @EXPORT_OK = (
|
|||
SQLITE_FLOAT
|
||||
SQLITE_INTEGER
|
||||
SQLITE_NULL
|
||||
SQLITE_TEXT
|
||||
/,
|
||||
|
||||
# result_codes
|
||||
|
@ -274,22 +239,18 @@ our %EXPORT_TAGS = (
|
|||
SQLITE_BUSY
|
||||
SQLITE_BUSY_RECOVERY
|
||||
SQLITE_BUSY_SNAPSHOT
|
||||
SQLITE_BUSY_TIMEOUT
|
||||
SQLITE_CANTOPEN
|
||||
SQLITE_CANTOPEN_CONVPATH
|
||||
SQLITE_CANTOPEN_DIRTYWAL
|
||||
SQLITE_CANTOPEN_FULLPATH
|
||||
SQLITE_CANTOPEN_ISDIR
|
||||
SQLITE_CANTOPEN_NOTEMPDIR
|
||||
SQLITE_CANTOPEN_SYMLINK
|
||||
SQLITE_CONSTRAINT
|
||||
SQLITE_CONSTRAINT_CHECK
|
||||
SQLITE_CONSTRAINT_COMMITHOOK
|
||||
SQLITE_CONSTRAINT_DATATYPE
|
||||
SQLITE_CONSTRAINT_FOREIGNKEY
|
||||
SQLITE_CONSTRAINT_FUNCTION
|
||||
SQLITE_CONSTRAINT_NOTNULL
|
||||
SQLITE_CONSTRAINT_PINNED
|
||||
SQLITE_CONSTRAINT_PRIMARYKEY
|
||||
SQLITE_CONSTRAINT_ROWID
|
||||
SQLITE_CONSTRAINT_TRIGGER
|
||||
|
@ -297,7 +258,6 @@ our %EXPORT_TAGS = (
|
|||
SQLITE_CONSTRAINT_VTAB
|
||||
SQLITE_COPY
|
||||
SQLITE_CORRUPT
|
||||
SQLITE_CORRUPT_INDEX
|
||||
SQLITE_CORRUPT_SEQUENCE
|
||||
SQLITE_CORRUPT_VTAB
|
||||
SQLITE_CREATE_INDEX
|
||||
|
@ -317,29 +277,18 @@ our %EXPORT_TAGS = (
|
|||
SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION
|
||||
SQLITE_DBCONFIG_ENABLE_QPSG
|
||||
SQLITE_DBCONFIG_ENABLE_TRIGGER
|
||||
SQLITE_DBCONFIG_ENABLE_VIEW
|
||||
SQLITE_DBCONFIG_LEGACY_ALTER_TABLE
|
||||
SQLITE_DBCONFIG_LEGACY_FILE_FORMAT
|
||||
SQLITE_DBCONFIG_LOOKASIDE
|
||||
SQLITE_DBCONFIG_MAINDBNAME
|
||||
SQLITE_DBCONFIG_MAX
|
||||
SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE
|
||||
SQLITE_DBCONFIG_RESET_DATABASE
|
||||
SQLITE_DBCONFIG_REVERSE_SCANORDER
|
||||
SQLITE_DBCONFIG_STMT_SCANSTATUS
|
||||
SQLITE_DBCONFIG_TRIGGER_EQP
|
||||
SQLITE_DBCONFIG_TRUSTED_SCHEMA
|
||||
SQLITE_DBCONFIG_WRITABLE_SCHEMA
|
||||
DBD_SQLITE_STRING_MODE_BYTES
|
||||
DBD_SQLITE_STRING_MODE_PV
|
||||
DBD_SQLITE_STRING_MODE_UNICODE_FALLBACK
|
||||
DBD_SQLITE_STRING_MODE_UNICODE_NAIVE
|
||||
DBD_SQLITE_STRING_MODE_UNICODE_STRICT
|
||||
SQLITE_DELETE
|
||||
SQLITE_DENY
|
||||
SQLITE_DETACH
|
||||
SQLITE_DETERMINISTIC
|
||||
SQLITE_DIRECTONLY
|
||||
SQLITE_DONE
|
||||
SQLITE_DROP_INDEX
|
||||
SQLITE_DROP_TABLE
|
||||
|
@ -360,7 +309,6 @@ our %EXPORT_TAGS = (
|
|||
SQLITE_FULL
|
||||
SQLITE_FUNCTION
|
||||
SQLITE_IGNORE
|
||||
SQLITE_INNOCUOUS
|
||||
SQLITE_INSERT
|
||||
SQLITE_INTEGER
|
||||
SQLITE_INTERNAL
|
||||
|
@ -374,8 +322,6 @@ our %EXPORT_TAGS = (
|
|||
SQLITE_IOERR_CLOSE
|
||||
SQLITE_IOERR_COMMIT_ATOMIC
|
||||
SQLITE_IOERR_CONVPATH
|
||||
SQLITE_IOERR_CORRUPTFS
|
||||
SQLITE_IOERR_DATA
|
||||
SQLITE_IOERR_DELETE
|
||||
SQLITE_IOERR_DELETE_NOENT
|
||||
SQLITE_IOERR_DIR_CLOSE
|
||||
|
@ -383,7 +329,6 @@ our %EXPORT_TAGS = (
|
|||
SQLITE_IOERR_FSTAT
|
||||
SQLITE_IOERR_FSYNC
|
||||
SQLITE_IOERR_GETTEMPPATH
|
||||
SQLITE_IOERR_IN_PAGE
|
||||
SQLITE_IOERR_LOCK
|
||||
SQLITE_IOERR_MMAP
|
||||
SQLITE_IOERR_NOMEM
|
||||
|
@ -422,23 +367,18 @@ our %EXPORT_TAGS = (
|
|||
SQLITE_NOTADB
|
||||
SQLITE_NOTFOUND
|
||||
SQLITE_NOTICE
|
||||
SQLITE_NOTICE_RBU
|
||||
SQLITE_NOTICE_RECOVER_ROLLBACK
|
||||
SQLITE_NOTICE_RECOVER_WAL
|
||||
SQLITE_NULL
|
||||
SQLITE_OK
|
||||
SQLITE_OK_SYMLINK
|
||||
SQLITE_OPEN_CREATE
|
||||
SQLITE_OPEN_EXRESCODE
|
||||
SQLITE_OPEN_FULLMUTEX
|
||||
SQLITE_OPEN_MEMORY
|
||||
SQLITE_OPEN_NOFOLLOW
|
||||
SQLITE_OPEN_NOMUTEX
|
||||
SQLITE_OPEN_PRIVATECACHE
|
||||
SQLITE_OPEN_READONLY
|
||||
SQLITE_OPEN_READWRITE
|
||||
SQLITE_OPEN_SHAREDCACHE
|
||||
SQLITE_OPEN_SUPER_JOURNAL
|
||||
SQLITE_OPEN_URI
|
||||
SQLITE_PERM
|
||||
SQLITE_PRAGMA
|
||||
|
@ -454,30 +394,18 @@ our %EXPORT_TAGS = (
|
|||
SQLITE_READONLY_ROLLBACK
|
||||
SQLITE_RECURSIVE
|
||||
SQLITE_REINDEX
|
||||
SQLITE_RESULT_SUBTYPE
|
||||
SQLITE_ROW
|
||||
SQLITE_SAVEPOINT
|
||||
SQLITE_SCHEMA
|
||||
SQLITE_SELECT
|
||||
SQLITE_SUBTYPE
|
||||
SQLITE_TEXT
|
||||
SQLITE_TOOBIG
|
||||
SQLITE_TRANSACTION
|
||||
SQLITE_TXN_NONE
|
||||
SQLITE_TXN_READ
|
||||
SQLITE_TXN_WRITE
|
||||
SQLITE_UPDATE
|
||||
SQLITE_VERSION_NUMBER
|
||||
SQLITE_WARNING
|
||||
SQLITE_WARNING_AUTOINDEX
|
||||
/],
|
||||
|
||||
allowed_return_values_from_sqlite3_txn_state => [qw/
|
||||
SQLITE_TXN_NONE
|
||||
SQLITE_TXN_READ
|
||||
SQLITE_TXN_WRITE
|
||||
/],
|
||||
|
||||
authorizer_action_codes => [qw/
|
||||
SQLITE_ALTER_TABLE
|
||||
SQLITE_ANALYZE
|
||||
|
@ -533,54 +461,36 @@ our %EXPORT_TAGS = (
|
|||
SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION
|
||||
SQLITE_DBCONFIG_ENABLE_QPSG
|
||||
SQLITE_DBCONFIG_ENABLE_TRIGGER
|
||||
SQLITE_DBCONFIG_ENABLE_VIEW
|
||||
SQLITE_DBCONFIG_LEGACY_ALTER_TABLE
|
||||
SQLITE_DBCONFIG_LEGACY_FILE_FORMAT
|
||||
SQLITE_DBCONFIG_LOOKASIDE
|
||||
SQLITE_DBCONFIG_MAINDBNAME
|
||||
SQLITE_DBCONFIG_MAX
|
||||
SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE
|
||||
SQLITE_DBCONFIG_RESET_DATABASE
|
||||
SQLITE_DBCONFIG_REVERSE_SCANORDER
|
||||
SQLITE_DBCONFIG_STMT_SCANSTATUS
|
||||
SQLITE_DBCONFIG_TRIGGER_EQP
|
||||
SQLITE_DBCONFIG_TRUSTED_SCHEMA
|
||||
SQLITE_DBCONFIG_WRITABLE_SCHEMA
|
||||
/],
|
||||
|
||||
dbd_sqlite_string_mode => [qw/
|
||||
DBD_SQLITE_STRING_MODE_BYTES
|
||||
DBD_SQLITE_STRING_MODE_PV
|
||||
DBD_SQLITE_STRING_MODE_UNICODE_FALLBACK
|
||||
DBD_SQLITE_STRING_MODE_UNICODE_NAIVE
|
||||
DBD_SQLITE_STRING_MODE_UNICODE_STRICT
|
||||
/],
|
||||
|
||||
extended_result_codes => [qw/
|
||||
SQLITE_ABORT_ROLLBACK
|
||||
SQLITE_AUTH_USER
|
||||
SQLITE_BUSY_RECOVERY
|
||||
SQLITE_BUSY_SNAPSHOT
|
||||
SQLITE_BUSY_TIMEOUT
|
||||
SQLITE_CANTOPEN_CONVPATH
|
||||
SQLITE_CANTOPEN_DIRTYWAL
|
||||
SQLITE_CANTOPEN_FULLPATH
|
||||
SQLITE_CANTOPEN_ISDIR
|
||||
SQLITE_CANTOPEN_NOTEMPDIR
|
||||
SQLITE_CANTOPEN_SYMLINK
|
||||
SQLITE_CONSTRAINT_CHECK
|
||||
SQLITE_CONSTRAINT_COMMITHOOK
|
||||
SQLITE_CONSTRAINT_DATATYPE
|
||||
SQLITE_CONSTRAINT_FOREIGNKEY
|
||||
SQLITE_CONSTRAINT_FUNCTION
|
||||
SQLITE_CONSTRAINT_NOTNULL
|
||||
SQLITE_CONSTRAINT_PINNED
|
||||
SQLITE_CONSTRAINT_PRIMARYKEY
|
||||
SQLITE_CONSTRAINT_ROWID
|
||||
SQLITE_CONSTRAINT_TRIGGER
|
||||
SQLITE_CONSTRAINT_UNIQUE
|
||||
SQLITE_CONSTRAINT_VTAB
|
||||
SQLITE_CORRUPT_INDEX
|
||||
SQLITE_CORRUPT_SEQUENCE
|
||||
SQLITE_CORRUPT_VTAB
|
||||
SQLITE_ERROR_MISSING_COLLSEQ
|
||||
|
@ -594,8 +504,6 @@ our %EXPORT_TAGS = (
|
|||
SQLITE_IOERR_CLOSE
|
||||
SQLITE_IOERR_COMMIT_ATOMIC
|
||||
SQLITE_IOERR_CONVPATH
|
||||
SQLITE_IOERR_CORRUPTFS
|
||||
SQLITE_IOERR_DATA
|
||||
SQLITE_IOERR_DELETE
|
||||
SQLITE_IOERR_DELETE_NOENT
|
||||
SQLITE_IOERR_DIR_CLOSE
|
||||
|
@ -603,7 +511,6 @@ our %EXPORT_TAGS = (
|
|||
SQLITE_IOERR_FSTAT
|
||||
SQLITE_IOERR_FSYNC
|
||||
SQLITE_IOERR_GETTEMPPATH
|
||||
SQLITE_IOERR_IN_PAGE
|
||||
SQLITE_IOERR_LOCK
|
||||
SQLITE_IOERR_MMAP
|
||||
SQLITE_IOERR_NOMEM
|
||||
|
@ -622,10 +529,8 @@ our %EXPORT_TAGS = (
|
|||
SQLITE_IOERR_WRITE
|
||||
SQLITE_LOCKED_SHAREDCACHE
|
||||
SQLITE_LOCKED_VTAB
|
||||
SQLITE_NOTICE_RBU
|
||||
SQLITE_NOTICE_RECOVER_ROLLBACK
|
||||
SQLITE_NOTICE_RECOVER_WAL
|
||||
SQLITE_OK_SYMLINK
|
||||
SQLITE_READONLY_CANTINIT
|
||||
SQLITE_READONLY_CANTLOCK
|
||||
SQLITE_READONLY_DBMOVED
|
||||
|
@ -637,25 +542,18 @@ our %EXPORT_TAGS = (
|
|||
|
||||
flags_for_file_open_operations => [qw/
|
||||
SQLITE_OPEN_CREATE
|
||||
SQLITE_OPEN_EXRESCODE
|
||||
SQLITE_OPEN_FULLMUTEX
|
||||
SQLITE_OPEN_MEMORY
|
||||
SQLITE_OPEN_NOFOLLOW
|
||||
SQLITE_OPEN_NOMUTEX
|
||||
SQLITE_OPEN_PRIVATECACHE
|
||||
SQLITE_OPEN_READONLY
|
||||
SQLITE_OPEN_READWRITE
|
||||
SQLITE_OPEN_SHAREDCACHE
|
||||
SQLITE_OPEN_SUPER_JOURNAL
|
||||
SQLITE_OPEN_URI
|
||||
/],
|
||||
|
||||
function_flags => [qw/
|
||||
SQLITE_DETERMINISTIC
|
||||
SQLITE_DIRECTONLY
|
||||
SQLITE_INNOCUOUS
|
||||
SQLITE_RESULT_SUBTYPE
|
||||
SQLITE_SUBTYPE
|
||||
/],
|
||||
|
||||
fundamental_datatypes => [qw/
|
||||
|
@ -663,7 +561,6 @@ our %EXPORT_TAGS = (
|
|||
SQLITE_FLOAT
|
||||
SQLITE_INTEGER
|
||||
SQLITE_NULL
|
||||
SQLITE_TEXT
|
||||
/],
|
||||
|
||||
result_codes => [qw/
|
||||
|
@ -736,24 +633,12 @@ DBD::SQLite::Constants - common SQLite constants
|
|||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
You can import necessary SQLite constants from this module. Available tags are C<all>, C<allowed_return_values_from_sqlite3_txn_state>, C<authorizer_action_codes>, C<authorizer_return_codes>, C<version> (C<compile_time_library_version_numbers>), C<database_connection_configuration_options>, C<dbd_sqlite_string_mode>, C<extended_result_codes>, C<file_open> (C<flags_for_file_open_operations>), C<function_flags>, C<datatypes> (C<fundamental_datatypes>), C<result_codes>, C<run_time_limit_categories>. See L<http://sqlite.org/c3ref/constlist.html> for the complete list of constants.
|
||||
You can import necessary SQLite constants from this module. Available tags are C<all>, C<authorizer_action_codes>, C<authorizer_return_codes>, C<version> (C<compile_time_library_version_numbers>), C<database_connection_configuration_options>, C<extended_result_codes>, C<file_open> (C<flags_for_file_open_operations>), C<function_flags>, C<datatypes> (C<fundamental_datatypes>), C<result_codes>, C<run_time_limit_categories>. See L<http://sqlite.org/c3ref/constlist.html> for the complete list of constants.
|
||||
|
||||
This module does not export anything by default.
|
||||
|
||||
=head1 CONSTANTS
|
||||
|
||||
=head2 allowed_return_values_from_sqlite3_txn_state
|
||||
|
||||
=over 4
|
||||
|
||||
=item SQLITE_TXN_NONE
|
||||
|
||||
=item SQLITE_TXN_READ
|
||||
|
||||
=item SQLITE_TXN_WRITE
|
||||
|
||||
=back
|
||||
|
||||
=head2 authorizer_action_codes
|
||||
|
||||
=over 4
|
||||
|
@ -882,32 +767,6 @@ This module does not export anything by default.
|
|||
|
||||
=item SQLITE_DBCONFIG_DQS_DDL
|
||||
|
||||
=item SQLITE_DBCONFIG_ENABLE_VIEW
|
||||
|
||||
=item SQLITE_DBCONFIG_LEGACY_FILE_FORMAT
|
||||
|
||||
=item SQLITE_DBCONFIG_TRUSTED_SCHEMA
|
||||
|
||||
=item SQLITE_DBCONFIG_STMT_SCANSTATUS
|
||||
|
||||
=item SQLITE_DBCONFIG_REVERSE_SCANORDER
|
||||
|
||||
=back
|
||||
|
||||
=head2 dbd_sqlite_string_mode
|
||||
|
||||
=over 4
|
||||
|
||||
=item DBD_SQLITE_STRING_MODE_PV
|
||||
|
||||
=item DBD_SQLITE_STRING_MODE_BYTES
|
||||
|
||||
=item DBD_SQLITE_STRING_MODE_UNICODE_NAIVE
|
||||
|
||||
=item DBD_SQLITE_STRING_MODE_UNICODE_FALLBACK
|
||||
|
||||
=item DBD_SQLITE_STRING_MODE_UNICODE_STRICT
|
||||
|
||||
=back
|
||||
|
||||
=head2 extended_result_codes
|
||||
|
@ -1046,26 +905,6 @@ This module does not export anything by default.
|
|||
|
||||
=item SQLITE_CANTOPEN_DIRTYWAL
|
||||
|
||||
=item SQLITE_CANTOPEN_SYMLINK
|
||||
|
||||
=item SQLITE_CONSTRAINT_PINNED
|
||||
|
||||
=item SQLITE_OK_SYMLINK
|
||||
|
||||
=item SQLITE_IOERR_DATA
|
||||
|
||||
=item SQLITE_BUSY_TIMEOUT
|
||||
|
||||
=item SQLITE_CORRUPT_INDEX
|
||||
|
||||
=item SQLITE_IOERR_CORRUPTFS
|
||||
|
||||
=item SQLITE_CONSTRAINT_DATATYPE
|
||||
|
||||
=item SQLITE_NOTICE_RBU
|
||||
|
||||
=item SQLITE_IOERR_IN_PAGE
|
||||
|
||||
=back
|
||||
|
||||
=head2 file_open (flags_for_file_open_operations)
|
||||
|
@ -1090,12 +929,6 @@ This module does not export anything by default.
|
|||
|
||||
=item SQLITE_OPEN_MEMORY
|
||||
|
||||
=item SQLITE_OPEN_NOFOLLOW
|
||||
|
||||
=item SQLITE_OPEN_SUPER_JOURNAL
|
||||
|
||||
=item SQLITE_OPEN_EXRESCODE
|
||||
|
||||
=back
|
||||
|
||||
=head2 function_flags
|
||||
|
@ -1104,14 +937,6 @@ This module does not export anything by default.
|
|||
|
||||
=item SQLITE_DETERMINISTIC
|
||||
|
||||
=item SQLITE_DIRECTONLY
|
||||
|
||||
=item SQLITE_SUBTYPE
|
||||
|
||||
=item SQLITE_INNOCUOUS
|
||||
|
||||
=item SQLITE_RESULT_SUBTYPE
|
||||
|
||||
=back
|
||||
|
||||
=head2 datatypes (fundamental_datatypes)
|
||||
|
@ -1126,8 +951,6 @@ This module does not export anything by default.
|
|||
|
||||
=item SQLITE_NULL
|
||||
|
||||
=item SQLITE_TEXT
|
||||
|
||||
=back
|
||||
|
||||
=head2 result_codes
|
||||
|
|
|
@ -5,7 +5,7 @@ use strict;
|
|||
use warnings;
|
||||
use Scalar::Util qw/weaken/;
|
||||
|
||||
our $VERSION = '1.76';
|
||||
our $VERSION = '1.63_05';
|
||||
our @ISA;
|
||||
|
||||
|
||||
|
|
89
sqlite3ext.h
89
sqlite3ext.h
|
@ -322,50 +322,6 @@ struct sqlite3_api_routines {
|
|||
/* Version 3.28.0 and later */
|
||||
int (*stmt_isexplain)(sqlite3_stmt*);
|
||||
int (*value_frombind)(sqlite3_value*);
|
||||
/* Version 3.30.0 and later */
|
||||
int (*drop_modules)(sqlite3*,const char**);
|
||||
/* Version 3.31.0 and later */
|
||||
sqlite3_int64 (*hard_heap_limit64)(sqlite3_int64);
|
||||
const char *(*uri_key)(const char*,int);
|
||||
const char *(*filename_database)(const char*);
|
||||
const char *(*filename_journal)(const char*);
|
||||
const char *(*filename_wal)(const char*);
|
||||
/* Version 3.32.0 and later */
|
||||
const char *(*create_filename)(const char*,const char*,const char*,
|
||||
int,const char**);
|
||||
void (*free_filename)(const char*);
|
||||
sqlite3_file *(*database_file_object)(const char*);
|
||||
/* Version 3.34.0 and later */
|
||||
int (*txn_state)(sqlite3*,const char*);
|
||||
/* Version 3.36.1 and later */
|
||||
sqlite3_int64 (*changes64)(sqlite3*);
|
||||
sqlite3_int64 (*total_changes64)(sqlite3*);
|
||||
/* Version 3.37.0 and later */
|
||||
int (*autovacuum_pages)(sqlite3*,
|
||||
unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
|
||||
void*, void(*)(void*));
|
||||
/* Version 3.38.0 and later */
|
||||
int (*error_offset)(sqlite3*);
|
||||
int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**);
|
||||
int (*vtab_distinct)(sqlite3_index_info*);
|
||||
int (*vtab_in)(sqlite3_index_info*,int,int);
|
||||
int (*vtab_in_first)(sqlite3_value*,sqlite3_value**);
|
||||
int (*vtab_in_next)(sqlite3_value*,sqlite3_value**);
|
||||
/* Version 3.39.0 and later */
|
||||
int (*deserialize)(sqlite3*,const char*,unsigned char*,
|
||||
sqlite3_int64,sqlite3_int64,unsigned);
|
||||
unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*,
|
||||
unsigned int);
|
||||
const char *(*db_name)(sqlite3*,int);
|
||||
/* Version 3.40.0 and later */
|
||||
int (*value_encoding)(sqlite3_value*);
|
||||
/* Version 3.41.0 and later */
|
||||
int (*is_interrupted)(sqlite3*);
|
||||
/* Version 3.43.0 and later */
|
||||
int (*stmt_explain)(sqlite3_stmt*,int);
|
||||
/* Version 3.44.0 and later */
|
||||
void *(*get_clientdata)(sqlite3*,const char*);
|
||||
int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*));
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -656,49 +612,8 @@ typedef int (*sqlite3_loadext_entry)(
|
|||
/* Version 3.26.0 and later */
|
||||
#define sqlite3_normalized_sql sqlite3_api->normalized_sql
|
||||
/* Version 3.28.0 and later */
|
||||
#define sqlite3_stmt_isexplain sqlite3_api->stmt_isexplain
|
||||
#define sqlite3_value_frombind sqlite3_api->value_frombind
|
||||
/* Version 3.30.0 and later */
|
||||
#define sqlite3_drop_modules sqlite3_api->drop_modules
|
||||
/* Version 3.31.0 and later */
|
||||
#define sqlite3_hard_heap_limit64 sqlite3_api->hard_heap_limit64
|
||||
#define sqlite3_uri_key sqlite3_api->uri_key
|
||||
#define sqlite3_filename_database sqlite3_api->filename_database
|
||||
#define sqlite3_filename_journal sqlite3_api->filename_journal
|
||||
#define sqlite3_filename_wal sqlite3_api->filename_wal
|
||||
/* Version 3.32.0 and later */
|
||||
#define sqlite3_create_filename sqlite3_api->create_filename
|
||||
#define sqlite3_free_filename sqlite3_api->free_filename
|
||||
#define sqlite3_database_file_object sqlite3_api->database_file_object
|
||||
/* Version 3.34.0 and later */
|
||||
#define sqlite3_txn_state sqlite3_api->txn_state
|
||||
/* Version 3.36.1 and later */
|
||||
#define sqlite3_changes64 sqlite3_api->changes64
|
||||
#define sqlite3_total_changes64 sqlite3_api->total_changes64
|
||||
/* Version 3.37.0 and later */
|
||||
#define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
|
||||
/* Version 3.38.0 and later */
|
||||
#define sqlite3_error_offset sqlite3_api->error_offset
|
||||
#define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value
|
||||
#define sqlite3_vtab_distinct sqlite3_api->vtab_distinct
|
||||
#define sqlite3_vtab_in sqlite3_api->vtab_in
|
||||
#define sqlite3_vtab_in_first sqlite3_api->vtab_in_first
|
||||
#define sqlite3_vtab_in_next sqlite3_api->vtab_in_next
|
||||
/* Version 3.39.0 and later */
|
||||
#ifndef SQLITE_OMIT_DESERIALIZE
|
||||
#define sqlite3_deserialize sqlite3_api->deserialize
|
||||
#define sqlite3_serialize sqlite3_api->serialize
|
||||
#endif
|
||||
#define sqlite3_db_name sqlite3_api->db_name
|
||||
/* Version 3.40.0 and later */
|
||||
#define sqlite3_value_encoding sqlite3_api->value_encoding
|
||||
/* Version 3.41.0 and later */
|
||||
#define sqlite3_is_interrupted sqlite3_api->is_interrupted
|
||||
/* Version 3.43.0 and later */
|
||||
#define sqlite3_stmt_explain sqlite3_api->stmt_explain
|
||||
/* Version 3.44.0 and later */
|
||||
#define sqlite3_get_clientdata sqlite3_api->get_clientdata
|
||||
#define sqlite3_set_clientdata sqlite3_api->set_clientdata
|
||||
#define sqlite3_stmt_isexplain sqlite3_api->isexplain
|
||||
#define sqlite3_value_frombind sqlite3_api->frombind
|
||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
|
|
|
@ -7,10 +7,6 @@ use SQLiteTest qw/connect_ok @CALL_FUNCS/;
|
|||
use Test::More;
|
||||
use if -d ".git", "Test::FailWarnings";
|
||||
|
||||
use DBD::SQLite::Constants ':dbd_sqlite_string_mode';
|
||||
|
||||
my $unicode_opt = DBD_SQLITE_STRING_MODE_UNICODE_STRICT;
|
||||
|
||||
my $show_diag = 0;
|
||||
foreach my $call_func (@CALL_FUNCS) {
|
||||
|
||||
|
@ -34,9 +30,9 @@ foreach my $call_func (@CALL_FUNCS) {
|
|||
skip( 'Unicode is not supported before 5.8.5', 2 );
|
||||
}
|
||||
my $file = 'foo'.$$;
|
||||
my $dbh = DBI->connect( "dbi:SQLite:dbname=$file;sqlite_string_mode=$unicode_opt", '', '' );
|
||||
my $dbh = DBI->connect( "dbi:SQLite:dbname=$file;sqlite_unicode=1", '', '' );
|
||||
isa_ok( $dbh, 'DBI::db' );
|
||||
is( $dbh->{sqlite_string_mode}, $unicode_opt, 'Unicode is on' );
|
||||
is( $dbh->{sqlite_unicode}, 1, 'Unicode is on' );
|
||||
$dbh->disconnect;
|
||||
unlink $file;
|
||||
}
|
||||
|
|
|
@ -25,12 +25,4 @@ ok($@, 'Statement 2 generated an error');
|
|||
is( $DBI::err, 19, '$DBI::err ok' );
|
||||
like( $DBI::errstr, qr/column a is not unique|UNIQUE constraint failed/, '$DBI::errstr ok' );
|
||||
|
||||
if ($DBD::SQLite::sqlite_version_number && $DBD::SQLite::sqlite_version_number >= 3038000) {
|
||||
my $sql = 'insert testerror values (1, 5)';
|
||||
eval { $dbh->do($sql) };
|
||||
my $offset = $dbh->sqlite_error_offset;
|
||||
ok $offset != -1, "error offset: $offset";
|
||||
note substr($sql, 0, $offset) . '<*error*>' . substr($sql, $offset);
|
||||
}
|
||||
|
||||
done_testing;
|
||||
|
|
|
@ -7,8 +7,6 @@ use Test::More;
|
|||
use if -d ".git", "Test::FailWarnings";
|
||||
use DBD::SQLite;
|
||||
use DBD::SQLite::Constants;
|
||||
use Digest::MD5 qw/md5/;
|
||||
use DBI qw/:sql_types/;
|
||||
|
||||
my @function_flags = (undef, 0);
|
||||
if ($DBD::SQLite::sqlite_version_number >= 3008003) {
|
||||
|
@ -55,14 +53,6 @@ sub noop {
|
|||
return $_[0];
|
||||
}
|
||||
|
||||
sub md5_text {
|
||||
return md5($_[0]);
|
||||
}
|
||||
|
||||
sub md5_blob {
|
||||
return [md5($_[0]), SQL_BLOB];
|
||||
}
|
||||
|
||||
foreach my $call_func (@CALL_FUNCS) { for my $flags (@function_flags) {
|
||||
my $dbh = connect_ok( PrintError => 0 );
|
||||
|
||||
|
@ -136,24 +126,6 @@ foreach my $call_func (@CALL_FUNCS) { for my $flags (@function_flags) {
|
|||
$result = $dbh->selectrow_arrayref( "SELECT typeof(noop(2147483648))" );
|
||||
is_deeply( $result, [ 'integer' ], "SELECT typeof(noop(2147483648))" );
|
||||
|
||||
ok($dbh->$call_func( "md5_text", 1, \&md5_text, defined $flags ? $flags : (), "create_function" ));
|
||||
$result = $dbh->selectrow_arrayref( "SELECT md5_text('my_blob')" );
|
||||
is_deeply( $result, [ md5('my_blob') ], "SELECT md5_text('my_blob')" );
|
||||
|
||||
$result = $dbh->selectrow_arrayref( "SELECT typeof(md5_text('my_blob'))" );
|
||||
is_deeply( $result, [ 'text' ], "SELECT typeof(md5_text('my_blob'))" );
|
||||
|
||||
ok($dbh->$call_func( "md5_blob", 1, \&md5_blob, defined $flags ? $flags : (), "create_function" ));
|
||||
$result = $dbh->selectrow_arrayref( "SELECT md5_blob('my_blob')" );
|
||||
is_deeply( $result, [ md5('my_blob') ], "SELECT md5_blob('my_blob')" );
|
||||
|
||||
$result = $dbh->selectrow_arrayref( "SELECT typeof(md5_blob('my_blob'))" );
|
||||
is_deeply( $result, [ 'blob' ], "SELECT typeof(md5_blob('my_blob'))" );
|
||||
|
||||
ok($dbh->$call_func( "md5_blob", 1, undef, defined $flags ? $flags : (), "create_function" ));
|
||||
$result = $dbh->selectrow_arrayref( "SELECT md5_blob('my_blob')" );
|
||||
is_deeply( $result, undef, "SELECT md5_blob('my_blob')" );
|
||||
|
||||
$dbh->disconnect;
|
||||
}}
|
||||
|
||||
|
|
|
@ -8,10 +8,6 @@ use SQLiteTest;
|
|||
use Test::More;
|
||||
use if -d ".git", "Test::FailWarnings";
|
||||
|
||||
use DBD::SQLite::Constants ':dbd_sqlite_string_mode';
|
||||
|
||||
my $unicode_opt = DBD_SQLITE_STRING_MODE_UNICODE_STRICT;
|
||||
|
||||
BEGIN { requires_unicode_support() }
|
||||
|
||||
#
|
||||
|
@ -55,7 +51,7 @@ ok(
|
|||
my ($textback, $bytesback);
|
||||
SCOPE: {
|
||||
my $dbh = connect_ok( dbfile => 'foo', RaiseError => 1 );
|
||||
is( $dbh->{sqlite_string_mode}, DBD::SQLite::Constants::DBD_SQLITE_STRING_MODE_PV, 'default string mode is pv' );
|
||||
is( $dbh->{sqlite_unicode}, 0, 'Unicode is off' );
|
||||
ok(
|
||||
$dbh->do("CREATE TABLE table1 (a TEXT, b BLOB)"),
|
||||
'CREATE TABLE',
|
||||
|
@ -77,8 +73,8 @@ SCOPE: {
|
|||
|
||||
# Start over but now activate Unicode support.
|
||||
SCOPE: {
|
||||
my $dbh = connect_ok( dbfile => 'foo', sqlite_string_mode => $unicode_opt );
|
||||
is( $dbh->{sqlite_string_mode}, $unicode_opt, 'Unicode is on' );
|
||||
my $dbh = connect_ok( dbfile => 'foo', sqlite_unicode => 1 );
|
||||
is( $dbh->{sqlite_unicode}, 1, 'Unicode is on' );
|
||||
|
||||
($textback, $bytesback) = database_roundtrip($dbh, $utfstring, $bytestring);
|
||||
|
||||
|
|
|
@ -7,9 +7,6 @@ use Test::More;
|
|||
use if -d ".git", "Test::FailWarnings";
|
||||
use Encode qw/decode/;
|
||||
use DBD::SQLite;
|
||||
use DBD::SQLite::Constants ':dbd_sqlite_string_mode';
|
||||
|
||||
my $unicode_opt = DBD_SQLITE_STRING_MODE_UNICODE_STRICT;
|
||||
|
||||
BEGIN { requires_unicode_support(); }
|
||||
|
||||
|
@ -74,10 +71,10 @@ is($DBD::SQLite::COLLATION{foo}, \&by_num_desc, "overridden collation");
|
|||
|
||||
foreach my $call_func (@CALL_FUNCS) {
|
||||
|
||||
for my $unicode_opt (DBD_SQLITE_STRING_MODE_BYTES, DBD_SQLITE_STRING_MODE_UNICODE_STRICT) {
|
||||
for my $use_unicode (0, 1) {
|
||||
|
||||
# connect
|
||||
my $dbh = connect_ok( RaiseError => 1, sqlite_string_mode => $unicode_opt );
|
||||
my $dbh = connect_ok( RaiseError => 1, sqlite_unicode => $use_unicode );
|
||||
|
||||
# populate test data
|
||||
my @words = qw{
|
||||
|
@ -87,7 +84,7 @@ foreach my $call_func (@CALL_FUNCS) {
|
|||
HAT hâôer
|
||||
féôu fêôe fèöe ferme
|
||||
};
|
||||
if ($unicode_opt != DBD_SQLITE_STRING_MODE_BYTES) {
|
||||
if ($use_unicode) {
|
||||
utf8::upgrade($_) foreach @words;
|
||||
}
|
||||
|
||||
|
|
17
t/20_blobs.t
17
t/20_blobs.t
|
@ -73,19 +73,6 @@ SCOPE: {
|
|||
ok( $dbh->do("INSERT INTO one VALUES( 5, $quoted_empty )"), 'insert quoted empty string' );
|
||||
ok my $quoted_undef = $dbh->quote(undef, SQL_BLOB);
|
||||
ok( $dbh->do("INSERT INTO one VALUES( 6, $quoted_undef )"), 'insert quoted undef' );
|
||||
|
||||
|
||||
ok my $quoted_bit = $dbh->quote($blob, SQL_BIT);
|
||||
ok( $dbh->do("INSERT INTO one VALUES( 7, $quoted_bit )"), 'insert quoted bit' );
|
||||
|
||||
ok my $quoted_binary = $dbh->quote($blob, SQL_BINARY);
|
||||
ok( $dbh->do("INSERT INTO one VALUES( 8, $quoted_binary )"), 'insert quoted binary' );
|
||||
|
||||
ok my $quoted_varbinary = $dbh->quote($blob, SQL_VARBINARY);
|
||||
ok( $dbh->do("INSERT INTO one VALUES( 9, $quoted_varbinary )"), 'insert quoted varbinary' );
|
||||
|
||||
ok my $quoted_longvarbinary = $dbh->quote($blob, SQL_LONGVARBINARY);
|
||||
ok( $dbh->do("INSERT INTO one VALUES( 10, $quoted_longvarbinary )"), 'insert quoted longvarbinary' );
|
||||
}
|
||||
|
||||
# Now, try SELECT'ing the row out.
|
||||
|
@ -101,10 +88,6 @@ SCOPE: {
|
|||
[ 4, $blob ],
|
||||
[ 5, '' ],
|
||||
[ 6, undef ],
|
||||
[ 7, $blob ],
|
||||
[ 8, $blob ],
|
||||
[ 9, $blob ],
|
||||
[ 10, $blob ],
|
||||
], 'Got the blob back ok' );
|
||||
ok( $sth->finish, '->finish' );
|
||||
}
|
||||
|
|
|
@ -10,10 +10,6 @@ use if -d ".git", "Test::FailWarnings";
|
|||
use File::Temp ();
|
||||
use File::Spec::Functions ':ALL';
|
||||
|
||||
use DBD::SQLite::Constants ':dbd_sqlite_string_mode';
|
||||
|
||||
my $unicode_opt = DBD_SQLITE_STRING_MODE_UNICODE_STRICT;
|
||||
|
||||
BEGIN { requires_unicode_support() }
|
||||
|
||||
my $dir = File::Temp::tempdir( CLEANUP => 1 );
|
||||
|
@ -59,7 +55,7 @@ foreach my $subdir ( 'longascii', 'adatb
|
|||
my $dbh = DBI->connect("dbi:SQLite:dbname=$dbfile", undef, undef, {
|
||||
RaiseError => 1,
|
||||
PrintError => 0,
|
||||
sqlite_string_mode => $unicode_opt,
|
||||
sqlite_unicode => 1,
|
||||
} );
|
||||
isa_ok( $dbh, 'DBI::db' );
|
||||
};
|
||||
|
@ -71,7 +67,7 @@ foreach my $subdir ( 'longascii', 'adatb
|
|||
my $dbh = DBI->connect("dbi:SQLite:dbname=$dbfile", undef, undef, {
|
||||
RaiseError => 1,
|
||||
PrintError => 0,
|
||||
sqlite_string_mode => $unicode_opt,
|
||||
sqlite_unicode => 1,
|
||||
} );
|
||||
isa_ok( $dbh, 'DBI::db' );
|
||||
};
|
||||
|
|
|
@ -28,14 +28,13 @@ BEGIN {
|
|||
use locale;
|
||||
|
||||
use DBD::SQLite;
|
||||
use DBD::SQLite::Constants ':dbd_sqlite_string_mode';
|
||||
|
||||
foreach my $call_func (@CALL_FUNCS) {
|
||||
|
||||
for my $string_mode (DBD_SQLITE_STRING_MODE_BYTES, DBD_SQLITE_STRING_MODE_UNICODE_STRICT) {
|
||||
for my $use_unicode (0, 1) {
|
||||
|
||||
# connect
|
||||
my $dbh = connect_ok( RaiseError => 1, sqlite_string_mode => $string_mode );
|
||||
my $dbh = connect_ok( RaiseError => 1, sqlite_unicode => $use_unicode );
|
||||
|
||||
# The following tests are about ordering, so don't reverse!
|
||||
if ($dbh->selectrow_array('PRAGMA reverse_unordered_selects')) {
|
||||
|
@ -44,7 +43,7 @@ foreach my $call_func (@CALL_FUNCS) {
|
|||
|
||||
# populate test data
|
||||
my @vals = @words;
|
||||
if ($string_mode == DBD_SQLITE_STRING_MODE_BYTES) {
|
||||
if ($use_unicode) {
|
||||
utf8::upgrade($_) foreach @vals;
|
||||
}
|
||||
|
||||
|
|
75
t/43_fts3.t
75
t/43_fts3.t
|
@ -1,15 +1,11 @@
|
|||
use strict;
|
||||
use warnings;
|
||||
no if $] >= 5.022, "warnings", "locale";
|
||||
use lib "t/lib";
|
||||
use Time::HiRes qw/time/;
|
||||
use SQLiteTest;
|
||||
use Test::More;
|
||||
use if -d ".git", "Test::FailWarnings";
|
||||
use DBD::SQLite;
|
||||
use DBD::SQLite::Constants ':dbd_sqlite_string_mode';
|
||||
|
||||
# Avoid slowdown with -DDEBUGGING:
|
||||
${^UTF8CACHE} = 1;
|
||||
|
||||
my @texts = ("il était une bergère",
|
||||
"qui gardait ses moutons",
|
||||
|
@ -28,9 +24,6 @@ my @tests = (
|
|||
["(il OR elle) AND un*" => 0, 2 ],
|
||||
);
|
||||
|
||||
my $ix_une_native = index($texts[0], "une");
|
||||
my $ix_une_utf8 = do {use bytes; utf8::upgrade(my $bergere_utf8 = $texts[0]); index($bergere_utf8, "une");};
|
||||
|
||||
BEGIN {
|
||||
requires_unicode_support();
|
||||
|
||||
|
@ -42,19 +35,31 @@ BEGIN {
|
|||
}
|
||||
}
|
||||
|
||||
# Perl may spit a warning on locale
|
||||
# use Test::NoWarnings;
|
||||
|
||||
sub Unicode_Word_tokenizer { # see also: Search::Tokenizer
|
||||
BEGIN {
|
||||
# Sadly perl for windows (and probably sqlite, too) may hang
|
||||
# if the system locale doesn't support european languages.
|
||||
# en-us should be a safe default. if it doesn't work, use 'C'.
|
||||
if ( $^O eq 'MSWin32') {
|
||||
use POSIX 'locale_h';
|
||||
setlocale(LC_COLLATE, 'en-us');
|
||||
}
|
||||
}
|
||||
|
||||
use locale;
|
||||
|
||||
sub locale_tokenizer { # see also: Search::Tokenizer
|
||||
return sub {
|
||||
my $string = shift;
|
||||
my $regex = qr/\p{Word}+/;
|
||||
my $regex = qr/\w+/;
|
||||
my $term_index = 0;
|
||||
|
||||
return sub {
|
||||
$string =~ /$regex/g or return; # either match, or no more token
|
||||
my $term = $&;
|
||||
my $end = pos $string; # $+[0] is much slower
|
||||
my $len = length($term);
|
||||
my $start = $end - $len;
|
||||
my ($start, $end) = ($-[0], $+[0]);
|
||||
my $term = substr($string, $start, my $len = $end-$start);
|
||||
return ($term, $len, $start, $end, $term_index++);
|
||||
};
|
||||
};
|
||||
|
@ -62,10 +67,10 @@ sub Unicode_Word_tokenizer { # see also: Search::Tokenizer
|
|||
|
||||
use DBD::SQLite;
|
||||
|
||||
for my $string_mode (DBD_SQLITE_STRING_MODE_BYTES, DBD_SQLITE_STRING_MODE_UNICODE_STRICT) {
|
||||
for my $use_unicode (0, 1) {
|
||||
|
||||
# connect
|
||||
my $dbh = connect_ok( RaiseError => 1, sqlite_string_mode => $string_mode );
|
||||
my $dbh = connect_ok( RaiseError => 1, sqlite_unicode => $use_unicode );
|
||||
|
||||
for my $fts (qw/fts3 fts4/) {
|
||||
next if $fts eq 'fts4' && !has_sqlite('3.7.4');
|
||||
|
@ -73,7 +78,7 @@ for my $string_mode (DBD_SQLITE_STRING_MODE_BYTES, DBD_SQLITE_STRING_MODE_UNICOD
|
|||
# create fts table
|
||||
$dbh->do(<<"") or die DBI::errstr;
|
||||
CREATE VIRTUAL TABLE try_$fts
|
||||
USING $fts(content, tokenize=perl 'main::Unicode_Word_tokenizer')
|
||||
USING $fts(content, tokenize=perl 'main::locale_tokenizer')
|
||||
|
||||
# populate it
|
||||
my $insert_sth = $dbh->prepare(<<"") or die DBI::errstr;
|
||||
|
@ -97,43 +102,9 @@ for my $string_mode (DBD_SQLITE_STRING_MODE_BYTES, DBD_SQLITE_STRING_MODE_UNICOD
|
|||
my ($query, @expected) = @$t;
|
||||
@expected = map {$doc_ids[$_]} @expected;
|
||||
my $results = $dbh->selectcol_arrayref($sql, undef, $query);
|
||||
is_deeply($results, \@expected, "$query ($fts, string_mode=$string_mode)");
|
||||
is_deeply($results, \@expected, "$query ($fts, unicode=$use_unicode)");
|
||||
}
|
||||
}
|
||||
|
||||
# the 'snippet' function should highlight the words in the MATCH query
|
||||
my $sql_snip = "SELECT snippet(try_$fts) FROM try_$fts WHERE content MATCH ?";
|
||||
my $result = $dbh->selectcol_arrayref($sql_snip, undef, 'une');
|
||||
is_deeply($result, ['il était <b>une</b> bergère'], "snippet ($fts, string_mode=$string_mode)");
|
||||
|
||||
# the 'offsets' function should return integer offsets for the words in the MATCH query
|
||||
my $sql_offsets = "SELECT offsets(try_$fts) FROM try_$fts WHERE content MATCH ?";
|
||||
$result = $dbh->selectcol_arrayref($sql_offsets, undef, 'une');
|
||||
my $offset_une = $string_mode == DBD_SQLITE_STRING_MODE_UNICODE_STRICT ? $ix_une_utf8 : $ix_une_native;
|
||||
my $expected_offsets = "0 0 $offset_une 3";
|
||||
is_deeply($result, [$expected_offsets], "offsets ($fts, string_mode=$string_mode)");
|
||||
|
||||
# test snippet() on a longer sentence
|
||||
$insert_sth->execute(join " ", @texts);
|
||||
$result = $dbh->selectcol_arrayref($sql_snip, undef, '"bergère qui gardait"');
|
||||
like($result->[0],
|
||||
qr[une <b>bergère</b> <b>qui</b> <b>gardait</b> ses],
|
||||
"longer snippet ($fts, string_mode=$string_mode)");
|
||||
|
||||
# simulated large document
|
||||
open my $fh, "<", $INC{'DBD/SQLite.pm'} or die $!;
|
||||
my $source_code = do {local $/; <$fh>};
|
||||
my $long_doc = $source_code x 5;
|
||||
|
||||
my $t0 = time;
|
||||
$insert_sth->execute($long_doc);
|
||||
my $t1 = time;
|
||||
$result = $dbh->selectcol_arrayref($sql_snip, undef, '"package DBD::SQLite"');
|
||||
my $t2 = time;
|
||||
|
||||
note sprintf("long doc (%d chars): insert in %.4f secs, select in %.4f secs",
|
||||
length($long_doc), $t1-$t0, $t2-$t1);
|
||||
like($result->[0], qr[^<b>package</b> <b>DBD</b>::<b>SQLite</b>;], 'snippet "package SQLite"');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,6 @@ use Test::More;
|
|||
|
||||
BEGIN { requires_unicode_support() }
|
||||
|
||||
use DBD::SQLite::Constants ':dbd_sqlite_string_mode';
|
||||
|
||||
# special case for multibyte (non-ASCII) character class,
|
||||
# which only works correctly under the unicode mode
|
||||
my @words = ("\x{e3}\x{83}\x{86}\x{e3}\x{82}\x{b9}\x{e3}\x{83}\x{88}", "\x{e3}\x{83}\x{86}\x{e3}\x{83}\x{b3}\x{e3}\x{83}\x{88}"); # テスト テント
|
||||
|
@ -17,15 +15,15 @@ my $regex = "\x{e3}\x{83}\x{86}[\x{e3}\x{82}\x{b9}\x{e3}\x{83}\x{b3}]\x{e3}\x{83
|
|||
|
||||
foreach my $call_func (@CALL_FUNCS) {
|
||||
|
||||
for my $string_mode (DBD_SQLITE_STRING_MODE_PV, DBD_SQLITE_STRING_MODE_UNICODE_STRICT) {
|
||||
for my $use_unicode (0, 1) {
|
||||
|
||||
# connect
|
||||
my $dbh = connect_ok( RaiseError => 1, sqlite_string_mode => $string_mode );
|
||||
my $dbh = connect_ok( RaiseError => 1, sqlite_unicode => $use_unicode );
|
||||
|
||||
# populate test data
|
||||
my @vals = @words;
|
||||
my $re = $regex;
|
||||
if ($string_mode == DBD_SQLITE_STRING_MODE_UNICODE_STRICT) {
|
||||
if ($use_unicode) {
|
||||
utf8::decode($_) foreach @vals;
|
||||
utf8::decode($re);
|
||||
}
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
use strict;
|
||||
use warnings;
|
||||
use lib "t/lib";
|
||||
use SQLiteTest qw/connect_ok @CALL_FUNCS/;
|
||||
use Test::More;
|
||||
use if -d ".git", "Test::FailWarnings";
|
||||
use DBD::SQLite::Constants ':allowed_return_values_from_sqlite3_txn_state';
|
||||
|
||||
note "test main schema";
|
||||
test('main');
|
||||
note "test undef schema";
|
||||
test(undef);
|
||||
note "omit schema";
|
||||
test();
|
||||
done_testing;
|
||||
|
||||
sub test {
|
||||
my @schema = @_;
|
||||
die if @schema > 1;
|
||||
|
||||
for my $func (@CALL_FUNCS) {
|
||||
my $dbh = connect_ok(PrintError => 0, RaiseError => 1);
|
||||
$dbh->do('create table foo (id)');
|
||||
|
||||
my $txn_state = $dbh->$func(@schema, 'txn_state');
|
||||
is $txn_state => SQLITE_TXN_NONE, "internal transaction is none";
|
||||
|
||||
$dbh->do('BEGIN');
|
||||
|
||||
my $row = $dbh->selectrow_arrayref('SELECT * FROM foo');
|
||||
|
||||
$txn_state = $dbh->$func(@schema, 'txn_state');
|
||||
is $txn_state => SQLITE_TXN_READ, "internal transaction is read";
|
||||
|
||||
$dbh->do('insert into foo values (1)');
|
||||
$txn_state = $dbh->$func(@schema, 'txn_state');
|
||||
is $txn_state => SQLITE_TXN_WRITE, "internal transaction is write";
|
||||
|
||||
$dbh->commit;
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
# This is a test for correct handling of upgraded strings without
|
||||
# the sqlite_unicode parameter.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use lib "t/lib";
|
||||
use SQLiteTest;
|
||||
use DBD::SQLite::Constants;
|
||||
use Test::More;
|
||||
use if -d ".git", "Test::FailWarnings";
|
||||
|
||||
{
|
||||
my $dbh = connect_ok( dbfile => 'foo', RaiseError => 1 );
|
||||
$dbh->{sqlite_string_mode} = DBD::SQLite::Constants::DBD_SQLITE_STRING_MODE_BYTES;
|
||||
|
||||
my $tbl_name = "\xe9p\xe9e";
|
||||
utf8::encode $tbl_name;
|
||||
|
||||
my $str = "CREATE TABLE $tbl_name ( col1 TEXT )";
|
||||
utf8::upgrade $str;
|
||||
|
||||
$dbh->do($str);
|
||||
|
||||
my $master_ar = $dbh->selectall_arrayref('SELECT * FROM sqlite_master', { Slice => {} });
|
||||
|
||||
is(
|
||||
$master_ar->[0]{'name'},
|
||||
$tbl_name,
|
||||
'do() takes correct string value',
|
||||
);
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
my $dummy_str = "SELECT '$tbl_name'";
|
||||
utf8::upgrade $dummy_str;
|
||||
|
||||
my $sth = $dbh->prepare($dummy_str);
|
||||
$sth->execute();
|
||||
my $row = $sth->fetchrow_arrayref();
|
||||
|
||||
is(
|
||||
$row->[0],
|
||||
$tbl_name,
|
||||
'prepare() takes correct string value',
|
||||
);
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
my $tbl_name_ug = $tbl_name;
|
||||
utf8::upgrade $tbl_name_ug;
|
||||
|
||||
my $sth2 = $dbh->prepare('SELECT ?');
|
||||
$sth2->execute( do { my $v = $tbl_name_ug } );
|
||||
$row = $sth2->fetchrow_arrayref();
|
||||
|
||||
is(
|
||||
$row->[0],
|
||||
$tbl_name,
|
||||
'execute() takes correct string value',
|
||||
);
|
||||
}
|
||||
|
||||
done_testing;
|
|
@ -5,14 +5,10 @@ use SQLiteTest;
|
|||
use Test::More;
|
||||
use if -d ".git", "Test::FailWarnings";
|
||||
|
||||
use DBD::SQLite::Constants ':dbd_sqlite_string_mode';
|
||||
|
||||
my $unicode_opt = DBD_SQLITE_STRING_MODE_UNICODE_STRICT;
|
||||
|
||||
BEGIN { requires_unicode_support(); }
|
||||
|
||||
my $dbh = connect_ok( sqlite_string_mode => $unicode_opt );
|
||||
is( $dbh->{sqlite_string_mode}, $unicode_opt, 'string mode is unicode/strict' );
|
||||
my $dbh = connect_ok( sqlite_unicode => 1 );
|
||||
is( $dbh->{sqlite_unicode}, 1, 'Unicode is on' );
|
||||
|
||||
ok( $dbh->do(<<'END_SQL'), 'CREATE TABLE' );
|
||||
CREATE TABLE foo (
|
||||
|
|
|
@ -5,14 +5,10 @@ use SQLiteTest;
|
|||
use Test::More;
|
||||
use if -d ".git", "Test::FailWarnings";
|
||||
|
||||
use DBD::SQLite::Constants ':dbd_sqlite_string_mode';
|
||||
|
||||
my $unicode_opt = DBD_SQLITE_STRING_MODE_UNICODE_STRICT;
|
||||
|
||||
BEGIN { requires_unicode_support() }
|
||||
|
||||
foreach my $call_func (@CALL_FUNCS) {
|
||||
my $dbh = connect_ok( sqlite_string_mode => $unicode_opt );
|
||||
my $dbh = connect_ok( sqlite_unicode => 1 );
|
||||
ok($dbh->$call_func( "perl_uc", 1, \&perl_uc, "create_function" ));
|
||||
|
||||
ok( $dbh->do(<<'END_SQL'), 'CREATE TABLE' );
|
||||
|
|
|
@ -6,11 +6,9 @@ use Test::More;
|
|||
use if -d ".git", "Test::FailWarnings";
|
||||
use DBI qw/:sql_types/;
|
||||
|
||||
use DBD::SQLite::Constants ':dbd_sqlite_string_mode';
|
||||
|
||||
BEGIN{ requires_unicode_support(); }
|
||||
|
||||
my $dbh = connect_ok(sqlite_string_mode => DBD_SQLITE_STRING_MODE_UNICODE_STRICT);
|
||||
my $dbh = connect_ok(sqlite_unicode => 1);
|
||||
$dbh->do('create table test1 (id integer, b blob)');
|
||||
|
||||
my $blob = "\x{82}\x{A0}";
|
||||
|
|
|
@ -8,7 +8,7 @@ use if -d ".git", "Test::FailWarnings";
|
|||
my $dbh = connect_ok(sqlite_see_if_its_a_number => 1);
|
||||
$dbh->do('create table foo (id integer primary key, exp)');
|
||||
my $ct = 0;
|
||||
for my $value (qw/2e1000 10.04e1000/) {
|
||||
for my $value (qw/2e100 10.04e100/) {
|
||||
eval {
|
||||
$dbh->do('insert into foo values (?, ?)', undef, $ct++, $value);
|
||||
my $got = $dbh->selectrow_arrayref('select * from foo where exp = ?', undef, $value);
|
||||
|
|
|
@ -6,8 +6,6 @@ use Test::More;
|
|||
use if -d ".git", "Test::FailWarnings";
|
||||
use Encode;
|
||||
|
||||
use DBD::SQLite::Constants ':dbd_sqlite_string_mode';
|
||||
|
||||
BEGIN { requires_unicode_support() }
|
||||
|
||||
unicode_test("\x{263A}"); # (decoded) smiley character
|
||||
|
@ -22,7 +20,7 @@ sub unicode_test {
|
|||
|
||||
{ # tests for an environment where everything is encoded
|
||||
|
||||
my $dbh = connect_ok(sqlite_string_mode => DBD_SQLITE_STRING_MODE_BYTES);
|
||||
my $dbh = connect_ok(sqlite_unicode => 0);
|
||||
$dbh->do("pragma foreign_keys = on");
|
||||
my $unicode_quoted = $dbh->quote_identifier($unicode_encoded);
|
||||
$dbh->do("create table $unicode_quoted (id, $unicode_quoted primary key)");
|
||||
|
@ -89,7 +87,7 @@ sub unicode_test {
|
|||
}
|
||||
|
||||
{ # tests for an environment where everything is decoded
|
||||
my $dbh = connect_ok(sqlite_string_mode => DBD_SQLITE_STRING_MODE_UNICODE_STRICT);
|
||||
my $dbh = connect_ok(sqlite_unicode => 1);
|
||||
$dbh->do("pragma foreign_keys = on");
|
||||
my $unicode_quoted = $dbh->quote_identifier($unicode);
|
||||
$dbh->do("create table $unicode_quoted (id, $unicode_quoted primary key)");
|
||||
|
|
|
@ -11,10 +11,8 @@ use if -d ".git", "Test::FailWarnings";
|
|||
|
||||
BEGIN { requires_unicode_support() }
|
||||
|
||||
use DBD::SQLite::Constants ':dbd_sqlite_string_mode';
|
||||
|
||||
my $dbh = connect_ok( sqlite_string_mode => DBD_SQLITE_STRING_MODE_UNICODE_NAIVE );
|
||||
is( $dbh->{sqlite_string_mode}, DBD_SQLITE_STRING_MODE_UNICODE_NAIVE, 'Unicode is on' );
|
||||
my $dbh = connect_ok( sqlite_unicode => 1 );
|
||||
is( $dbh->{sqlite_unicode}, 1, 'Unicode is on' );
|
||||
|
||||
ok( $dbh->do(<<'END_SQL'), 'CREATE TABLE' );
|
||||
CREATE TABLE foo (
|
||||
|
|
|
@ -166,32 +166,6 @@ my %since = (
|
|||
DBCONFIG_LEGACY_ALTER_TABLE => '3029000',
|
||||
DBCONFIG_DQS_DML => '3029000',
|
||||
DBCONFIG_DQS_DDL => '3029000',
|
||||
DBCONFIG_ENABLE_VIEW => '3030000',
|
||||
DIRECTONLY => '3030000',
|
||||
SUBTYPE => '3030000',
|
||||
DBCONFIG_LEGACY_FILE_FORMAT => '3031000',
|
||||
DBCONFIG_TRUSTED_SCHEMA => '3031000',
|
||||
CANTOPEN_SYMLINK => '3031000',
|
||||
CONSTRAINT_PINNED => '3031000',
|
||||
OK_SYMLINK => '3031000',
|
||||
OPEN_NOFOLLOW => '3031000',
|
||||
INNOCUOUS => '3031000',
|
||||
IOERR_DATA => '3032000',
|
||||
BUSY_TIMEOUT => '3032000',
|
||||
CORRUPT_INDEX => '3032000',
|
||||
OPEN_SUPER_JOURNAL => '3033000',
|
||||
TXN_NONE => '3034000',
|
||||
TXN_READ => '3034000',
|
||||
TXN_WRITE => '3034000',
|
||||
IOERR_CORRUPTFS => '3034000',
|
||||
SESSION_OBJCONFIG_SIZE => '3036000',
|
||||
CONSTRAINT_DATATYPE => '3037000',
|
||||
OPEN_EXRESCODE => '3037000',
|
||||
NOTICE_RBU => '3041000',
|
||||
DBCONFIG_STMT_SCANSTATUS => '3042000',
|
||||
DBCONFIG_REVERSE_SCANORDER => '3042000',
|
||||
IOERR_IN_PAGE => '3043000',
|
||||
RESULT_SUBTYPE => '3044001',
|
||||
|
||||
status_parameters_for_prepared_statements => '3006004',
|
||||
extended_result_codes => '3006005',
|
||||
|
@ -206,7 +180,6 @@ my %since = (
|
|||
checkpoint_mode_values => '3008008',
|
||||
prepared_statement_scan_status_opcodes => '3008008',
|
||||
sql_trace_event_codes => '3014000',
|
||||
allowed_return_values_from_sqlite3_txn_state => '3034000',
|
||||
);
|
||||
|
||||
my %until = (
|
||||
|
@ -222,7 +195,6 @@ my %ignore = map {$_ => 1} qw/
|
|||
OPEN_MAIN_JOURNAL OPEN_TEMP_JOURNAL
|
||||
OPEN_SUBJOURNAL OPEN_MASTER_JOURNAL OPEN_WAL
|
||||
OK_LOAD_PERMANENTLY PREPARE_PERSISTENT
|
||||
SESSION_OBJCONFIG_SIZE
|
||||
/;
|
||||
|
||||
my $ignore_tag_re = join '|', (
|
||||
|
@ -237,9 +209,6 @@ my $ignore_tag_re = join '|', (
|
|||
'virtual_table_configuration_options', # for sqlite3_vtab_config
|
||||
'prepare_flags', # for sqlite3_prepare_v3
|
||||
|
||||
'delete_a_session_object',
|
||||
'prepared_statement_scan_status',
|
||||
|
||||
# status flags (status methods are read-only at the moment)
|
||||
'status_parameters',
|
||||
'status_parameters_for_database_connections',
|
||||
|
@ -265,7 +234,6 @@ my $ignore_tag_re = join '|', (
|
|||
'text_encodings',
|
||||
'virtual_table_constraint_operator_codes',
|
||||
'virtual_table_indexing_information',
|
||||
'options_for_sqlite3session_object_config',
|
||||
);
|
||||
|
||||
my %compat = map {$_ => 1} qw/
|
||||
|
@ -286,7 +254,6 @@ sub extract_constants {
|
|||
if (/^\*\* CAPI3REF: (.+)/) {
|
||||
$tag = lc $1;
|
||||
$tag =~ s/[ \-]+/_/g;
|
||||
$tag =~ s/[\[\]]//g;
|
||||
($tag) = $tag =~ /^(\w+)/;
|
||||
$tag =~ s/_$//;
|
||||
if ($tag =~ /^($ignore_tag_re)/) {
|
||||
|
@ -295,7 +262,7 @@ sub extract_constants {
|
|||
}
|
||||
next;
|
||||
}
|
||||
if ($tag && /^#\s*define SQLITE_(\S+)\s+(\d+|\(SQLITE)/) {
|
||||
if ($tag && /^#define SQLITE_(\S+)\s+(\d+|\(SQLITE)/) {
|
||||
my ($name, $value) = ($1, $2);
|
||||
if ($name eq 'VERSION_NUMBER' and $value =~ /^\d+$/) {
|
||||
$known_versions{$value} = 1;
|
||||
|
@ -318,7 +285,7 @@ sub extract_constants {
|
|||
|
||||
my %bad_dist = map {$_ => 1} qw/3061601 3120000 3090300 3120100 3180100/;
|
||||
sub versions {
|
||||
my $res = HTTP::Tiny->new->get("https://sqlite.org/changes.html");
|
||||
my $res = HTTP::Tiny->new->get("http://sqlite.org/changes.html");
|
||||
reverse grep {$_->as_num >= 3060100 && !$bad_dist{$_->as_num}} map {s/_/./g; SQLiteUtil::Version->new($_)} $res->{content} =~ /name="version_(3_[\d_]+)"/g;
|
||||
}
|
||||
|
||||
|
@ -478,11 +445,6 @@ sub year {
|
|||
my $self = shift;
|
||||
return "snapshot" if $self->is_snapshot;
|
||||
my $version = $self->as_num;
|
||||
return 2024 if $version >= 3450000;
|
||||
return 2023 if $version >= 3410000;
|
||||
return 2022 if $version >= 3370200;
|
||||
return 2021 if $version >= 3340100;
|
||||
return 2020 if $version >= 3310000;
|
||||
return 2019 if $version >= 3270000;
|
||||
return 2018 if $version >= 3220000;
|
||||
return 2017 if $version >= 3160000;
|
||||
|
|
|
@ -17,14 +17,6 @@ my %shorter_tags = (
|
|||
compile_time_library_version_numbers => 'version',
|
||||
);
|
||||
|
||||
my @dbd_sqlite_constants = (
|
||||
'DBD_SQLITE_STRING_MODE_PV',
|
||||
'DBD_SQLITE_STRING_MODE_BYTES',
|
||||
'DBD_SQLITE_STRING_MODE_UNICODE_NAIVE',
|
||||
'DBD_SQLITE_STRING_MODE_UNICODE_FALLBACK',
|
||||
'DBD_SQLITE_STRING_MODE_UNICODE_STRICT',
|
||||
);
|
||||
|
||||
my %constants = extract_constants();
|
||||
write_inc(%constants);
|
||||
write_pm(%constants);
|
||||
|
@ -42,14 +34,8 @@ MODULE = DBD::SQLite PACKAGE = DBD::SQLite::Constants
|
|||
|
||||
PROTOTYPES: ENABLE
|
||||
|
||||
BOOT:
|
||||
END
|
||||
|
||||
for my $constsub (@dbd_sqlite_constants) {
|
||||
print {$fh} qq< newCONSTSUB( gv_stashpv("DBD::SQLite::Constants", FALSE), "$constsub", newSVuv($constsub) );\n>
|
||||
}
|
||||
print $fh "\n";
|
||||
|
||||
for my $tag (sort grep !/^_/, keys %constants) {
|
||||
_write_tag($fh, $tag, $constants{$tag});
|
||||
}
|
||||
|
@ -158,10 +144,6 @@ use DBD::SQLite;
|
|||
our \@EXPORT_OK = (
|
||||
END
|
||||
|
||||
for my $const (@dbd_sqlite_constants) {
|
||||
print {$fh} " '$const',\n";
|
||||
}
|
||||
|
||||
for my $tag (sort keys %constants) {
|
||||
print $fh <<"END";
|
||||
# $tag
|
||||
|
@ -189,14 +171,11 @@ END
|
|||
|
||||
my %seen;
|
||||
$constants{all} = [sort grep {!$seen{$_}++} map {@$_} values %constants];
|
||||
push @{$constants{all}}, @dbd_sqlite_constants;
|
||||
$constants{dbd_sqlite_string_mode} = [grep /^DBD_SQLITE_STRING_MODE_/, @dbd_sqlite_constants];
|
||||
|
||||
my $sp = ' ' x 6;
|
||||
for my $tag (sort keys %constants) {
|
||||
print $fh <<"END";
|
||||
$tag => [qw/
|
||||
@{[join "\n", map { /^DBD_SQLITE_/ ? "$sp$_" : "${sp}SQLITE_$_"} sort @{$constants{$tag}}]}
|
||||
@{[join "\n", map {" SQLITE_$_"} sort @{$constants{$tag}}]}
|
||||
/],
|
||||
|
||||
END
|
||||
|
@ -247,18 +226,11 @@ END
|
|||
|
||||
END
|
||||
for my $const (@{$constants{$tag}}) {
|
||||
if ($const =~ /^DBD_SQLITE_/) {
|
||||
print $fh <<"END";
|
||||
\=item $const
|
||||
|
||||
END
|
||||
} else {
|
||||
print $fh <<"END";
|
||||
\=item SQLITE_$const
|
||||
|
||||
END
|
||||
}
|
||||
}
|
||||
print $fh <<"END";
|
||||
\=back
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue