You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
perl-DBD-SQLite/DBD-SQLite-1.48-LIKE-GLOB-R...

116 lines
3.7 KiB

From b38e57a23b4e4b5c3b5b115558e12950f393b323 Mon Sep 17 00:00:00 2001
From: Kenichi Ishigaki <ishigaki@cpan.org>
Date: Thu, 7 Jan 2016 19:47:10 +0900
Subject: [PATCH] LIKE/GLOB/REGEXP are also required to be implemented for
SQLite 3.10.0 and above
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
SQLite.xs | 18 ++++++++++++++++++
dbdimp.c | 8 ++++++++
lib/DBD/SQLite/VirtualTable/PerlData.pm | 24 +++++++++++++++++-------
3 files changed, 43 insertions(+), 7 deletions(-)
diff --git a/SQLite.xs b/SQLite.xs
index abe3524..bc6644b 100644
--- a/SQLite.xs
+++ b/SQLite.xs
@@ -363,5 +363,23 @@ sqlite_status(reset = 0)
OUTPUT:
RETVAL
+#if SQLITE_VERSION_NUMBER >= 3010000
+
+int
+strglob(const char *zglob, const char *zstr)
+ CODE:
+ RETVAL = sqlite3_strglob(zglob, zstr);
+ OUTPUT:
+ RETVAL
+
+int
+strlike(const char *zglob, const char *zstr, unsigned int esc = 0)
+ CODE:
+ RETVAL = sqlite3_strlike(zglob, zstr, esc);
+ OUTPUT:
+ RETVAL
+
+#endif
+
INCLUDE: constants.inc
INCLUDE: SQLite.xsi
diff --git a/dbdimp.c b/dbdimp.c
index a4e426b..b441940 100644
--- a/dbdimp.c
+++ b/dbdimp.c
@@ -3129,6 +3129,14 @@ _constraint_op_to_string(unsigned char op) {
return "<=";
case SQLITE_INDEX_CONSTRAINT_MATCH:
return "MATCH";
+#if SQLITE_VERSION_NUMBER >= 3010000
+ case SQLITE_INDEX_CONSTRAINT_LIKE:
+ return "LIKE";
+ case SQLITE_INDEX_CONSTRAINT_GLOB:
+ return "GLOB";
+ case SQLITE_INDEX_CONSTRAINT_REGEXP:
+ return "REGEXP";
+#endif
default:
return "unknown";
}
diff --git a/lib/DBD/SQLite/VirtualTable/PerlData.pm b/lib/DBD/SQLite/VirtualTable/PerlData.pm
index 7bbcb0d..8151fe1 100644
--- a/lib/DBD/SQLite/VirtualTable/PerlData.pm
+++ b/lib/DBD/SQLite/VirtualTable/PerlData.pm
@@ -4,7 +4,8 @@ package DBD::SQLite::VirtualTable::PerlData;
use strict;
use warnings;
use base 'DBD::SQLite::VirtualTable';
-
+use DBD::SQLite;
+use constant SQLITE_3010000 => $DBD::SQLite::sqlite_version_number >= 3010000 ? 1 : 0;
# private data for translating comparison operators from Sqlite to Perl
my $TXT = 0;
@@ -17,6 +18,11 @@ my %SQLOP2PERLOP = (
'>' => [ 'gt', '>' ],
'>=' => [ 'ge', '>=' ],
'MATCH' => [ '=~', '=~' ],
+ (SQLITE_3010000 ? (
+ 'LIKE' => [ 'DBD::SQLite::strlike', 'DBD::SQLite::strlike' ],
+ 'GLOB' => [ 'DBD::SQLite::strglob', 'DBD::SQLite::strglob' ],
+ 'REGEXP'=> [ '=~', '=~' ],
+ ) : ()),
);
#----------------------------------------------------------------------
@@ -95,12 +101,16 @@ sub BEST_INDEX {
$optype = $self->{optypes}[$col];
}
my $op = $SQLOP2PERLOP{$constraint->{op}}[$optype];
- push @conditions,
- "(defined($member) && defined(\$vals[$ix]) && $member $op \$vals[$ix])";
- # Note : $vals[$ix] refers to an array of values passed to the
- # FILTER method (see below); so the eval-ed perl code will be a
- # closure on those values
-
+ if (SQLITE_3010000 && $op =~ /str/) {
+ push @conditions,
+ "(defined($member) && defined(\$vals[$ix]) && !$op(\$vals[$ix], $member))";
+ } else {
+ push @conditions,
+ "(defined($member) && defined(\$vals[$ix]) && $member $op \$vals[$ix])";
+ }
+ # Note : $vals[$ix] refers to an array of values passed to the
+ # FILTER method (see below); so the eval-ed perl code will be a
+ # closure on those values
# info passed back to the SQLite core -- see vtab.html in sqlite doc
$constraint->{argvIndex} = $ix++;
$constraint->{omit} = 1;
--
2.5.0