update dependencies

This commit is contained in:
nkanaev 2025-03-24 02:32:57 +00:00
parent 58bb2c22c3
commit 9fb3da2b4a
52 changed files with 44532 additions and 19524 deletions

12
go.mod
View File

@ -1,11 +1,13 @@
module github.com/nkanaev/yarr module github.com/nkanaev/yarr
go 1.18 go 1.23.0
toolchain go1.23.5
require ( require (
github.com/mattn/go-sqlite3 v1.14.7 github.com/mattn/go-sqlite3 v1.14.24
golang.org/x/net v0.36.0 golang.org/x/net v0.37.0
golang.org/x/sys v0.30.0 golang.org/x/sys v0.31.0
) )
require golang.org/x/text v0.22.0 // indirect require golang.org/x/text v0.23.0 // indirect

10
go.sum
View File

@ -1,8 +1,14 @@
github.com/mattn/go-sqlite3 v1.14.7 h1:fxWBnXkxfM6sRiuH3bqJ4CfzZojMOLVc0UTsTglEghA= github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA=
golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I=
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=

View File

@ -1,23 +1,23 @@
go-sqlite3 go-sqlite3
========== ==========
[![GoDoc Reference](https://godoc.org/github.com/mattn/go-sqlite3?status.svg)](http://godoc.org/github.com/mattn/go-sqlite3) [![Go Reference](https://pkg.go.dev/badge/github.com/mattn/go-sqlite3.svg)](https://pkg.go.dev/github.com/mattn/go-sqlite3)
[![GitHub Actions](https://github.com/mattn/go-sqlite3/workflows/Go/badge.svg)](https://github.com/mattn/go-sqlite3/actions?query=workflow%3AGo) [![GitHub Actions](https://github.com/mattn/go-sqlite3/workflows/Go/badge.svg)](https://github.com/mattn/go-sqlite3/actions?query=workflow%3AGo)
[![Financial Contributors on Open Collective](https://opencollective.com/mattn-go-sqlite3/all/badge.svg?label=financial+contributors)](https://opencollective.com/mattn-go-sqlite3) [![Financial Contributors on Open Collective](https://opencollective.com/mattn-go-sqlite3/all/badge.svg?label=financial+contributors)](https://opencollective.com/mattn-go-sqlite3)
[![codecov](https://codecov.io/gh/mattn/go-sqlite3/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-sqlite3) [![codecov](https://codecov.io/gh/mattn/go-sqlite3/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-sqlite3)
[![Go Report Card](https://goreportcard.com/badge/github.com/mattn/go-sqlite3)](https://goreportcard.com/report/github.com/mattn/go-sqlite3) [![Go Report Card](https://goreportcard.com/badge/github.com/mattn/go-sqlite3)](https://goreportcard.com/report/github.com/mattn/go-sqlite3)
Latest stable version is v1.14 or later not v2. Latest stable version is v1.14 or later, not v2.
~~**NOTE:** The increase to v2 was an accident. There were no major changes or features.~~ ~~**NOTE:** The increase to v2 was an accident. There were no major changes or features.~~
# Description # Description
sqlite3 driver conforming to the built-in database/sql interface A sqlite3 driver that conforms to the built-in database/sql interface.
Supported Golang version: See [.github/workflows/go.yaml](./.github/workflows/go.yaml) Supported Golang version: See [.github/workflows/go.yaml](./.github/workflows/go.yaml).
[This package follows the official Golang Release Policy.](https://golang.org/doc/devel/release.html#policy) This package follows the official [Golang Release Policy](https://golang.org/doc/devel/release.html#policy).
### Overview ### Overview
@ -40,7 +40,7 @@ Supported Golang version: See [.github/workflows/go.yaml](./.github/workflows/go
- [Alpine](#alpine) - [Alpine](#alpine)
- [Fedora](#fedora) - [Fedora](#fedora)
- [Ubuntu](#ubuntu) - [Ubuntu](#ubuntu)
- [Mac OSX](#mac-osx) - [macOS](#mac-osx)
- [Windows](#windows) - [Windows](#windows)
- [Errors](#errors) - [Errors](#errors)
- [User Authentication](#user-authentication) - [User Authentication](#user-authentication)
@ -64,7 +64,7 @@ Supported Golang version: See [.github/workflows/go.yaml](./.github/workflows/go
# Installation # Installation
This package can be installed with the go get command: This package can be installed with the `go get` command:
go get github.com/mattn/go-sqlite3 go get github.com/mattn/go-sqlite3
@ -72,28 +72,28 @@ _go-sqlite3_ is *cgo* package.
If you want to build your app using go-sqlite3, you need gcc. If you want to build your app using go-sqlite3, you need gcc.
However, after you have built and installed _go-sqlite3_ with `go install github.com/mattn/go-sqlite3` (which requires gcc), you can build your app without relying on gcc in future. However, after you have built and installed _go-sqlite3_ with `go install github.com/mattn/go-sqlite3` (which requires gcc), you can build your app without relying on gcc in future.
***Important: because this is a `CGO` enabled package you are required to set the environment variable `CGO_ENABLED=1` and have a `gcc` compile present within your path.*** ***Important: because this is a `CGO` enabled package, you are required to set the environment variable `CGO_ENABLED=1` and have a `gcc` compiler present within your path.***
# API Reference # API Reference
API documentation can be found here: http://godoc.org/github.com/mattn/go-sqlite3 API documentation can be found [here](http://godoc.org/github.com/mattn/go-sqlite3).
Examples can be found under the [examples](./_example) directory Examples can be found under the [examples](./_example) directory.
# Connection String # Connection String
When creating a new SQLite database or connection to an existing one, with the file name additional options can be given. When creating a new SQLite database or connection to an existing one, with the file name additional options can be given.
This is also known as a DSN string. (Data Source Name). This is also known as a DSN (Data Source Name) string.
Options are append after the filename of the SQLite database. Options are append after the filename of the SQLite database.
The database filename and options are seperated by an `?` (Question Mark). The database filename and options are separated by an `?` (Question Mark).
Options should be URL-encoded (see [url.QueryEscape](https://golang.org/pkg/net/url/#QueryEscape)). Options should be URL-encoded (see [url.QueryEscape](https://golang.org/pkg/net/url/#QueryEscape)).
This also applies when using an in-memory database instead of a file. This also applies when using an in-memory database instead of a file.
Options can be given using the following format: `KEYWORD=VALUE` and multiple options can be combined with the `&` ampersand. Options can be given using the following format: `KEYWORD=VALUE` and multiple options can be combined with the `&` ampersand.
This library supports dsn options of SQLite itself and provides additional options. This library supports DSN options of SQLite itself and provides additional options.
Boolean values can be one of: Boolean values can be one of:
* `0` `no` `false` `off` * `0` `no` `false` `off`
@ -138,24 +138,23 @@ file:test.db?cache=shared&mode=memory
This package allows additional configuration of features available within SQLite3 to be enabled or disabled by golang build constraints also known as build `tags`. This package allows additional configuration of features available within SQLite3 to be enabled or disabled by golang build constraints also known as build `tags`.
[Click here for more information about build tags / constraints.](https://golang.org/pkg/go/build/#hdr-Build_Constraints) Click [here](https://golang.org/pkg/go/build/#hdr-Build_Constraints) for more information about build tags / constraints.
### Usage ### Usage
If you wish to build this library with additional extensions / features. If you wish to build this library with additional extensions / features, use the following command:
Use the following command.
```bash ```bash
go build --tags "<FEATURE>" go build -tags "<FEATURE>"
``` ```
For available features see the extension list. For available features, see the extension list.
When using multiple build tags, all the different tags should be space delimted. When using multiple build tags, all the different tags should be space delimited.
Example: Example:
```bash ```bash
go build --tags "icu json1 fts5 secure_delete" go build -tags "icu json1 fts5 secure_delete"
``` ```
### Feature / Extension List ### Feature / Extension List
@ -166,6 +165,7 @@ go build --tags "icu json1 fts5 secure_delete"
| Allow URI Authority | sqlite_allow_uri_authority | URI filenames normally throws an error if the authority section is not either empty or "localhost".<br><br>However, if SQLite is compiled with the SQLITE_ALLOW_URI_AUTHORITY compile-time option, then the URI is converted into a Uniform Naming Convention (UNC) filename and passed down to the underlying operating system that way | | Allow URI Authority | sqlite_allow_uri_authority | URI filenames normally throws an error if the authority section is not either empty or "localhost".<br><br>However, if SQLite is compiled with the SQLITE_ALLOW_URI_AUTHORITY compile-time option, then the URI is converted into a Uniform Naming Convention (UNC) filename and passed down to the underlying operating system that way |
| App Armor | sqlite_app_armor | When defined, this C-preprocessor macro activates extra code that attempts to detect misuse of the SQLite API, such as passing in NULL pointers to required parameters or using objects after they have been destroyed. <br><br>App Armor is not available under `Windows`. | | App Armor | sqlite_app_armor | When defined, this C-preprocessor macro activates extra code that attempts to detect misuse of the SQLite API, such as passing in NULL pointers to required parameters or using objects after they have been destroyed. <br><br>App Armor is not available under `Windows`. |
| Disable Load Extensions | sqlite_omit_load_extension | Loading of external extensions is enabled by default.<br><br>To disable extension loading add the build tag `sqlite_omit_load_extension`. | | Disable Load Extensions | sqlite_omit_load_extension | Loading of external extensions is enabled by default.<br><br>To disable extension loading add the build tag `sqlite_omit_load_extension`. |
| Enable Serialization with `libsqlite3` | sqlite_serialize | Serialization and deserialization of a SQLite database is available by default, unless the build tag `libsqlite3` is set.<br><br>To enable this functionality even if `libsqlite3` is set, add the build tag `sqlite_serialize`. |
| Foreign Keys | sqlite_foreign_keys | This macro determines whether enforcement of foreign key constraints is enabled or disabled by default for new database connections.<br><br>Each database connection can always turn enforcement of foreign key constraints on and off and run-time using the foreign_keys pragma.<br><br>Enforcement of foreign key constraints is normally off by default, but if this compile-time parameter is set to 1, enforcement of foreign key constraints will be on by default | | Foreign Keys | sqlite_foreign_keys | This macro determines whether enforcement of foreign key constraints is enabled or disabled by default for new database connections.<br><br>Each database connection can always turn enforcement of foreign key constraints on and off and run-time using the foreign_keys pragma.<br><br>Enforcement of foreign key constraints is normally off by default, but if this compile-time parameter is set to 1, enforcement of foreign key constraints will be on by default |
| Full Auto Vacuum | sqlite_vacuum_full | Set the default auto vacuum to full | | Full Auto Vacuum | sqlite_vacuum_full | Set the default auto vacuum to full |
| Incremental Auto Vacuum | sqlite_vacuum_incr | Set the default auto vacuum to incremental | | Incremental Auto Vacuum | sqlite_vacuum_incr | Set the default auto vacuum to incremental |
@ -173,17 +173,20 @@ go build --tags "icu json1 fts5 secure_delete"
| International Components for Unicode | sqlite_icu | This option causes the International Components for Unicode or "ICU" extension to SQLite to be added to the build | | International Components for Unicode | sqlite_icu | This option causes the International Components for Unicode or "ICU" extension to SQLite to be added to the build |
| Introspect PRAGMAS | sqlite_introspect | This option adds some extra PRAGMA statements. <ul><li>PRAGMA function_list</li><li>PRAGMA module_list</li><li>PRAGMA pragma_list</li></ul> | | Introspect PRAGMAS | sqlite_introspect | This option adds some extra PRAGMA statements. <ul><li>PRAGMA function_list</li><li>PRAGMA module_list</li><li>PRAGMA pragma_list</li></ul> |
| JSON SQL Functions | sqlite_json | When this option is defined in the amalgamation, the JSON SQL functions are added to the build automatically | | JSON SQL Functions | sqlite_json | When this option is defined in the amalgamation, the JSON SQL functions are added to the build automatically |
| Math Functions | sqlite_math_functions | This compile-time option enables built-in scalar math functions. For more information see [Built-In Mathematical SQL Functions](https://www.sqlite.org/lang_mathfunc.html) |
| OS Trace | sqlite_os_trace | This option enables OSTRACE() debug logging. This can be verbose and should not be used in production. |
| Pre Update Hook | sqlite_preupdate_hook | Registers a callback function that is invoked prior to each INSERT, UPDATE, and DELETE operation on a database table. | | Pre Update Hook | sqlite_preupdate_hook | Registers a callback function that is invoked prior to each INSERT, UPDATE, and DELETE operation on a database table. |
| Secure Delete | sqlite_secure_delete | This compile-time option changes the default setting of the secure_delete pragma.<br><br>When this option is not used, secure_delete defaults to off. When this option is present, secure_delete defaults to on.<br><br>The secure_delete setting causes deleted content to be overwritten with zeros. There is a small performance penalty since additional I/O must occur.<br><br>On the other hand, secure_delete can prevent fragments of sensitive information from lingering in unused parts of the database file after it has been deleted. See the documentation on the secure_delete pragma for additional information | | Secure Delete | sqlite_secure_delete | This compile-time option changes the default setting of the secure_delete pragma.<br><br>When this option is not used, secure_delete defaults to off. When this option is present, secure_delete defaults to on.<br><br>The secure_delete setting causes deleted content to be overwritten with zeros. There is a small performance penalty since additional I/O must occur.<br><br>On the other hand, secure_delete can prevent fragments of sensitive information from lingering in unused parts of the database file after it has been deleted. See the documentation on the secure_delete pragma for additional information |
| Secure Delete (FAST) | sqlite_secure_delete_fast | For more information see [PRAGMA secure_delete](https://www.sqlite.org/pragma.html#pragma_secure_delete) | | Secure Delete (FAST) | sqlite_secure_delete_fast | For more information see [PRAGMA secure_delete](https://www.sqlite.org/pragma.html#pragma_secure_delete) |
| Tracing / Debug | sqlite_trace | Activate trace functions | | Tracing / Debug | sqlite_trace | Activate trace functions |
| User Authentication | sqlite_userauth | SQLite User Authentication see [User Authentication](#user-authentication) for more information. | | User Authentication | sqlite_userauth | SQLite User Authentication see [User Authentication](#user-authentication) for more information. |
| Virtual Tables | sqlite_vtable | SQLite Virtual Tables see [SQLite Official VTABLE Documentation](https://www.sqlite.org/vtab.html) for more information, and a [full example here](https://github.com/mattn/go-sqlite3/tree/master/_example/vtable) |
# Compilation # Compilation
This package requires `CGO_ENABLED=1` ennvironment variable if not set by default, and the presence of the `gcc` compiler. This package requires the `CGO_ENABLED=1` environment variable if not set by default, and the presence of the `gcc` compiler.
If you need to add additional CFLAGS or LDFLAGS to the build command, and do not want to modify this package. Then this can be achieved by using the `CGO_CFLAGS` and `CGO_LDFLAGS` environment variables. If you need to add additional CFLAGS or LDFLAGS to the build command, and do not want to modify this package, then this can be achieved by using the `CGO_CFLAGS` and `CGO_LDFLAGS` environment variables.
## Android ## Android
@ -191,14 +194,14 @@ This package can be compiled for android.
Compile with: Compile with:
```bash ```bash
go build --tags "android" go build -tags "android"
``` ```
For more information see [#201](https://github.com/mattn/go-sqlite3/issues/201) For more information see [#201](https://github.com/mattn/go-sqlite3/issues/201)
# ARM # ARM
To compile for `ARM` use the following environment. To compile for `ARM` use the following environment:
```bash ```bash
env CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++ \ env CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++ \
@ -216,15 +219,14 @@ This library can be cross-compiled.
In some cases you are required to the `CC` environment variable with the cross compiler. In some cases you are required to the `CC` environment variable with the cross compiler.
## Cross Compiling from MAC OSX ## Cross Compiling from macOS
The simplest way to cross compile from OSX is to use [xgo](https://github.com/karalabe/xgo). The simplest way to cross compile from macOS is to use [xgo](https://github.com/karalabe/xgo).
Steps: Steps:
- Install [xgo](https://github.com/karalabe/xgo) (`go get github.com/karalabe/xgo`). - Install [musl-cross](https://github.com/FiloSottile/homebrew-musl-cross) (`brew install FiloSottile/musl-cross/musl-cross`).
- Ensure that your project is within your `GOPATH`. - Run `CC=x86_64-linux-musl-gcc CXX=x86_64-linux-musl-g++ GOARCH=amd64 GOOS=linux CGO_ENABLED=1 go build -ldflags "-linkmode external -extldflags -static"`.
- Run `xgo local/path/to/project`.
Please refer to the project's [README](https://github.com/karalabe/xgo/blob/master/README.md) for further information. Please refer to the project's [README](https://github.com/FiloSottile/homebrew-musl-cross#readme) for further information.
# Google Cloud Platform # Google Cloud Platform
@ -234,23 +236,23 @@ Please work only with compiled final binaries.
## Linux ## Linux
To compile this package on Linux you must install the development tools for your linux distribution. To compile this package on Linux, you must install the development tools for your linux distribution.
To compile under linux use the build tag `linux`. To compile under linux use the build tag `linux`.
```bash ```bash
go build --tags "linux" go build -tags "linux"
``` ```
If you wish to link directly to libsqlite3 then you can use the `libsqlite3` build tag. If you wish to link directly to libsqlite3 then you can use the `libsqlite3` build tag.
``` ```
go build --tags "libsqlite3 linux" go build -tags "libsqlite3 linux"
``` ```
### Alpine ### Alpine
When building in an `alpine` container run the following command before building. When building in an `alpine` container run the following command before building:
``` ```
apk add --update gcc musl-dev apk add --update gcc musl-dev
@ -268,34 +270,43 @@ sudo yum groupinstall "Development Tools" "Development Libraries"
sudo apt-get install build-essential sudo apt-get install build-essential
``` ```
## Mac OSX ## macOS
OSX should have all the tools present to compile this package, if not install XCode this will add all the developers tools. macOS should have all the tools present to compile this package. If not, install XCode to add all the developers tools.
Required dependency Required dependency:
```bash ```bash
brew install sqlite3 brew install sqlite3
``` ```
For OSX there is an additional package install which is required if you wish to build the `icu` extension. For macOS, there is an additional package to install which is required if you wish to build the `icu` extension.
This additional package can be installed with `homebrew`. This additional package can be installed with `homebrew`:
```bash ```bash
brew upgrade icu4c brew upgrade icu4c
``` ```
To compile for Mac OSX. To compile for macOS on x86:
```bash ```bash
go build --tags "darwin" go build -tags "darwin amd64"
``` ```
If you wish to link directly to libsqlite3 then you can use the `libsqlite3` build tag. To compile for macOS on ARM chips:
```bash
go build -tags "darwin arm64"
```
If you wish to link directly to libsqlite3, use the `libsqlite3` build tag:
``` ```
go build --tags "libsqlite3 darwin" # x86
go build -tags "libsqlite3 darwin amd64"
# ARM
go build -tags "libsqlite3 darwin arm64"
``` ```
Additional information: Additional information:
@ -304,14 +315,14 @@ Additional information:
## Windows ## Windows
To compile this package on Windows OS you must have the `gcc` compiler installed. To compile this package on Windows, you must have the `gcc` compiler installed.
1) Install a Windows `gcc` toolchain. 1) Install a Windows `gcc` toolchain.
2) Add the `bin` folders to the Windows path if the installer did not do this by default. 2) Add the `bin` folder to the Windows path, if the installer did not do this by default.
3) Open a terminal for the TDM-GCC toolchain, can be found in the Windows Start menu. 3) Open a terminal for the TDM-GCC toolchain, which can be found in the Windows Start menu.
4) Navigate to your project folder and run the `go build ...` command for this package. 4) Navigate to your project folder and run the `go build ...` command for this package.
For example the TDM-GCC Toolchain can be found [here](https://sourceforge.net/projects/tdm-gcc/). For example the TDM-GCC Toolchain can be found [here](https://jmeubank.github.io/tdm-gcc/).
## Errors ## Errors
@ -349,28 +360,28 @@ This package supports the SQLite User Authentication module.
## Compile ## Compile
To use the User authentication module the package has to be compiled with the tag `sqlite_userauth`. See [Features](#features). To use the User authentication module, the package has to be compiled with the tag `sqlite_userauth`. See [Features](#features).
## Usage ## Usage
### Create protected database ### Create protected database
To create a database protected by user authentication provide the following argument to the connection string `_auth`. To create a database protected by user authentication, provide the following argument to the connection string `_auth`.
This will enable user authentication within the database. This option however requires two additional arguments: This will enable user authentication within the database. This option however requires two additional arguments:
- `_auth_user` - `_auth_user`
- `_auth_pass` - `_auth_pass`
When `_auth` is present on the connection string user authentication will be enabled and the provided user will be created When `_auth` is present in the connection string user authentication will be enabled and the provided user will be created
as an `admin` user. After initial creation, the parameter `_auth` has no effect anymore and can be omitted from the connection string. as an `admin` user. After initial creation, the parameter `_auth` has no effect anymore and can be omitted from the connection string.
Example connection string: Example connection strings:
Create an user authentication database with user `admin` and password `admin`. Create an user authentication database with user `admin` and password `admin`:
`file:test.s3db?_auth&_auth_user=admin&_auth_pass=admin` `file:test.s3db?_auth&_auth_user=admin&_auth_pass=admin`
Create an user authentication database with user `admin` and password `admin` and use `SHA1` for the password encoding. Create an user authentication database with user `admin` and password `admin` and use `SHA1` for the password encoding:
`file:test.s3db?_auth&_auth_user=admin&_auth_pass=admin&_auth_crypt=sha1` `file:test.s3db?_auth&_auth_user=admin&_auth_pass=admin&_auth_crypt=sha1`
@ -396,11 +407,11 @@ salt this can be configured with `_auth_salt`.
### Restrictions ### Restrictions
Operations on the database regarding to user management can only be preformed by an administrator user. Operations on the database regarding user management can only be preformed by an administrator user.
### Support ### Support
The user authentication supports two kinds of users The user authentication supports two kinds of users:
- administrators - administrators
- regular users - regular users
@ -411,7 +422,7 @@ User management can be done by directly using the `*SQLiteConn` or by SQL.
#### SQL #### SQL
The following sql functions are available for user management. The following sql functions are available for user management:
| Function | Arguments | Description | | Function | Arguments | Description |
|----------|-----------|-------------| |----------|-----------|-------------|
@ -420,7 +431,7 @@ The following sql functions are available for user management.
| `auth_user_change` | username `string`, password `string`, admin `int` | Function to modify an user. Users can change their own password, but only an administrator can change the administrator flag. | | `auth_user_change` | username `string`, password `string`, admin `int` | Function to modify an user. Users can change their own password, but only an administrator can change the administrator flag. |
| `authUserDelete` | username `string` | Delete an user from the database. Can only be used by an administrator. The current logged in administrator cannot be deleted. This is to make sure their is always an administrator remaining. | | `authUserDelete` | username `string` | Delete an user from the database. Can only be used by an administrator. The current logged in administrator cannot be deleted. This is to make sure their is always an administrator remaining. |
These functions will return an integer. These functions will return an integer:
- 0 (SQLITE_OK) - 0 (SQLITE_OK)
- 23 (SQLITE_AUTH) Failed to perform due to authentication or insufficient privileges - 23 (SQLITE_AUTH) Failed to perform due to authentication or insufficient privileges
@ -441,7 +452,7 @@ SELECT user_delete('user');
#### *SQLiteConn #### *SQLiteConn
The following functions are available for User authentication from the `*SQLiteConn`. The following functions are available for User authentication from the `*SQLiteConn`:
| Function | Description | | Function | Description |
|----------|-------------| |----------|-------------|
@ -452,16 +463,16 @@ The following functions are available for User authentication from the `*SQLiteC
### Attached database ### Attached database
When using attached databases. SQLite will use the authentication from the `main` database for the attached database(s). When using attached databases, SQLite will use the authentication from the `main` database for the attached database(s).
# Extensions # Extensions
If you want your own extension to be listed here or you want to add a reference to an extension; please submit an Issue for this. If you want your own extension to be listed here, or you want to add a reference to an extension; please submit an Issue for this.
## Spatialite ## Spatialite
Spatialite is available as an extension to SQLite, and can be used in combination with this repository. Spatialite is available as an extension to SQLite, and can be used in combination with this repository.
For an example see [shaxbee/go-spatialite](https://github.com/shaxbee/go-spatialite). For an example, see [shaxbee/go-spatialite](https://github.com/shaxbee/go-spatialite).
## extension-functions.c from SQLite3 Contrib ## extension-functions.c from SQLite3 Contrib
@ -471,7 +482,7 @@ extension-functions.c is available as an extension to SQLite, and provides the f
- String: replicate, charindex, leftstr, rightstr, ltrim, rtrim, trim, replace, reverse, proper, padl, padr, padc, strfilter. - String: replicate, charindex, leftstr, rightstr, ltrim, rtrim, trim, replace, reverse, proper, padl, padr, padc, strfilter.
- Aggregate: stdev, variance, mode, median, lower_quartile, upper_quartile - Aggregate: stdev, variance, mode, median, lower_quartile, upper_quartile
For an example see [dinedal/go-sqlite3-extension-functions](https://github.com/dinedal/go-sqlite3-extension-functions). For an example, see [dinedal/go-sqlite3-extension-functions](https://github.com/dinedal/go-sqlite3-extension-functions).
# FAQ # FAQ
@ -491,7 +502,7 @@ For an example see [dinedal/go-sqlite3-extension-functions](https://github.com/d
- Can I use this in multiple routines concurrently? - Can I use this in multiple routines concurrently?
Yes for readonly. But, No for writable. See [#50](https://github.com/mattn/go-sqlite3/issues/50), [#51](https://github.com/mattn/go-sqlite3/issues/51), [#209](https://github.com/mattn/go-sqlite3/issues/209), [#274](https://github.com/mattn/go-sqlite3/issues/274). Yes for readonly. But not for writable. See [#50](https://github.com/mattn/go-sqlite3/issues/50), [#51](https://github.com/mattn/go-sqlite3/issues/51), [#209](https://github.com/mattn/go-sqlite3/issues/209), [#274](https://github.com/mattn/go-sqlite3/issues/274).
- Why I'm getting `no such table` error? - Why I'm getting `no such table` error?
@ -505,7 +516,7 @@ For an example see [dinedal/go-sqlite3-extension-functions](https://github.com/d
Note that if the last database connection in the pool closes, the in-memory database is deleted. Make sure the [max idle connection limit](https://golang.org/pkg/database/sql/#DB.SetMaxIdleConns) is > 0, and the [connection lifetime](https://golang.org/pkg/database/sql/#DB.SetConnMaxLifetime) is infinite. Note that if the last database connection in the pool closes, the in-memory database is deleted. Make sure the [max idle connection limit](https://golang.org/pkg/database/sql/#DB.SetMaxIdleConns) is > 0, and the [connection lifetime](https://golang.org/pkg/database/sql/#DB.SetConnMaxLifetime) is infinite.
For more information see For more information see:
* [#204](https://github.com/mattn/go-sqlite3/issues/204) * [#204](https://github.com/mattn/go-sqlite3/issues/204)
* [#511](https://github.com/mattn/go-sqlite3/issues/511) * [#511](https://github.com/mattn/go-sqlite3/issues/511)
* https://www.sqlite.org/sharedcache.html#shared_cache_and_in_memory_databases * https://www.sqlite.org/sharedcache.html#shared_cache_and_in_memory_databases
@ -515,20 +526,20 @@ For an example see [dinedal/go-sqlite3-extension-functions](https://github.com/d
OS X limits OS-wide to not have more than 1000 files open simultaneously by default. OS X limits OS-wide to not have more than 1000 files open simultaneously by default.
For more information see [#289](https://github.com/mattn/go-sqlite3/issues/289) For more information, see [#289](https://github.com/mattn/go-sqlite3/issues/289)
- Trying to execute a `.` (dot) command throws an error. - Trying to execute a `.` (dot) command throws an error.
Error: `Error: near ".": syntax error` Error: `Error: near ".": syntax error`
Dot command are part of SQLite3 CLI not of this library. Dot command are part of SQLite3 CLI, not of this library.
You need to implement the feature or call the sqlite3 cli. You need to implement the feature or call the sqlite3 cli.
More information see [#305](https://github.com/mattn/go-sqlite3/issues/305) More information see [#305](https://github.com/mattn/go-sqlite3/issues/305).
- Error: `database is locked` - Error: `database is locked`
When you get a database is locked. Please use the following options. When you get a database is locked, please use the following options.
Add to DSN: `cache=shared` Add to DSN: `cache=shared`
@ -537,24 +548,24 @@ For an example see [dinedal/go-sqlite3-extension-functions](https://github.com/d
db, err := sql.Open("sqlite3", "file:locked.sqlite?cache=shared") db, err := sql.Open("sqlite3", "file:locked.sqlite?cache=shared")
``` ```
Second please set the database connections of the SQL package to 1. Next, please set the database connections of the SQL package to 1:
```go ```go
db.SetMaxOpenConns(1) db.SetMaxOpenConns(1)
``` ```
More information see [#209](https://github.com/mattn/go-sqlite3/issues/209) For more information, see [#209](https://github.com/mattn/go-sqlite3/issues/209).
## Contributors ## Contributors
### Code Contributors ### Code Contributors
This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)]. This project exists thanks to all the people who [[contribute](CONTRIBUTING.md)].
<a href="https://github.com/mattn/go-sqlite3/graphs/contributors"><img src="https://opencollective.com/mattn-go-sqlite3/contributors.svg?width=890&button=false" /></a> <a href="https://github.com/mattn/go-sqlite3/graphs/contributors"><img src="https://opencollective.com/mattn-go-sqlite3/contributors.svg?width=890&button=false" /></a>
### Financial Contributors ### Financial Contributors
Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/mattn-go-sqlite3/contribute)] Become a financial contributor and help us sustain our community. [[Contribute here](https://opencollective.com/mattn-go-sqlite3/contribute)].
#### Individuals #### Individuals

View File

@ -7,7 +7,7 @@ package sqlite3
/* /*
#ifndef USE_LIBSQLITE3 #ifndef USE_LIBSQLITE3
#include <sqlite3-binding.h> #include "sqlite3-binding.h"
#else #else
#include <sqlite3.h> #include <sqlite3.h>
#endif #endif

View File

@ -12,7 +12,7 @@ package sqlite3
/* /*
#ifndef USE_LIBSQLITE3 #ifndef USE_LIBSQLITE3
#include <sqlite3-binding.h> #include "sqlite3-binding.h"
#else #else
#include <sqlite3.h> #include <sqlite3.h>
#endif #endif
@ -100,13 +100,13 @@ func preUpdateHookTrampoline(handle unsafe.Pointer, dbHandle uintptr, op int, db
// Use handles to avoid passing Go pointers to C. // Use handles to avoid passing Go pointers to C.
type handleVal struct { type handleVal struct {
db *SQLiteConn db *SQLiteConn
val interface{} val any
} }
var handleLock sync.Mutex var handleLock sync.Mutex
var handleVals = make(map[unsafe.Pointer]handleVal) var handleVals = make(map[unsafe.Pointer]handleVal)
func newHandle(db *SQLiteConn, v interface{}) unsafe.Pointer { func newHandle(db *SQLiteConn, v any) unsafe.Pointer {
handleLock.Lock() handleLock.Lock()
defer handleLock.Unlock() defer handleLock.Unlock()
val := handleVal{db: db, val: v} val := handleVal{db: db, val: v}
@ -124,7 +124,7 @@ func lookupHandleVal(handle unsafe.Pointer) handleVal {
return handleVals[handle] return handleVals[handle]
} }
func lookupHandle(handle unsafe.Pointer) interface{} { func lookupHandle(handle unsafe.Pointer) any {
return lookupHandleVal(handle).val return lookupHandleVal(handle).val
} }
@ -238,7 +238,7 @@ func callbackArg(typ reflect.Type) (callbackArgConverter, error) {
switch typ.Kind() { switch typ.Kind() {
case reflect.Interface: case reflect.Interface:
if typ.NumMethod() != 0 { if typ.NumMethod() != 0 {
return nil, errors.New("the only supported interface type is interface{}") return nil, errors.New("the only supported interface type is any")
} }
return callbackArgGeneric, nil return callbackArgGeneric, nil
case reflect.Slice: case reflect.Slice:
@ -353,6 +353,20 @@ func callbackRetNil(ctx *C.sqlite3_context, v reflect.Value) error {
return nil return nil
} }
func callbackRetGeneric(ctx *C.sqlite3_context, v reflect.Value) error {
if v.IsNil() {
C.sqlite3_result_null(ctx)
return nil
}
cb, err := callbackRet(v.Elem().Type())
if err != nil {
return err
}
return cb(ctx, v.Elem())
}
func callbackRet(typ reflect.Type) (callbackRetConverter, error) { func callbackRet(typ reflect.Type) (callbackRetConverter, error) {
switch typ.Kind() { switch typ.Kind() {
case reflect.Interface: case reflect.Interface:
@ -360,6 +374,11 @@ func callbackRet(typ reflect.Type) (callbackRetConverter, error) {
if typ.Implements(errorInterface) { if typ.Implements(errorInterface) {
return callbackRetNil, nil return callbackRetNil, nil
} }
if typ.NumMethod() == 0 {
return callbackRetGeneric, nil
}
fallthrough fallthrough
case reflect.Slice: case reflect.Slice:
if typ.Elem().Kind() != reflect.Uint8 { if typ.Elem().Kind() != reflect.Uint8 {

View File

@ -23,7 +23,7 @@ var errNilPtr = errors.New("destination pointer is nil") // embedded in descript
// convertAssign copies to dest the value in src, converting it if possible. // convertAssign copies to dest the value in src, converting it if possible.
// An error is returned if the copy would result in loss of information. // An error is returned if the copy would result in loss of information.
// dest should be a pointer type. // dest should be a pointer type.
func convertAssign(dest, src interface{}) error { func convertAssign(dest, src any) error {
// Common cases, without reflect. // Common cases, without reflect.
switch s := src.(type) { switch s := src.(type) {
case string: case string:
@ -55,7 +55,7 @@ func convertAssign(dest, src interface{}) error {
} }
*d = string(s) *d = string(s)
return nil return nil
case *interface{}: case *any:
if d == nil { if d == nil {
return errNilPtr return errNilPtr
} }
@ -97,7 +97,7 @@ func convertAssign(dest, src interface{}) error {
} }
case nil: case nil:
switch d := dest.(type) { switch d := dest.(type) {
case *interface{}: case *any:
if d == nil { if d == nil {
return errNilPtr return errNilPtr
} }
@ -149,7 +149,7 @@ func convertAssign(dest, src interface{}) error {
*d = bv.(bool) *d = bv.(bool)
} }
return err return err
case *interface{}: case *any:
*d = src *d = src
return nil return nil
} }
@ -256,7 +256,7 @@ func cloneBytes(b []byte) []byte {
return c return c
} }
func asString(src interface{}) string { func asString(src any) string {
switch v := src.(type) { switch v := src.(type) {
case string: case string:
return v return v

View File

@ -5,63 +5,63 @@ This works as a driver for database/sql.
Installation Installation
go get github.com/mattn/go-sqlite3 go get github.com/mattn/go-sqlite3
Supported Types # Supported Types
Currently, go-sqlite3 supports the following data types. Currently, go-sqlite3 supports the following data types.
+------------------------------+ +------------------------------+
|go | sqlite3 | |go | sqlite3 |
|----------|-------------------| |----------|-------------------|
|nil | null | |nil | null |
|int | integer | |int | integer |
|int64 | integer | |int64 | integer |
|float64 | float | |float64 | float |
|bool | integer | |bool | integer |
|[]byte | blob | |[]byte | blob |
|string | text | |string | text |
|time.Time | timestamp/datetime| |time.Time | timestamp/datetime|
+------------------------------+ +------------------------------+
SQLite3 Extension # SQLite3 Extension
You can write your own extension module for sqlite3. For example, below is an You can write your own extension module for sqlite3. For example, below is an
extension for a Regexp matcher operation. extension for a Regexp matcher operation.
#include <pcre.h> #include <pcre.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <sqlite3ext.h> #include <sqlite3ext.h>
SQLITE_EXTENSION_INIT1 SQLITE_EXTENSION_INIT1
static void regexp_func(sqlite3_context *context, int argc, sqlite3_value **argv) { static void regexp_func(sqlite3_context *context, int argc, sqlite3_value **argv) {
if (argc >= 2) { if (argc >= 2) {
const char *target = (const char *)sqlite3_value_text(argv[1]); const char *target = (const char *)sqlite3_value_text(argv[1]);
const char *pattern = (const char *)sqlite3_value_text(argv[0]); const char *pattern = (const char *)sqlite3_value_text(argv[0]);
const char* errstr = NULL; const char* errstr = NULL;
int erroff = 0; int erroff = 0;
int vec[500]; int vec[500];
int n, rc; int n, rc;
pcre* re = pcre_compile(pattern, 0, &errstr, &erroff, NULL); pcre* re = pcre_compile(pattern, 0, &errstr, &erroff, NULL);
rc = pcre_exec(re, NULL, target, strlen(target), 0, 0, vec, 500); rc = pcre_exec(re, NULL, target, strlen(target), 0, 0, vec, 500);
if (rc <= 0) { if (rc <= 0) {
sqlite3_result_error(context, errstr, 0); sqlite3_result_error(context, errstr, 0);
return; return;
} }
sqlite3_result_int(context, 1); sqlite3_result_int(context, 1);
} }
} }
#ifdef _WIN32 #ifdef _WIN32
__declspec(dllexport) __declspec(dllexport)
#endif #endif
int sqlite3_extension_init(sqlite3 *db, char **errmsg, int sqlite3_extension_init(sqlite3 *db, char **errmsg,
const sqlite3_api_routines *api) { const sqlite3_api_routines *api) {
SQLITE_EXTENSION_INIT2(api); SQLITE_EXTENSION_INIT2(api);
return sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8, return sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8,
(void*)db, regexp_func, NULL, NULL); (void*)db, regexp_func, NULL, NULL);
} }
It needs to be built as a so/dll shared library. And you need to register It needs to be built as a so/dll shared library. And you need to register
the extension module like below. the extension module like below.
@ -77,7 +77,7 @@ Then, you can use this extension.
rows, err := db.Query("select text from mytable where name regexp '^golang'") rows, err := db.Query("select text from mytable where name regexp '^golang'")
Connection Hook # Connection Hook
You can hook and inject your code when the connection is established by setting You can hook and inject your code when the connection is established by setting
ConnectHook to get the SQLiteConn. ConnectHook to get the SQLiteConn.
@ -95,13 +95,13 @@ You can also use database/sql.Conn.Raw (Go >= 1.13):
conn, err := db.Conn(context.Background()) conn, err := db.Conn(context.Background())
// if err != nil { ... } // if err != nil { ... }
defer conn.Close() defer conn.Close()
err = conn.Raw(func (driverConn interface{}) error { err = conn.Raw(func (driverConn any) error {
sqliteConn := driverConn.(*sqlite3.SQLiteConn) sqliteConn := driverConn.(*sqlite3.SQLiteConn)
// ... use sqliteConn // ... use sqliteConn
}) })
// if err != nil { ... } // if err != nil { ... }
Go SQlite3 Extensions # Go SQlite3 Extensions
If you want to register Go functions as SQLite extension functions If you want to register Go functions as SQLite extension functions
you can make a custom driver by calling RegisterFunction from you can make a custom driver by calling RegisterFunction from
@ -130,6 +130,5 @@ You can then use the custom driver by passing its name to sql.Open.
} }
See the documentation of RegisterFunc for more details. See the documentation of RegisterFunc for more details.
*/ */
package sqlite3 package sqlite3

View File

@ -7,7 +7,7 @@ package sqlite3
/* /*
#ifndef USE_LIBSQLITE3 #ifndef USE_LIBSQLITE3
#include <sqlite3-binding.h> #include "sqlite3-binding.h"
#else #else
#include <sqlite3.h> #include <sqlite3.h>
#endif #endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build cgo
// +build cgo // +build cgo
package sqlite3 package sqlite3
@ -20,9 +21,10 @@ package sqlite3
#cgo CFLAGS: -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 #cgo CFLAGS: -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1
#cgo CFLAGS: -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT #cgo CFLAGS: -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT
#cgo CFLAGS: -Wno-deprecated-declarations #cgo CFLAGS: -Wno-deprecated-declarations
#cgo linux,!android CFLAGS: -DHAVE_PREAD64=1 -DHAVE_PWRITE64=1 #cgo openbsd CFLAGS: -I/usr/local/include
#cgo openbsd LDFLAGS: -L/usr/local/lib
#ifndef USE_LIBSQLITE3 #ifndef USE_LIBSQLITE3
#include <sqlite3-binding.h> #include "sqlite3-binding.h"
#else #else
#include <sqlite3.h> #include <sqlite3.h>
#endif #endif
@ -45,6 +47,18 @@ package sqlite3
# define SQLITE_DETERMINISTIC 0 # define SQLITE_DETERMINISTIC 0
#endif #endif
#if defined(HAVE_PREAD64) && defined(HAVE_PWRITE64)
# undef USE_PREAD
# undef USE_PWRITE
# define USE_PREAD64 1
# define USE_PWRITE64 1
#elif defined(HAVE_PREAD) && defined(HAVE_PWRITE)
# undef USE_PREAD
# undef USE_PWRITE
# define USE_PREAD64 1
# define USE_PWRITE64 1
#endif
static int static int
_sqlite3_open_v2(const char *filename, sqlite3 **ppDb, int flags, const char *zVfs) { _sqlite3_open_v2(const char *filename, sqlite3 **ppDb, int flags, const char *zVfs) {
#ifdef SQLITE_OPEN_URI #ifdef SQLITE_OPEN_URI
@ -231,8 +245,14 @@ const (
columnTimestamp string = "timestamp" columnTimestamp string = "timestamp"
) )
// This variable can be replaced with -ldflags like below:
// go build -ldflags="-X 'github.com/mattn/go-sqlite3.driverName=my-sqlite3'"
var driverName = "sqlite3"
func init() { func init() {
sql.Register("sqlite3", &SQLiteDriver{}) if driverName != "" {
sql.Register(driverName, &SQLiteDriver{})
}
} }
// Version returns SQLite library version information. // Version returns SQLite library version information.
@ -288,6 +308,51 @@ const (
/*SQLITE_RECURSIVE = C.SQLITE_RECURSIVE*/ /*SQLITE_RECURSIVE = C.SQLITE_RECURSIVE*/
) )
// Standard File Control Opcodes
// See: https://www.sqlite.org/c3ref/c_fcntl_begin_atomic_write.html
const (
SQLITE_FCNTL_LOCKSTATE = int(1)
SQLITE_FCNTL_GET_LOCKPROXYFILE = int(2)
SQLITE_FCNTL_SET_LOCKPROXYFILE = int(3)
SQLITE_FCNTL_LAST_ERRNO = int(4)
SQLITE_FCNTL_SIZE_HINT = int(5)
SQLITE_FCNTL_CHUNK_SIZE = int(6)
SQLITE_FCNTL_FILE_POINTER = int(7)
SQLITE_FCNTL_SYNC_OMITTED = int(8)
SQLITE_FCNTL_WIN32_AV_RETRY = int(9)
SQLITE_FCNTL_PERSIST_WAL = int(10)
SQLITE_FCNTL_OVERWRITE = int(11)
SQLITE_FCNTL_VFSNAME = int(12)
SQLITE_FCNTL_POWERSAFE_OVERWRITE = int(13)
SQLITE_FCNTL_PRAGMA = int(14)
SQLITE_FCNTL_BUSYHANDLER = int(15)
SQLITE_FCNTL_TEMPFILENAME = int(16)
SQLITE_FCNTL_MMAP_SIZE = int(18)
SQLITE_FCNTL_TRACE = int(19)
SQLITE_FCNTL_HAS_MOVED = int(20)
SQLITE_FCNTL_SYNC = int(21)
SQLITE_FCNTL_COMMIT_PHASETWO = int(22)
SQLITE_FCNTL_WIN32_SET_HANDLE = int(23)
SQLITE_FCNTL_WAL_BLOCK = int(24)
SQLITE_FCNTL_ZIPVFS = int(25)
SQLITE_FCNTL_RBU = int(26)
SQLITE_FCNTL_VFS_POINTER = int(27)
SQLITE_FCNTL_JOURNAL_POINTER = int(28)
SQLITE_FCNTL_WIN32_GET_HANDLE = int(29)
SQLITE_FCNTL_PDB = int(30)
SQLITE_FCNTL_BEGIN_ATOMIC_WRITE = int(31)
SQLITE_FCNTL_COMMIT_ATOMIC_WRITE = int(32)
SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE = int(33)
SQLITE_FCNTL_LOCK_TIMEOUT = int(34)
SQLITE_FCNTL_DATA_VERSION = int(35)
SQLITE_FCNTL_SIZE_LIMIT = int(36)
SQLITE_FCNTL_CKPT_DONE = int(37)
SQLITE_FCNTL_RESERVE_BYTES = int(38)
SQLITE_FCNTL_CKPT_START = int(39)
SQLITE_FCNTL_EXTERNAL_READER = int(40)
SQLITE_FCNTL_CKSM_FILE = int(41)
)
// SQLiteDriver implements driver.Driver. // SQLiteDriver implements driver.Driver.
type SQLiteDriver struct { type SQLiteDriver struct {
Extensions []string Extensions []string
@ -440,10 +505,12 @@ func (ai *aggInfo) Done(ctx *C.sqlite3_context) {
// Commit transaction. // Commit transaction.
func (tx *SQLiteTx) Commit() error { func (tx *SQLiteTx) Commit() error {
_, err := tx.c.exec(context.Background(), "COMMIT", nil) _, err := tx.c.exec(context.Background(), "COMMIT", nil)
if err != nil && err.(Error).Code == C.SQLITE_BUSY { if err != nil {
// sqlite3 will leave the transaction open in this scenario. // sqlite3 may leave the transaction open in this scenario.
// However, database/sql considers the transaction complete once we // However, database/sql considers the transaction complete once we
// return from Commit() - we must clean up to honour its semantics. // return from Commit() - we must clean up to honour its semantics.
// We don't know if the ROLLBACK is strictly necessary, but according
// to sqlite's docs, there is no harm in calling ROLLBACK unnecessarily.
tx.c.exec(context.Background(), "ROLLBACK", nil) tx.c.exec(context.Background(), "ROLLBACK", nil)
} }
return err return err
@ -540,10 +607,9 @@ func (c *SQLiteConn) RegisterAuthorizer(callback func(int, string, string, strin
// RegisterFunc makes a Go function available as a SQLite function. // RegisterFunc makes a Go function available as a SQLite function.
// //
// The Go function can have arguments of the following types: any // The Go function can have arguments of the following types: any
// numeric type except complex, bool, []byte, string and // numeric type except complex, bool, []byte, string and any.
// interface{}. interface{} arguments are given the direct translation // any arguments are given the direct translation of the SQLite data type:
// of the SQLite data type: int64 for INTEGER, float64 for FLOAT, // int64 for INTEGER, float64 for FLOAT, []byte for BLOB, string for TEXT.
// []byte for BLOB, string for TEXT.
// //
// The function can additionally be variadic, as long as the type of // The function can additionally be variadic, as long as the type of
// the variadic argument is one of the above. // the variadic argument is one of the above.
@ -553,7 +619,7 @@ func (c *SQLiteConn) RegisterAuthorizer(callback func(int, string, string, strin
// optimizations in its queries. // optimizations in its queries.
// //
// See _example/go_custom_funcs for a detailed example. // See _example/go_custom_funcs for a detailed example.
func (c *SQLiteConn) RegisterFunc(name string, impl interface{}, pure bool) error { func (c *SQLiteConn) RegisterFunc(name string, impl any, pure bool) error {
var fi functionInfo var fi functionInfo
fi.f = reflect.ValueOf(impl) fi.f = reflect.ValueOf(impl)
t := fi.f.Type() t := fi.f.Type()
@ -635,7 +701,7 @@ func sqlite3CreateFunction(db *C.sqlite3, zFunctionName *C.char, nArg C.int, eTe
// return an error in addition to their other return values. // return an error in addition to their other return values.
// //
// See _example/go_custom_funcs for a detailed example. // See _example/go_custom_funcs for a detailed example.
func (c *SQLiteConn) RegisterAggregator(name string, impl interface{}, pure bool) error { func (c *SQLiteConn) RegisterAggregator(name string, impl any, pure bool) error {
var ai aggInfo var ai aggInfo
ai.constructor = reflect.ValueOf(impl) ai.constructor = reflect.ValueOf(impl)
t := ai.constructor.Type() t := ai.constructor.Type()
@ -781,9 +847,9 @@ func lastError(db *C.sqlite3) error {
// Exec implements Execer. // Exec implements Execer.
func (c *SQLiteConn) Exec(query string, args []driver.Value) (driver.Result, error) { func (c *SQLiteConn) Exec(query string, args []driver.Value) (driver.Result, error) {
list := make([]namedValue, len(args)) list := make([]driver.NamedValue, len(args))
for i, v := range args { for i, v := range args {
list[i] = namedValue{ list[i] = driver.NamedValue{
Ordinal: i + 1, Ordinal: i + 1,
Value: v, Value: v,
} }
@ -791,7 +857,7 @@ func (c *SQLiteConn) Exec(query string, args []driver.Value) (driver.Result, err
return c.exec(context.Background(), query, list) return c.exec(context.Background(), query, list)
} }
func (c *SQLiteConn) exec(ctx context.Context, query string, args []namedValue) (driver.Result, error) { func (c *SQLiteConn) exec(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) {
start := 0 start := 0
for { for {
s, err := c.prepare(ctx, query) s, err := c.prepare(ctx, query)
@ -800,7 +866,7 @@ func (c *SQLiteConn) exec(ctx context.Context, query string, args []namedValue)
} }
var res driver.Result var res driver.Result
if s.(*SQLiteStmt).s != nil { if s.(*SQLiteStmt).s != nil {
stmtArgs := make([]namedValue, 0, len(args)) stmtArgs := make([]driver.NamedValue, 0, len(args))
na := s.NumInput() na := s.NumInput()
if len(args)-start < na { if len(args)-start < na {
s.Close() s.Close()
@ -809,14 +875,16 @@ func (c *SQLiteConn) exec(ctx context.Context, query string, args []namedValue)
// consume the number of arguments used in the current // consume the number of arguments used in the current
// statement and append all named arguments not // statement and append all named arguments not
// contained therein // contained therein
stmtArgs = append(stmtArgs, args[start:start+na]...) if len(args[start:start+na]) > 0 {
for i := range args { stmtArgs = append(stmtArgs, args[start:start+na]...)
if (i < start || i >= na) && args[i].Name != "" { for i := range args {
stmtArgs = append(stmtArgs, args[i]) if (i < start || i >= na) && args[i].Name != "" {
stmtArgs = append(stmtArgs, args[i])
}
}
for i := range stmtArgs {
stmtArgs[i].Ordinal = i + 1
} }
}
for i := range stmtArgs {
stmtArgs[i].Ordinal = i + 1
} }
res, err = s.(*SQLiteStmt).exec(ctx, stmtArgs) res, err = s.(*SQLiteStmt).exec(ctx, stmtArgs)
if err != nil && err != driver.ErrSkip { if err != nil && err != driver.ErrSkip {
@ -828,23 +896,21 @@ func (c *SQLiteConn) exec(ctx context.Context, query string, args []namedValue)
tail := s.(*SQLiteStmt).t tail := s.(*SQLiteStmt).t
s.Close() s.Close()
if tail == "" { if tail == "" {
if res == nil {
// https://github.com/mattn/go-sqlite3/issues/963
res = &SQLiteResult{0, 0}
}
return res, nil return res, nil
} }
query = tail query = tail
} }
} }
type namedValue struct {
Name string
Ordinal int
Value driver.Value
}
// Query implements Queryer. // Query implements Queryer.
func (c *SQLiteConn) Query(query string, args []driver.Value) (driver.Rows, error) { func (c *SQLiteConn) Query(query string, args []driver.Value) (driver.Rows, error) {
list := make([]namedValue, len(args)) list := make([]driver.NamedValue, len(args))
for i, v := range args { for i, v := range args {
list[i] = namedValue{ list[i] = driver.NamedValue{
Ordinal: i + 1, Ordinal: i + 1,
Value: v, Value: v,
} }
@ -852,10 +918,10 @@ func (c *SQLiteConn) Query(query string, args []driver.Value) (driver.Rows, erro
return c.query(context.Background(), query, list) return c.query(context.Background(), query, list)
} }
func (c *SQLiteConn) query(ctx context.Context, query string, args []namedValue) (driver.Rows, error) { func (c *SQLiteConn) query(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) {
start := 0 start := 0
for { for {
stmtArgs := make([]namedValue, 0, len(args)) stmtArgs := make([]driver.NamedValue, 0, len(args))
s, err := c.prepare(ctx, query) s, err := c.prepare(ctx, query)
if err != nil { if err != nil {
return nil, err return nil, err
@ -911,103 +977,104 @@ func (c *SQLiteConn) begin(ctx context.Context) (driver.Tx, error) {
// The argument is may be either in parentheses or it may be separated from // The argument is may be either in parentheses or it may be separated from
// the pragma name by an equal sign. The two syntaxes yield identical results. // the pragma name by an equal sign. The two syntaxes yield identical results.
// In many pragmas, the argument is a boolean. The boolean can be one of: // In many pragmas, the argument is a boolean. The boolean can be one of:
// 1 yes true on //
// 0 no false off // 1 yes true on
// 0 no false off
// //
// You can specify a DSN string using a URI as the filename. // You can specify a DSN string using a URI as the filename.
// test.db
// file:test.db?cache=shared&mode=memory
// :memory:
// file::memory:
// //
// mode // test.db
// Access mode of the database. // file:test.db?cache=shared&mode=memory
// https://www.sqlite.org/c3ref/open.html // :memory:
// Values: // file::memory:
// - ro
// - rw
// - rwc
// - memory
// //
// cache // mode
// SQLite Shared-Cache Mode // Access mode of the database.
// https://www.sqlite.org/sharedcache.html // https://www.sqlite.org/c3ref/open.html
// Values: // Values:
// - shared // - ro
// - private // - rw
// - rwc
// - memory
// //
// immutable=Boolean // cache
// The immutable parameter is a boolean query parameter that indicates // SQLite Shared-Cache Mode
// that the database file is stored on read-only media. When immutable is set, // https://www.sqlite.org/sharedcache.html
// SQLite assumes that the database file cannot be changed, // Values:
// even by a process with higher privilege, // - shared
// and so the database is opened read-only and all locking and change detection is disabled. // - private
// Caution: Setting the immutable property on a database file that //
// does in fact change can result in incorrect query results and/or SQLITE_CORRUPT errors. // immutable=Boolean
// The immutable parameter is a boolean query parameter that indicates
// that the database file is stored on read-only media. When immutable is set,
// SQLite assumes that the database file cannot be changed,
// even by a process with higher privilege,
// and so the database is opened read-only and all locking and change detection is disabled.
// Caution: Setting the immutable property on a database file that
// does in fact change can result in incorrect query results and/or SQLITE_CORRUPT errors.
// //
// go-sqlite3 adds the following query parameters to those used by SQLite: // go-sqlite3 adds the following query parameters to those used by SQLite:
// _loc=XXX
// Specify location of time format. It's possible to specify "auto".
// //
// _mutex=XXX // _loc=XXX
// Specify mutex mode. XXX can be "no", "full". // Specify location of time format. It's possible to specify "auto".
// //
// _txlock=XXX // _mutex=XXX
// Specify locking behavior for transactions. XXX can be "immediate", // Specify mutex mode. XXX can be "no", "full".
// "deferred", "exclusive".
// //
// _auto_vacuum=X | _vacuum=X // _txlock=XXX
// 0 | none - Auto Vacuum disabled // Specify locking behavior for transactions. XXX can be "immediate",
// 1 | full - Auto Vacuum FULL // "deferred", "exclusive".
// 2 | incremental - Auto Vacuum Incremental
// //
// _busy_timeout=XXX"| _timeout=XXX // _auto_vacuum=X | _vacuum=X
// Specify value for sqlite3_busy_timeout. // 0 | none - Auto Vacuum disabled
// 1 | full - Auto Vacuum FULL
// 2 | incremental - Auto Vacuum Incremental
// //
// _case_sensitive_like=Boolean | _cslike=Boolean // _busy_timeout=XXX"| _timeout=XXX
// https://www.sqlite.org/pragma.html#pragma_case_sensitive_like // Specify value for sqlite3_busy_timeout.
// Default or disabled the LIKE operation is case-insensitive.
// When enabling this options behaviour of LIKE will become case-sensitive.
// //
// _defer_foreign_keys=Boolean | _defer_fk=Boolean // _case_sensitive_like=Boolean | _cslike=Boolean
// Defer Foreign Keys until outermost transaction is committed. // https://www.sqlite.org/pragma.html#pragma_case_sensitive_like
// Default or disabled the LIKE operation is case-insensitive.
// When enabling this options behaviour of LIKE will become case-sensitive.
// //
// _foreign_keys=Boolean | _fk=Boolean // _defer_foreign_keys=Boolean | _defer_fk=Boolean
// Enable or disable enforcement of foreign keys. // Defer Foreign Keys until outermost transaction is committed.
// //
// _ignore_check_constraints=Boolean // _foreign_keys=Boolean | _fk=Boolean
// This pragma enables or disables the enforcement of CHECK constraints. // Enable or disable enforcement of foreign keys.
// The default setting is off, meaning that CHECK constraints are enforced by default.
// //
// _journal_mode=MODE | _journal=MODE // _ignore_check_constraints=Boolean
// Set journal mode for the databases associated with the current connection. // This pragma enables or disables the enforcement of CHECK constraints.
// https://www.sqlite.org/pragma.html#pragma_journal_mode // The default setting is off, meaning that CHECK constraints are enforced by default.
// //
// _locking_mode=X | _locking=X // _journal_mode=MODE | _journal=MODE
// Sets the database connection locking-mode. // Set journal mode for the databases associated with the current connection.
// The locking-mode is either NORMAL or EXCLUSIVE. // https://www.sqlite.org/pragma.html#pragma_journal_mode
// https://www.sqlite.org/pragma.html#pragma_locking_mode
// //
// _query_only=Boolean // _locking_mode=X | _locking=X
// The query_only pragma prevents all changes to database files when enabled. // Sets the database connection locking-mode.
// The locking-mode is either NORMAL or EXCLUSIVE.
// https://www.sqlite.org/pragma.html#pragma_locking_mode
// //
// _recursive_triggers=Boolean | _rt=Boolean // _query_only=Boolean
// Enable or disable recursive triggers. // The query_only pragma prevents all changes to database files when enabled.
// //
// _secure_delete=Boolean|FAST // _recursive_triggers=Boolean | _rt=Boolean
// When secure_delete is on, SQLite overwrites deleted content with zeros. // Enable or disable recursive triggers.
// https://www.sqlite.org/pragma.html#pragma_secure_delete
// //
// _synchronous=X | _sync=X // _secure_delete=Boolean|FAST
// Change the setting of the "synchronous" flag. // When secure_delete is on, SQLite overwrites deleted content with zeros.
// https://www.sqlite.org/pragma.html#pragma_synchronous // https://www.sqlite.org/pragma.html#pragma_secure_delete
//
// _writable_schema=Boolean
// When this pragma is on, the SQLITE_MASTER tables in which database
// can be changed using ordinary UPDATE, INSERT, and DELETE statements.
// Warning: misuse of this pragma can easily result in a corrupt database file.
// //
// _synchronous=X | _sync=X
// Change the setting of the "synchronous" flag.
// https://www.sqlite.org/pragma.html#pragma_synchronous
// //
// _writable_schema=Boolean
// When this pragma is on, the SQLITE_MASTER tables in which database
// can be changed using ordinary UPDATE, INSERT, and DELETE statements.
// Warning: misuse of this pragma can easily result in a corrupt database file.
func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
if C.sqlite3_threadsafe() == 0 { if C.sqlite3_threadsafe() == 0 {
return nil, errors.New("sqlite library was not compiled for thread-safe operation") return nil, errors.New("sqlite library was not compiled for thread-safe operation")
@ -1409,12 +1476,6 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
return nil, errors.New("sqlite succeeded without returning a database") return nil, errors.New("sqlite succeeded without returning a database")
} }
rv = C.sqlite3_busy_timeout(db, C.int(busyTimeout))
if rv != C.SQLITE_OK {
C.sqlite3_close_v2(db)
return nil, Error{Code: ErrNo(rv)}
}
exec := func(s string) error { exec := func(s string) error {
cs := C.CString(s) cs := C.CString(s)
rv := C.sqlite3_exec(db, cs, nil, nil, nil) rv := C.sqlite3_exec(db, cs, nil, nil, nil)
@ -1425,6 +1486,12 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
return nil return nil
} }
// Busy timeout
if err := exec(fmt.Sprintf("PRAGMA busy_timeout = %d;", busyTimeout)); err != nil {
C.sqlite3_close_v2(db)
return nil, err
}
// USER AUTHENTICATION // USER AUTHENTICATION
// //
// User Authentication is always performed even when // User Authentication is always performed even when
@ -1612,7 +1679,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
} }
} }
// Forgein Keys // Foreign Keys
if foreignKeys > -1 { if foreignKeys > -1 {
if err := exec(fmt.Sprintf("PRAGMA foreign_keys = %d;", foreignKeys)); err != nil { if err := exec(fmt.Sprintf("PRAGMA foreign_keys = %d;", foreignKeys)); err != nil {
C.sqlite3_close_v2(db) C.sqlite3_close_v2(db)
@ -1800,6 +1867,31 @@ func (c *SQLiteConn) SetLimit(id int, newVal int) int {
return int(C._sqlite3_limit(c.db, C.int(id), C.int(newVal))) return int(C._sqlite3_limit(c.db, C.int(id), C.int(newVal)))
} }
// SetFileControlInt invokes the xFileControl method on a given database. The
// dbName is the name of the database. It will default to "main" if left blank.
// The op is one of the opcodes prefixed by "SQLITE_FCNTL_". The arg argument
// and return code are both opcode-specific. Please see the SQLite documentation.
//
// This method is not thread-safe as the returned error code can be changed by
// another call if invoked concurrently.
//
// See: sqlite3_file_control, https://www.sqlite.org/c3ref/file_control.html
func (c *SQLiteConn) SetFileControlInt(dbName string, op int, arg int) error {
if dbName == "" {
dbName = "main"
}
cDBName := C.CString(dbName)
defer C.free(unsafe.Pointer(cDBName))
cArg := C.int(arg)
rv := C.sqlite3_file_control(c.db, cDBName, C.int(op), unsafe.Pointer(&cArg))
if rv != C.SQLITE_OK {
return c.lastError()
}
return nil
}
// Close the statement. // Close the statement.
func (s *SQLiteStmt) Close() error { func (s *SQLiteStmt) Close() error {
s.mu.Lock() s.mu.Lock()
@ -1816,6 +1908,7 @@ func (s *SQLiteStmt) Close() error {
if rv != C.SQLITE_OK { if rv != C.SQLITE_OK {
return s.c.lastError() return s.c.lastError()
} }
s.c = nil
runtime.SetFinalizer(s, nil) runtime.SetFinalizer(s, nil)
return nil return nil
} }
@ -1827,7 +1920,7 @@ func (s *SQLiteStmt) NumInput() int {
var placeHolder = []byte{0} var placeHolder = []byte{0}
func (s *SQLiteStmt) bind(args []namedValue) error { func (s *SQLiteStmt) bind(args []driver.NamedValue) error {
rv := C.sqlite3_reset(s.s) rv := C.sqlite3_reset(s.s)
if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE { if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE {
return s.c.lastError() return s.c.lastError()
@ -1897,9 +1990,9 @@ func (s *SQLiteStmt) bind(args []namedValue) error {
// Query the statement with arguments. Return records. // Query the statement with arguments. Return records.
func (s *SQLiteStmt) Query(args []driver.Value) (driver.Rows, error) { func (s *SQLiteStmt) Query(args []driver.Value) (driver.Rows, error) {
list := make([]namedValue, len(args)) list := make([]driver.NamedValue, len(args))
for i, v := range args { for i, v := range args {
list[i] = namedValue{ list[i] = driver.NamedValue{
Ordinal: i + 1, Ordinal: i + 1,
Value: v, Value: v,
} }
@ -1907,7 +2000,7 @@ func (s *SQLiteStmt) Query(args []driver.Value) (driver.Rows, error) {
return s.query(context.Background(), list) return s.query(context.Background(), list)
} }
func (s *SQLiteStmt) query(ctx context.Context, args []namedValue) (driver.Rows, error) { func (s *SQLiteStmt) query(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) {
if err := s.bind(args); err != nil { if err := s.bind(args); err != nil {
return nil, err return nil, err
} }
@ -1921,6 +2014,7 @@ func (s *SQLiteStmt) query(ctx context.Context, args []namedValue) (driver.Rows,
closed: false, closed: false,
ctx: ctx, ctx: ctx,
} }
runtime.SetFinalizer(rows, (*SQLiteRows).Close)
return rows, nil return rows, nil
} }
@ -1937,9 +2031,9 @@ func (r *SQLiteResult) RowsAffected() (int64, error) {
// Exec execute the statement with arguments. Return result object. // Exec execute the statement with arguments. Return result object.
func (s *SQLiteStmt) Exec(args []driver.Value) (driver.Result, error) { func (s *SQLiteStmt) Exec(args []driver.Value) (driver.Result, error) {
list := make([]namedValue, len(args)) list := make([]driver.NamedValue, len(args))
for i, v := range args { for i, v := range args {
list[i] = namedValue{ list[i] = driver.NamedValue{
Ordinal: i + 1, Ordinal: i + 1,
Value: v, Value: v,
} }
@ -1956,7 +2050,7 @@ func isInterruptErr(err error) bool {
} }
// exec executes a query that doesn't return rows. Attempts to honor context timeout. // exec executes a query that doesn't return rows. Attempts to honor context timeout.
func (s *SQLiteStmt) exec(ctx context.Context, args []namedValue) (driver.Result, error) { func (s *SQLiteStmt) exec(ctx context.Context, args []driver.NamedValue) (driver.Result, error) {
if ctx.Done() == nil { if ctx.Done() == nil {
return s.execSync(args) return s.execSync(args)
} }
@ -1966,6 +2060,7 @@ func (s *SQLiteStmt) exec(ctx context.Context, args []namedValue) (driver.Result
err error err error
} }
resultCh := make(chan result) resultCh := make(chan result)
defer close(resultCh)
go func() { go func() {
r, err := s.execSync(args) r, err := s.execSync(args)
resultCh <- result{r, err} resultCh <- result{r, err}
@ -1988,7 +2083,7 @@ func (s *SQLiteStmt) exec(ctx context.Context, args []namedValue) (driver.Result
return rv.r, rv.err return rv.r, rv.err
} }
func (s *SQLiteStmt) execSync(args []namedValue) (driver.Result, error) { func (s *SQLiteStmt) execSync(args []driver.NamedValue) (driver.Result, error) {
if err := s.bind(args); err != nil { if err := s.bind(args); err != nil {
C.sqlite3_reset(s.s) C.sqlite3_reset(s.s)
C.sqlite3_clear_bindings(s.s) C.sqlite3_clear_bindings(s.s)
@ -2032,6 +2127,8 @@ func (rc *SQLiteRows) Close() error {
return rc.s.c.lastError() return rc.s.c.lastError()
} }
rc.s.mu.Unlock() rc.s.mu.Unlock()
rc.s = nil
runtime.SetFinalizer(rc, nil)
return nil return nil
} }
@ -2078,6 +2175,7 @@ func (rc *SQLiteRows) Next(dest []driver.Value) error {
return rc.nextSyncLocked(dest) return rc.nextSyncLocked(dest)
} }
resultCh := make(chan error) resultCh := make(chan error)
defer close(resultCh)
go func() { go func() {
resultCh <- rc.nextSyncLocked(dest) resultCh <- rc.nextSyncLocked(dest)
}() }()

View File

@ -8,7 +8,7 @@ package sqlite3
/* /*
#ifndef USE_LIBSQLITE3 #ifndef USE_LIBSQLITE3
#include <sqlite3-binding.h> #include "sqlite3-binding.h"
#else #else
#include <sqlite3.h> #include <sqlite3.h>
#endif #endif

View File

@ -50,15 +50,15 @@ import (
// perhaps using a cryptographic hash function like SHA1. // perhaps using a cryptographic hash function like SHA1.
// CryptEncoderSHA1 encodes a password with SHA1 // CryptEncoderSHA1 encodes a password with SHA1
func CryptEncoderSHA1(pass []byte, hash interface{}) []byte { func CryptEncoderSHA1(pass []byte, hash any) []byte {
h := sha1.Sum(pass) h := sha1.Sum(pass)
return h[:] return h[:]
} }
// CryptEncoderSSHA1 encodes a password with SHA1 with the // CryptEncoderSSHA1 encodes a password with SHA1 with the
// configured salt. // configured salt.
func CryptEncoderSSHA1(salt string) func(pass []byte, hash interface{}) []byte { func CryptEncoderSSHA1(salt string) func(pass []byte, hash any) []byte {
return func(pass []byte, hash interface{}) []byte { return func(pass []byte, hash any) []byte {
s := []byte(salt) s := []byte(salt)
p := append(pass, s...) p := append(pass, s...)
h := sha1.Sum(p) h := sha1.Sum(p)
@ -67,15 +67,15 @@ func CryptEncoderSSHA1(salt string) func(pass []byte, hash interface{}) []byte {
} }
// CryptEncoderSHA256 encodes a password with SHA256 // CryptEncoderSHA256 encodes a password with SHA256
func CryptEncoderSHA256(pass []byte, hash interface{}) []byte { func CryptEncoderSHA256(pass []byte, hash any) []byte {
h := sha256.Sum256(pass) h := sha256.Sum256(pass)
return h[:] return h[:]
} }
// CryptEncoderSSHA256 encodes a password with SHA256 // CryptEncoderSSHA256 encodes a password with SHA256
// with the configured salt // with the configured salt
func CryptEncoderSSHA256(salt string) func(pass []byte, hash interface{}) []byte { func CryptEncoderSSHA256(salt string) func(pass []byte, hash any) []byte {
return func(pass []byte, hash interface{}) []byte { return func(pass []byte, hash any) []byte {
s := []byte(salt) s := []byte(salt)
p := append(pass, s...) p := append(pass, s...)
h := sha256.Sum256(p) h := sha256.Sum256(p)
@ -84,15 +84,15 @@ func CryptEncoderSSHA256(salt string) func(pass []byte, hash interface{}) []byte
} }
// CryptEncoderSHA384 encodes a password with SHA384 // CryptEncoderSHA384 encodes a password with SHA384
func CryptEncoderSHA384(pass []byte, hash interface{}) []byte { func CryptEncoderSHA384(pass []byte, hash any) []byte {
h := sha512.Sum384(pass) h := sha512.Sum384(pass)
return h[:] return h[:]
} }
// CryptEncoderSSHA384 encodes a password with SHA384 // CryptEncoderSSHA384 encodes a password with SHA384
// with the configured salt // with the configured salt
func CryptEncoderSSHA384(salt string) func(pass []byte, hash interface{}) []byte { func CryptEncoderSSHA384(salt string) func(pass []byte, hash any) []byte {
return func(pass []byte, hash interface{}) []byte { return func(pass []byte, hash any) []byte {
s := []byte(salt) s := []byte(salt)
p := append(pass, s...) p := append(pass, s...)
h := sha512.Sum384(p) h := sha512.Sum384(p)
@ -101,15 +101,15 @@ func CryptEncoderSSHA384(salt string) func(pass []byte, hash interface{}) []byte
} }
// CryptEncoderSHA512 encodes a password with SHA512 // CryptEncoderSHA512 encodes a password with SHA512
func CryptEncoderSHA512(pass []byte, hash interface{}) []byte { func CryptEncoderSHA512(pass []byte, hash any) []byte {
h := sha512.Sum512(pass) h := sha512.Sum512(pass)
return h[:] return h[:]
} }
// CryptEncoderSSHA512 encodes a password with SHA512 // CryptEncoderSSHA512 encodes a password with SHA512
// with the configured salt // with the configured salt
func CryptEncoderSSHA512(salt string) func(pass []byte, hash interface{}) []byte { func CryptEncoderSSHA512(salt string) func(pass []byte, hash any) []byte {
return func(pass []byte, hash interface{}) []byte { return func(pass []byte, hash any) []byte {
s := []byte(salt) s := []byte(salt)
p := append(pass, s...) p := append(pass, s...)
h := sha512.Sum512(p) h := sha512.Sum512(p)

View File

@ -3,8 +3,8 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build cgo //go:build cgo && go1.8
// +build go1.8 // +build cgo,go1.8
package sqlite3 package sqlite3
@ -25,20 +25,12 @@ func (c *SQLiteConn) Ping(ctx context.Context) error {
// QueryContext implement QueryerContext. // QueryContext implement QueryerContext.
func (c *SQLiteConn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) { func (c *SQLiteConn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) {
list := make([]namedValue, len(args)) return c.query(ctx, query, args)
for i, nv := range args {
list[i] = namedValue(nv)
}
return c.query(ctx, query, list)
} }
// ExecContext implement ExecerContext. // ExecContext implement ExecerContext.
func (c *SQLiteConn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) { func (c *SQLiteConn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) {
list := make([]namedValue, len(args)) return c.exec(ctx, query, args)
for i, nv := range args {
list[i] = namedValue(nv)
}
return c.exec(ctx, query, list)
} }
// PrepareContext implement ConnPrepareContext. // PrepareContext implement ConnPrepareContext.
@ -53,18 +45,10 @@ func (c *SQLiteConn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver
// QueryContext implement QueryerContext. // QueryContext implement QueryerContext.
func (s *SQLiteStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) { func (s *SQLiteStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) {
list := make([]namedValue, len(args)) return s.query(ctx, args)
for i, nv := range args {
list[i] = namedValue(nv)
}
return s.query(ctx, list)
} }
// ExecContext implement ExecerContext. // ExecContext implement ExecerContext.
func (s *SQLiteStmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) { func (s *SQLiteStmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) {
list := make([]namedValue, len(args)) return s.exec(ctx, args)
for i, nv := range args {
list[i] = namedValue(nv)
}
return s.exec(ctx, list)
} }

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build libsqlite3
// +build libsqlite3 // +build libsqlite3
package sqlite3 package sqlite3
@ -10,10 +11,13 @@ package sqlite3
/* /*
#cgo CFLAGS: -DUSE_LIBSQLITE3 #cgo CFLAGS: -DUSE_LIBSQLITE3
#cgo linux LDFLAGS: -lsqlite3 #cgo linux LDFLAGS: -lsqlite3
#cgo darwin LDFLAGS: -L/usr/local/opt/sqlite/lib -lsqlite3 #cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/sqlite/lib -lsqlite3
#cgo darwin CFLAGS: -I/usr/local/opt/sqlite/include #cgo darwin,amd64 CFLAGS: -I/usr/local/opt/sqlite/include
#cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/sqlite/lib -lsqlite3
#cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/sqlite/include
#cgo openbsd LDFLAGS: -lsqlite3 #cgo openbsd LDFLAGS: -lsqlite3
#cgo solaris LDFLAGS: -lsqlite3 #cgo solaris LDFLAGS: -lsqlite3
#cgo windows LDFLAGS: -lsqlite3 #cgo windows LDFLAGS: -lsqlite3
#cgo zos LDFLAGS: -lsqlite3
*/ */
import "C" import "C"

View File

@ -3,13 +3,14 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !sqlite_omit_load_extension
// +build !sqlite_omit_load_extension // +build !sqlite_omit_load_extension
package sqlite3 package sqlite3
/* /*
#ifndef USE_LIBSQLITE3 #ifndef USE_LIBSQLITE3
#include <sqlite3-binding.h> #include "sqlite3-binding.h"
#else #else
#include <sqlite3.h> #include <sqlite3.h>
#endif #endif

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_omit_load_extension
// +build sqlite_omit_load_extension // +build sqlite_omit_load_extension
package sqlite3 package sqlite3

View File

@ -4,6 +4,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_allow_uri_authority
// +build sqlite_allow_uri_authority // +build sqlite_allow_uri_authority
package sqlite3 package sqlite3

View File

@ -4,8 +4,8 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build !windows //go:build !windows && sqlite_app_armor
// +build sqlite_app_armor // +build !windows,sqlite_app_armor
package sqlite3 package sqlite3

View File

@ -1,3 +1,4 @@
//go:build sqlite_column_metadata
// +build sqlite_column_metadata // +build sqlite_column_metadata
package sqlite3 package sqlite3

View File

@ -4,6 +4,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_foreign_keys
// +build sqlite_foreign_keys // +build sqlite_foreign_keys
package sqlite3 package sqlite3

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_fts5 || fts5
// +build sqlite_fts5 fts5 // +build sqlite_fts5 fts5
package sqlite3 package sqlite3

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_icu || icu
// +build sqlite_icu icu // +build sqlite_icu icu
package sqlite3 package sqlite3
@ -10,8 +11,10 @@ package sqlite3
/* /*
#cgo LDFLAGS: -licuuc -licui18n #cgo LDFLAGS: -licuuc -licui18n
#cgo CFLAGS: -DSQLITE_ENABLE_ICU #cgo CFLAGS: -DSQLITE_ENABLE_ICU
#cgo darwin CFLAGS: -I/usr/local/opt/icu4c/include #cgo darwin,amd64 CFLAGS: -I/usr/local/opt/icu4c/include
#cgo darwin LDFLAGS: -L/usr/local/opt/icu4c/lib #cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/icu4c/lib
#cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/icu4c/include
#cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/icu4c/lib
#cgo openbsd LDFLAGS: -lsqlite3 #cgo openbsd LDFLAGS: -lsqlite3
*/ */
import "C" import "C"

View File

@ -4,6 +4,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_introspect
// +build sqlite_introspect // +build sqlite_introspect
package sqlite3 package sqlite3

View File

@ -1,13 +0,0 @@
// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.
// +build sqlite_json sqlite_json1 json1
package sqlite3
/*
#cgo CFLAGS: -DSQLITE_ENABLE_JSON1
*/
import "C"

View File

@ -0,0 +1,15 @@
// Copyright (C) 2022 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.
//go:build sqlite_math_functions
// +build sqlite_math_functions
package sqlite3
/*
#cgo CFLAGS: -DSQLITE_ENABLE_MATH_FUNCTIONS
#cgo LDFLAGS: -lm
*/
import "C"

View File

@ -0,0 +1,15 @@
// Copyright (C) 2022 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.
//go:build sqlite_os_trace
// +build sqlite_os_trace
package sqlite3
/*
#cgo CFLAGS: -DSQLITE_FORCE_OS_TRACE=1
#cgo CFLAGS: -DSQLITE_DEBUG_OS_TRACE=1
*/
import "C"

View File

@ -4,6 +4,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build cgo
// +build cgo // +build cgo
package sqlite3 package sqlite3

View File

@ -4,6 +4,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_preupdate_hook
// +build sqlite_preupdate_hook // +build sqlite_preupdate_hook
package sqlite3 package sqlite3
@ -13,7 +14,7 @@ package sqlite3
#cgo LDFLAGS: -lm #cgo LDFLAGS: -lm
#ifndef USE_LIBSQLITE3 #ifndef USE_LIBSQLITE3
#include <sqlite3-binding.h> #include "sqlite3-binding.h"
#else #else
#include <sqlite3.h> #include <sqlite3.h>
#endif #endif
@ -33,7 +34,7 @@ import (
// The callback is passed a SQLitePreUpdateData struct with the data for // The callback is passed a SQLitePreUpdateData struct with the data for
// the update, as well as methods for fetching copies of impacted data. // the update, as well as methods for fetching copies of impacted data.
// //
// If there is an existing update hook for this connection, it will be // If there is an existing preupdate hook for this connection, it will be
// removed. If callback is nil the existing hook (if any) will be removed // removed. If callback is nil the existing hook (if any) will be removed
// without creating a new one. // without creating a new one.
func (c *SQLiteConn) RegisterPreUpdateHook(callback func(SQLitePreUpdateData)) { func (c *SQLiteConn) RegisterPreUpdateHook(callback func(SQLitePreUpdateData)) {
@ -54,10 +55,10 @@ func (d *SQLitePreUpdateData) Count() int {
return int(C.sqlite3_preupdate_count(d.Conn.db)) return int(C.sqlite3_preupdate_count(d.Conn.db))
} }
func (d *SQLitePreUpdateData) row(dest []interface{}, new bool) error { func (d *SQLitePreUpdateData) row(dest []any, new bool) error {
for i := 0; i < d.Count() && i < len(dest); i++ { for i := 0; i < d.Count() && i < len(dest); i++ {
var val *C.sqlite3_value var val *C.sqlite3_value
var src interface{} var src any
// Initially I tried making this just a function pointer argument, but // Initially I tried making this just a function pointer argument, but
// it's absurdly complicated to pass C function pointers. // it's absurdly complicated to pass C function pointers.
@ -95,7 +96,7 @@ func (d *SQLitePreUpdateData) row(dest []interface{}, new bool) error {
// Old populates dest with the row data to be replaced. This works similar to // Old populates dest with the row data to be replaced. This works similar to
// database/sql's Rows.Scan() // database/sql's Rows.Scan()
func (d *SQLitePreUpdateData) Old(dest ...interface{}) error { func (d *SQLitePreUpdateData) Old(dest ...any) error {
if d.Op == SQLITE_INSERT { if d.Op == SQLITE_INSERT {
return errors.New("There is no old row for INSERT operations") return errors.New("There is no old row for INSERT operations")
} }
@ -104,7 +105,7 @@ func (d *SQLitePreUpdateData) Old(dest ...interface{}) error {
// New populates dest with the replacement row data. This works similar to // New populates dest with the replacement row data. This works similar to
// database/sql's Rows.Scan() // database/sql's Rows.Scan()
func (d *SQLitePreUpdateData) New(dest ...interface{}) error { func (d *SQLitePreUpdateData) New(dest ...any) error {
if d.Op == SQLITE_DELETE { if d.Op == SQLITE_DELETE {
return errors.New("There is no new row for DELETE operations") return errors.New("There is no new row for DELETE operations")
} }

View File

@ -4,6 +4,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !sqlite_preupdate_hook && cgo
// +build !sqlite_preupdate_hook,cgo // +build !sqlite_preupdate_hook,cgo
package sqlite3 package sqlite3
@ -13,7 +14,7 @@ package sqlite3
// The callback is passed a SQLitePreUpdateData struct with the data for // The callback is passed a SQLitePreUpdateData struct with the data for
// the update, as well as methods for fetching copies of impacted data. // the update, as well as methods for fetching copies of impacted data.
// //
// If there is an existing update hook for this connection, it will be // If there is an existing preupdate hook for this connection, it will be
// removed. If callback is nil the existing hook (if any) will be removed // removed. If callback is nil the existing hook (if any) will be removed
// without creating a new one. // without creating a new one.
func (c *SQLiteConn) RegisterPreUpdateHook(callback func(SQLitePreUpdateData)) { func (c *SQLiteConn) RegisterPreUpdateHook(callback func(SQLitePreUpdateData)) {

View File

@ -4,6 +4,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_secure_delete
// +build sqlite_secure_delete // +build sqlite_secure_delete
package sqlite3 package sqlite3

View File

@ -4,6 +4,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_secure_delete_fast
// +build sqlite_secure_delete_fast // +build sqlite_secure_delete_fast
package sqlite3 package sqlite3

View File

@ -0,0 +1,83 @@
//go:build !libsqlite3 || sqlite_serialize
// +build !libsqlite3 sqlite_serialize
package sqlite3
/*
#ifndef USE_LIBSQLITE3
#include <sqlite3-binding.h>
#else
#include <sqlite3.h>
#endif
#include <stdlib.h>
#include <stdint.h>
*/
import "C"
import (
"fmt"
"math"
"reflect"
"unsafe"
)
// Serialize returns a byte slice that is a serialization of the database.
//
// See https://www.sqlite.org/c3ref/serialize.html
func (c *SQLiteConn) Serialize(schema string) ([]byte, error) {
if schema == "" {
schema = "main"
}
var zSchema *C.char
zSchema = C.CString(schema)
defer C.free(unsafe.Pointer(zSchema))
var sz C.sqlite3_int64
ptr := C.sqlite3_serialize(c.db, zSchema, &sz, 0)
if ptr == nil {
return nil, fmt.Errorf("serialize failed")
}
defer C.sqlite3_free(unsafe.Pointer(ptr))
if sz > C.sqlite3_int64(math.MaxInt) {
return nil, fmt.Errorf("serialized database is too large (%d bytes)", sz)
}
cBuf := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(ptr)),
Len: int(sz),
Cap: int(sz),
}))
res := make([]byte, int(sz))
copy(res, cBuf)
return res, nil
}
// Deserialize causes the connection to disconnect from the current database and
// then re-open as an in-memory database based on the contents of the byte slice.
//
// See https://www.sqlite.org/c3ref/deserialize.html
func (c *SQLiteConn) Deserialize(b []byte, schema string) error {
if schema == "" {
schema = "main"
}
var zSchema *C.char
zSchema = C.CString(schema)
defer C.free(unsafe.Pointer(zSchema))
tmpBuf := (*C.uchar)(C.sqlite3_malloc64(C.sqlite3_uint64(len(b))))
cBuf := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(tmpBuf)),
Len: len(b),
Cap: len(b),
}))
copy(cBuf, b)
rc := C.sqlite3_deserialize(c.db, zSchema, tmpBuf, C.sqlite3_int64(len(b)),
C.sqlite3_int64(len(b)), C.SQLITE_DESERIALIZE_FREEONCLOSE)
if rc != C.SQLITE_OK {
return fmt.Errorf("deserialize failed with return %v", rc)
}
return nil
}

View File

@ -0,0 +1,21 @@
//go:build libsqlite3 && !sqlite_serialize
// +build libsqlite3,!sqlite_serialize
package sqlite3
import (
"errors"
)
/*
#cgo CFLAGS: -DSQLITE_OMIT_DESERIALIZE
*/
import "C"
func (c *SQLiteConn) Serialize(schema string) ([]byte, error) {
return nil, errors.New("sqlite3: Serialize requires the sqlite_serialize build tag when using the libsqlite3 build tag")
}
func (c *SQLiteConn) Deserialize(b []byte, schema string) error {
return errors.New("sqlite3: Deserialize requires the sqlite_serialize build tag when using the libsqlite3 build tag")
}

View File

@ -4,6 +4,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_stat4
// +build sqlite_stat4 // +build sqlite_stat4
package sqlite3 package sqlite3

View File

@ -5,7 +5,7 @@
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
#include <stdio.h> #include <stdio.h>
#include <sqlite3-binding.h> #include "sqlite3-binding.h"
extern int unlock_notify_wait(sqlite3 *db); extern int unlock_notify_wait(sqlite3 *db);

View File

@ -3,8 +3,8 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build cgo //go:build cgo && sqlite_unlock_notify
// +build sqlite_unlock_notify // +build cgo,sqlite_unlock_notify
package sqlite3 package sqlite3
@ -12,7 +12,7 @@ package sqlite3
#cgo CFLAGS: -DSQLITE_ENABLE_UNLOCK_NOTIFY #cgo CFLAGS: -DSQLITE_ENABLE_UNLOCK_NOTIFY
#include <stdlib.h> #include <stdlib.h>
#include <sqlite3-binding.h> #include "sqlite3-binding.h"
extern void unlock_notify_callback(void *arg, int argc); extern void unlock_notify_callback(void *arg, int argc);
*/ */

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_userauth
// +build sqlite_userauth // +build sqlite_userauth
package sqlite3 package sqlite3
@ -11,7 +12,7 @@ package sqlite3
#cgo CFLAGS: -DSQLITE_USER_AUTHENTICATION #cgo CFLAGS: -DSQLITE_USER_AUTHENTICATION
#cgo LDFLAGS: -lm #cgo LDFLAGS: -lm
#ifndef USE_LIBSQLITE3 #ifndef USE_LIBSQLITE3
#include <sqlite3-binding.h> #include "sqlite3-binding.h"
#else #else
#include <sqlite3.h> #include <sqlite3.h>
#endif #endif
@ -79,13 +80,13 @@ var (
// If a database contains the SQLITE_USER table, then the // If a database contains the SQLITE_USER table, then the
// call to Authenticate must be invoked with an // call to Authenticate must be invoked with an
// appropriate username and password prior to enable read and write // appropriate username and password prior to enable read and write
//access to the database. // access to the database.
// //
// Return SQLITE_OK on success or SQLITE_ERROR if the username/password // Return SQLITE_OK on success or SQLITE_ERROR if the username/password
// combination is incorrect or unknown. // combination is incorrect or unknown.
// //
// If the SQLITE_USER table is not present in the database file, then // If the SQLITE_USER table is not present in the database file, then
// this interface is a harmless no-op returnning SQLITE_OK. // this interface is a harmless no-op returning SQLITE_OK.
func (c *SQLiteConn) Authenticate(username, password string) error { func (c *SQLiteConn) Authenticate(username, password string) error {
rv := c.authenticate(username, password) rv := c.authenticate(username, password)
switch rv { switch rv {
@ -103,9 +104,10 @@ func (c *SQLiteConn) Authenticate(username, password string) error {
// It is however exported for usage within SQL by the user. // It is however exported for usage within SQL by the user.
// //
// Returns: // Returns:
// C.SQLITE_OK (0) //
// C.SQLITE_ERROR (1) // C.SQLITE_OK (0)
// C.SQLITE_AUTH (23) // C.SQLITE_ERROR (1)
// C.SQLITE_AUTH (23)
func (c *SQLiteConn) authenticate(username, password string) int { func (c *SQLiteConn) authenticate(username, password string) int {
// Allocate C Variables // Allocate C Variables
cuser := C.CString(username) cuser := C.CString(username)
@ -155,9 +157,10 @@ func (c *SQLiteConn) AuthUserAdd(username, password string, admin bool) error {
// It is however exported for usage within SQL by the user. // It is however exported for usage within SQL by the user.
// //
// Returns: // Returns:
// C.SQLITE_OK (0) //
// C.SQLITE_ERROR (1) // C.SQLITE_OK (0)
// C.SQLITE_AUTH (23) // C.SQLITE_ERROR (1)
// C.SQLITE_AUTH (23)
func (c *SQLiteConn) authUserAdd(username, password string, admin int) int { func (c *SQLiteConn) authUserAdd(username, password string, admin int) int {
// Allocate C Variables // Allocate C Variables
cuser := C.CString(username) cuser := C.CString(username)
@ -207,9 +210,10 @@ func (c *SQLiteConn) AuthUserChange(username, password string, admin bool) error
// It is however exported for usage within SQL by the user. // It is however exported for usage within SQL by the user.
// //
// Returns: // Returns:
// C.SQLITE_OK (0) //
// C.SQLITE_ERROR (1) // C.SQLITE_OK (0)
// C.SQLITE_AUTH (23) // C.SQLITE_ERROR (1)
// C.SQLITE_AUTH (23)
func (c *SQLiteConn) authUserChange(username, password string, admin int) int { func (c *SQLiteConn) authUserChange(username, password string, admin int) int {
// Allocate C Variables // Allocate C Variables
cuser := C.CString(username) cuser := C.CString(username)
@ -249,9 +253,10 @@ func (c *SQLiteConn) AuthUserDelete(username string) error {
// It is however exported for usage within SQL by the user. // It is however exported for usage within SQL by the user.
// //
// Returns: // Returns:
// C.SQLITE_OK (0) //
// C.SQLITE_ERROR (1) // C.SQLITE_OK (0)
// C.SQLITE_AUTH (23) // C.SQLITE_ERROR (1)
// C.SQLITE_AUTH (23)
func (c *SQLiteConn) authUserDelete(username string) int { func (c *SQLiteConn) authUserDelete(username string) int {
// Allocate C Variables // Allocate C Variables
cuser := C.CString(username) cuser := C.CString(username)
@ -280,8 +285,9 @@ func (c *SQLiteConn) AuthEnabled() (exists bool) {
// It is however exported for usage within SQL by the user. // It is however exported for usage within SQL by the user.
// //
// Returns: // Returns:
// 0 - Disabled //
// 1 - Enabled // 0 - Disabled
// 1 - Enabled
func (c *SQLiteConn) authEnabled() int { func (c *SQLiteConn) authEnabled() int {
return int(C._sqlite3_auth_enabled(c.db)) return int(C._sqlite3_auth_enabled(c.db))
} }

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !sqlite_userauth
// +build !sqlite_userauth // +build !sqlite_userauth
package sqlite3 package sqlite3
@ -17,7 +18,7 @@ import (
// If a database contains the SQLITE_USER table, then the // If a database contains the SQLITE_USER table, then the
// call to Authenticate must be invoked with an // call to Authenticate must be invoked with an
// appropriate username and password prior to enable read and write // appropriate username and password prior to enable read and write
//access to the database. // access to the database.
// //
// Return SQLITE_OK on success or SQLITE_ERROR if the username/password // Return SQLITE_OK on success or SQLITE_ERROR if the username/password
// combination is incorrect or unknown. // combination is incorrect or unknown.
@ -34,9 +35,10 @@ func (c *SQLiteConn) Authenticate(username, password string) error {
// It is however exported for usage within SQL by the user. // It is however exported for usage within SQL by the user.
// //
// Returns: // Returns:
// C.SQLITE_OK (0) //
// C.SQLITE_ERROR (1) // C.SQLITE_OK (0)
// C.SQLITE_AUTH (23) // C.SQLITE_ERROR (1)
// C.SQLITE_AUTH (23)
func (c *SQLiteConn) authenticate(username, password string) int { func (c *SQLiteConn) authenticate(username, password string) int {
// NOOP // NOOP
return 0 return 0
@ -65,9 +67,10 @@ func (c *SQLiteConn) AuthUserAdd(username, password string, admin bool) error {
// It is however exported for usage within SQL by the user. // It is however exported for usage within SQL by the user.
// //
// Returns: // Returns:
// C.SQLITE_OK (0) //
// C.SQLITE_ERROR (1) // C.SQLITE_OK (0)
// C.SQLITE_AUTH (23) // C.SQLITE_ERROR (1)
// C.SQLITE_AUTH (23)
func (c *SQLiteConn) authUserAdd(username, password string, admin int) int { func (c *SQLiteConn) authUserAdd(username, password string, admin int) int {
// NOOP // NOOP
return 0 return 0
@ -96,9 +99,10 @@ func (c *SQLiteConn) AuthUserChange(username, password string, admin bool) error
// It is however exported for usage within SQL by the user. // It is however exported for usage within SQL by the user.
// //
// Returns: // Returns:
// C.SQLITE_OK (0) //
// C.SQLITE_ERROR (1) // C.SQLITE_OK (0)
// C.SQLITE_AUTH (23) // C.SQLITE_ERROR (1)
// C.SQLITE_AUTH (23)
func (c *SQLiteConn) authUserChange(username, password string, admin int) int { func (c *SQLiteConn) authUserChange(username, password string, admin int) int {
// NOOP // NOOP
return 0 return 0
@ -122,9 +126,10 @@ func (c *SQLiteConn) AuthUserDelete(username string) error {
// It is however exported for usage within SQL by the user. // It is however exported for usage within SQL by the user.
// //
// Returns: // Returns:
// C.SQLITE_OK (0) //
// C.SQLITE_ERROR (1) // C.SQLITE_OK (0)
// C.SQLITE_AUTH (23) // C.SQLITE_ERROR (1)
// C.SQLITE_AUTH (23)
func (c *SQLiteConn) authUserDelete(username string) int { func (c *SQLiteConn) authUserDelete(username string) int {
// NOOP // NOOP
return 0 return 0
@ -142,8 +147,9 @@ func (c *SQLiteConn) AuthEnabled() (exists bool) {
// It is however exported for usage within SQL by the user. // It is however exported for usage within SQL by the user.
// //
// Returns: // Returns:
// 0 - Disabled //
// 1 - Enabled // 0 - Disabled
// 1 - Enabled
func (c *SQLiteConn) authEnabled() int { func (c *SQLiteConn) authEnabled() int {
// NOOP // NOOP
return 0 return 0

View File

@ -4,6 +4,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_vacuum_full
// +build sqlite_vacuum_full // +build sqlite_vacuum_full
package sqlite3 package sqlite3

View File

@ -4,6 +4,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_vacuum_incr
// +build sqlite_vacuum_incr // +build sqlite_vacuum_incr
package sqlite3 package sqlite3

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_vtable || vtable
// +build sqlite_vtable vtable // +build sqlite_vtable vtable
package sqlite3 package sqlite3
@ -19,7 +20,7 @@ package sqlite3
#cgo CFLAGS: -Wno-deprecated-declarations #cgo CFLAGS: -Wno-deprecated-declarations
#ifndef USE_LIBSQLITE3 #ifndef USE_LIBSQLITE3
#include <sqlite3-binding.h> #include "sqlite3-binding.h"
#else #else
#include <sqlite3.h> #include <sqlite3.h>
#endif #endif
@ -472,10 +473,21 @@ func goVBestIndex(pVTab unsafe.Pointer, icp unsafe.Pointer) *C.char {
} }
info.idxNum = C.int(res.IdxNum) info.idxNum = C.int(res.IdxNum)
idxStr := C.CString(res.IdxStr) info.idxStr = (*C.char)(C.sqlite3_malloc(C.int(len(res.IdxStr) + 1)))
defer C.free(unsafe.Pointer(idxStr)) if info.idxStr == nil {
info.idxStr = idxStr // C.malloc and C.CString ordinarily do this for you. See https://golang.org/cmd/cgo/
info.needToFreeIdxStr = C.int(0) panic("out of memory")
}
info.needToFreeIdxStr = C.int(1)
idxStr := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(info.idxStr)),
Len: len(res.IdxStr) + 1,
Cap: len(res.IdxStr) + 1,
}))
copy(idxStr, res.IdxStr)
idxStr[len(idxStr)-1] = 0 // null-terminated string
if res.AlreadyOrdered { if res.AlreadyOrdered {
info.orderByConsumed = C.int(1) info.orderByConsumed = C.int(1)
} }
@ -505,7 +517,7 @@ func goMDestroy(pClientData unsafe.Pointer) {
func goVFilter(pCursor unsafe.Pointer, idxNum C.int, idxName *C.char, argc C.int, argv **C.sqlite3_value) *C.char { func goVFilter(pCursor unsafe.Pointer, idxNum C.int, idxName *C.char, argc C.int, argv **C.sqlite3_value) *C.char {
vtc := lookupHandle(pCursor).(*sqliteVTabCursor) vtc := lookupHandle(pCursor).(*sqliteVTabCursor)
args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:argc:argc] args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:argc:argc]
vals := make([]interface{}, 0, argc) vals := make([]any, 0, argc)
for _, v := range args { for _, v := range args {
conv, err := callbackArgGeneric(v) conv, err := callbackArgGeneric(v)
if err != nil { if err != nil {
@ -577,7 +589,7 @@ func goVUpdate(pVTab unsafe.Pointer, argc C.int, argv **C.sqlite3_value, pRowid
if v, ok := vt.vTab.(VTabUpdater); ok { if v, ok := vt.vTab.(VTabUpdater); ok {
// convert argv // convert argv
args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:argc:argc] args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:argc:argc]
vals := make([]interface{}, 0, argc) vals := make([]any, 0, argc)
for _, v := range args { for _, v := range args {
conv, err := callbackArgGeneric(v) conv, err := callbackArgGeneric(v)
if err != nil { if err != nil {
@ -651,9 +663,9 @@ type VTab interface {
// deleted. // deleted.
// See: https://sqlite.org/vtab.html#xupdate // See: https://sqlite.org/vtab.html#xupdate
type VTabUpdater interface { type VTabUpdater interface {
Delete(interface{}) error Delete(any) error
Insert(interface{}, []interface{}) (int64, error) Insert(any, []any) (int64, error)
Update(interface{}, []interface{}) error Update(any, []any) error
} }
// VTabCursor describes cursors that point into the virtual table and are used // VTabCursor describes cursors that point into the virtual table and are used
@ -662,7 +674,7 @@ type VTabCursor interface {
// http://sqlite.org/vtab.html#xclose // http://sqlite.org/vtab.html#xclose
Close() error Close() error
// http://sqlite.org/vtab.html#xfilter // http://sqlite.org/vtab.html#xfilter
Filter(idxNum int, idxStr string, vals []interface{}) error Filter(idxNum int, idxStr string, vals []any) error
// http://sqlite.org/vtab.html#xnext // http://sqlite.org/vtab.html#xnext
Next() error Next() error
// http://sqlite.org/vtab.html#xeof // http://sqlite.org/vtab.html#xeof

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !windows
// +build !windows // +build !windows
package sqlite3 package sqlite3

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build solaris
// +build solaris // +build solaris
package sqlite3 package sqlite3

View File

@ -3,13 +3,14 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build sqlite_trace || trace
// +build sqlite_trace trace // +build sqlite_trace trace
package sqlite3 package sqlite3
/* /*
#ifndef USE_LIBSQLITE3 #ifndef USE_LIBSQLITE3
#include <sqlite3-binding.h> #include "sqlite3-binding.h"
#else #else
#include <sqlite3.h> #include <sqlite3.h>
#endif #endif

View File

@ -1,5 +1,4 @@
// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
//
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
@ -7,15 +6,16 @@ package sqlite3
/* /*
#ifndef USE_LIBSQLITE3 #ifndef USE_LIBSQLITE3
#include <sqlite3-binding.h> #include "sqlite3-binding.h"
#else #else
#include <sqlite3.h> #include <sqlite3.h>
#endif #endif
*/ */
import "C" import "C"
import ( import (
"database/sql"
"reflect" "reflect"
"time" "strings"
) )
// ColumnTypeDatabaseTypeName implement RowsColumnTypeDatabaseTypeName. // ColumnTypeDatabaseTypeName implement RowsColumnTypeDatabaseTypeName.
@ -31,32 +31,78 @@ func (rc *SQLiteRows) ColumnTypeLength(index int) (length int64, ok bool) {
func (rc *SQLiteRows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) { func (rc *SQLiteRows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) {
return 0, 0, false return 0, 0, false
} }
*/
// ColumnTypeNullable implement RowsColumnTypeNullable. // ColumnTypeNullable implement RowsColumnTypeNullable.
func (rc *SQLiteRows) ColumnTypeNullable(i int) (nullable, ok bool) { func (rc *SQLiteRows) ColumnTypeNullable(i int) (nullable, ok bool) {
return false, false return true, true
} }
*/
// ColumnTypeScanType implement RowsColumnTypeScanType. // ColumnTypeScanType implement RowsColumnTypeScanType.
func (rc *SQLiteRows) ColumnTypeScanType(i int) reflect.Type { func (rc *SQLiteRows) ColumnTypeScanType(i int) reflect.Type {
switch C.sqlite3_column_type(rc.s.s, C.int(i)) { //ct := C.sqlite3_column_type(rc.s.s, C.int(i)) // Always returns 5
case C.SQLITE_INTEGER: return scanType(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i))))
switch C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i))) { }
case "timestamp", "datetime", "date":
return reflect.TypeOf(time.Time{}) const (
case "boolean": SQLITE_INTEGER = iota
return reflect.TypeOf(false) SQLITE_TEXT
} SQLITE_BLOB
return reflect.TypeOf(int64(0)) SQLITE_REAL
case C.SQLITE_FLOAT: SQLITE_NUMERIC
return reflect.TypeOf(float64(0)) SQLITE_TIME
case C.SQLITE_BLOB: SQLITE_BOOL
return reflect.SliceOf(reflect.TypeOf(byte(0))) SQLITE_NULL
case C.SQLITE_NULL: )
return reflect.TypeOf(nil)
case C.SQLITE_TEXT: func scanType(cdt string) reflect.Type {
return reflect.TypeOf("") t := strings.ToUpper(cdt)
} i := databaseTypeConvSqlite(t)
return reflect.SliceOf(reflect.TypeOf(byte(0))) switch i {
case SQLITE_INTEGER:
return reflect.TypeOf(sql.NullInt64{})
case SQLITE_TEXT:
return reflect.TypeOf(sql.NullString{})
case SQLITE_BLOB:
return reflect.TypeOf(sql.RawBytes{})
case SQLITE_REAL:
return reflect.TypeOf(sql.NullFloat64{})
case SQLITE_NUMERIC:
return reflect.TypeOf(sql.NullFloat64{})
case SQLITE_BOOL:
return reflect.TypeOf(sql.NullBool{})
case SQLITE_TIME:
return reflect.TypeOf(sql.NullTime{})
}
return reflect.TypeOf(new(any))
}
func databaseTypeConvSqlite(t string) int {
if strings.Contains(t, "INT") {
return SQLITE_INTEGER
}
if t == "CLOB" || t == "TEXT" ||
strings.Contains(t, "CHAR") {
return SQLITE_TEXT
}
if t == "BLOB" {
return SQLITE_BLOB
}
if t == "REAL" || t == "FLOAT" ||
strings.Contains(t, "DOUBLE") {
return SQLITE_REAL
}
if t == "DATE" || t == "DATETIME" ||
t == "TIMESTAMP" {
return SQLITE_TIME
}
if t == "NUMERIC" ||
strings.Contains(t, "DECIMAL") {
return SQLITE_NUMERIC
}
if t == "BOOLEAN" {
return SQLITE_BOOL
}
return SQLITE_NULL
} }

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build cgo
// +build cgo // +build cgo
package sqlite3 package sqlite3

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build windows
// +build windows // +build windows
package sqlite3 package sqlite3
@ -12,7 +13,6 @@ package sqlite3
#cgo CFLAGS: -fno-stack-check #cgo CFLAGS: -fno-stack-check
#cgo CFLAGS: -fno-stack-protector #cgo CFLAGS: -fno-stack-protector
#cgo CFLAGS: -mno-stack-arg-probe #cgo CFLAGS: -mno-stack-arg-probe
#cgo LDFLAGS: -lmingwex -lmingw32
#cgo windows,386 CFLAGS: -D_USE_32BIT_TIME_T #cgo windows,386 CFLAGS: -D_USE_32BIT_TIME_T
*/ */
import "C" import "C"

View File

@ -19,6 +19,10 @@
#ifndef SQLITE3EXT_H #ifndef SQLITE3EXT_H
#define SQLITE3EXT_H #define SQLITE3EXT_H
#include "sqlite3-binding.h" #include "sqlite3-binding.h"
#ifdef __clang__
#define assert(condition) ((void)0)
#endif
/* /*
** The following structure holds pointers to all of the SQLite API ** The following structure holds pointers to all of the SQLite API
@ -332,12 +336,41 @@ struct sqlite3_api_routines {
const char *(*filename_journal)(const char*); const char *(*filename_journal)(const char*);
const char *(*filename_wal)(const char*); const char *(*filename_wal)(const char*);
/* Version 3.32.0 and later */ /* Version 3.32.0 and later */
char *(*create_filename)(const char*,const char*,const char*, const char *(*create_filename)(const char*,const char*,const char*,
int,const char**); int,const char**);
void (*free_filename)(char*); void (*free_filename)(const char*);
sqlite3_file *(*database_file_object)(const char*); sqlite3_file *(*database_file_object)(const char*);
/* Version 3.34.0 and later */ /* Version 3.34.0 and later */
int (*txn_state)(sqlite3*,const char*); int (*txn_state)(sqlite3*,const char*);
/* Version 3.36.1 and later */
sqlite3_int64 (*changes64)(sqlite3*);
sqlite3_int64 (*total_changes64)(sqlite3*);
/* Version 3.37.0 and later */
int (*autovacuum_pages)(sqlite3*,
unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
void*, void(*)(void*));
/* Version 3.38.0 and later */
int (*error_offset)(sqlite3*);
int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**);
int (*vtab_distinct)(sqlite3_index_info*);
int (*vtab_in)(sqlite3_index_info*,int,int);
int (*vtab_in_first)(sqlite3_value*,sqlite3_value**);
int (*vtab_in_next)(sqlite3_value*,sqlite3_value**);
/* Version 3.39.0 and later */
int (*deserialize)(sqlite3*,const char*,unsigned char*,
sqlite3_int64,sqlite3_int64,unsigned);
unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*,
unsigned int);
const char *(*db_name)(sqlite3*,int);
/* Version 3.40.0 and later */
int (*value_encoding)(sqlite3_value*);
/* Version 3.41.0 and later */
int (*is_interrupted)(sqlite3*);
/* Version 3.43.0 and later */
int (*stmt_explain)(sqlite3_stmt*,int);
/* Version 3.44.0 and later */
void *(*get_clientdata)(sqlite3*,const char*);
int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*));
}; };
/* /*
@ -644,6 +677,33 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_database_file_object sqlite3_api->database_file_object #define sqlite3_database_file_object sqlite3_api->database_file_object
/* Version 3.34.0 and later */ /* Version 3.34.0 and later */
#define sqlite3_txn_state sqlite3_api->txn_state #define sqlite3_txn_state sqlite3_api->txn_state
/* Version 3.36.1 and later */
#define sqlite3_changes64 sqlite3_api->changes64
#define sqlite3_total_changes64 sqlite3_api->total_changes64
/* Version 3.37.0 and later */
#define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
/* Version 3.38.0 and later */
#define sqlite3_error_offset sqlite3_api->error_offset
#define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value
#define sqlite3_vtab_distinct sqlite3_api->vtab_distinct
#define sqlite3_vtab_in sqlite3_api->vtab_in
#define sqlite3_vtab_in_first sqlite3_api->vtab_in_first
#define sqlite3_vtab_in_next sqlite3_api->vtab_in_next
/* Version 3.39.0 and later */
#ifndef SQLITE_OMIT_DESERIALIZE
#define sqlite3_deserialize sqlite3_api->deserialize
#define sqlite3_serialize sqlite3_api->serialize
#endif
#define sqlite3_db_name sqlite3_api->db_name
/* Version 3.40.0 and later */
#define sqlite3_value_encoding sqlite3_api->value_encoding
/* Version 3.41.0 and later */
#define sqlite3_is_interrupted sqlite3_api->is_interrupted
/* Version 3.43.0 and later */
#define sqlite3_stmt_explain sqlite3_api->stmt_explain
/* Version 3.44.0 and later */
#define sqlite3_get_clientdata sqlite3_api->get_clientdata
#define sqlite3_set_clientdata sqlite3_api->set_clientdata
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)

View File

@ -3,6 +3,7 @@
// Use of this source code is governed by an MIT-style // Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !cgo
// +build !cgo // +build !cgo
package sqlite3 package sqlite3
@ -28,10 +29,10 @@ type (
) )
func (SQLiteDriver) Open(s string) (driver.Conn, error) { return nil, errorMsg } func (SQLiteDriver) Open(s string) (driver.Conn, error) { return nil, errorMsg }
func (c *SQLiteConn) RegisterAggregator(string, interface{}, bool) error { return errorMsg } func (c *SQLiteConn) RegisterAggregator(string, any, bool) error { return errorMsg }
func (c *SQLiteConn) RegisterAuthorizer(func(int, string, string, string) int) {} func (c *SQLiteConn) RegisterAuthorizer(func(int, string, string, string) int) {}
func (c *SQLiteConn) RegisterCollation(string, func(string, string) int) error { return errorMsg } func (c *SQLiteConn) RegisterCollation(string, func(string, string) int) error { return errorMsg }
func (c *SQLiteConn) RegisterCommitHook(func() int) {} func (c *SQLiteConn) RegisterCommitHook(func() int) {}
func (c *SQLiteConn) RegisterFunc(string, interface{}, bool) error { return errorMsg } func (c *SQLiteConn) RegisterFunc(string, any, bool) error { return errorMsg }
func (c *SQLiteConn) RegisterRollbackHook(func()) {} func (c *SQLiteConn) RegisterRollbackHook(func()) {}
func (c *SQLiteConn) RegisterUpdateHook(func(int, string, string, int64)) {} func (c *SQLiteConn) RegisterUpdateHook(func(int, string, string, int64)) {}

View File

@ -59,7 +59,7 @@ func (c CanonType) Parse(s string) (t Tag, err error) {
if changed { if changed {
tt.RemakeString() tt.RemakeString()
} }
return makeTag(tt), err return makeTag(tt), nil
} }
// Compose creates a Tag from individual parts, which may be of type Tag, Base, // Compose creates a Tag from individual parts, which may be of type Tag, Base,

16
vendor/modules.txt vendored
View File

@ -1,16 +1,16 @@
# github.com/mattn/go-sqlite3 v1.14.7 # github.com/mattn/go-sqlite3 v1.14.24
## explicit; go 1.12 ## explicit; go 1.19
github.com/mattn/go-sqlite3 github.com/mattn/go-sqlite3
# golang.org/x/net v0.36.0 # golang.org/x/net v0.37.0
## explicit; go 1.23 ## explicit; go 1.23.0
golang.org/x/net/html golang.org/x/net/html
golang.org/x/net/html/atom golang.org/x/net/html/atom
golang.org/x/net/html/charset golang.org/x/net/html/charset
# golang.org/x/sys v0.30.0 # golang.org/x/sys v0.31.0
## explicit; go 1.18 ## explicit; go 1.23.0
golang.org/x/sys/windows golang.org/x/sys/windows
# golang.org/x/text v0.22.0 # golang.org/x/text v0.23.0
## explicit; go 1.18 ## explicit; go 1.23.0
golang.org/x/text/encoding golang.org/x/text/encoding
golang.org/x/text/encoding/charmap golang.org/x/text/encoding/charmap
golang.org/x/text/encoding/htmlindex golang.org/x/text/encoding/htmlindex