|
|
@@ -1,7 +1,7 @@
|
|
|
Index: Makefile.in
|
|
|
---- Makefile.in.orig 2009-07-06 16:29:57 +0200
|
|
|
-+++ Makefile.in 2009-08-12 20:12:13 +0200
|
|
|
-@@ -187,6 +187,17 @@
|
|
|
+--- Makefile.in.orig 2010-01-05 01:02:40 +0100
|
|
|
++++ Makefile.in 2010-01-30 20:42:09 +0100
|
|
|
+@@ -187,6 +187,23 @@
|
|
|
USE_AMALGAMATION = @USE_AMALGAMATION@
|
|
|
LIBOBJ = $(OBJS$(USE_AMALGAMATION))
|
|
|
|
|
|
@@ -15,16 +15,31 @@ Index: Makefile.in
|
|
|
+ifdef RTREE
|
|
|
+TCC += -DSQLITE_ENABLE_RTREE -I$(TOP)/ext/rtree
|
|
|
+LIBOBJ += rtree.lo
|
|
|
++endif
|
|
|
++
|
|
|
++# REGEXP support
|
|
|
++ifdef REGEXP
|
|
|
++TCC += -DSQLITE_ENABLE_REGEXP
|
|
|
++LIBOBJ += regexp.lo
|
|
|
+endif
|
|
|
|
|
|
# All of the source code files.
|
|
|
#
|
|
|
-@@ -477,6 +488,24 @@
|
|
|
+@@ -329,6 +346,8 @@
|
|
|
+ SRC += \
|
|
|
+ $(TOP)/ext/rtree/rtree.h \
|
|
|
+ $(TOP)/ext/rtree/rtree.c
|
|
|
++SRC += \
|
|
|
++ $(TOP)/ext/regexp/regexp.c
|
|
|
+
|
|
|
+ # Source code to the library files needed by the test fixture
|
|
|
+ #
|
|
|
+@@ -477,6 +496,27 @@
|
|
|
-o $@ $(TOP)/src/shell.c libsqlite3.la \
|
|
|
$(LIBREADLINE) $(TLIBS) -rpath "$(libdir)"
|
|
|
|
|
|
+fts3.lo: $(TOP)/ext/fts3/fts3.c $(HDR)
|
|
|
-+ $(LTCOMPILE) -c $(TOP)/ext/fts3/fts3.c
|
|
|
++ $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3.c
|
|
|
+fts3_hash.lo: $(TOP)/ext/fts3/fts3_hash.c $(HDR)
|
|
|
+ $(LTCOMPILE) -c $(TOP)/ext/fts3/fts3_hash.c
|
|
|
+fts3_expr.lo: $(TOP)/ext/fts3/fts3_expr.c $(HDR)
|
|
|
@@ -39,14 +54,17 @@ Index: Makefile.in
|
|
|
+ $(LTCOMPILE) -c $(TOP)/ext/fts3/fts3_tokenizer1.c
|
|
|
+
|
|
|
+rtree.lo: $(TOP)/ext/rtree/rtree.c $(HDR)
|
|
|
-+ $(LTCOMPILE) -c $(TOP)/ext/rtree/rtree.c
|
|
|
++ $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c
|
|
|
++
|
|
|
++regexp.lo: $(TOP)/ext/regexp/regexp.c $(HDR)
|
|
|
++ $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/regexp/regexp.c
|
|
|
+
|
|
|
# This target creates a directory named "tsrc" and fills it with
|
|
|
# copies of all of the C source code and header files needed to
|
|
|
# build on the target system. Some of the C source code and header
|
|
|
Index: configure
|
|
|
---- configure.orig 2009-08-01 17:04:20 +0200
|
|
|
-+++ configure 2009-08-12 20:12:13 +0200
|
|
|
+--- configure.orig 2010-01-05 01:02:40 +0100
|
|
|
++++ configure 2010-01-30 20:00:15 +0100
|
|
|
@@ -6012,11 +6012,7 @@
|
|
|
if $ac_preproc_ok; then
|
|
|
:
|
|
|
@@ -60,9 +78,160 @@ Index: configure
|
|
|
fi
|
|
|
|
|
|
ac_ext=c
|
|
|
+Index: ext/regexp/regexp.c
|
|
|
+--- ext/regexp/regexp.c.orig 2010-01-30 20:00:15 +0100
|
|
|
++++ ext/regexp/regexp.c 2010-01-30 20:43:01 +0100
|
|
|
+@@ -0,0 +1,147 @@
|
|
|
++/*
|
|
|
++ * SQLite REGEXP(regex, string) function
|
|
|
++ * Copyright (c) 2010 by Ralf S. Engelschall <rse@engelschall.com>
|
|
|
++ *
|
|
|
++ * Based on Public Domain code from 2007 by Alexey Tourbin
|
|
|
++ * <at@altlinux.org> which added plain PCRE based REGEXP function to
|
|
|
++ * SQLite. In order to not require the SQLite _library_ to require the
|
|
|
++ * external PCRE library, the code was adapted to the regex(3) API as
|
|
|
++ * standardized by IEEE Std 1003.2 ("POSIX.2"), sections 2.8 (Regular
|
|
|
++ * Expression Notation) and B.5 (C Binding for Regular Expression
|
|
|
++ * Matching) and which is usually provided already by any modern Unix
|
|
|
++ * system in libc.
|
|
|
++ */
|
|
|
++
|
|
|
++#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_REGEXP)
|
|
|
++
|
|
|
++/* standard includes */
|
|
|
++#include <assert.h>
|
|
|
++#include <stdlib.h>
|
|
|
++#include <string.h>
|
|
|
++#include <regex.h>
|
|
|
++
|
|
|
++/* SQLite includes */
|
|
|
++#ifndef SQLITE_CORE
|
|
|
++#include "sqlite3ext.h"
|
|
|
++SQLITE_EXTENSION_INIT1
|
|
|
++#else
|
|
|
++#include "sqlite3.h"
|
|
|
++#endif
|
|
|
++
|
|
|
++/* regex cache configuration */
|
|
|
++#ifndef CACHE_SIZE
|
|
|
++#define CACHE_SIZE 32
|
|
|
++#endif
|
|
|
++typedef struct {
|
|
|
++ char *str;
|
|
|
++ regex_t re;
|
|
|
++} cache_entry;
|
|
|
++
|
|
|
++/* the SQL REGEXP(regex, string) function C implementation */
|
|
|
++static void regexp(sqlite3_context *ctx, int argc, sqlite3_value **argv)
|
|
|
++{
|
|
|
++ const char *re_str, *str;
|
|
|
++ regex_t *re;
|
|
|
++ int i;
|
|
|
++ int rc;
|
|
|
++ int found;
|
|
|
++ cache_entry *cache;
|
|
|
++ cache_entry c;
|
|
|
++ char err[1024];
|
|
|
++
|
|
|
++ /* sanity check arguments */
|
|
|
++ if (argc != 2) {
|
|
|
++ sqlite3_result_error(ctx, "invalid number of arguments to REGEXP function", -1);
|
|
|
++ return;
|
|
|
++ }
|
|
|
++ if ((re_str = (const char *)sqlite3_value_text(argv[0])) == NULL) {
|
|
|
++ sqlite3_result_error(ctx, "no regexp argument given to REGEXP function", -1);
|
|
|
++ return;
|
|
|
++ }
|
|
|
++ if ((str = (const char *)sqlite3_value_text(argv[1])) == NULL) {
|
|
|
++ sqlite3_result_error(ctx, "no string argument given to REGEXP function", -1);
|
|
|
++ return;
|
|
|
++ }
|
|
|
++
|
|
|
++ /* simple regex LRU caching */
|
|
|
++ if ((cache = sqlite3_user_data(ctx)) == NULL) {
|
|
|
++ sqlite3_result_error(ctx, "no regex cache available", -1);
|
|
|
++ return;
|
|
|
++ }
|
|
|
++ found = 0;
|
|
|
++ for (i = 0; i < CACHE_SIZE && cache[i].str != NULL; i++) {
|
|
|
++ if (strcmp(re_str, cache[i].str) == 0) {
|
|
|
++ found = 1;
|
|
|
++ break;
|
|
|
++ }
|
|
|
++ }
|
|
|
++ if (found) {
|
|
|
++ if (i > 0) {
|
|
|
++ /* move cache[i] element to front for faster searching next time */
|
|
|
++ c = cache[i];
|
|
|
++ memmove(cache + 1, cache, i * sizeof(cache_entry));
|
|
|
++ cache[0] = c;
|
|
|
++ }
|
|
|
++ }
|
|
|
++ else {
|
|
|
++ /* compile and store regular expression */
|
|
|
++ int rc = regcomp(&(c.re), re_str, REG_EXTENDED|REG_NOSUB);
|
|
|
++ if (rc != 0) {
|
|
|
++ regerror(rc, &(c.re), err, sizeof(err));
|
|
|
++ char *e2 = sqlite3_mprintf("regex \"%s\" failed to compile: %s", re_str, err);
|
|
|
++ sqlite3_result_error(ctx, e2, -1);
|
|
|
++ sqlite3_free(e2);
|
|
|
++ return;
|
|
|
++ }
|
|
|
++ if ((c.str = strdup(re_str)) == NULL) {
|
|
|
++ sqlite3_result_error(ctx, "strdup: ENOMEM", -1);
|
|
|
++ regfree(&(c.re));
|
|
|
++ return;
|
|
|
++ }
|
|
|
++
|
|
|
++ /* insert regex into cache (at first position) */
|
|
|
++ i = CACHE_SIZE - 1;
|
|
|
++ if (cache[i].str != NULL) {
|
|
|
++ /* expire oldest cache entry */
|
|
|
++ free(cache[i].str);
|
|
|
++ regfree(&(cache[i].re));
|
|
|
++ }
|
|
|
++ memmove(cache + 1, cache, i * sizeof(cache_entry));
|
|
|
++ cache[0] = c;
|
|
|
++ }
|
|
|
++
|
|
|
++ /* take compiled regular expression (either found old one or created new one) */
|
|
|
++ re = &(cache[0].re);
|
|
|
++
|
|
|
++ /* apply regular expression onto given string and report matching result */
|
|
|
++ rc = regexec(re, str, 0, NULL, 0);
|
|
|
++ sqlite3_result_int(ctx, rc == 0);
|
|
|
++
|
|
|
++ return;
|
|
|
++}
|
|
|
++
|
|
|
++/* SQLITE_CORE (built-in) entry point */
|
|
|
++int sqlite3RegexpInit(sqlite3 *);
|
|
|
++int sqlite3RegexpInit(sqlite3 *db)
|
|
|
++{
|
|
|
++ cache_entry *cache = NULL;
|
|
|
++ int rc = SQLITE_OK;
|
|
|
++
|
|
|
++ if ((cache = calloc(CACHE_SIZE, sizeof(cache_entry))) == NULL)
|
|
|
++ return SQLITE_NOMEM;
|
|
|
++ rc = sqlite3_create_function(db, "REGEXP", 2, SQLITE_UTF8, cache, regexp, NULL, NULL);
|
|
|
++ return rc;
|
|
|
++}
|
|
|
++
|
|
|
++#ifndef SQLITE_CORE
|
|
|
++/* DSO entry point */
|
|
|
++int sqlite3_extension_init(sqlite3 *, char **, const sqlite3_api_routines *);
|
|
|
++int sqlite3_extension_init(sqlite3 *db, char **err, const sqlite3_api_routines *api)
|
|
|
++{
|
|
|
++ SQLITE_EXTENSION_INIT2(api)
|
|
|
++ return sqlite3RegexpInit(db);
|
|
|
++}
|
|
|
++#endif
|
|
|
++
|
|
|
++#endif
|
|
|
++
|
|
|
Index: sqlite3.pc.in
|
|
|
---- sqlite3.pc.in.orig 2009-05-05 05:39:51 +0200
|
|
|
-+++ sqlite3.pc.in 2009-08-12 20:12:13 +0200
|
|
|
+--- sqlite3.pc.in.orig 2009-09-03 22:32:06 +0200
|
|
|
++++ sqlite3.pc.in 2010-01-30 20:00:15 +0100
|
|
|
@@ -8,6 +8,5 @@
|
|
|
Name: SQLite
|
|
|
Description: SQL database engine
|
|
|
@@ -71,3 +240,20 @@ Index: sqlite3.pc.in
|
|
|
-Libs.private: @LIBS@
|
|
|
+Libs: -L${libdir} -lsqlite3 @LIBS@
|
|
|
Cflags: -I${includedir}
|
|
|
+Index: src/main.c
|
|
|
+--- src/main.c.orig 2010-01-05 01:02:40 +0100
|
|
|
++++ src/main.c 2010-01-30 20:43:26 +0100
|
|
|
+@@ -1715,6 +1715,13 @@
|
|
|
+ }
|
|
|
+ #endif
|
|
|
+
|
|
|
++#ifdef SQLITE_ENABLE_REGEXP
|
|
|
++ if( !db->mallocFailed && rc==SQLITE_OK){
|
|
|
++ extern int sqlite3RegexpInit(sqlite3*);
|
|
|
++ rc = sqlite3RegexpInit(db);
|
|
|
++ }
|
|
|
++#endif
|
|
|
++
|
|
|
+ sqlite3Error(db, rc, 0);
|
|
|
+
|
|
|
+ /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking
|