From my own Functions:
...
Not really tested to the last possible use-case, nevermind it was more or less just a proof-of-concept which worked
Nice!
Btw, mORMot links SQLite statically, and regexp.c is incorporated. Thus, when using mORMot, the SQLite regexp() function is available. Here's a complete mORMot program doing regex seach on the Sakila database. Obtaining a copy of the database in SQLite format is left as an exercise for the reader. :-)
program mormotregex;
{$mode delphi}{$H+}
{$define FPC_X64MM}
{$define FPCMM_SERVER}
{$define FPCMM_REPORTMEMORYLEAKS}
{$define FPCMM_DEBUG}
{$I mormot.defines.inc}
uses
cthreads, sysutils,
mormot.db.raw.sqlite3, mormot.db.raw.sqlite3.static,
mormot.db.sql, mormot.db.sql.sqlite3;
procedure sqlite_ormless_regexp;
var
connprop: TSqlDBSQLite3ConnectionProperties;
dbconn: TSqlDBSQLite3Connection;
sql: String;
stmt: TSqlDBStatement;
begin
connprop := TSqlDBSQLite3ConnectionProperties.Create('sakila.db', '', '', '');
dbconn := TSqlDBSQLite3Connection.Create(connprop);
try
dbconn.Connect;
sql := 'SELECT first_name, last_name, count(*) films FROM actor ' +
'JOIN film_actor ' +
'ON film_actor.actor_id = actor.actor_id ' +
'AND actor.first_name REGEXP ''ILL'' ' +
'GROUP BY actor.actor_id, first_name, last_name ' +
'ORDER BY films DESC ';
stmt := dbconn.NewStatement;
try
stmt.Prepare(sql, true);
stmt.ExecutePrepared;
while stmt.Step do
writeln(Format('%s %s made %d films', [stmt.ColumnUtf8(0), stmt.ColumnUtf8(1), stmt.ColumnInt(2)]));
finally
stmt.ReleaseRows;
stmt.Free;
end;
dbconn.Disconnect;
finally
dbconn.Free;
connprop.Free;
end;
end;
begin
sqlite_ormless_regexp;
end.
When run, the program produces:
WILL WILSON made 31 films
LUCILLE TRACY made 30 films
MILLA KEITEL made 28 films
WILLIAM HACKMAN made 27 films
MILLA PECK made 24 films
LUCILLE DEE made 24 films
The REGEXP operator in SQLite is case-sensitive, so searching for 'ill' in the above would yield no row. However, it is also possible to use function call syntax, and SQLite provides both regexp() and regexpi(), the latter for case-insensitive matching.
When using regexpi(), the query becomes:
SELECT first_name, last_name, COUNT(*) films FROM actor
JOIN film_actor
ON film_actor.actor_id = actor.actor_id
AND regexpi('ill', actor.first_name) = 1
GROUP BY actor.actor_id, first_name, last_name
ORDER BY films DESC
The regexpi() function is available in the SQLite CLI, but unfortunately not in current mORMot, because mORMot is using an older version of regexp.c.