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.55_07" have entirely different histories.
147 changed files with 39229 additions and 95240 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
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -18,6 +18,3 @@ foo*
|
||||||
tmp/
|
tmp/
|
||||||
*.pl
|
*.pl
|
||||||
*.old
|
*.old
|
||||||
*.bak
|
|
||||||
*.sqlite
|
|
||||||
.perl-version
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
dist: trusty
|
|
||||||
language: perl
|
language: perl
|
||||||
perl:
|
perl:
|
||||||
# - "5.8.1"
|
# - "5.8.1"
|
||||||
|
|
201
Changes
201
Changes
|
@ -1,206 +1,5 @@
|
||||||
Changes for Perl extension DBD-SQLite
|
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)
|
|
||||||
- Addded new db_config constants, notably to prohibit
|
|
||||||
double-quoted string literals
|
|
||||||
|
|
||||||
1.63_04 2019-05-25
|
|
||||||
- Upgraded SQLite to 3.28.0
|
|
||||||
- Modified doc for sqlite_db_filename which actually returns undef
|
|
||||||
or an empty string (GH#50)
|
|
||||||
- Fixed ->quote($blob, SQL_BLOB) to quote correctly (GH#51, pali++)
|
|
||||||
|
|
||||||
1.63_03 2019-02-15
|
|
||||||
- Applied a patch to fix segmentation fault on 32-bit big-endian
|
|
||||||
platforms by Niko Tyni (GH#45)
|
|
||||||
|
|
||||||
1.63_02 2019-02-14
|
|
||||||
- Upgraded SQLite to 3.27.1
|
|
||||||
- Let a URI filename test skip if SQLite is compiled with URI filename
|
|
||||||
support (GH#47)
|
|
||||||
|
|
||||||
1.63_01 2019-01-26
|
|
||||||
- Made sure an internal hv is initialized (GH#45)
|
|
||||||
- Fixed a number of tests to skip
|
|
||||||
- Bumped up Test::More requirement
|
|
||||||
- Replaced bundled Test::NoWarnings with Test::FailWarnings
|
|
||||||
- Handle 'unknown' op in DBD::SQLite::VirtualTable::PerlData (Corion++)
|
|
||||||
|
|
||||||
1.62 2018-12-29
|
|
||||||
- Switched to a production version
|
|
||||||
|
|
||||||
1.61_04 2018-12-22
|
|
||||||
- Added sqlite_db_config method and new constants for it
|
|
||||||
- Added sqlite_defensive option to disallow dangerous SQLite features
|
|
||||||
- Exposed some of the hidden extended result codes
|
|
||||||
|
|
||||||
1.61_03 2018-12-19
|
|
||||||
- Upgraded SQLite to 3.26.0, which reportedly has a security fix
|
|
||||||
|
|
||||||
1.61_02 2018-12-01
|
|
||||||
- Added sqlite_backup_from_dbh/sqlite_backup_to_dbh methods
|
|
||||||
- Introduced sqlite_prefer_numeric_type database handle attribute
|
|
||||||
that changes the value of TYPE statement handle attribute
|
|
||||||
from an array of string to an array of integer, as an experimental
|
|
||||||
feature. Setting this may break your applications.
|
|
||||||
- Changed preferred bugtracker
|
|
||||||
|
|
||||||
1.61_01 2018-12-01
|
|
||||||
- Added ability to configure SQLITE_MAX_LENGT with environmental
|
|
||||||
variable (Roy Storey)
|
|
||||||
- Added sqlite_limit database handle method to change run-time limits
|
|
||||||
- Upgraded SQLite to 3.25.3
|
|
||||||
- Updated constants
|
|
||||||
|
|
||||||
1.60 2018-12-01
|
|
||||||
- Switched to a production version
|
|
||||||
|
|
||||||
1.59_03 2018-11-03
|
|
||||||
- Added a note on the long standing bug on TYPE statement
|
|
||||||
handle attribute
|
|
||||||
- Applied a doc patch on Virtual::PerlData by Björn Höhrmann
|
|
||||||
(GH-31)
|
|
||||||
|
|
||||||
1.59_02 2018-09-30
|
|
||||||
- Upgraded SQLite to 3.25.2
|
|
||||||
|
|
||||||
1.59_01 2018-09-17
|
|
||||||
- Upgraded SQLite to 3.25.0, with ALTER TABLE ... RENAME COLUMN
|
|
||||||
and UPSERT among others
|
|
||||||
- Added ::GetInfo (GH#32, Brendan Byrd)
|
|
||||||
- Fix to use a PV value as a virtual table column value
|
|
||||||
where appropriate (RT-124941)
|
|
||||||
- Add deferrability to foreign_key_info (mohawk2)
|
|
||||||
|
|
||||||
1.58 2018-03-28
|
|
||||||
- Switched to a production version.
|
|
||||||
|
|
||||||
1.57_01 2018-03-21
|
|
||||||
- Made it an error to fetch attributes from a statement
|
|
||||||
handle whose database handle is inactive (ribasushi++)
|
|
||||||
|
|
||||||
1.56 2018-02-28
|
|
||||||
- Switched to a production version.
|
|
||||||
|
|
||||||
1.55_07 2018-01-27
|
1.55_07 2018-01-27
|
||||||
- This is a developer release to help testing DBIx::Class
|
- This is a developer release to help testing DBIx::Class
|
||||||
- Upgraded SQLite to 3.22.0
|
- Upgraded SQLite to 3.22.0
|
||||||
|
|
10
MANIFEST
10
MANIFEST
|
@ -6,12 +6,12 @@ dbdimp.h
|
||||||
dbdimp_tokenizer.inc
|
dbdimp_tokenizer.inc
|
||||||
dbdimp_virtual_table.inc
|
dbdimp_virtual_table.inc
|
||||||
fts3_tokenizer.h
|
fts3_tokenizer.h
|
||||||
inc/Test/FailWarnings.pm
|
inc/Test/NoWarnings.pm
|
||||||
|
inc/Test/NoWarnings/Warning.pm
|
||||||
lib/DBD/SQLite.pm
|
lib/DBD/SQLite.pm
|
||||||
lib/DBD/SQLite/Constants.pm
|
lib/DBD/SQLite/Constants.pm
|
||||||
lib/DBD/SQLite/Cookbook.pod
|
lib/DBD/SQLite/Cookbook.pod
|
||||||
lib/DBD/SQLite/Fulltext_search.pod
|
lib/DBD/SQLite/Fulltext_search.pod
|
||||||
lib/DBD/SQLite/GetInfo.pm
|
|
||||||
lib/DBD/SQLite/VirtualTable.pm
|
lib/DBD/SQLite/VirtualTable.pm
|
||||||
lib/DBD/SQLite/VirtualTable/FileContent.pm
|
lib/DBD/SQLite/VirtualTable/FileContent.pm
|
||||||
lib/DBD/SQLite/VirtualTable/PerlData.pm
|
lib/DBD/SQLite/VirtualTable/PerlData.pm
|
||||||
|
@ -36,7 +36,6 @@ t/07_error.t
|
||||||
t/08_busy.t
|
t/08_busy.t
|
||||||
t/09_create_function.t
|
t/09_create_function.t
|
||||||
t/10_create_aggregate.t
|
t/10_create_aggregate.t
|
||||||
t/11_get_info.t
|
|
||||||
t/12_unicode.t
|
t/12_unicode.t
|
||||||
t/13_create_collation.t
|
t/13_create_collation.t
|
||||||
t/14_progress_handler.t
|
t/14_progress_handler.t
|
||||||
|
@ -88,9 +87,6 @@ t/60_readonly.t
|
||||||
t/61_strlike.t
|
t/61_strlike.t
|
||||||
t/62_regexp_multibyte_char_class.t
|
t/62_regexp_multibyte_char_class.t
|
||||||
t/63_param_values.t
|
t/63_param_values.t
|
||||||
t/64_limit.t
|
|
||||||
t/65_db_config.t
|
|
||||||
t/66_get_autocommit.t
|
|
||||||
t/cookbook_variance.t
|
t/cookbook_variance.t
|
||||||
t/lib/SQLiteTest.pm
|
t/lib/SQLiteTest.pm
|
||||||
t/rt_106151_outermost_savepoint.t
|
t/rt_106151_outermost_savepoint.t
|
||||||
|
@ -137,9 +133,7 @@ t/virtual_table/10_filecontent.t
|
||||||
t/virtual_table/11_filecontent_fulltext.t
|
t/virtual_table/11_filecontent_fulltext.t
|
||||||
t/virtual_table/20_perldata.t
|
t/virtual_table/20_perldata.t
|
||||||
t/virtual_table/21_perldata_charinfo.t
|
t/virtual_table/21_perldata_charinfo.t
|
||||||
t/virtual_table/rt_124941.t
|
|
||||||
t/virtual_table/rt_99748.t
|
t/virtual_table/rt_99748.t
|
||||||
t/virtual_table/unknown_op.t
|
|
||||||
typemap
|
typemap
|
||||||
xt/cpp_comments.t
|
xt/cpp_comments.t
|
||||||
xt/meta.t
|
xt/meta.t
|
||||||
|
|
|
@ -12,7 +12,6 @@ CVS/.*
|
||||||
\.xsi$
|
\.xsi$
|
||||||
\.bs$
|
\.bs$
|
||||||
\.el$
|
\.el$
|
||||||
\.pl$
|
|
||||||
^.#
|
^.#
|
||||||
^mess/
|
^mess/
|
||||||
^sqlite/
|
^sqlite/
|
||||||
|
|
32
Makefile.PL
32
Makefile.PL
|
@ -236,7 +236,6 @@ my @CC_DEFINE = (
|
||||||
# '-DSQLITE_ENABLE_STAT4', # for sqlite >= 3.8.3.1
|
# '-DSQLITE_ENABLE_STAT4', # for sqlite >= 3.8.3.1
|
||||||
'-DSQLITE_ENABLE_JSON1', # for sqlite >= 3.9.0
|
'-DSQLITE_ENABLE_JSON1', # for sqlite >= 3.9.0
|
||||||
'-DSQLITE_ENABLE_FTS5', # for sqlite >= 3.9.0
|
'-DSQLITE_ENABLE_FTS5', # for sqlite >= 3.9.0
|
||||||
'-DSQLITE_ENABLE_MATH_FUNCTIONS', # for sqlite >= 3.35.0
|
|
||||||
'-DNDEBUG=1',
|
'-DNDEBUG=1',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -245,11 +244,6 @@ if ($ENV{SQLITE_ENABLE_FTS3_TOKENIZER}) {
|
||||||
push @CC_DEFINE, '-DSQLITE_ENABLE_FTS3_TOKENIZER'; # for sqlite >= 3.11.0
|
push @CC_DEFINE, '-DSQLITE_ENABLE_FTS3_TOKENIZER'; # for sqlite >= 3.11.0
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($ENV{SQLITE_MAX_LENGTH} && $ENV{SQLITE_MAX_LENGTH} =~ m/^[0-9]+$/) {
|
|
||||||
push @CC_DEFINE, join '=', '-DSQLITE_MAX_LENGTH', $ENV{SQLITE_MAX_LENGTH}
|
|
||||||
if $ENV{SQLITE_MAX_LENGTH} >= 100 && $ENV{SQLITE_MAX_LENGTH} <= ((2**31)-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DEVELOPER_ONLY) {
|
if (DEVELOPER_ONLY) {
|
||||||
# for sqlite >= 3.8.8
|
# for sqlite >= 3.8.8
|
||||||
push @CC_DEFINE, '-DSQLITE_ENABLE_API_ARMOR';
|
push @CC_DEFINE, '-DSQLITE_ENABLE_API_ARMOR';
|
||||||
|
@ -262,7 +256,7 @@ if ( $^O eq 'cygwin') {
|
||||||
if ( $Config{d_usleep} || $Config{osname} =~ m/linux/ ) {
|
if ( $Config{d_usleep} || $Config{osname} =~ m/linux/ ) {
|
||||||
push @CC_DEFINE, '-DHAVE_USLEEP=1';
|
push @CC_DEFINE, '-DHAVE_USLEEP=1';
|
||||||
}
|
}
|
||||||
if ( !$Config{usethreads} and $Config{libs} !~ /pthread/ ) {
|
unless ( $Config{usethreads} ) {
|
||||||
push @CC_DEFINE, '-DTHREADSAFE=0';
|
push @CC_DEFINE, '-DTHREADSAFE=0';
|
||||||
}
|
}
|
||||||
if ($^O eq 'hpux' and $Config{osvers} <= 10.20) {
|
if ($^O eq 'hpux' and $Config{osvers} <= 10.20) {
|
||||||
|
@ -288,18 +282,8 @@ if ($^O =~ /bsd/i && $^O !~ /(?:open|net)bsd/) {
|
||||||
push @CC_DEFINE, '-D_XOPEN_SOURCE';
|
push @CC_DEFINE, '-D_XOPEN_SOURCE';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$Config{usedl}) {
|
|
||||||
push @CC_DEFINE, '-DSQLITE_OMIT_LOAD_EXTENSION';
|
|
||||||
}
|
|
||||||
|
|
||||||
my (@CCFLAGS, @LDFLAGS, @LDDLFLAGS);
|
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;
|
# RT #70135: See if ld supports Bsymbolic;
|
||||||
unless ($^O eq 'MSWin32' && $Config{ld} =~ /link/) {
|
unless ($^O eq 'MSWin32' && $Config{ld} =~ /link/) {
|
||||||
for my $path (File::Spec->path) {
|
for my $path (File::Spec->path) {
|
||||||
|
@ -346,7 +330,8 @@ WriteMakefile(
|
||||||
'Tie::Hash' => 0,
|
'Tie::Hash' => 0,
|
||||||
'File::Spec' => (WINLIKE ? '3.27' : '0.82'),
|
'File::Spec' => (WINLIKE ? '3.27' : '0.82'),
|
||||||
'DBI' => $DBI_required,
|
'DBI' => $DBI_required,
|
||||||
'Test::More' => '0.88', # done_testing
|
'Test::More' => '0.47', # Test::NoWarnings
|
||||||
|
'Test::Builder' => '0.86', # Test::NoWarnings
|
||||||
( WINLIKE ? (
|
( WINLIKE ? (
|
||||||
'Win32' => '0.30',
|
'Win32' => '0.30',
|
||||||
) : () ),
|
) : () ),
|
||||||
|
@ -377,7 +362,9 @@ WriteMakefile(
|
||||||
},
|
},
|
||||||
build_requires => {
|
build_requires => {
|
||||||
'File::Spec' => (WINLIKE ? '3.27' : '0.82'),
|
'File::Spec' => (WINLIKE ? '3.27' : '0.82'),
|
||||||
'Test::More' => '0.88',
|
'Test::More' => '0.42',
|
||||||
|
# Bundled in /inc
|
||||||
|
# 'Test::NoWarnings' => '0.081',
|
||||||
},
|
},
|
||||||
requires => {
|
requires => {
|
||||||
'Tie::Hash' => 0,
|
'Tie::Hash' => 0,
|
||||||
|
@ -389,7 +376,7 @@ WriteMakefile(
|
||||||
},
|
},
|
||||||
resources => {
|
resources => {
|
||||||
license => 'http://dev.perl.org/licenses/',
|
license => 'http://dev.perl.org/licenses/',
|
||||||
bugtracker => 'https://github.com/DBD-SQLite/DBD-SQLite/issues',
|
bugtracker => 'http://rt.cpan.org/Public/Dist/Display.html?Name=DBD-SQLite',
|
||||||
repository => 'https://github.com/DBD-SQLite/DBD-SQLite',
|
repository => 'https://github.com/DBD-SQLite/DBD-SQLite',
|
||||||
MailingList => 'http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbd-sqlite',
|
MailingList => 'http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbd-sqlite',
|
||||||
},
|
},
|
||||||
|
@ -404,14 +391,11 @@ WriteMakefile(
|
||||||
? '$(O_FILES)'
|
? '$(O_FILES)'
|
||||||
: 'SQLite.o dbdimp.o'
|
: 'SQLite.o dbdimp.o'
|
||||||
),
|
),
|
||||||
depend => {
|
|
||||||
'dbdimp.o' => 'dbdimp_tokenizer.inc dbdimp_virtual_table.inc',
|
|
||||||
},
|
|
||||||
clean => {
|
clean => {
|
||||||
FILES => 'SQLite.xsi config.h tv.log *.old',
|
FILES => 'SQLite.xsi config.h tv.log *.old',
|
||||||
},
|
},
|
||||||
test => {
|
test => {
|
||||||
TESTS => 't/*.t t/*/*.t',
|
TESTS => 't/*.t t/**/*.t',
|
||||||
},
|
},
|
||||||
PL_FILES => {},
|
PL_FILES => {},
|
||||||
EXE_FILES => [],
|
EXE_FILES => [],
|
||||||
|
|
90
SQLite.xs
90
SQLite.xs
|
@ -259,28 +259,6 @@ backup_to_file(dbh, filename)
|
||||||
OUTPUT:
|
OUTPUT:
|
||||||
RETVAL
|
RETVAL
|
||||||
|
|
||||||
static int
|
|
||||||
backup_from_dbh(dbh, from)
|
|
||||||
SV *dbh
|
|
||||||
SV *from
|
|
||||||
ALIAS:
|
|
||||||
DBD::SQLite::db::sqlite_backup_from_dbh = 1
|
|
||||||
CODE:
|
|
||||||
RETVAL = sqlite_db_backup_from_dbh(aTHX_ dbh, from);
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
static int
|
|
||||||
backup_to_dbh(dbh, to)
|
|
||||||
SV *dbh
|
|
||||||
SV *to
|
|
||||||
ALIAS:
|
|
||||||
DBD::SQLite::db::sqlite_backup_to_dbh = 1
|
|
||||||
CODE:
|
|
||||||
RETVAL = sqlite_db_backup_to_dbh(aTHX_ dbh, to);
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
HV*
|
HV*
|
||||||
table_column_metadata(dbh, dbname, tablename, columnname)
|
table_column_metadata(dbh, dbname, tablename, columnname)
|
||||||
SV* dbh
|
SV* dbh
|
||||||
|
@ -340,74 +318,6 @@ create_module(dbh, name, perl_class)
|
||||||
OUTPUT:
|
OUTPUT:
|
||||||
RETVAL
|
RETVAL
|
||||||
|
|
||||||
static int
|
|
||||||
limit(dbh, id, new_value = -1)
|
|
||||||
SV *dbh
|
|
||||||
int id
|
|
||||||
int new_value
|
|
||||||
ALIAS:
|
|
||||||
DBD::SQLite::db::sqlite_limit = 1
|
|
||||||
CODE:
|
|
||||||
{
|
|
||||||
RETVAL = sqlite_db_limit(aTHX_ dbh, id, new_value);
|
|
||||||
}
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
static int
|
|
||||||
db_config(dbh, id, new_value = -1)
|
|
||||||
SV *dbh
|
|
||||||
int id
|
|
||||||
int new_value
|
|
||||||
ALIAS:
|
|
||||||
DBD::SQLite::db::sqlite_db_config = 1
|
|
||||||
CODE:
|
|
||||||
{
|
|
||||||
RETVAL = sqlite_db_config(aTHX_ dbh, id, new_value);
|
|
||||||
}
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
static int
|
|
||||||
get_autocommit(dbh)
|
|
||||||
SV *dbh
|
|
||||||
ALIAS:
|
|
||||||
DBD::SQLite::db::sqlite_get_autocommit = 1
|
|
||||||
CODE:
|
|
||||||
{
|
|
||||||
RETVAL = sqlite_db_get_autocommit(aTHX_ 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
|
MODULE = DBD::SQLite PACKAGE = DBD::SQLite::st
|
||||||
|
|
||||||
|
|
926
constants.inc
926
constants.inc
|
@ -5,41 +5,6 @@ MODULE = DBD::SQLite PACKAGE = DBD::SQLite::Constants
|
||||||
|
|
||||||
PROTOTYPES: ENABLE
|
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
|
IV
|
||||||
_const_authorizer_action_codes()
|
_const_authorizer_action_codes()
|
||||||
ALIAS:
|
ALIAS:
|
||||||
|
@ -147,378 +112,6 @@ _const_compile_time_library_version_numbers()
|
||||||
OUTPUT:
|
OUTPUT:
|
||||||
RETVAL
|
RETVAL
|
||||||
|
|
||||||
#if SQLITE_VERSION_NUMBER >= 3007000
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_database_connection_configuration_options_3007000()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_DBCONFIG_LOOKASIDE = SQLITE_DBCONFIG_LOOKASIDE
|
|
||||||
CODE:
|
|
||||||
RETVAL = ix;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_database_connection_configuration_options_3007000_zero()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_DBCONFIG_LOOKASIDE = 1
|
|
||||||
CODE:
|
|
||||||
RETVAL = 0;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SQLITE_VERSION_NUMBER >= 3007006
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_database_connection_configuration_options_3007006()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_DBCONFIG_ENABLE_FKEY = SQLITE_DBCONFIG_ENABLE_FKEY
|
|
||||||
SQLITE_DBCONFIG_ENABLE_TRIGGER = SQLITE_DBCONFIG_ENABLE_TRIGGER
|
|
||||||
CODE:
|
|
||||||
RETVAL = ix;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_database_connection_configuration_options_3007006_zero()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_DBCONFIG_ENABLE_FKEY = 1
|
|
||||||
SQLITE_DBCONFIG_ENABLE_TRIGGER = 2
|
|
||||||
CODE:
|
|
||||||
RETVAL = 0;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SQLITE_VERSION_NUMBER >= 3012002
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_database_connection_configuration_options_3012002()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER = SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
|
|
||||||
CODE:
|
|
||||||
RETVAL = ix;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_database_connection_configuration_options_3012002_zero()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER = 1
|
|
||||||
CODE:
|
|
||||||
RETVAL = 0;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SQLITE_VERSION_NUMBER >= 3013000
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_database_connection_configuration_options_3013000()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION = SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION
|
|
||||||
CODE:
|
|
||||||
RETVAL = ix;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_database_connection_configuration_options_3013000_zero()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION = 1
|
|
||||||
CODE:
|
|
||||||
RETVAL = 0;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SQLITE_VERSION_NUMBER >= 3015000
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_database_connection_configuration_options_3015000()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_DBCONFIG_MAINDBNAME = SQLITE_DBCONFIG_MAINDBNAME
|
|
||||||
CODE:
|
|
||||||
RETVAL = ix;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_database_connection_configuration_options_3015000_zero()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_DBCONFIG_MAINDBNAME = 1
|
|
||||||
CODE:
|
|
||||||
RETVAL = 0;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SQLITE_VERSION_NUMBER >= 3016000
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_database_connection_configuration_options_3016000()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE = SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE
|
|
||||||
CODE:
|
|
||||||
RETVAL = ix;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_database_connection_configuration_options_3016000_zero()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE = 1
|
|
||||||
CODE:
|
|
||||||
RETVAL = 0;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SQLITE_VERSION_NUMBER >= 3020000
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_database_connection_configuration_options_3020000()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_DBCONFIG_ENABLE_QPSG = SQLITE_DBCONFIG_ENABLE_QPSG
|
|
||||||
CODE:
|
|
||||||
RETVAL = ix;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_database_connection_configuration_options_3020000_zero()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_DBCONFIG_ENABLE_QPSG = 1
|
|
||||||
CODE:
|
|
||||||
RETVAL = 0;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SQLITE_VERSION_NUMBER >= 3022000
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_database_connection_configuration_options_3022000()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_DBCONFIG_TRIGGER_EQP = SQLITE_DBCONFIG_TRIGGER_EQP
|
|
||||||
SQLITE_DBCONFIG_MAX = SQLITE_DBCONFIG_MAX
|
|
||||||
CODE:
|
|
||||||
RETVAL = ix;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_database_connection_configuration_options_3022000_zero()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_DBCONFIG_TRIGGER_EQP = 1
|
|
||||||
SQLITE_DBCONFIG_MAX = 2
|
|
||||||
CODE:
|
|
||||||
RETVAL = 0;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SQLITE_VERSION_NUMBER >= 3024000
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_database_connection_configuration_options_3024000()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_DBCONFIG_RESET_DATABASE = SQLITE_DBCONFIG_RESET_DATABASE
|
|
||||||
CODE:
|
|
||||||
RETVAL = ix;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_database_connection_configuration_options_3024000_zero()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_DBCONFIG_RESET_DATABASE = 1
|
|
||||||
CODE:
|
|
||||||
RETVAL = 0;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SQLITE_VERSION_NUMBER >= 3026000
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_database_connection_configuration_options_3026000()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_DBCONFIG_DEFENSIVE = SQLITE_DBCONFIG_DEFENSIVE
|
|
||||||
CODE:
|
|
||||||
RETVAL = ix;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_database_connection_configuration_options_3026000_zero()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_DBCONFIG_DEFENSIVE = 1
|
|
||||||
CODE:
|
|
||||||
RETVAL = 0;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SQLITE_VERSION_NUMBER >= 3028000
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_database_connection_configuration_options_3028000()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_DBCONFIG_WRITABLE_SCHEMA = SQLITE_DBCONFIG_WRITABLE_SCHEMA
|
|
||||||
CODE:
|
|
||||||
RETVAL = ix;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_database_connection_configuration_options_3028000_zero()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_DBCONFIG_WRITABLE_SCHEMA = 1
|
|
||||||
CODE:
|
|
||||||
RETVAL = 0;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SQLITE_VERSION_NUMBER >= 3029000
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_database_connection_configuration_options_3029000()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_DBCONFIG_LEGACY_ALTER_TABLE = SQLITE_DBCONFIG_LEGACY_ALTER_TABLE
|
|
||||||
SQLITE_DBCONFIG_DQS_DML = SQLITE_DBCONFIG_DQS_DML
|
|
||||||
SQLITE_DBCONFIG_DQS_DDL = SQLITE_DBCONFIG_DQS_DDL
|
|
||||||
CODE:
|
|
||||||
RETVAL = ix;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_database_connection_configuration_options_3029000_zero()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_DBCONFIG_LEGACY_ALTER_TABLE = 1
|
|
||||||
SQLITE_DBCONFIG_DQS_DML = 2
|
|
||||||
SQLITE_DBCONFIG_DQS_DDL = 3
|
|
||||||
CODE:
|
|
||||||
RETVAL = 0;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#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
|
#if SQLITE_VERSION_NUMBER >= 3006002
|
||||||
|
|
||||||
IV
|
IV
|
||||||
|
@ -1053,240 +646,6 @@ _const_extended_result_codes_3021000_zero()
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SQLITE_VERSION_NUMBER >= 3022000
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_extended_result_codes_3022000()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_ERROR_MISSING_COLLSEQ = SQLITE_ERROR_MISSING_COLLSEQ
|
|
||||||
SQLITE_ERROR_RETRY = SQLITE_ERROR_RETRY
|
|
||||||
SQLITE_READONLY_CANTINIT = SQLITE_READONLY_CANTINIT
|
|
||||||
SQLITE_READONLY_DIRECTORY = SQLITE_READONLY_DIRECTORY
|
|
||||||
CODE:
|
|
||||||
RETVAL = ix;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_extended_result_codes_3022000_zero()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_ERROR_MISSING_COLLSEQ = 1
|
|
||||||
SQLITE_ERROR_RETRY = 2
|
|
||||||
SQLITE_READONLY_CANTINIT = 3
|
|
||||||
SQLITE_READONLY_DIRECTORY = 4
|
|
||||||
CODE:
|
|
||||||
RETVAL = 0;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SQLITE_VERSION_NUMBER >= 3024000
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_extended_result_codes_3024000()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_LOCKED_VTAB = SQLITE_LOCKED_VTAB
|
|
||||||
SQLITE_CORRUPT_SEQUENCE = SQLITE_CORRUPT_SEQUENCE
|
|
||||||
CODE:
|
|
||||||
RETVAL = ix;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_extended_result_codes_3024000_zero()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_LOCKED_VTAB = 1
|
|
||||||
SQLITE_CORRUPT_SEQUENCE = 2
|
|
||||||
CODE:
|
|
||||||
RETVAL = 0;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SQLITE_VERSION_NUMBER >= 3025000
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_extended_result_codes_3025000()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_ERROR_SNAPSHOT = SQLITE_ERROR_SNAPSHOT
|
|
||||||
SQLITE_CANTOPEN_DIRTYWAL = SQLITE_CANTOPEN_DIRTYWAL
|
|
||||||
CODE:
|
|
||||||
RETVAL = ix;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_extended_result_codes_3025000_zero()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_ERROR_SNAPSHOT = 1
|
|
||||||
SQLITE_CANTOPEN_DIRTYWAL = 2
|
|
||||||
CODE:
|
|
||||||
RETVAL = 0;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#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
|
IV
|
||||||
_const_flags_for_file_open_operations()
|
_const_flags_for_file_open_operations()
|
||||||
ALIAS:
|
ALIAS:
|
||||||
|
@ -1397,78 +756,6 @@ _const_flags_for_file_open_operations_3007013_zero()
|
||||||
|
|
||||||
#endif
|
#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
|
#if SQLITE_VERSION_NUMBER >= 3008003
|
||||||
|
|
||||||
IV
|
IV
|
||||||
|
@ -1493,80 +780,6 @@ _const_function_flags_3008003_zero()
|
||||||
|
|
||||||
#endif
|
#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
|
IV
|
||||||
_const_fundamental_datatypes()
|
_const_fundamental_datatypes()
|
||||||
ALIAS:
|
ALIAS:
|
||||||
|
@ -1574,7 +787,6 @@ _const_fundamental_datatypes()
|
||||||
SQLITE_FLOAT = SQLITE_FLOAT
|
SQLITE_FLOAT = SQLITE_FLOAT
|
||||||
SQLITE_BLOB = SQLITE_BLOB
|
SQLITE_BLOB = SQLITE_BLOB
|
||||||
SQLITE_NULL = SQLITE_NULL
|
SQLITE_NULL = SQLITE_NULL
|
||||||
SQLITE_TEXT = SQLITE_TEXT
|
|
||||||
CODE:
|
CODE:
|
||||||
RETVAL = ix;
|
RETVAL = ix;
|
||||||
OUTPUT:
|
OUTPUT:
|
||||||
|
@ -1643,72 +855,6 @@ _const_result_codes_3007017_zero()
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
IV
|
|
||||||
_const_run_time_limit_categories()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_LIMIT_LENGTH = SQLITE_LIMIT_LENGTH
|
|
||||||
SQLITE_LIMIT_SQL_LENGTH = SQLITE_LIMIT_SQL_LENGTH
|
|
||||||
SQLITE_LIMIT_COLUMN = SQLITE_LIMIT_COLUMN
|
|
||||||
SQLITE_LIMIT_EXPR_DEPTH = SQLITE_LIMIT_EXPR_DEPTH
|
|
||||||
SQLITE_LIMIT_COMPOUND_SELECT = SQLITE_LIMIT_COMPOUND_SELECT
|
|
||||||
SQLITE_LIMIT_VDBE_OP = SQLITE_LIMIT_VDBE_OP
|
|
||||||
SQLITE_LIMIT_FUNCTION_ARG = SQLITE_LIMIT_FUNCTION_ARG
|
|
||||||
SQLITE_LIMIT_ATTACHED = SQLITE_LIMIT_ATTACHED
|
|
||||||
SQLITE_LIMIT_LIKE_PATTERN_LENGTH = SQLITE_LIMIT_LIKE_PATTERN_LENGTH
|
|
||||||
SQLITE_LIMIT_VARIABLE_NUMBER = SQLITE_LIMIT_VARIABLE_NUMBER
|
|
||||||
CODE:
|
|
||||||
RETVAL = ix;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#if SQLITE_VERSION_NUMBER >= 3006018
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_run_time_limit_categories_3006018()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_LIMIT_TRIGGER_DEPTH = SQLITE_LIMIT_TRIGGER_DEPTH
|
|
||||||
CODE:
|
|
||||||
RETVAL = ix;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_run_time_limit_categories_3006018_zero()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_LIMIT_TRIGGER_DEPTH = 1
|
|
||||||
CODE:
|
|
||||||
RETVAL = 0;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SQLITE_VERSION_NUMBER >= 3008007
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_run_time_limit_categories_3008007()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_LIMIT_WORKER_THREADS = SQLITE_LIMIT_WORKER_THREADS
|
|
||||||
CODE:
|
|
||||||
RETVAL = ix;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
IV
|
|
||||||
_const_run_time_limit_categories_3008007_zero()
|
|
||||||
ALIAS:
|
|
||||||
SQLITE_LIMIT_WORKER_THREADS = 1
|
|
||||||
CODE:
|
|
||||||
RETVAL = 0;
|
|
||||||
OUTPUT:
|
|
||||||
RETVAL
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
# For backward compatibility
|
# For backward compatibility
|
||||||
|
|
||||||
MODULE = DBD::SQLite PACKAGE = DBD::SQLite
|
MODULE = DBD::SQLite PACKAGE = DBD::SQLite
|
||||||
|
@ -1924,75 +1070,3 @@ _const__flags_for_file_open_operations_3007013_zero()
|
||||||
|
|
||||||
#endif
|
#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';
|
|
||||||
};
|
|
569
dbdimp.c
569
dbdimp.c
|
@ -214,7 +214,6 @@ sqlite_type_from_odbc_type(int type)
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case SQL_UNKNOWN_TYPE:
|
case SQL_UNKNOWN_TYPE:
|
||||||
return SQLITE_NULL;
|
return SQLITE_NULL;
|
||||||
case SQL_BOOLEAN:
|
|
||||||
case SQL_INTEGER:
|
case SQL_INTEGER:
|
||||||
case SQL_SMALLINT:
|
case SQL_SMALLINT:
|
||||||
case SQL_TINYINT:
|
case SQL_TINYINT:
|
||||||
|
@ -224,11 +223,7 @@ sqlite_type_from_odbc_type(int type)
|
||||||
case SQL_REAL:
|
case SQL_REAL:
|
||||||
case SQL_DOUBLE:
|
case SQL_DOUBLE:
|
||||||
return SQLITE_FLOAT;
|
return SQLITE_FLOAT;
|
||||||
case SQL_BIT:
|
|
||||||
case SQL_BLOB:
|
case SQL_BLOB:
|
||||||
case SQL_BINARY:
|
|
||||||
case SQL_VARBINARY:
|
|
||||||
case SQL_LONGVARBINARY:
|
|
||||||
return SQLITE_BLOB;
|
return SQLITE_BLOB;
|
||||||
default:
|
default:
|
||||||
return SQLITE_TEXT;
|
return SQLITE_TEXT;
|
||||||
|
@ -239,11 +234,11 @@ void
|
||||||
init_cxt() {
|
init_cxt() {
|
||||||
dTHX;
|
dTHX;
|
||||||
MY_CXT_INIT;
|
MY_CXT_INIT;
|
||||||
MY_CXT.last_dbh_string_mode = DBD_SQLITE_STRING_MODE_PV;
|
MY_CXT.last_dbh_is_unicode = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SV *
|
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;
|
STRLEN len;
|
||||||
sqlite_int64 iv;
|
sqlite_int64 iv;
|
||||||
|
@ -271,7 +266,9 @@ stacked_sv_from_sqlite3_value(pTHX_ sqlite3_value *value, dbd_sqlite_string_mode
|
||||||
case SQLITE_TEXT:
|
case SQLITE_TEXT:
|
||||||
len = sqlite3_value_bytes(value);
|
len = sqlite3_value_bytes(value);
|
||||||
sv = newSVpvn((const char *)sqlite3_value_text(value), len);
|
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);
|
return sv_2mortal(sv);
|
||||||
case SQLITE_BLOB:
|
case SQLITE_BLOB:
|
||||||
len = sqlite3_value_bytes(value);
|
len = sqlite3_value_bytes(value);
|
||||||
|
@ -292,9 +289,6 @@ sqlite_set_result(pTHX_ sqlite3_context *context, SV *result, int is_error)
|
||||||
STRLEN len;
|
STRLEN len;
|
||||||
char *s;
|
char *s;
|
||||||
sqlite3_int64 iv;
|
sqlite3_int64 iv;
|
||||||
AV *av;
|
|
||||||
SV *result2, *type;
|
|
||||||
SV **presult2, **ptype;
|
|
||||||
|
|
||||||
if ( is_error ) {
|
if ( is_error ) {
|
||||||
s = SvPV(result, len);
|
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)); */
|
/* warn("result: %s\n", SvPV_nolen(result)); */
|
||||||
if ( !SvOK(result) ) {
|
if ( !SvOK(result) ) {
|
||||||
sqlite3_result_null( context );
|
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) ) {
|
} else if( SvIOK_UV(result) ) {
|
||||||
if ((UV)(sqlite3_int64)UV_MAX == UV_MAX)
|
if ((UV)(sqlite3_int64)UV_MAX == UV_MAX)
|
||||||
sqlite3_result_int64( context, (sqlite3_int64)SvUV(result));
|
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 (!_sqlite_atoi64(v, &iv)) return 1;
|
||||||
}
|
}
|
||||||
if (sql_type != SQLITE_INTEGER) {
|
if (sql_type != SQLITE_INTEGER) {
|
||||||
#ifdef USE_QUADMATH
|
sprintf(format, (has_plus ? "+%%.%df" : "%%.%df"), precision);
|
||||||
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
|
|
||||||
if (strEQ(form(format, atof(v)), v)) return 2;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -439,54 +396,16 @@ sqlite_discon_all(SV *drh, imp_drh_t *imp_drh)
|
||||||
return FALSE; /* no way to do this */
|
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
|
int
|
||||||
sqlite_db_login6(SV *dbh, imp_dbh_t *imp_dbh, char *dbname, char *user, char *pass, SV *attr)
|
sqlite_db_login6(SV *dbh, imp_dbh_t *imp_dbh, char *dbname, char *user, char *pass, SV *attr)
|
||||||
{
|
{
|
||||||
dTHX;
|
dTHX;
|
||||||
int rc;
|
int rc;
|
||||||
HV *hv = NULL;
|
HV *hv;
|
||||||
SV **val;
|
SV **val;
|
||||||
int extended = 0;
|
int extended = 0;
|
||||||
int flag = 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));
|
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));
|
hv_stores(hv, "ReadOnly", newSViv(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* sqlite_unicode should be detected earlier, to register default functions correctly */
|
||||||
/* sqlite_string_mode should be detected earlier, to register default functions correctly */
|
if (hv_exists(hv, "sqlite_unicode", 14)) {
|
||||||
|
|
||||||
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)) {
|
|
||||||
val = hv_fetch(hv, "sqlite_unicode", 14, 0);
|
val = hv_fetch(hv, "sqlite_unicode", 14, 0);
|
||||||
if ( (val && SvOK(*val)) ? SvIV(*val) : 0 ) {
|
unicode = (val && SvOK(*val)) ? SvIV(*val) : 0;
|
||||||
string_mode = DBD_SQLITE_STRING_MODE_UNICODE_NAIVE;
|
|
||||||
}
|
|
||||||
} else if (hv_exists(hv, "unicode", 7)) {
|
} else if (hv_exists(hv, "unicode", 7)) {
|
||||||
val = hv_fetch(hv, "unicode", 7, 0);
|
val = hv_fetch(hv, "unicode", 7, 0);
|
||||||
if ( (val && SvOK(*val)) ? SvIV(*val) : 0 ) {
|
unicode = (val && SvOK(*val)) ? SvIV(*val) : 0;
|
||||||
string_mode = DBD_SQLITE_STRING_MODE_UNICODE_NAIVE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rc = sqlite_open2(dbname, &(imp_dbh->db), flag, extended);
|
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);
|
DBIc_IMPSET_on(imp_dbh);
|
||||||
|
|
||||||
imp_dbh->string_mode = string_mode;
|
imp_dbh->unicode = unicode;
|
||||||
imp_dbh->functions = newAV();
|
imp_dbh->functions = newAV();
|
||||||
imp_dbh->aggregates = newAV();
|
imp_dbh->aggregates = newAV();
|
||||||
imp_dbh->collation_needed_callback = newSVsv( &PL_sv_undef );
|
imp_dbh->collation_needed_callback = newSVsv( &PL_sv_undef );
|
||||||
|
@ -547,20 +455,9 @@ sqlite_db_login6(SV *dbh, imp_dbh_t *imp_dbh, char *dbname, char *user, char *pa
|
||||||
imp_dbh->extended_result_codes = extended;
|
imp_dbh->extended_result_codes = extended;
|
||||||
imp_dbh->stmt_list = NULL;
|
imp_dbh->stmt_list = NULL;
|
||||||
imp_dbh->began_transaction = FALSE;
|
imp_dbh->began_transaction = FALSE;
|
||||||
imp_dbh->prefer_numeric_type = FALSE;
|
|
||||||
|
|
||||||
sqlite3_busy_timeout(imp_dbh->db, SQL_TIMEOUT);
|
sqlite3_busy_timeout(imp_dbh->db, SQL_TIMEOUT);
|
||||||
|
|
||||||
if (SvROK(attr)) {
|
|
||||||
hv = (HV*)SvRV(attr);
|
|
||||||
if (hv_exists(hv, "sqlite_defensive", 16)) {
|
|
||||||
val = hv_fetch(hv, "sqlite_defensive", 16, 0);
|
|
||||||
if (val && SvIOK(*val)) {
|
|
||||||
sqlite3_db_config(imp_dbh->db, SQLITE_DBCONFIG_DEFENSIVE, (int)SvIV(*val), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/*
|
/*
|
||||||
** As of 1.26_06 foreign keys support was enabled by default,
|
** As of 1.26_06 foreign keys support was enabled by default,
|
||||||
|
@ -603,7 +500,9 @@ sqlite_db_do_sv(SV *dbh, imp_dbh_t *imp_dbh, SV *sv_statement)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sqlite3_prepare wants an utf8-encoded SQL 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);
|
statement = SvPV_nolen(sv_statement);
|
||||||
|
|
||||||
|
@ -790,10 +689,6 @@ sqlite_db_destroy(SV *dbh, imp_dbh_t *imp_dbh)
|
||||||
DBIc_IMPSET_off(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
|
int
|
||||||
sqlite_db_STORE_attrib(SV *dbh, imp_dbh_t *imp_dbh, SV *keysv, SV *valuesv)
|
sqlite_db_STORE_attrib(SV *dbh, imp_dbh_t *imp_dbh, SV *keysv, SV *valuesv)
|
||||||
{
|
{
|
||||||
|
@ -842,48 +737,26 @@ sqlite_db_STORE_attrib(SV *dbh, imp_dbh_t *imp_dbh, SV *keysv, SV *valuesv)
|
||||||
sqlite3_extended_result_codes(imp_dbh->db, imp_dbh->extended_result_codes);
|
sqlite3_extended_result_codes(imp_dbh->db, imp_dbh->extended_result_codes);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
if (strEQ(key, "sqlite_prefer_numeric_type")) {
|
|
||||||
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")) {
|
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
|
#if PERL_UNICODE_DOES_NOT_WORK_WELL
|
||||||
sqlite_trace(dbh, imp_dbh, 3, form("Unicode support is disabled for this version of perl."));
|
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
|
#else
|
||||||
imp_dbh->string_mode = SvTRUE(valuesv) ? DBD_SQLITE_STRING_MODE_UNICODE_NAIVE : DBD_SQLITE_STRING_MODE_PV;
|
imp_dbh->unicode = !(! SvTRUE(valuesv));
|
||||||
#endif
|
#endif
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strEQ(key, "unicode")) {
|
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
|
#if PERL_UNICODE_DOES_NOT_WORK_WELL
|
||||||
sqlite_trace(dbh, imp_dbh, 3, form("Unicode support is disabled for this version of perl."));
|
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
|
#else
|
||||||
imp_dbh->string_mode = SvTRUE(valuesv) ? DBD_SQLITE_STRING_MODE_UNICODE_NAIVE : DBD_SQLITE_STRING_MODE_PV;
|
imp_dbh->unicode = !(! SvTRUE(valuesv));
|
||||||
#endif
|
#endif
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -908,21 +781,22 @@ sqlite_db_FETCH_attrib(SV *dbh, imp_dbh_t *imp_dbh, SV *keysv)
|
||||||
if (strEQ(key, "sqlite_extended_result_codes")) {
|
if (strEQ(key, "sqlite_extended_result_codes")) {
|
||||||
return sv_2mortal(newSViv(imp_dbh->extended_result_codes ? 1 : 0));
|
return sv_2mortal(newSViv(imp_dbh->extended_result_codes ? 1 : 0));
|
||||||
}
|
}
|
||||||
if (strEQ(key, "sqlite_prefer_numeric_type")) {
|
if (strEQ(key, "sqlite_unicode")) {
|
||||||
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 PERL_UNICODE_DOES_NOT_WORK_WELL
|
#if PERL_UNICODE_DOES_NOT_WORK_WELL
|
||||||
sqlite_trace(dbh, imp_dbh, 3, "Unicode support is disabled for this version of perl.");
|
sqlite_trace(dbh, imp_dbh, 3, "Unicode support is disabled for this version of perl.");
|
||||||
return sv_2mortal(newSViv(0));
|
return sv_2mortal(newSViv(0));
|
||||||
#else
|
#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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -955,7 +829,7 @@ sqlite_st_prepare_sv(SV *sth, imp_sth_t *imp_sth, SV *sv_statement, SV *attribs)
|
||||||
stmt_list_s * new_stmt;
|
stmt_list_s * new_stmt;
|
||||||
D_imp_dbh_from_sth;
|
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)) {
|
if (!DBIc_ACTIVE(imp_dbh)) {
|
||||||
sqlite_error(sth, -2, "attempt to prepare on inactive database handle");
|
sqlite_error(sth, -2, "attempt to prepare on inactive database handle");
|
||||||
|
@ -963,7 +837,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 */
|
/* 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);
|
statement = SvPV_nolen(sv_statement);
|
||||||
|
|
||||||
|
@ -1077,15 +953,10 @@ sqlite_st_execute(SV *sth, imp_sth_t *imp_sth)
|
||||||
const char *data;
|
const char *data;
|
||||||
int numtype = 0;
|
int numtype = 0;
|
||||||
|
|
||||||
if (imp_dbh->string_mode & DBD_SQLITE_STRING_MODE_UNICODE_ANY) {
|
if (imp_dbh->unicode) {
|
||||||
data = SvPVutf8(value, len);
|
sv_utf8_upgrade(value);
|
||||||
}
|
}
|
||||||
else if (imp_dbh->string_mode == DBD_SQLITE_STRING_MODE_BYTES) {
|
|
||||||
data = SvPVbyte(value, len);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
data = SvPV(value, len);
|
data = SvPV(value, len);
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX: For backward compatibility, it'd be better to
|
* XXX: For backward compatibility, it'd be better to
|
||||||
|
@ -1296,9 +1167,11 @@ sqlite_st_fetch(SV *sth, imp_sth_t *imp_sth)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sv_setpvn(AvARRAY(av)[i], val, len);
|
sv_setpvn(AvARRAY(av)[i], val, len);
|
||||||
|
if (imp_dbh->unicode) {
|
||||||
DBD_SQLITE_UTF8_DECODE_IF_NEEDED(AvARRAY(av)[i], imp_dbh->string_mode);
|
SvUTF8_on(AvARRAY(av)[i]);
|
||||||
|
} else {
|
||||||
|
SvUTF8_off(AvARRAY(av)[i]);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SQLITE_BLOB:
|
case SQLITE_BLOB:
|
||||||
sqlite_trace(sth, imp_sth, 5, form("fetch column %d as blob", i));
|
sqlite_trace(sth, imp_sth, 5, form("fetch column %d as blob", i));
|
||||||
|
@ -1439,11 +1312,6 @@ sqlite_st_FETCH_attrib(SV *sth, imp_sth_t *imp_sth, SV *keysv)
|
||||||
croak_if_db_is_null();
|
croak_if_db_is_null();
|
||||||
croak_if_stmt_is_null();
|
croak_if_stmt_is_null();
|
||||||
|
|
||||||
if (!DBIc_ACTIVE(imp_dbh)) {
|
|
||||||
sqlite_error(sth, -2, "attempt to fetch on inactive database handle");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strEQ(key, "sqlite_unprepared_statements")) {
|
if (strEQ(key, "sqlite_unprepared_statements")) {
|
||||||
return sv_2mortal(newSVpv(imp_sth->unprepared_statements, 0));
|
return sv_2mortal(newSVpv(imp_sth->unprepared_statements, 0));
|
||||||
}
|
}
|
||||||
|
@ -1470,9 +1338,8 @@ sqlite_st_FETCH_attrib(SV *sth, imp_sth_t *imp_sth, SV *keysv)
|
||||||
/* if (dot) drop table name from field name */
|
/* if (dot) drop table name from field name */
|
||||||
/* fieldname = ++dot; */
|
/* fieldname = ++dot; */
|
||||||
SV *sv_fieldname = newSVpv(fieldname, 0);
|
SV *sv_fieldname = newSVpv(fieldname, 0);
|
||||||
|
if (imp_dbh->unicode)
|
||||||
DBD_SQLITE_UTF8_DECODE_IF_NEEDED(sv_fieldname, imp_dbh->string_mode);
|
SvUTF8_on(sv_fieldname);
|
||||||
|
|
||||||
av_store(av, n, sv_fieldname);
|
av_store(av, n, sv_fieldname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1486,20 +1353,17 @@ sqlite_st_FETCH_attrib(SV *sth, imp_sth_t *imp_sth, SV *keysv)
|
||||||
av_extend(av, i);
|
av_extend(av, i);
|
||||||
retsv = sv_2mortal(newRV_noinc((SV*)av));
|
retsv = sv_2mortal(newRV_noinc((SV*)av));
|
||||||
for (n = 0; n < i; n++) {
|
for (n = 0; n < i; n++) {
|
||||||
if (imp_dbh->prefer_numeric_type) {
|
const char *fieldtype = sqlite3_column_decltype(imp_sth->stmt, n);
|
||||||
int type = sqlite3_column_type(imp_sth->stmt, n);
|
int type = sqlite3_column_type(imp_sth->stmt, n);
|
||||||
/* warn("got type: %d = %s\n", type, fieldtype); */
|
/* warn("got type: %d = %s\n", type, fieldtype); */
|
||||||
type = sqlite_type_to_odbc_type(type);
|
type = sqlite_type_to_odbc_type(type);
|
||||||
av_store(av, n, newSViv(type));
|
/* av_store(av, n, newSViv(type)); */
|
||||||
} else {
|
|
||||||
const char *fieldtype = sqlite3_column_decltype(imp_sth->stmt, n);
|
|
||||||
if (fieldtype)
|
if (fieldtype)
|
||||||
av_store(av, n, newSVpv(fieldtype, 0));
|
av_store(av, n, newSVpv(fieldtype, 0));
|
||||||
else
|
else
|
||||||
av_store(av, n, newSVpv("VARCHAR", 0));
|
av_store(av, n, newSVpv("VARCHAR", 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (strEQ(key, "NULLABLE")) {
|
else if (strEQ(key, "NULLABLE")) {
|
||||||
AV *av = newAV();
|
AV *av = newAV();
|
||||||
av_extend(av, i);
|
av_extend(av, i);
|
||||||
|
@ -1733,7 +1597,7 @@ SV *
|
||||||
sqlite_db_filename(pTHX_ SV *dbh)
|
sqlite_db_filename(pTHX_ SV *dbh)
|
||||||
{
|
{
|
||||||
D_imp_dbh(dbh);
|
D_imp_dbh(dbh);
|
||||||
const char *filename = NULL;
|
const char *filename;
|
||||||
|
|
||||||
if (!imp_dbh->db) {
|
if (!imp_dbh->db) {
|
||||||
return &PL_sv_undef;
|
return &PL_sv_undef;
|
||||||
|
@ -1766,7 +1630,7 @@ sqlite_db_busy_timeout(pTHX_ SV *dbh, SV *timeout )
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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;
|
dTHX;
|
||||||
dSP;
|
dSP;
|
||||||
|
@ -1781,7 +1645,7 @@ sqlite_db_func_dispatcher(dbd_sqlite_string_mode_t string_mode, sqlite3_context
|
||||||
|
|
||||||
PUSHMARK(SP);
|
PUSHMARK(SP);
|
||||||
for ( i=0; i < argc; i++ ) {
|
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;
|
PUTBACK;
|
||||||
|
|
||||||
|
@ -1812,46 +1676,17 @@ sqlite_db_func_dispatcher(dbd_sqlite_string_mode_t string_mode, sqlite3_context
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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
|
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
|
int
|
||||||
sqlite_db_create_function(pTHX_ SV *dbh, const char *name, int argc, SV *func, int flags)
|
sqlite_db_create_function(pTHX_ SV *dbh, const char *name, int argc, SV *func, int flags)
|
||||||
{
|
{
|
||||||
|
@ -1865,20 +1700,17 @@ sqlite_db_create_function(pTHX_ SV *dbh, const char *name, int argc, SV *func, i
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the function reference */
|
/* Copy the function reference */
|
||||||
if (SvOK(func)) {
|
|
||||||
func_sv = newSVsv(func);
|
func_sv = newSVsv(func);
|
||||||
av_push( imp_dbh->functions, func_sv );
|
av_push( imp_dbh->functions, func_sv );
|
||||||
}
|
|
||||||
|
|
||||||
croak_if_db_is_null();
|
croak_if_db_is_null();
|
||||||
|
|
||||||
/* warn("create_function %s with %d args\n", name, argc); */
|
/* 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,
|
rc = sqlite3_create_function( imp_dbh->db, name, argc, SQLITE_UTF8|flags,
|
||||||
func_sv, _FUNC_DISPATCHER[imp_dbh->string_mode], NULL, NULL );
|
func_sv,
|
||||||
} else {
|
imp_dbh->unicode ? sqlite_db_func_dispatcher_unicode
|
||||||
rc = sqlite3_create_function( imp_dbh->db, name, argc, SQLITE_UTF8|flags, NULL, NULL, NULL, NULL );
|
: sqlite_db_func_dispatcher_no_unicode,
|
||||||
}
|
NULL, NULL );
|
||||||
if ( rc != SQLITE_OK ) {
|
if ( rc != SQLITE_OK ) {
|
||||||
sqlite_error(dbh, rc, form("sqlite_create_function failed with error %s", sqlite3_errmsg(imp_dbh->db)));
|
sqlite_error(dbh, rc, form("sqlite_create_function failed with error %s", sqlite3_errmsg(imp_dbh->db)));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1934,21 +1766,6 @@ sqlite_db_load_extension(pTHX_ SV *dbh, const char *file, const char *proc)
|
||||||
|
|
||||||
#endif
|
#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*
|
HV*
|
||||||
sqlite_db_table_column_metadata(pTHX_ SV *dbh, SV *dbname, SV *tablename, SV *columnname)
|
sqlite_db_table_column_metadata(pTHX_ SV *dbh, SV *dbname, SV *tablename, SV *columnname)
|
||||||
{
|
{
|
||||||
|
@ -1985,7 +1802,7 @@ sqlite_db_table_column_metadata(pTHX_ SV *dbh, SV *dbname, SV *tablename, SV *co
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (rc == SQLITE_OK) {
|
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, "collation_name", collseq ? newSVpv(collseq, 0) : newSV(0));
|
||||||
hv_stores(metadata, "not_null", newSViv(notnull));
|
hv_stores(metadata, "not_null", newSViv(notnull));
|
||||||
hv_stores(metadata, "primary", newSViv(primary));
|
hv_stores(metadata, "primary", newSViv(primary));
|
||||||
|
@ -2057,7 +1874,7 @@ sqlite_db_aggr_step_dispatcher(sqlite3_context *context,
|
||||||
{
|
{
|
||||||
dTHX;
|
dTHX;
|
||||||
dSP;
|
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;
|
aggrInfo *aggr;
|
||||||
|
|
||||||
aggr = sqlite3_aggregate_context(context, sizeof (aggrInfo));
|
aggr = sqlite3_aggregate_context(context, sizeof (aggrInfo));
|
||||||
|
@ -2079,7 +1896,7 @@ sqlite_db_aggr_step_dispatcher(sqlite3_context *context,
|
||||||
PUSHMARK(SP);
|
PUSHMARK(SP);
|
||||||
XPUSHs( sv_2mortal( newSVsv( aggr->aggr_inst ) ));
|
XPUSHs( sv_2mortal( newSVsv( aggr->aggr_inst ) ));
|
||||||
for ( i=0; i < argc; i++ ) {
|
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;
|
PUTBACK;
|
||||||
|
|
||||||
|
@ -2195,78 +2012,71 @@ sqlite_db_create_aggregate(pTHX_ SV *dbh, const char *name, int argc, SV *aggr_p
|
||||||
return TRUE;
|
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
|
int
|
||||||
sqlite_db_collation_dispatcher(void *func, int len1, const void *string1,
|
sqlite_db_collation_dispatcher(void *func, int len1, const void *string1,
|
||||||
int len2, const void *string2)
|
int len2, const void *string2)
|
||||||
{
|
{
|
||||||
dTHX;
|
dTHX;
|
||||||
dSP;
|
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
|
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)
|
int len2, const void *string2)
|
||||||
{
|
{
|
||||||
dTHX;
|
dTHX;
|
||||||
dSP;
|
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
|
int
|
||||||
sqlite_db_create_collation(pTHX_ SV *dbh, const char *name, SV *func)
|
sqlite_db_create_collation(pTHX_ SV *dbh, const char *name, SV *func)
|
||||||
{
|
{
|
||||||
|
@ -2302,7 +2112,8 @@ sqlite_db_create_collation(pTHX_ SV *dbh, const char *name, SV *func)
|
||||||
rv = sqlite3_create_collation(
|
rv = sqlite3_create_collation(
|
||||||
imp_dbh->db, name, SQLITE_UTF8,
|
imp_dbh->db, name, SQLITE_UTF8,
|
||||||
func_sv,
|
func_sv,
|
||||||
_COLLATION_DISPATCHER[imp_dbh->string_mode]
|
imp_dbh->unicode ? sqlite_db_collation_dispatcher_utf8
|
||||||
|
: sqlite_db_collation_dispatcher
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( rv != SQLITE_OK ) {
|
if ( rv != SQLITE_OK ) {
|
||||||
|
@ -2788,49 +2599,6 @@ sqlite_db_backup_from_file(pTHX_ SV *dbh, char *filename)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
sqlite_db_backup_from_dbh(pTHX_ SV *dbh, SV *from)
|
|
||||||
{
|
|
||||||
D_imp_dbh(dbh);
|
|
||||||
|
|
||||||
#if SQLITE_VERSION_NUMBER >= 3006011
|
|
||||||
int rc;
|
|
||||||
sqlite3_backup *pBackup;
|
|
||||||
|
|
||||||
imp_dbh_t *imp_dbh_from = (imp_dbh_t *)DBIh_COM(from);
|
|
||||||
|
|
||||||
if (!DBIc_ACTIVE(imp_dbh)) {
|
|
||||||
sqlite_error(dbh, -2, "attempt to backup from file on inactive database handle");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!DBIc_ACTIVE(imp_dbh_from)) {
|
|
||||||
sqlite_error(dbh, -2, "attempt to backup from inactive database handle");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
croak_if_db_is_null();
|
|
||||||
|
|
||||||
/* COMPAT: sqlite3_backup_* are only available for 3006011 or newer */
|
|
||||||
pBackup = sqlite3_backup_init(imp_dbh->db, "main", imp_dbh_from->db, "main");
|
|
||||||
if (pBackup) {
|
|
||||||
(void)sqlite3_backup_step(pBackup, -1);
|
|
||||||
(void)sqlite3_backup_finish(pBackup);
|
|
||||||
}
|
|
||||||
rc = sqlite3_errcode(imp_dbh->db);
|
|
||||||
|
|
||||||
if ( rc != SQLITE_OK ) {
|
|
||||||
sqlite_error(dbh, rc, form("sqlite_backup_from_file failed with error %s", sqlite3_errmsg(imp_dbh->db)));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
#else
|
|
||||||
sqlite_error(dbh, SQLITE_ERROR, form("backup feature requires SQLite 3.6.11 and newer"));
|
|
||||||
return FALSE;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Accesses the SQLite Online Backup API, and copies the currently loaded
|
/* Accesses the SQLite Online Backup API, and copies the currently loaded
|
||||||
* database into the passed filename.
|
* database into the passed filename.
|
||||||
* Usual usage of this would be when you're operating on the :memory:
|
* Usual usage of this would be when you're operating on the :memory:
|
||||||
|
@ -2879,117 +2647,6 @@ sqlite_db_backup_to_file(pTHX_ SV *dbh, char *filename)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
sqlite_db_backup_to_dbh(pTHX_ SV *dbh, SV *to)
|
|
||||||
{
|
|
||||||
D_imp_dbh(dbh);
|
|
||||||
|
|
||||||
#if SQLITE_VERSION_NUMBER >= 3006011
|
|
||||||
int rc;
|
|
||||||
sqlite3_backup *pBackup;
|
|
||||||
|
|
||||||
imp_dbh_t *imp_dbh_to = (imp_dbh_t *)DBIh_COM(to);
|
|
||||||
|
|
||||||
if (!DBIc_ACTIVE(imp_dbh)) {
|
|
||||||
sqlite_error(dbh, -2, "attempt to backup to file on inactive database handle");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!DBIc_ACTIVE(imp_dbh_to)) {
|
|
||||||
sqlite_error(dbh, -2, "attempt to backup to inactive database handle");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
croak_if_db_is_null();
|
|
||||||
|
|
||||||
/* COMPAT: sqlite3_backup_* are only available for 3006011 or newer */
|
|
||||||
pBackup = sqlite3_backup_init(imp_dbh_to->db, "main", imp_dbh->db, "main");
|
|
||||||
if (pBackup) {
|
|
||||||
(void)sqlite3_backup_step(pBackup, -1);
|
|
||||||
(void)sqlite3_backup_finish(pBackup);
|
|
||||||
}
|
|
||||||
rc = sqlite3_errcode(imp_dbh_to->db);
|
|
||||||
|
|
||||||
if ( rc != SQLITE_OK ) {
|
|
||||||
sqlite_error(dbh, rc, form("sqlite_backup_to_file failed with error %s", sqlite3_errmsg(imp_dbh->db)));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
#else
|
|
||||||
sqlite_error(dbh, SQLITE_ERROR, form("backup feature requires SQLite 3.6.11 and newer"));
|
|
||||||
return FALSE;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
sqlite_db_limit(pTHX_ SV *dbh, int id, int new_value)
|
|
||||||
{
|
|
||||||
D_imp_dbh(dbh);
|
|
||||||
return sqlite3_limit(imp_dbh->db, id, new_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
sqlite_db_config(pTHX_ SV *dbh, int id, int new_value)
|
|
||||||
{
|
|
||||||
D_imp_dbh(dbh);
|
|
||||||
int ret;
|
|
||||||
int rc = -1;
|
|
||||||
switch (id) {
|
|
||||||
case SQLITE_DBCONFIG_LOOKASIDE:
|
|
||||||
sqlite_error(dbh, rc, "SQLITE_DBCONFIG_LOOKASIDE is not supported");
|
|
||||||
return FALSE;
|
|
||||||
case SQLITE_DBCONFIG_MAINDBNAME:
|
|
||||||
sqlite_error(dbh, rc, "SQLITE_DBCONFIG_MAINDBNAME is not supported");
|
|
||||||
return FALSE;
|
|
||||||
case SQLITE_DBCONFIG_ENABLE_FKEY:
|
|
||||||
case SQLITE_DBCONFIG_ENABLE_TRIGGER:
|
|
||||||
case SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER:
|
|
||||||
case SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION:
|
|
||||||
case SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE:
|
|
||||||
case SQLITE_DBCONFIG_ENABLE_QPSG:
|
|
||||||
case SQLITE_DBCONFIG_TRIGGER_EQP:
|
|
||||||
case SQLITE_DBCONFIG_RESET_DATABASE:
|
|
||||||
case SQLITE_DBCONFIG_DEFENSIVE:
|
|
||||||
case SQLITE_DBCONFIG_WRITABLE_SCHEMA:
|
|
||||||
case SQLITE_DBCONFIG_LEGACY_ALTER_TABLE:
|
|
||||||
case SQLITE_DBCONFIG_DQS_DML:
|
|
||||||
case SQLITE_DBCONFIG_DQS_DDL:
|
|
||||||
rc = sqlite3_db_config(imp_dbh->db, id, new_value, &ret);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sqlite_error(dbh, rc, form("Unknown config id: %d", id));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if ( rc != SQLITE_OK ) {
|
|
||||||
sqlite_error(dbh, rc, form("sqlite_db_config failed with error %s", sqlite3_errmsg(imp_dbh->db)));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
sqlite_db_get_autocommit(pTHX_ SV *dbh)
|
|
||||||
{
|
|
||||||
D_imp_dbh(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_tokenizer.inc"
|
||||||
#include "dbdimp_virtual_table.inc"
|
#include "dbdimp_virtual_table.inc"
|
||||||
|
|
||||||
|
|
62
dbdimp.h
62
dbdimp.h
|
@ -7,24 +7,8 @@
|
||||||
|
|
||||||
#define MY_CXT_KEY "DBD::SQLite::_guts" XS_VERSION
|
#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 {
|
typedef struct {
|
||||||
dbd_sqlite_string_mode_t last_dbh_string_mode;
|
int last_dbh_is_unicode;
|
||||||
} my_cxt_t;
|
} my_cxt_t;
|
||||||
|
|
||||||
#define PERL_UNICODE_DOES_NOT_WORK_WELL \
|
#define PERL_UNICODE_DOES_NOT_WORK_WELL \
|
||||||
|
@ -38,41 +22,6 @@ typedef struct {
|
||||||
#define sqlite3_int64 sqlite_int64
|
#define sqlite3_int64 sqlite_int64
|
||||||
#endif
|
#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 */
|
/* A linked list of statements prepared by this module */
|
||||||
typedef struct stmt_list_s stmt_list_s;
|
typedef struct stmt_list_s stmt_list_s;
|
||||||
|
|
||||||
|
@ -92,7 +41,7 @@ struct imp_dbh_st {
|
||||||
dbih_dbc_t com;
|
dbih_dbc_t com;
|
||||||
/* sqlite specific bits */
|
/* sqlite specific bits */
|
||||||
sqlite3 *db;
|
sqlite3 *db;
|
||||||
dbd_sqlite_string_mode_t string_mode;
|
bool unicode;
|
||||||
bool handle_binary_nulls;
|
bool handle_binary_nulls;
|
||||||
int timeout;
|
int timeout;
|
||||||
AV *functions;
|
AV *functions;
|
||||||
|
@ -104,7 +53,6 @@ struct imp_dbh_st {
|
||||||
int extended_result_codes;
|
int extended_result_codes;
|
||||||
stmt_list_s * stmt_list;
|
stmt_list_s * stmt_list;
|
||||||
bool began_transaction;
|
bool began_transaction;
|
||||||
bool prefer_numeric_type;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Statement Handle */
|
/* Statement Handle */
|
||||||
|
@ -168,8 +116,6 @@ int sqlite_bind_col( SV *sth, imp_sth_t *imp_sth, SV *col, SV *ref, IV sql_type,
|
||||||
int sqlite_db_busy_timeout (pTHX_ SV *dbh, SV *timeout );
|
int sqlite_db_busy_timeout (pTHX_ SV *dbh, SV *timeout );
|
||||||
int sqlite_db_backup_from_file(pTHX_ SV *dbh, char *filename);
|
int sqlite_db_backup_from_file(pTHX_ SV *dbh, char *filename);
|
||||||
int sqlite_db_backup_to_file(pTHX_ SV *dbh, char *filename);
|
int sqlite_db_backup_to_file(pTHX_ SV *dbh, char *filename);
|
||||||
int sqlite_db_backup_from_dbh(pTHX_ SV *dbh, SV *from);
|
|
||||||
int sqlite_db_backup_to_dbh(pTHX_ SV *dbh, SV *to);
|
|
||||||
void sqlite_db_collation_needed(pTHX_ SV *dbh, SV *callback );
|
void sqlite_db_collation_needed(pTHX_ SV *dbh, SV *callback );
|
||||||
SV* sqlite_db_commit_hook( pTHX_ SV *dbh, SV *hook );
|
SV* sqlite_db_commit_hook( pTHX_ SV *dbh, SV *hook );
|
||||||
SV* sqlite_db_rollback_hook( pTHX_ SV *dbh, SV *hook );
|
SV* sqlite_db_rollback_hook( pTHX_ SV *dbh, SV *hook );
|
||||||
|
@ -185,10 +131,6 @@ int sqlite_db_register_fts3_perl_tokenizer(pTHX_ SV *dbh);
|
||||||
HV* _sqlite_status(int reset);
|
HV* _sqlite_status(int reset);
|
||||||
HV* _sqlite_st_status(pTHX_ SV *sth, int reset);
|
HV* _sqlite_st_status(pTHX_ SV *sth, int reset);
|
||||||
int sqlite_db_create_module(pTHX_ SV *dbh, const char *name, const char *perl_class);
|
int sqlite_db_create_module(pTHX_ SV *dbh, const char *name, const char *perl_class);
|
||||||
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);
|
int sqlite_db_do_sv(SV *dbh, imp_dbh_t *imp_dbh, SV *sv_statement);
|
||||||
void init_cxt();
|
void init_cxt();
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,8 @@ typedef struct perl_tokenizer_cursor {
|
||||||
|
|
||||||
/* members below are only used if the input string is in utf8 */
|
/* members below are only used if the input string is in utf8 */
|
||||||
const char *pInput; /* input we are tokenizing */
|
const char *pInput; /* input we are tokenizing */
|
||||||
const char *currentByte; /* pointer into pInput */
|
const char *lastByteOffset; /* offset into pInput */
|
||||||
int currentChar; /* char position corresponding to currentByte */
|
int lastCharOffset; /* char offset corresponding to lastByteOffset */
|
||||||
} perl_tokenizer_cursor;
|
} perl_tokenizer_cursor;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -94,30 +94,6 @@ static int perl_tokenizer_Open(
|
||||||
SV *perl_string;
|
SV *perl_string;
|
||||||
int n_retval;
|
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;
|
perl_tokenizer *t = (perl_tokenizer *)pTokenizer;
|
||||||
|
|
||||||
/* allocate and initialize the cursor struct */
|
/* allocate and initialize the cursor struct */
|
||||||
|
@ -126,17 +102,29 @@ static int perl_tokenizer_Open(
|
||||||
memset(c, 0, sizeof(*c));
|
memset(c, 0, sizeof(*c));
|
||||||
*ppCursor = &c->base;
|
*ppCursor = &c->base;
|
||||||
|
|
||||||
/* special handling if working with utf8 strings */
|
/* flags for creating the Perl SV containing the input string */
|
||||||
if (MY_CXT.last_dbh_string_mode & DBD_SQLITE_STRING_MODE_UNICODE_ANY) {
|
flags = SVs_TEMP; /* will call sv_2mortal */
|
||||||
|
|
||||||
/* data to keep track of byte positions */
|
/* special handling if working with utf8 strings */
|
||||||
c->currentByte = c->pInput = pInput;
|
if (MY_CXT.last_dbh_is_unicode) {
|
||||||
c->currentChar = 0;
|
|
||||||
|
/* 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;
|
ENTER;
|
||||||
SAVETMPS;
|
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 */
|
/* call the tokenizer coderef */
|
||||||
PUSHMARK(SP);
|
PUSHMARK(SP);
|
||||||
XPUSHs(perl_string);
|
XPUSHs(perl_string);
|
||||||
|
@ -146,7 +134,7 @@ static int perl_tokenizer_Open(
|
||||||
|
|
||||||
/* store the cursor coderef returned by the tokenizer */
|
/* store the cursor coderef returned by the tokenizer */
|
||||||
if (n_retval != 1) {
|
if (n_retval != 1) {
|
||||||
warn("tokenizer returned %d arguments, expected 1", n_retval);
|
warn("tokenizer returned %d arguments", n_retval);
|
||||||
}
|
}
|
||||||
c->coderef = newSVsv(POPs);
|
c->coderef = newSVsv(POPs);
|
||||||
|
|
||||||
|
@ -176,17 +164,17 @@ static int perl_tokenizer_Close(sqlite3_tokenizer_cursor *pCursor){
|
||||||
*/
|
*/
|
||||||
static int perl_tokenizer_Next(
|
static int perl_tokenizer_Next(
|
||||||
sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by perl_tokenizer_Open */
|
sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by perl_tokenizer_Open */
|
||||||
const char **ppToken, /* OUT: Normalized text for token */
|
const char **ppToken, /* OUT: *ppToken is the token text */
|
||||||
int *pnBytes, /* OUT: Number of bytes in normalized text */
|
int *pnBytes, /* OUT: Number of bytes in token */
|
||||||
int *piStartOffset, /* Starting offset of token. IN : char offset; OUT : byte offset */
|
int *piStartOffset, /* OUT: Starting offset of token */
|
||||||
int *piEndOffset, /* Ending offset of token. IN : char offset; OUT : byte offset */
|
int *piEndOffset, /* OUT: Ending offset of token */
|
||||||
int *piPosition /* OUT: Number of tokens returned before this one */
|
int *piPosition /* OUT: Position integer of token */
|
||||||
){
|
){
|
||||||
perl_tokenizer_cursor *c = (perl_tokenizer_cursor *) pCursor;
|
perl_tokenizer_cursor *c = (perl_tokenizer_cursor *) pCursor;
|
||||||
int result;
|
int result;
|
||||||
int n_retval;
|
int n_retval;
|
||||||
char *token;
|
char *token;
|
||||||
char *nextByte;
|
char *byteOffset;
|
||||||
STRLEN n_a; /* this is required for older perls < 5.8.8 */
|
STRLEN n_a; /* this is required for older perls < 5.8.8 */
|
||||||
I32 hop;
|
I32 hop;
|
||||||
|
|
||||||
|
@ -209,7 +197,7 @@ static int perl_tokenizer_Next(
|
||||||
/* otherwise, get token details from the return list */
|
/* otherwise, get token details from the return list */
|
||||||
else {
|
else {
|
||||||
if (n_retval != 5) {
|
if (n_retval != 5) {
|
||||||
warn("tokenizer cursor returned %d arguments, expected 5", n_retval);
|
warn("tokenizer cursor returned %d arguments", n_retval);
|
||||||
}
|
}
|
||||||
*piPosition = POPi;
|
*piPosition = POPi;
|
||||||
*piEndOffset = POPi;
|
*piEndOffset = POPi;
|
||||||
|
@ -218,30 +206,21 @@ static int perl_tokenizer_Next(
|
||||||
token = POPpx;
|
token = POPpx;
|
||||||
|
|
||||||
if (c->pInput) { /* if working with utf8 data */
|
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 */
|
/* recompute *pnBytes in bytes, not in chars */
|
||||||
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 */
|
|
||||||
*pnBytes = strlen(token);
|
*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 */
|
/* make sure we have enough storage for copying the token */
|
||||||
|
@ -253,7 +232,8 @@ static int perl_tokenizer_Next(
|
||||||
c->pToken = pNew;
|
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);
|
memcpy(c->pToken, token, *pnBytes);
|
||||||
*ppToken = c->pToken;
|
*ppToken = c->pToken;
|
||||||
|
|
||||||
|
|
|
@ -47,44 +47,6 @@ static int _call_perl_vtab_method(sqlite3_vtab *pVTab,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* RT-124941: it seems better to prefer PV where appropriate */
|
|
||||||
static void
|
|
||||||
sqlite_set_result_for_vtable(pTHX_ sqlite3_context *context, SV *result, int is_error)
|
|
||||||
{
|
|
||||||
STRLEN len;
|
|
||||||
char *s;
|
|
||||||
sqlite3_int64 iv;
|
|
||||||
|
|
||||||
if ( is_error ) {
|
|
||||||
s = SvPV(result, len);
|
|
||||||
sqlite3_result_error( context, s, len );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* warn("result: %s\n", SvPV_nolen(result)); */
|
|
||||||
if ( !SvOK(result) ) {
|
|
||||||
sqlite3_result_null( context );
|
|
||||||
} else if ( SvPOK(result) ) {
|
|
||||||
s = SvPV(result, len);
|
|
||||||
sqlite3_result_text( context, s, len, SQLITE_TRANSIENT );
|
|
||||||
} else if( SvIOK_UV(result) ) {
|
|
||||||
if ((UV)(sqlite3_int64)UV_MAX == UV_MAX)
|
|
||||||
sqlite3_result_int64( context, (sqlite3_int64)SvUV(result));
|
|
||||||
else {
|
|
||||||
s = SvPV(result, len);
|
|
||||||
sqlite3_result_text( context, s, len, SQLITE_TRANSIENT );
|
|
||||||
}
|
|
||||||
} else if ( !_sqlite_atoi64(SvPV(result, len), &iv) ) {
|
|
||||||
sqlite3_result_int64( context, iv );
|
|
||||||
} else if ( SvNOK(result) && ( sizeof(NV) == sizeof(double) || SvNVX(result) == (double) SvNVX(result) ) ) {
|
|
||||||
sqlite3_result_double( context, SvNV(result));
|
|
||||||
} else {
|
|
||||||
s = SvPV(result, len);
|
|
||||||
sqlite3_result_text( context, s, len, SQLITE_TRANSIENT );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int perl_vt_New(const char *method,
|
static int perl_vt_New(const char *method,
|
||||||
sqlite3 *db, void *pAux,
|
sqlite3 *db, void *pAux,
|
||||||
|
@ -432,7 +394,7 @@ static int perl_vt_Filter( sqlite3_vtab_cursor *pVtabCursor,
|
||||||
dSP;
|
dSP;
|
||||||
dMY_CXT;
|
dMY_CXT;
|
||||||
int i, count;
|
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;
|
ENTER;
|
||||||
SAVETMPS;
|
SAVETMPS;
|
||||||
|
@ -443,7 +405,7 @@ static int perl_vt_Filter( sqlite3_vtab_cursor *pVtabCursor,
|
||||||
XPUSHs(sv_2mortal(newSViv(idxNum)));
|
XPUSHs(sv_2mortal(newSViv(idxNum)));
|
||||||
XPUSHs(sv_2mortal(newSVpv(idxStr, 0)));
|
XPUSHs(sv_2mortal(newSVpv(idxStr, 0)));
|
||||||
for(i = 0; i < argc; i++) {
|
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;
|
PUTBACK;
|
||||||
count = call_method("FILTER", G_VOID);
|
count = call_method("FILTER", G_VOID);
|
||||||
|
@ -484,8 +446,7 @@ static int perl_vt_Next(sqlite3_vtab_cursor *pVtabCursor){
|
||||||
static int perl_vt_Eof(sqlite3_vtab_cursor *pVtabCursor){
|
static int perl_vt_Eof(sqlite3_vtab_cursor *pVtabCursor){
|
||||||
dTHX;
|
dTHX;
|
||||||
dSP;
|
dSP;
|
||||||
int count;
|
int count, eof;
|
||||||
int eof = 1;
|
|
||||||
|
|
||||||
ENTER;
|
ENTER;
|
||||||
SAVETMPS;
|
SAVETMPS;
|
||||||
|
@ -538,7 +499,7 @@ static int perl_vt_Column(sqlite3_vtab_cursor *pVtabCursor,
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SV *result = POPs;
|
SV *result = POPs;
|
||||||
sqlite_set_result_for_vtable(aTHX_ context, result, 0 );
|
sqlite_set_result(aTHX_ context, result, 0 );
|
||||||
rc = SQLITE_OK;
|
rc = SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -588,7 +549,7 @@ static int perl_vt_Update( sqlite3_vtab *pVTab,
|
||||||
dSP;
|
dSP;
|
||||||
dMY_CXT;
|
dMY_CXT;
|
||||||
int count, i;
|
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;
|
int rc = SQLITE_ERROR;
|
||||||
SV *rowidsv;
|
SV *rowidsv;
|
||||||
|
|
||||||
|
@ -599,7 +560,7 @@ static int perl_vt_Update( sqlite3_vtab *pVTab,
|
||||||
PUSHMARK(SP);
|
PUSHMARK(SP);
|
||||||
XPUSHs(((perl_vtab *) pVTab)->perl_vtab_obj);
|
XPUSHs(((perl_vtab *) pVTab)->perl_vtab_obj);
|
||||||
for(i = 0; i < argc; i++) {
|
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;
|
PUTBACK;
|
||||||
count = call_method ("_SQLITE_UPDATE", G_SCALAR);
|
count = call_method ("_SQLITE_UPDATE", G_SCALAR);
|
||||||
|
@ -704,9 +665,8 @@ static int perl_vt_FindFunction(sqlite3_vtab *pVTab,
|
||||||
/* return function information for sqlite3 within *pxFunc and *ppArg */
|
/* return function information for sqlite3 within *pxFunc and *ppArg */
|
||||||
is_overloaded = coderef && SvTRUE(coderef);
|
is_overloaded = coderef && SvTRUE(coderef);
|
||||||
if (is_overloaded) {
|
if (is_overloaded) {
|
||||||
|
*pxFunc = MY_CXT.last_dbh_is_unicode ? sqlite_db_func_dispatcher_unicode
|
||||||
*pxFunc = _FUNC_DISPATCHER[MY_CXT.last_dbh_string_mode];
|
: sqlite_db_func_dispatcher_no_unicode;
|
||||||
|
|
||||||
*ppArg = coderef;
|
*ppArg = coderef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -815,7 +775,6 @@ sqlite_db_destroy_module_data(void *pAux)
|
||||||
/* free module memory */
|
/* free module memory */
|
||||||
SvREFCNT_dec(init_data->dbh);
|
SvREFCNT_dec(init_data->dbh);
|
||||||
sqlite3_free((char *)init_data->perl_class);
|
sqlite3_free((char *)init_data->perl_class);
|
||||||
sqlite3_free(init_data);
|
|
||||||
|
|
||||||
PUTBACK;
|
PUTBACK;
|
||||||
FREETMPS;
|
FREETMPS;
|
||||||
|
|
|
@ -1,216 +0,0 @@
|
||||||
use 5.008001;
|
|
||||||
use strict;
|
|
||||||
use warnings;
|
|
||||||
|
|
||||||
package Test::FailWarnings;
|
|
||||||
# ABSTRACT: Add test failures if warnings are caught
|
|
||||||
our $VERSION = '0.008'; # VERSION
|
|
||||||
|
|
||||||
use Test::More 0.86;
|
|
||||||
use Cwd qw/getcwd/;
|
|
||||||
use File::Spec;
|
|
||||||
use Carp;
|
|
||||||
|
|
||||||
our $ALLOW_DEPS = 0;
|
|
||||||
our @ALLOW_FROM = ();
|
|
||||||
|
|
||||||
my $ORIG_DIR = getcwd(); # cache in case handler runs after a chdir
|
|
||||||
|
|
||||||
sub import {
|
|
||||||
my ( $class, @args ) = @_;
|
|
||||||
croak("import arguments must be key/value pairs")
|
|
||||||
unless @args % 2 == 0;
|
|
||||||
my %opts = @args;
|
|
||||||
$ALLOW_DEPS = $opts{'-allow_deps'};
|
|
||||||
if ( $opts{'-allow_from'} ) {
|
|
||||||
@ALLOW_FROM =
|
|
||||||
ref $opts{'-allow_from'} ? @{ $opts{'-allow_from'} } : $opts{'-allow_from'};
|
|
||||||
}
|
|
||||||
$SIG{__WARN__} = \&handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub handler {
|
|
||||||
my $msg = shift;
|
|
||||||
$msg = '' unless defined $msg;
|
|
||||||
chomp $msg;
|
|
||||||
my ( $package, $filename, $line ) = _find_source();
|
|
||||||
|
|
||||||
# shortcut if ignoring dependencies and warning did not
|
|
||||||
# come from something local
|
|
||||||
if ($ALLOW_DEPS) {
|
|
||||||
$filename = File::Spec->abs2rel( $filename, $ORIG_DIR )
|
|
||||||
if File::Spec->file_name_is_absolute($filename);
|
|
||||||
return if $filename !~ /^(?:t|xt|lib|blib)/;
|
|
||||||
}
|
|
||||||
|
|
||||||
return if grep { $package eq $_ } @ALLOW_FROM;
|
|
||||||
|
|
||||||
if ( $msg !~ m/at .*? line \d/ ) {
|
|
||||||
chomp $msg;
|
|
||||||
$msg = "'$msg' at $filename line $line.";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$msg = "'$msg'";
|
|
||||||
}
|
|
||||||
my $builder = Test::More->builder;
|
|
||||||
$builder->ok( 0, "Test::FailWarnings should catch no warnings" )
|
|
||||||
or $builder->diag("Warning was $msg");
|
|
||||||
}
|
|
||||||
|
|
||||||
sub _find_source {
|
|
||||||
my $i = 1;
|
|
||||||
while (1) {
|
|
||||||
my ( $pkg, $filename, $line ) = caller( $i++ );
|
|
||||||
return caller( $i - 2 ) unless defined $pkg;
|
|
||||||
next if $pkg =~ /^(?:Carp|warnings)/;
|
|
||||||
return ( $pkg, $filename, $line );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
1;
|
|
||||||
|
|
||||||
|
|
||||||
# vim: ts=4 sts=4 sw=4 et:
|
|
||||||
|
|
||||||
__END__
|
|
||||||
|
|
||||||
=pod
|
|
||||||
|
|
||||||
=encoding utf-8
|
|
||||||
|
|
||||||
=head1 NAME
|
|
||||||
|
|
||||||
Test::FailWarnings - Add test failures if warnings are caught
|
|
||||||
|
|
||||||
=head1 VERSION
|
|
||||||
|
|
||||||
version 0.008
|
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
|
||||||
|
|
||||||
Test file:
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
use warnings;
|
|
||||||
use Test::More;
|
|
||||||
use Test::FailWarnings;
|
|
||||||
|
|
||||||
ok( 1, "first test" );
|
|
||||||
ok( 1 + "lkadjaks", "add non-numeric" );
|
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
||||||
Output:
|
|
||||||
|
|
||||||
ok 1 - first test
|
|
||||||
not ok 2 - Test::FailWarnings should catch no warnings
|
|
||||||
# Failed test 'Test::FailWarnings should catch no warnings'
|
|
||||||
# at t/bin/main-warn.pl line 7.
|
|
||||||
# Warning was 'Argument "lkadjaks" isn't numeric in addition (+) at t/bin/main-warn.pl line 7.'
|
|
||||||
ok 3 - add non-numeric
|
|
||||||
1..3
|
|
||||||
# Looks like you failed 1 test of 3.
|
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
|
||||||
|
|
||||||
This module hooks C<$SIG{__WARN__}> and converts warnings to L<Test::More>
|
|
||||||
C<fail()> calls. It is designed to be used with C<done_testing>, when you
|
|
||||||
don't need to know the test count in advance.
|
|
||||||
|
|
||||||
Just as with L<Test::NoWarnings>, this does not catch warnings if other things
|
|
||||||
localize C<$SIG{__WARN__}>, as this is designed to catch I<unhandled> warnings.
|
|
||||||
|
|
||||||
=for Pod::Coverage handler
|
|
||||||
|
|
||||||
=head1 USAGE
|
|
||||||
|
|
||||||
=head2 Overriding C<$SIG{__WARN__}>
|
|
||||||
|
|
||||||
On C<import>, C<$SIG{__WARN__}> is replaced with
|
|
||||||
C<Test::FailWarnings::handler>.
|
|
||||||
|
|
||||||
use Test::FailWarnings; # global
|
|
||||||
|
|
||||||
If you don't want global replacement, require the module instead and localize
|
|
||||||
in whatever scope you want.
|
|
||||||
|
|
||||||
require Test::FailWarnings;
|
|
||||||
|
|
||||||
{
|
|
||||||
local $SIG{__WARN__} = \&Test::FailWarnings::handler;
|
|
||||||
# ... warnings will issue fail() here
|
|
||||||
}
|
|
||||||
|
|
||||||
When the handler reports on the source of the warning, it will look past
|
|
||||||
any calling packages starting with C<Carp> or C<warnings> to try to detect
|
|
||||||
the real origin of the warning.
|
|
||||||
|
|
||||||
=head2 Allowing warnings from dependencies
|
|
||||||
|
|
||||||
If you want to ignore failures from outside your own code, you can set
|
|
||||||
C<$Test::FailWarnings::ALLOW_DEPS> to a true value. You can
|
|
||||||
do that on the C<use> line with C<< -allow_deps >>.
|
|
||||||
|
|
||||||
use Test::FailWarnings -allow_deps => 1;
|
|
||||||
|
|
||||||
When true, warnings will only be thrown if they appear to originate from a filename
|
|
||||||
matching C<< qr/^(?:t|xt|lib|blib)/ >>
|
|
||||||
|
|
||||||
=head2 Allowing warnings from specific modules
|
|
||||||
|
|
||||||
If you want to white-list specific modules only, you can add their package
|
|
||||||
names to C<@Test::NoWarnings::ALLOW_FROM>. You can do that on the C<use> line
|
|
||||||
with C<< -allow_from >>.
|
|
||||||
|
|
||||||
use Test::FailWarnings -allow_from => [ qw/Annoying::Module/ ];
|
|
||||||
|
|
||||||
=head1 SEE ALSO
|
|
||||||
|
|
||||||
=over 4
|
|
||||||
|
|
||||||
=item *
|
|
||||||
|
|
||||||
L<Test::NoWarnings> -- catches warnings and reports in an C<END> block. Not (yet) friendly with C<done_testing>.
|
|
||||||
|
|
||||||
=item *
|
|
||||||
|
|
||||||
L<Test::Warnings> -- a replacement for Test::NoWarnings that works with done_testing
|
|
||||||
|
|
||||||
=item *
|
|
||||||
|
|
||||||
L<Test::Warn> -- test for warnings without triggering failures from this modules
|
|
||||||
|
|
||||||
=back
|
|
||||||
|
|
||||||
=for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan
|
|
||||||
|
|
||||||
=head1 SUPPORT
|
|
||||||
|
|
||||||
=head2 Bugs / Feature Requests
|
|
||||||
|
|
||||||
Please report any bugs or feature requests through the issue tracker
|
|
||||||
at L<https://github.com/dagolden/Test-FailWarnings/issues>.
|
|
||||||
You will be notified automatically of any progress on your issue.
|
|
||||||
|
|
||||||
=head2 Source Code
|
|
||||||
|
|
||||||
This is open source software. The code repository is available for
|
|
||||||
public review and contribution under the terms of the license.
|
|
||||||
|
|
||||||
L<https://github.com/dagolden/Test-FailWarnings>
|
|
||||||
|
|
||||||
git clone https://github.com/dagolden/Test-FailWarnings.git
|
|
||||||
|
|
||||||
=head1 AUTHOR
|
|
||||||
|
|
||||||
David Golden <dagolden@cpan.org>
|
|
||||||
|
|
||||||
=head1 COPYRIGHT AND LICENSE
|
|
||||||
|
|
||||||
This software is Copyright (c) 2013 by David Golden.
|
|
||||||
|
|
||||||
This is free software, licensed under:
|
|
||||||
|
|
||||||
The Apache License, Version 2.0, January 2004
|
|
||||||
|
|
||||||
=cut
|
|
301
inc/Test/NoWarnings.pm
Normal file
301
inc/Test/NoWarnings.pm
Normal file
|
@ -0,0 +1,301 @@
|
||||||
|
package Test::NoWarnings;
|
||||||
|
|
||||||
|
use 5.006;
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Carp ();
|
||||||
|
use Exporter ();
|
||||||
|
use Test::Builder ();
|
||||||
|
use Test::NoWarnings::Warning ();
|
||||||
|
|
||||||
|
use vars qw( $VERSION @EXPORT_OK @ISA $do_end_test );
|
||||||
|
BEGIN {
|
||||||
|
$VERSION = '1.02';
|
||||||
|
@ISA = 'Exporter';
|
||||||
|
@EXPORT_OK = qw(
|
||||||
|
clear_warnings had_no_warnings warnings
|
||||||
|
);
|
||||||
|
|
||||||
|
# Do we add the warning test at the end?
|
||||||
|
$do_end_test = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $TEST = Test::Builder->new;
|
||||||
|
my $PID = $$;
|
||||||
|
my @WARNINGS = ();
|
||||||
|
|
||||||
|
$SIG{__WARN__} = make_catcher(\@WARNINGS);
|
||||||
|
|
||||||
|
sub import {
|
||||||
|
$do_end_test = 1;
|
||||||
|
goto &Exporter::import;
|
||||||
|
}
|
||||||
|
|
||||||
|
# the END block must be after the "use Test::Builder" to make sure it runs
|
||||||
|
# before Test::Builder's end block
|
||||||
|
# only run the test if there have been other tests
|
||||||
|
END {
|
||||||
|
had_no_warnings() if $do_end_test;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub make_warning {
|
||||||
|
local $SIG{__WARN__};
|
||||||
|
|
||||||
|
my $msg = shift;
|
||||||
|
my $warning = Test::NoWarnings::Warning->new;
|
||||||
|
|
||||||
|
$warning->setMessage($msg);
|
||||||
|
$warning->fillTest($TEST);
|
||||||
|
$warning->fillTrace(__PACKAGE__);
|
||||||
|
|
||||||
|
$Carp::Internal{__PACKAGE__.""}++;
|
||||||
|
local $Carp::CarpLevel = $Carp::CarpLevel + 1;
|
||||||
|
$warning->fillCarp($msg);
|
||||||
|
$Carp::Internal{__PACKAGE__.""}--;
|
||||||
|
|
||||||
|
return $warning;
|
||||||
|
}
|
||||||
|
|
||||||
|
# this make a subroutine which can be used in $SIG{__WARN__}
|
||||||
|
# it takes one argument, a ref to an array
|
||||||
|
# it will push the details of the warning onto the end of the array.
|
||||||
|
sub make_catcher {
|
||||||
|
my $array = shift;
|
||||||
|
|
||||||
|
return sub {
|
||||||
|
my $msg = shift;
|
||||||
|
|
||||||
|
$Carp::Internal{__PACKAGE__.""}++;
|
||||||
|
push(@$array, make_warning($msg));
|
||||||
|
$Carp::Internal{__PACKAGE__.""}--;
|
||||||
|
|
||||||
|
return $msg;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub had_no_warnings {
|
||||||
|
return 0 if $$ != $PID;
|
||||||
|
|
||||||
|
local $SIG{__WARN__};
|
||||||
|
my $name = shift || "no warnings";
|
||||||
|
|
||||||
|
my $ok;
|
||||||
|
my $diag;
|
||||||
|
if ( @WARNINGS == 0 ) {
|
||||||
|
$ok = 1;
|
||||||
|
} else {
|
||||||
|
$ok = 0;
|
||||||
|
$diag = "There were ".@WARNINGS." warning(s)\n";
|
||||||
|
$diag .= join "----------\n", map { $_->toString } @WARNINGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
$TEST->ok($ok, $name) || $TEST->diag($diag);
|
||||||
|
|
||||||
|
return $ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub clear_warnings {
|
||||||
|
local $SIG{__WARN__};
|
||||||
|
@WARNINGS = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
sub warnings {
|
||||||
|
local $SIG{__WARN__};
|
||||||
|
return @WARNINGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub builder {
|
||||||
|
local $SIG{__WARN__};
|
||||||
|
if ( @_ ) {
|
||||||
|
$TEST = shift;
|
||||||
|
}
|
||||||
|
return $TEST;
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
=pod
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
Test::NoWarnings - Make sure you didn't emit any warnings while testing
|
||||||
|
|
||||||
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
For scripts that have no plan
|
||||||
|
|
||||||
|
use Test::NoWarnings;
|
||||||
|
|
||||||
|
that's it, you don't need to do anything else
|
||||||
|
|
||||||
|
For scripts that look like
|
||||||
|
|
||||||
|
use Test::More tests => x;
|
||||||
|
|
||||||
|
change to
|
||||||
|
|
||||||
|
use Test::More tests => x + 1;
|
||||||
|
use Test::NoWarnings;
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
In general, your tests shouldn't produce warnings. This modules causes any
|
||||||
|
warnings to be captured and stored. It automatically adds an extra test that
|
||||||
|
will run when your script ends to check that there were no warnings. If
|
||||||
|
there were any warings, the test will give a "not ok" and diagnostics of
|
||||||
|
where, when and what the warning was, including a stack trace of what was
|
||||||
|
going on when the it occurred.
|
||||||
|
|
||||||
|
If some of your tests B<are supposed to> produce warnings then you should be
|
||||||
|
capturing and checking them with L<Test::Warn>, that way L<Test::NoWarnings>
|
||||||
|
will not see them and so not complain.
|
||||||
|
|
||||||
|
The test is run by an END block in Test::NoWarnings. It will not be run when
|
||||||
|
any forked children exit.
|
||||||
|
|
||||||
|
=head1 USAGE
|
||||||
|
|
||||||
|
Simply by using the module, you automatically get an extra test at the end
|
||||||
|
of your script that checks that no warnings were emitted. So just stick
|
||||||
|
|
||||||
|
use Test::NoWarnings
|
||||||
|
|
||||||
|
at the top of your script and continue as normal.
|
||||||
|
|
||||||
|
If you want more control you can invoke the test manually at any time with
|
||||||
|
C<had_no_warnings()>.
|
||||||
|
|
||||||
|
The warnings your test has generated so far are stored in an array. You can
|
||||||
|
look inside and clear this whenever you want with C<warnings()> and
|
||||||
|
C<clear_warnings()>, however, if you are doing this sort of thing then you
|
||||||
|
probably want to use L<Test::Warn> in combination with L<Test::NoWarnings>.
|
||||||
|
|
||||||
|
=head1 USE vs REQUIRE
|
||||||
|
|
||||||
|
You will almost always want to do
|
||||||
|
|
||||||
|
use Test::NoWarnings
|
||||||
|
|
||||||
|
If you do a C<require> rather than a C<use>, then there will be no automatic
|
||||||
|
test at the end of your script.
|
||||||
|
|
||||||
|
=head1 OUTPUT
|
||||||
|
|
||||||
|
If warning is captured during your test then the details will output as part
|
||||||
|
of the diagnostics. You will get:
|
||||||
|
|
||||||
|
=over 2
|
||||||
|
|
||||||
|
=item o
|
||||||
|
|
||||||
|
the number and name of the test that was executed just before the warning
|
||||||
|
(if no test had been executed these will be 0 and '')
|
||||||
|
|
||||||
|
=item o
|
||||||
|
|
||||||
|
the message passed to C<warn>,
|
||||||
|
|
||||||
|
=item o
|
||||||
|
|
||||||
|
a full dump of the stack when warn was called, courtesy of the C<Carp>
|
||||||
|
module
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
=head1 EXPORTABLE FUNCTIONS
|
||||||
|
|
||||||
|
=head2 had_no_warnings
|
||||||
|
|
||||||
|
This checks that there have been warnings emitted by your test scripts.
|
||||||
|
Usually you will not call this explicitly as it is called automatically when
|
||||||
|
your script finishes.
|
||||||
|
|
||||||
|
=head2 clear_warnings
|
||||||
|
|
||||||
|
This will clear the array of warnings that have been captured. If the array
|
||||||
|
is empty then a call to C<had_no_warnings()> will produce a pass result.
|
||||||
|
|
||||||
|
=head2 warnings
|
||||||
|
|
||||||
|
This will return the array of warnings captured so far. Each element of this
|
||||||
|
array is an object containing information about the warning. The following
|
||||||
|
methods are available on these object.
|
||||||
|
|
||||||
|
=over 2
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
$warn-E<gt>getMessage
|
||||||
|
|
||||||
|
Get the message that would been printed by the warning.
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
$warn-E<gt>getCarp
|
||||||
|
|
||||||
|
Get a stack trace of what was going on when the warning happened, this stack
|
||||||
|
trace is just a string generated by the L<Carp> module.
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
$warn-E<gt>getTrace
|
||||||
|
|
||||||
|
Get a stack trace object generated by the L<Devel::StackTrace> module. This
|
||||||
|
will return undef if L<Devel::StackTrace> is not installed.
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
$warn-E<gt>getTest
|
||||||
|
|
||||||
|
Get the number of the test that executed before the warning was emitted.
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
$warn-E<gt>getTestName
|
||||||
|
|
||||||
|
Get the name of the test that executed before the warning was emitted.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
=head1 PITFALLS
|
||||||
|
|
||||||
|
When counting your tests for the plan, don't forget to include the test that
|
||||||
|
runs automatically when your script ends.
|
||||||
|
|
||||||
|
=head1 SUPPORT
|
||||||
|
|
||||||
|
Bugs should be reported via the CPAN bug tracker at
|
||||||
|
|
||||||
|
L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Test-NoWarnings>
|
||||||
|
|
||||||
|
For other issues, contact the author.
|
||||||
|
|
||||||
|
=head1 HISTORY
|
||||||
|
|
||||||
|
This was previously known as L<Test::Warn::None>
|
||||||
|
|
||||||
|
=head1 SEE ALSO
|
||||||
|
|
||||||
|
L<Test::Builder>, L<Test::Warn>
|
||||||
|
|
||||||
|
=head1 AUTHORS
|
||||||
|
|
||||||
|
Fergal Daly E<lt>fergal@esatclear.ieE<gt>
|
||||||
|
|
||||||
|
Adam Kennedy E<lt>adamk@cpan.orgE<gt>
|
||||||
|
|
||||||
|
=head1 COPYRIGHT
|
||||||
|
|
||||||
|
Copyright 2003 - 2007 Fergal Daly.
|
||||||
|
|
||||||
|
Some parts copyright 2010 Adam Kennedy.
|
||||||
|
|
||||||
|
This program is free software and comes with no warranty. It is distributed
|
||||||
|
under the LGPL license
|
||||||
|
|
||||||
|
See the file F<LGPL> included in this distribution or
|
||||||
|
F<http://www.fsf.org/licenses/licenses.html>.
|
||||||
|
|
||||||
|
=cut
|
78
inc/Test/NoWarnings/Warning.pm
Normal file
78
inc/Test/NoWarnings/Warning.pm
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
package Test::NoWarnings::Warning;
|
||||||
|
|
||||||
|
use 5.006;
|
||||||
|
use strict;
|
||||||
|
use Carp ();
|
||||||
|
|
||||||
|
use vars qw{$VERSION};
|
||||||
|
BEGIN {
|
||||||
|
$VERSION = '1.02';
|
||||||
|
|
||||||
|
# Optional stacktrace support
|
||||||
|
eval "require Devel::StackTrace";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub new {
|
||||||
|
my $class = shift;
|
||||||
|
bless { @_ }, $class;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub getTrace {
|
||||||
|
$_[0]->{Trace};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub fillTrace {
|
||||||
|
my $self = shift;
|
||||||
|
$self->{Trace} = Devel::StackTrace->new(
|
||||||
|
ignore_class => [__PACKAGE__, @_],
|
||||||
|
) if $Devel::StackTrace::VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub getCarp {
|
||||||
|
$_[0]->{Carp};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub fillCarp {
|
||||||
|
my $self = shift;
|
||||||
|
my $msg = shift;
|
||||||
|
$Carp::Internal{ __PACKAGE__ . "" }++;
|
||||||
|
local $Carp::CarpLevel = $Carp::CarpLevel + 1;
|
||||||
|
$self->{Carp} = Carp::longmess($msg);
|
||||||
|
$Carp::Internal{ __PACKAGE__ . "" }--;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub getMessage {
|
||||||
|
$_[0]->{Message};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub setMessage {
|
||||||
|
$_[0]->{Message} = $_[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
sub fillTest {
|
||||||
|
my $self = shift;
|
||||||
|
my $builder = shift;
|
||||||
|
my $prev_test = $builder->current_test;
|
||||||
|
$self->{Test} = $prev_test;
|
||||||
|
my @tests = $builder->details;
|
||||||
|
my $prev_test_name = $prev_test ? $tests[$prev_test - 1]->{name} : "";
|
||||||
|
$self->{TestName} = $prev_test_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub getTest {
|
||||||
|
$_[0]->{Test};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub getTestName {
|
||||||
|
$_[0]->{TestName};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub toString {
|
||||||
|
my $self = shift;
|
||||||
|
return <<EOM;
|
||||||
|
Previous test $self->{Test} '$self->{TestName}'
|
||||||
|
$self->{Carp}
|
||||||
|
EOM
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
|
@ -3,9 +3,10 @@ package DBD::SQLite;
|
||||||
use 5.006;
|
use 5.006;
|
||||||
use strict;
|
use strict;
|
||||||
use DBI 1.57 ();
|
use DBI 1.57 ();
|
||||||
use XSLoader ();
|
use DynaLoader ();
|
||||||
|
|
||||||
our $VERSION = '1.76';
|
our $VERSION = '1.55_07';
|
||||||
|
our @ISA = 'DynaLoader';
|
||||||
|
|
||||||
# sqlite_version cache (set in the XS bootstrap)
|
# sqlite_version cache (set in the XS bootstrap)
|
||||||
our ($sqlite_version, $sqlite_version_number);
|
our ($sqlite_version, $sqlite_version_number);
|
||||||
|
@ -13,7 +14,7 @@ our ($sqlite_version, $sqlite_version_number);
|
||||||
# not sure if we still need these...
|
# not sure if we still need these...
|
||||||
our ($err, $errstr);
|
our ($err, $errstr);
|
||||||
|
|
||||||
XSLoader::load('DBD::SQLite', $VERSION);
|
__PACKAGE__->bootstrap($VERSION);
|
||||||
|
|
||||||
# New or old API?
|
# New or old API?
|
||||||
use constant NEWAPI => ($DBI::VERSION >= 1.608);
|
use constant NEWAPI => ($DBI::VERSION >= 1.608);
|
||||||
|
@ -46,8 +47,6 @@ sub driver {
|
||||||
DBD::SQLite::db->install_method('sqlite_set_authorizer');
|
DBD::SQLite::db->install_method('sqlite_set_authorizer');
|
||||||
DBD::SQLite::db->install_method('sqlite_backup_from_file');
|
DBD::SQLite::db->install_method('sqlite_backup_from_file');
|
||||||
DBD::SQLite::db->install_method('sqlite_backup_to_file');
|
DBD::SQLite::db->install_method('sqlite_backup_to_file');
|
||||||
DBD::SQLite::db->install_method('sqlite_backup_from_dbh');
|
|
||||||
DBD::SQLite::db->install_method('sqlite_backup_to_dbh');
|
|
||||||
DBD::SQLite::db->install_method('sqlite_enable_load_extension');
|
DBD::SQLite::db->install_method('sqlite_enable_load_extension');
|
||||||
DBD::SQLite::db->install_method('sqlite_load_extension');
|
DBD::SQLite::db->install_method('sqlite_load_extension');
|
||||||
DBD::SQLite::db->install_method('sqlite_register_fts3_perl_tokenizer');
|
DBD::SQLite::db->install_method('sqlite_register_fts3_perl_tokenizer');
|
||||||
|
@ -58,11 +57,6 @@ sub driver {
|
||||||
DBD::SQLite::db->install_method('sqlite_db_status', { O => 0x0004 });
|
DBD::SQLite::db->install_method('sqlite_db_status', { O => 0x0004 });
|
||||||
DBD::SQLite::st->install_method('sqlite_st_status', { O => 0x0004 });
|
DBD::SQLite::st->install_method('sqlite_st_status', { O => 0x0004 });
|
||||||
DBD::SQLite::db->install_method('sqlite_create_module');
|
DBD::SQLite::db->install_method('sqlite_create_module');
|
||||||
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++;
|
$methods_are_installed++;
|
||||||
}
|
}
|
||||||
|
@ -186,7 +180,7 @@ sub install_collation {
|
||||||
|
|
||||||
# default implementation for sqlite 'REGEXP' infix operator.
|
# default implementation for sqlite 'REGEXP' infix operator.
|
||||||
# Note : args are reversed, i.e. "a REGEXP b" calls REGEXP(b, a)
|
# Note : args are reversed, i.e. "a REGEXP b" calls REGEXP(b, a)
|
||||||
# (see https://www.sqlite.org/vtab.html#xfindfunction)
|
# (see http://www.sqlite.org/vtab.html#xfindfunction)
|
||||||
sub regexp {
|
sub regexp {
|
||||||
use locale;
|
use locale;
|
||||||
return if !defined $_[0] || !defined $_[1];
|
return if !defined $_[0] || !defined $_[1];
|
||||||
|
@ -196,8 +190,6 @@ sub regexp {
|
||||||
package # hide from PAUSE
|
package # hide from PAUSE
|
||||||
DBD::SQLite::db;
|
DBD::SQLite::db;
|
||||||
|
|
||||||
use DBI qw/:sql_types/;
|
|
||||||
|
|
||||||
sub prepare {
|
sub prepare {
|
||||||
my $dbh = shift;
|
my $dbh = shift;
|
||||||
my $sql = shift;
|
my $sql = shift;
|
||||||
|
@ -253,26 +245,19 @@ sub ping {
|
||||||
return $dbh->FETCH('Active') ? 1 : 0;
|
return $dbh->FETCH('Active') ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub quote {
|
sub _get_version {
|
||||||
my ($self, $value, $data_type) = @_;
|
return ( DBD::SQLite::db::FETCH($_[0], 'sqlite_version') );
|
||||||
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)) {
|
|
||||||
return q(X') . unpack('H*', $value) . q(');
|
|
||||||
}
|
|
||||||
$value =~ s/'/''/g;
|
|
||||||
return "'$value'";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub get_info {
|
my %info = (
|
||||||
my ($dbh, $info_type) = @_;
|
17 => 'SQLite', # SQL_DBMS_NAME
|
||||||
|
18 => \&_get_version, # SQL_DBMS_VER
|
||||||
|
29 => '"', # SQL_IDENTIFIER_QUOTE_CHAR
|
||||||
|
);
|
||||||
|
|
||||||
require DBD::SQLite::GetInfo;
|
sub get_info {
|
||||||
my $v = $DBD::SQLite::GetInfo::info{int($info_type)};
|
my($dbh, $info_type) = @_;
|
||||||
|
my $v = $info{int($info_type)};
|
||||||
$v = $v->($dbh) if ref $v eq 'CODE';
|
$v = $v->($dbh) if ref $v eq 'CODE';
|
||||||
return $v;
|
return $v;
|
||||||
}
|
}
|
||||||
|
@ -568,15 +553,6 @@ my @FOREIGN_KEY_INFO_SQL_CLI = qw(
|
||||||
UNIQUE_OR_PRIMARY
|
UNIQUE_OR_PRIMARY
|
||||||
);
|
);
|
||||||
|
|
||||||
my $DEFERRABLE_RE = qr/
|
|
||||||
(?:(?:
|
|
||||||
on \s+ (?:delete|update) \s+ (?:set \s+ null|set \s+ default|cascade|restrict|no \s+ action)
|
|
||||||
|
|
|
||||||
match \s* (?:\S+|".+?(?<!")")
|
|
||||||
) \s*)*
|
|
||||||
((?:not)? \s* deferrable (?: \s* initially \s* (?: immediate | deferred))?)?
|
|
||||||
/sxi;
|
|
||||||
|
|
||||||
sub foreign_key_info {
|
sub foreign_key_info {
|
||||||
my ($dbh, $pk_catalog, $pk_schema, $pk_table, $fk_catalog, $fk_schema, $fk_table) = @_;
|
my ($dbh, $pk_catalog, $pk_schema, $pk_table, $fk_catalog, $fk_schema, $fk_table) = @_;
|
||||||
|
|
||||||
|
@ -594,11 +570,9 @@ sub foreign_key_info {
|
||||||
($dbname eq 'temp') ? 'sqlite_temp_master' :
|
($dbname eq 'temp') ? 'sqlite_temp_master' :
|
||||||
$quoted_dbname.'.sqlite_master';
|
$quoted_dbname.'.sqlite_master';
|
||||||
|
|
||||||
my $tables = $dbh->selectall_arrayref("SELECT name, sql FROM $master_table WHERE type = ?", undef, "table") or return;
|
my $tables = $dbh->selectall_arrayref("SELECT name FROM $master_table WHERE type = ?", undef, "table") or return;
|
||||||
for my $table (@$tables) {
|
for my $table (@$tables) {
|
||||||
my $tbname = $table->[0];
|
my $tbname = $table->[0];
|
||||||
my $ddl = $table->[1];
|
|
||||||
my (@rels, %relid2rels);
|
|
||||||
next if defined $fk_table && $fk_table ne '%' && $fk_table ne $tbname;
|
next if defined $fk_table && $fk_table ne '%' && $fk_table ne $tbname;
|
||||||
|
|
||||||
my $quoted_tbname = $dbh->quote_identifier($tbname);
|
my $quoted_tbname = $dbh->quote_identifier($tbname);
|
||||||
|
@ -629,17 +603,7 @@ sub foreign_key_info {
|
||||||
|
|
||||||
next if defined $pk_schema && $pk_schema ne '%' && $pk_schema ne $table_info{$row->{table}}{schema};
|
next if defined $pk_schema && $pk_schema ne '%' && $pk_schema ne $table_info{$row->{table}}{schema};
|
||||||
|
|
||||||
# cribbed from DBIx::Class::Schema::Loader::DBI::SQLite
|
push @fk_info, {
|
||||||
my $rel = $rels[ $row->{id} ] ||= {
|
|
||||||
local_columns => [],
|
|
||||||
remote_columns => undef,
|
|
||||||
remote_table => $row->{table},
|
|
||||||
};
|
|
||||||
push @{ $rel->{local_columns} }, $row->{from};
|
|
||||||
push @{ $rel->{remote_columns} }, $row->{to}
|
|
||||||
if defined $row->{to};
|
|
||||||
|
|
||||||
my $fk_row = {
|
|
||||||
PKTABLE_CAT => undef,
|
PKTABLE_CAT => undef,
|
||||||
PKTABLE_SCHEM => $table_info{$row->{table}}{schema},
|
PKTABLE_SCHEM => $table_info{$row->{table}}{schema},
|
||||||
PKTABLE_NAME => $row->{table},
|
PKTABLE_NAME => $row->{table},
|
||||||
|
@ -656,44 +620,6 @@ sub foreign_key_info {
|
||||||
DEFERRABILITY => undef,
|
DEFERRABILITY => undef,
|
||||||
UNIQUE_OR_PRIMARY => $table_info{$row->{table}}{columns}{$row->{to}} ? 'PRIMARY' : 'UNIQUE',
|
UNIQUE_OR_PRIMARY => $table_info{$row->{table}}{columns}{$row->{to}} ? 'PRIMARY' : 'UNIQUE',
|
||||||
};
|
};
|
||||||
push @fk_info, $fk_row;
|
|
||||||
push @{ $relid2rels{$row->{id}} }, $fk_row; # keep so can fixup
|
|
||||||
}
|
|
||||||
|
|
||||||
# cribbed from DBIx::Class::Schema::Loader::DBI::SQLite
|
|
||||||
# but with additional parsing of which kind of deferrable
|
|
||||||
REL: for my $relid (keys %relid2rels) {
|
|
||||||
my $rel = $rels[$relid];
|
|
||||||
my $deferrable = $DBI_code_for_rule{'NOT DEFERRABLE'};
|
|
||||||
my $local_cols = '"?' . (join '"? \s* , \s* "?', map quotemeta, @{ $rel->{local_columns} }) . '"?';
|
|
||||||
my $remote_cols = '"?' . (join '"? \s* , \s* "?', map quotemeta, @{ $rel->{remote_columns} || [] }) . '"?';
|
|
||||||
my ($deferrable_clause) = $ddl =~ /
|
|
||||||
foreign \s+ key \s* \( \s* $local_cols \s* \) \s* references \s* (?:\S+|".+?(?<!")") \s*
|
|
||||||
(?:\( \s* $remote_cols \s* \) \s*)?
|
|
||||||
$DEFERRABLE_RE
|
|
||||||
/sxi;
|
|
||||||
if (!$deferrable_clause) {
|
|
||||||
# check for inline constraint if 1 local column
|
|
||||||
if (@{ $rel->{local_columns} } == 1) {
|
|
||||||
my ($local_col) = @{ $rel->{local_columns} };
|
|
||||||
my ($remote_col) = @{ $rel->{remote_columns} || [] };
|
|
||||||
$remote_col ||= '';
|
|
||||||
($deferrable_clause) = $ddl =~ /
|
|
||||||
"?\Q$local_col\E"? \s* (?:\w+\s*)* (?: \( \s* \d\+ (?:\s*,\s*\d+)* \s* \) )? \s*
|
|
||||||
references \s+ (?:\S+|".+?(?<!")") (?:\s* \( \s* "?\Q$remote_col\E"? \s* \))? \s*
|
|
||||||
$DEFERRABLE_RE
|
|
||||||
/sxi;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($deferrable_clause) {
|
|
||||||
# default is already NOT
|
|
||||||
if ($deferrable_clause !~ /not/i) {
|
|
||||||
$deferrable = $deferrable_clause =~ /deferred/i
|
|
||||||
? $DBI_code_for_rule{'INITIALLY DEFERRED'}
|
|
||||||
: $DBI_code_for_rule{'INITIALLY IMMEDIATE'};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$_->{DEFERRABILITY} = $deferrable for @{ $relid2rels{$relid} };
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -768,7 +694,7 @@ sub statistics_info {
|
||||||
NON_UNIQUE => $row->{unique} ? 0 : 1,
|
NON_UNIQUE => $row->{unique} ? 0 : 1,
|
||||||
INDEX_QUALIFIER => undef,
|
INDEX_QUALIFIER => undef,
|
||||||
INDEX_NAME => $row->{name},
|
INDEX_NAME => $row->{name},
|
||||||
TYPE => 'btree', # see https://www.sqlite.org/version3.html esp. "Traditional B-trees are still used for indices"
|
TYPE => 'btree', # see http://www.sqlite.org/version3.html esp. "Traditional B-trees are still used for indices"
|
||||||
ORDINAL_POSITION => $info->{seqno} + 1,
|
ORDINAL_POSITION => $info->{seqno} + 1,
|
||||||
COLUMN_NAME => $info->{name},
|
COLUMN_NAME => $info->{name},
|
||||||
ASC_OR_DESC => undef,
|
ASC_OR_DESC => undef,
|
||||||
|
@ -795,68 +721,45 @@ sub statistics_info {
|
||||||
return $sponge_sth;
|
return $sponge_sth;
|
||||||
}
|
}
|
||||||
|
|
||||||
my @TypeInfoKeys = qw/
|
|
||||||
TYPE_NAME
|
|
||||||
DATA_TYPE
|
|
||||||
COLUMN_SIZE
|
|
||||||
LITERAL_PREFIX
|
|
||||||
LITERAL_SUFFIX
|
|
||||||
CREATE_PARAMS
|
|
||||||
NULLABLE
|
|
||||||
CASE_SENSITIVE
|
|
||||||
SEARCHABLE
|
|
||||||
UNSIGNED_ATTRIBUTE
|
|
||||||
FIXED_PREC_SCALE
|
|
||||||
AUTO_UNIQUE_VALUE
|
|
||||||
LOCAL_TYPE_NAME
|
|
||||||
MINIMUM_SCALE
|
|
||||||
MAXIMUM_SCALE
|
|
||||||
SQL_DATA_TYPE
|
|
||||||
SQL_DATETIME_SUB
|
|
||||||
NUM_PREC_RADIX
|
|
||||||
INTERVAL_PRECISION
|
|
||||||
/;
|
|
||||||
|
|
||||||
my %TypeInfo = (
|
|
||||||
SQL_INTEGER ,=> {
|
|
||||||
TYPE_NAME => 'INTEGER',
|
|
||||||
DATA_TYPE => SQL_INTEGER,
|
|
||||||
NULLABLE => 2, # no for integer primary key, otherwise yes
|
|
||||||
SEARCHABLE => 3,
|
|
||||||
},
|
|
||||||
SQL_DOUBLE ,=> {
|
|
||||||
TYPE_NAME => 'REAL',
|
|
||||||
DATA_TYPE => SQL_DOUBLE,
|
|
||||||
NULLABLE => 1,
|
|
||||||
SEARCHABLE => 3,
|
|
||||||
},
|
|
||||||
SQL_VARCHAR ,=> {
|
|
||||||
TYPE_NAME => 'TEXT',
|
|
||||||
DATA_TYPE => SQL_VARCHAR,
|
|
||||||
LITERAL_PREFIX => "'",
|
|
||||||
LITERAL_SUFFIX => "'",
|
|
||||||
NULLABLE => 1,
|
|
||||||
SEARCHABLE => 3,
|
|
||||||
},
|
|
||||||
SQL_BLOB ,=> {
|
|
||||||
TYPE_NAME => 'BLOB',
|
|
||||||
DATA_TYPE => SQL_BLOB,
|
|
||||||
NULLABLE => 1,
|
|
||||||
SEARCHABLE => 3,
|
|
||||||
},
|
|
||||||
SQL_UNKNOWN_TYPE ,=> {
|
|
||||||
DATA_TYPE => SQL_UNKNOWN_TYPE,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
sub type_info_all {
|
sub type_info_all {
|
||||||
my $idx = 0;
|
return; # XXX code just copied from DBD::Oracle, not yet thought about
|
||||||
|
# return [
|
||||||
my @info = ({map {$_ => $idx++} @TypeInfoKeys});
|
# {
|
||||||
for my $id (sort {$a <=> $b} keys %TypeInfo) {
|
# TYPE_NAME => 0,
|
||||||
push @info, [map {$TypeInfo{$id}{$_}} @TypeInfoKeys];
|
# DATA_TYPE => 1,
|
||||||
}
|
# COLUMN_SIZE => 2,
|
||||||
return \@info;
|
# LITERAL_PREFIX => 3,
|
||||||
|
# LITERAL_SUFFIX => 4,
|
||||||
|
# CREATE_PARAMS => 5,
|
||||||
|
# NULLABLE => 6,
|
||||||
|
# CASE_SENSITIVE => 7,
|
||||||
|
# SEARCHABLE => 8,
|
||||||
|
# UNSIGNED_ATTRIBUTE => 9,
|
||||||
|
# FIXED_PREC_SCALE => 10,
|
||||||
|
# AUTO_UNIQUE_VALUE => 11,
|
||||||
|
# LOCAL_TYPE_NAME => 12,
|
||||||
|
# MINIMUM_SCALE => 13,
|
||||||
|
# MAXIMUM_SCALE => 14,
|
||||||
|
# SQL_DATA_TYPE => 15,
|
||||||
|
# SQL_DATETIME_SUB => 16,
|
||||||
|
# NUM_PREC_RADIX => 17,
|
||||||
|
# },
|
||||||
|
# [ 'CHAR', 1, 255, '\'', '\'', 'max length', 1, 1, 3,
|
||||||
|
# undef, '0', '0', undef, undef, undef, 1, undef, undef
|
||||||
|
# ],
|
||||||
|
# [ 'NUMBER', 3, 38, undef, undef, 'precision,scale', 1, '0', 3,
|
||||||
|
# '0', '0', '0', undef, '0', 38, 3, undef, 10
|
||||||
|
# ],
|
||||||
|
# [ 'DOUBLE', 8, 15, undef, undef, undef, 1, '0', 3,
|
||||||
|
# '0', '0', '0', undef, undef, undef, 8, undef, 10
|
||||||
|
# ],
|
||||||
|
# [ 'DATE', 9, 19, '\'', '\'', undef, 1, '0', 3,
|
||||||
|
# undef, '0', '0', undef, '0', '0', 11, undef, undef
|
||||||
|
# ],
|
||||||
|
# [ 'VARCHAR', 12, 1024*1024, '\'', '\'', 'max length', 1, 1, 3,
|
||||||
|
# undef, '0', '0', undef, undef, undef, 12, undef, undef
|
||||||
|
# ]
|
||||||
|
# ];
|
||||||
}
|
}
|
||||||
|
|
||||||
my @COLUMN_INFO = qw(
|
my @COLUMN_INFO = qw(
|
||||||
|
@ -1033,7 +936,7 @@ DBD::SQLite - Self-contained RDBMS in a DBI Driver
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
SQLite is a public domain file-based relational database engine that
|
SQLite is a public domain file-based relational database engine that
|
||||||
you can find at L<https://www.sqlite.org/>.
|
you can find at L<http://www.sqlite.org/>.
|
||||||
|
|
||||||
B<DBD::SQLite> is a Perl DBI driver for SQLite, that includes
|
B<DBD::SQLite> is a Perl DBI driver for SQLite, that includes
|
||||||
the entire thing in the distribution.
|
the entire thing in the distribution.
|
||||||
|
@ -1047,7 +950,7 @@ SQLite supports the following features:
|
||||||
|
|
||||||
=item Implements a large subset of SQL92
|
=item Implements a large subset of SQL92
|
||||||
|
|
||||||
See L<https://www.sqlite.org/lang.html> for details.
|
See L<http://www.sqlite.org/lang.html> for details.
|
||||||
|
|
||||||
=item A complete DB in a single disk file
|
=item A complete DB in a single disk file
|
||||||
|
|
||||||
|
@ -1074,7 +977,7 @@ are limited by the typeless nature of the SQLite database.
|
||||||
=head1 SQLITE VERSION
|
=head1 SQLITE VERSION
|
||||||
|
|
||||||
DBD::SQLite is usually compiled with a bundled SQLite library
|
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.22.0> as of this release) for consistency.
|
||||||
However, a different version of SQLite may sometimes be used for
|
However, a different version of SQLite may sometimes be used for
|
||||||
some reasons like security, or some new experimental features.
|
some reasons like security, or some new experimental features.
|
||||||
|
|
||||||
|
@ -1118,7 +1021,7 @@ If the filename C<$dbfile> is an empty string, then a private,
|
||||||
temporary on-disk database will be created. This private database will
|
temporary on-disk database will be created. This private database will
|
||||||
be automatically deleted as soon as the database connection is closed.
|
be automatically deleted as soon as the database connection is closed.
|
||||||
|
|
||||||
As of 1.41_01, you can pass URI filename (see L<https://www.sqlite.org/uri.html>)
|
As of 1.41_01, you can pass URI filename (see L<http://www.sqlite.org/uri.html>)
|
||||||
as well for finer control:
|
as well for finer control:
|
||||||
|
|
||||||
my $dbh = DBI->connect("dbi:SQLite:uri=file:$path_to_dbfile?mode=rwc");
|
my $dbh = DBI->connect("dbi:SQLite:uri=file:$path_to_dbfile?mode=rwc");
|
||||||
|
@ -1135,7 +1038,7 @@ You can set sqlite_open_flags (only) when you connect to a database:
|
||||||
sqlite_open_flags => SQLITE_OPEN_READONLY,
|
sqlite_open_flags => SQLITE_OPEN_READONLY,
|
||||||
});
|
});
|
||||||
|
|
||||||
See L<https://www.sqlite.org/c3ref/open.html> for details.
|
See L<http://www.sqlite.org/c3ref/open.html> for details.
|
||||||
|
|
||||||
As of 1.49_05, you can also make a database read-only by setting
|
As of 1.49_05, you can also make a database read-only by setting
|
||||||
C<ReadOnly> attribute to true (only) when you connect to a database.
|
C<ReadOnly> attribute to true (only) when you connect to a database.
|
||||||
|
@ -1253,7 +1156,7 @@ like this while executing:
|
||||||
|
|
||||||
SELECT bar FROM foo GROUP BY bar HAVING count(*) > "5";
|
SELECT bar FROM foo GROUP BY bar HAVING count(*) > "5";
|
||||||
|
|
||||||
There are four workarounds for this.
|
There are three workarounds for this.
|
||||||
|
|
||||||
=over 4
|
=over 4
|
||||||
|
|
||||||
|
@ -1279,15 +1182,6 @@ This is somewhat weird, but works anyway.
|
||||||
});
|
});
|
||||||
$sth->execute(5);
|
$sth->execute(5);
|
||||||
|
|
||||||
=item Use SQL cast() function
|
|
||||||
|
|
||||||
This is more explicit way to do the above.
|
|
||||||
|
|
||||||
my $sth = $dbh->prepare(q{
|
|
||||||
SELECT bar FROM foo GROUP BY bar HAVING count(*) > cast(? as integer);
|
|
||||||
});
|
|
||||||
$sth->execute(5);
|
|
||||||
|
|
||||||
=item Set C<sqlite_see_if_its_a_number> database handle attribute
|
=item Set C<sqlite_see_if_its_a_number> database handle attribute
|
||||||
|
|
||||||
As of version 1.32_02, you can use C<sqlite_see_if_its_a_number>
|
As of version 1.32_02, you can use C<sqlite_see_if_its_a_number>
|
||||||
|
@ -1336,7 +1230,7 @@ SQLite supports several placeholder expressions, including C<?>
|
||||||
and C<:AAAA>. Consult the L<DBI> and SQLite documentation for
|
and C<:AAAA>. Consult the L<DBI> and SQLite documentation for
|
||||||
details.
|
details.
|
||||||
|
|
||||||
L<https://www.sqlite.org/lang_expr.html#varparam>
|
L<http://www.sqlite.org/lang_expr.html#varparam>
|
||||||
|
|
||||||
Note that a question mark actually means a next unused (numbered)
|
Note that a question mark actually means a next unused (numbered)
|
||||||
placeholder. You're advised not to use it with other (numbered or
|
placeholder. You're advised not to use it with other (numbered or
|
||||||
|
@ -1406,7 +1300,7 @@ in the worst case. See also L</"Performance"> section below.
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
See L<https://www.sqlite.org/pragma.html> for more details.
|
See L<http://www.sqlite.org/pragma.html> for more details.
|
||||||
|
|
||||||
=head2 Foreign Keys
|
=head2 Foreign Keys
|
||||||
|
|
||||||
|
@ -1434,7 +1328,7 @@ SQLite, be prepared, and please do extensive testing to ensure
|
||||||
that your applications will continue to work when the foreign keys
|
that your applications will continue to work when the foreign keys
|
||||||
support is enabled by default.
|
support is enabled by default.
|
||||||
|
|
||||||
See L<https://www.sqlite.org/foreignkeys.html> for details.
|
See L<http://www.sqlite.org/foreignkeys.html> for details.
|
||||||
|
|
||||||
=head2 Transactions
|
=head2 Transactions
|
||||||
|
|
||||||
|
@ -1488,7 +1382,7 @@ automatically begin if you execute another statement.
|
||||||
|
|
||||||
This C<AutoCommit> mode is independent from the autocommit mode
|
This C<AutoCommit> mode is independent from the autocommit mode
|
||||||
of the internal SQLite library, which always begins by a C<BEGIN>
|
of the internal SQLite library, which always begins by a C<BEGIN>
|
||||||
statement, and ends by a C<COMMIT> or a C<ROLLBACK>.
|
statement, and ends by a C<COMMIT> or a <ROLLBACK>.
|
||||||
|
|
||||||
=head2 Transaction and Database Locking
|
=head2 Transaction and Database Locking
|
||||||
|
|
||||||
|
@ -1557,22 +1451,9 @@ of the rest (since 1.30_01, and without creating DBI's statement
|
||||||
handles internally since 1.47_01). If you do need to use C<prepare>
|
handles internally since 1.47_01). If you do need to use C<prepare>
|
||||||
or C<prepare_cached> (which I don't recommend in this case, because
|
or C<prepare_cached> (which I don't recommend in this case, because
|
||||||
typically there's no placeholder nor reusable part in a dump),
|
typically there's no placeholder nor reusable part in a dump),
|
||||||
you can look at C<< $sth->{sqlite_unprepared_statements} >> to retrieve
|
you can look at << $sth->{sqlite_unprepared_statements} >> to retrieve
|
||||||
what's left, though it usually contains nothing but white spaces.
|
what's left, though it usually contains nothing but white spaces.
|
||||||
|
|
||||||
=head2 TYPE statement attribute
|
|
||||||
|
|
||||||
Because of historical reasons, DBD::SQLite's C<TYPE> statement
|
|
||||||
handle attribute returns an array ref of string values, contrary to
|
|
||||||
the DBI specification. This value is also less useful for SQLite
|
|
||||||
users because SQLite uses dynamic type system (that means,
|
|
||||||
the datatype of a value is associated with the value itself, not
|
|
||||||
with its container).
|
|
||||||
|
|
||||||
As of version 1.61_02, if you set C<sqlite_prefer_numeric_type>
|
|
||||||
database handle attribute to true, C<TYPE> statement handle
|
|
||||||
attribute returns an array of integer, as an experiment.
|
|
||||||
|
|
||||||
=head2 Performance
|
=head2 Performance
|
||||||
|
|
||||||
SQLite is fast, very fast. Matt processed his 72MB log file with it,
|
SQLite is fast, very fast. Matt processed his 72MB log file with it,
|
||||||
|
@ -1621,42 +1502,24 @@ Your sweet spot probably lies somewhere in between.
|
||||||
=item sqlite_version
|
=item sqlite_version
|
||||||
|
|
||||||
Returns the version of the SQLite library which B<DBD::SQLite> is using,
|
Returns the version of the SQLite library which B<DBD::SQLite> is using,
|
||||||
e.g., "3.26.0". Can only be read.
|
e.g., "2.8.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
|
If set to a true value, B<DBD::SQLite> will turn the UTF-8 flag on for all
|
||||||
arbitrary Unicode code point. Thus, DBD::SQLite has to adopt some method
|
text strings coming out of the database (this feature is currently disabled
|
||||||
of translating between those two models. This parameter defines that
|
for perl < 5.8.5). For more details on the UTF-8 flag see
|
||||||
translation.
|
L<perlunicode>. The default is for the UTF-8 flag to be turned off.
|
||||||
|
|
||||||
Accepted values are the following constants:
|
Also note that due to some bizarreness in SQLite's type system (see
|
||||||
|
L<http://www.sqlite.org/datatype3.html>), if you want to retain
|
||||||
=over
|
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
|
||||||
=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
|
|
||||||
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
|
|
||||||
explicitly using the 3-argument form of L<DBI/bind_param> when doing
|
explicitly using the 3-argument form of L<DBI/bind_param> when doing
|
||||||
updates:
|
updates:
|
||||||
|
|
||||||
use DBI qw(:sql_types);
|
use DBI qw(:sql_types);
|
||||||
use DBD::SQLite::Constants ':dbd_sqlite_string_mode';
|
$dbh->{sqlite_unicode} = 1;
|
||||||
$dbh->{sqlite_string_mode} = DBD_SQLITE_STRING_MODE_UNICODE_FALLBACK;
|
|
||||||
my $sth = $dbh->prepare("INSERT INTO mytable (blobcolumn) VALUES (?)");
|
my $sth = $dbh->prepare("INSERT INTO mytable (blobcolumn) VALUES (?)");
|
||||||
|
|
||||||
# Binary_data will be stored as is.
|
# Binary_data will be stored as is.
|
||||||
|
@ -1664,31 +1527,9 @@ updates:
|
||||||
|
|
||||||
Defining the column type as C<BLOB> in the DDL is B<not> sufficient.
|
Defining the column type as C<BLOB> in the DDL is B<not> sufficient.
|
||||||
|
|
||||||
=item * DBD_SQLITE_STRING_MODE_UNICODE_STRICT: Like
|
This attribute was originally named as C<unicode>, and renamed to
|
||||||
DBD_SQLITE_STRING_MODE_UNICODE_FALLBACK but usually throws an exception
|
C<sqlite_unicode> for integrity since version 1.26_06. Old C<unicode>
|
||||||
rather than a warning if SQLite sends invalid UTF-8. (In Perl callbacks
|
attribute is still accessible but will be deprecated in the near future.
|
||||||
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.
|
|
||||||
|
|
||||||
=item sqlite_allow_multiple_statements
|
=item sqlite_allow_multiple_statements
|
||||||
|
|
||||||
|
@ -1715,12 +1556,7 @@ for details.
|
||||||
=item sqlite_extended_result_codes
|
=item sqlite_extended_result_codes
|
||||||
|
|
||||||
If set to true, DBD::SQLite uses extended result codes where appropriate
|
If set to true, DBD::SQLite uses extended result codes where appropriate
|
||||||
(see L<https://www.sqlite.org/rescode.html>).
|
(see L<http://www.sqlite.org/rescode.html>).
|
||||||
|
|
||||||
=item sqlite_defensive
|
|
||||||
|
|
||||||
If set to true, language features that allow ordinary SQL to deliberately
|
|
||||||
corrupt the database file are prohibited.
|
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
|
@ -1749,8 +1585,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
|
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>
|
ESCAPE character by including an 'Escape' attribute in \%attr. The C<$type>
|
||||||
argument accepts a comma separated list of the following types 'TABLE',
|
argument accepts a comma separated list of the following types 'TABLE',
|
||||||
'INDEX', 'VIEW', 'TRIGGER', 'LOCAL TEMPORARY' and 'SYSTEM TABLE'
|
'VIEW', 'LOCAL TEMPORARY' and 'SYSTEM TABLE' (by default all are returned).
|
||||||
(by default all are returned).
|
|
||||||
Note that a statement handle is returned, and not a direct list of tables.
|
Note that a statement handle is returned, and not a direct list of tables.
|
||||||
|
|
||||||
The following fields are returned:
|
The following fields are returned:
|
||||||
|
@ -1763,8 +1598,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_NAME>: The name of the table or view.
|
||||||
|
|
||||||
B<TABLE_TYPE>: The type of object returned. Will be one of 'TABLE', 'INDEX',
|
B<TABLE_TYPE>: The type of object returned. Will be one of 'TABLE', 'VIEW',
|
||||||
'VIEW', 'TRIGGER', 'LOCAL TEMPORARY' or 'SYSTEM TABLE'.
|
'LOCAL TEMPORARY' or 'SYSTEM TABLE'.
|
||||||
|
|
||||||
=head2 primary_key, primary_key_info
|
=head2 primary_key, primary_key_info
|
||||||
|
|
||||||
|
@ -1830,12 +1665,10 @@ B<DELETE_RULE>:
|
||||||
The referential action for the DELETE rule.
|
The referential action for the DELETE rule.
|
||||||
The codes are the same as for UPDATE_RULE.
|
The codes are the same as for UPDATE_RULE.
|
||||||
|
|
||||||
B<DEFERRABILITY>:
|
Unfortunately, the B<DEFERRABILITY> field is always C<undef>;
|
||||||
The following codes are defined:
|
as a matter of fact, deferrability clauses are supported by SQLite,
|
||||||
|
but they can't be reported because the C<PRAGMA foreign_key_list>
|
||||||
INITIALLY DEFERRED 5
|
tells nothing about them.
|
||||||
INITIALLY IMMEDIATE 6
|
|
||||||
NOT DEFERRABLE 7
|
|
||||||
|
|
||||||
B<UNIQUE_OR_PRIMARY>:
|
B<UNIQUE_OR_PRIMARY>:
|
||||||
Whether the column is primary or unique.
|
Whether the column is primary or unique.
|
||||||
|
@ -1895,7 +1728,7 @@ returns true if the database file exists (or the database is in-memory), and the
|
||||||
The following methods can be called via the func() method with a little
|
The following methods can be called via the func() method with a little
|
||||||
tweak, but the use of func() method is now discouraged by the L<DBI> author
|
tweak, but the use of func() method is now discouraged by the L<DBI> author
|
||||||
for various reasons (see DBI's document
|
for various reasons (see DBI's document
|
||||||
L<https://metacpan.org/pod/DBI::DBD#Using-install_method()-to-expose-driver-private-methods>
|
L<http://search.cpan.org/dist/DBI/lib/DBI/DBD.pm#Using_install_method()_to_expose_driver-private_methods>
|
||||||
for details). So, if you're using L<DBI> >= 1.608, use these C<sqlite_>
|
for details). So, if you're using L<DBI> >= 1.608, use these C<sqlite_>
|
||||||
methods. If you need to use an older L<DBI>, you can call these like this:
|
methods. If you need to use an older L<DBI>, you can call these like this:
|
||||||
|
|
||||||
|
@ -1922,8 +1755,7 @@ C<$dbh-E<gt>sqlite_last_insert_rowid()> directly.
|
||||||
|
|
||||||
=head2 $dbh->sqlite_db_filename()
|
=head2 $dbh->sqlite_db_filename()
|
||||||
|
|
||||||
Retrieve the current (main) database filename. If the database is in-memory
|
Retrieve the current (main) database filename. If the database is in-memory or temporary, this returns C<undef>.
|
||||||
or temporary, this returns an empty string, or C<undef>.
|
|
||||||
|
|
||||||
=head2 $dbh->sqlite_busy_timeout()
|
=head2 $dbh->sqlite_busy_timeout()
|
||||||
|
|
||||||
|
@ -1969,13 +1801,6 @@ After this, it could be used from SQL as:
|
||||||
|
|
||||||
INSERT INTO mytable ( now() );
|
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
|
=head3 REGEXP function
|
||||||
|
|
||||||
SQLite includes syntactic support for an infix operator 'REGEXP', but
|
SQLite includes syntactic support for an infix operator 'REGEXP', but
|
||||||
|
@ -2280,39 +2105,18 @@ special :memory: database, and you wish to populate it from an existing DB.
|
||||||
This method accesses the SQLite Online Backup API, and will take a backup of
|
This method accesses the SQLite Online Backup API, and will take a backup of
|
||||||
the currently connected database, and write it out to the named file.
|
the currently connected database, and write it out to the named file.
|
||||||
|
|
||||||
=head2 $dbh->sqlite_backup_from_dbh( $another_dbh )
|
|
||||||
|
|
||||||
This method accesses the SQLite Online Backup API, and will take a backup of
|
|
||||||
the database for the passed handle, copying it to, and overwriting, your current database
|
|
||||||
connection. This can be particularly handy if your current connection is to the
|
|
||||||
special :memory: database, and you wish to populate it from an existing DB.
|
|
||||||
You can use this to backup from an in-memory database to another in-memory database.
|
|
||||||
|
|
||||||
=head2 $dbh->sqlite_backup_to_dbh( $another_dbh )
|
|
||||||
|
|
||||||
This method accesses the SQLite Online Backup API, and will take a backup of
|
|
||||||
the currently connected database, and write it out to the passed database handle.
|
|
||||||
|
|
||||||
=head2 $dbh->sqlite_enable_load_extension( $bool )
|
=head2 $dbh->sqlite_enable_load_extension( $bool )
|
||||||
|
|
||||||
Calling this method with a true value enables loading (external)
|
Calling this method with a true value enables loading (external)
|
||||||
SQLite3 extensions. After the call, you can load extensions like this:
|
SQLite3 extensions. After the call, you can load extensions like this:
|
||||||
|
|
||||||
$dbh->sqlite_enable_load_extension(1);
|
$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();
|
or die "Cannot prepare: " . $dbh->errstr();
|
||||||
|
|
||||||
=head2 $dbh->sqlite_load_extension( $file, $proc )
|
=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>:
|
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>.
|
||||||
|
|
||||||
$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()>.
|
|
||||||
|
|
||||||
=head2 $dbh->sqlite_trace( $code_ref )
|
=head2 $dbh->sqlite_trace( $code_ref )
|
||||||
|
|
||||||
|
@ -2373,38 +2177,17 @@ is for internal use only.
|
||||||
|
|
||||||
=head2 $dbh->sqlite_db_status()
|
=head2 $dbh->sqlite_db_status()
|
||||||
|
|
||||||
Returns a hash reference that holds a set of status information of database connection such as cache usage. See L<https://www.sqlite.org/c3ref/c_dbstatus_options.html> for details. You may also pass 0 as an argument to reset the status.
|
Returns a hash reference that holds a set of status information of database connection such as cache usage. See L<http://www.sqlite.org/c3ref/c_dbstatus_options.html> for details. You may also pass 0 as an argument to reset the status.
|
||||||
|
|
||||||
=head2 $sth->sqlite_st_status()
|
=head2 $sth->sqlite_st_status()
|
||||||
|
|
||||||
Returns a hash reference that holds a set of status information of SQLite statement handle such as full table scan count. See L<https://www.sqlite.org/c3ref/c_stmtstatus_counter.html> for details. Statement status only holds the current value.
|
Returns a hash reference that holds a set of status information of SQLite statement handle such as full table scan count. See L<http://www.sqlite.org/c3ref/c_stmtstatus_counter.html> for details. Statement status only holds the current value.
|
||||||
|
|
||||||
my $status = $sth->sqlite_st_status();
|
my $status = $sth->sqlite_st_status();
|
||||||
my $cur = $status->{fullscan_step};
|
my $cur = $status->{fullscan_step};
|
||||||
|
|
||||||
You may also pass 0 as an argument to reset the status.
|
You may also pass 0 as an argument to reset the status.
|
||||||
|
|
||||||
=head2 $dbh->sqlite_db_config( $id, $new_integer_value )
|
|
||||||
|
|
||||||
You can change how the connected database should behave like this:
|
|
||||||
|
|
||||||
use DBD::SQLite::Constants qw/:database_connection_configuration_options/;
|
|
||||||
|
|
||||||
my $dbh = DBI->connect('dbi:SQLite::memory:');
|
|
||||||
|
|
||||||
# This disables language features that allow ordinary SQL
|
|
||||||
# to deliberately corrupt the database file
|
|
||||||
$dbh->sqlite_db_config( SQLITE_DBCONFIG_DEFENSIVE, 1 );
|
|
||||||
|
|
||||||
# This disables two-arg version of fts3_tokenizer.
|
|
||||||
$dbh->sqlite_db_config( SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, 0 );
|
|
||||||
|
|
||||||
C<sqlite_db_config> returns the new value after the call. If you just want to know the current value without changing anything, pass a negative integer value.
|
|
||||||
|
|
||||||
my $current_value = $dbh->sqlite_db_config( SQLITE_DBCONFIG_DEFENSIVE, -1 );
|
|
||||||
|
|
||||||
As of this writing, C<sqlite_db_config> only supports options that set an integer value. C<SQLITE_DBCONFIG_LOOKASIDE> and C<SQLITE_DBCONFIG_MAINDBNAME> are not supported. See also C<https://www.sqlite.org/capi3ref.html#sqlite3_db_config> for details.
|
|
||||||
|
|
||||||
=head2 $dbh->sqlite_create_module()
|
=head2 $dbh->sqlite_create_module()
|
||||||
|
|
||||||
Registers a name for a I<virtual table module>. Module names must be
|
Registers a name for a I<virtual table module>. Module names must be
|
||||||
|
@ -2412,33 +2195,6 @@ registered before creating a new virtual table using the module and
|
||||||
before using a preexisting virtual table for the module.
|
before using a preexisting virtual table for the module.
|
||||||
Virtual tables are explained in L<DBD::SQLite::VirtualTable>.
|
Virtual tables are explained in L<DBD::SQLite::VirtualTable>.
|
||||||
|
|
||||||
=head2 $dbh->sqlite_limit( $category_id, $new_value )
|
|
||||||
|
|
||||||
Sets a new run-time limit for the category, and returns the current limit.
|
|
||||||
If the new value is a negative number (or omitted), the limit is unchanged
|
|
||||||
and just returns the current limit. Category ids (SQLITE_LIMIT_LENGTH,
|
|
||||||
SQLITE_LIMIT_VARIABLE_NUMBER, etc) can be imported from DBD::SQLite::Constants.
|
|
||||||
|
|
||||||
=head2 $dbh->sqlite_get_autocommit()
|
|
||||||
|
|
||||||
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
|
=head1 DRIVER FUNCTIONS
|
||||||
|
|
||||||
=head2 DBD::SQLite::compile_options()
|
=head2 DBD::SQLite::compile_options()
|
||||||
|
@ -2449,7 +2205,7 @@ library is old or compiled with SQLITE_OMIT_COMPILEOPTION_DIAGS.
|
||||||
|
|
||||||
=head2 DBD::SQLite::sqlite_status()
|
=head2 DBD::SQLite::sqlite_status()
|
||||||
|
|
||||||
Returns a hash reference that holds a set of status information of SQLite runtime such as memory usage or page cache usage (see L<https://www.sqlite.org/c3ref/c_status_malloc_count.html> for details). Each of the entry contains the current value and the highwater value.
|
Returns a hash reference that holds a set of status information of SQLite runtime such as memory usage or page cache usage (see L<http://www.sqlite.org/c3ref/c_status_malloc_count.html> for details). Each of the entry contains the current value and the highwater value.
|
||||||
|
|
||||||
my $status = DBD::SQLite::sqlite_status();
|
my $status = DBD::SQLite::sqlite_status();
|
||||||
my $cur = $status->{memory_used}{current};
|
my $cur = $status->{memory_used}{current};
|
||||||
|
@ -2483,7 +2239,7 @@ DELETE operation would be written as follows :
|
||||||
|
|
||||||
The list of constants implemented in C<DBD::SQLite> is given
|
The list of constants implemented in C<DBD::SQLite> is given
|
||||||
below; more information can be found ad
|
below; more information can be found ad
|
||||||
at L<https://www.sqlite.org/c3ref/constlist.html>.
|
at L<http://www.sqlite.org/c3ref/constlist.html>.
|
||||||
|
|
||||||
=head2 Authorizer Return Codes
|
=head2 Authorizer Return Codes
|
||||||
|
|
||||||
|
@ -2543,7 +2299,7 @@ associated strings.
|
||||||
SQLite v3 provides the ability for users to supply arbitrary
|
SQLite v3 provides the ability for users to supply arbitrary
|
||||||
comparison functions, known as user-defined "collation sequences" or
|
comparison functions, known as user-defined "collation sequences" or
|
||||||
"collating functions", to be used for comparing two text values.
|
"collating functions", to be used for comparing two text values.
|
||||||
L<https://www.sqlite.org/datatype3.html#collation>
|
L<http://www.sqlite.org/datatype3.html#collation>
|
||||||
explains how collations are used in various SQL expressions.
|
explains how collations are used in various SQL expressions.
|
||||||
|
|
||||||
=head2 Builtin collation sequences
|
=head2 Builtin collation sequences
|
||||||
|
@ -2601,17 +2357,18 @@ or
|
||||||
|
|
||||||
=head2 Unicode handling
|
=head2 Unicode handling
|
||||||
|
|
||||||
Depending on the C<< $dbh->{sqlite_string_mode} >> value, strings coming
|
If the attribute C<< $dbh->{sqlite_unicode} >> is set, strings coming from
|
||||||
from the database and passed to the collation function may be decoded as
|
the database and passed to the collation function will be properly
|
||||||
UTF-8. This only works, though, if the C<sqlite_string_mode> attribute is
|
tagged with the utf8 flag; but this only works if the
|
||||||
set B<before> the first call to a perl collation sequence. The recommended
|
C<sqlite_unicode> attribute is set B<before> the first call to
|
||||||
way to activate unicode is to set C<sqlite_string_mode> at connection time:
|
a perl collation sequence . The recommended way to activate unicode
|
||||||
|
is to set the parameter at connection time :
|
||||||
|
|
||||||
my $dbh = DBI->connect(
|
my $dbh = DBI->connect(
|
||||||
"dbi:SQLite:dbname=foo", "", "",
|
"dbi:SQLite:dbname=foo", "", "",
|
||||||
{
|
{
|
||||||
RaiseError => 1,
|
RaiseError => 1,
|
||||||
sqlite_string_mode => DBD_SQLITE_STRING_MODE_UNICODE_STRICT,
|
sqlite_unicode => 1,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2633,7 +2390,7 @@ characters :
|
||||||
use DBD::SQLite;
|
use DBD::SQLite;
|
||||||
$DBD::SQLite::COLLATION{no_accents} = sub {
|
$DBD::SQLite::COLLATION{no_accents} = sub {
|
||||||
my ( $a, $b ) = map lc, @_;
|
my ( $a, $b ) = map lc, @_;
|
||||||
tr[àâáäåãçðèêéëìîíïñòôóöõøùûúüý]
|
tr[àâáäåãçðèêéëìîíïñòôóöõøùûúüý]
|
||||||
[aaaaaacdeeeeiiiinoooooouuuuy] for $a, $b;
|
[aaaaaacdeeeeiiiinoooooouuuuy] for $a, $b;
|
||||||
$a cmp $b;
|
$a cmp $b;
|
||||||
};
|
};
|
||||||
|
@ -2706,7 +2463,7 @@ then query which buildings overlap or are contained within a specified region:
|
||||||
$minLong, $maxLong, $minLat, $maxLat);
|
$minLong, $maxLong, $minLat, $maxLat);
|
||||||
|
|
||||||
For more detail, please see the SQLite R-Tree page
|
For more detail, please see the SQLite R-Tree page
|
||||||
(L<https://www.sqlite.org/rtree.html>). Note that custom R-Tree
|
(L<http://www.sqlite.org/rtree.html>). Note that custom R-Tree
|
||||||
queries using callbacks, as mentioned in the prior link, have not been
|
queries using callbacks, as mentioned in the prior link, have not been
|
||||||
implemented yet.
|
implemented yet.
|
||||||
|
|
||||||
|
@ -2790,17 +2547,13 @@ Reading/writing into blobs using C<sqlite2_blob_open> / C<sqlite2_blob_close>.
|
||||||
=head2 Support for custom callbacks for R-Tree queries
|
=head2 Support for custom callbacks for R-Tree queries
|
||||||
|
|
||||||
Custom queries of a R-Tree index using a callback are possible with
|
Custom queries of a R-Tree index using a callback are possible with
|
||||||
the SQLite C API (L<https://www.sqlite.org/rtree.html>), so one could
|
the SQLite C API (L<http://www.sqlite.org/rtree.html>), so one could
|
||||||
potentially use a callback that narrowed the result set down based
|
potentially use a callback that narrowed the result set down based
|
||||||
on a specific need, such as querying for overlapping circles.
|
on a specific need, such as querying for overlapping circles.
|
||||||
|
|
||||||
=head1 SUPPORT
|
=head1 SUPPORT
|
||||||
|
|
||||||
Bugs should be reported to GitHub issues:
|
Bugs should be reported via the CPAN bug tracker at
|
||||||
|
|
||||||
L<https://github.com/DBD-SQLite/DBD-SQLite/issues>
|
|
||||||
|
|
||||||
or via RT if you prefer:
|
|
||||||
|
|
||||||
L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=DBD-SQLite>
|
L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=DBD-SQLite>
|
||||||
|
|
||||||
|
|
|
@ -8,18 +8,6 @@ use warnings;
|
||||||
use base 'Exporter';
|
use base 'Exporter';
|
||||||
use DBD::SQLite;
|
use DBD::SQLite;
|
||||||
our @EXPORT_OK = (
|
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
|
# authorizer_action_codes
|
||||||
qw/
|
qw/
|
||||||
SQLITE_ALTER_TABLE
|
SQLITE_ALTER_TABLE
|
||||||
|
@ -69,62 +57,27 @@ our @EXPORT_OK = (
|
||||||
SQLITE_VERSION_NUMBER
|
SQLITE_VERSION_NUMBER
|
||||||
/,
|
/,
|
||||||
|
|
||||||
# database_connection_configuration_options
|
|
||||||
qw/
|
|
||||||
SQLITE_DBCONFIG_DEFENSIVE
|
|
||||||
SQLITE_DBCONFIG_DQS_DDL
|
|
||||||
SQLITE_DBCONFIG_DQS_DML
|
|
||||||
SQLITE_DBCONFIG_ENABLE_FKEY
|
|
||||||
SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
|
|
||||||
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
|
|
||||||
/,
|
|
||||||
|
|
||||||
# extended_result_codes
|
# extended_result_codes
|
||||||
qw/
|
qw/
|
||||||
SQLITE_ABORT_ROLLBACK
|
SQLITE_ABORT_ROLLBACK
|
||||||
SQLITE_AUTH_USER
|
SQLITE_AUTH_USER
|
||||||
SQLITE_BUSY_RECOVERY
|
SQLITE_BUSY_RECOVERY
|
||||||
SQLITE_BUSY_SNAPSHOT
|
SQLITE_BUSY_SNAPSHOT
|
||||||
SQLITE_BUSY_TIMEOUT
|
|
||||||
SQLITE_CANTOPEN_CONVPATH
|
SQLITE_CANTOPEN_CONVPATH
|
||||||
SQLITE_CANTOPEN_DIRTYWAL
|
|
||||||
SQLITE_CANTOPEN_FULLPATH
|
SQLITE_CANTOPEN_FULLPATH
|
||||||
SQLITE_CANTOPEN_ISDIR
|
SQLITE_CANTOPEN_ISDIR
|
||||||
SQLITE_CANTOPEN_NOTEMPDIR
|
SQLITE_CANTOPEN_NOTEMPDIR
|
||||||
SQLITE_CANTOPEN_SYMLINK
|
|
||||||
SQLITE_CONSTRAINT_CHECK
|
SQLITE_CONSTRAINT_CHECK
|
||||||
SQLITE_CONSTRAINT_COMMITHOOK
|
SQLITE_CONSTRAINT_COMMITHOOK
|
||||||
SQLITE_CONSTRAINT_DATATYPE
|
|
||||||
SQLITE_CONSTRAINT_FOREIGNKEY
|
SQLITE_CONSTRAINT_FOREIGNKEY
|
||||||
SQLITE_CONSTRAINT_FUNCTION
|
SQLITE_CONSTRAINT_FUNCTION
|
||||||
SQLITE_CONSTRAINT_NOTNULL
|
SQLITE_CONSTRAINT_NOTNULL
|
||||||
SQLITE_CONSTRAINT_PINNED
|
|
||||||
SQLITE_CONSTRAINT_PRIMARYKEY
|
SQLITE_CONSTRAINT_PRIMARYKEY
|
||||||
SQLITE_CONSTRAINT_ROWID
|
SQLITE_CONSTRAINT_ROWID
|
||||||
SQLITE_CONSTRAINT_TRIGGER
|
SQLITE_CONSTRAINT_TRIGGER
|
||||||
SQLITE_CONSTRAINT_UNIQUE
|
SQLITE_CONSTRAINT_UNIQUE
|
||||||
SQLITE_CONSTRAINT_VTAB
|
SQLITE_CONSTRAINT_VTAB
|
||||||
SQLITE_CORRUPT_INDEX
|
|
||||||
SQLITE_CORRUPT_SEQUENCE
|
|
||||||
SQLITE_CORRUPT_VTAB
|
SQLITE_CORRUPT_VTAB
|
||||||
SQLITE_ERROR_MISSING_COLLSEQ
|
|
||||||
SQLITE_ERROR_RETRY
|
|
||||||
SQLITE_ERROR_SNAPSHOT
|
|
||||||
SQLITE_IOERR_ACCESS
|
SQLITE_IOERR_ACCESS
|
||||||
SQLITE_IOERR_AUTH
|
SQLITE_IOERR_AUTH
|
||||||
SQLITE_IOERR_BEGIN_ATOMIC
|
SQLITE_IOERR_BEGIN_ATOMIC
|
||||||
|
@ -133,8 +86,6 @@ our @EXPORT_OK = (
|
||||||
SQLITE_IOERR_CLOSE
|
SQLITE_IOERR_CLOSE
|
||||||
SQLITE_IOERR_COMMIT_ATOMIC
|
SQLITE_IOERR_COMMIT_ATOMIC
|
||||||
SQLITE_IOERR_CONVPATH
|
SQLITE_IOERR_CONVPATH
|
||||||
SQLITE_IOERR_CORRUPTFS
|
|
||||||
SQLITE_IOERR_DATA
|
|
||||||
SQLITE_IOERR_DELETE
|
SQLITE_IOERR_DELETE
|
||||||
SQLITE_IOERR_DELETE_NOENT
|
SQLITE_IOERR_DELETE_NOENT
|
||||||
SQLITE_IOERR_DIR_CLOSE
|
SQLITE_IOERR_DIR_CLOSE
|
||||||
|
@ -142,7 +93,6 @@ our @EXPORT_OK = (
|
||||||
SQLITE_IOERR_FSTAT
|
SQLITE_IOERR_FSTAT
|
||||||
SQLITE_IOERR_FSYNC
|
SQLITE_IOERR_FSYNC
|
||||||
SQLITE_IOERR_GETTEMPPATH
|
SQLITE_IOERR_GETTEMPPATH
|
||||||
SQLITE_IOERR_IN_PAGE
|
|
||||||
SQLITE_IOERR_LOCK
|
SQLITE_IOERR_LOCK
|
||||||
SQLITE_IOERR_MMAP
|
SQLITE_IOERR_MMAP
|
||||||
SQLITE_IOERR_NOMEM
|
SQLITE_IOERR_NOMEM
|
||||||
|
@ -160,15 +110,10 @@ our @EXPORT_OK = (
|
||||||
SQLITE_IOERR_VNODE
|
SQLITE_IOERR_VNODE
|
||||||
SQLITE_IOERR_WRITE
|
SQLITE_IOERR_WRITE
|
||||||
SQLITE_LOCKED_SHAREDCACHE
|
SQLITE_LOCKED_SHAREDCACHE
|
||||||
SQLITE_LOCKED_VTAB
|
|
||||||
SQLITE_NOTICE_RBU
|
|
||||||
SQLITE_NOTICE_RECOVER_ROLLBACK
|
SQLITE_NOTICE_RECOVER_ROLLBACK
|
||||||
SQLITE_NOTICE_RECOVER_WAL
|
SQLITE_NOTICE_RECOVER_WAL
|
||||||
SQLITE_OK_SYMLINK
|
|
||||||
SQLITE_READONLY_CANTINIT
|
|
||||||
SQLITE_READONLY_CANTLOCK
|
SQLITE_READONLY_CANTLOCK
|
||||||
SQLITE_READONLY_DBMOVED
|
SQLITE_READONLY_DBMOVED
|
||||||
SQLITE_READONLY_DIRECTORY
|
|
||||||
SQLITE_READONLY_RECOVERY
|
SQLITE_READONLY_RECOVERY
|
||||||
SQLITE_READONLY_ROLLBACK
|
SQLITE_READONLY_ROLLBACK
|
||||||
SQLITE_WARNING_AUTOINDEX
|
SQLITE_WARNING_AUTOINDEX
|
||||||
|
@ -177,26 +122,19 @@ our @EXPORT_OK = (
|
||||||
# flags_for_file_open_operations
|
# flags_for_file_open_operations
|
||||||
qw/
|
qw/
|
||||||
SQLITE_OPEN_CREATE
|
SQLITE_OPEN_CREATE
|
||||||
SQLITE_OPEN_EXRESCODE
|
|
||||||
SQLITE_OPEN_FULLMUTEX
|
SQLITE_OPEN_FULLMUTEX
|
||||||
SQLITE_OPEN_MEMORY
|
SQLITE_OPEN_MEMORY
|
||||||
SQLITE_OPEN_NOFOLLOW
|
|
||||||
SQLITE_OPEN_NOMUTEX
|
SQLITE_OPEN_NOMUTEX
|
||||||
SQLITE_OPEN_PRIVATECACHE
|
SQLITE_OPEN_PRIVATECACHE
|
||||||
SQLITE_OPEN_READONLY
|
SQLITE_OPEN_READONLY
|
||||||
SQLITE_OPEN_READWRITE
|
SQLITE_OPEN_READWRITE
|
||||||
SQLITE_OPEN_SHAREDCACHE
|
SQLITE_OPEN_SHAREDCACHE
|
||||||
SQLITE_OPEN_SUPER_JOURNAL
|
|
||||||
SQLITE_OPEN_URI
|
SQLITE_OPEN_URI
|
||||||
/,
|
/,
|
||||||
|
|
||||||
# function_flags
|
# function_flags
|
||||||
qw/
|
qw/
|
||||||
SQLITE_DETERMINISTIC
|
SQLITE_DETERMINISTIC
|
||||||
SQLITE_DIRECTONLY
|
|
||||||
SQLITE_INNOCUOUS
|
|
||||||
SQLITE_RESULT_SUBTYPE
|
|
||||||
SQLITE_SUBTYPE
|
|
||||||
/,
|
/,
|
||||||
|
|
||||||
# fundamental_datatypes
|
# fundamental_datatypes
|
||||||
|
@ -205,7 +143,6 @@ our @EXPORT_OK = (
|
||||||
SQLITE_FLOAT
|
SQLITE_FLOAT
|
||||||
SQLITE_INTEGER
|
SQLITE_INTEGER
|
||||||
SQLITE_NULL
|
SQLITE_NULL
|
||||||
SQLITE_TEXT
|
|
||||||
/,
|
/,
|
||||||
|
|
||||||
# result_codes
|
# result_codes
|
||||||
|
@ -243,22 +180,6 @@ our @EXPORT_OK = (
|
||||||
SQLITE_WARNING
|
SQLITE_WARNING
|
||||||
/,
|
/,
|
||||||
|
|
||||||
# run_time_limit_categories
|
|
||||||
qw/
|
|
||||||
SQLITE_LIMIT_ATTACHED
|
|
||||||
SQLITE_LIMIT_COLUMN
|
|
||||||
SQLITE_LIMIT_COMPOUND_SELECT
|
|
||||||
SQLITE_LIMIT_EXPR_DEPTH
|
|
||||||
SQLITE_LIMIT_FUNCTION_ARG
|
|
||||||
SQLITE_LIMIT_LENGTH
|
|
||||||
SQLITE_LIMIT_LIKE_PATTERN_LENGTH
|
|
||||||
SQLITE_LIMIT_SQL_LENGTH
|
|
||||||
SQLITE_LIMIT_TRIGGER_DEPTH
|
|
||||||
SQLITE_LIMIT_VARIABLE_NUMBER
|
|
||||||
SQLITE_LIMIT_VDBE_OP
|
|
||||||
SQLITE_LIMIT_WORKER_THREADS
|
|
||||||
/,
|
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
our %EXPORT_TAGS = (
|
our %EXPORT_TAGS = (
|
||||||
|
@ -274,22 +195,17 @@ our %EXPORT_TAGS = (
|
||||||
SQLITE_BUSY
|
SQLITE_BUSY
|
||||||
SQLITE_BUSY_RECOVERY
|
SQLITE_BUSY_RECOVERY
|
||||||
SQLITE_BUSY_SNAPSHOT
|
SQLITE_BUSY_SNAPSHOT
|
||||||
SQLITE_BUSY_TIMEOUT
|
|
||||||
SQLITE_CANTOPEN
|
SQLITE_CANTOPEN
|
||||||
SQLITE_CANTOPEN_CONVPATH
|
SQLITE_CANTOPEN_CONVPATH
|
||||||
SQLITE_CANTOPEN_DIRTYWAL
|
|
||||||
SQLITE_CANTOPEN_FULLPATH
|
SQLITE_CANTOPEN_FULLPATH
|
||||||
SQLITE_CANTOPEN_ISDIR
|
SQLITE_CANTOPEN_ISDIR
|
||||||
SQLITE_CANTOPEN_NOTEMPDIR
|
SQLITE_CANTOPEN_NOTEMPDIR
|
||||||
SQLITE_CANTOPEN_SYMLINK
|
|
||||||
SQLITE_CONSTRAINT
|
SQLITE_CONSTRAINT
|
||||||
SQLITE_CONSTRAINT_CHECK
|
SQLITE_CONSTRAINT_CHECK
|
||||||
SQLITE_CONSTRAINT_COMMITHOOK
|
SQLITE_CONSTRAINT_COMMITHOOK
|
||||||
SQLITE_CONSTRAINT_DATATYPE
|
|
||||||
SQLITE_CONSTRAINT_FOREIGNKEY
|
SQLITE_CONSTRAINT_FOREIGNKEY
|
||||||
SQLITE_CONSTRAINT_FUNCTION
|
SQLITE_CONSTRAINT_FUNCTION
|
||||||
SQLITE_CONSTRAINT_NOTNULL
|
SQLITE_CONSTRAINT_NOTNULL
|
||||||
SQLITE_CONSTRAINT_PINNED
|
|
||||||
SQLITE_CONSTRAINT_PRIMARYKEY
|
SQLITE_CONSTRAINT_PRIMARYKEY
|
||||||
SQLITE_CONSTRAINT_ROWID
|
SQLITE_CONSTRAINT_ROWID
|
||||||
SQLITE_CONSTRAINT_TRIGGER
|
SQLITE_CONSTRAINT_TRIGGER
|
||||||
|
@ -297,8 +213,6 @@ our %EXPORT_TAGS = (
|
||||||
SQLITE_CONSTRAINT_VTAB
|
SQLITE_CONSTRAINT_VTAB
|
||||||
SQLITE_COPY
|
SQLITE_COPY
|
||||||
SQLITE_CORRUPT
|
SQLITE_CORRUPT
|
||||||
SQLITE_CORRUPT_INDEX
|
|
||||||
SQLITE_CORRUPT_SEQUENCE
|
|
||||||
SQLITE_CORRUPT_VTAB
|
SQLITE_CORRUPT_VTAB
|
||||||
SQLITE_CREATE_INDEX
|
SQLITE_CREATE_INDEX
|
||||||
SQLITE_CREATE_TABLE
|
SQLITE_CREATE_TABLE
|
||||||
|
@ -309,37 +223,10 @@ our %EXPORT_TAGS = (
|
||||||
SQLITE_CREATE_TRIGGER
|
SQLITE_CREATE_TRIGGER
|
||||||
SQLITE_CREATE_VIEW
|
SQLITE_CREATE_VIEW
|
||||||
SQLITE_CREATE_VTABLE
|
SQLITE_CREATE_VTABLE
|
||||||
SQLITE_DBCONFIG_DEFENSIVE
|
|
||||||
SQLITE_DBCONFIG_DQS_DDL
|
|
||||||
SQLITE_DBCONFIG_DQS_DML
|
|
||||||
SQLITE_DBCONFIG_ENABLE_FKEY
|
|
||||||
SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
|
|
||||||
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_DELETE
|
||||||
SQLITE_DENY
|
SQLITE_DENY
|
||||||
SQLITE_DETACH
|
SQLITE_DETACH
|
||||||
SQLITE_DETERMINISTIC
|
SQLITE_DETERMINISTIC
|
||||||
SQLITE_DIRECTONLY
|
|
||||||
SQLITE_DONE
|
SQLITE_DONE
|
||||||
SQLITE_DROP_INDEX
|
SQLITE_DROP_INDEX
|
||||||
SQLITE_DROP_TABLE
|
SQLITE_DROP_TABLE
|
||||||
|
@ -352,15 +239,11 @@ our %EXPORT_TAGS = (
|
||||||
SQLITE_DROP_VTABLE
|
SQLITE_DROP_VTABLE
|
||||||
SQLITE_EMPTY
|
SQLITE_EMPTY
|
||||||
SQLITE_ERROR
|
SQLITE_ERROR
|
||||||
SQLITE_ERROR_MISSING_COLLSEQ
|
|
||||||
SQLITE_ERROR_RETRY
|
|
||||||
SQLITE_ERROR_SNAPSHOT
|
|
||||||
SQLITE_FLOAT
|
SQLITE_FLOAT
|
||||||
SQLITE_FORMAT
|
SQLITE_FORMAT
|
||||||
SQLITE_FULL
|
SQLITE_FULL
|
||||||
SQLITE_FUNCTION
|
SQLITE_FUNCTION
|
||||||
SQLITE_IGNORE
|
SQLITE_IGNORE
|
||||||
SQLITE_INNOCUOUS
|
|
||||||
SQLITE_INSERT
|
SQLITE_INSERT
|
||||||
SQLITE_INTEGER
|
SQLITE_INTEGER
|
||||||
SQLITE_INTERNAL
|
SQLITE_INTERNAL
|
||||||
|
@ -374,8 +257,6 @@ our %EXPORT_TAGS = (
|
||||||
SQLITE_IOERR_CLOSE
|
SQLITE_IOERR_CLOSE
|
||||||
SQLITE_IOERR_COMMIT_ATOMIC
|
SQLITE_IOERR_COMMIT_ATOMIC
|
||||||
SQLITE_IOERR_CONVPATH
|
SQLITE_IOERR_CONVPATH
|
||||||
SQLITE_IOERR_CORRUPTFS
|
|
||||||
SQLITE_IOERR_DATA
|
|
||||||
SQLITE_IOERR_DELETE
|
SQLITE_IOERR_DELETE
|
||||||
SQLITE_IOERR_DELETE_NOENT
|
SQLITE_IOERR_DELETE_NOENT
|
||||||
SQLITE_IOERR_DIR_CLOSE
|
SQLITE_IOERR_DIR_CLOSE
|
||||||
|
@ -383,7 +264,6 @@ our %EXPORT_TAGS = (
|
||||||
SQLITE_IOERR_FSTAT
|
SQLITE_IOERR_FSTAT
|
||||||
SQLITE_IOERR_FSYNC
|
SQLITE_IOERR_FSYNC
|
||||||
SQLITE_IOERR_GETTEMPPATH
|
SQLITE_IOERR_GETTEMPPATH
|
||||||
SQLITE_IOERR_IN_PAGE
|
|
||||||
SQLITE_IOERR_LOCK
|
SQLITE_IOERR_LOCK
|
||||||
SQLITE_IOERR_MMAP
|
SQLITE_IOERR_MMAP
|
||||||
SQLITE_IOERR_NOMEM
|
SQLITE_IOERR_NOMEM
|
||||||
|
@ -400,21 +280,8 @@ our %EXPORT_TAGS = (
|
||||||
SQLITE_IOERR_UNLOCK
|
SQLITE_IOERR_UNLOCK
|
||||||
SQLITE_IOERR_VNODE
|
SQLITE_IOERR_VNODE
|
||||||
SQLITE_IOERR_WRITE
|
SQLITE_IOERR_WRITE
|
||||||
SQLITE_LIMIT_ATTACHED
|
|
||||||
SQLITE_LIMIT_COLUMN
|
|
||||||
SQLITE_LIMIT_COMPOUND_SELECT
|
|
||||||
SQLITE_LIMIT_EXPR_DEPTH
|
|
||||||
SQLITE_LIMIT_FUNCTION_ARG
|
|
||||||
SQLITE_LIMIT_LENGTH
|
|
||||||
SQLITE_LIMIT_LIKE_PATTERN_LENGTH
|
|
||||||
SQLITE_LIMIT_SQL_LENGTH
|
|
||||||
SQLITE_LIMIT_TRIGGER_DEPTH
|
|
||||||
SQLITE_LIMIT_VARIABLE_NUMBER
|
|
||||||
SQLITE_LIMIT_VDBE_OP
|
|
||||||
SQLITE_LIMIT_WORKER_THREADS
|
|
||||||
SQLITE_LOCKED
|
SQLITE_LOCKED
|
||||||
SQLITE_LOCKED_SHAREDCACHE
|
SQLITE_LOCKED_SHAREDCACHE
|
||||||
SQLITE_LOCKED_VTAB
|
|
||||||
SQLITE_MISMATCH
|
SQLITE_MISMATCH
|
||||||
SQLITE_MISUSE
|
SQLITE_MISUSE
|
||||||
SQLITE_NOLFS
|
SQLITE_NOLFS
|
||||||
|
@ -422,23 +289,18 @@ our %EXPORT_TAGS = (
|
||||||
SQLITE_NOTADB
|
SQLITE_NOTADB
|
||||||
SQLITE_NOTFOUND
|
SQLITE_NOTFOUND
|
||||||
SQLITE_NOTICE
|
SQLITE_NOTICE
|
||||||
SQLITE_NOTICE_RBU
|
|
||||||
SQLITE_NOTICE_RECOVER_ROLLBACK
|
SQLITE_NOTICE_RECOVER_ROLLBACK
|
||||||
SQLITE_NOTICE_RECOVER_WAL
|
SQLITE_NOTICE_RECOVER_WAL
|
||||||
SQLITE_NULL
|
SQLITE_NULL
|
||||||
SQLITE_OK
|
SQLITE_OK
|
||||||
SQLITE_OK_SYMLINK
|
|
||||||
SQLITE_OPEN_CREATE
|
SQLITE_OPEN_CREATE
|
||||||
SQLITE_OPEN_EXRESCODE
|
|
||||||
SQLITE_OPEN_FULLMUTEX
|
SQLITE_OPEN_FULLMUTEX
|
||||||
SQLITE_OPEN_MEMORY
|
SQLITE_OPEN_MEMORY
|
||||||
SQLITE_OPEN_NOFOLLOW
|
|
||||||
SQLITE_OPEN_NOMUTEX
|
SQLITE_OPEN_NOMUTEX
|
||||||
SQLITE_OPEN_PRIVATECACHE
|
SQLITE_OPEN_PRIVATECACHE
|
||||||
SQLITE_OPEN_READONLY
|
SQLITE_OPEN_READONLY
|
||||||
SQLITE_OPEN_READWRITE
|
SQLITE_OPEN_READWRITE
|
||||||
SQLITE_OPEN_SHAREDCACHE
|
SQLITE_OPEN_SHAREDCACHE
|
||||||
SQLITE_OPEN_SUPER_JOURNAL
|
|
||||||
SQLITE_OPEN_URI
|
SQLITE_OPEN_URI
|
||||||
SQLITE_PERM
|
SQLITE_PERM
|
||||||
SQLITE_PRAGMA
|
SQLITE_PRAGMA
|
||||||
|
@ -446,38 +308,24 @@ our %EXPORT_TAGS = (
|
||||||
SQLITE_RANGE
|
SQLITE_RANGE
|
||||||
SQLITE_READ
|
SQLITE_READ
|
||||||
SQLITE_READONLY
|
SQLITE_READONLY
|
||||||
SQLITE_READONLY_CANTINIT
|
|
||||||
SQLITE_READONLY_CANTLOCK
|
SQLITE_READONLY_CANTLOCK
|
||||||
SQLITE_READONLY_DBMOVED
|
SQLITE_READONLY_DBMOVED
|
||||||
SQLITE_READONLY_DIRECTORY
|
|
||||||
SQLITE_READONLY_RECOVERY
|
SQLITE_READONLY_RECOVERY
|
||||||
SQLITE_READONLY_ROLLBACK
|
SQLITE_READONLY_ROLLBACK
|
||||||
SQLITE_RECURSIVE
|
SQLITE_RECURSIVE
|
||||||
SQLITE_REINDEX
|
SQLITE_REINDEX
|
||||||
SQLITE_RESULT_SUBTYPE
|
|
||||||
SQLITE_ROW
|
SQLITE_ROW
|
||||||
SQLITE_SAVEPOINT
|
SQLITE_SAVEPOINT
|
||||||
SQLITE_SCHEMA
|
SQLITE_SCHEMA
|
||||||
SQLITE_SELECT
|
SQLITE_SELECT
|
||||||
SQLITE_SUBTYPE
|
|
||||||
SQLITE_TEXT
|
|
||||||
SQLITE_TOOBIG
|
SQLITE_TOOBIG
|
||||||
SQLITE_TRANSACTION
|
SQLITE_TRANSACTION
|
||||||
SQLITE_TXN_NONE
|
|
||||||
SQLITE_TXN_READ
|
|
||||||
SQLITE_TXN_WRITE
|
|
||||||
SQLITE_UPDATE
|
SQLITE_UPDATE
|
||||||
SQLITE_VERSION_NUMBER
|
SQLITE_VERSION_NUMBER
|
||||||
SQLITE_WARNING
|
SQLITE_WARNING
|
||||||
SQLITE_WARNING_AUTOINDEX
|
SQLITE_WARNING_AUTOINDEX
|
||||||
/],
|
/],
|
||||||
|
|
||||||
allowed_return_values_from_sqlite3_txn_state => [qw/
|
|
||||||
SQLITE_TXN_NONE
|
|
||||||
SQLITE_TXN_READ
|
|
||||||
SQLITE_TXN_WRITE
|
|
||||||
/],
|
|
||||||
|
|
||||||
authorizer_action_codes => [qw/
|
authorizer_action_codes => [qw/
|
||||||
SQLITE_ALTER_TABLE
|
SQLITE_ALTER_TABLE
|
||||||
SQLITE_ANALYZE
|
SQLITE_ANALYZE
|
||||||
|
@ -524,68 +372,26 @@ our %EXPORT_TAGS = (
|
||||||
SQLITE_VERSION_NUMBER
|
SQLITE_VERSION_NUMBER
|
||||||
/],
|
/],
|
||||||
|
|
||||||
database_connection_configuration_options => [qw/
|
|
||||||
SQLITE_DBCONFIG_DEFENSIVE
|
|
||||||
SQLITE_DBCONFIG_DQS_DDL
|
|
||||||
SQLITE_DBCONFIG_DQS_DML
|
|
||||||
SQLITE_DBCONFIG_ENABLE_FKEY
|
|
||||||
SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
|
|
||||||
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/
|
extended_result_codes => [qw/
|
||||||
SQLITE_ABORT_ROLLBACK
|
SQLITE_ABORT_ROLLBACK
|
||||||
SQLITE_AUTH_USER
|
SQLITE_AUTH_USER
|
||||||
SQLITE_BUSY_RECOVERY
|
SQLITE_BUSY_RECOVERY
|
||||||
SQLITE_BUSY_SNAPSHOT
|
SQLITE_BUSY_SNAPSHOT
|
||||||
SQLITE_BUSY_TIMEOUT
|
|
||||||
SQLITE_CANTOPEN_CONVPATH
|
SQLITE_CANTOPEN_CONVPATH
|
||||||
SQLITE_CANTOPEN_DIRTYWAL
|
|
||||||
SQLITE_CANTOPEN_FULLPATH
|
SQLITE_CANTOPEN_FULLPATH
|
||||||
SQLITE_CANTOPEN_ISDIR
|
SQLITE_CANTOPEN_ISDIR
|
||||||
SQLITE_CANTOPEN_NOTEMPDIR
|
SQLITE_CANTOPEN_NOTEMPDIR
|
||||||
SQLITE_CANTOPEN_SYMLINK
|
|
||||||
SQLITE_CONSTRAINT_CHECK
|
SQLITE_CONSTRAINT_CHECK
|
||||||
SQLITE_CONSTRAINT_COMMITHOOK
|
SQLITE_CONSTRAINT_COMMITHOOK
|
||||||
SQLITE_CONSTRAINT_DATATYPE
|
|
||||||
SQLITE_CONSTRAINT_FOREIGNKEY
|
SQLITE_CONSTRAINT_FOREIGNKEY
|
||||||
SQLITE_CONSTRAINT_FUNCTION
|
SQLITE_CONSTRAINT_FUNCTION
|
||||||
SQLITE_CONSTRAINT_NOTNULL
|
SQLITE_CONSTRAINT_NOTNULL
|
||||||
SQLITE_CONSTRAINT_PINNED
|
|
||||||
SQLITE_CONSTRAINT_PRIMARYKEY
|
SQLITE_CONSTRAINT_PRIMARYKEY
|
||||||
SQLITE_CONSTRAINT_ROWID
|
SQLITE_CONSTRAINT_ROWID
|
||||||
SQLITE_CONSTRAINT_TRIGGER
|
SQLITE_CONSTRAINT_TRIGGER
|
||||||
SQLITE_CONSTRAINT_UNIQUE
|
SQLITE_CONSTRAINT_UNIQUE
|
||||||
SQLITE_CONSTRAINT_VTAB
|
SQLITE_CONSTRAINT_VTAB
|
||||||
SQLITE_CORRUPT_INDEX
|
|
||||||
SQLITE_CORRUPT_SEQUENCE
|
|
||||||
SQLITE_CORRUPT_VTAB
|
SQLITE_CORRUPT_VTAB
|
||||||
SQLITE_ERROR_MISSING_COLLSEQ
|
|
||||||
SQLITE_ERROR_RETRY
|
|
||||||
SQLITE_ERROR_SNAPSHOT
|
|
||||||
SQLITE_IOERR_ACCESS
|
SQLITE_IOERR_ACCESS
|
||||||
SQLITE_IOERR_AUTH
|
SQLITE_IOERR_AUTH
|
||||||
SQLITE_IOERR_BEGIN_ATOMIC
|
SQLITE_IOERR_BEGIN_ATOMIC
|
||||||
|
@ -594,8 +400,6 @@ our %EXPORT_TAGS = (
|
||||||
SQLITE_IOERR_CLOSE
|
SQLITE_IOERR_CLOSE
|
||||||
SQLITE_IOERR_COMMIT_ATOMIC
|
SQLITE_IOERR_COMMIT_ATOMIC
|
||||||
SQLITE_IOERR_CONVPATH
|
SQLITE_IOERR_CONVPATH
|
||||||
SQLITE_IOERR_CORRUPTFS
|
|
||||||
SQLITE_IOERR_DATA
|
|
||||||
SQLITE_IOERR_DELETE
|
SQLITE_IOERR_DELETE
|
||||||
SQLITE_IOERR_DELETE_NOENT
|
SQLITE_IOERR_DELETE_NOENT
|
||||||
SQLITE_IOERR_DIR_CLOSE
|
SQLITE_IOERR_DIR_CLOSE
|
||||||
|
@ -603,7 +407,6 @@ our %EXPORT_TAGS = (
|
||||||
SQLITE_IOERR_FSTAT
|
SQLITE_IOERR_FSTAT
|
||||||
SQLITE_IOERR_FSYNC
|
SQLITE_IOERR_FSYNC
|
||||||
SQLITE_IOERR_GETTEMPPATH
|
SQLITE_IOERR_GETTEMPPATH
|
||||||
SQLITE_IOERR_IN_PAGE
|
|
||||||
SQLITE_IOERR_LOCK
|
SQLITE_IOERR_LOCK
|
||||||
SQLITE_IOERR_MMAP
|
SQLITE_IOERR_MMAP
|
||||||
SQLITE_IOERR_NOMEM
|
SQLITE_IOERR_NOMEM
|
||||||
|
@ -621,15 +424,10 @@ our %EXPORT_TAGS = (
|
||||||
SQLITE_IOERR_VNODE
|
SQLITE_IOERR_VNODE
|
||||||
SQLITE_IOERR_WRITE
|
SQLITE_IOERR_WRITE
|
||||||
SQLITE_LOCKED_SHAREDCACHE
|
SQLITE_LOCKED_SHAREDCACHE
|
||||||
SQLITE_LOCKED_VTAB
|
|
||||||
SQLITE_NOTICE_RBU
|
|
||||||
SQLITE_NOTICE_RECOVER_ROLLBACK
|
SQLITE_NOTICE_RECOVER_ROLLBACK
|
||||||
SQLITE_NOTICE_RECOVER_WAL
|
SQLITE_NOTICE_RECOVER_WAL
|
||||||
SQLITE_OK_SYMLINK
|
|
||||||
SQLITE_READONLY_CANTINIT
|
|
||||||
SQLITE_READONLY_CANTLOCK
|
SQLITE_READONLY_CANTLOCK
|
||||||
SQLITE_READONLY_DBMOVED
|
SQLITE_READONLY_DBMOVED
|
||||||
SQLITE_READONLY_DIRECTORY
|
|
||||||
SQLITE_READONLY_RECOVERY
|
SQLITE_READONLY_RECOVERY
|
||||||
SQLITE_READONLY_ROLLBACK
|
SQLITE_READONLY_ROLLBACK
|
||||||
SQLITE_WARNING_AUTOINDEX
|
SQLITE_WARNING_AUTOINDEX
|
||||||
|
@ -637,25 +435,18 @@ our %EXPORT_TAGS = (
|
||||||
|
|
||||||
flags_for_file_open_operations => [qw/
|
flags_for_file_open_operations => [qw/
|
||||||
SQLITE_OPEN_CREATE
|
SQLITE_OPEN_CREATE
|
||||||
SQLITE_OPEN_EXRESCODE
|
|
||||||
SQLITE_OPEN_FULLMUTEX
|
SQLITE_OPEN_FULLMUTEX
|
||||||
SQLITE_OPEN_MEMORY
|
SQLITE_OPEN_MEMORY
|
||||||
SQLITE_OPEN_NOFOLLOW
|
|
||||||
SQLITE_OPEN_NOMUTEX
|
SQLITE_OPEN_NOMUTEX
|
||||||
SQLITE_OPEN_PRIVATECACHE
|
SQLITE_OPEN_PRIVATECACHE
|
||||||
SQLITE_OPEN_READONLY
|
SQLITE_OPEN_READONLY
|
||||||
SQLITE_OPEN_READWRITE
|
SQLITE_OPEN_READWRITE
|
||||||
SQLITE_OPEN_SHAREDCACHE
|
SQLITE_OPEN_SHAREDCACHE
|
||||||
SQLITE_OPEN_SUPER_JOURNAL
|
|
||||||
SQLITE_OPEN_URI
|
SQLITE_OPEN_URI
|
||||||
/],
|
/],
|
||||||
|
|
||||||
function_flags => [qw/
|
function_flags => [qw/
|
||||||
SQLITE_DETERMINISTIC
|
SQLITE_DETERMINISTIC
|
||||||
SQLITE_DIRECTONLY
|
|
||||||
SQLITE_INNOCUOUS
|
|
||||||
SQLITE_RESULT_SUBTYPE
|
|
||||||
SQLITE_SUBTYPE
|
|
||||||
/],
|
/],
|
||||||
|
|
||||||
fundamental_datatypes => [qw/
|
fundamental_datatypes => [qw/
|
||||||
|
@ -663,7 +454,6 @@ our %EXPORT_TAGS = (
|
||||||
SQLITE_FLOAT
|
SQLITE_FLOAT
|
||||||
SQLITE_INTEGER
|
SQLITE_INTEGER
|
||||||
SQLITE_NULL
|
SQLITE_NULL
|
||||||
SQLITE_TEXT
|
|
||||||
/],
|
/],
|
||||||
|
|
||||||
result_codes => [qw/
|
result_codes => [qw/
|
||||||
|
@ -700,21 +490,6 @@ our %EXPORT_TAGS = (
|
||||||
SQLITE_WARNING
|
SQLITE_WARNING
|
||||||
/],
|
/],
|
||||||
|
|
||||||
run_time_limit_categories => [qw/
|
|
||||||
SQLITE_LIMIT_ATTACHED
|
|
||||||
SQLITE_LIMIT_COLUMN
|
|
||||||
SQLITE_LIMIT_COMPOUND_SELECT
|
|
||||||
SQLITE_LIMIT_EXPR_DEPTH
|
|
||||||
SQLITE_LIMIT_FUNCTION_ARG
|
|
||||||
SQLITE_LIMIT_LENGTH
|
|
||||||
SQLITE_LIMIT_LIKE_PATTERN_LENGTH
|
|
||||||
SQLITE_LIMIT_SQL_LENGTH
|
|
||||||
SQLITE_LIMIT_TRIGGER_DEPTH
|
|
||||||
SQLITE_LIMIT_VARIABLE_NUMBER
|
|
||||||
SQLITE_LIMIT_VDBE_OP
|
|
||||||
SQLITE_LIMIT_WORKER_THREADS
|
|
||||||
/],
|
|
||||||
|
|
||||||
);
|
);
|
||||||
$EXPORT_TAGS{version} = $EXPORT_TAGS{compile_time_library_version_numbers};
|
$EXPORT_TAGS{version} = $EXPORT_TAGS{compile_time_library_version_numbers};
|
||||||
$EXPORT_TAGS{file_open} = $EXPORT_TAGS{flags_for_file_open_operations};
|
$EXPORT_TAGS{file_open} = $EXPORT_TAGS{flags_for_file_open_operations};
|
||||||
|
@ -736,24 +511,12 @@ DBD::SQLite::Constants - common SQLite constants
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=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<extended_result_codes>, C<file_open> (C<flags_for_file_open_operations>), C<function_flags>, C<datatypes> (C<fundamental_datatypes>), C<result_codes>. See L<http://sqlite.org/c3ref/constlist.html> for the complete list of constants.
|
||||||
|
|
||||||
This module does not export anything by default.
|
This module does not export anything by default.
|
||||||
|
|
||||||
=head1 CONSTANTS
|
=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
|
=head2 authorizer_action_codes
|
||||||
|
|
||||||
=over 4
|
=over 4
|
||||||
|
@ -846,70 +609,6 @@ This module does not export anything by default.
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
=head2 database_connection_configuration_options
|
|
||||||
|
|
||||||
=over 4
|
|
||||||
|
|
||||||
=item SQLITE_DBCONFIG_LOOKASIDE
|
|
||||||
|
|
||||||
=item SQLITE_DBCONFIG_ENABLE_FKEY
|
|
||||||
|
|
||||||
=item SQLITE_DBCONFIG_ENABLE_TRIGGER
|
|
||||||
|
|
||||||
=item SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
|
|
||||||
|
|
||||||
=item SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION
|
|
||||||
|
|
||||||
=item SQLITE_DBCONFIG_MAINDBNAME
|
|
||||||
|
|
||||||
=item SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE
|
|
||||||
|
|
||||||
=item SQLITE_DBCONFIG_ENABLE_QPSG
|
|
||||||
|
|
||||||
=item SQLITE_DBCONFIG_TRIGGER_EQP
|
|
||||||
|
|
||||||
=item SQLITE_DBCONFIG_MAX
|
|
||||||
|
|
||||||
=item SQLITE_DBCONFIG_RESET_DATABASE
|
|
||||||
|
|
||||||
=item SQLITE_DBCONFIG_DEFENSIVE
|
|
||||||
|
|
||||||
=item SQLITE_DBCONFIG_WRITABLE_SCHEMA
|
|
||||||
|
|
||||||
=item SQLITE_DBCONFIG_LEGACY_ALTER_TABLE
|
|
||||||
|
|
||||||
=item SQLITE_DBCONFIG_DQS_DML
|
|
||||||
|
|
||||||
=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
|
=head2 extended_result_codes
|
||||||
|
|
||||||
=over 4
|
=over 4
|
||||||
|
@ -1030,42 +729,6 @@ This module does not export anything by default.
|
||||||
|
|
||||||
=item SQLITE_IOERR_ROLLBACK_ATOMIC
|
=item SQLITE_IOERR_ROLLBACK_ATOMIC
|
||||||
|
|
||||||
=item SQLITE_ERROR_MISSING_COLLSEQ
|
|
||||||
|
|
||||||
=item SQLITE_ERROR_RETRY
|
|
||||||
|
|
||||||
=item SQLITE_READONLY_CANTINIT
|
|
||||||
|
|
||||||
=item SQLITE_READONLY_DIRECTORY
|
|
||||||
|
|
||||||
=item SQLITE_LOCKED_VTAB
|
|
||||||
|
|
||||||
=item SQLITE_CORRUPT_SEQUENCE
|
|
||||||
|
|
||||||
=item SQLITE_ERROR_SNAPSHOT
|
|
||||||
|
|
||||||
=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
|
=back
|
||||||
|
|
||||||
=head2 file_open (flags_for_file_open_operations)
|
=head2 file_open (flags_for_file_open_operations)
|
||||||
|
@ -1090,12 +753,6 @@ This module does not export anything by default.
|
||||||
|
|
||||||
=item SQLITE_OPEN_MEMORY
|
=item SQLITE_OPEN_MEMORY
|
||||||
|
|
||||||
=item SQLITE_OPEN_NOFOLLOW
|
|
||||||
|
|
||||||
=item SQLITE_OPEN_SUPER_JOURNAL
|
|
||||||
|
|
||||||
=item SQLITE_OPEN_EXRESCODE
|
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
=head2 function_flags
|
=head2 function_flags
|
||||||
|
@ -1104,14 +761,6 @@ This module does not export anything by default.
|
||||||
|
|
||||||
=item SQLITE_DETERMINISTIC
|
=item SQLITE_DETERMINISTIC
|
||||||
|
|
||||||
=item SQLITE_DIRECTONLY
|
|
||||||
|
|
||||||
=item SQLITE_SUBTYPE
|
|
||||||
|
|
||||||
=item SQLITE_INNOCUOUS
|
|
||||||
|
|
||||||
=item SQLITE_RESULT_SUBTYPE
|
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
=head2 datatypes (fundamental_datatypes)
|
=head2 datatypes (fundamental_datatypes)
|
||||||
|
@ -1126,8 +775,6 @@ This module does not export anything by default.
|
||||||
|
|
||||||
=item SQLITE_NULL
|
=item SQLITE_NULL
|
||||||
|
|
||||||
=item SQLITE_TEXT
|
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
=head2 result_codes
|
=head2 result_codes
|
||||||
|
@ -1198,33 +845,3 @@ This module does not export anything by default.
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
=head2 run_time_limit_categories
|
|
||||||
|
|
||||||
=over 4
|
|
||||||
|
|
||||||
=item SQLITE_LIMIT_LENGTH
|
|
||||||
|
|
||||||
=item SQLITE_LIMIT_SQL_LENGTH
|
|
||||||
|
|
||||||
=item SQLITE_LIMIT_COLUMN
|
|
||||||
|
|
||||||
=item SQLITE_LIMIT_EXPR_DEPTH
|
|
||||||
|
|
||||||
=item SQLITE_LIMIT_COMPOUND_SELECT
|
|
||||||
|
|
||||||
=item SQLITE_LIMIT_VDBE_OP
|
|
||||||
|
|
||||||
=item SQLITE_LIMIT_FUNCTION_ARG
|
|
||||||
|
|
||||||
=item SQLITE_LIMIT_ATTACHED
|
|
||||||
|
|
||||||
=item SQLITE_LIMIT_LIKE_PATTERN_LENGTH
|
|
||||||
|
|
||||||
=item SQLITE_LIMIT_VARIABLE_NUMBER
|
|
||||||
|
|
||||||
=item SQLITE_LIMIT_TRIGGER_DEPTH
|
|
||||||
|
|
||||||
=item SQLITE_LIMIT_WORKER_THREADS
|
|
||||||
|
|
||||||
=back
|
|
||||||
|
|
||||||
|
|
|
@ -1,288 +0,0 @@
|
||||||
package DBD::SQLite::GetInfo;
|
|
||||||
|
|
||||||
use 5.006;
|
|
||||||
use strict;
|
|
||||||
use warnings;
|
|
||||||
|
|
||||||
use DBD::SQLite;
|
|
||||||
|
|
||||||
# SQL_DRIVER_VER should be formatted as dd.dd.dddd
|
|
||||||
my $dbdversion = $DBD::SQLite::VERSION;
|
|
||||||
$dbdversion .= '_00' if $dbdversion =~ /^\d+\.\d+$/;
|
|
||||||
my $sql_driver_ver = sprintf("%02d.%02d.%04d", split(/[\._]/, $dbdversion));
|
|
||||||
|
|
||||||
# Full list of keys and their return types: DBI::Const::GetInfo::ODBC
|
|
||||||
|
|
||||||
# Most of the key definitions can be gleaned from:
|
|
||||||
#
|
|
||||||
# https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetinfo-function
|
|
||||||
|
|
||||||
our %info = (
|
|
||||||
20 => 'N', # SQL_ACCESSIBLE_PROCEDURES - No stored procedures to access
|
|
||||||
19 => 'Y', # SQL_ACCESSIBLE_TABLES - SELECT access to all tables in table_info
|
|
||||||
0 => 0, # SQL_ACTIVE_CONNECTIONS - No maximum connection limit
|
|
||||||
116 => 0, # SQL_ACTIVE_ENVIRONMENTS - No "active environment" limit
|
|
||||||
1 => 0, # SQL_ACTIVE_STATEMENTS - No concurrent activity limit
|
|
||||||
169 => 127, # SQL_AGGREGATE_FUNCTIONS - Supports all SQL-92 aggregrate functions
|
|
||||||
117 => 0, # SQL_ALTER_DOMAIN - No ALTER DOMAIN support
|
|
||||||
86 => 1, # SQL_ALTER_TABLE - Only supports ADD COLUMN and table rename (not listed in enum) in ALTER TABLE statements
|
|
||||||
10021 => 0, # SQL_ASYNC_MODE - No asynchronous support (in vanilla SQLite)
|
|
||||||
120 => 0, # SQL_BATCH_ROW_COUNT - No special row counting access
|
|
||||||
121 => 0, # SQL_BATCH_SUPPORT - No batches
|
|
||||||
82 => 0, # SQL_BOOKMARK_PERSISTENCE - No bookmark support
|
|
||||||
114 => 1, # SQL_CATALOG_LOCATION - Database comes first in identifiers
|
|
||||||
10003 => 'Y', # SQL_CATALOG_NAME - Supports database names
|
|
||||||
41 => '.', # SQL_CATALOG_NAME_SEPARATOR - Separated by dot
|
|
||||||
42 => 'database', # SQL_CATALOG_TERM - SQLite calls catalogs databases
|
|
||||||
92 => 1+4+8, # SQL_CATALOG_USAGE - Supported in calls to DML & table/index definiton (no procedures or permissions)
|
|
||||||
10004 => 'UTF-8', # SQL_COLLATION_SEQ - SQLite 3 uses UTF-8 by default
|
|
||||||
87 => 'Y', # SQL_COLUMN_ALIAS - Supports column aliases
|
|
||||||
22 => 0, # SQL_CONCAT_NULL_BEHAVIOR - 'a'||NULL = NULL
|
|
||||||
|
|
||||||
# SQLite has no CONVERT function, only CAST. However, it converts to every "affinity" it supports.
|
|
||||||
#
|
|
||||||
# The only SQL_CVT_* types it doesn't support are date/time types, as it has no concept of
|
|
||||||
# date/time values once inserted. These are only convertable to text-like types. GUIDs are in
|
|
||||||
# the same boat, having no real means of switching to a numeric format.
|
|
||||||
#
|
|
||||||
# text/binary types = 31723265
|
|
||||||
# numeric types = 28926
|
|
||||||
# date/time types = 1802240
|
|
||||||
# total = 33554431
|
|
||||||
|
|
||||||
48 => 1, # SQL_CONVERT_FUNCTIONS - CAST only
|
|
||||||
|
|
||||||
53 => 31723265+28926, # SQL_CONVERT_BIGINT
|
|
||||||
54 => 31723265+28926, # SQL_CONVERT_BINARY
|
|
||||||
55 => 31723265+28926, # SQL_CONVERT_BIT
|
|
||||||
56 => 33554431, # SQL_CONVERT_CHAR
|
|
||||||
57 => 31723265+1802240, # SQL_CONVERT_DATE
|
|
||||||
58 => 31723265+28926, # SQL_CONVERT_DECIMAL
|
|
||||||
59 => 31723265+28926, # SQL_CONVERT_DOUBLE
|
|
||||||
60 => 31723265+28926, # SQL_CONVERT_FLOAT
|
|
||||||
173 => 31723265, # SQL_CONVERT_GUID
|
|
||||||
61 => 31723265+28926, # SQL_CONVERT_INTEGER
|
|
||||||
123 => 31723265+1802240, # SQL_CONVERT_INTERVAL_DAY_TIME
|
|
||||||
124 => 31723265+1802240, # SQL_CONVERT_INTERVAL_YEAR_MONTH
|
|
||||||
71 => 31723265+28926, # SQL_CONVERT_LONGVARBINARY
|
|
||||||
62 => 31723265+28926, # SQL_CONVERT_LONGVARCHAR
|
|
||||||
63 => 31723265+28926, # SQL_CONVERT_NUMERIC
|
|
||||||
64 => 31723265+28926, # SQL_CONVERT_REAL
|
|
||||||
65 => 31723265+28926, # SQL_CONVERT_SMALLINT
|
|
||||||
66 => 31723265+1802240, # SQL_CONVERT_TIME
|
|
||||||
67 => 31723265+1802240, # SQL_CONVERT_TIMESTAMP
|
|
||||||
68 => 31723265+28926, # SQL_CONVERT_TINYINT
|
|
||||||
69 => 33554431, # SQL_CONVERT_VARBINARY
|
|
||||||
70 => 33554431, # SQL_CONVERT_VARCHAR
|
|
||||||
122 => 33554431, # SQL_CONVERT_WCHAR
|
|
||||||
125 => 33554431, # SQL_CONVERT_WLONGVARCHAR
|
|
||||||
126 => 33554431, # SQL_CONVERT_WVARCHAR
|
|
||||||
|
|
||||||
74 => 1, # SQL_CORRELATION_NAME - Table aliases are supported, but must be named differently
|
|
||||||
127 => 0, # SQL_CREATE_ASSERTION - No CREATE ASSERTION support
|
|
||||||
128 => 0, # SQL_CREATE_CHARACTER_SET - No CREATE CHARACTER SET support
|
|
||||||
129 => 0, # SQL_CREATE_COLLATION - No CREATE COLLATION support
|
|
||||||
130 => 0, # SQL_CREATE_DOMAIN - No CREATE DOMAIN support
|
|
||||||
131 => 0, # SQL_CREATE_SCHEMA - No CREATE SCHEMA support
|
|
||||||
132 => 16383-2-8-4096, # SQL_CREATE_TABLE - Most of the functionality of CREATE TABLE support
|
|
||||||
133 => 0, # SQL_CREATE_TRANSLATION - No CREATE TRANSLATION support
|
|
||||||
134 => 1, # SQL_CREATE_VIEW - CREATE VIEW, no WITH CHECK OPTION support
|
|
||||||
|
|
||||||
23 => 2, # SQL_CURSOR_COMMIT_BEHAVIOR - Cursors are preserved
|
|
||||||
24 => 2, # SQL_CURSOR_ROLLBACK_BEHAVIOR - Cursors are preserved
|
|
||||||
10001 => 0, # SQL_CURSOR_SENSITIVITY - Cursors have a concept of snapshots, though this depends on the transaction type
|
|
||||||
|
|
||||||
2 => \&sql_data_source_name, # SQL_DATA_SOURCE_NAME - The DSN
|
|
||||||
25 => \&sql_data_source_read_only, # SQL_DATA_SOURCE_READ_ONLY - Might have a SQLITE_OPEN_READONLY flag
|
|
||||||
16 => \&sql_database_name, # SQL_DATABASE_NAME - Self-explanatory
|
|
||||||
119 => 0, # SQL_DATETIME_LITERALS - No support for SQL-92's super weird date/time literal format (ie: {d '2999-12-12'})
|
|
||||||
17 => 'SQLite', # SQL_DBMS_NAME - You are here
|
|
||||||
18 => \&sql_dbms_ver, # SQL_DBMS_VER - This driver version
|
|
||||||
170 => 1+2, # SQL_DDL_INDEX - Supports CREATE/DROP INDEX
|
|
||||||
26 => 8, # SQL_DEFAULT_TXN_ISOLATION - Default is SERIALIZABLE (See "PRAGMA read_uncommitted")
|
|
||||||
10002 => 'N', # SQL_DESCRIBE_PARAMETER - No DESCRIBE INPUT support
|
|
||||||
|
|
||||||
# XXX: MySQL/Oracle fills in HDBC and HENV, but information on what should actually go there is
|
|
||||||
# hard to acquire.
|
|
||||||
|
|
||||||
# 171 => undef, # SQL_DM_VER - Not a Driver Manager
|
|
||||||
# 3 => undef, # SQL_DRIVER_HDBC - Not a Driver Manager
|
|
||||||
# 135 => undef, # SQL_DRIVER_HDESC - Not a Driver Manager
|
|
||||||
# 4 => undef, # SQL_DRIVER_HENV - Not a Driver Manager
|
|
||||||
# 76 => undef, # SQL_DRIVER_HLIB - Not a Driver Manager
|
|
||||||
# 5 => undef, # SQL_DRIVER_HSTMT - Not a Driver Manager
|
|
||||||
6 => 'libsqlite3odbc.so', # SQL_DRIVER_NAME - SQLite3 ODBC driver (if installed)
|
|
||||||
77 => '03.00', # SQL_DRIVER_ODBC_VER - Same as sqlite3odbc.c
|
|
||||||
7 => $sql_driver_ver, # SQL_DRIVER_VER - Self-explanatory
|
|
||||||
|
|
||||||
136 => 0, # SQL_DROP_ASSERTION - No DROP ASSERTION support
|
|
||||||
137 => 0, # SQL_DROP_CHARACTER_SET - No DROP CHARACTER SET support
|
|
||||||
138 => 0, # SQL_DROP_COLLATION - No DROP COLLATION support
|
|
||||||
139 => 0, # SQL_DROP_DOMAIN - No DROP DOMAIN support
|
|
||||||
140 => 0, # SQL_DROP_SCHEMA - No DROP SCHEMA support
|
|
||||||
141 => 1, # SQL_DROP_TABLE - DROP TABLE support, no RESTRICT/CASCADE
|
|
||||||
142 => 0, # SQL_DROP_TRANSLATION - No DROP TRANSLATION support
|
|
||||||
143 => 1, # SQL_DROP_VIEW - DROP VIEW support, no RESTRICT/CASCADE
|
|
||||||
|
|
||||||
# NOTE: This is based purely on what sqlite3odbc supports.
|
|
||||||
#
|
|
||||||
# Static CA1: NEXT, ABSOLUTE, RELATIVE, BOOKMARK, LOCK_NO_CHANGE, POSITION, UPDATE, DELETE, REFRESH,
|
|
||||||
# BULK_ADD, BULK_UPDATE_BY_BOOKMARK, BULK_DELETE_BY_BOOKMARK = 466511
|
|
||||||
#
|
|
||||||
# Forward-only CA1: NEXT, BOOKMARK
|
|
||||||
#
|
|
||||||
# CA2: READ_ONLY_CONCURRENCY, LOCK_CONCURRENCY
|
|
||||||
|
|
||||||
144 => 0, # SQL_DYNAMIC_CURSOR_ATTRIBUTES1 - No dynamic cursor support
|
|
||||||
145 => 0, # SQL_DYNAMIC_CURSOR_ATTRIBUTES2 - No dynamic cursor support
|
|
||||||
146 => 1+8, # SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1
|
|
||||||
147 => 1+2, # SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2
|
|
||||||
150 => 0, # SQL_KEYSET_CURSOR_ATTRIBUTES1 - No keyset cursor support
|
|
||||||
151 => 0, # SQL_KEYSET_CURSOR_ATTRIBUTES2 - No keyset cursor support
|
|
||||||
167 => 466511, # SQL_STATIC_CURSOR_ATTRIBUTES1
|
|
||||||
168 => 1+2, # SQL_STATIC_CURSOR_ATTRIBUTES2
|
|
||||||
|
|
||||||
27 => 'Y', # SQL_EXPRESSIONS_IN_ORDERBY - ORDER BY allows expressions
|
|
||||||
8 => 63, # SQL_FETCH_DIRECTION - Cursors support next, first, last, prior, absolute, relative
|
|
||||||
84 => 2, # SQL_FILE_USAGE - Single-tier driver, treats files as databases
|
|
||||||
81 => 1+2+8, # SQL_GETDATA_EXTENSIONS - Same as sqlite3odbc.c
|
|
||||||
88 => 3, # SQL_GROUP_BY - SELECT columns are independent of GROUP BY columns
|
|
||||||
28 => 4, # SQL_IDENTIFIER_CASE - Not case-sensitive, stored in mixed case
|
|
||||||
29 => '"', # SQL_IDENTIFIER_QUOTE_CHAR - Uses " for identifiers, though supports [] and ` as well
|
|
||||||
148 => 0, # SQL_INDEX_KEYWORDS - No support for ASC/DESC/ALL for CREATE INDEX
|
|
||||||
149 => 0, # SQL_INFO_SCHEMA_VIEWS - No support for INFORMATION_SCHEMA
|
|
||||||
172 => 1+2, # SQL_INSERT_STATEMENT - INSERT...VALUES & INSERT...SELECT
|
|
||||||
73 => 'N', # SQL_INTEGRITY - No support for "Integrity Enhancement Facility"
|
|
||||||
89 => \&sql_keywords, # SQL_KEYWORDS - List of non-ODBC keywords
|
|
||||||
113 => 'Y', # SQL_LIKE_ESCAPE_CLAUSE - Supports LIKE...ESCAPE
|
|
||||||
78 => 1, # SQL_LOCK_TYPES - Only NO_CHANGE
|
|
||||||
|
|
||||||
10022 => 0, # SQL_MAX_ASYNC_CONCURRENT_STATEMENTS - No async mode
|
|
||||||
112 => 1_000_000, # SQL_MAX_BINARY_LITERAL_LEN - SQLITE_MAX_SQL_LENGTH
|
|
||||||
34 => 1_000_000, # SQL_MAX_CATALOG_NAME_LEN - SQLITE_MAX_SQL_LENGTH
|
|
||||||
108 => 1_000_000, # SQL_MAX_CHAR_LITERAL_LEN - SQLITE_MAX_SQL_LENGTH
|
|
||||||
97 => 2000, # SQL_MAX_COLUMNS_IN_GROUP_BY - SQLITE_MAX_COLUMN
|
|
||||||
98 => 2000, # SQL_MAX_COLUMNS_IN_INDEX - SQLITE_MAX_COLUMN
|
|
||||||
99 => 2000, # SQL_MAX_COLUMNS_IN_ORDER_BY - SQLITE_MAX_COLUMN
|
|
||||||
100 => 2000, # SQL_MAX_COLUMNS_IN_SELECT - SQLITE_MAX_COLUMN
|
|
||||||
101 => 2000, # SQL_MAX_COLUMNS_IN_TABLE - SQLITE_MAX_COLUMN
|
|
||||||
30 => 1_000_000, # SQL_MAX_COLUMN_NAME_LEN - SQLITE_MAX_SQL_LENGTH
|
|
||||||
1 => 1021, # SQL_MAX_CONCURRENT_ACTIVITIES - Typical filehandle limits
|
|
||||||
31 => 1_000_000, # SQL_MAX_CURSOR_NAME_LEN - SQLITE_MAX_SQL_LENGTH
|
|
||||||
0 => 1021, # SQL_MAX_DRIVER_CONNECTIONS - Typical filehandle limits
|
|
||||||
10005 => 1_000_000, # SQL_MAX_IDENTIFIER_LEN - SQLITE_MAX_SQL_LENGTH
|
|
||||||
102 => 2147483646*65536, # SQL_MAX_INDEX_SIZE - Tied to DB size, which is theortically 140TB
|
|
||||||
32 => 1_000_000, # SQL_MAX_OWNER_NAME_LEN - SQLITE_MAX_SQL_LENGTH
|
|
||||||
33 => 1_000_000, # SQL_MAX_PROCEDURE_NAME_LEN - SQLITE_MAX_SQL_LENGTH
|
|
||||||
34 => 1_000_000, # SQL_MAX_QUALIFIER_NAME_LEN - SQLITE_MAX_SQL_LENGTH
|
|
||||||
104 => 1_000_000, # SQL_MAX_ROW_SIZE - SQLITE_MAX_SQL_LENGTH (since INSERT has to be used)
|
|
||||||
103 => 'Y', # SQL_MAX_ROW_SIZE_INCLUDES_LONG
|
|
||||||
32 => 1_000_000, # SQL_MAX_SCHEMA_NAME_LEN - SQLITE_MAX_SQL_LENGTH
|
|
||||||
105 => 1_000_000, # SQL_MAX_STATEMENT_LEN - SQLITE_MAX_SQL_LENGTH
|
|
||||||
106 => 64, # SQL_MAX_TABLES_IN_SELECT - 64 tables, because of the bitmap in the query optimizer
|
|
||||||
35 => 1_000_000, # SQL_MAX_TABLE_NAME_LEN - SQLITE_MAX_SQL_LENGTH
|
|
||||||
107 => 0, # SQL_MAX_USER_NAME_LEN - No user support
|
|
||||||
|
|
||||||
37 => 'Y', # SQL_MULTIPLE_ACTIVE_TXN - Supports mulitple txns, though not nested
|
|
||||||
36 => 'N', # SQL_MULT_RESULT_SETS - No batches
|
|
||||||
111 => 'N', # SQL_NEED_LONG_DATA_LEN - Doesn't care about LONG
|
|
||||||
75 => 1, # SQL_NON_NULLABLE_COLUMNS - Supports NOT NULL
|
|
||||||
85 => 1, # SQL_NULL_COLLATION - NULLs first on ASC (low end)
|
|
||||||
49 => 4194304+1, # SQL_NUMERIC_FUNCTIONS - Just ABS & ROUND (has RANDOM, but not RAND)
|
|
||||||
|
|
||||||
9 => 1, # SQL_ODBC_API_CONFORMANCE - Same as sqlite3odbc.c
|
|
||||||
152 => 1, # SQL_ODBC_INTERFACE_CONFORMANCE - Same as sqlite3odbc.c
|
|
||||||
12 => 0, # SQL_ODBC_SAG_CLI_CONFORMANCE - Same as sqlite3odbc.c
|
|
||||||
15 => 0, # SQL_ODBC_SQL_CONFORMANCE - Same as sqlite3odbc.c
|
|
||||||
10 => '03.00', # SQL_ODBC_VER - Same as sqlite3odbc.c
|
|
||||||
|
|
||||||
115 => 1+8+16+32+64, # SQL_OJ_CAPABILITIES - Supports all OUTER JOINs except RIGHT & FULL
|
|
||||||
90 => 'N', # SQL_ORDER_BY_COLUMNS_IN_SELECT - ORDER BY columns don't have to be in the SELECT list
|
|
||||||
38 => 'Y', # SQL_OUTER_JOINS - Supports OUTER JOINs
|
|
||||||
153 => 2, # SQL_PARAM_ARRAY_ROW_COUNTS - Only has row counts for executed statements
|
|
||||||
154 => 3, # SQL_PARAM_ARRAY_SELECTS - No support for arrays of parameters
|
|
||||||
80 => 0, # SQL_POSITIONED_STATEMENTS - No support for positioned statements (WHERE CURRENT OF or SELECT FOR UPDATE)
|
|
||||||
79 => 31, # SQL_POS_OPERATIONS - Supports all SQLSetPos operations
|
|
||||||
21 => 'N', # SQL_PROCEDURES - No procedures
|
|
||||||
40 => '', # SQL_PROCEDURE_TERM - No procedures
|
|
||||||
93 => 4, # SQL_QUOTED_IDENTIFIER_CASE - Even quoted identifiers are case-insensitive
|
|
||||||
11 => 'N', # SQL_ROW_UPDATES - No fancy cursor update support
|
|
||||||
39 => '', # SQL_SCHEMA_TERM - No schemas
|
|
||||||
91 => 0, # SQL_SCHEMA_USAGE - No schemas
|
|
||||||
43 => 2, # SQL_SCROLL_CONCURRENCY - Updates/deletes on cursors lock the database
|
|
||||||
44 => 1+16, # SQL_SCROLL_OPTIONS - Only supports static & forward-only cursors
|
|
||||||
14 => '\\', # SQL_SEARCH_PATTERN_ESCAPE - Default escape character for LIKE is \
|
|
||||||
13 => \&sql_server_name, # SQL_SERVER_NAME - Just $dbh->{Name}
|
|
||||||
94 => '', # SQL_SPECIAL_CHARACTERS - Other drivers tend to stick to the ASCII/Latin-1 range, and SQLite uses all of
|
|
||||||
# the lower 7-bit punctuation for other things
|
|
||||||
|
|
||||||
155 => 7, # SQL_SQL92_DATETIME_FUNCTIONS - Supports CURRENT_(DATE|TIME|TIMESTAMP)
|
|
||||||
156 => 1+2+4+8, # SQL_SQL92_FOREIGN_KEY_DELETE_RULE - Support all ON DELETE options
|
|
||||||
157 => 1+2+4+8, # SQL_SQL92_FOREIGN_KEY_UPDATE_RULE - Support all ON UPDATE options
|
|
||||||
158 => 0, # SQL_SQL92_GRANT - No users; no support for GRANT
|
|
||||||
159 => 0, # SQL_SQL92_NUMERIC_VALUE_FUNCTIONS - No support for any of the listed functions
|
|
||||||
160 => 1+2+4+512+1024+2048+4096+8192, # SQL_SQL92_PREDICATES - Supports the important comparison operators
|
|
||||||
161 => 2+16+64+128, # SQL_SQL92_RELATIONAL_JOIN_OPERATORS - Supports the important ones except RIGHT/FULL OUTER JOINs
|
|
||||||
162 => 0, # SQL_SQL92_REVOKE - No users; no support for REVOKE
|
|
||||||
163 => 1+2+8, # SQL_SQL92_ROW_VALUE_CONSTRUCTOR - Supports most row value constructors
|
|
||||||
164 => 2+4, # SQL_SQL92_STRING_FUNCTIONS - Just UPPER & LOWER (has SUBSTR, but not SUBSTRING and SQL-92's weird TRIM syntax)
|
|
||||||
165 => 1+2+4+8, # SQL_SQL92_VALUE_EXPRESSIONS - Supports all SQL-92 value expressions
|
|
||||||
|
|
||||||
118 => 1, # SQL_SQL_CONFORMANCE - SQL-92 Entry level
|
|
||||||
83 => 0, # SQL_STATIC_SENSITIVITY - Cursors would lock the DB, so only old data is visible
|
|
||||||
50 => 8+16+256+1024+16384+131072, # SQL_STRING_FUNCTIONS - LTRIM, LENGTH, REPLACE, RTRIM, CHAR, SOUNDEX
|
|
||||||
95 => 1+2+4+8+16, # SQL_SUBQUERIES - Supports all of the subquery types
|
|
||||||
51 => 4, # SQL_SYSTEM_FUNCTIONS - Only IFNULL
|
|
||||||
45 => 'table', # SQL_TABLE_TERM - Tables are called tables
|
|
||||||
109 => 0, # SQL_TIMEDATE_ADD_INTERVALS - No support for INTERVAL
|
|
||||||
110 => 0, # SQL_TIMEDATE_DIFF_INTERVALS - No support for INTERVAL
|
|
||||||
52 => 0x20000+0x40000+0x80000, # SQL_TIMEDATE_FUNCTIONS - Only supports CURRENT_(DATE|TIME|TIMESTAMP)
|
|
||||||
46 => 2, # SQL_TXN_CAPABLE - Full transaction support for both DML & DDL
|
|
||||||
72 => 1+8, # SQL_TXN_ISOLATION_OPTION - Supports read uncommitted and serializable
|
|
||||||
96 => 1+2, # SQL_UNION - Supports UNION and UNION ALL
|
|
||||||
47 => '', # SQL_USER_NAME - No users
|
|
||||||
|
|
||||||
166 => 1, # SQL_STANDARD_CLI_CONFORMANCE - X/Open CLI Version 1.0
|
|
||||||
10000 => 1992, # SQL_XOPEN_CLI_YEAR - Year for V1.0
|
|
||||||
);
|
|
||||||
|
|
||||||
sub sql_dbms_ver {
|
|
||||||
my $dbh = shift;
|
|
||||||
return $dbh->FETCH('sqlite_version');
|
|
||||||
}
|
|
||||||
|
|
||||||
sub sql_data_source_name {
|
|
||||||
my $dbh = shift;
|
|
||||||
return "dbi:SQLite:".$dbh->{Name};
|
|
||||||
}
|
|
||||||
|
|
||||||
sub sql_data_source_read_only {
|
|
||||||
my $dbh = shift;
|
|
||||||
my $flags = $dbh->FETCH('sqlite_open_flags') || 0;
|
|
||||||
return $dbh->{ReadOnly} || ($flags & DBD::SQLite::OPEN_READONLY()) ? 'Y' : 'N';
|
|
||||||
}
|
|
||||||
|
|
||||||
sub sql_database_name {
|
|
||||||
my $dbh = shift;
|
|
||||||
my $databases = $dbh->selectall_hashref('PRAGMA database_list', 'seq');
|
|
||||||
return $databases->{0}{name};
|
|
||||||
}
|
|
||||||
|
|
||||||
sub sql_keywords {
|
|
||||||
# SQLite keywords minus ODBC keywords
|
|
||||||
return join ',', (qw<
|
|
||||||
ABORT AFTER ANALYZE ATTACH AUTOINCREMENT BEFORE CONFLICT DATABASE DETACH EACH EXCLUSIVE
|
|
||||||
EXPLAIN FAIL GLOB IF IGNORE INDEXED INSTEAD ISNULL LIMIT NOTNULL OFFSET
|
|
||||||
PLAN PRAGMA QUERY RAISE RECURSIVE REGEXP REINDEX RELEASE RENAME REPLACE ROW
|
|
||||||
SAVEPOINT TEMP TRIGGER VACUUM VIRTUAL WITHOUT
|
|
||||||
>);
|
|
||||||
}
|
|
||||||
|
|
||||||
sub sql_server_name {
|
|
||||||
my $dbh = shift;
|
|
||||||
return $dbh->{Name};
|
|
||||||
}
|
|
||||||
|
|
||||||
1;
|
|
||||||
|
|
||||||
__END__
|
|
|
@ -5,7 +5,7 @@ use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use Scalar::Util qw/weaken/;
|
use Scalar::Util qw/weaken/;
|
||||||
|
|
||||||
our $VERSION = '1.76';
|
our $VERSION = '1.55_07';
|
||||||
our @ISA;
|
our @ISA;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ sub BEST_INDEX {
|
||||||
# in FILTER() for deciding which rows match the constraints.
|
# in FILTER() for deciding which rows match the constraints.
|
||||||
my @conditions;
|
my @conditions;
|
||||||
my $ix = 0;
|
my $ix = 0;
|
||||||
foreach my $constraint (grep {$_->{usable} and exists $SQLOP2PERLOP{ $_->{op} } } @$constraints) {
|
foreach my $constraint (grep {$_->{usable}} @$constraints) {
|
||||||
my $col = $constraint->{col};
|
my $col = $constraint->{col};
|
||||||
my ($member, $optype);
|
my ($member, $optype);
|
||||||
|
|
||||||
|
@ -389,7 +389,7 @@ time. Here is a way to do it with a virtual table :
|
||||||
my @files = ... ; # list of files to inspect
|
my @files = ... ; # list of files to inspect
|
||||||
|
|
||||||
# apply the L<stat> function to each file
|
# apply the L<stat> function to each file
|
||||||
our $file_stats = [ map { [ $_, stat $_ ] } @files];
|
our $file_stats = [ map {($_, stat $_)} @files];
|
||||||
|
|
||||||
# create a temporary virtual table
|
# create a temporary virtual table
|
||||||
$dbh->do(<<"");
|
$dbh->do(<<"");
|
||||||
|
|
138
sqlite3ext.h
138
sqlite3ext.h
|
@ -295,77 +295,6 @@ struct sqlite3_api_routines {
|
||||||
int (*vtab_nochange)(sqlite3_context*);
|
int (*vtab_nochange)(sqlite3_context*);
|
||||||
int (*value_nochange)(sqlite3_value*);
|
int (*value_nochange)(sqlite3_value*);
|
||||||
const char *(*vtab_collation)(sqlite3_index_info*,int);
|
const char *(*vtab_collation)(sqlite3_index_info*,int);
|
||||||
/* Version 3.24.0 and later */
|
|
||||||
int (*keyword_count)(void);
|
|
||||||
int (*keyword_name)(int,const char**,int*);
|
|
||||||
int (*keyword_check)(const char*,int);
|
|
||||||
sqlite3_str *(*str_new)(sqlite3*);
|
|
||||||
char *(*str_finish)(sqlite3_str*);
|
|
||||||
void (*str_appendf)(sqlite3_str*, const char *zFormat, ...);
|
|
||||||
void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list);
|
|
||||||
void (*str_append)(sqlite3_str*, const char *zIn, int N);
|
|
||||||
void (*str_appendall)(sqlite3_str*, const char *zIn);
|
|
||||||
void (*str_appendchar)(sqlite3_str*, int N, char C);
|
|
||||||
void (*str_reset)(sqlite3_str*);
|
|
||||||
int (*str_errcode)(sqlite3_str*);
|
|
||||||
int (*str_length)(sqlite3_str*);
|
|
||||||
char *(*str_value)(sqlite3_str*);
|
|
||||||
/* Version 3.25.0 and later */
|
|
||||||
int (*create_window_function)(sqlite3*,const char*,int,int,void*,
|
|
||||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
|
||||||
void (*xFinal)(sqlite3_context*),
|
|
||||||
void (*xValue)(sqlite3_context*),
|
|
||||||
void (*xInv)(sqlite3_context*,int,sqlite3_value**),
|
|
||||||
void(*xDestroy)(void*));
|
|
||||||
/* Version 3.26.0 and later */
|
|
||||||
const char *(*normalized_sql)(sqlite3_stmt*);
|
|
||||||
/* 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*));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -634,71 +563,8 @@ typedef int (*sqlite3_loadext_entry)(
|
||||||
#define sqlite3_value_pointer sqlite3_api->value_pointer
|
#define sqlite3_value_pointer sqlite3_api->value_pointer
|
||||||
/* Version 3.22.0 and later */
|
/* Version 3.22.0 and later */
|
||||||
#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange
|
#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange
|
||||||
#define sqlite3_value_nochange sqlite3_api->value_nochange
|
#define sqlite3_value_nochange sqltie3_api->value_nochange
|
||||||
#define sqlite3_vtab_collation sqlite3_api->vtab_collation
|
#define sqlite3_vtab_collation sqltie3_api->vtab_collation
|
||||||
/* Version 3.24.0 and later */
|
|
||||||
#define sqlite3_keyword_count sqlite3_api->keyword_count
|
|
||||||
#define sqlite3_keyword_name sqlite3_api->keyword_name
|
|
||||||
#define sqlite3_keyword_check sqlite3_api->keyword_check
|
|
||||||
#define sqlite3_str_new sqlite3_api->str_new
|
|
||||||
#define sqlite3_str_finish sqlite3_api->str_finish
|
|
||||||
#define sqlite3_str_appendf sqlite3_api->str_appendf
|
|
||||||
#define sqlite3_str_vappendf sqlite3_api->str_vappendf
|
|
||||||
#define sqlite3_str_append sqlite3_api->str_append
|
|
||||||
#define sqlite3_str_appendall sqlite3_api->str_appendall
|
|
||||||
#define sqlite3_str_appendchar sqlite3_api->str_appendchar
|
|
||||||
#define sqlite3_str_reset sqlite3_api->str_reset
|
|
||||||
#define sqlite3_str_errcode sqlite3_api->str_errcode
|
|
||||||
#define sqlite3_str_length sqlite3_api->str_length
|
|
||||||
#define sqlite3_str_value sqlite3_api->str_value
|
|
||||||
/* Version 3.25.0 and later */
|
|
||||||
#define sqlite3_create_window_function sqlite3_api->create_window_function
|
|
||||||
/* 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
|
|
||||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||||
|
|
||||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
# Test that everything compiles, so the rest of the test suite can
|
# Test that everything compiles, so the rest of the test suite can
|
||||||
# load modules without having to check if it worked.
|
# load modules without having to check if it worked.
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
use Test::More;
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
use Test::More tests => 3;
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
|
|
||||||
|
@ -17,5 +23,3 @@ if (my @compile_options = DBD::SQLite::compile_options()) {
|
||||||
diag("Compile Options:");
|
diag("Compile Options:");
|
||||||
diag(join "", map { " $_\n" } @compile_options);
|
diag(join "", map { " $_\n" } @compile_options);
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
20
t/02_logon.t
20
t/02_logon.t
|
@ -1,15 +1,19 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
# Tests basic login and pragma setting
|
# Tests basic login and pragma setting
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest qw/connect_ok @CALL_FUNCS/;
|
use SQLiteTest qw/connect_ok @CALL_FUNCS/;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
use DBD::SQLite::Constants ':dbd_sqlite_string_mode';
|
plan tests => 20 * @CALL_FUNCS + 1;
|
||||||
|
|
||||||
my $unicode_opt = DBD_SQLITE_STRING_MODE_UNICODE_STRICT;
|
|
||||||
|
|
||||||
my $show_diag = 0;
|
my $show_diag = 0;
|
||||||
foreach my $call_func (@CALL_FUNCS) {
|
foreach my $call_func (@CALL_FUNCS) {
|
||||||
|
@ -34,9 +38,9 @@ foreach my $call_func (@CALL_FUNCS) {
|
||||||
skip( 'Unicode is not supported before 5.8.5', 2 );
|
skip( 'Unicode is not supported before 5.8.5', 2 );
|
||||||
}
|
}
|
||||||
my $file = 'foo'.$$;
|
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' );
|
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;
|
$dbh->disconnect;
|
||||||
unlink $file;
|
unlink $file;
|
||||||
}
|
}
|
||||||
|
@ -61,5 +65,3 @@ foreach my $call_func (@CALL_FUNCS) {
|
||||||
isa_ok( $dbh, 'DBI::db' );
|
isa_ok( $dbh, 'DBI::db' );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
# Tests simple table creation
|
# Tests simple table creation
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More tests => 7;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
my $dbh = connect_ok();
|
my $dbh = connect_ok();
|
||||||
$dbh->do(<<'END_SQL');
|
$dbh->do(<<'END_SQL');
|
||||||
|
@ -29,4 +35,3 @@ my $names = $sth->{NAME};
|
||||||
is( scalar(@$names), 4, 'Got 4 columns' );
|
is( scalar(@$names), 4, 'Got 4 columns' );
|
||||||
is_deeply( $names, [ 'f1', 'f1', 'f2', 'f3' ], 'Table prepending is disabled by default' );
|
is_deeply( $names, [ 'f1', 'f1', 'f2', 'f3' ], 'Table prepending is disabled by default' );
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More tests => 14;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
my $dbh = connect_ok();
|
my $dbh = connect_ok();
|
||||||
|
|
||||||
|
@ -34,5 +40,3 @@ SCOPE: {
|
||||||
}
|
}
|
||||||
|
|
||||||
is( $dbh->do("delete from f where f1='test'"), 3 );
|
is( $dbh->do("delete from f where f1='test'"), 3 );
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More tests => 22;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
my $dbh = connect_ok( RaiseError => 1 );
|
my $dbh = connect_ok( RaiseError => 1 );
|
||||||
$dbh->do("CREATE TABLE f (f1, f2, f3)");
|
$dbh->do("CREATE TABLE f (f1, f2, f3)");
|
||||||
|
@ -55,5 +61,3 @@ while ($row = $sth->fetch) {
|
||||||
ok($num_rows == 1);
|
ok($num_rows == 1);
|
||||||
$sth->finish;
|
$sth->finish;
|
||||||
$dbh->do("delete from f where f1='test'");
|
$dbh->do("delete from f where f1='test'");
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
14
t/06_tran.t
14
t/06_tran.t
|
@ -1,9 +1,15 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More tests => 6;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
my $dbh = connect_ok(
|
my $dbh = connect_ok(
|
||||||
AutoCommit => 0,
|
AutoCommit => 0,
|
||||||
|
@ -48,5 +54,3 @@ $dbh->rollback;
|
||||||
);
|
);
|
||||||
ok !$dbh->{sqlite_use_immediate_transaction}, "sqlite_use_immediate_transaction is false if you set explicitly";
|
ok !$dbh->{sqlite_use_immediate_transaction}, "sqlite_use_immediate_transaction is false if you set explicitly";
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
22
t/07_error.t
22
t/07_error.t
|
@ -1,9 +1,15 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More tests => 8;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
my $dbh = connect_ok( RaiseError => 1, PrintError => 0 );
|
my $dbh = connect_ok( RaiseError => 1, PrintError => 0 );
|
||||||
eval {
|
eval {
|
||||||
|
@ -24,13 +30,3 @@ eval {
|
||||||
ok($@, 'Statement 2 generated an error');
|
ok($@, 'Statement 2 generated an error');
|
||||||
is( $DBI::err, 19, '$DBI::err ok' );
|
is( $DBI::err, 19, '$DBI::err ok' );
|
||||||
like( $DBI::errstr, qr/column a is not unique|UNIQUE constraint failed/, '$DBI::errstr 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;
|
|
||||||
|
|
14
t/08_busy.t
14
t/08_busy.t
|
@ -1,11 +1,19 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
# Test that two processes can write at once, assuming we commit timely.
|
# Test that two processes can write at once, assuming we commit timely.
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest qw/connect_ok dbfile @CALL_FUNCS/;
|
use SQLiteTest qw/connect_ok dbfile @CALL_FUNCS/;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
|
plan tests => 11 * @CALL_FUNCS + 1;
|
||||||
|
|
||||||
foreach my $call_func (@CALL_FUNCS) {
|
foreach my $call_func (@CALL_FUNCS) {
|
||||||
|
|
||||||
|
@ -117,5 +125,3 @@ foreach my $call_func (@CALL_FUNCS) {
|
||||||
unlink $dbfile;
|
unlink $dbfile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,20 +1,26 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use 5.00503;
|
use 5.00503;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest qw/connect_ok @CALL_FUNCS/;
|
use SQLiteTest qw/connect_ok @CALL_FUNCS/;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
use DBD::SQLite;
|
use DBD::SQLite;
|
||||||
use DBD::SQLite::Constants;
|
use DBD::SQLite::Constants;
|
||||||
use Digest::MD5 qw/md5/;
|
|
||||||
use DBI qw/:sql_types/;
|
|
||||||
|
|
||||||
my @function_flags = (undef, 0);
|
my @function_flags = (undef, 0);
|
||||||
if ($DBD::SQLite::sqlite_version_number >= 3008003) {
|
if ($DBD::SQLite::sqlite_version_number >= 3008003) {
|
||||||
push @function_flags, DBD::SQLite::Constants::SQLITE_DETERMINISTIC;
|
push @function_flags, DBD::SQLite::Constants::SQLITE_DETERMINISTIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
plan tests => 29 * @CALL_FUNCS * @function_flags + 1;
|
||||||
|
|
||||||
sub now {
|
sub now {
|
||||||
return time();
|
return time();
|
||||||
}
|
}
|
||||||
|
@ -55,14 +61,6 @@ sub noop {
|
||||||
return $_[0];
|
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) {
|
foreach my $call_func (@CALL_FUNCS) { for my $flags (@function_flags) {
|
||||||
my $dbh = connect_ok( PrintError => 0 );
|
my $dbh = connect_ok( PrintError => 0 );
|
||||||
|
|
||||||
|
@ -136,25 +134,5 @@ foreach my $call_func (@CALL_FUNCS) { for my $flags (@function_flags) {
|
||||||
$result = $dbh->selectrow_arrayref( "SELECT typeof(noop(2147483648))" );
|
$result = $dbh->selectrow_arrayref( "SELECT typeof(noop(2147483648))" );
|
||||||
is_deeply( $result, [ 'integer' ], "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;
|
$dbh->disconnect;
|
||||||
}}
|
}}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest qw/connect_ok @CALL_FUNCS/;
|
use SQLiteTest qw/connect_ok @CALL_FUNCS/;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
use DBD::SQLite;
|
use DBD::SQLite;
|
||||||
use DBD::SQLite::Constants;
|
use DBD::SQLite::Constants;
|
||||||
|
|
||||||
|
@ -12,6 +18,8 @@ if ($DBD::SQLite::sqlite_version_number >= 3008003) {
|
||||||
push @function_flags, DBD::SQLite::Constants::SQLITE_DETERMINISTIC;
|
push @function_flags, DBD::SQLite::Constants::SQLITE_DETERMINISTIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
plan tests => 21 * @CALL_FUNCS * @function_flags + 1;
|
||||||
|
|
||||||
# Create the aggregate test packages
|
# Create the aggregate test packages
|
||||||
SCOPE: {
|
SCOPE: {
|
||||||
package count_aggr;
|
package count_aggr;
|
||||||
|
@ -86,6 +94,7 @@ foreach my $call_func (@CALL_FUNCS) { for my $flags (@function_flags) {
|
||||||
$result = $dbh->selectall_arrayref( "SELECT newcount() FROM aggr_test GROUP BY field" );
|
$result = $dbh->selectall_arrayref( "SELECT newcount() FROM aggr_test GROUP BY field" );
|
||||||
ok( @$result == 3 && $result->[0][0] == 1 && $result->[1][0] == 1 );
|
ok( @$result == 3 && $result->[0][0] == 1 && $result->[1][0] == 1 );
|
||||||
|
|
||||||
|
|
||||||
# Test aggregate on empty table
|
# Test aggregate on empty table
|
||||||
$dbh->do( "DROP TABLE aggr_empty_test;" );
|
$dbh->do( "DROP TABLE aggr_empty_test;" );
|
||||||
$dbh->do( "CREATE TABLE aggr_empty_test ( field )" );
|
$dbh->do( "CREATE TABLE aggr_empty_test ( field )" );
|
||||||
|
@ -132,5 +141,3 @@ foreach my $call_func (@CALL_FUNCS) { for my $flags (@function_flags) {
|
||||||
|
|
||||||
$dbh->disconnect;
|
$dbh->disconnect;
|
||||||
}}
|
}}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
use strict;
|
|
||||||
use warnings;
|
|
||||||
use lib "t/lib";
|
|
||||||
use SQLiteTest;
|
|
||||||
use Test::More;
|
|
||||||
use if -d ".git", "Test::FailWarnings";
|
|
||||||
|
|
||||||
use DBI::Const::GetInfoType;
|
|
||||||
|
|
||||||
# NOTE: These are tests for just a very basic set of get_info variables.
|
|
||||||
|
|
||||||
my %info = (
|
|
||||||
SQL_CATALOG_LOCATION => 1,
|
|
||||||
SQL_CATALOG_NAME => 'Y',
|
|
||||||
SQL_CATALOG_NAME_SEPARATOR => '.',
|
|
||||||
SQL_CATALOG_TERM => 'database',
|
|
||||||
|
|
||||||
# some of these are dynamic, but always the same for connect_ok
|
|
||||||
SQL_DATA_SOURCE_NAME => qr/^dbi:SQLite:dbname=/,
|
|
||||||
SQL_DATA_SOURCE_READ_ONLY => 'N',
|
|
||||||
SQL_DATABASE_NAME => 'main',
|
|
||||||
SQL_DBMS_NAME => 'SQLite',
|
|
||||||
SQL_DBMS_VER => qr/^[1-9]+\.\d+\.\d+$/,
|
|
||||||
|
|
||||||
SQL_IDENTIFIER_QUOTE_CHAR => '"',
|
|
||||||
|
|
||||||
SQL_MAX_IDENTIFIER_LEN => qr/^[1-9]\d+$/,
|
|
||||||
SQL_MAX_TABLE_NAME_LEN => qr/^[1-9]\d+$/,
|
|
||||||
|
|
||||||
SQL_KEYWORDS => qr/^(?:\w+,)+\w+$/,
|
|
||||||
|
|
||||||
SQL_SEARCH_PATTERN_ESCAPE => '\\',
|
|
||||||
SQL_SERVER_NAME => qr/^dbname=/,
|
|
||||||
|
|
||||||
SQL_TABLE_TERM => 'table',
|
|
||||||
);
|
|
||||||
|
|
||||||
my $dbh = connect_ok( RaiseError => 1 );
|
|
||||||
|
|
||||||
foreach my $option ( sort keys %info ) {
|
|
||||||
my $value = $dbh->get_info( $GetInfoType{$option} );
|
|
||||||
my $check = $info{$option};
|
|
||||||
if (ref $check eq 'Regexp') { like($value, $check, $option); }
|
|
||||||
else { is ($value, $check, $option); }
|
|
||||||
}
|
|
||||||
|
|
||||||
$dbh->disconnect;
|
|
||||||
|
|
||||||
done_testing;
|
|
|
@ -1,18 +1,25 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
# This is a test for correct handling of the "unicode" database
|
# This is a test for correct handling of the "unicode" database
|
||||||
# handle parameter.
|
# handle parameter.
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
BEGIN {
|
||||||
|
if ( $] >= 5.008005 ) {
|
||||||
use DBD::SQLite::Constants ':dbd_sqlite_string_mode';
|
plan( tests => 26 );
|
||||||
|
} else {
|
||||||
my $unicode_opt = DBD_SQLITE_STRING_MODE_UNICODE_STRICT;
|
plan( skip_all => 'Unicode is not supported before 5.8.5' );
|
||||||
|
}
|
||||||
BEGIN { requires_unicode_support() }
|
}
|
||||||
|
use Test::NoWarnings;
|
||||||
|
|
||||||
#
|
#
|
||||||
# Include std stuff
|
# Include std stuff
|
||||||
|
@ -55,7 +62,7 @@ ok(
|
||||||
my ($textback, $bytesback);
|
my ($textback, $bytesback);
|
||||||
SCOPE: {
|
SCOPE: {
|
||||||
my $dbh = connect_ok( dbfile => 'foo', RaiseError => 1 );
|
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(
|
ok(
|
||||||
$dbh->do("CREATE TABLE table1 (a TEXT, b BLOB)"),
|
$dbh->do("CREATE TABLE table1 (a TEXT, b BLOB)"),
|
||||||
'CREATE TABLE',
|
'CREATE TABLE',
|
||||||
|
@ -77,8 +84,8 @@ SCOPE: {
|
||||||
|
|
||||||
# Start over but now activate Unicode support.
|
# Start over but now activate Unicode support.
|
||||||
SCOPE: {
|
SCOPE: {
|
||||||
my $dbh = connect_ok( dbfile => 'foo', sqlite_string_mode => $unicode_opt );
|
my $dbh = connect_ok( dbfile => 'foo', sqlite_unicode => 1 );
|
||||||
is( $dbh->{sqlite_string_mode}, $unicode_opt, 'Unicode is on' );
|
is( $dbh->{sqlite_unicode}, 1, 'Unicode is on' );
|
||||||
|
|
||||||
($textback, $bytesback) = database_roundtrip($dbh, $utfstring, $bytestring);
|
($textback, $bytesback) = database_roundtrip($dbh, $utfstring, $bytestring);
|
||||||
|
|
||||||
|
@ -130,5 +137,3 @@ sub database_roundtrip {
|
||||||
croak "Bad row length ".@row unless (@row == 2);
|
croak "Bad row length ".@row unless (@row == 2);
|
||||||
@row;
|
@row;
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,17 +1,28 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
no if $] >= 5.022, "warnings", "locale";
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest qw/connect_ok dies @CALL_FUNCS/;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
BEGIN {
|
||||||
|
my $COLLATION_TESTS = 10;
|
||||||
|
my $WRITE_ONCE_TESTS = 4;
|
||||||
|
|
||||||
|
if ( $] >= 5.008005 ) {
|
||||||
|
plan( tests => $COLLATION_TESTS * @CALL_FUNCS +
|
||||||
|
$WRITE_ONCE_TESTS + 1);
|
||||||
|
} else {
|
||||||
|
plan( skip_all => 'Unicode is not supported before 5.8.5' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
use Test::NoWarnings;
|
||||||
use Encode qw/decode/;
|
use Encode qw/decode/;
|
||||||
use DBD::SQLite;
|
use DBD::SQLite;
|
||||||
use DBD::SQLite::Constants ':dbd_sqlite_string_mode';
|
|
||||||
|
|
||||||
my $unicode_opt = DBD_SQLITE_STRING_MODE_UNICODE_STRICT;
|
|
||||||
|
|
||||||
BEGIN { requires_unicode_support(); }
|
|
||||||
|
|
||||||
BEGIN {
|
BEGIN {
|
||||||
# Sadly perl for windows (and probably sqlite, too) may hang
|
# Sadly perl for windows (and probably sqlite, too) may hang
|
||||||
|
@ -42,13 +53,17 @@ sub by_num_desc ($$) {
|
||||||
$_[1] <=> $_[0];
|
$_[1] <=> $_[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# collation 'no_accents' will be automatically loaded on demand
|
# collation 'no_accents' will be automatically loaded on demand
|
||||||
$DBD::SQLite::COLLATION{no_accents} = \&no_accents;
|
$DBD::SQLite::COLLATION{no_accents} = \&no_accents;
|
||||||
|
|
||||||
|
|
||||||
$" = ", "; # to embed arrays into message strings
|
$" = ", "; # to embed arrays into message strings
|
||||||
|
|
||||||
my $sql = "SELECT txt from collate_test ORDER BY txt";
|
my $sql = "SELECT txt from collate_test ORDER BY txt";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# test interaction with the global COLLATION hash ("WriteOnce")
|
# test interaction with the global COLLATION hash ("WriteOnce")
|
||||||
|
|
||||||
dies (sub {$DBD::SQLite::COLLATION{perl} = sub {}},
|
dies (sub {$DBD::SQLite::COLLATION{perl} = sub {}},
|
||||||
|
@ -70,14 +85,16 @@ delete $tied->{foo};
|
||||||
$DBD::SQLite::COLLATION{foo} = \&by_num_desc; # override, no longer dies
|
$DBD::SQLite::COLLATION{foo} = \&by_num_desc; # override, no longer dies
|
||||||
is($DBD::SQLite::COLLATION{foo}, \&by_num_desc, "overridden collation");
|
is($DBD::SQLite::COLLATION{foo}, \&by_num_desc, "overridden collation");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# now really test the collation functions
|
# now really test the collation functions
|
||||||
|
|
||||||
foreach my $call_func (@CALL_FUNCS) {
|
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
|
# 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
|
# populate test data
|
||||||
my @words = qw{
|
my @words = qw{
|
||||||
|
@ -87,7 +104,7 @@ foreach my $call_func (@CALL_FUNCS) {
|
||||||
HAT hâôer
|
HAT hâôer
|
||||||
féôu fêôe fèöe ferme
|
féôu fêôe fèöe ferme
|
||||||
};
|
};
|
||||||
if ($unicode_opt != DBD_SQLITE_STRING_MODE_BYTES) {
|
if ($use_unicode) {
|
||||||
utf8::upgrade($_) foreach @words;
|
utf8::upgrade($_) foreach @words;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +132,7 @@ foreach my $call_func (@CALL_FUNCS) {
|
||||||
is_deeply(\@sorted, $db_sorted,
|
is_deeply(\@sorted, $db_sorted,
|
||||||
"collate no_accents (@sorted // @$db_sorted)");
|
"collate no_accents (@sorted // @$db_sorted)");
|
||||||
|
|
||||||
|
|
||||||
# manual addition of a collation for this dbh
|
# manual addition of a collation for this dbh
|
||||||
$dbh->$call_func(by_length => \&by_length, "create_collation");
|
$dbh->$call_func(by_length => \&by_length, "create_collation");
|
||||||
@sorted = sort by_length @words;
|
@sorted = sort by_length @words;
|
||||||
|
@ -124,4 +142,6 @@ foreach my $call_func (@CALL_FUNCS) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,17 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest qw/connect_ok @CALL_FUNCS/;
|
use SQLiteTest qw/connect_ok @CALL_FUNCS/;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
|
plan tests => 5 * @CALL_FUNCS + 1;
|
||||||
|
|
||||||
my $N_OPCODES = 50; # how many opcodes before calling the progress handler
|
my $N_OPCODES = 50; # how many opcodes before calling the progress handler
|
||||||
|
|
||||||
|
@ -36,6 +44,7 @@ foreach my $call_func (@CALL_FUNCS) {
|
||||||
# now the progress handler should have been called a number of times
|
# now the progress handler should have been called a number of times
|
||||||
ok($n_callback);
|
ok($n_callback);
|
||||||
|
|
||||||
|
|
||||||
# unregister the progress handler, set counter back to zero, do more work
|
# unregister the progress handler, set counter back to zero, do more work
|
||||||
ok($dbh->$call_func( $N_OPCODES, undef, "progress_handler" ));
|
ok($dbh->$call_func( $N_OPCODES, undef, "progress_handler" ));
|
||||||
$n_callback = 0;
|
$n_callback = 0;
|
||||||
|
@ -46,5 +55,3 @@ foreach my $call_func (@CALL_FUNCS) {
|
||||||
|
|
||||||
$dbh->disconnect;
|
$dbh->disconnect;
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More tests => 37;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
# Create a database
|
# Create a database
|
||||||
my $dbh = connect_ok( dbfile => 'foo', RaiseError => 1, PrintError => 1, PrintWarn => 1 );
|
my $dbh = connect_ok( dbfile => 'foo', RaiseError => 1, PrintError => 1, PrintWarn => 1 );
|
||||||
|
@ -110,6 +116,7 @@ SCOPE: {
|
||||||
ok( $sth->finish, '->finish' );
|
ok( $sth->finish, '->finish' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Delete the test row from the table
|
# Delete the test row from the table
|
||||||
ok( $dbh->do('DELETE FROM ONE WHERE id = 2 AND name IS NULL'), 'DELETE' );
|
ok( $dbh->do('DELETE FROM ONE WHERE id = 2 AND name IS NULL'), 'DELETE' );
|
||||||
|
|
||||||
|
@ -130,5 +137,3 @@ SCOPE: {
|
||||||
my $sth = $dbh->prepare("UPDATE one SET id = 3 WHERE name = 'Gary Shea'");
|
my $sth = $dbh->prepare("UPDATE one SET id = 3 WHERE name = 'Gary Shea'");
|
||||||
isa_ok( $sth, 'DBI::st' );
|
isa_ok( $sth, 'DBI::st' );
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More tests => 12;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
my $dbh = DBI->connect('dbi:SQLite:dbname=:memory:',undef,undef,{RaiseError => 1});
|
my $dbh = DBI->connect('dbi:SQLite:dbname=:memory:',undef,undef,{RaiseError => 1});
|
||||||
|
|
||||||
|
@ -75,5 +81,3 @@ SKIP: {
|
||||||
# 11. Correct info retrieved
|
# 11. Correct info retrieved
|
||||||
is_deeply( \@info, $expected, 'We got the right info from multiple databases' );
|
is_deeply( \@info, $expected, 'We got the right info from multiple databases' );
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,12 +1,18 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
# This is a skeleton test. For writing new tests, take this file
|
# This is a skeleton test. For writing new tests, take this file
|
||||||
# and modify/extend it.
|
# and modify/extend it.
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More tests => 4;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
# Create a database
|
# Create a database
|
||||||
my $dbh = connect_ok();
|
my $dbh = connect_ok();
|
||||||
|
@ -21,5 +27,3 @@ END_SQL
|
||||||
|
|
||||||
# Drop the table
|
# Drop the table
|
||||||
ok( $dbh->do('DROP TABLE one'), 'DROP TABLE' );
|
ok( $dbh->do('DROP TABLE one'), 'DROP TABLE' );
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
# This is a simple insert/fetch test.
|
# This is a simple insert/fetch test.
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More tests => 10;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
# Create a database
|
# Create a database
|
||||||
my $dbh = connect_ok( RaiseError => 1 );
|
my $dbh = connect_ok( RaiseError => 1 );
|
||||||
|
@ -41,5 +47,3 @@ SCOPE: {
|
||||||
my $row2 = $sth->fetchrow_arrayref;
|
my $row2 = $sth->fetchrow_arrayref;
|
||||||
is( $row2, undef, 'fetch empty statement handler' );
|
is( $row2, undef, 'fetch empty statement handler' );
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More tests => 39;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
use DBI ':sql_types';
|
use DBI ':sql_types';
|
||||||
|
|
||||||
# Create a database
|
# Create a database
|
||||||
|
@ -81,5 +87,3 @@ SCOPE: {
|
||||||
is( $id, 6, 'id = 6' );
|
is( $id, 6, 'id = 6' );
|
||||||
is( $name, 'Larry', 'name = Larry' );
|
is( $name, 'Larry', 'name = Larry' );
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
41
t/20_blobs.t
41
t/20_blobs.t
|
@ -1,12 +1,18 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
# This is a test for correct handling of BLOBS; namely $dbh->quote
|
# This is a test for correct handling of BLOBS; namely $dbh->quote
|
||||||
# is expected to work correctly.
|
# is expected to work correctly.
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More tests => 17;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
use DBI ':sql_types';
|
use DBI ':sql_types';
|
||||||
|
|
||||||
sub ShowBlob($) {
|
sub ShowBlob($) {
|
||||||
|
@ -66,26 +72,6 @@ SCOPE: {
|
||||||
ok( $sth->bind_param(1, 3), '->bind_param' );
|
ok( $sth->bind_param(1, 3), '->bind_param' );
|
||||||
ok( $sth->bind_param(2, undef, SQL_BLOB), '->bind_param' );
|
ok( $sth->bind_param(2, undef, SQL_BLOB), '->bind_param' );
|
||||||
ok( $sth->execute, '->execute' );
|
ok( $sth->execute, '->execute' );
|
||||||
|
|
||||||
ok my $quoted_blob = $dbh->quote($blob, SQL_BLOB);
|
|
||||||
ok( $dbh->do("INSERT INTO one VALUES( 4, $quoted_blob )"), 'insert quoted blob' );
|
|
||||||
ok my $quoted_empty = $dbh->quote('', SQL_BLOB);
|
|
||||||
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.
|
# Now, try SELECT'ing the row out.
|
||||||
|
@ -98,15 +84,6 @@ SCOPE: {
|
||||||
[ 1, $blob ],
|
[ 1, $blob ],
|
||||||
[ 2, '' ],
|
[ 2, '' ],
|
||||||
[ 3, undef ],
|
[ 3, undef ],
|
||||||
[ 4, $blob ],
|
|
||||||
[ 5, '' ],
|
|
||||||
[ 6, undef ],
|
|
||||||
[ 7, $blob ],
|
|
||||||
[ 8, $blob ],
|
|
||||||
[ 9, $blob ],
|
|
||||||
[ 10, $blob ],
|
|
||||||
], 'Got the blob back ok' );
|
], 'Got the blob back ok' );
|
||||||
ok( $sth->finish, '->finish' );
|
ok( $sth->finish, '->finish' );
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More tests => 27;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
my $dbh = connect_ok(
|
my $dbh = connect_ok(
|
||||||
RaiseError => 1,
|
RaiseError => 1,
|
||||||
|
@ -75,4 +81,3 @@ sub dumpblob {
|
||||||
if ($ENV{SHOW_BLOBS}) { close(OUT) }
|
if ($ENV{SHOW_BLOBS}) { close(OUT) }
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
# This is a test for statement attributes being present appropriately.
|
# This is a test for statement attributes being present appropriately.
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More tests => 12;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
# Create a database
|
# Create a database
|
||||||
my $dbh = connect_ok();
|
my $dbh = connect_ok();
|
||||||
|
@ -40,5 +46,3 @@ SCOPE: {
|
||||||
is( $sth->{NUM_OF_FIELDS}, 0, 'No fields in statement' );
|
is( $sth->{NUM_OF_FIELDS}, 0, 'No fields in statement' );
|
||||||
ok( $sth->finish, '->finish ok' );
|
ok( $sth->finish, '->finish ok' );
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
13
t/23_nulls.t
13
t/23_nulls.t
|
@ -1,11 +1,16 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
# This is a test for correctly handling NULL values.
|
# This is a test for correctly handling NULL values.
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More tests => 9;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
|
||||||
|
|
||||||
# Create a database
|
# Create a database
|
||||||
my $dbh = connect_ok();
|
my $dbh = connect_ok();
|
||||||
|
@ -35,5 +40,3 @@ SCOPE: {
|
||||||
is( $row->[1], 'NULL-valued id', 'Second column is defined' );
|
is( $row->[1], 'NULL-valued id', 'Second column is defined' );
|
||||||
ok( $sth->finish, '->finish' );
|
ok( $sth->finish, '->finish' );
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
# This tests, whether the number of rows can be retrieved.
|
# This tests, whether the number of rows can be retrieved.
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More tests => 18;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
sub rows {
|
sub rows {
|
||||||
my $sth = shift;
|
my $sth = shift;
|
||||||
|
@ -72,5 +78,3 @@ SCOPE: {
|
||||||
rows( $sth, 2 );
|
rows( $sth, 2 );
|
||||||
ok( $sth->finish, '->finish' );
|
ok( $sth->finish, '->finish' );
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
# Check whether 'ChopBlanks' works.
|
# Check whether 'ChopBlanks' works.
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More tests => 14;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
# Create a database
|
# Create a database
|
||||||
my $dbh = connect_ok( RaiseError => 1 );
|
my $dbh = connect_ok( RaiseError => 1 );
|
||||||
|
@ -61,5 +67,3 @@ SCOPE: {
|
||||||
], 'ChopBlanks = 1' );
|
], 'ChopBlanks = 1' );
|
||||||
ok( $sth->finish, '->finish' );
|
ok( $sth->finish, '->finish' );
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,14 +1,23 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
# This is testing the transaction support.
|
# This is testing the transaction support.
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More tests => 28;
|
||||||
# use if -d ".git", "Test::FailWarnings";
|
# use Test::NoWarnings;
|
||||||
|
|
||||||
my $warning_count = 0;
|
my $warning_count = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#####################################################################
|
#####################################################################
|
||||||
# Support functions
|
# Support functions
|
||||||
|
|
||||||
|
@ -29,6 +38,10 @@ sub rows {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#####################################################################
|
#####################################################################
|
||||||
# Main Tests
|
# Main Tests
|
||||||
|
|
||||||
|
@ -107,5 +120,3 @@ SCOPE: {
|
||||||
$SIG{__WARN__} = 'DEFAULT';
|
$SIG{__WARN__} = 'DEFAULT';
|
||||||
is( $warning_count, 2, 'Got one warning' );
|
is( $warning_count, 2, 'Got one warning' );
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
use Test::More;
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
use Test::More tests => 21;
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
|
||||||
|
|
||||||
# 1-4. Connect & create tables
|
# 1-4. Connect & create tables
|
||||||
my $dbh = connect_ok(dbfile => 'foo');
|
my $dbh = connect_ok(dbfile => 'foo');
|
||||||
|
@ -40,17 +45,16 @@ $dbh->do("INSERT INTO meta4 VALUES ('xyz', 'b')");
|
||||||
$sth = $dbh->prepare('SELECT * FROM meta4');
|
$sth = $dbh->prepare('SELECT * FROM meta4');
|
||||||
$sth->execute;
|
$sth->execute;
|
||||||
$sth->fetch;
|
$sth->fetch;
|
||||||
|
|
||||||
$dbh->{sqlite_prefer_numeric_type} = 1;
|
|
||||||
|
|
||||||
my $types = $sth->{TYPE};
|
my $types = $sth->{TYPE};
|
||||||
my $names = $sth->{NAME};
|
my $names = $sth->{NAME};
|
||||||
# diag "Types: @$types\nNames: @$names";
|
# diag "Types: @$types\nNames: @$names";
|
||||||
is scalar @$types, scalar @$names, '$sth->{TYPE} array is same length as $sth->{NAME} array';
|
is scalar @$types, scalar @$names, '$sth->{TYPE} array is same length as $sth->{NAME} array';
|
||||||
# $sth->{TYPE} should return an array of integers see: rt #46873
|
# FIXME: This is wrong! $sth->{TYPE} should return an array of integers see: rt #46873
|
||||||
isnt $types->[0], 'VARCHAR(2)', '$sth->{TYPE}[0] doesn\'t return a string';
|
TODO: {
|
||||||
isnt $types->[1], 'CHAR(1)', '$sth->{TYPE}[1] doesn\'t return a string';
|
local $TODO = '$sth->{TYPE} should return an array of integers.';
|
||||||
like $types->[0], qr/^-?\d+$/, '$sth->{TYPE}[0] returns an integer';
|
isnt $types->[0], 'VARCHAR(2)', '$sth->{TYPE}[0] doesn\'t return a string';
|
||||||
like $types->[1], qr/^-?\d+$/, '$sth->{TYPE}[1] returns an integer';
|
isnt $types->[1], 'CHAR(1)', '$sth->{TYPE}[1] doesn\'t return a string';
|
||||||
|
like $types->[0], qr/^-?\d+$/, '$sth->{TYPE}[0] returns an integer';
|
||||||
|
like $types->[1], qr/^-?\d+$/, '$sth->{TYPE}[1] returns an integer';
|
||||||
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
# This test works, but as far as I can tell this doesn't actually test
|
# This test works, but as far as I can tell this doesn't actually test
|
||||||
# the thing that the test was originally meant to test.
|
# the thing that the test was originally meant to test.
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
use Test::More;
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
use Test::More tests => 9;
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
|
||||||
|
|
||||||
my $create1 = 'CREATE TABLE table1 (id INTEGER NOT NULL, name CHAR (64) NOT NULL)';
|
my $create1 = 'CREATE TABLE table1 (id INTEGER NOT NULL, name CHAR (64) NOT NULL)';
|
||||||
my $create2 = 'CREATE TABLE table2 (id INTEGER NOT NULL, name CHAR (64) NOT NULL)';
|
my $create2 = 'CREATE TABLE table2 (id INTEGER NOT NULL, name CHAR (64) NOT NULL)';
|
||||||
|
@ -54,5 +59,3 @@ SCOPE: {
|
||||||
ok( $dbh->do($create2), $create2 ) or diag("Error: '$DBI::errstr'");
|
ok( $dbh->do($create2), $create2 ) or diag("Error: '$DBI::errstr'");
|
||||||
ok( $dbh->disconnect, '->disconnect ok' );
|
ok( $dbh->disconnect, '->disconnect ok' );
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
# I've disabled warnings, so theoretically warnings shouldn't be printed
|
# I've disabled warnings, so theoretically warnings shouldn't be printed
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More tests => 6;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
SCOPE: {
|
SCOPE: {
|
||||||
my $dbh = connect_ok( RaiseError => 1, PrintWarn => 0, Warn => 0 );
|
my $dbh = connect_ok( RaiseError => 1, PrintWarn => 0, Warn => 0 );
|
||||||
|
@ -17,5 +23,3 @@ SCOPE: {
|
||||||
'INSERT ok',
|
'INSERT ok',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
my @to_be_tested;
|
my @to_be_tested;
|
||||||
BEGIN { @to_be_tested = (1.23E4); }
|
BEGIN { @to_be_tested = (1.23E4); }
|
||||||
|
|
||||||
use Test::More;
|
use Test::More tests => 2 + @to_be_tested;
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
|
||||||
|
|
||||||
my $dbh = connect_ok();
|
my $dbh = connect_ok();
|
||||||
|
|
||||||
|
@ -20,5 +25,3 @@ SCOPE: {
|
||||||
ok( (@$av && $av->[0] == $to_be_tested[$id]), "accepts $to_be_tested[$id]: ".$av->[0]);
|
ok( (@$av && $av->[0] == $to_be_tested[$id]), "accepts $to_be_tested[$id]: ".$av->[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
use Test::More;
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
use Test::More tests => 4;
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
|
||||||
|
|
||||||
my $dbh = connect_ok( PrintError => 0, RaiseError => 0 );
|
my $dbh = connect_ok( PrintError => 0, RaiseError => 0 );
|
||||||
|
|
||||||
|
@ -28,20 +33,3 @@ like(
|
||||||
qr/attempt to execute on inactive database handle/,
|
qr/attempt to execute on inactive database handle/,
|
||||||
'Got the expected warning',
|
'Got the expected warning',
|
||||||
);
|
);
|
||||||
|
|
||||||
@warning = ();
|
|
||||||
SCOPE: {
|
|
||||||
local $SIG{__WARN__} = sub { push @warning, @_; return };
|
|
||||||
my $ret = eval { $sth->{NUM_OF_PARAMS}; };
|
|
||||||
# we need PrintError => 1, or warn $@ if $@;
|
|
||||||
ok !$ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
is( scalar(@warning), 1, 'Got 1 warning' );
|
|
||||||
like(
|
|
||||||
$warning[0],
|
|
||||||
qr/attempt to fetch on inactive database handle/,
|
|
||||||
'Got the expected warning',
|
|
||||||
);
|
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,21 +1,28 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
# Tests path containing non-latine-1 characters
|
# Tests path containing non-latine-1 characters
|
||||||
# currently fails on Windows
|
# currently fails on Windows
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
BEGIN {
|
||||||
|
if ( $] >= 5.008005 ) {
|
||||||
|
plan( tests => 2 + 12 * (($^O eq 'cygwin') ? 2 : 4) );
|
||||||
|
} else {
|
||||||
|
plan( skip_all => 'Unicode is not supported before 5.8.5' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#use Test::NoWarnings;
|
||||||
use File::Temp ();
|
use File::Temp ();
|
||||||
use File::Spec::Functions ':ALL';
|
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 );
|
my $dir = File::Temp::tempdir( CLEANUP => 1 );
|
||||||
foreach my $subdir ( 'longascii', 'adatbázis', 'name with spaces', '¿¿¿ ¿¿¿¿¿¿') {
|
foreach my $subdir ( 'longascii', 'adatbázis', 'name with spaces', '¿¿¿ ¿¿¿¿¿¿') {
|
||||||
if ($^O eq 'cygwin') {
|
if ($^O eq 'cygwin') {
|
||||||
|
@ -59,7 +66,7 @@ foreach my $subdir ( 'longascii', 'adatb
|
||||||
my $dbh = DBI->connect("dbi:SQLite:dbname=$dbfile", undef, undef, {
|
my $dbh = DBI->connect("dbi:SQLite:dbname=$dbfile", undef, undef, {
|
||||||
RaiseError => 1,
|
RaiseError => 1,
|
||||||
PrintError => 0,
|
PrintError => 0,
|
||||||
sqlite_string_mode => $unicode_opt,
|
sqlite_unicode => 1,
|
||||||
} );
|
} );
|
||||||
isa_ok( $dbh, 'DBI::db' );
|
isa_ok( $dbh, 'DBI::db' );
|
||||||
};
|
};
|
||||||
|
@ -71,7 +78,7 @@ foreach my $subdir ( 'longascii', 'adatb
|
||||||
my $dbh = DBI->connect("dbi:SQLite:dbname=$dbfile", undef, undef, {
|
my $dbh = DBI->connect("dbi:SQLite:dbname=$dbfile", undef, undef, {
|
||||||
RaiseError => 1,
|
RaiseError => 1,
|
||||||
PrintError => 0,
|
PrintError => 0,
|
||||||
sqlite_string_mode => $unicode_opt,
|
sqlite_unicode => 1,
|
||||||
} );
|
} );
|
||||||
isa_ok( $dbh, 'DBI::db' );
|
isa_ok( $dbh, 'DBI::db' );
|
||||||
};
|
};
|
||||||
|
@ -97,6 +104,7 @@ foreach my $subdir ( 'longascii', 'adatb
|
||||||
unlink(_path($dbfilex)) if -e _path($dbfilex);
|
unlink(_path($dbfilex)) if -e _path($dbfilex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# connect to an empty filename - sqlite will create a tempfile
|
# connect to an empty filename - sqlite will create a tempfile
|
||||||
eval {
|
eval {
|
||||||
my $dbh = DBI->connect("dbi:SQLite:dbname=", undef, undef, {
|
my $dbh = DBI->connect("dbi:SQLite:dbname=", undef, undef, {
|
||||||
|
@ -108,6 +116,9 @@ eval {
|
||||||
is( $@, '', "Could connect to temp database (empty filename)" );
|
is( $@, '', "Could connect to temp database (empty filename)" );
|
||||||
diag( $@ ) if $@;
|
diag( $@ ) if $@;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sub _path { # copied from DBD::SQLite::connect
|
sub _path { # copied from DBD::SQLite::connect
|
||||||
my $path = shift;
|
my $path = shift;
|
||||||
|
|
||||||
|
@ -126,5 +137,3 @@ sub _path { # copied from DBD::SQLite::connect
|
||||||
}
|
}
|
||||||
return $path;
|
return $path;
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
|
@ -7,9 +9,11 @@ use SQLiteTest qw/connect_ok dbfile @CALL_FUNCS requires_sqlite/;
|
||||||
|
|
||||||
BEGIN { requires_sqlite('3.6.11') }
|
BEGIN { requires_sqlite('3.6.11') }
|
||||||
|
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
use DBI;
|
use DBI;
|
||||||
|
|
||||||
|
plan tests => 6 * @CALL_FUNCS + 1;
|
||||||
|
|
||||||
foreach my $call_func (@CALL_FUNCS) {
|
foreach my $call_func (@CALL_FUNCS) {
|
||||||
# Connect to the test db and add some stuff:
|
# Connect to the test db and add some stuff:
|
||||||
my $foo = connect_ok( dbfile => 'foo', RaiseError => 1 );
|
my $foo = connect_ok( dbfile => 'foo', RaiseError => 1 );
|
||||||
|
@ -65,47 +69,3 @@ foreach my $call_func (@CALL_FUNCS) {
|
||||||
|
|
||||||
unlink $dbfile;
|
unlink $dbfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach my $call_func (@CALL_FUNCS) {
|
|
||||||
# Connect to the test db and add some stuff:
|
|
||||||
my $foo = connect_ok( dbfile => ':memory:', RaiseError => 1 );
|
|
||||||
$foo->do(
|
|
||||||
'CREATE TABLE online_backup_test( id INTEGER PRIMARY KEY, foo INTEGER )'
|
|
||||||
);
|
|
||||||
$foo->do("INSERT INTO online_backup_test (foo) VALUES ($$)");
|
|
||||||
|
|
||||||
my $dbh = DBI->connect(
|
|
||||||
'dbi:SQLite:dbname=:memory:',
|
|
||||||
undef, undef,
|
|
||||||
{ RaiseError => 1 }
|
|
||||||
);
|
|
||||||
|
|
||||||
ok($dbh->$call_func($foo, 'backup_from_dbh'));
|
|
||||||
|
|
||||||
{
|
|
||||||
my ($count) = $dbh->selectrow_array(
|
|
||||||
"SELECT count(foo) FROM online_backup_test WHERE foo=$$"
|
|
||||||
);
|
|
||||||
is($count, 1, "Found our process ID in backed-up table");
|
|
||||||
}
|
|
||||||
|
|
||||||
# Add more data then attempt to copy it back to file:
|
|
||||||
$dbh->do(
|
|
||||||
'CREATE TABLE online_backup_test2 ( id INTEGER PRIMARY KEY, foo INTEGER )'
|
|
||||||
);
|
|
||||||
$dbh->do("INSERT INTO online_backup_test2 (foo) VALUES ($$)");
|
|
||||||
|
|
||||||
# backup to dbh (foo):
|
|
||||||
ok($dbh->$call_func($foo, 'backup_to_dbh'));
|
|
||||||
|
|
||||||
$dbh->disconnect;
|
|
||||||
|
|
||||||
my ($count) = $foo->selectrow_array(
|
|
||||||
"SELECT count(foo) FROM online_backup_test2 WHERE foo=$$"
|
|
||||||
);
|
|
||||||
is($count, 1, "Found our process ID in table back on disk");
|
|
||||||
|
|
||||||
$foo->disconnect;
|
|
||||||
}
|
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More tests => 22;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
my @catalog_info = (
|
my @catalog_info = (
|
||||||
[undef, undef, undef, undef, undef],
|
[undef, undef, undef, undef, undef],
|
||||||
|
@ -140,4 +146,3 @@ is_deeply $info, [$table2_info, @systable_info, $table4_info, $table3_info, $tab
|
||||||
#warn 'Table Types', substr Dumper($dbh->table_info('', '', '', '%')->fetchall_arrayref), 5;
|
#warn 'Table Types', substr Dumper($dbh->table_info('', '', '', '%')->fetchall_arrayref), 5;
|
||||||
#warn 'table_info', substr Dumper($info), 5;
|
#warn 'table_info', substr Dumper($info), 5;
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
35
t/36_hooks.t
35
t/36_hooks.t
|
@ -1,12 +1,20 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest qw/connect_ok @CALL_FUNCS/;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings qw/had_no_warnings clear_warnings/;
|
||||||
|
|
||||||
use DBD::SQLite;
|
use DBD::SQLite;
|
||||||
|
|
||||||
|
plan tests => 24 * @CALL_FUNCS + 1;
|
||||||
|
|
||||||
# hooks : just count the commits / rollbacks / updates
|
# hooks : just count the commits / rollbacks / updates
|
||||||
my ($n_commits, $n_rollbacks, $n_updates, @update_args);
|
my ($n_commits, $n_rollbacks, $n_updates, @update_args);
|
||||||
sub commit_hook { $n_commits += 1; return 0; }
|
sub commit_hook { $n_commits += 1; return 0; }
|
||||||
|
@ -63,12 +71,15 @@ foreach my $call_func (@CALL_FUNCS) {
|
||||||
is($n_commits, 0, "commit hook unregistered");
|
is($n_commits, 0, "commit hook unregistered");
|
||||||
is($n_updates, 0, "update hook unregistered");
|
is($n_updates, 0, "update hook unregistered");
|
||||||
|
|
||||||
|
# check here explicitly for warnings, before we clear them
|
||||||
|
had_no_warnings();
|
||||||
|
|
||||||
# remember how many rows we had so far
|
# remember how many rows we had so far
|
||||||
my ($n_rows) = $dbh->selectrow_array($sql_count_rows);
|
my ($n_rows) = $dbh->selectrow_array($sql_count_rows);
|
||||||
|
|
||||||
# a commit hook that rejects the transaction
|
# a commit hook that rejects the transaction
|
||||||
$dbh->$call_func(sub {return 1}, "commit_hook");
|
$dbh->$call_func(sub {return 1}, "commit_hook");
|
||||||
allow_warnings { eval {do_transaction($dbh)} }; # in eval() because of RaiseError
|
eval {do_transaction($dbh)}; # in eval() because of RaiseError
|
||||||
ok ($@, "transaction was rejected: $@" );
|
ok ($@, "transaction was rejected: $@" );
|
||||||
|
|
||||||
# no explicit rollback, because SQLite already did it
|
# no explicit rollback, because SQLite already did it
|
||||||
|
@ -85,7 +96,7 @@ foreach my $call_func (@CALL_FUNCS) {
|
||||||
|
|
||||||
# try transaction again .. rollback hook should not be called
|
# try transaction again .. rollback hook should not be called
|
||||||
$n_rollbacks = 0;
|
$n_rollbacks = 0;
|
||||||
allow_warnings { eval {do_transaction($dbh)} };
|
eval {do_transaction($dbh)};
|
||||||
is($n_rollbacks, 0, "rollback hook unregistered");
|
is($n_rollbacks, 0, "rollback hook unregistered");
|
||||||
|
|
||||||
# check that the rollbacks did really occur
|
# check that the rollbacks did really occur
|
||||||
|
@ -111,18 +122,26 @@ foreach my $call_func (@CALL_FUNCS) {
|
||||||
"args to authorizer (INSERT)");
|
"args to authorizer (INSERT)");
|
||||||
|
|
||||||
# try a delete (should be unauthorized)
|
# try a delete (should be unauthorized)
|
||||||
allow_warnings { eval {$dbh->do("DELETE FROM hook_test WHERE foo = 'auth_test'")} };
|
eval {$dbh->do("DELETE FROM hook_test WHERE foo = 'auth_test'")};
|
||||||
ok($@, "delete was rejected with message $@");
|
ok($@, "delete was rejected with message $@");
|
||||||
is_deeply(\@authorizer_args,
|
is_deeply(\@authorizer_args,
|
||||||
[DBD::SQLite::DELETE, 'hook_test', undef, 'temp', undef],
|
[DBD::SQLite::DELETE, 'hook_test', undef, 'temp', undef],
|
||||||
"args to authorizer (DELETE)");
|
"args to authorizer (DELETE)");
|
||||||
|
|
||||||
|
|
||||||
# unregister the authorizer ... now DELETE should be authorized
|
# unregister the authorizer ... now DELETE should be authorized
|
||||||
$dbh->$call_func(undef, "set_authorizer");
|
$dbh->$call_func(undef, "set_authorizer");
|
||||||
allow_warnings { eval {$dbh->do("DELETE FROM hook_test WHERE foo = 'auth_test'")} };
|
eval {$dbh->do("DELETE FROM hook_test WHERE foo = 'auth_test'")};
|
||||||
ok(!$@, "delete was accepted");
|
ok(!$@, "delete was accepted");
|
||||||
|
|
||||||
|
|
||||||
|
# sqlite3 did warn in tests above, so avoid complains from Test::Warnings
|
||||||
|
# (would be better to turn off warnings from sqlite3, but I didn't find
|
||||||
|
# any way to do that)
|
||||||
|
clear_warnings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sub do_transaction {
|
sub do_transaction {
|
||||||
my $dbh = shift;
|
my $dbh = shift;
|
||||||
|
|
||||||
|
@ -133,5 +152,3 @@ sub do_transaction {
|
||||||
}
|
}
|
||||||
$dbh->commit;
|
$dbh->commit;
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
no if $] >= 5.022, "warnings", "locale";
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest qw/connect_ok @CALL_FUNCS/;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
|
||||||
|
|
||||||
my @words = qw{
|
my @words = qw{
|
||||||
berger Bergère bergère Bergere
|
berger Bergère bergère Bergere
|
||||||
|
@ -15,7 +19,14 @@ my @words = qw{
|
||||||
};
|
};
|
||||||
my @regexes = qw( ^b\\w+ (?i:^b\\w+) );
|
my @regexes = qw( ^b\\w+ (?i:^b\\w+) );
|
||||||
|
|
||||||
BEGIN { requires_unicode_support() }
|
BEGIN {
|
||||||
|
if ($] < 5.008005) {
|
||||||
|
plan skip_all => 'Unicode is not supported before 5.8.5';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plan tests => 2 * (3 + 2 * @regexes) * @CALL_FUNCS;
|
||||||
|
|
||||||
BEGIN {
|
BEGIN {
|
||||||
# Sadly perl for windows (and probably sqlite, too) may hang
|
# Sadly perl for windows (and probably sqlite, too) may hang
|
||||||
# if the system locale doesn't support european languages.
|
# if the system locale doesn't support european languages.
|
||||||
|
@ -28,14 +39,15 @@ BEGIN {
|
||||||
use locale;
|
use locale;
|
||||||
|
|
||||||
use DBD::SQLite;
|
use DBD::SQLite;
|
||||||
use DBD::SQLite::Constants ':dbd_sqlite_string_mode';
|
|
||||||
|
|
||||||
|
|
||||||
foreach my $call_func (@CALL_FUNCS) {
|
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
|
# 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!
|
# The following tests are about ordering, so don't reverse!
|
||||||
if ($dbh->selectrow_array('PRAGMA reverse_unordered_selects')) {
|
if ($dbh->selectrow_array('PRAGMA reverse_unordered_selects')) {
|
||||||
|
@ -44,7 +56,7 @@ foreach my $call_func (@CALL_FUNCS) {
|
||||||
|
|
||||||
# populate test data
|
# populate test data
|
||||||
my @vals = @words;
|
my @vals = @words;
|
||||||
if ($string_mode == DBD_SQLITE_STRING_MODE_BYTES) {
|
if ($use_unicode) {
|
||||||
utf8::upgrade($_) foreach @vals;
|
utf8::upgrade($_) foreach @vals;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,4 +92,3 @@ foreach my $call_func (@CALL_FUNCS) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,9 +1,17 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest qw/connect_ok/;
|
use SQLiteTest qw/connect_ok/;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
|
plan tests => 8;
|
||||||
|
|
||||||
my $dbh = connect_ok( RaiseError => 1 );
|
my $dbh = connect_ok( RaiseError => 1 );
|
||||||
|
|
||||||
|
@ -30,5 +38,3 @@ diag $@ if $@;
|
||||||
eval { $dbh->do(undef) };
|
eval { $dbh->do(undef) };
|
||||||
ok !$@, "undef statement does not spit a warning, and does not die anyway";
|
ok !$@, "undef statement does not spit a warning, and does not die anyway";
|
||||||
diag $@ if $@;
|
diag $@ if $@;
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,12 +1,20 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
|
|
||||||
BEGIN { requires_sqlite('3.6.19') }
|
BEGIN { requires_sqlite('3.6.19') }
|
||||||
|
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
|
plan tests => 17;
|
||||||
|
|
||||||
# following tests are from http://www.sqlite.org/foreignkeys.html
|
# following tests are from http://www.sqlite.org/foreignkeys.html
|
||||||
|
|
||||||
|
@ -69,5 +77,3 @@ sub insert_track { _do("INSERT INTO track (trackid, trackname, trackartist) VAL
|
||||||
sub update_track { _do("UPDATE track SET trackartist = ? WHERE trackname = ?", @_); }
|
sub update_track { _do("UPDATE track SET trackartist = ? WHERE trackname = ?", @_); }
|
||||||
|
|
||||||
sub _do { eval { $dbh->do(shift, undef, @_) }; }
|
sub _do { eval { $dbh->do(shift, undef, @_) }; }
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,9 +1,17 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest qw/connect_ok/;
|
use SQLiteTest qw/connect_ok/;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
|
plan tests => 21;
|
||||||
|
|
||||||
{
|
{
|
||||||
# DBD::SQLite prepares/does the first statement only;
|
# DBD::SQLite prepares/does the first statement only;
|
||||||
|
@ -124,5 +132,3 @@ use if -d ".git", "Test::FailWarnings";
|
||||||
ok $got->[0][0] == 1
|
ok $got->[0][0] == 1
|
||||||
&& $got->[1][0] == 2, "and got the inserted values";
|
&& $got->[1][0] == 2, "and got the inserted values";
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,9 +1,17 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest qw/connect_ok/;
|
use SQLiteTest qw/connect_ok/;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
|
plan tests => 13;
|
||||||
|
|
||||||
my $dbh = connect_ok( RaiseError => 1 );
|
my $dbh = connect_ok( RaiseError => 1 );
|
||||||
ok $dbh->do('create table foo (id integer, value integer)');
|
ok $dbh->do('create table foo (id integer, value integer)');
|
||||||
|
@ -50,5 +58,3 @@ SKIP: {
|
||||||
|
|
||||||
ok $count == 2;
|
ok $count == 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,9 +1,17 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest qw/connect_ok/;
|
use SQLiteTest qw/connect_ok/;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
|
plan tests => (5 * 5) + (3 * 6 + 1) + (5 * 2) + 1;
|
||||||
|
|
||||||
for my $quote ('', qw/' " ` []/) {
|
for my $quote ('', qw/' " ` []/) {
|
||||||
my ($begin_quote, $end_quote) = (substr($quote, 0, 1), substr($quote, -1, 1));
|
my ($begin_quote, $end_quote) = (substr($quote, 0, 1), substr($quote, -1, 1));
|
||||||
|
@ -111,5 +119,3 @@ for my $quote ('', qw/' " ` []/) {
|
||||||
is $pk_info[0]{PK_NAME} => 'bar', "pk name is correct";
|
is $pk_info[0]{PK_NAME} => 'bar', "pk name is correct";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
117
t/43_fts3.t
117
t/43_fts3.t
|
@ -1,15 +1,14 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
use lib "t/lib";
|
$| = 1;
|
||||||
use Time::HiRes qw/time/;
|
$^W = 1;
|
||||||
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:
|
use lib "t/lib";
|
||||||
${^UTF8CACHE} = 1;
|
use SQLiteTest qw/connect_ok has_sqlite/;
|
||||||
|
use Test::More;
|
||||||
|
use DBD::SQLite;
|
||||||
|
|
||||||
my @texts = ("il était une bergère",
|
my @texts = ("il était une bergère",
|
||||||
"qui gardait ses moutons",
|
"qui gardait ses moutons",
|
||||||
|
@ -28,52 +27,71 @@ my @tests = (
|
||||||
["(il OR elle) AND un*" => 0, 2 ],
|
["(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 {
|
BEGIN {
|
||||||
requires_unicode_support();
|
if ($] < 5.008005) {
|
||||||
|
plan skip_all => 'Unicode is not supported before 5.8.5';
|
||||||
if (!has_fts()) {
|
|
||||||
plan skip_all => 'FTS is disabled for this DBD::SQLite';
|
|
||||||
}
|
}
|
||||||
if ($DBD::SQLite::sqlite_version_number >= 3011000 and $DBD::SQLite::sqlite_version_number < 3012000 and !has_compile_option('ENABLE_FTS3_TOKENIZER')) {
|
if (!grep /ENABLE_FTS3/, DBD::SQLite::compile_options()) {
|
||||||
|
plan skip_all => 'FTS3 is disabled for this DBD::SQLite';
|
||||||
|
}
|
||||||
|
if ($DBD::SQLite::sqlite_version_number >= 3011000 and $DBD::SQLite::sqlite_version_number < 3012000 and !grep /ENABLE_FTS3_TOKENIZER/, DBD::SQLite::compile_options()) {
|
||||||
plan skip_all => 'FTS3 tokenizer is disabled for this DBD::SQLite';
|
plan skip_all => 'FTS3 tokenizer is disabled for this DBD::SQLite';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Perl may spit a warning on locale
|
||||||
|
# use Test::NoWarnings;
|
||||||
|
|
||||||
sub Unicode_Word_tokenizer { # see also: Search::Tokenizer
|
my $num = has_sqlite('3.7.4') ? 4 : 2;
|
||||||
|
|
||||||
|
plan tests => $num * @tests # each test with unicode y/n and with fts3/fts4
|
||||||
|
+ 2; # connect_ok with unicode y/n
|
||||||
|
|
||||||
|
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 {
|
return sub {
|
||||||
my $string = shift;
|
my $string = shift;
|
||||||
my $regex = qr/\p{Word}+/;
|
|
||||||
|
my $regex = qr/\w+/;
|
||||||
my $term_index = 0;
|
my $term_index = 0;
|
||||||
|
|
||||||
return sub {
|
return sub {
|
||||||
$string =~ /$regex/g or return; # either match, or no more token
|
$string =~ /$regex/g or return; # either match, or no more token
|
||||||
my $term = $&;
|
my ($start, $end) = ($-[0], $+[0]);
|
||||||
my $end = pos $string; # $+[0] is much slower
|
my $term = substr($string, $start, my $len = $end-$start);
|
||||||
my $len = length($term);
|
|
||||||
my $start = $end - $len;
|
|
||||||
return ($term, $len, $start, $end, $term_index++);
|
return ($term, $len, $start, $end, $term_index++);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
use DBD::SQLite;
|
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
|
# 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/) {
|
for my $fts (qw/fts3 fts4/) {
|
||||||
next if $fts eq 'fts4' && !has_sqlite('3.7.4');
|
next if $fts eq 'fts4' && !has_sqlite('3.7.4');
|
||||||
|
|
||||||
# create fts table
|
# create fts table
|
||||||
$dbh->do(<<"") or die DBI::errstr;
|
$dbh->do(<<"") or die DBI::errstr;
|
||||||
CREATE VIRTUAL TABLE try_$fts
|
CREATE VIRTUAL TABLE try_$fts
|
||||||
USING $fts(content, tokenize=perl 'main::Unicode_Word_tokenizer')
|
USING $fts(content, tokenize=perl 'main::locale_tokenizer')
|
||||||
|
|
||||||
# populate it
|
# populate it
|
||||||
my $insert_sth = $dbh->prepare(<<"") or die DBI::errstr;
|
my $insert_sth = $dbh->prepare(<<"") or die DBI::errstr;
|
||||||
|
@ -89,52 +107,17 @@ for my $string_mode (DBD_SQLITE_STRING_MODE_BYTES, DBD_SQLITE_STRING_MODE_UNICOD
|
||||||
SKIP: {
|
SKIP: {
|
||||||
skip "These tests require SQLite compiled with "
|
skip "These tests require SQLite compiled with "
|
||||||
. "ENABLE_FTS3_PARENTHESIS option", scalar @tests
|
. "ENABLE_FTS3_PARENTHESIS option", scalar @tests
|
||||||
unless has_compile_option('ENABLE_FTS3_PARENTHESIS');
|
unless DBD::SQLite->can('compile_options') &&
|
||||||
|
grep /ENABLE_FTS3_PARENTHESIS/, DBD::SQLite::compile_options();
|
||||||
my $sql = "SELECT docid FROM try_$fts WHERE content MATCH ?";
|
my $sql = "SELECT docid FROM try_$fts WHERE content MATCH ?";
|
||||||
|
|
||||||
for my $t (@tests) {
|
for my $t (@tests) {
|
||||||
my ($query, @expected) = @$t;
|
my ($query, @expected) = @$t;
|
||||||
@expected = map {$doc_ids[$_]} @expected;
|
@expected = map {$doc_ids[$_]} @expected;
|
||||||
my $results = $dbh->selectcol_arrayref($sql, undef, $query);
|
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"');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
28
t/44_rtree.t
28
t/44_rtree.t
|
@ -1,15 +1,16 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use DBD::SQLite;
|
||||||
|
use Data::Dumper;
|
||||||
BEGIN {
|
|
||||||
if (!has_compile_option('ENABLE_RTREE')) {
|
|
||||||
plan skip_all => 'RTREE is disabled for this DBD::SQLite';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# NOTE: It seems to be better to compare rounded values
|
# NOTE: It seems to be better to compare rounded values
|
||||||
# because stored coordinate values may have slight errors
|
# because stored coordinate values may have slight errors
|
||||||
|
@ -52,6 +53,15 @@ my @test_results = (
|
||||||
[1, 3, 5, 6]
|
[1, 3, 5, 6]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
BEGIN {
|
||||||
|
if (!grep /ENABLE_RTREE/, DBD::SQLite::compile_options()) {
|
||||||
|
plan skip_all => 'RTREE is disabled for this DBD::SQLite';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
use Test::NoWarnings;
|
||||||
|
|
||||||
|
plan tests => @coords + (2 * @test_regions) + 4;
|
||||||
|
|
||||||
# connect
|
# connect
|
||||||
my $dbh = connect_ok( RaiseError => 1 );
|
my $dbh = connect_ok( RaiseError => 1 );
|
||||||
|
|
||||||
|
@ -102,5 +112,3 @@ for my $region (@test_regions) {
|
||||||
my $results = $dbh->selectcol_arrayref($overlap_sql, undef, @$region);
|
my $results = $dbh->selectcol_arrayref($overlap_sql, undef, @$region);
|
||||||
is_deeply_approx($results, shift @test_results);
|
is_deeply_approx($results, shift @test_results);
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,12 +1,20 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
|
||||||
|
|
||||||
BEGIN { requires_sqlite('3.6.8') }
|
BEGIN { requires_sqlite('3.6.8') }
|
||||||
|
|
||||||
|
plan tests => 5;
|
||||||
|
use Test::NoWarnings;
|
||||||
|
|
||||||
my $dbh = connect_ok(
|
my $dbh = connect_ok(
|
||||||
AutoCommit => 1,
|
AutoCommit => 1,
|
||||||
RaiseError => 1,
|
RaiseError => 1,
|
||||||
|
@ -39,5 +47,3 @@ is $dbh->selectrow_array("SELECT COUNT(*) FROM MST"), 0,
|
||||||
"savepoint rolled back";
|
"savepoint rolled back";
|
||||||
|
|
||||||
$dbh->rollback;
|
$dbh->rollback;
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,15 +1,22 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
|
||||||
|
|
||||||
BEGIN {
|
BEGIN {
|
||||||
eval {require APR::Table; 1};
|
eval {require APR::Table; 1};
|
||||||
if ($@) {
|
if ($@) {
|
||||||
plan skip_all => 'requires APR::Table';
|
plan skip_all => 'requires APR::Table';
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
plan tests => 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
my $dbh = connect_ok(
|
my $dbh = connect_ok(
|
||||||
|
@ -20,5 +27,3 @@ my $dbh = connect_ok(
|
||||||
eval { $dbh->do('SELECT 1') };
|
eval { $dbh->do('SELECT 1') };
|
||||||
ok !$@, "no errors";
|
ok !$@, "no errors";
|
||||||
diag $@ if $@;
|
diag $@ if $@;
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
# Trigger locking error and test prepared statement is still valid afterwards
|
# Trigger locking error and test prepared statement is still valid afterwards
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest qw/connect_ok dbfile @CALL_FUNCS/;
|
use SQLiteTest qw/connect_ok dbfile @CALL_FUNCS/;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
|
plan tests => 10 * @CALL_FUNCS + 1;
|
||||||
|
|
||||||
foreach my $call_func (@CALL_FUNCS) {
|
foreach my $call_func (@CALL_FUNCS) {
|
||||||
|
|
||||||
|
@ -75,5 +83,3 @@ foreach my $call_func (@CALL_FUNCS) {
|
||||||
|
|
||||||
unlink $dbfile;
|
unlink $dbfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,12 +1,20 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
# Check data type assignment in bind_param is sticky
|
# Check data type assignment in bind_param is sticky
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest qw/connect_ok/;
|
use SQLiteTest qw/connect_ok/;
|
||||||
use DBI qw(:sql_types);
|
use DBI qw(:sql_types);
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
|
plan tests => 10 + 1;
|
||||||
|
|
||||||
my $dbh = connect_ok(
|
my $dbh = connect_ok(
|
||||||
RaiseError => 1,
|
RaiseError => 1,
|
||||||
|
@ -39,5 +47,3 @@ $dbh->commit;
|
||||||
|
|
||||||
$dbh->disconnect;
|
$dbh->disconnect;
|
||||||
undef($dbh);
|
undef($dbh);
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,12 +1,20 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest qw/connect_ok @CALL_FUNCS requires_sqlite/;
|
use SQLiteTest qw/connect_ok @CALL_FUNCS requires_sqlite/;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
|
|
||||||
BEGIN { requires_sqlite('3.6.21') }
|
BEGIN { requires_sqlite('3.6.21') }
|
||||||
|
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
|
plan tests => 12 * @CALL_FUNCS + 1;
|
||||||
|
|
||||||
my $flag = 0;
|
my $flag = 0;
|
||||||
for my $call_func (@CALL_FUNCS) {
|
for my $call_func (@CALL_FUNCS) {
|
||||||
|
@ -55,5 +63,3 @@ for my $call_func (@CALL_FUNCS) {
|
||||||
is $profile[2][0] => "insert into bar values (?)";
|
is $profile[2][0] => "insert into bar values (?)";
|
||||||
like $profile[2][1] => qr/^[0-9]+$/;
|
like $profile[2][1] => qr/^[0-9]+$/;
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
24
t/50_foreign_key_info.t
Normal file → Executable file
24
t/50_foreign_key_info.t
Normal file → Executable file
|
@ -1,5 +1,11 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
|
@ -12,7 +18,7 @@ BEGIN {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
# SQL below freely adapted from http://www.sqlite.org/foreignkeys.htm ...
|
# SQL below freely adapted from http://www.sqlite.org/foreignkeys.htm ...
|
||||||
# not the best datamodel in the world, but good enough for our tests.
|
# not the best datamodel in the world, but good enough for our tests.
|
||||||
|
@ -36,7 +42,7 @@ ATTACH DATABASE ':memory:' AS remote;
|
||||||
CREATE TABLE remote.album (
|
CREATE TABLE remote.album (
|
||||||
albumartist INTEGER NOT NULL REFERENCES artist(artistid)
|
albumartist INTEGER NOT NULL REFERENCES artist(artistid)
|
||||||
ON DELETE RESTRICT
|
ON DELETE RESTRICT
|
||||||
ON UPDATE CASCADE DEFERRABLE,
|
ON UPDATE CASCADE,
|
||||||
albumname TEXT,
|
albumname TEXT,
|
||||||
albumcover BINARY,
|
albumcover BINARY,
|
||||||
albumeditor INTEGER NOT NULL REFERENCES editor(editorid),
|
albumeditor INTEGER NOT NULL REFERENCES editor(editorid),
|
||||||
|
@ -52,6 +58,9 @@ CREATE TABLE song(
|
||||||
);
|
);
|
||||||
__EOSQL__
|
__EOSQL__
|
||||||
|
|
||||||
|
|
||||||
|
plan tests => @sql_statements + 20;
|
||||||
|
|
||||||
my $dbh = connect_ok( RaiseError => 1, PrintError => 0, AutoCommit => 1 );
|
my $dbh = connect_ok( RaiseError => 1, PrintError => 0, AutoCommit => 1 );
|
||||||
my $sth;
|
my $sth;
|
||||||
my $fk_data;
|
my $fk_data;
|
||||||
|
@ -69,7 +78,6 @@ for ($fk_data->{albumartist}) {
|
||||||
is($_->{KEY_SEQ}, 1, "FK albumartist, key seq");
|
is($_->{KEY_SEQ}, 1, "FK albumartist, key seq");
|
||||||
is($_->{DELETE_RULE}, $R->{RESTRICT}, "FK albumartist, delete rule");
|
is($_->{DELETE_RULE}, $R->{RESTRICT}, "FK albumartist, delete rule");
|
||||||
is($_->{UPDATE_RULE}, $R->{CASCADE}, "FK albumartist, update rule");
|
is($_->{UPDATE_RULE}, $R->{CASCADE}, "FK albumartist, update rule");
|
||||||
is($_->{DEFERRABILITY}, $R->{'INITIALLY IMMEDIATE'}, "FK albumartist, deferrability");
|
|
||||||
is($_->{UNIQUE_OR_PRIMARY}, 'UNIQUE', "FK albumartist, unique");
|
is($_->{UNIQUE_OR_PRIMARY}, 'UNIQUE', "FK albumartist, unique");
|
||||||
}
|
}
|
||||||
for ($fk_data->{albumeditor}) {
|
for ($fk_data->{albumeditor}) {
|
||||||
|
@ -79,30 +87,34 @@ for ($fk_data->{albumeditor}) {
|
||||||
# rules are 'NO ACTION' by default
|
# rules are 'NO ACTION' by default
|
||||||
is($_->{DELETE_RULE}, $R->{'NO ACTION'}, "FK albumeditor, delete rule");
|
is($_->{DELETE_RULE}, $R->{'NO ACTION'}, "FK albumeditor, delete rule");
|
||||||
is($_->{UPDATE_RULE}, $R->{'NO ACTION'}, "FK albumeditor, update rule");
|
is($_->{UPDATE_RULE}, $R->{'NO ACTION'}, "FK albumeditor, update rule");
|
||||||
is($_->{DEFERRABILITY}, $R->{'NOT DEFERRABLE'}, "FK albumeditor, deferrability");
|
|
||||||
is($_->{UNIQUE_OR_PRIMARY}, 'PRIMARY', "FK albumeditor, primary");
|
is($_->{UNIQUE_OR_PRIMARY}, 'PRIMARY', "FK albumeditor, primary");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$sth = $dbh->foreign_key_info(undef, undef, 'artist',
|
$sth = $dbh->foreign_key_info(undef, undef, 'artist',
|
||||||
undef, undef, 'album');
|
undef, undef, 'album');
|
||||||
$fk_data = $sth->fetchall_hashref('FKCOLUMN_NAME');
|
$fk_data = $sth->fetchall_hashref('FKCOLUMN_NAME');
|
||||||
is_deeply([keys %$fk_data], ['albumartist'], "FK album with PK, only 1 result");
|
is_deeply([keys %$fk_data], ['albumartist'], "FK album with PK, only 1 result");
|
||||||
|
|
||||||
|
|
||||||
$sth = $dbh->foreign_key_info(undef, undef, 'foobar',
|
$sth = $dbh->foreign_key_info(undef, undef, 'foobar',
|
||||||
undef, undef, 'album');
|
undef, undef, 'album');
|
||||||
$fk_data = $sth->fetchall_hashref('FKCOLUMN_NAME');
|
$fk_data = $sth->fetchall_hashref('FKCOLUMN_NAME');
|
||||||
is_deeply([keys %$fk_data], [], "FK album with PK foobar, 0 result");
|
is_deeply([keys %$fk_data], [], "FK album with PK foobar, 0 result");
|
||||||
|
|
||||||
|
|
||||||
$sth = $dbh->foreign_key_info(undef, undef, undef,
|
$sth = $dbh->foreign_key_info(undef, undef, undef,
|
||||||
undef, 'remote', undef);
|
undef, 'remote', undef);
|
||||||
$fk_data = $sth->fetchall_hashref('FKCOLUMN_NAME');
|
$fk_data = $sth->fetchall_hashref('FKCOLUMN_NAME');
|
||||||
is_deeply([sort keys %$fk_data], [qw/albumartist albumeditor/], "FK remote.*, 2 results");
|
is_deeply([sort keys %$fk_data], [qw/albumartist albumeditor/], "FK remote.*, 2 results");
|
||||||
|
|
||||||
|
|
||||||
$sth = $dbh->foreign_key_info(undef, 'remote', undef,
|
$sth = $dbh->foreign_key_info(undef, 'remote', undef,
|
||||||
undef, undef, undef);
|
undef, undef, undef);
|
||||||
$fk_data = $sth->fetchall_hashref('FKCOLUMN_NAME');
|
$fk_data = $sth->fetchall_hashref('FKCOLUMN_NAME');
|
||||||
is_deeply([sort keys %$fk_data], [qw/songalbum songartist/], "FK with PK remote.*, 2 results");
|
is_deeply([sort keys %$fk_data], [qw/songalbum songartist/], "FK with PK remote.*, 2 results");
|
||||||
|
|
||||||
|
|
||||||
$sth = $dbh->foreign_key_info(undef, undef, undef,
|
$sth = $dbh->foreign_key_info(undef, undef, undef,
|
||||||
undef, undef, 'song');
|
undef, undef, 'song');
|
||||||
$fk_data = $sth->fetchall_hashref('FKCOLUMN_NAME');
|
$fk_data = $sth->fetchall_hashref('FKCOLUMN_NAME');
|
||||||
|
@ -112,5 +124,3 @@ for ($fk_data->{songartist}) {
|
||||||
for ($fk_data->{songalbum}) {
|
for ($fk_data->{songalbum}) {
|
||||||
is($_->{KEY_SEQ}, 2, "FK song, key seq 2");
|
is($_->{KEY_SEQ}, 2, "FK song, key seq 2");
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,16 +1,25 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
use lib "t/lib";
|
$| = 1;
|
||||||
use SQLiteTest;
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
use DBD::SQLite;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
|
||||||
|
|
||||||
BEGIN {
|
BEGIN {
|
||||||
if (!has_compile_option('ENABLE_COLUMN_METADATA')) {
|
if (!grep /^ENABLE_COLUMN_METADATA/, DBD::SQLite::compile_options()) {
|
||||||
plan skip_all => "Column metadata is disabled for this DBD::SQLite";
|
plan skip_all => "Column metadata is disabled for this DBD::SQLite";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use lib "t/lib";
|
||||||
|
use SQLiteTest qw/connect_ok @CALL_FUNCS/;
|
||||||
|
use Test::NoWarnings;
|
||||||
|
|
||||||
|
plan tests => 16 * @CALL_FUNCS + 1;
|
||||||
for my $call_func (@CALL_FUNCS) {
|
for my $call_func (@CALL_FUNCS) {
|
||||||
my $dbh = connect_ok(RaiseError => 1);
|
my $dbh = connect_ok(RaiseError => 1);
|
||||||
$dbh->do('create table foo (id integer primary key autoincrement, "name space", unique_col integer unique)');
|
$dbh->do('create table foo (id integer primary key autoincrement, "name space", unique_col integer unique)');
|
||||||
|
@ -54,5 +63,3 @@ for my $call_func (@CALL_FUNCS) {
|
||||||
ok $@, "successfully died when dbh is inactive";
|
ok $@, "successfully died when dbh is inactive";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,12 +1,20 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest qw/connect_ok @CALL_FUNCS requires_sqlite/;
|
use SQLiteTest qw/connect_ok @CALL_FUNCS requires_sqlite/;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
|
|
||||||
BEGIN { requires_sqlite('3.7.10') }
|
BEGIN { requires_sqlite('3.7.10') }
|
||||||
|
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
|
plan tests => 6 * @CALL_FUNCS + 1;
|
||||||
|
|
||||||
for my $func (@CALL_FUNCS) {
|
for my $func (@CALL_FUNCS) {
|
||||||
{
|
{
|
||||||
|
@ -31,5 +39,3 @@ sub filename {
|
||||||
my $dbh = connect_ok(@_);
|
my $dbh = connect_ok(@_);
|
||||||
$dbh->$func('db_filename');
|
$dbh->$func('db_filename');
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,9 +1,21 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest qw/connect_ok @CALL_FUNCS has_sqlite/;
|
use SQLiteTest qw/connect_ok @CALL_FUNCS has_sqlite/;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
|
my $tests = 3;
|
||||||
|
$tests += 2 if has_sqlite('3.6.4');
|
||||||
|
$tests += 1 if has_sqlite('3.7.0');
|
||||||
|
|
||||||
|
plan tests => 4 + $tests * @CALL_FUNCS + 1;
|
||||||
|
|
||||||
my $dbh = connect_ok();
|
my $dbh = connect_ok();
|
||||||
{
|
{
|
||||||
|
@ -46,5 +58,3 @@ for my $func (@CALL_FUNCS) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest qw/connect_ok/;
|
use SQLiteTest qw/connect_ok/;
|
||||||
use Test::More;
|
use Test::More tests => 5;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
my $dbh = connect_ok();
|
my $dbh = connect_ok();
|
||||||
|
|
||||||
|
@ -21,5 +27,3 @@ $dbh->do("\nCOMMIT");
|
||||||
|
|
||||||
is $dbh->{AutoCommit}, 1,
|
is $dbh->{AutoCommit}, 1,
|
||||||
'AutoCommit=1 after "\nCOMMIT"';
|
'AutoCommit=1 after "\nCOMMIT"';
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
|
@ -12,7 +18,7 @@ BEGIN {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
my @sql_statements = split /\n\n/, <<__EOSQL__;
|
my @sql_statements = split /\n\n/, <<__EOSQL__;
|
||||||
CREATE TABLE a (
|
CREATE TABLE a (
|
||||||
|
@ -40,6 +46,9 @@ CREATE TABLE remote.b (
|
||||||
|
|
||||||
__EOSQL__
|
__EOSQL__
|
||||||
|
|
||||||
|
|
||||||
|
plan tests => @sql_statements + 2 + 46 * 2;
|
||||||
|
|
||||||
my $dbh = connect_ok( RaiseError => 1, PrintError => 0, AutoCommit => 1 );
|
my $dbh = connect_ok( RaiseError => 1, PrintError => 0, AutoCommit => 1 );
|
||||||
my $sth;
|
my $sth;
|
||||||
my $stats_data;
|
my $stats_data;
|
||||||
|
@ -114,5 +123,3 @@ for my $table_name ('a', 'A') {
|
||||||
}
|
}
|
||||||
ok(not(exists $stats_data->{a_ln}->{3}), "only two indexes in a_an index");
|
ok(not(exists $stats_data->{a_ln}->{3}), "only two indexes in a_an index");
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,9 +1,19 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
|
||||||
|
my $tests = 7;
|
||||||
|
$tests += 1 if has_sqlite('3.7.7');
|
||||||
|
plan tests => $tests;
|
||||||
|
|
||||||
use DBI;
|
use DBI;
|
||||||
use DBD::SQLite;
|
use DBD::SQLite;
|
||||||
|
|
||||||
|
@ -101,5 +111,3 @@ if (has_sqlite('3.7.7')) {
|
||||||
$dbh->disconnect;
|
$dbh->disconnect;
|
||||||
unlink $dbfile if -f $dbfile;
|
unlink $dbfile if -f $dbfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,12 +1,18 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
|
||||||
|
|
||||||
BEGIN { requires_sqlite('3.7.7') }
|
BEGIN { requires_sqlite('3.7.7') }
|
||||||
|
|
||||||
|
plan tests => 17;
|
||||||
use DBI;
|
use DBI;
|
||||||
use DBD::SQLite;
|
use DBD::SQLite;
|
||||||
|
|
||||||
|
@ -28,8 +34,7 @@ sub cleanup {
|
||||||
|
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
SKIP: {
|
{
|
||||||
skip 'URI filename is enabled', 1 if has_compile_option('USE_URI');
|
|
||||||
my $dbh = eval {
|
my $dbh = eval {
|
||||||
DBI->connect("dbi:SQLite:$uri{base}", undef, undef, {
|
DBI->connect("dbi:SQLite:$uri{base}", undef, undef, {
|
||||||
PrintError => 0,
|
PrintError => 0,
|
||||||
|
@ -220,5 +225,3 @@ SKIP: {
|
||||||
$dbh->disconnect;
|
$dbh->disconnect;
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest qw/connect_ok/;
|
use SQLiteTest qw/connect_ok/;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
use DBI qw(:sql_types);
|
use DBI qw(:sql_types);
|
||||||
|
|
||||||
|
plan tests => 9;
|
||||||
|
|
||||||
# The following is by mje++
|
# The following is by mje++
|
||||||
# http://pastebin.com/RkUwwVti
|
# http://pastebin.com/RkUwwVti
|
||||||
|
|
||||||
|
@ -64,5 +72,3 @@ $sth->bind_param(1, 1, SQL_INTEGER);
|
||||||
$sth->bind_param(2, $test_value, SQL_VARCHAR);
|
$sth->bind_param(2, $test_value, SQL_VARCHAR);
|
||||||
$sth->execute;
|
$sth->execute;
|
||||||
my_is($dbh, "prepared insert with provided bound data and type SQL_VARCHAR see_if_its_a_number=0");
|
my_is($dbh, "prepared insert with provided bound data and type SQL_VARCHAR see_if_its_a_number=0");
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest qw/connect_ok/;
|
use SQLiteTest qw/connect_ok/;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
|
@ -10,10 +16,12 @@ BEGIN{
|
||||||
plan skip_all => 'this test requires SQLite 3.7.12 and above' unless $DBD::SQLite::sqlite_version_number > 3007011;
|
plan skip_all => 'this test requires SQLite 3.7.12 and above' unless $DBD::SQLite::sqlite_version_number > 3007011;
|
||||||
}
|
}
|
||||||
|
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
use DBD::SQLite::Constants qw/:extended_result_codes :result_codes/;
|
use DBD::SQLite::Constants qw/:extended_result_codes :result_codes/;
|
||||||
use File::Temp;
|
use File::Temp;
|
||||||
|
|
||||||
|
plan tests => 18;
|
||||||
|
|
||||||
my $tmpdir = File::Temp::tempdir(CLEANUP => 1);
|
my $tmpdir = File::Temp::tempdir(CLEANUP => 1);
|
||||||
ok -d $tmpdir;
|
ok -d $tmpdir;
|
||||||
|
|
||||||
|
@ -48,5 +56,3 @@ for my $flag (0, 1) {
|
||||||
my $err = DBI->err;
|
my $err = DBI->err;
|
||||||
is $err => $expected{$flag};
|
is $err => $expected{$flag};
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest qw/connect_ok requires_sqlite/;
|
use SQLiteTest qw/connect_ok requires_sqlite/;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
|
@ -7,7 +13,9 @@ use DBD::SQLite::Constants qw/SQLITE_OPEN_READONLY/;
|
||||||
|
|
||||||
BEGIN { requires_sqlite('3.7.11') }
|
BEGIN { requires_sqlite('3.7.11') }
|
||||||
|
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
|
plan tests => 14;
|
||||||
|
|
||||||
{
|
{
|
||||||
my $dbh = connect_ok(
|
my $dbh = connect_ok(
|
||||||
|
@ -38,5 +46,3 @@ use if -d ".git", "Test::FailWarnings";
|
||||||
# told so)
|
# told so)
|
||||||
ok $dbh->do('CREATE TABLE foo (id)');
|
ok $dbh->do('CREATE TABLE foo (id)');
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest qw/requires_sqlite/;
|
use SQLiteTest qw/requires_sqlite/;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
|
@ -7,7 +13,9 @@ use DBD::SQLite;
|
||||||
|
|
||||||
BEGIN { requires_sqlite('3.10.0'); }
|
BEGIN { requires_sqlite('3.10.0'); }
|
||||||
|
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
|
plan tests => 13;
|
||||||
|
|
||||||
ok !DBD::SQLite::strlike("foo_bar", "FOO1BAR");
|
ok !DBD::SQLite::strlike("foo_bar", "FOO1BAR");
|
||||||
ok !DBD::SQLite::strlike("foo_bar", "FOO_BAR");
|
ok !DBD::SQLite::strlike("foo_bar", "FOO_BAR");
|
||||||
|
@ -21,5 +29,3 @@ ok DBD::SQLite::strlike("\\%foobar", "1FOOBAR", "\\");
|
||||||
ok !DBD::SQLite::strlike("\\%foobar", "%FOOBAR", "\\");
|
ok !DBD::SQLite::strlike("\\%foobar", "%FOOBAR", "\\");
|
||||||
ok DBD::SQLite::strlike("!%foobar", "1FOOBAR", "!");
|
ok DBD::SQLite::strlike("!%foobar", "1FOOBAR", "!");
|
||||||
ok !DBD::SQLite::strlike("!%foobar", "%FOOBAR", "!");
|
ok !DBD::SQLite::strlike("!%foobar", "%FOOBAR", "!");
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,13 +1,20 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest qw/connect_ok @CALL_FUNCS/;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
#use if -d ".git", "Test::FailWarnings"; # see RT#112220
|
BEGIN {
|
||||||
|
if ($] < 5.008005) {
|
||||||
BEGIN { requires_unicode_support() }
|
plan skip_all => 'Unicode is not supported before 5.8.5';
|
||||||
|
}
|
||||||
use DBD::SQLite::Constants ':dbd_sqlite_string_mode';
|
}
|
||||||
|
#use Test::NoWarnings; # see RT#112220
|
||||||
|
|
||||||
# special case for multibyte (non-ASCII) character class,
|
# special case for multibyte (non-ASCII) character class,
|
||||||
# which only works correctly under the unicode mode
|
# which only works correctly under the unicode mode
|
||||||
|
@ -15,17 +22,19 @@ my @words = ("\x{e3}\x{83}\x{86}\x{e3}\x{82}\x{b9}\x{e3}\x{83}\x{88}", "\x{e3}\x
|
||||||
|
|
||||||
my $regex = "\x{e3}\x{83}\x{86}[\x{e3}\x{82}\x{b9}\x{e3}\x{83}\x{b3}]\x{e3}\x{83}\x{88}"; # テ[スン]ト
|
my $regex = "\x{e3}\x{83}\x{86}[\x{e3}\x{82}\x{b9}\x{e3}\x{83}\x{b3}]\x{e3}\x{83}\x{88}"; # テ[スン]ト
|
||||||
|
|
||||||
|
plan tests => 2 * 2 * @CALL_FUNCS;
|
||||||
|
|
||||||
foreach my $call_func (@CALL_FUNCS) {
|
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
|
# 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
|
# populate test data
|
||||||
my @vals = @words;
|
my @vals = @words;
|
||||||
my $re = $regex;
|
my $re = $regex;
|
||||||
if ($string_mode == DBD_SQLITE_STRING_MODE_UNICODE_STRICT) {
|
if ($use_unicode) {
|
||||||
utf8::decode($_) foreach @vals;
|
utf8::decode($_) foreach @vals;
|
||||||
utf8::decode($re);
|
utf8::decode($re);
|
||||||
}
|
}
|
||||||
|
@ -43,4 +52,3 @@ foreach my $call_func (@CALL_FUNCS) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,9 +1,17 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest qw/connect_ok/;
|
use SQLiteTest qw/connect_ok/;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
|
plan tests => 7;
|
||||||
|
|
||||||
my $dbh = connect_ok( RaiseError => 1 );
|
my $dbh = connect_ok( RaiseError => 1 );
|
||||||
ok $dbh->do('create table foo (id integer, value integer)');
|
ok $dbh->do('create table foo (id integer, value integer)');
|
||||||
|
@ -26,5 +34,3 @@ ok $dbh->do('create table foo (id integer, value integer)');
|
||||||
my $sth = $dbh->prepare('select * from foo where id = ?');
|
my $sth = $dbh->prepare('select * from foo where id = ?');
|
||||||
is_deeply $sth->{ParamValues} => {1 => undef}, "ParamValues without binding";
|
is_deeply $sth->{ParamValues} => {1 => undef}, "ParamValues without binding";
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
25
t/64_limit.t
25
t/64_limit.t
|
@ -1,25 +0,0 @@
|
||||||
use strict;
|
|
||||||
use warnings;
|
|
||||||
use lib "t/lib";
|
|
||||||
use SQLiteTest qw/connect_ok @CALL_FUNCS/;
|
|
||||||
use Test::More;
|
|
||||||
use DBD::SQLite::Constants qw/SQLITE_LIMIT_VARIABLE_NUMBER/;
|
|
||||||
use if -d ".git", "Test::FailWarnings";
|
|
||||||
|
|
||||||
for my $func (@CALL_FUNCS) {
|
|
||||||
my $dbh = connect_ok(PrintError => 0, RaiseError => 1);
|
|
||||||
my $current_limit = $dbh->$func(SQLITE_LIMIT_VARIABLE_NUMBER, 'limit');
|
|
||||||
ok $current_limit, "current limit: $current_limit";
|
|
||||||
|
|
||||||
$current_limit = $dbh->$func(SQLITE_LIMIT_VARIABLE_NUMBER, -1, 'limit');
|
|
||||||
ok $current_limit, "current limit: $current_limit";
|
|
||||||
|
|
||||||
ok $dbh->do('create table foo (id, text)');
|
|
||||||
ok $dbh->do('insert into foo values(?, ?)', undef, 1, 'OK');
|
|
||||||
|
|
||||||
ok $dbh->$func(SQLITE_LIMIT_VARIABLE_NUMBER, 1, 'limit');
|
|
||||||
eval { $dbh->do('insert into foo values(?, ?)', undef, 2, 'NOT OK') };
|
|
||||||
like $@ => qr/too many SQL variables/, "should raise error because of the variable limit";
|
|
||||||
}
|
|
||||||
|
|
||||||
done_testing;
|
|
313
t/65_db_config.t
313
t/65_db_config.t
|
@ -1,313 +0,0 @@
|
||||||
use strict;
|
|
||||||
use warnings;
|
|
||||||
use lib "t/lib";
|
|
||||||
use SQLiteTest qw/connect_ok @CALL_FUNCS/;
|
|
||||||
use Test::More;
|
|
||||||
use DBD::SQLite::Constants qw/:database_connection_configuration_options/;
|
|
||||||
use if -d ".git", "Test::FailWarnings";
|
|
||||||
|
|
||||||
# LOOKASIDE
|
|
||||||
for my $func (@CALL_FUNCS) {
|
|
||||||
SKIP: {
|
|
||||||
skip 'LOOKASIDE is not supported', 2 if !SQLITE_DBCONFIG_LOOKASIDE;
|
|
||||||
my $dbh = connect_ok(RaiseError => 1, PrintError => 0);
|
|
||||||
eval { $dbh->$func(SQLITE_DBCONFIG_LOOKASIDE, 1, 'db_config') };
|
|
||||||
ok $@, 'LOOKASIDE is not supported';
|
|
||||||
like $@ => qr/LOOKASIDE is not supported/;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# MAINDBNAME
|
|
||||||
for my $func (@CALL_FUNCS) {
|
|
||||||
SKIP: {
|
|
||||||
skip 'MAINDBNAME is not supported', 2 if !SQLITE_DBCONFIG_MAINDBNAME;
|
|
||||||
my $dbh = connect_ok(RaiseError => 1, PrintError => 0);
|
|
||||||
eval { $dbh->$func(SQLITE_DBCONFIG_MAINDBNAME, 1, 'db_config') };
|
|
||||||
ok $@, 'MAINDBNAME is not supported';
|
|
||||||
like $@ => qr/MAINDBNAME is not supported/;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# ENABLE_FKEY
|
|
||||||
for my $func (@CALL_FUNCS) {
|
|
||||||
SKIP: {
|
|
||||||
skip 'ENABLE_FKEY is not supported', 3 if !SQLITE_DBCONFIG_ENABLE_FKEY;
|
|
||||||
my $dbh = connect_ok(RaiseError => 1, PrintError => 0);
|
|
||||||
my $ret = $dbh->$func(SQLITE_DBCONFIG_ENABLE_FKEY, -1, 'db_config');
|
|
||||||
note "current ENABLE_FKEY value: $ret";
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_ENABLE_FKEY, 1, 'db_config');
|
|
||||||
is $ret => 1, 'enable foreign key';
|
|
||||||
|
|
||||||
# TODO: add foreign key check
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_ENABLE_FKEY, 0, 'db_config');
|
|
||||||
is $ret => 0, 'disable foreign key';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# ENABLE_TRIGGER
|
|
||||||
for my $func (@CALL_FUNCS) {
|
|
||||||
SKIP: {
|
|
||||||
skip 'ENABLE_TRIGGER is not supported', 3 if !SQLITE_DBCONFIG_ENABLE_TRIGGER;
|
|
||||||
my $dbh = connect_ok(RaiseError => 1, PrintError => 0);
|
|
||||||
my $ret = $dbh->$func(SQLITE_DBCONFIG_ENABLE_TRIGGER, -1, 'db_config');
|
|
||||||
note "current ENABLE_TRIGGER value: $ret";
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_ENABLE_TRIGGER, 1, 'db_config');
|
|
||||||
is $ret => 1, 'enable trigger';
|
|
||||||
|
|
||||||
# TODO: add trigger check
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_ENABLE_TRIGGER, 0, 'db_config');
|
|
||||||
is $ret => 0, 'disable trigger';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# ENABLE_FTS3_TOKENIZER
|
|
||||||
for my $func (@CALL_FUNCS) {
|
|
||||||
SKIP: {
|
|
||||||
skip 'ENABLE_FTS3_TOKENIZER is not supported', 3 if !SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER;
|
|
||||||
my $dbh = connect_ok(RaiseError => 1, PrintError => 0);
|
|
||||||
my $ret = $dbh->$func(SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, -1, 'db_config');
|
|
||||||
note "current ENABLE_FTS3_TOKENIZER value: $ret";
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, 1, 'db_config');
|
|
||||||
is $ret => 1, 'enable fts3_tokenizer';
|
|
||||||
|
|
||||||
# TODO: add fts3_tokenizer check
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, 0, 'db_config');
|
|
||||||
is $ret => 0, 'disable fts3_tokenizer';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# ENABLE_LOAD_EXTENSION
|
|
||||||
for my $func (@CALL_FUNCS) {
|
|
||||||
SKIP: {
|
|
||||||
skip 'ENABLE_LOAD_EXTENSION is not supported', 3 if !SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION;
|
|
||||||
my $dbh = connect_ok(RaiseError => 1, PrintError => 0);
|
|
||||||
my $ret = $dbh->$func(SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, -1, 'db_config');
|
|
||||||
note "current ENABLE_LOAD_EXTENSION value: $ret";
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, 'db_config');
|
|
||||||
is $ret => 1, 'enable load_extension';
|
|
||||||
|
|
||||||
# TODO: add load_extension check
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 0, 'db_config');
|
|
||||||
is $ret => 0, 'disable load_extension';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# NO_CKPT_ON_CLOSE
|
|
||||||
for my $func (@CALL_FUNCS) {
|
|
||||||
SKIP: {
|
|
||||||
skip 'NO_CKPT_ON_CLOSE is not supported', 3 if !SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE;
|
|
||||||
my $dbh = connect_ok(RaiseError => 1, PrintError => 0);
|
|
||||||
my $ret = $dbh->$func(SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, -1, 'db_config');
|
|
||||||
note "current NO_CKPT_ON_CLOSE value: $ret";
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, 1, 'db_config');
|
|
||||||
is $ret => 1, 'no checkpoint on close';
|
|
||||||
|
|
||||||
# TODO: add checkpoint check
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, 0, 'db_config');
|
|
||||||
is $ret => 0, 'checkpoint on close';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# ENABLE_QPSG
|
|
||||||
for my $func (@CALL_FUNCS) {
|
|
||||||
SKIP: {
|
|
||||||
skip 'ENABLE_QPSG is not supported', 3 if !SQLITE_DBCONFIG_ENABLE_QPSG;
|
|
||||||
my $dbh = connect_ok(RaiseError => 1, PrintError => 0);
|
|
||||||
my $ret = $dbh->$func(SQLITE_DBCONFIG_ENABLE_QPSG, -1, 'db_config');
|
|
||||||
note "current ENABLE_OPSG value: $ret";
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_ENABLE_QPSG, 1, 'db_config');
|
|
||||||
is $ret => 1, 'enable query planner stability guarantee';
|
|
||||||
|
|
||||||
# TODO: add qpsg check
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_ENABLE_QPSG, 0, 'db_config');
|
|
||||||
is $ret => 0, 'disable query planner stability guarantee';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# TRIGGER_EQP
|
|
||||||
for my $func (@CALL_FUNCS) {
|
|
||||||
SKIP: {
|
|
||||||
skip 'TRIGGER_EQP is not supported', 3 if !SQLITE_DBCONFIG_TRIGGER_EQP;
|
|
||||||
my $dbh = connect_ok(RaiseError => 1, PrintError => 0);
|
|
||||||
my $ret = $dbh->$func(SQLITE_DBCONFIG_TRIGGER_EQP, -1, 'db_config');
|
|
||||||
note "current TRIGGER_EQP value: $ret";
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_TRIGGER_EQP, 1, 'db_config');
|
|
||||||
is $ret => 1, 'trigger explain query plan';
|
|
||||||
|
|
||||||
# TODO: add trigger check
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_TRIGGER_EQP, 0, 'db_config');
|
|
||||||
is $ret => 0, 'no trigger explain query plan';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# RESET_DATABASE
|
|
||||||
for my $func (@CALL_FUNCS) {
|
|
||||||
SKIP: {
|
|
||||||
skip 'RESET_DATABASE is not supported', 3 if !SQLITE_DBCONFIG_RESET_DATABASE;
|
|
||||||
my $dbh = connect_ok(RaiseError => 1, PrintError => 0);
|
|
||||||
my $ret = $dbh->$func(SQLITE_DBCONFIG_RESET_DATABASE, -1, 'db_config');
|
|
||||||
note "current RESET_DATABASE value: $ret";
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_RESET_DATABASE, 1, 'db_config');
|
|
||||||
is $ret => 1, 'enable reset database';
|
|
||||||
|
|
||||||
# TODO: add reset check
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_RESET_DATABASE, 0, 'db_config');
|
|
||||||
is $ret => 0, 'disable reset database';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# DEFENSIVE
|
|
||||||
for my $func (@CALL_FUNCS) {
|
|
||||||
SKIP: {
|
|
||||||
skip 'DEFENSIVE is not supported', 8 if !SQLITE_DBCONFIG_DEFENSIVE;
|
|
||||||
my $dbh = connect_ok(RaiseError => 1, PrintError => 0);
|
|
||||||
|
|
||||||
my $sql = 'CREATE TABLE foo (id, text)';
|
|
||||||
$dbh->do($sql);
|
|
||||||
$dbh->do('PRAGMA writable_schema=ON');
|
|
||||||
my $row = $dbh->selectrow_hashref('SELECT * FROM sqlite_master WHERE name = ?', {Slice => +{}}, 'foo');
|
|
||||||
is $row->{sql} => $sql, 'found sql';
|
|
||||||
|
|
||||||
my $ret = $dbh->$func(SQLITE_DBCONFIG_DEFENSIVE, -1, 'db_config');
|
|
||||||
note "current DEFENSIVE value: $ret";
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_DEFENSIVE, 1, 'db_config');
|
|
||||||
is $ret => 1;
|
|
||||||
eval { $dbh->do('UPDATE sqlite_master SET name = ? WHERE name = ?', undef, 'bar', 'foo'); };
|
|
||||||
ok $@, "updating sqlite_master is prohibited";
|
|
||||||
like $@ => qr/table sqlite_master may not be modified/;
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_DEFENSIVE, 0, 'db_config');
|
|
||||||
is $ret => 0;
|
|
||||||
$ret = $dbh->do('UPDATE sqlite_master SET name = ? WHERE name = ?', undef, 'bar', 'foo');
|
|
||||||
ok $ret, 'updating sqlite_master is succeeded';
|
|
||||||
$row = $dbh->selectrow_hashref('SELECT * FROM sqlite_master WHERE name = ?', {Slice => +{}}, 'foo');
|
|
||||||
ok !$row, 'sql not found';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# DEFENSIVE at connection
|
|
||||||
SKIP: {
|
|
||||||
skip 'DEFENSIVE is not supported', 3 if !SQLITE_DBCONFIG_DEFENSIVE;
|
|
||||||
my $dbh = connect_ok(RaiseError => 1, PrintError => 0, sqlite_defensive => 1);
|
|
||||||
|
|
||||||
my $sql = 'CREATE TABLE foo (id, text)';
|
|
||||||
$dbh->do($sql);
|
|
||||||
$dbh->do('PRAGMA writable_schema=ON');
|
|
||||||
eval { $dbh->do('UPDATE sqlite_master SET name = ? WHERE name = ?', undef, 'bar', 'foo'); };
|
|
||||||
ok $@, "updating sqlite_master is prohibited";
|
|
||||||
like $@ => qr/table sqlite_master may not be modified/;
|
|
||||||
}
|
|
||||||
|
|
||||||
# WRITABLE_SCHEMA
|
|
||||||
for my $func (@CALL_FUNCS) {
|
|
||||||
SKIP: {
|
|
||||||
skip 'WRITABLE_SCHEMA is not supported', 5 if !SQLITE_DBCONFIG_WRITABLE_SCHEMA;
|
|
||||||
my $dbh = connect_ok(RaiseError => 1, PrintError => 0);
|
|
||||||
my $ret = $dbh->$func(SQLITE_DBCONFIG_WRITABLE_SCHEMA, -1, 'db_config');
|
|
||||||
note "current WRITABLE_SCHEMA value: $ret";
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_WRITABLE_SCHEMA, 1, 'db_config');
|
|
||||||
is $ret => 1, 'schema is writable';
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_WRITABLE_SCHEMA, 0, 'db_config');
|
|
||||||
is $ret => 0, 'schema is not writable';
|
|
||||||
|
|
||||||
$dbh->do('PRAGMA writable_schema=ON');
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_WRITABLE_SCHEMA, -1, 'db_config');
|
|
||||||
is $ret => 1, 'schema is writable (by pragma)';
|
|
||||||
|
|
||||||
$dbh->do('PRAGMA writable_schema=OFF');
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_WRITABLE_SCHEMA, -1, 'db_config');
|
|
||||||
is $ret => 0, 'schema is not writable (by pragma)';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# LEGACY_ALTER_TABLE
|
|
||||||
for my $func (@CALL_FUNCS) {
|
|
||||||
SKIP: {
|
|
||||||
skip 'WRITABLE_SCHEMA is not supported', 5 if !SQLITE_DBCONFIG_LEGACY_ALTER_TABLE;
|
|
||||||
my $dbh = connect_ok(RaiseError => 1, PrintError => 0);
|
|
||||||
my $ret = $dbh->$func(SQLITE_DBCONFIG_LEGACY_ALTER_TABLE, -1, 'db_config');
|
|
||||||
note "current LEGACY_ALTER_TABLE value: $ret";
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_LEGACY_ALTER_TABLE, 1, 'db_config');
|
|
||||||
is $ret => 1, 'use legacy alter table';
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_LEGACY_ALTER_TABLE, 0, 'db_config');
|
|
||||||
is $ret => 0, 'no legacy alter table';
|
|
||||||
|
|
||||||
# TODO: add alter table check?
|
|
||||||
|
|
||||||
$dbh->do('PRAGMA legacy_alter_table=ON');
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_LEGACY_ALTER_TABLE, -1, 'db_config');
|
|
||||||
is $ret => 1, 'use legacy alter table (by pragma)';
|
|
||||||
|
|
||||||
$dbh->do('PRAGMA legacy_alter_table=OFF');
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_LEGACY_ALTER_TABLE, -1, 'db_config');
|
|
||||||
is $ret => 0, 'no legacy alter table (by pragma)';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# DQS_DML
|
|
||||||
for my $func (@CALL_FUNCS) {
|
|
||||||
SKIP: {
|
|
||||||
skip 'DQS_DML is not supported', 5 if !SQLITE_DBCONFIG_DQS_DML;
|
|
||||||
my $dbh = connect_ok(RaiseError => 1, PrintError => 0);
|
|
||||||
my $ret = $dbh->$func(SQLITE_DBCONFIG_DQS_DML, -1, 'db_config');
|
|
||||||
note "current DQS_DML value: $ret";
|
|
||||||
$dbh->do('CREATE TABLE foo (id, text)');
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_DQS_DML, 1, 'db_config');
|
|
||||||
is $ret => 1, 'allows double-quoted string literal';
|
|
||||||
|
|
||||||
eval { $dbh->do('INSERT INTO foo VALUES (1, "text")'); };
|
|
||||||
ok !$@, "double-quoted string literal is allowed";
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_DQS_DML, 0, 'db_config');
|
|
||||||
is $ret => 0, 'no double-quoted string literal';
|
|
||||||
|
|
||||||
eval { $dbh->do('INSERT INTO foo VALUES (2, "text2")'); };
|
|
||||||
like $@ => qr/no such column/, "double-quoted string literal is not allowed";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# DQS_DDL
|
|
||||||
for my $func (@CALL_FUNCS) {
|
|
||||||
SKIP: {
|
|
||||||
skip 'DQS_DDL is not supported', 5 if !SQLITE_DBCONFIG_DQS_DDL;
|
|
||||||
my $dbh = connect_ok(RaiseError => 1, PrintError => 0);
|
|
||||||
my $ret = $dbh->$func(SQLITE_DBCONFIG_DQS_DDL, -1, 'db_config');
|
|
||||||
note "current DQS_DDL value: $ret";
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_DQS_DDL, 1, 'db_config');
|
|
||||||
is $ret => 1, 'allows double-quoted string literal';
|
|
||||||
|
|
||||||
eval { $dbh->do('CREATE TABLE foo (a, b, c CHECK (c!="null") )'); };
|
|
||||||
ok !$@, "double-quoted string literal is allowed";
|
|
||||||
|
|
||||||
$ret = $dbh->$func(SQLITE_DBCONFIG_DQS_DDL, 0, 'db_config');
|
|
||||||
is $ret => 0, 'no double-quoted string literal';
|
|
||||||
|
|
||||||
eval { $dbh->do('CREATE TABLE bar (a, b, c CHECK (c!="null") )'); };
|
|
||||||
like $@ => qr/no such column/, "double-quoted string literal is not allowed";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
done_testing;
|
|
|
@ -1,57 +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";
|
|
||||||
|
|
||||||
for my $func (@CALL_FUNCS) {
|
|
||||||
my $dbh = connect_ok(PrintError => 0, RaiseError => 1);
|
|
||||||
$dbh->do('create table foo (id)');
|
|
||||||
|
|
||||||
note 'begin_work does not make autocommit false';
|
|
||||||
my $autocommit = $dbh->$func('get_autocommit');
|
|
||||||
ok $autocommit, "internal autocommit is true";
|
|
||||||
ok $dbh->{AutoCommit}, "AutoCommit is also true";
|
|
||||||
|
|
||||||
$dbh->begin_work;
|
|
||||||
$autocommit = $dbh->$func('get_autocommit');
|
|
||||||
ok $autocommit, "internal autocommit is still true";
|
|
||||||
ok !$dbh->{AutoCommit}, "AutoCommit gets false";
|
|
||||||
|
|
||||||
$dbh->do('insert into foo values (1)');
|
|
||||||
$dbh->commit;
|
|
||||||
|
|
||||||
$autocommit = $dbh->$func('get_autocommit');
|
|
||||||
ok $autocommit, "internal autocommit is still true";
|
|
||||||
ok $dbh->{AutoCommit}, "AutoCommit is true now";
|
|
||||||
|
|
||||||
note 'nor turning AutoCommit off does not make autocommit false';
|
|
||||||
$dbh->{AutoCommit} = 0;
|
|
||||||
$autocommit = $dbh->$func('get_autocommit');
|
|
||||||
ok $autocommit, "internal autocommit is still true";
|
|
||||||
ok !$dbh->{AutoCommit}, "AutoCommit is false";
|
|
||||||
|
|
||||||
$dbh->do('insert into foo values (1)');
|
|
||||||
$dbh->commit;
|
|
||||||
$dbh->{AutoCommit} = 1;
|
|
||||||
|
|
||||||
$autocommit = $dbh->$func('get_autocommit');
|
|
||||||
ok $autocommit, "internal autocommit is still true";
|
|
||||||
ok $dbh->{AutoCommit}, "AutoCommit is true now";
|
|
||||||
|
|
||||||
note 'explicit BEGIN make autocommit false';
|
|
||||||
$dbh->do('BEGIN');
|
|
||||||
$autocommit = $dbh->$func('get_autocommit');
|
|
||||||
ok !$autocommit, "internal autocommit gets false";
|
|
||||||
ok !$dbh->{AutoCommit}, "AutoCommit is also false";
|
|
||||||
|
|
||||||
$dbh->do('insert into foo values (1)');
|
|
||||||
$dbh->commit;
|
|
||||||
|
|
||||||
$autocommit = $dbh->$func('get_autocommit');
|
|
||||||
ok $autocommit, "internal autocommit is true now";
|
|
||||||
ok $dbh->{AutoCommit}, "AutoCommit is true now";
|
|
||||||
}
|
|
||||||
|
|
||||||
done_testing;
|
|
|
@ -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;
|
|
|
@ -1,9 +1,17 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
use Test::NoWarnings;
|
||||||
|
|
||||||
|
plan tests => 3 * @CALL_FUNCS * 3 + 1;
|
||||||
|
|
||||||
# The following snippets are copied from Cookbook.pod by hand.
|
# The following snippets are copied from Cookbook.pod by hand.
|
||||||
# Don't forget to update here when the pod is updated.
|
# Don't forget to update here when the pod is updated.
|
||||||
|
@ -124,5 +132,3 @@ END_SQL
|
||||||
is $result->[1] => 1250;
|
is $result->[1] => 1250;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -8,11 +8,7 @@ use File::Spec ();
|
||||||
use Test::More ();
|
use Test::More ();
|
||||||
|
|
||||||
our @ISA = 'Exporter';
|
our @ISA = 'Exporter';
|
||||||
our @EXPORT = qw/
|
our @EXPORT = qw/connect_ok dies dbfile @CALL_FUNCS $sqlite_call has_sqlite requires_sqlite/;
|
||||||
connect_ok dies dbfile @CALL_FUNCS $sqlite_call
|
|
||||||
has_sqlite requires_sqlite requires_unicode_support
|
|
||||||
allow_warnings has_compile_option has_fts
|
|
||||||
/;
|
|
||||||
our @CALL_FUNCS;
|
our @CALL_FUNCS;
|
||||||
our $sqlite_call;
|
our $sqlite_call;
|
||||||
|
|
||||||
|
@ -104,6 +100,15 @@ On more recent versions, the loop will run twice;
|
||||||
the second execution will call
|
the second execution will call
|
||||||
C<< $dbh->sqlite_method_to_call(@args) >>.
|
C<< $dbh->sqlite_method_to_call(@args) >>.
|
||||||
|
|
||||||
|
The number of tests to plan should be adapted accordingly.
|
||||||
|
It can be computed like this :
|
||||||
|
|
||||||
|
plan tests => $n_normal_tests * @CALL_FUNCS + 1;
|
||||||
|
|
||||||
|
The additional C< + 1> is required when using
|
||||||
|
L<Test::NoWarnings>, because that module adds
|
||||||
|
a final test in an END block outside of the loop.
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
|
|
||||||
|
@ -141,40 +146,6 @@ $sqlite_call = sub {
|
||||||
$CALL_FUNCS[-1]->($dbh, @_, $func_to_call);
|
$CALL_FUNCS[-1]->($dbh, @_, $func_to_call);
|
||||||
};
|
};
|
||||||
|
|
||||||
=head2 has_compile_option
|
|
||||||
|
|
||||||
has_compile_option('ENABLE_FTS3');
|
|
||||||
has_compile_option(qr/^ENABLE_FTS[345]/);
|
|
||||||
|
|
||||||
returns true if DBD::SQLite is built with a specified compile option.
|
|
||||||
|
|
||||||
=cut
|
|
||||||
|
|
||||||
sub has_compile_option {
|
|
||||||
my $option = shift;
|
|
||||||
require DBD::SQLite;
|
|
||||||
return unless DBD::SQLite->can('compile_options');
|
|
||||||
my $re = ref $option eq ref qr// ? $option : qr/\b$option\b/;
|
|
||||||
grep /$re/, DBD::SQLite::compile_options();
|
|
||||||
}
|
|
||||||
|
|
||||||
=head2 has_fts
|
|
||||||
|
|
||||||
has_fts();
|
|
||||||
has_fts(3);
|
|
||||||
|
|
||||||
returns true if DBD::SQLite is built with FTS.
|
|
||||||
|
|
||||||
=cut
|
|
||||||
|
|
||||||
sub has_fts {
|
|
||||||
if (my $version = shift) {
|
|
||||||
has_compile_option("ENABLE_FTS$version");
|
|
||||||
} else {
|
|
||||||
has_compile_option(qr/\bENABLE_FTS\d\b/);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
=head2 has_sqlite
|
=head2 has_sqlite
|
||||||
|
|
||||||
has_sqlite('3.6.11');
|
has_sqlite('3.6.11');
|
||||||
|
@ -208,33 +179,4 @@ sub requires_sqlite {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
=head2 requires_unicode_support
|
|
||||||
|
|
||||||
BEGIN { requires_unicode_support(); }
|
|
||||||
|
|
||||||
skips all the tests if Perl does not have sane Unicode support.
|
|
||||||
|
|
||||||
=cut
|
|
||||||
|
|
||||||
sub requires_unicode_support {
|
|
||||||
unless ($] >= 5.008005) {
|
|
||||||
Test::More::plan skip_all => "Unicode is not supported before 5.8.5";
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
=head2 allow_warnings
|
|
||||||
|
|
||||||
allow_warnings { eval {...} };
|
|
||||||
|
|
||||||
hides SQLite warnings from Test::FailWarnings.
|
|
||||||
|
|
||||||
=cut
|
|
||||||
|
|
||||||
sub allow_warnings (&) {
|
|
||||||
my $code = shift;
|
|
||||||
local $SIG{__WARN__} = sub { Test::More::note @_ };
|
|
||||||
$code->();
|
|
||||||
}
|
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -1,12 +1,20 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
|
||||||
|
|
||||||
BEGIN { requires_sqlite('3.6.8') }
|
BEGIN { requires_sqlite('3.6.8') }
|
||||||
|
|
||||||
|
plan tests => 13;
|
||||||
|
use Test::NoWarnings;
|
||||||
|
|
||||||
{ # simple case
|
{ # simple case
|
||||||
my $dbh = connect_ok(
|
my $dbh = connect_ok(
|
||||||
AutoCommit => 1,
|
AutoCommit => 1,
|
||||||
|
@ -152,5 +160,3 @@ BEGIN { requires_sqlite('3.6.8') }
|
||||||
$dbh->{AutoCommit} = 1;
|
$dbh->{AutoCommit} = 1;
|
||||||
# should not spit the "Issuing rollback()" warning
|
# should not spit the "Issuing rollback()" warning
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,12 +1,20 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
|
||||||
|
|
||||||
BEGIN { requires_sqlite('3.6.8') }
|
BEGIN { requires_sqlite('3.6.8') }
|
||||||
|
|
||||||
|
plan tests => 2;
|
||||||
|
use Test::NoWarnings;
|
||||||
|
|
||||||
{ # simple case
|
{ # simple case
|
||||||
my $dbh = connect_ok(
|
my $dbh = connect_ok(
|
||||||
AutoCommit => 1,
|
AutoCommit => 1,
|
||||||
|
@ -18,5 +26,3 @@ BEGIN { requires_sqlite('3.6.8') }
|
||||||
$dbh->commit;
|
$dbh->commit;
|
||||||
# should not spit the "Issuing rollback()" warning
|
# should not spit the "Issuing rollback()" warning
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
|
@ -1,9 +1,17 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
use lib "t/lib";
|
use lib "t/lib";
|
||||||
use SQLiteTest;
|
use SQLiteTest;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
use if -d ".git", "Test::FailWarnings";
|
|
||||||
|
plan tests => 14;
|
||||||
|
use Test::NoWarnings;
|
||||||
|
|
||||||
{
|
{
|
||||||
my $dbh = connect_ok();
|
my $dbh = connect_ok();
|
||||||
|
@ -28,5 +36,3 @@ use if -d ".git", "Test::FailWarnings";
|
||||||
is $info{bat}[1] => 4;
|
is $info{bat}[1] => 4;
|
||||||
is $info{bat}[2] => 4;
|
is $info{bat}[2] => 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
done_testing;
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue