pcre2

package module
v0.0.0-...-eb5c8c4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 17, 2024 License: MIT Imports: 8 Imported by: 0

README

Tests GoDoc

sqlite3-pcre2

sqlite3-pcre2 is a sqlite3 extension that adds the PCRE2 match functions: REGEXP and IREGEXP (case-insensitive). A small LRU cache is used to store frequently used regexes (the size is controlled by the CACHE_SIZE macro).

It also comes with a Go library that will automatically register the extension with github.com/mattn/go-sqlite3.

Installing / Building

The build system here is still a work in progress and installation is manual (the Makefile is a bit of a mess). The make build or make release targets will create a library which can be loaded into sqlite3 and it is suggested to either colocate the library with you application or to place it in a well known location like: "/lib", "/usr/lib", or "/usr/local/lib" (the Go library will search all of these when trying to load the extension).

Examples

$ cat testdata/example.sql | sqlite3
# 1|foo
# 2|bar
# 3|baz
# 1|foo
# 2|bar
# 3|baz

The following example illustrates how to use the REGEXP and IREGEXP functions and the *_INFO functions to query cache stats (you can run this with cat testdata/example.sql | sqlite3:

-- sqlite3 will deduce the library extension based on the current OS
.load sqlite3_pcre2

CREATE TABLE strings (
    id    INTEGER PRIMARY KEY,
    value TEXT
);

INSERT INTO strings VALUES (1, 'foo');
INSERT INTO strings VALUES (2, 'bar');
INSERT INTO strings VALUES (3, 'baz');

SELECT * FROM strings WHERE REGEXP('^(foo|bar|baz)$', value);
-- 1|foo
-- 2|bar
-- 3|baz

SELECT * FROM strings WHERE IREGEXP('^(FOO|BAR|BAZ)$', value);
-- 1|foo
-- 2|bar
-- 3|baz

-- You can also use this syntax for the REGEXP function,
-- but not IREGEXP:
SELECT * FROM strings WHERE value REGEXP 'foo';
-- 1|foo

SELECT REGEXP_INFO('cache_in_use');
-- 2
SELECT IREGEXP_INFO('cache_in_use');
-- 1

Go Library

A Go library pcre2 is included in this repo that will automatically register the sqlite3-pcre2 library with github.com/mattn/go-sqlite3. Below is an example of how to use the library.

package pcre2_test

import (
	"database/sql"
	"fmt"

	// The pcre2 package can also be imported for side-effect ("_") if
	// the library search settings do not need to be changed.
	pcre2 "github.com/charlievieth/sqlite3-pcre2"
)

func Example() {
	// This example requires the sqlite3_pcre2 shared library to exist in
	// the current working directory or in a well known library path such
	// as "/lib", "/usr/lib", or "/usr/local/lib". The shared library can
	// be create by running `make build`.
	//
	// Search the current working directory for the "sqlite3_pcre2" shared library.
	pcre2.SearchWorkingDirectory(true)

	// We need to use the pcre2.DriverName to open the database connection
	// since includes the sqlite3 connection hook.
	db, err := sql.Open(pcre2.DriverName, ":memory:")
	if err != nil {
		panic(err)
	}
	defer db.Close()

	var ok bool
	if err := db.QueryRow(`SELECT REGEXP('^a$', 'a');`).Scan(&ok); err != nil {
		panic(err)
	}
	if !ok {
		panic(fmt.Sprintf("got: %t want: %t", ok, true))
	}
}

Testing

There are two test targets: test which runs the Go tests that are comprehensive; and test_pcre2 which uses a small and hacky C++ test suite. In the future the C++ test suite will be expanded to be more comprehensive since it makes checking for memory leaks simpler.

Documentation

Overview

Package pcre2 registers a sqlite3 PCRE2 extension for use with github.com/mattn/go-sqlite3.

This adds the REGEXP and IREGEXP (case-insensitive) functions to sqlite3. Both functions use PCRE2 for matching, and if available, will JIT compile the PCRE2 code before use.

Example
package main

import (
	"database/sql"
	"fmt"

	pcre2 "github.com/charlievieth/sqlite3-pcre2"
)

func main() {
	// This example requires the sqlite3_pcre2 shared library to exist in
	// the current working directory or in a well known library path such
	// as "/lib", "/usr/lib", or "/usr/local/lib". The shared library can
	// be create by running `make build`.
	//
	// Search the current working directory for the "sqlite3_pcre2" shared library.
	pcre2.SearchWorkingDirectory(true)

	// We need to use the pcre2.DriverName to open the database connection
	// since includes the sqlite3 connection hook.
	db, err := sql.Open(pcre2.DriverName, ":memory:")
	if err != nil {
		panic(err)
	}
	defer db.Close()

	var ok bool
	if err := db.QueryRow(`SELECT REGEXP('^a$', 'a');`).Scan(&ok); err != nil {
		panic(err)
	}
	if !ok {
		panic(fmt.Sprintf("got: %t want: %t", ok, true))
	}
}

Index

Examples

Constants

View Source
const (
	// Name of the sqlite3_pcre2 database driver. To use this library with
	// go-sqlite3 open the database with:
	//
	// 	sql.Open(pcre2.DriverName, "opts...").
	//
	DriverName = "sqlite3_pcre2"

	// Name of the sqlite3_pcre2 library without file extension(s).
	LibraryName = "sqlite3_pcre2"

	// Environment variable key to set a custom path to the sqlite3_pcre2
	// library, which can be the path to the library itself or the directory
	// containing it.
	//
	// The path must be absolute.
	EnvKey = "SQLITE3_PCRE2_LIBRARY"
)

Variables

View Source
var ErrLibraryNotFound = errors.New("pcre2: could not find sqlite3_pcre2 shared library")

ErrLibraryNotFound is returned if the sqlite3_pcre2 library could not be found.

View Source
var LibExts = []string{".so"}

LibExts are the library file extensions searched for (LibraryName + ext).

Functions

func SearchPaths

func SearchPaths() []string

SearchPaths returns the system paths searched for the sqlite3_pcre2 shared library.

The search order is:

  1. The path set by SetLibraryPath(), if any, which can be the path to the shared library or the directory containing it. If set, the seach ends here (that is the below locations will not be checked).

  2. "SQLITE3_PCRE2_LIBRARY" environment variable, which can be the path to the shared library or the directory containing it.

  3. Directory containing the executable that started the current process. If the executable is a symlink the directory containing the symlink is also searched.

  4. System specific directories ("/usr/local/lib").

  5. The current working directory, but only if SearchWorkingDirectory(true) is enabled.

Relative paths are joined with the current working directory. Empty strings are ignored.

func SearchWorkingDirectory

func SearchWorkingDirectory(search bool) (previous bool)

SearchWorkingDirectory toggles if the current working directory is searched for the sqlite3_pcre2 shared library and returns the previous state.

Searching the current working directory is disabled by default because it can be exploited to load malicious code.

func SetLibraryPath

func SetLibraryPath(path string)

SetLibraryPath sets the path to the sqlite3_pcre2 shared library, which can be the path to the shared library or the directory containing it. Relative paths are allowed.

If set, then *only* this path will be searched.

func Sqlite3ConnectHook

func Sqlite3ConnectHook(conn *sqlite3.SQLiteConn) error

Sqlite3ConnectHook is the connection hook for sqlite3.

Usage:

sql.Register("NAME", &sqlite3.SQLiteDriver{
	ConnectHook: Sqlite3ConnectHook,
})

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL