Skip to content
Permalink
Browse files

Add a REGEXP function in spatialite_connect() python function

This enables DB Manager and the Spatialite Execute SQL algorithm
to use the 'string REGEXP pattern' syntax.
  • Loading branch information
nirvn committed May 5, 2019
1 parent 47faac5 commit eacc506a5a701a3ab6be1370937ee929be0f5004
Showing with 13 additions and 12 deletions.
  1. +7 −0 python/utils.py
  2. +6 −12 src/providers/spatialite/qgsspatialiteconnection.cpp
@@ -646,6 +646,12 @@ def spatialite_connect(*args, **kwargs):
"""returns a dbapi2.Connection to a SpatiaLite db
using the "mod_spatialite" extension (python3)"""
import sqlite3
import re

def fcnRegexp(pattern, string):
result = re.search(pattern, string)
return True if result else False

con = sqlite3.dbapi2.connect(*args, **kwargs)
con.enable_load_extension(True)
cur = con.cursor()
@@ -670,6 +676,7 @@ def spatialite_connect(*args, **kwargs):
raise RuntimeError("Cannot find any suitable spatialite module")
cur.close()
con.enable_load_extension(False)
con.create_function("regexp", 2, fcnRegexp)
return con


@@ -19,6 +19,7 @@
#include "qgssqliteutils.h"

#include <QFileInfo>
#include <QRegularExpression>
#include <cstdlib> // atoi

#ifdef _MSC_VER
@@ -642,20 +643,13 @@ bool QgsSpatiaLiteConnection::isDeclaredHidden( sqlite3 *handle, const QString &

static void fcnRegexp( sqlite3_context *ctx, int /*argc*/, sqlite3_value *argv[] )
{
// Get arguments and check their values
QRegExp arg1( reinterpret_cast<const char *>( sqlite3_value_text( argv[0] ) ) );
QString arg2( reinterpret_cast<const char *>( sqlite3_value_text( argv[1] ) ) );
if ( !arg1.isValid() )
QRegularExpression re( reinterpret_cast<const char *>( sqlite3_value_text( argv[0] ) ) );
QString string( reinterpret_cast<const char *>( sqlite3_value_text( argv[1] ) ) );

if ( !re.isValid() )
return sqlite3_result_error( ctx, "invalid operand", -1 );

// Set the pattern matching syntax to a Perl-like one. This is the default in Qt 4.x but Qt 5
// changes this to a greedy one (QRegExp::RegExp2). To make sure the behaviour of our application
// doesn't change depending on the build environment, we make sure to always set the same pattern
// matching syntax.
arg1.setPatternSyntax( QRegExp::RegExp );
// Perform the actual matching and return the result. Note that Qt's QRegExp returns -1 if the regex
// doesn't match and the position in the string otherwise; SQLite expects a 0 for not found and a 1 for found.
sqlite3_result_int( ctx, arg1.indexIn( arg2 ) >= 0 );
sqlite3_result_int( ctx, string.contains( re ) );
}


0 comments on commit eacc506

Please sign in to comment.
You can’t perform that action at this time.