mirror of
https://github.com/sbrow/envr.git
synced 2026-06-27 10:38:33 -04:00
feat: zig-sqlite.
This commit is contained in:
2
.envrc
2
.envrc
@@ -1,3 +1,3 @@
|
||||
use flake
|
||||
|
||||
export PATH=".:./deps/zig:./deps/zls:$PATH"
|
||||
export PATH=".:/home/spencer/github.com/envr-zig/deps/zig:/home/spencer/github.com/envr-zig/deps/zls:$PATH"
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -14,3 +14,4 @@ builds
|
||||
envr
|
||||
envr-go
|
||||
result
|
||||
zig-pkg
|
||||
|
||||
@@ -26,6 +26,11 @@ pub fn build(b: *std.Build) void {
|
||||
.target = target,
|
||||
});
|
||||
|
||||
const sqlite = b.dependency("sqlite", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
// This creates a module, which represents a collection of source files alongside
|
||||
// some compilation options, such as optimization mode and linked system libraries.
|
||||
// Zig modules are the preferred way of making Zig code available to consumers.
|
||||
@@ -49,6 +54,8 @@ pub fn build(b: *std.Build) void {
|
||||
},
|
||||
});
|
||||
|
||||
mod.addImport("sqlite", sqlite.module("sqlite"));
|
||||
|
||||
// Here we define an executable. An executable needs to have a root module
|
||||
// which needs to expose a `main` function. While we could add a main function
|
||||
// to the module defined above, it's sometimes preferable to split business
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
// Once all dependencies are fetched, `zig build` no longer requires
|
||||
// internet connectivity.
|
||||
.dependencies = .{
|
||||
.sqlite = .{ .path = "zig-vendor/zig-sqlite" },
|
||||
// See `zig fetch --save <url>` for a command-line interface for adding dependencies.
|
||||
//.example = .{
|
||||
// // When updating this field to a new URL, be sure to delete the corresponding
|
||||
|
||||
BIN
fixtures/example.db
Normal file
BIN
fixtures/example.db
Normal file
Binary file not shown.
26
src/db.zig
Normal file
26
src/db.zig
Normal file
@@ -0,0 +1,26 @@
|
||||
const std = @import("std");
|
||||
const sqlite = @import("sqlite");
|
||||
|
||||
test "simple database can be opened" {
|
||||
var db = try sqlite.Db.init(.{
|
||||
.mode = sqlite.Db.Mode{ .File = "./fixtures/example.db" },
|
||||
.open_flags = .{
|
||||
.write = false,
|
||||
.create = false,
|
||||
},
|
||||
.threading_mode = .MultiThread,
|
||||
});
|
||||
|
||||
var stmt = try db.prepare("SELECT * FROM hello");
|
||||
defer stmt.deinit();
|
||||
|
||||
const alloc = std.testing.allocator;
|
||||
|
||||
if (try stmt.oneAlloc(struct { text: []const u8 }, alloc, .{}, .{})) |got| {
|
||||
defer alloc.free(got.text);
|
||||
|
||||
try std.testing.expectEqualSlices(u8, "world!", got.text);
|
||||
} else {
|
||||
return error.TestUnexpectedResult;
|
||||
}
|
||||
}
|
||||
@@ -56,6 +56,10 @@ pub const root: Command = .new(.{
|
||||
},
|
||||
});
|
||||
|
||||
test {
|
||||
std.testing.refAllDecls(@import("db.zig"));
|
||||
}
|
||||
|
||||
test "enum type" {
|
||||
const got: root.Type = @enumFromInt(2);
|
||||
|
||||
|
||||
1
zig-vendor/zig-sqlite/.dockerignore
Normal file
1
zig-vendor/zig-sqlite/.dockerignore
Normal file
@@ -0,0 +1 @@
|
||||
/zig-cache
|
||||
4
zig-vendor/zig-sqlite/.gitattributes
vendored
Normal file
4
zig-vendor/zig-sqlite/.gitattributes
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
c/sqlite3.c linguist-vendored
|
||||
c/sqlite3.h linguist-vendored
|
||||
zig.mod linguist-vendored
|
||||
*.zig text=auto eol=lf
|
||||
44
zig-vendor/zig-sqlite/.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
44
zig-vendor/zig-sqlite/.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
name: Bug report
|
||||
description: Create a bug report
|
||||
labels:
|
||||
- bug
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
# A bug means something doesn't work as expected
|
||||
Remember to include as much detail as possible.
|
||||
|
||||
- type: input
|
||||
id: commit
|
||||
attributes:
|
||||
label: zig-sqlite commit
|
||||
description: "The git commit of zig-sqlite"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: zig_version
|
||||
attributes:
|
||||
label: Zig version
|
||||
description: "The output of `zig version`"
|
||||
placeholder: "0.11.0-dev.3335+3085e2af4"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: repro
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: How can someone reproduce the problem you encountered ? Include a self-contained reproducer if possible
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: expected
|
||||
attributes:
|
||||
label: Expected behaviour
|
||||
description: What did you expect to happen?
|
||||
validations:
|
||||
required: true
|
||||
6
zig-vendor/zig-sqlite/.github/pull_request_template.md
vendored
Normal file
6
zig-vendor/zig-sqlite/.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
# Description
|
||||
|
||||
Please describe the changes you want to make and why. Please also provide an explanation of the implementation.
|
||||
As a rule of thumb, give as much detail as you would want to see if you were to review this PR.
|
||||
|
||||
If this PR closes an issue, please reference it with something like "Closes #issue".
|
||||
62
zig-vendor/zig-sqlite/.github/workflows/main.yml
vendored
Normal file
62
zig-vendor/zig-sqlite/.github/workflows/main.yml
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
create:
|
||||
push:
|
||||
branches: master
|
||||
paths:
|
||||
- '**.zig'
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: "0 13 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ci-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: master
|
||||
- run: zig fmt --check *.zig
|
||||
|
||||
test-in-memory:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-24.04, windows-latest, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup zig
|
||||
uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: master
|
||||
|
||||
- name: Install qemu
|
||||
if: ${{ matrix.os == 'ubuntu-24.04' }}
|
||||
run: |
|
||||
sudo apt-get update -y && sudo apt-get install -y qemu-user-binfmt
|
||||
|
||||
- name: Restore cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
zig-cache
|
||||
~/.cache/zig
|
||||
key: ${{ runner.os }}-${{ matrix.os }}-zig-${{ github.sha }}
|
||||
restore-keys: ${{ runner.os }}-${{ matrix.os }}-zig-
|
||||
|
||||
- name: Run Tests in memory
|
||||
if: ${{ matrix.os == 'ubuntu-24.04' }}
|
||||
run: zig build test -Dci=true -Din_memory=true --summary all -fqemu -fwine
|
||||
- name: Run Tests in memory
|
||||
if: ${{ matrix.os != 'ubuntu-24.04' }}
|
||||
run: zig build test -Dci=true -Din_memory=true --summary all
|
||||
8
zig-vendor/zig-sqlite/.gitignore
vendored
Normal file
8
zig-vendor/zig-sqlite/.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/build_runner.zig
|
||||
/.zig-cache
|
||||
zig-out
|
||||
.zigmod
|
||||
deps.zig
|
||||
core.*
|
||||
/qemu*.core
|
||||
/fuzz/outputs
|
||||
21
zig-vendor/zig-sqlite/LICENSE
Normal file
21
zig-vendor/zig-sqlite/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Vincent Rischmann <vincent@rischmann.fr>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
652
zig-vendor/zig-sqlite/README.md
Normal file
652
zig-vendor/zig-sqlite/README.md
Normal file
@@ -0,0 +1,652 @@
|
||||
# zig-sqlite
|
||||
|
||||
This package is a thin wrapper around [sqlite](https://sqlite.org/index.html)'s C API.
|
||||
|
||||
_Maintainer note_: I'm currently on a break working with Zig and don't intend to work on new features for zig-sqlite.
|
||||
I will keep it updated for the latest Zig versions because that doesn't take too much of my time.
|
||||
|
||||
# Status
|
||||
|
||||
While the core functionality works right now, the API is still subject to changes.
|
||||
|
||||
If you use this library, expect to have to make changes when you update the code.
|
||||
|
||||
# Zig release support
|
||||
|
||||
`zig-sqlite` follows Zig's release structure:
|
||||
- [master](https://github.com/vrischmann/zig-sqlite) tracks Zig master
|
||||
- [zig-0.15.1](https://github.com/vrischmann/zig-sqlite/tree/zig-0.15.1) tracks Zig 0.15.1
|
||||
|
||||
The plan is to support releases once Zig 1.0 is released but this can still change.
|
||||
|
||||
# Table of contents
|
||||
|
||||
<!--toc:start-->
|
||||
- [zig-sqlite](#zig-sqlite)
|
||||
- [Status](#status)
|
||||
- [Zig release support](#zig-release-support)
|
||||
- [Table of contents](#table-of-contents)
|
||||
- [Requirements](#requirements)
|
||||
- [Features](#features)
|
||||
- [Installation](#installation)
|
||||
- [Usage](#usage)
|
||||
- [Demo](#demo)
|
||||
- [Initialization](#initialization)
|
||||
- [Preparing a statement](#preparing-a-statement)
|
||||
- [Common use](#common-use)
|
||||
- [Diagnostics](#diagnostics)
|
||||
- [Executing a statement](#executing-a-statement)
|
||||
- [Reuse a statement](#reuse-a-statement)
|
||||
- [Reading data in one go](#reading-data-in-one-go)
|
||||
- [Type parameter](#type-parameter)
|
||||
- [`Statement.one`](#statementone)
|
||||
- [`Statement.all` and `Statement.oneAlloc`](#statementall-and-statementonealloc)
|
||||
- [Iterating](#iterating)
|
||||
- [`Iterator.next`](#iteratornext)
|
||||
- [`Iterator.nextAlloc`](#iteratornextalloc)
|
||||
- [Bind parameters and resultset rows](#bind-parameters-and-resultset-rows)
|
||||
- [Custom type binding and reading](#custom-type-binding-and-reading)
|
||||
- [Note about complex allocations](#note-about-complex-allocations)
|
||||
- [Comptime checks](#comptime-checks)
|
||||
- [Check the number of bind parameters.](#check-the-number-of-bind-parameters)
|
||||
- [Assign types to bind markers and check them.](#assign-types-to-bind-markers-and-check-them)
|
||||
- [User defined SQL functions](#user-defined-sql-functions)
|
||||
- [Scalar functions](#scalar-functions)
|
||||
- [Aggregate functions](#aggregate-functions)
|
||||
<!--toc:end-->
|
||||
|
||||
# Requirements
|
||||
|
||||
[Zig master](https://ziglang.org/download/) is the only required dependency.
|
||||
|
||||
For sqlite, you have options depending on your target:
|
||||
* On Windows the only supported way at the moment to build `zig-sqlite` is with the bundled sqlite source code file.
|
||||
* On Linux we have two options:
|
||||
* use the system and development package for sqlite (`libsqlite3-dev` for Debian and derivatives, `sqlite3-devel` for Fedora)
|
||||
* use the bundled sqlite source code file.
|
||||
|
||||
# Features
|
||||
|
||||
* Preparing, executing statements
|
||||
* comptime checked bind parameters
|
||||
* user defined SQL functions
|
||||
|
||||
# Installation
|
||||
|
||||
Use the following `zig fetch` command:
|
||||
|
||||
```
|
||||
zig fetch --save git+https://github.com/vrischmann/zig-sqlite
|
||||
```
|
||||
|
||||
Now in your `build.zig` you can access the module like this:
|
||||
```zig
|
||||
const sqlite = b.dependency("sqlite", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
exe.root_module.addImport("sqlite", sqlite.module("sqlite"));
|
||||
```
|
||||
|
||||
# Usage
|
||||
|
||||
## Demo
|
||||
|
||||
See https://github.com/vrischmann/zig-sqlite-demo for a quick demo.
|
||||
|
||||
## Initialization
|
||||
|
||||
Import `zig-sqlite` like this:
|
||||
|
||||
```zig
|
||||
const sqlite = @import("sqlite");
|
||||
```
|
||||
|
||||
You must create and initialize an instance of `sqlite.Db`:
|
||||
|
||||
```zig
|
||||
var db = try sqlite.Db.init(.{
|
||||
.mode = sqlite.Db.Mode{ .File = "/home/vincent/mydata.db" },
|
||||
.open_flags = .{
|
||||
.write = true,
|
||||
.create = true,
|
||||
},
|
||||
.threading_mode = .MultiThread,
|
||||
});
|
||||
```
|
||||
|
||||
The `init` method takes a `InitOptions` struct which will be used to configure sqlite.
|
||||
|
||||
Only the `mode` field is mandatory, the other fields have sane default values.
|
||||
|
||||
## Preparing a statement
|
||||
|
||||
### Common use
|
||||
|
||||
sqlite works exclusively by using prepared statements. The wrapper type is `sqlite.Statement`. Here is how you get one:
|
||||
|
||||
```zig
|
||||
try db.exec("CREATE TABLE IF NOT EXISTS employees(id integer primary key, name text, age integer, salary integer)", .{}, .{});
|
||||
|
||||
const query =
|
||||
\\SELECT id, name, age, salary FROM employees WHERE age > ? AND age < ?
|
||||
;
|
||||
|
||||
var stmt = try db.prepare(query);
|
||||
defer stmt.deinit();
|
||||
```
|
||||
|
||||
The `Db.prepare` method takes a `comptime` query string.
|
||||
|
||||
### Diagnostics
|
||||
|
||||
If you want failure diagnostics you can use `prepareWithDiags` like this:
|
||||
|
||||
```zig
|
||||
var diags = sqlite.Diagnostics{};
|
||||
var stmt = db.prepareWithDiags(query, .{ .diags = &diags }) catch |err| {
|
||||
std.log.err("unable to prepare statement, got error {}. diagnostics: {s}", .{ err, diags });
|
||||
return err;
|
||||
};
|
||||
defer stmt.deinit();
|
||||
```
|
||||
|
||||
## Executing a statement
|
||||
|
||||
For queries which do not return data (`INSERT`, `UPDATE`) you can use the `exec` method:
|
||||
|
||||
```zig
|
||||
const query =
|
||||
\\INSERT INTO employees(name, age, salary) VALUES(?, ?, ?)
|
||||
;
|
||||
|
||||
var stmt = try db.prepare(query);
|
||||
defer stmt.deinit();
|
||||
|
||||
try stmt.exec(.{}, .{
|
||||
.name = "José",
|
||||
.age = 40,
|
||||
.salary = 20000,
|
||||
});
|
||||
```
|
||||
|
||||
See the section "Bind parameters and resultset rows" for more information on the types mapping rules.
|
||||
|
||||
## Reuse a statement
|
||||
|
||||
You can reuse a statement by resetting it like this:
|
||||
```zig
|
||||
const query =
|
||||
\\UPDATE employees SET salary = ? WHERE id = ?
|
||||
;
|
||||
|
||||
var stmt = try db.prepare(query);
|
||||
defer stmt.deinit();
|
||||
|
||||
var id: usize = 0;
|
||||
while (id < 20) : (id += 1) {
|
||||
stmt.reset();
|
||||
try stmt.exec(.{}, .{
|
||||
.salary = 2000,
|
||||
.id = id,
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
## Reading data in one go
|
||||
|
||||
For queries which return data you have multiple options:
|
||||
* `Statement.all` which takes an allocator and can allocate memory.
|
||||
* `Statement.one` which does not take an allocator and cannot allocate memory (aside from what sqlite allocates itself).
|
||||
* `Statement.oneAlloc` which takes an allocator and can allocate memory.
|
||||
|
||||
### Type parameter
|
||||
|
||||
All these methods take a type as first parameter.
|
||||
|
||||
The type represents a "row", it can be:
|
||||
* a struct where each field maps to the corresponding column in the resultset (so field 0 must map to column 1 and so on).
|
||||
* a single type, in that case the resultset must only return one column.
|
||||
|
||||
The type can be a pointer but only when using the methods taking an allocator.
|
||||
|
||||
Not all types are allowed, see the section "Bind parameters and resultset rows" for more information on the types mapping rules.
|
||||
|
||||
### `Statement.one`
|
||||
|
||||
Using `one`:
|
||||
|
||||
```zig
|
||||
const query =
|
||||
\\SELECT name, age FROM employees WHERE id = ?
|
||||
;
|
||||
|
||||
var stmt = try db.prepare(query);
|
||||
defer stmt.deinit();
|
||||
|
||||
const row = try stmt.one(
|
||||
struct {
|
||||
name: [128:0]u8,
|
||||
age: usize,
|
||||
},
|
||||
.{},
|
||||
.{ .id = 20 },
|
||||
);
|
||||
if (row) |r| {
|
||||
const name_ptr: [*:0]const u8 = &r.name;
|
||||
std.log.debug("name: {s}, age: {}", .{ std.mem.span(name_ptr), r.age });
|
||||
}
|
||||
```
|
||||
Notice that to read text we need to use a 0-terminated array; if the `name` column is bigger than 127 bytes the call to `one` will fail.
|
||||
|
||||
If the length of the data is variable then the sentinel is mandatory: without one there would be no way to know where the data ends in the array.
|
||||
|
||||
However if the length is fixed, you can read into a non 0-terminated array, for example:
|
||||
|
||||
```zig
|
||||
const query =
|
||||
\\SELECT id FROM employees WHERE name = ?
|
||||
;
|
||||
|
||||
var stmt = try db.prepare(query);
|
||||
defer stmt.deinit();
|
||||
|
||||
const row = try stmt.one(
|
||||
[16]u8,
|
||||
.{},
|
||||
.{ .name = "Vincent" },
|
||||
);
|
||||
if (row) |id| {
|
||||
std.log.debug("id: {s}", .{std.fmt.fmtSliceHexLower(&id)});
|
||||
}
|
||||
```
|
||||
|
||||
If the column data doesn't have the correct length a `error.ArraySizeMismatch` will be returned.
|
||||
|
||||
The convenience function `sqlite.Db.one` works exactly the same way:
|
||||
|
||||
```zig
|
||||
const query =
|
||||
\\SELECT age FROM employees WHERE id = ?
|
||||
;
|
||||
|
||||
const row = try db.one(usize, query, .{}, .{ .id = 20 });
|
||||
if (row) |age| {
|
||||
std.log.debug("age: {}", .{age});
|
||||
}
|
||||
```
|
||||
|
||||
### `Statement.all` and `Statement.oneAlloc`
|
||||
|
||||
Using `all`:
|
||||
|
||||
```zig
|
||||
const query =
|
||||
\\SELECT name FROM employees WHERE age > ? AND age < ?
|
||||
;
|
||||
|
||||
var stmt = try db.prepare(query);
|
||||
defer stmt.deinit();
|
||||
|
||||
const allocator = std.heap.page_allocator; // Use a suitable allocator
|
||||
|
||||
const names = try stmt.all([]const u8, allocator, .{}, .{
|
||||
.age1 = 20,
|
||||
.age2 = 40,
|
||||
});
|
||||
for (names) |name| {
|
||||
std.log.debug("name: {s}", .{ name });
|
||||
}
|
||||
```
|
||||
|
||||
Using `oneAlloc`:
|
||||
|
||||
```zig
|
||||
const query =
|
||||
\\SELECT name FROM employees WHERE id = ?
|
||||
;
|
||||
|
||||
var stmt = try db.prepare(query);
|
||||
defer stmt.deinit();
|
||||
|
||||
const allocator = std.heap.page_allocator; // Use a suitable allocator
|
||||
|
||||
const row = try stmt.oneAlloc([]const u8, allocator, .{}, .{
|
||||
.id = 200,
|
||||
});
|
||||
if (row) |name| {
|
||||
std.log.debug("name: {s}", .{name});
|
||||
}
|
||||
```
|
||||
|
||||
## Iterating
|
||||
|
||||
Another way to get the data returned by a query is to use the `sqlite.Iterator` type.
|
||||
|
||||
You can only get one by calling the `iterator` method on a statement.
|
||||
|
||||
The `iterator` method takes a type which is the same as with `all`, `one` or `oneAlloc`: every row retrieved by calling `next` or `nextAlloc` will have this type.
|
||||
|
||||
Iterating is done by calling the `next` or `nextAlloc` method on an iterator. Just like before, `next` cannot allocate memory while `nextAlloc` can allocate memory.
|
||||
|
||||
`next` or `nextAlloc` will either return an optional value or an error; you should keep iterating until `null` is returned.
|
||||
|
||||
### `Iterator.next`
|
||||
|
||||
```zig
|
||||
var stmt = try db.prepare("SELECT age FROM employees WHERE age < ?");
|
||||
defer stmt.deinit();
|
||||
|
||||
var iter = try stmt.iterator(usize, .{
|
||||
.age = 20,
|
||||
});
|
||||
|
||||
while (try iter.next(.{})) |age| {
|
||||
std.debug.print("age: {}\n", .{age});
|
||||
}
|
||||
```
|
||||
|
||||
### `Iterator.nextAlloc`
|
||||
|
||||
```zig
|
||||
var stmt = try db.prepare("SELECT name FROM employees WHERE age < ?");
|
||||
defer stmt.deinit();
|
||||
|
||||
var iter = try stmt.iterator([]const u8, .{
|
||||
.age = 20,
|
||||
});
|
||||
|
||||
const allocator = std.heap.page_allocator; // Use a suitable allocator
|
||||
|
||||
while (true) {
|
||||
var arena = std.heap.ArenaAllocator.init(allocator);
|
||||
defer arena.deinit();
|
||||
|
||||
const name = (try iter.nextAlloc(arena.allocator(), .{})) orelse break;
|
||||
std.debug.print("name: {s}\n", .{name});
|
||||
}
|
||||
```
|
||||
|
||||
## Bind parameters and resultset rows
|
||||
|
||||
Since sqlite doesn't have many [types](https://www.sqlite.org/datatype3.html) only a small number of Zig types are allowed in binding parameters and in resultset mapping types.
|
||||
|
||||
Here are the rules for bind parameters:
|
||||
* any Zig `Int` or `ComptimeInt` is treated as a `INTEGER`.
|
||||
* any Zig `Float` or `ComptimeFloat` is treated as a `REAL`.
|
||||
* `[]const u8`, `[]u8` is treated as a `TEXT`.
|
||||
* the custom `sqlite.Blob` type is treated as a `BLOB`.
|
||||
* the custom `sqlite.Text` type is treated as a `TEXT`.
|
||||
* the `null` value is treated as a `NULL`.
|
||||
* non-null optionals are treated like a regular value, null optionals are treated as a `NULL`.
|
||||
|
||||
Here are the rules for resultset rows:
|
||||
* `INTEGER` can be read into any Zig `Int` provided the data fits.
|
||||
* `REAL` can be read into any Zig `Float` provided the data fits.
|
||||
* `TEXT` can be read into a `[]const u8` or `[]u8`.
|
||||
* `TEXT` can be read into any array of `u8` with a sentinel provided the data fits.
|
||||
* `BLOB` follows the same rules as `TEXT`.
|
||||
* `NULL` can be read into any optional.
|
||||
|
||||
Note that arrays must have a sentinel because we need a way to communicate where the data actually stops in the array, so for example use `[200:0]u8` for a `TEXT` field.
|
||||
|
||||
## Custom type binding and reading
|
||||
|
||||
Sometimes the default field binding or reading logic is not what you want, for example if you want to store an enum using its tag name instead of its integer value or
|
||||
if you want to store a byte slice as an hex string.
|
||||
|
||||
To accomplish this you must first define a wrapper struct for your type. For example if your type is a `[4]u8` and you want to treat it as an integer:
|
||||
```zig
|
||||
pub const MyArray = struct {
|
||||
data: [4]u8,
|
||||
|
||||
pub const BaseType = u32;
|
||||
|
||||
pub fn bindField(self: MyArray, _: std.mem.Allocator) !BaseType {
|
||||
return std.mem.readIntNative(BaseType, &self.data);
|
||||
}
|
||||
|
||||
pub fn readField(_: std.mem.Allocator, value: BaseType) !MyArray {
|
||||
var arr: MyArray = undefined;
|
||||
std.mem.writeIntNative(BaseType, &arr.data, value);
|
||||
return arr;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
Now when you bind a value of type `MyArray` the value returned by `bindField` will be used for binding instead.
|
||||
|
||||
Same for reading, when you select _into_ a `MyArray` row or field the value returned by `readField` will be used instead.
|
||||
|
||||
_NOTE_: when you _do_ allocate in `bindField` or `readField` make sure to pass a `std.heap.ArenaAllocator`-based allocator.
|
||||
|
||||
The binding or reading code does not keep tracking of allocations made in custom types so it can't free the allocated data itself; it's therefore required
|
||||
to use an arena to prevent memory leaks.
|
||||
|
||||
## Note about complex allocations
|
||||
|
||||
Depending on your queries and types there can be a lot of allocations required. Take the following example:
|
||||
```zig
|
||||
const User = struct {
|
||||
id: usize,
|
||||
first_name: []const u8,
|
||||
last_name: []const u8,
|
||||
data: []const u8,
|
||||
};
|
||||
|
||||
fn fetchUsers(allocator: std.mem.Allocator, db: *sqlite.Db) ![]User {
|
||||
var stmt = try db.prepare("SELECT id FROM user WHERE id > $id");
|
||||
defer stmt.deinit();
|
||||
|
||||
return stmt.all(User, allocator, .{}, .{ .id = 20 });
|
||||
}
|
||||
```
|
||||
|
||||
This will do multiple allocations:
|
||||
* one for each id field in the `User` type
|
||||
* one for the resulting slice
|
||||
|
||||
To facilitate memory handling, consider using an arena allocator like this:
|
||||
```zig
|
||||
const allocator = std.heap.page_allocator; // Use a suitable allocator
|
||||
|
||||
var arena = std.heap.ArenaAllocator.init(allocator);
|
||||
defer arena.deinit();
|
||||
|
||||
const users = try fetchUsers(arena.allocator(), db);
|
||||
_ = users;
|
||||
```
|
||||
|
||||
This is especially recommended if you use custom types that allocate memory since, as noted above, it's necessary to prevent memory leaks.
|
||||
|
||||
# Comptime checks
|
||||
|
||||
Prepared statements contain _comptime_ metadata which is used to validate every call to `exec`, `one` and `all` _at compile time_.
|
||||
|
||||
## Check the number of bind parameters.
|
||||
|
||||
The first check makes sure you provide the same number of bind parameters as there are bind markers in the query string.
|
||||
|
||||
Take the following code:
|
||||
```zig
|
||||
var stmt = try db.prepare("SELECT id FROM user WHERE age > ? AND age < ? AND weight > ?");
|
||||
defer stmt.deinit();
|
||||
|
||||
const allocator = std.heap.page_allocator; // Use a suitable allocator
|
||||
|
||||
const rows = try stmt.all(usize, allocator, .{}, .{
|
||||
.age_1 = 10,
|
||||
.age_2 = 20,
|
||||
});
|
||||
_ = rows;
|
||||
```
|
||||
It fails with this compilation error:
|
||||
```
|
||||
/home/vincent/dev/perso/libs/zig-sqlite/sqlite.zig:738:17: error: number of bind markers not equal to number of fields
|
||||
@compileError("number of bind markers not equal to number of fields");
|
||||
^
|
||||
/home/vincent/dev/perso/libs/zig-sqlite/sqlite.zig:817:22: note: called from here
|
||||
self.bind(values);
|
||||
^
|
||||
/home/vincent/dev/perso/libs/zig-sqlite/sqlite.zig:905:41: note: called from here
|
||||
var iter = try self.iterator(Type, values);
|
||||
^
|
||||
./src/main.zig:19:30: note: called from here
|
||||
const rows = try stmt.all(usize, allocator, .{}, .{
|
||||
^
|
||||
./src/main.zig:5:29: note: called from here
|
||||
pub fn main() anyerror!void {
|
||||
```
|
||||
|
||||
## Assign types to bind markers and check them.
|
||||
|
||||
The second (and more interesting) check makes sure you provide appropriately typed values as bind parameters.
|
||||
|
||||
This check is not automatic since with a standard SQL query we have no way to know the types of the bind parameters, to use it you must provide theses types in the SQL query with a custom syntax.
|
||||
|
||||
For example, take the same code as above but now we also bind the last parameter:
|
||||
```zig
|
||||
var stmt = try db.prepare("SELECT id FROM user WHERE age > ? AND age < ? AND weight > ?");
|
||||
defer stmt.deinit();
|
||||
|
||||
const allocator = std.heap.page_allocator; // Use a suitable allocator
|
||||
|
||||
const rows = try stmt.all(usize, allocator, .{}, .{
|
||||
.age_1 = 10,
|
||||
.age_2 = 20,
|
||||
.weight = false,
|
||||
});
|
||||
_ = rows;
|
||||
```
|
||||
|
||||
This compiles correctly even if the `weight` field in our `user` table is of the type `INTEGER`.
|
||||
|
||||
We can make sure the bind parameters have the right type if we rewrite the query like this:
|
||||
```zig
|
||||
var stmt = try db.prepare("SELECT id FROM user WHERE age > ? AND age < ? AND weight > ?{usize}");
|
||||
defer stmt.deinit();
|
||||
|
||||
const allocator = std.heap.page_allocator; // Use a suitable allocator
|
||||
|
||||
const rows = try stmt.all(usize, allocator, .{}, .{
|
||||
.age_1 = 10,
|
||||
.age_2 = 20,
|
||||
.weight = false,
|
||||
});
|
||||
_ = rows;
|
||||
```
|
||||
Now this fails to compile:
|
||||
```
|
||||
/home/vincent/dev/perso/libs/zig-sqlite/sqlite.zig:745:25: error: value type bool is not the bind marker type usize
|
||||
@compileError("value type " ++ @typeName(struct_field.field_type) ++ " is not the bind marker type " ++ @typeName(typ));
|
||||
^
|
||||
/home/vincent/dev/perso/libs/zig-sqlite/sqlite.zig:817:22: note: called from here
|
||||
self.bind(values);
|
||||
^
|
||||
/home/vincent/dev/perso/libs/zig-sqlite/sqlite.zig:905:41: note: called from here
|
||||
var iter = try self.iterator(Type, values);
|
||||
^
|
||||
./src/main.zig:19:30: note: called from here
|
||||
const rows = try stmt.all(usize, allocator, .{}, .{
|
||||
^
|
||||
./src/main.zig:5:29: note: called from here
|
||||
pub fn main() anyerror!void {
|
||||
```
|
||||
The syntax is straightforward: a bind marker `?` followed by `{`, a Zig type name and finally `}`.
|
||||
|
||||
There are a limited number of types allowed currently:
|
||||
* all [integer](https://ziglang.org/documentation/master/#Primitive-Types) types.
|
||||
* all [arbitrary bit-width integer](https://ziglang.org/documentation/master/#Primitive-Types) types.
|
||||
* all [float](https://ziglang.org/documentation/master/#Primitive-Types) types.
|
||||
* bool.
|
||||
* strings with `[]const u8` or `[]u8`.
|
||||
* strings with `sqlite.Text`.
|
||||
* blobs with `sqlite.Blob`.
|
||||
|
||||
It is probably possible to support arbitrary types if they can be marshaled to an SQLite type. This is something to investigate.
|
||||
|
||||
**NOTE**: this is done at compile time and is quite CPU intensive, therefore it's possible you'll have to play with [@setEvalBranchQuota](https://ziglang.org/documentation/master/#setEvalBranchQuota) to make it compile.
|
||||
|
||||
To finish our example, passing the proper type allows it compile:
|
||||
```zig
|
||||
var stmt = try db.prepare("SELECT id FROM user WHERE age > ? AND age < ? AND weight > ?{usize}");
|
||||
defer stmt.deinit();
|
||||
|
||||
const allocator = std.heap.page_allocator; // Use a suitable allocator
|
||||
|
||||
const rows = try stmt.all(usize, allocator, .{}, .{
|
||||
.age_1 = 10,
|
||||
.age_2 = 20,
|
||||
.weight = @as(usize, 200),
|
||||
});
|
||||
_ = rows;
|
||||
```
|
||||
|
||||
# User defined SQL functions
|
||||
|
||||
sqlite supports [user-defined SQL functions](https://www.sqlite.org/c3ref/create_function.html) which come in two types:
|
||||
* scalar functions
|
||||
* aggregate functions
|
||||
|
||||
In both cases the arguments are [sqlite3\_values](https://www.sqlite.org/c3ref/value_blob.html) and are converted to Zig values using the following rules:
|
||||
* `TEXT` values can be either `sqlite.Text` or `[]const u8`
|
||||
* `BLOB` values can be either `sqlite.Blob` or `[]const u8`
|
||||
* `INTEGER` values can be any Zig integer
|
||||
* `REAL` values can be any Zig float
|
||||
|
||||
## Scalar functions
|
||||
|
||||
You can define a scalar function using `db.createScalarFunction`:
|
||||
```zig
|
||||
try db.createScalarFunction(
|
||||
"blake3",
|
||||
struct {
|
||||
fn run(input: []const u8) [std.crypto.hash.Blake3.digest_length]u8 {
|
||||
var hash: [std.crypto.hash.Blake3.digest_length]u8 = undefined;
|
||||
std.crypto.hash.Blake3.hash(input, &hash, .{});
|
||||
return hash;
|
||||
}
|
||||
}.run,
|
||||
.{},
|
||||
);
|
||||
|
||||
const hash = try db.one([std.crypto.hash.Blake3.digest_length]u8, "SELECT blake3('hello')", .{}, .{});
|
||||
```
|
||||
|
||||
Each input arguments in the function call in the statement is passed on to the registered `run` function.
|
||||
|
||||
## Aggregate functions
|
||||
|
||||
You can define an aggregate function using `db.createAggregateFunction`:
|
||||
```zig
|
||||
const MyContext = struct {
|
||||
sum: u32,
|
||||
};
|
||||
var my_ctx = MyContext{ .sum = 0 };
|
||||
|
||||
try db.createAggregateFunction(
|
||||
"mySum",
|
||||
&my_ctx,
|
||||
struct {
|
||||
fn step(fctx: sqlite.FunctionContext, input: u32) void {
|
||||
var ctx = fctx.userContext(*MyContext) orelse return;
|
||||
ctx.sum += input;
|
||||
}
|
||||
}.step,
|
||||
struct {
|
||||
fn finalize(fctx: sqlite.FunctionContext) u32 {
|
||||
const ctx = fctx.userContext(*MyContext) orelse return 0;
|
||||
return ctx.sum;
|
||||
}
|
||||
}.finalize,
|
||||
.{},
|
||||
);
|
||||
|
||||
const result = try db.one(usize, "SELECT mySum(nb) FROM foobar", .{}, .{});
|
||||
```
|
||||
|
||||
Each input arguments in the function call in the statement is passed on to the registered `step` function.
|
||||
The `finalize` function is called once at the end.
|
||||
|
||||
The context (2nd argument of `createAggregateFunction`) can be whatever you want; both the `step` and `finalize` functions must
|
||||
have their first argument of the same type as the context.
|
||||
382
zig-vendor/zig-sqlite/build.zig
Normal file
382
zig-vendor/zig-sqlite/build.zig
Normal file
@@ -0,0 +1,382 @@
|
||||
const std = @import("std");
|
||||
const debug = std.debug;
|
||||
const heap = std.heap;
|
||||
const mem = std.mem;
|
||||
const ResolvedTarget = std.Build.ResolvedTarget;
|
||||
const Query = std.Target.Query;
|
||||
const builtin = @import("builtin");
|
||||
|
||||
const Preprocessor = @import("build/Preprocessor.zig");
|
||||
|
||||
fn getTarget(original_target: ResolvedTarget) ResolvedTarget {
|
||||
var tmp = original_target;
|
||||
|
||||
if (tmp.result.isGnuLibC()) {
|
||||
const min_glibc_version = std.SemanticVersion{
|
||||
.major = 2,
|
||||
.minor = 28,
|
||||
.patch = 0,
|
||||
};
|
||||
const ver = tmp.result.os.version_range.linux.glibc;
|
||||
if (ver.order(min_glibc_version) == .lt) {
|
||||
std.debug.panic("sqlite requires glibc version >= 2.28", .{});
|
||||
}
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
const TestTarget = struct {
|
||||
query: Query,
|
||||
single_threaded: bool = false,
|
||||
};
|
||||
|
||||
const ci_targets = switch (builtin.target.cpu.arch) {
|
||||
.x86_64 => switch (builtin.target.os.tag) {
|
||||
.linux => [_]TestTarget{
|
||||
TestTarget{ .query = .{ .cpu_arch = .x86_64, .abi = .musl } },
|
||||
TestTarget{ .query = .{ .cpu_arch = .x86, .abi = .musl } },
|
||||
TestTarget{ .query = .{ .cpu_arch = .aarch64, .abi = .musl } },
|
||||
},
|
||||
.windows => [_]TestTarget{
|
||||
TestTarget{ .query = .{ .cpu_arch = .x86_64, .abi = .gnu } },
|
||||
// Disabled due to https://github.com/ziglang/zig/issues/20047
|
||||
// TestTarget{ .query = .{ .cpu_arch = .x86, .abi = .gnu } },
|
||||
},
|
||||
.macos => [_]TestTarget{
|
||||
TestTarget{ .query = .{ .cpu_arch = .x86_64 } },
|
||||
},
|
||||
else => [_]TestTarget{},
|
||||
},
|
||||
else => [_]TestTarget{},
|
||||
};
|
||||
|
||||
const all_test_targets = switch (builtin.target.cpu.arch) {
|
||||
.x86_64 => switch (builtin.target.os.tag) {
|
||||
.linux => [_]TestTarget{
|
||||
TestTarget{ .query = .{} },
|
||||
TestTarget{ .query = .{ .cpu_arch = .x86_64, .abi = .musl } },
|
||||
TestTarget{ .query = .{ .cpu_arch = .x86, .abi = .musl } },
|
||||
TestTarget{ .query = .{ .cpu_arch = .aarch64, .abi = .musl } },
|
||||
TestTarget{ .query = .{ .cpu_arch = .riscv64, .abi = .musl } },
|
||||
// Disabled because it fails for some unknown reason
|
||||
// TestTarget{ .query = .{ .cpu_arch = .mips, .abi = .musl } },
|
||||
TestTarget{ .query = .{ .cpu_arch = .x86_64, .os_tag = .windows } },
|
||||
// Disabled due to https://github.com/ziglang/zig/issues/20047
|
||||
// TestTarget{ .query = .{ .cpu_arch = .x86, .os_tag = .windows } },
|
||||
TestTarget{ .query = .{ .cpu_arch = .x86_64, .os_tag = .macos } },
|
||||
TestTarget{ .query = .{ .cpu_arch = .aarch64, .os_tag = .macos } },
|
||||
},
|
||||
.windows => [_]TestTarget{
|
||||
TestTarget{ .query = .{ .cpu_arch = .x86_64, .abi = .gnu } },
|
||||
// Disabled due to https://github.com/ziglang/zig/issues/20047
|
||||
// TestTarget{ .query = .{ .cpu_arch = .x86, .abi = .gnu } },
|
||||
},
|
||||
.freebsd => [_]TestTarget{
|
||||
TestTarget{ .query = .{} },
|
||||
TestTarget{ .query = .{ .cpu_arch = .x86_64 } },
|
||||
},
|
||||
.macos => [_]TestTarget{
|
||||
TestTarget{ .query = .{ .cpu_arch = .x86_64 } },
|
||||
},
|
||||
else => [_]TestTarget{
|
||||
TestTarget{ .query = .{} },
|
||||
},
|
||||
},
|
||||
.aarch64 => switch (builtin.target.os.tag) {
|
||||
.linux, .windows, .freebsd, .macos => [_]TestTarget{
|
||||
TestTarget{ .query = .{} },
|
||||
},
|
||||
else => [_]TestTarget{
|
||||
TestTarget{ .query = .{} },
|
||||
},
|
||||
},
|
||||
else => [_]TestTarget{
|
||||
TestTarget{ .query = .{} },
|
||||
},
|
||||
};
|
||||
|
||||
fn computeTestTargets(isNative: bool, ci: ?bool) ?[]const TestTarget {
|
||||
if (ci != null and ci.?) return &ci_targets;
|
||||
|
||||
if (isNative) {
|
||||
// If the target is native we assume the user didn't change it with -Dtarget and run all test targets.
|
||||
return &all_test_targets;
|
||||
}
|
||||
|
||||
// Otherwise we run a single test target.
|
||||
return null;
|
||||
}
|
||||
|
||||
// This creates a SQLite static library from the SQLite dependency code.
|
||||
fn makeSQLiteLib(b: *std.Build, dep: *std.Build.Dependency, c_flags: []const []const u8, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, sqlite_c: enum { with, without }) *std.Build.Step.Compile {
|
||||
const mod = b.addModule("lib-sqlite", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.link_libc = true,
|
||||
});
|
||||
const lib = b.addLibrary(.{
|
||||
.name = "sqlite",
|
||||
.linkage = .static,
|
||||
.root_module = mod,
|
||||
});
|
||||
|
||||
mod.addIncludePath(dep.path("."));
|
||||
mod.addIncludePath(b.path("c"));
|
||||
if (sqlite_c == .with) {
|
||||
mod.addCSourceFile(.{
|
||||
.file = dep.path("sqlite3.c"),
|
||||
.flags = c_flags,
|
||||
});
|
||||
}
|
||||
mod.addCSourceFile(.{
|
||||
.file = b.path("c/workaround.c"),
|
||||
.flags = c_flags,
|
||||
});
|
||||
|
||||
return lib;
|
||||
}
|
||||
|
||||
pub fn build(b: *std.Build) !void {
|
||||
const in_memory = b.option(bool, "in_memory", "Should the tests run with sqlite in memory (default true)") orelse true;
|
||||
const dbfile = b.option([]const u8, "dbfile", "Always use this database file instead of a temporary one");
|
||||
const ci = b.option(bool, "ci", "Build and test in the CI on GitHub");
|
||||
|
||||
const query = b.standardTargetOptionsQueryOnly(.{});
|
||||
const target = b.resolveTargetQuery(query);
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
// Upstream dependency
|
||||
const sqlite_dep = b.dependency("sqlite", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
// Define C flags to use
|
||||
|
||||
var flags: std.ArrayList([]const u8) = .empty;
|
||||
defer flags.deinit(b.allocator);
|
||||
try flags.append(b.allocator, "-std=c99");
|
||||
|
||||
inline for (std.meta.fields(EnableOptions)) |field| {
|
||||
const opt = b.option(bool, field.name, "Enable " ++ field.name) orelse field.defaultValue().?;
|
||||
|
||||
if (opt) {
|
||||
var buf: [field.name.len]u8 = undefined;
|
||||
const name = std.ascii.upperString(&buf, field.name);
|
||||
const flag = try std.fmt.allocPrint(b.allocator, "-DSQLITE_ENABLE_{s}", .{name});
|
||||
|
||||
try flags.append(b.allocator, flag);
|
||||
}
|
||||
}
|
||||
|
||||
const c_flags = flags.items;
|
||||
|
||||
//
|
||||
// Main library and module
|
||||
//
|
||||
|
||||
// const sqlite_lib, const sqlite_mod = blk: {
|
||||
const sqlite_lib, _ = blk: {
|
||||
const lib = makeSQLiteLib(b, sqlite_dep, c_flags, target, optimize, .with);
|
||||
|
||||
const mod = b.addModule("sqlite", .{
|
||||
.root_source_file = b.path("sqlite.zig"),
|
||||
.link_libc = true,
|
||||
});
|
||||
mod.addIncludePath(b.path("c"));
|
||||
mod.addIncludePath(sqlite_dep.path("."));
|
||||
mod.linkLibrary(lib);
|
||||
|
||||
break :blk .{ lib, mod };
|
||||
};
|
||||
b.installArtifact(sqlite_lib);
|
||||
|
||||
// const sqliteext_mod = blk: {
|
||||
_ = blk: {
|
||||
const lib = makeSQLiteLib(b, sqlite_dep, c_flags, target, optimize, .without);
|
||||
|
||||
const mod = b.addModule("sqliteext", .{
|
||||
.root_source_file = b.path("sqlite.zig"),
|
||||
.link_libc = true,
|
||||
});
|
||||
mod.addIncludePath(b.path("c"));
|
||||
mod.linkLibrary(lib);
|
||||
|
||||
break :blk mod;
|
||||
};
|
||||
|
||||
//
|
||||
// Tests
|
||||
//
|
||||
|
||||
const test_targets = computeTestTargets(query.isNative(), ci) orelse &[_]TestTarget{.{
|
||||
.query = query,
|
||||
}};
|
||||
const test_step = b.step("test", "Run library tests");
|
||||
|
||||
// By default the tests will only be execute for native test targets, however they will be compiled
|
||||
// for _all_ targets defined in `test_targets`.
|
||||
//
|
||||
// If you want to execute tests for other targets you can pass -fqemu, -fdarling, -fwine, -frosetta.
|
||||
|
||||
for (test_targets) |test_target| {
|
||||
const cross_target = getTarget(b.resolveTargetQuery(test_target.query));
|
||||
const single_threaded_txt = if (test_target.single_threaded) "single" else "multi";
|
||||
const test_name = b.fmt("{s}-{s}-{s}", .{
|
||||
try cross_target.result.zigTriple(b.allocator),
|
||||
@tagName(optimize),
|
||||
single_threaded_txt,
|
||||
});
|
||||
|
||||
const test_sqlite_lib = makeSQLiteLib(b, sqlite_dep, c_flags, cross_target, optimize, .with);
|
||||
|
||||
const mod = b.addModule(test_name, .{
|
||||
.target = cross_target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = b.path("sqlite.zig"),
|
||||
.single_threaded = test_target.single_threaded,
|
||||
});
|
||||
|
||||
const tests = b.addTest(.{
|
||||
.name = test_name,
|
||||
.root_module = mod,
|
||||
});
|
||||
tests.root_module.addIncludePath(b.path("c"));
|
||||
tests.root_module.addIncludePath(sqlite_dep.path("."));
|
||||
tests.root_module.linkLibrary(test_sqlite_lib);
|
||||
|
||||
const tests_options = b.addOptions();
|
||||
tests.root_module.addImport("build_options", tests_options.createModule());
|
||||
|
||||
tests_options.addOption(bool, "in_memory", in_memory);
|
||||
tests_options.addOption(?[]const u8, "dbfile", dbfile);
|
||||
|
||||
const run_tests = b.addRunArtifact(tests);
|
||||
test_step.dependOn(&run_tests.step);
|
||||
}
|
||||
|
||||
// This builds an example shared library with the extension and a binary that tests it.
|
||||
|
||||
//\ const zigcrypto_install_artifact = addZigcrypto(b, sqliteext_mod, target, optimize);
|
||||
//\ test_step.dependOn(&zigcrypto_install_artifact.step);
|
||||
//\ const zigcrypto_test_run = addZigcryptoTestRun(b, sqlite_mod, target, optimize);
|
||||
//\ zigcrypto_test_run.step.dependOn(&zigcrypto_install_artifact.step);
|
||||
//\ test_step.dependOn(&zigcrypto_test_run.step);
|
||||
|
||||
//
|
||||
// Tools
|
||||
//
|
||||
|
||||
addPreprocessStep(b, sqlite_dep);
|
||||
}
|
||||
|
||||
fn addPreprocessStep(b: *std.Build, sqlite_dep: *std.Build.Dependency) void {
|
||||
var wf = b.addWriteFiles();
|
||||
|
||||
// Preprocessing step
|
||||
const preprocess = PreprocessStep.create(b, .{
|
||||
.source = sqlite_dep.path("."),
|
||||
.target = wf.getDirectory(),
|
||||
});
|
||||
preprocess.step.dependOn(&wf.step);
|
||||
|
||||
const w = b.addUpdateSourceFiles();
|
||||
w.addCopyFileToSource(preprocess.target.join(b.allocator, "loadable-ext-sqlite3.h") catch @panic("OOM"), "c/loadable-ext-sqlite3.h");
|
||||
w.addCopyFileToSource(preprocess.target.join(b.allocator, "loadable-ext-sqlite3ext.h") catch @panic("OOM"), "c/loadable-ext-sqlite3ext.h");
|
||||
w.step.dependOn(&preprocess.step);
|
||||
|
||||
const preprocess_headers = b.step("preprocess-headers", "Preprocess the headers for the loadable extensions");
|
||||
preprocess_headers.dependOn(&w.step);
|
||||
}
|
||||
|
||||
fn addZigcrypto(b: *std.Build, sqlite_mod: *std.Build.Module, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) *std.Build.Step.InstallArtifact {
|
||||
const mod = b.addModule("zigcryto", .{
|
||||
.root_source_file = b.path("examples/zigcrypto.zig"),
|
||||
.target = getTarget(target),
|
||||
.optimize = optimize,
|
||||
});
|
||||
const exe = b.addLibrary(.{
|
||||
.name = "zigcrypto",
|
||||
.root_module = mod,
|
||||
.version = null,
|
||||
.linkage = .dynamic,
|
||||
});
|
||||
exe.root_module.addImport("sqlite", sqlite_mod);
|
||||
|
||||
const install_artifact = b.addInstallArtifact(exe, .{});
|
||||
install_artifact.step.dependOn(&exe.step);
|
||||
|
||||
return install_artifact;
|
||||
}
|
||||
|
||||
fn addZigcryptoTestRun(b: *std.Build, sqlite_mod: *std.Build.Module, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) *std.Build.Step.Run {
|
||||
const mod = b.addModule("zigcryto-test", .{
|
||||
.root_source_file = b.path("examples/zigcrypto_test.zig"),
|
||||
.target = getTarget(target),
|
||||
.optimize = optimize,
|
||||
});
|
||||
const zigcrypto_test = b.addExecutable(.{
|
||||
.name = "zigcrypto-test",
|
||||
.root_module = mod,
|
||||
});
|
||||
zigcrypto_test.root_module.addImport("sqlite", sqlite_mod);
|
||||
|
||||
const install = b.addInstallArtifact(zigcrypto_test, .{});
|
||||
install.step.dependOn(&zigcrypto_test.step);
|
||||
|
||||
const run = b.addRunArtifact(zigcrypto_test);
|
||||
run.step.dependOn(&zigcrypto_test.step);
|
||||
|
||||
return run;
|
||||
}
|
||||
|
||||
// See https://www.sqlite.org/compile.html for flags
|
||||
const EnableOptions = struct {
|
||||
// https://www.sqlite.org/fts5.html
|
||||
fts5: bool = false,
|
||||
};
|
||||
|
||||
const PreprocessStep = struct {
|
||||
const Config = struct {
|
||||
source: std.Build.LazyPath,
|
||||
target: std.Build.LazyPath,
|
||||
};
|
||||
|
||||
step: std.Build.Step,
|
||||
|
||||
source: std.Build.LazyPath,
|
||||
target: std.Build.LazyPath,
|
||||
|
||||
fn create(owner: *std.Build, config: Config) *PreprocessStep {
|
||||
const step = owner.allocator.create(PreprocessStep) catch @panic("OOM");
|
||||
step.* = .{
|
||||
.step = std.Build.Step.init(.{
|
||||
.id = std.Build.Step.Id.custom,
|
||||
.name = "preprocess",
|
||||
.owner = owner,
|
||||
.makeFn = make,
|
||||
}),
|
||||
.source = config.source,
|
||||
.target = config.target,
|
||||
};
|
||||
|
||||
return step;
|
||||
}
|
||||
|
||||
fn make(step: *std.Build.Step, _: std.Build.Step.MakeOptions) !void {
|
||||
const ps: *PreprocessStep = @fieldParentPtr("step", step);
|
||||
const owner = step.owner;
|
||||
|
||||
const sqlite3_h = try ps.source.path(owner, "sqlite3.h").getPath3(owner, step).toString(owner.allocator);
|
||||
const sqlite3ext_h = try ps.source.path(owner, "sqlite3ext.h").getPath3(owner, step).toString(owner.allocator);
|
||||
|
||||
const loadable_sqlite3_h = try ps.target.path(owner, "loadable-ext-sqlite3.h").getPath3(owner, step).toString(owner.allocator);
|
||||
const loadable_sqlite3ext_h = try ps.target.path(owner, "loadable-ext-sqlite3ext.h").getPath3(owner, step).toString(owner.allocator);
|
||||
|
||||
var threaded: std.Io.Threaded = .init_single_threaded;
|
||||
const io = threaded.io();
|
||||
try Preprocessor.sqlite3(io, owner.allocator, sqlite3_h, loadable_sqlite3_h);
|
||||
try Preprocessor.sqlite3ext(io, owner.allocator, sqlite3ext_h, loadable_sqlite3ext_h);
|
||||
}
|
||||
};
|
||||
13
zig-vendor/zig-sqlite/build.zig.zon
Normal file
13
zig-vendor/zig-sqlite/build.zig.zon
Normal file
@@ -0,0 +1,13 @@
|
||||
.{
|
||||
.name = .sqlite,
|
||||
.fingerprint = 0xb8bb86826b7f6417,
|
||||
.minimum_zig_version = "0.14.0",
|
||||
.version = "3.48.0",
|
||||
.dependencies = .{
|
||||
.sqlite = .{
|
||||
.url = "https://www.sqlite.org/2025/sqlite-amalgamation-3490200.zip",
|
||||
.hash = "N-V-__8AAH-mpwB7g3MnqYU-ooUBF1t99RP27dZ9addtMVXD",
|
||||
},
|
||||
},
|
||||
.paths = .{"."},
|
||||
}
|
||||
243
zig-vendor/zig-sqlite/build/Preprocessor.zig
Normal file
243
zig-vendor/zig-sqlite/build/Preprocessor.zig
Normal file
@@ -0,0 +1,243 @@
|
||||
const std = @import("std");
|
||||
const debug = std.debug;
|
||||
const mem = std.mem;
|
||||
|
||||
// This tool is used to preprocess the sqlite3 headers to make them usable to build loadable extensions.
|
||||
//
|
||||
// Due to limitations of `zig translate-c` (used by @cImport) the code produced by @cImport'ing the sqlite3ext.h header is unusable.
|
||||
// The sqlite3ext.h header redefines the SQLite API like this:
|
||||
//
|
||||
// #define sqlite3_open_v2 sqlite3_api->open_v2
|
||||
//
|
||||
// This is not supported by `zig translate-c`, if there's already a definition for a function the aliasing macros won't do anything:
|
||||
// translate-c keeps generating the code for the function defined in sqlite3.h
|
||||
//
|
||||
// Even if there's no definition already (we could for example remove the definition manually from the sqlite3.h file),
|
||||
// the code generated fails to compile because it references the variable sqlite3_api which is not defined
|
||||
//
|
||||
// And even if the sqlite3_api is defined before, the generated code fails to compile because the functions are defined as consts and
|
||||
// can only reference comptime stuff, however sqlite3_api is a runtime variable.
|
||||
//
|
||||
// The only viable option is to completely reomve the original function definitions and redefine all functions in Zig which forward
|
||||
// calls to the sqlite3_api object.
|
||||
//
|
||||
// This works but it requires fairly extensive modifications of both sqlite3.h and sqlite3ext.h which is time consuming to do manually;
|
||||
// this tool is intended to automate all these modifications.
|
||||
|
||||
fn readOriginalData(io: std.Io, allocator: mem.Allocator, path: []const u8) ![]const u8 {
|
||||
var file = try std.Io.Dir.cwd().openFile(io, path, .{});
|
||||
defer file.close(io);
|
||||
var buf: [1024]u8 = undefined;
|
||||
var reader = file.reader(io, &buf);
|
||||
|
||||
const data = reader.interface.readAlloc(allocator, 1024 * 1024);
|
||||
return data;
|
||||
}
|
||||
|
||||
const Processor = struct {
|
||||
const Range = union(enum) {
|
||||
delete: struct {
|
||||
start: usize,
|
||||
end: usize,
|
||||
},
|
||||
replace: struct {
|
||||
start: usize,
|
||||
end: usize,
|
||||
replacement: []const u8,
|
||||
},
|
||||
};
|
||||
|
||||
allocator: mem.Allocator,
|
||||
|
||||
data: []const u8,
|
||||
pos: usize,
|
||||
|
||||
range_start: usize,
|
||||
ranges: std.ArrayList(Range),
|
||||
|
||||
fn init(allocator: mem.Allocator, data: []const u8) !Processor {
|
||||
return .{
|
||||
.allocator = allocator,
|
||||
.data = data,
|
||||
.pos = 0,
|
||||
.range_start = 0,
|
||||
.ranges = try std.ArrayList(Range).initCapacity(allocator, 4096),
|
||||
};
|
||||
}
|
||||
|
||||
fn readable(self: *Processor) []const u8 {
|
||||
if (self.pos >= self.data.len) return "";
|
||||
|
||||
return self.data[self.pos..];
|
||||
}
|
||||
|
||||
fn previousByte(self: *Processor) ?u8 {
|
||||
if (self.pos <= 0) return null;
|
||||
return self.data[self.pos - 1];
|
||||
}
|
||||
|
||||
fn skipUntil(self: *Processor, needle: []const u8) bool {
|
||||
const pos = mem.indexOfPos(u8, self.data, self.pos, needle);
|
||||
if (pos) |p| {
|
||||
self.pos = p;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
fn consume(self: *Processor, needle: []const u8) void {
|
||||
debug.assert(self.startsWith(needle));
|
||||
|
||||
self.pos += needle.len;
|
||||
}
|
||||
|
||||
fn startsWith(self: *Processor, needle: []const u8) bool {
|
||||
if (self.pos >= self.data.len) return false;
|
||||
|
||||
const data = self.data[self.pos..];
|
||||
return mem.startsWith(u8, data, needle);
|
||||
}
|
||||
|
||||
fn rangeStart(self: *Processor) void {
|
||||
self.range_start = self.pos;
|
||||
}
|
||||
|
||||
fn rangeDelete(self: *Processor) void {
|
||||
self.ranges.appendAssumeCapacity(Range{
|
||||
.delete = .{
|
||||
.start = self.range_start,
|
||||
.end = self.pos,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
fn rangeReplace(self: *Processor, replacement: []const u8) void {
|
||||
self.ranges.appendAssumeCapacity(Range{
|
||||
.replace = .{
|
||||
.start = self.range_start,
|
||||
.end = self.pos,
|
||||
.replacement = replacement,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
fn dump(self: *Processor, writer: anytype) !void {
|
||||
var pos: usize = 0;
|
||||
for (self.ranges.items) |range| {
|
||||
switch (range) {
|
||||
.delete => |dr| {
|
||||
const to_write = self.data[pos..dr.start];
|
||||
try writer.interface.writeAll(to_write);
|
||||
pos = dr.end;
|
||||
},
|
||||
.replace => |rr| {
|
||||
const to_write = self.data[pos..rr.start];
|
||||
try writer.interface.writeAll(to_write);
|
||||
try writer.interface.writeAll(rr.replacement);
|
||||
pos = rr.end;
|
||||
},
|
||||
}
|
||||
|
||||
// debug.print("excluded range: start={d} end={d} slice=\"{s}\"\n", .{
|
||||
// range.start,
|
||||
// range.end,
|
||||
// processor.data[range.start..range.end],
|
||||
// });
|
||||
}
|
||||
|
||||
// Finally append the remaining data in the buffer (the last range will probably not be the end of the file)
|
||||
if (pos < self.data.len) {
|
||||
const remaining_data = self.data[pos..];
|
||||
try writer.interface.writeAll(remaining_data);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub fn sqlite3(io: std.Io, allocator: mem.Allocator, input_path: []const u8, output_path: []const u8) !void {
|
||||
const data = try readOriginalData(io, allocator, input_path);
|
||||
|
||||
var processor = try Processor.init(allocator, data);
|
||||
|
||||
while (true) {
|
||||
// Everything function definition is declared with SQLITE_API.
|
||||
// Stop the loop if there's none in the remaining data.
|
||||
if (!processor.skipUntil("SQLITE_API ")) break;
|
||||
|
||||
// If the byte just before is not a LN it's not a function definition.
|
||||
// There are a couple instances where SQLITE_API appears in a comment.
|
||||
const previous_byte = processor.previousByte() orelse 0;
|
||||
if (previous_byte != '\n') {
|
||||
processor.consume("SQLITE_API ");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Now we assume we're at the start of a function definition.
|
||||
//
|
||||
// We keep track of every function definition by marking its start and end position in the data.
|
||||
|
||||
processor.rangeStart();
|
||||
|
||||
processor.consume("SQLITE_API ");
|
||||
if (processor.startsWith("SQLITE_EXTERN ")) {
|
||||
// This is not a function definition, ignore it.
|
||||
// try processor.unmark();
|
||||
continue;
|
||||
}
|
||||
|
||||
_ = processor.skipUntil(");\n");
|
||||
processor.consume(");\n");
|
||||
|
||||
processor.rangeDelete();
|
||||
}
|
||||
|
||||
// Write the result
|
||||
|
||||
// FIXME: Handle this
|
||||
var output_file = try std.Io.Dir.cwd().createFile(io, output_path, .{}); //0o644 });
|
||||
defer output_file.close(io);
|
||||
|
||||
try output_file.writeStreamingAll(io, "/* sqlite3.h edited by the zig-sqlite build script */\n");
|
||||
var buf: [1024]u8 = undefined;
|
||||
var out_writer = output_file.writer(io, &buf);
|
||||
try processor.dump(&out_writer);
|
||||
}
|
||||
|
||||
pub fn sqlite3ext(io: std.Io, allocator: mem.Allocator, input_path: []const u8, output_path: []const u8) !void {
|
||||
const data = try readOriginalData(io, allocator, input_path);
|
||||
|
||||
var processor = try Processor.init(allocator, data);
|
||||
|
||||
// Replace the include line
|
||||
|
||||
debug.assert(processor.skipUntil("#include \"sqlite3.h\""));
|
||||
|
||||
processor.rangeStart();
|
||||
processor.consume("#include \"sqlite3.h\"");
|
||||
processor.rangeReplace("#include \"loadable-ext-sqlite3.h\"");
|
||||
|
||||
// Delete all #define macros
|
||||
|
||||
while (true) {
|
||||
if (!processor.skipUntil("#define sqlite3_")) break;
|
||||
|
||||
processor.rangeStart();
|
||||
|
||||
processor.consume("#define sqlite3_");
|
||||
_ = processor.skipUntil("\n");
|
||||
processor.consume("\n");
|
||||
|
||||
processor.rangeDelete();
|
||||
}
|
||||
|
||||
// Write the result
|
||||
|
||||
// FIXME: File permissions
|
||||
// var output_file = try std.fs.cwd().createFile(output_path, .{ .mode = 0o0644 });
|
||||
var output_file = try std.Io.Dir.cwd().createFile(io, output_path, .{});
|
||||
defer output_file.close(io);
|
||||
|
||||
try output_file.writeStreamingAll(io, "/* sqlite3ext.h edited by the zig-sqlite build script */\n");
|
||||
var buf: [1024]u8 = undefined;
|
||||
var out_writer = output_file.writer(io, &buf);
|
||||
try processor.dump(&out_writer);
|
||||
}
|
||||
20
zig-vendor/zig-sqlite/c.zig
Normal file
20
zig-vendor/zig-sqlite/c.zig
Normal file
@@ -0,0 +1,20 @@
|
||||
const root = @import("root");
|
||||
|
||||
pub const c = if (@hasDecl(root, "loadable_extension"))
|
||||
@import("c/loadable_extension.zig")
|
||||
else
|
||||
@cImport({
|
||||
@cInclude("sqlite3.h");
|
||||
@cInclude("workaround.h");
|
||||
});
|
||||
|
||||
// versionGreaterThanOrEqualTo returns true if the SQLite version is >= to the major.minor.patch provided.
|
||||
pub fn versionGreaterThanOrEqualTo(major: u8, minor: u8, patch: u8) bool {
|
||||
return c.SQLITE_VERSION_NUMBER >= @as(u32, major) * 1000000 + @as(u32, minor) * 1000 + @as(u32, patch);
|
||||
}
|
||||
|
||||
comptime {
|
||||
if (!versionGreaterThanOrEqualTo(3, 21, 0)) {
|
||||
@compileError("must use SQLite >= 3.21.0");
|
||||
}
|
||||
}
|
||||
12799
zig-vendor/zig-sqlite/c/loadable-ext-sqlite3.h
Normal file
12799
zig-vendor/zig-sqlite/c/loadable-ext-sqlite3.h
Normal file
File diff suppressed because it is too large
Load Diff
447
zig-vendor/zig-sqlite/c/loadable-ext-sqlite3ext.h
Normal file
447
zig-vendor/zig-sqlite/c/loadable-ext-sqlite3ext.h
Normal file
@@ -0,0 +1,447 @@
|
||||
/* sqlite3ext.h edited by the zig-sqlite build script */
|
||||
/*
|
||||
** 2006 June 7
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This header file defines the SQLite interface for use by
|
||||
** shared libraries that want to be imported as extensions into
|
||||
** an SQLite instance. Shared libraries that intend to be loaded
|
||||
** as extensions by SQLite should #include this file instead of
|
||||
** sqlite3.h.
|
||||
*/
|
||||
#ifndef SQLITE3EXT_H
|
||||
#define SQLITE3EXT_H
|
||||
#include "loadable-ext-sqlite3.h"
|
||||
|
||||
/*
|
||||
** The following structure holds pointers to all of the SQLite API
|
||||
** routines.
|
||||
**
|
||||
** WARNING: In order to maintain backwards compatibility, add new
|
||||
** interfaces to the end of this structure only. If you insert new
|
||||
** interfaces in the middle of this structure, then older different
|
||||
** versions of SQLite will not be able to load each other's shared
|
||||
** libraries!
|
||||
*/
|
||||
struct sqlite3_api_routines {
|
||||
void * (*aggregate_context)(sqlite3_context*,int nBytes);
|
||||
int (*aggregate_count)(sqlite3_context*);
|
||||
int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*));
|
||||
int (*bind_double)(sqlite3_stmt*,int,double);
|
||||
int (*bind_int)(sqlite3_stmt*,int,int);
|
||||
int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64);
|
||||
int (*bind_null)(sqlite3_stmt*,int);
|
||||
int (*bind_parameter_count)(sqlite3_stmt*);
|
||||
int (*bind_parameter_index)(sqlite3_stmt*,const char*zName);
|
||||
const char * (*bind_parameter_name)(sqlite3_stmt*,int);
|
||||
int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*));
|
||||
int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*));
|
||||
int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*);
|
||||
int (*busy_handler)(sqlite3*,int(*)(void*,int),void*);
|
||||
int (*busy_timeout)(sqlite3*,int ms);
|
||||
int (*changes)(sqlite3*);
|
||||
int (*close)(sqlite3*);
|
||||
int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*,
|
||||
int eTextRep,const char*));
|
||||
int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*,
|
||||
int eTextRep,const void*));
|
||||
const void * (*column_blob)(sqlite3_stmt*,int iCol);
|
||||
int (*column_bytes)(sqlite3_stmt*,int iCol);
|
||||
int (*column_bytes16)(sqlite3_stmt*,int iCol);
|
||||
int (*column_count)(sqlite3_stmt*pStmt);
|
||||
const char * (*column_database_name)(sqlite3_stmt*,int);
|
||||
const void * (*column_database_name16)(sqlite3_stmt*,int);
|
||||
const char * (*column_decltype)(sqlite3_stmt*,int i);
|
||||
const void * (*column_decltype16)(sqlite3_stmt*,int);
|
||||
double (*column_double)(sqlite3_stmt*,int iCol);
|
||||
int (*column_int)(sqlite3_stmt*,int iCol);
|
||||
sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol);
|
||||
const char * (*column_name)(sqlite3_stmt*,int);
|
||||
const void * (*column_name16)(sqlite3_stmt*,int);
|
||||
const char * (*column_origin_name)(sqlite3_stmt*,int);
|
||||
const void * (*column_origin_name16)(sqlite3_stmt*,int);
|
||||
const char * (*column_table_name)(sqlite3_stmt*,int);
|
||||
const void * (*column_table_name16)(sqlite3_stmt*,int);
|
||||
const unsigned char * (*column_text)(sqlite3_stmt*,int iCol);
|
||||
const void * (*column_text16)(sqlite3_stmt*,int iCol);
|
||||
int (*column_type)(sqlite3_stmt*,int iCol);
|
||||
sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol);
|
||||
void * (*commit_hook)(sqlite3*,int(*)(void*),void*);
|
||||
int (*complete)(const char*sql);
|
||||
int (*complete16)(const void*sql);
|
||||
int (*create_collation)(sqlite3*,const char*,int,void*,
|
||||
int(*)(void*,int,const void*,int,const void*));
|
||||
int (*create_collation16)(sqlite3*,const void*,int,void*,
|
||||
int(*)(void*,int,const void*,int,const void*));
|
||||
int (*create_function)(sqlite3*,const char*,int,int,void*,
|
||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*));
|
||||
int (*create_function16)(sqlite3*,const void*,int,int,void*,
|
||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*));
|
||||
int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*);
|
||||
int (*data_count)(sqlite3_stmt*pStmt);
|
||||
sqlite3 * (*db_handle)(sqlite3_stmt*);
|
||||
int (*declare_vtab)(sqlite3*,const char*);
|
||||
int (*enable_shared_cache)(int);
|
||||
int (*errcode)(sqlite3*db);
|
||||
const char * (*errmsg)(sqlite3*);
|
||||
const void * (*errmsg16)(sqlite3*);
|
||||
int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**);
|
||||
int (*expired)(sqlite3_stmt*);
|
||||
int (*finalize)(sqlite3_stmt*pStmt);
|
||||
void (*free)(void*);
|
||||
void (*free_table)(char**result);
|
||||
int (*get_autocommit)(sqlite3*);
|
||||
void * (*get_auxdata)(sqlite3_context*,int);
|
||||
int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**);
|
||||
int (*global_recover)(void);
|
||||
void (*interruptx)(sqlite3*);
|
||||
sqlite_int64 (*last_insert_rowid)(sqlite3*);
|
||||
const char * (*libversion)(void);
|
||||
int (*libversion_number)(void);
|
||||
void *(*malloc)(int);
|
||||
char * (*mprintf)(const char*,...);
|
||||
int (*open)(const char*,sqlite3**);
|
||||
int (*open16)(const void*,sqlite3**);
|
||||
int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
|
||||
int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
|
||||
void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*);
|
||||
void (*progress_handler)(sqlite3*,int,int(*)(void*),void*);
|
||||
void *(*realloc)(void*,int);
|
||||
int (*reset)(sqlite3_stmt*pStmt);
|
||||
void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*));
|
||||
void (*result_double)(sqlite3_context*,double);
|
||||
void (*result_error)(sqlite3_context*,const char*,int);
|
||||
void (*result_error16)(sqlite3_context*,const void*,int);
|
||||
void (*result_int)(sqlite3_context*,int);
|
||||
void (*result_int64)(sqlite3_context*,sqlite_int64);
|
||||
void (*result_null)(sqlite3_context*);
|
||||
void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*));
|
||||
void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*));
|
||||
void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*));
|
||||
void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*));
|
||||
void (*result_value)(sqlite3_context*,sqlite3_value*);
|
||||
void * (*rollback_hook)(sqlite3*,void(*)(void*),void*);
|
||||
int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
|
||||
const char*,const char*),void*);
|
||||
void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
|
||||
char * (*xsnprintf)(int,char*,const char*,...);
|
||||
int (*step)(sqlite3_stmt*);
|
||||
int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
|
||||
char const**,char const**,int*,int*,int*);
|
||||
void (*thread_cleanup)(void);
|
||||
int (*total_changes)(sqlite3*);
|
||||
void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*);
|
||||
int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*);
|
||||
void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*,
|
||||
sqlite_int64),void*);
|
||||
void * (*user_data)(sqlite3_context*);
|
||||
const void * (*value_blob)(sqlite3_value*);
|
||||
int (*value_bytes)(sqlite3_value*);
|
||||
int (*value_bytes16)(sqlite3_value*);
|
||||
double (*value_double)(sqlite3_value*);
|
||||
int (*value_int)(sqlite3_value*);
|
||||
sqlite_int64 (*value_int64)(sqlite3_value*);
|
||||
int (*value_numeric_type)(sqlite3_value*);
|
||||
const unsigned char * (*value_text)(sqlite3_value*);
|
||||
const void * (*value_text16)(sqlite3_value*);
|
||||
const void * (*value_text16be)(sqlite3_value*);
|
||||
const void * (*value_text16le)(sqlite3_value*);
|
||||
int (*value_type)(sqlite3_value*);
|
||||
char *(*vmprintf)(const char*,va_list);
|
||||
/* Added ??? */
|
||||
int (*overload_function)(sqlite3*, const char *zFuncName, int nArg);
|
||||
/* Added by 3.3.13 */
|
||||
int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
|
||||
int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
|
||||
int (*clear_bindings)(sqlite3_stmt*);
|
||||
/* Added by 3.4.1 */
|
||||
int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*,
|
||||
void (*xDestroy)(void *));
|
||||
/* Added by 3.5.0 */
|
||||
int (*bind_zeroblob)(sqlite3_stmt*,int,int);
|
||||
int (*blob_bytes)(sqlite3_blob*);
|
||||
int (*blob_close)(sqlite3_blob*);
|
||||
int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64,
|
||||
int,sqlite3_blob**);
|
||||
int (*blob_read)(sqlite3_blob*,void*,int,int);
|
||||
int (*blob_write)(sqlite3_blob*,const void*,int,int);
|
||||
int (*create_collation_v2)(sqlite3*,const char*,int,void*,
|
||||
int(*)(void*,int,const void*,int,const void*),
|
||||
void(*)(void*));
|
||||
int (*file_control)(sqlite3*,const char*,int,void*);
|
||||
sqlite3_int64 (*memory_highwater)(int);
|
||||
sqlite3_int64 (*memory_used)(void);
|
||||
sqlite3_mutex *(*mutex_alloc)(int);
|
||||
void (*mutex_enter)(sqlite3_mutex*);
|
||||
void (*mutex_free)(sqlite3_mutex*);
|
||||
void (*mutex_leave)(sqlite3_mutex*);
|
||||
int (*mutex_try)(sqlite3_mutex*);
|
||||
int (*open_v2)(const char*,sqlite3**,int,const char*);
|
||||
int (*release_memory)(int);
|
||||
void (*result_error_nomem)(sqlite3_context*);
|
||||
void (*result_error_toobig)(sqlite3_context*);
|
||||
int (*sleep)(int);
|
||||
void (*soft_heap_limit)(int);
|
||||
sqlite3_vfs *(*vfs_find)(const char*);
|
||||
int (*vfs_register)(sqlite3_vfs*,int);
|
||||
int (*vfs_unregister)(sqlite3_vfs*);
|
||||
int (*xthreadsafe)(void);
|
||||
void (*result_zeroblob)(sqlite3_context*,int);
|
||||
void (*result_error_code)(sqlite3_context*,int);
|
||||
int (*test_control)(int, ...);
|
||||
void (*randomness)(int,void*);
|
||||
sqlite3 *(*context_db_handle)(sqlite3_context*);
|
||||
int (*extended_result_codes)(sqlite3*,int);
|
||||
int (*limit)(sqlite3*,int,int);
|
||||
sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*);
|
||||
const char *(*sql)(sqlite3_stmt*);
|
||||
int (*status)(int,int*,int*,int);
|
||||
int (*backup_finish)(sqlite3_backup*);
|
||||
sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*);
|
||||
int (*backup_pagecount)(sqlite3_backup*);
|
||||
int (*backup_remaining)(sqlite3_backup*);
|
||||
int (*backup_step)(sqlite3_backup*,int);
|
||||
const char *(*compileoption_get)(int);
|
||||
int (*compileoption_used)(const char*);
|
||||
int (*create_function_v2)(sqlite3*,const char*,int,int,void*,
|
||||
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*),
|
||||
void(*xDestroy)(void*));
|
||||
int (*db_config)(sqlite3*,int,...);
|
||||
sqlite3_mutex *(*db_mutex)(sqlite3*);
|
||||
int (*db_status)(sqlite3*,int,int*,int*,int);
|
||||
int (*extended_errcode)(sqlite3*);
|
||||
void (*log)(int,const char*,...);
|
||||
sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64);
|
||||
const char *(*sourceid)(void);
|
||||
int (*stmt_status)(sqlite3_stmt*,int,int);
|
||||
int (*strnicmp)(const char*,const char*,int);
|
||||
int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*);
|
||||
int (*wal_autocheckpoint)(sqlite3*,int);
|
||||
int (*wal_checkpoint)(sqlite3*,const char*);
|
||||
void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*);
|
||||
int (*blob_reopen)(sqlite3_blob*,sqlite3_int64);
|
||||
int (*vtab_config)(sqlite3*,int op,...);
|
||||
int (*vtab_on_conflict)(sqlite3*);
|
||||
/* Version 3.7.16 and later */
|
||||
int (*close_v2)(sqlite3*);
|
||||
const char *(*db_filename)(sqlite3*,const char*);
|
||||
int (*db_readonly)(sqlite3*,const char*);
|
||||
int (*db_release_memory)(sqlite3*);
|
||||
const char *(*errstr)(int);
|
||||
int (*stmt_busy)(sqlite3_stmt*);
|
||||
int (*stmt_readonly)(sqlite3_stmt*);
|
||||
int (*stricmp)(const char*,const char*);
|
||||
int (*uri_boolean)(const char*,const char*,int);
|
||||
sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
|
||||
const char *(*uri_parameter)(const char*,const char*);
|
||||
char *(*xvsnprintf)(int,char*,const char*,va_list);
|
||||
int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
|
||||
/* Version 3.8.7 and later */
|
||||
int (*auto_extension)(void(*)(void));
|
||||
int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64,
|
||||
void(*)(void*));
|
||||
int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64,
|
||||
void(*)(void*),unsigned char);
|
||||
int (*cancel_auto_extension)(void(*)(void));
|
||||
int (*load_extension)(sqlite3*,const char*,const char*,char**);
|
||||
void *(*malloc64)(sqlite3_uint64);
|
||||
sqlite3_uint64 (*msize)(void*);
|
||||
void *(*realloc64)(void*,sqlite3_uint64);
|
||||
void (*reset_auto_extension)(void);
|
||||
void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64,
|
||||
void(*)(void*));
|
||||
void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64,
|
||||
void(*)(void*), unsigned char);
|
||||
int (*strglob)(const char*,const char*);
|
||||
/* Version 3.8.11 and later */
|
||||
sqlite3_value *(*value_dup)(const sqlite3_value*);
|
||||
void (*value_free)(sqlite3_value*);
|
||||
int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
|
||||
int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
|
||||
/* Version 3.9.0 and later */
|
||||
unsigned int (*value_subtype)(sqlite3_value*);
|
||||
void (*result_subtype)(sqlite3_context*,unsigned int);
|
||||
/* Version 3.10.0 and later */
|
||||
int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
|
||||
int (*strlike)(const char*,const char*,unsigned int);
|
||||
int (*db_cacheflush)(sqlite3*);
|
||||
/* Version 3.12.0 and later */
|
||||
int (*system_errno)(sqlite3*);
|
||||
/* Version 3.14.0 and later */
|
||||
int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
|
||||
char *(*expanded_sql)(sqlite3_stmt*);
|
||||
/* Version 3.18.0 and later */
|
||||
void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
|
||||
/* Version 3.20.0 and later */
|
||||
int (*prepare_v3)(sqlite3*,const char*,int,unsigned int,
|
||||
sqlite3_stmt**,const char**);
|
||||
int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int,
|
||||
sqlite3_stmt**,const void**);
|
||||
int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
|
||||
void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
|
||||
void *(*value_pointer)(sqlite3_value*,const char*);
|
||||
int (*vtab_nochange)(sqlite3_context*);
|
||||
int (*value_nochange)(sqlite3_value*);
|
||||
const char *(*vtab_collation)(sqlite3_index_info*,int);
|
||||
/* Version 3.24.0 and later */
|
||||
int (*keyword_count)(void);
|
||||
int (*keyword_name)(int,const char**,int*);
|
||||
int (*keyword_check)(const char*,int);
|
||||
sqlite3_str *(*str_new)(sqlite3*);
|
||||
char *(*str_finish)(sqlite3_str*);
|
||||
void (*str_appendf)(sqlite3_str*, const char *zFormat, ...);
|
||||
void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list);
|
||||
void (*str_append)(sqlite3_str*, const char *zIn, int N);
|
||||
void (*str_appendall)(sqlite3_str*, const char *zIn);
|
||||
void (*str_appendchar)(sqlite3_str*, int N, char C);
|
||||
void (*str_reset)(sqlite3_str*);
|
||||
int (*str_errcode)(sqlite3_str*);
|
||||
int (*str_length)(sqlite3_str*);
|
||||
char *(*str_value)(sqlite3_str*);
|
||||
/* Version 3.25.0 and later */
|
||||
int (*create_window_function)(sqlite3*,const char*,int,int,void*,
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*),
|
||||
void (*xValue)(sqlite3_context*),
|
||||
void (*xInv)(sqlite3_context*,int,sqlite3_value**),
|
||||
void(*xDestroy)(void*));
|
||||
/* Version 3.26.0 and later */
|
||||
const char *(*normalized_sql)(sqlite3_stmt*);
|
||||
/* Version 3.28.0 and later */
|
||||
int (*stmt_isexplain)(sqlite3_stmt*);
|
||||
int (*value_frombind)(sqlite3_value*);
|
||||
/* Version 3.30.0 and later */
|
||||
int (*drop_modules)(sqlite3*,const char**);
|
||||
/* Version 3.31.0 and later */
|
||||
sqlite3_int64 (*hard_heap_limit64)(sqlite3_int64);
|
||||
const char *(*uri_key)(const char*,int);
|
||||
const char *(*filename_database)(const char*);
|
||||
const char *(*filename_journal)(const char*);
|
||||
const char *(*filename_wal)(const char*);
|
||||
/* Version 3.32.0 and later */
|
||||
const char *(*create_filename)(const char*,const char*,const char*,
|
||||
int,const char**);
|
||||
void (*free_filename)(const char*);
|
||||
sqlite3_file *(*database_file_object)(const char*);
|
||||
/* Version 3.34.0 and later */
|
||||
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*));
|
||||
};
|
||||
|
||||
/*
|
||||
** This is the function signature used for all extension entry points. It
|
||||
** is also defined in the file "loadext.c".
|
||||
*/
|
||||
typedef int (*sqlite3_loadext_entry)(
|
||||
sqlite3 *db, /* Handle to the database. */
|
||||
char **pzErrMsg, /* Used to set error string on failure. */
|
||||
const sqlite3_api_routines *pThunk /* Extension API function pointers. */
|
||||
);
|
||||
|
||||
/*
|
||||
** The following macros redefine the API routines so that they are
|
||||
** redirected through the global sqlite3_api structure.
|
||||
**
|
||||
** This header file is also used by the loadext.c source file
|
||||
** (part of the main SQLite library - not an extension) so that
|
||||
** it can get access to the sqlite3_api_routines structure
|
||||
** definition. But the main library does not want to redefine
|
||||
** the API. So the redefinition macros are only valid if the
|
||||
** SQLITE_CORE macros is undefined.
|
||||
*/
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#endif
|
||||
/* Version 3.7.16 and later */
|
||||
/* Version 3.8.7 and later */
|
||||
/* Version 3.8.11 and later */
|
||||
/* Version 3.9.0 and later */
|
||||
/* Version 3.10.0 and later */
|
||||
/* Version 3.12.0 and later */
|
||||
/* Version 3.14.0 and later */
|
||||
/* Version 3.18.0 and later */
|
||||
/* Version 3.20.0 and later */
|
||||
/* Version 3.22.0 and later */
|
||||
/* Version 3.24.0 and later */
|
||||
/* Version 3.25.0 and later */
|
||||
/* Version 3.26.0 and later */
|
||||
/* Version 3.28.0 and later */
|
||||
/* Version 3.30.0 and later */
|
||||
/* Version 3.31.0 and later */
|
||||
/* Version 3.32.0 and later */
|
||||
/* Version 3.34.0 and later */
|
||||
/* Version 3.36.1 and later */
|
||||
/* Version 3.37.0 and later */
|
||||
/* Version 3.38.0 and later */
|
||||
/* Version 3.39.0 and later */
|
||||
#ifndef SQLITE_OMIT_DESERIALIZE
|
||||
#endif
|
||||
/* Version 3.40.0 and later */
|
||||
/* Version 3.41.0 and later */
|
||||
/* Version 3.43.0 and later */
|
||||
/* Version 3.44.0 and later */
|
||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
/* This case when the file really is being compiled as a loadable
|
||||
** extension */
|
||||
# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
|
||||
# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v;
|
||||
# define SQLITE_EXTENSION_INIT3 \
|
||||
extern const sqlite3_api_routines *sqlite3_api;
|
||||
#else
|
||||
/* This case when the file is being statically linked into the
|
||||
** application */
|
||||
# define SQLITE_EXTENSION_INIT1 /*no-op*/
|
||||
# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */
|
||||
# define SQLITE_EXTENSION_INIT3 /*no-op*/
|
||||
#endif
|
||||
|
||||
#endif /* SQLITE3EXT_H */
|
||||
808
zig-vendor/zig-sqlite/c/loadable_extension.zig
Normal file
808
zig-vendor/zig-sqlite/c/loadable_extension.zig
Normal file
@@ -0,0 +1,808 @@
|
||||
pub const c = @cImport({
|
||||
@cInclude("loadable-ext-sqlite3ext.h");
|
||||
@cInclude("workaround.h");
|
||||
});
|
||||
|
||||
pub var sqlite3_api: [*c]c.sqlite3_api_routines = null;
|
||||
|
||||
pub const sqlite3_transfer_bindings = @compileError("sqlite3_transfer_bindings is deprecated");
|
||||
pub const sqlite3_global_recover = @compileError("sqlite3_global_recover is deprecated");
|
||||
pub const sqlite3_expired = @compileError("sqlite3_expired is deprecated");
|
||||
|
||||
pub const sqlite3_mprintf = @compileError("sqlite3_mprintf can't be implemented in Zig");
|
||||
pub const sqlite3_snprintf = @compileError("sqlite3_snprintf can't be implemented in Zig");
|
||||
pub const sqlite3_vmprintf = @compileError("sqlite3_vmprintf can't be implemented in Zig");
|
||||
pub const sqlite3_vsnprintf = @compileError("sqlite3_vsnprintf can't be implemented in Zig");
|
||||
pub const sqlite3_test_control = @compileError("sqlite3_test_control can't be implemented in Zig");
|
||||
pub const sqlite3_db_config = @compileError("sqlite3_db_config can't be implemented in Zig");
|
||||
pub const sqlite3_log = @compileError("sqlite3_log can't be implemented in Zig");
|
||||
pub const sqlite3_vtab_config = @compileError("sqlite3_vtab_config can't be implemented in Zig");
|
||||
pub const sqlite3_uri_vsnprintf = @compileError("sqlite3_uri_vsnprintf can't be implemented in Zig");
|
||||
pub const sqlite3_str_appendf = @compileError("sqlite3_str_appendf can't be implemented in Zig");
|
||||
pub const sqlite3_str_vappendf = @compileError("sqlite3_str_vappendf can't be implemented in Zig");
|
||||
|
||||
pub export fn sqlite3_aggregate_context(p: ?*c.sqlite3_context, nBytes: c_int) callconv(.c) ?*anyopaque {
|
||||
return sqlite3_api.*.aggregate_context.?(p, nBytes);
|
||||
}
|
||||
pub export fn sqlite3_bind_blob(pStmt: ?*c.sqlite3_stmt, i: c_int, zData: ?*const anyopaque, nData: c_int, xDel: ?*const fn (?*anyopaque) callconv(.c) void) c_int {
|
||||
return sqlite3_api.*.bind_blob.?(pStmt, i, zData, nData, xDel);
|
||||
}
|
||||
pub export fn sqlite3_bind_double(pStmt: ?*c.sqlite3_stmt, i: c_int, rValue: f64) callconv(.c) c_int {
|
||||
return sqlite3_api.*.bind_double.?(pStmt, i, rValue);
|
||||
}
|
||||
pub export fn sqlite3_bind_int(pStmt: ?*c.sqlite3_stmt, i: c_int, iValue: c_int) callconv(.c) c_int {
|
||||
return sqlite3_api.*.bind_int.?(pStmt, i, iValue);
|
||||
}
|
||||
pub export fn sqlite3_bind_int64(pStmt: ?*c.sqlite3_stmt, i: c_int, iValue: c.sqlite3_int64) c_int {
|
||||
return sqlite3_api.*.bind_int64.?(pStmt, i, iValue);
|
||||
}
|
||||
pub export fn sqlite3_bind_null(pStmt: ?*c.sqlite3_stmt, i: c_int) c_int {
|
||||
return sqlite3_api.*.bind_null.?(pStmt, i);
|
||||
}
|
||||
pub export fn sqlite3_bind_parameter_count(pStmt: ?*c.sqlite3_stmt) c_int {
|
||||
return sqlite3_api.*.bind_parameter_count.?(pStmt);
|
||||
}
|
||||
pub export fn sqlite3_bind_parameter_index(pStmt: ?*c.sqlite3_stmt, zName: [*c]const u8) c_int {
|
||||
return sqlite3_api.*.bind_parameter_index.?(pStmt, zName);
|
||||
}
|
||||
pub export fn sqlite3_bind_parameter_name(pStmt: ?*c.sqlite3_stmt, i: c_int) [*c]const u8 {
|
||||
return sqlite3_api.*.bind_parameter_name.?(pStmt, i);
|
||||
}
|
||||
pub export fn sqlite3_bind_text(pStmt: ?*c.sqlite3_stmt, i: c_int, zData: [*c]const u8, nData: c_int, xDel: ?*const fn (?*anyopaque) callconv(.c) void) c_int {
|
||||
return sqlite3_api.*.bind_text.?(pStmt, i, zData, nData, xDel);
|
||||
}
|
||||
pub export fn sqlite3_bind_text16(pStmt: ?*c.sqlite3_stmt, i: c_int, zData: ?*const anyopaque, nData: c_int, xDel: ?*const fn (?*anyopaque) callconv(.c) void) c_int {
|
||||
return sqlite3_api.*.bind_text16.?(pStmt, i, zData, nData, xDel);
|
||||
}
|
||||
pub export fn sqlite3_bind_value(pStmt: ?*c.sqlite3_stmt, i: c_int, pValue: ?*const c.sqlite3_value) c_int {
|
||||
return sqlite3_api.*.bind_value.?(pStmt, i, pValue);
|
||||
}
|
||||
pub export fn sqlite3_busy_handler(db: ?*c.sqlite3, xBusy: ?*const fn (?*anyopaque, c_int) callconv(.c) c_int, pArg: ?*anyopaque) c_int {
|
||||
return sqlite3_api.*.busy_handler.?(db, xBusy, pArg);
|
||||
}
|
||||
pub export fn sqlite3_busy_timeout(db: ?*c.sqlite3, ms: c_int) c_int {
|
||||
return sqlite3_api.*.busy_timeout.?(db, ms);
|
||||
}
|
||||
pub export fn sqlite3_changes(db: ?*c.sqlite3) c_int {
|
||||
return sqlite3_api.*.changes.?(db);
|
||||
}
|
||||
pub export fn sqlite3_close(db: ?*c.sqlite3) c_int {
|
||||
return sqlite3_api.*.close.?(db);
|
||||
}
|
||||
pub export fn sqlite3_collation_needed(db: ?*c.sqlite3, pCollNeededArg: ?*anyopaque, xCollNeeded: ?*const fn (?*anyopaque, ?*c.sqlite3, c_int, [*c]const u8) callconv(.c) void) c_int {
|
||||
return sqlite3_api.*.collation_needed.?(db, pCollNeededArg, xCollNeeded);
|
||||
}
|
||||
pub export fn sqlite3_collation_needed16(db: ?*c.sqlite3, pCollNeededArg: ?*anyopaque, xCollNeeded16: ?*const fn (?*anyopaque, ?*c.sqlite3, c_int, ?*const anyopaque) callconv(.c) void) c_int {
|
||||
return sqlite3_api.*.collation_needed16.?(db, pCollNeededArg, xCollNeeded16);
|
||||
}
|
||||
pub export fn sqlite3_column_blob(pStmt: ?*c.sqlite3_stmt, iCol: c_int) ?*const anyopaque {
|
||||
return sqlite3_api.*.column_blob.?(pStmt, iCol);
|
||||
}
|
||||
pub export fn sqlite3_column_bytes(pStmt: ?*c.sqlite3_stmt, iCol: c_int) c_int {
|
||||
return sqlite3_api.*.column_bytes.?(pStmt, iCol);
|
||||
}
|
||||
pub export fn sqlite3_column_bytes16(pStmt: ?*c.sqlite3_stmt, iCol: c_int) c_int {
|
||||
return sqlite3_api.*.column_bytes16.?(pStmt, iCol);
|
||||
}
|
||||
pub export fn sqlite3_column_count(pStmt: ?*c.sqlite3_stmt) c_int {
|
||||
return sqlite3_api.*.column_count.?(pStmt);
|
||||
}
|
||||
pub export fn sqlite3_column_database_name(pStmt: ?*c.sqlite3_stmt, iCol: c_int) [*c]const u8 {
|
||||
return sqlite3_api.*.column_database_name.?(pStmt, iCol);
|
||||
}
|
||||
pub export fn sqlite3_column_database_name16(pStmt: ?*c.sqlite3_stmt, iCol: c_int) ?*const anyopaque {
|
||||
return sqlite3_api.*.column_database_name16.?(pStmt, iCol);
|
||||
}
|
||||
pub export fn sqlite3_column_decltype(pStmt: ?*c.sqlite3_stmt, iCol: c_int) [*c]const u8 {
|
||||
return sqlite3_api.*.column_decltype.?(pStmt, iCol);
|
||||
}
|
||||
pub export fn sqlite3_column_decltype16(pStmt: ?*c.sqlite3_stmt, iCol: c_int) ?*const anyopaque {
|
||||
return sqlite3_api.*.column_decltype16.?(pStmt, iCol);
|
||||
}
|
||||
pub export fn sqlite3_column_double(pStmt: ?*c.sqlite3_stmt, iCol: c_int) f64 {
|
||||
return sqlite3_api.*.column_double.?(pStmt, iCol);
|
||||
}
|
||||
pub export fn sqlite3_column_int(pStmt: ?*c.sqlite3_stmt, iCol: c_int) c_int {
|
||||
return sqlite3_api.*.column_int.?(pStmt, iCol);
|
||||
}
|
||||
pub export fn sqlite3_column_int64(pStmt: ?*c.sqlite3_stmt, iCol: c_int) c.sqlite3_int64 {
|
||||
return sqlite3_api.*.column_int64.?(pStmt, iCol);
|
||||
}
|
||||
pub export fn sqlite3_column_name(pStmt: ?*c.sqlite3_stmt, N: c_int) [*c]const u8 {
|
||||
return sqlite3_api.*.column_name.?(pStmt, N);
|
||||
}
|
||||
pub export fn sqlite3_column_name16(pStmt: ?*c.sqlite3_stmt, N: c_int) ?*const anyopaque {
|
||||
return sqlite3_api.*.column_name16.?(pStmt, N);
|
||||
}
|
||||
pub export fn sqlite3_column_origin_name(pStmt: ?*c.sqlite3_stmt, N: c_int) [*c]const u8 {
|
||||
return sqlite3_api.*.column_origin_name.?(pStmt, N);
|
||||
}
|
||||
pub export fn sqlite3_column_origin_name16(pStmt: ?*c.sqlite3_stmt, N: c_int) ?*const anyopaque {
|
||||
return sqlite3_api.*.column_origin_name16.?(pStmt, N);
|
||||
}
|
||||
pub export fn sqlite3_column_table_name(pStmt: ?*c.sqlite3_stmt, N: c_int) [*c]const u8 {
|
||||
return sqlite3_api.*.column_table_name.?(pStmt, N);
|
||||
}
|
||||
pub export fn sqlite3_column_table_name16(pStmt: ?*c.sqlite3_stmt, N: c_int) ?*const anyopaque {
|
||||
return sqlite3_api.*.column_table_name16.?(pStmt, N);
|
||||
}
|
||||
pub export fn sqlite3_column_text(pStmt: ?*c.sqlite3_stmt, iCol: c_int) [*c]const u8 {
|
||||
return sqlite3_api.*.column_text.?(pStmt, iCol);
|
||||
}
|
||||
pub export fn sqlite3_column_text16(pStmt: ?*c.sqlite3_stmt, iCol: c_int) ?*const anyopaque {
|
||||
return sqlite3_api.*.column_text16.?(pStmt, iCol);
|
||||
}
|
||||
pub export fn sqlite3_column_type(pStmt: ?*c.sqlite3_stmt, iCol: c_int) c_int {
|
||||
return sqlite3_api.*.column_type.?(pStmt, iCol);
|
||||
}
|
||||
pub export fn sqlite3_column_value(pStmt: ?*c.sqlite3_stmt, iCol: c_int) ?*c.sqlite3_value {
|
||||
return sqlite3_api.*.column_value.?(pStmt, iCol);
|
||||
}
|
||||
pub export fn sqlite3_commit_hook(db: ?*c.sqlite3, xCallback: ?*const fn (?*anyopaque) callconv(.c) c_int, pArg: ?*anyopaque) ?*anyopaque {
|
||||
return sqlite3_api.*.commit_hook.?(db, xCallback, pArg);
|
||||
}
|
||||
pub export fn sqlite3_complete(sql: [*c]const u8) c_int {
|
||||
return sqlite3_api.*.complete.?(sql);
|
||||
}
|
||||
pub export fn sqlite3_complete16(sql: ?*const anyopaque) c_int {
|
||||
return sqlite3_api.*.complete16.?(sql);
|
||||
}
|
||||
pub export fn sqlite3_create_collation(db: ?*c.sqlite3, zName: [*c]const u8, eTextRep: c_int, pArg: ?*anyopaque, xCompare: ?*const fn (?*anyopaque, c_int, ?*const anyopaque, c_int, ?*const anyopaque) callconv(.c) c_int) c_int {
|
||||
return sqlite3_api.*.create_collation.?(db, zName, eTextRep, pArg, xCompare);
|
||||
}
|
||||
pub export fn sqlite3_create_collation16(db: ?*c.sqlite3, zName: ?*const anyopaque, eTextRep: c_int, pArg: ?*anyopaque, xCompare: ?*const fn (?*anyopaque, c_int, ?*const anyopaque, c_int, ?*const anyopaque) callconv(.c) c_int) c_int {
|
||||
return sqlite3_api.*.create_collation16.?(db, zName, eTextRep, pArg, xCompare);
|
||||
}
|
||||
pub export fn sqlite3_create_function(db: ?*c.sqlite3, zFunctionName: [*c]const u8, nArg: c_int, eTextRep: c_int, pApp: ?*anyopaque, xFunc: ?*const fn (?*c.sqlite3_context, c_int, [*c]?*c.sqlite3_value) callconv(.c) void, xStep: ?*const fn (?*c.sqlite3_context, c_int, [*c]?*c.sqlite3_value) callconv(.c) void, xFinal: ?*const fn (?*c.sqlite3_context) callconv(.c) void) c_int {
|
||||
return sqlite3_api.*.create_function.?(db, zFunctionName, nArg, eTextRep, pApp, xFunc, xStep, xFinal);
|
||||
}
|
||||
pub export fn sqlite3_create_function16(db: ?*c.sqlite3, zFunctionName: ?*const anyopaque, nArg: c_int, eTextRep: c_int, pApp: ?*anyopaque, xFunc: ?*const fn (?*c.sqlite3_context, c_int, [*c]?*c.sqlite3_value) callconv(.c) void, xStep: ?*const fn (?*c.sqlite3_context, c_int, [*c]?*c.sqlite3_value) callconv(.c) void, xFinal: ?*const fn (?*c.sqlite3_context) callconv(.c) void) c_int {
|
||||
return sqlite3_api.*.create_function16.?(db, zFunctionName, nArg, eTextRep, pApp, xFunc, xStep, xFinal);
|
||||
}
|
||||
pub export fn sqlite3_create_module(db: ?*c.sqlite3, zName: [*c]const u8, pModule: [*c]const c.sqlite3_module, pAux: ?*anyopaque) c_int {
|
||||
return sqlite3_api.*.create_module.?(db, zName, pModule, pAux);
|
||||
}
|
||||
pub export fn sqlite3_create_module_v2(db: ?*c.sqlite3, zName: [*c]const u8, pModule: [*c]const c.sqlite3_module, pAux: ?*anyopaque, xDestroy: ?*const fn (?*anyopaque) callconv(.c) void) c_int {
|
||||
return sqlite3_api.*.create_module_v2.?(db, zName, pModule, pAux, xDestroy);
|
||||
}
|
||||
pub export fn sqlite3_data_count(pStmt: ?*c.sqlite3_stmt) c_int {
|
||||
return sqlite3_api.*.data_count.?(pStmt);
|
||||
}
|
||||
pub export fn sqlite3_db_handle(pStmt: ?*c.sqlite3_stmt) ?*c.sqlite3 {
|
||||
return sqlite3_api.*.db_handle.?(pStmt);
|
||||
}
|
||||
|
||||
pub export fn sqlite3_declare_vtab(db: ?*c.sqlite3, zSQL: [*c]const u8) c_int {
|
||||
return sqlite3_api.*.declare_vtab.?(db, zSQL);
|
||||
}
|
||||
pub export fn sqlite3_enable_shared_cache(enable: c_int) c_int {
|
||||
return sqlite3_api.*.enable_shared_cache.?(enable);
|
||||
}
|
||||
pub export fn sqlite3_errcode(db: ?*c.sqlite3) c_int {
|
||||
return sqlite3_api.*.errcode.?(db);
|
||||
}
|
||||
pub export fn sqlite3_errmsg(db: ?*c.sqlite3) [*c]const u8 {
|
||||
return sqlite3_api.*.errmsg.?(db);
|
||||
}
|
||||
pub export fn sqlite3_errmsg16(db: ?*c.sqlite3) ?*const anyopaque {
|
||||
return sqlite3_api.*.errmsg16.?(db);
|
||||
}
|
||||
pub export fn sqlite3_exec(db: ?*c.sqlite3, zSql: [*c]const u8, xCallback: ?*const fn (?*anyopaque, c_int, [*c][*c]u8, [*c][*c]u8) callconv(.c) c_int, pArg: ?*anyopaque, pzErrMsg: [*c][*c]u8) c_int {
|
||||
return sqlite3_api.*.exec.?(db, zSql, xCallback, pArg, pzErrMsg);
|
||||
}
|
||||
pub export fn sqlite3_finalize(pStmt: ?*c.sqlite3_stmt) c_int {
|
||||
return sqlite3_api.*.finalize.?(pStmt);
|
||||
}
|
||||
pub export fn sqlite3_free(p: ?*anyopaque) void {
|
||||
return sqlite3_api.*.free.?(p);
|
||||
}
|
||||
pub export fn sqlite3_free_table(result: [*c][*c]u8) void {
|
||||
return sqlite3_api.*.free_table.?(result);
|
||||
}
|
||||
pub export fn sqlite3_get_autocommit(db: ?*c.sqlite3) c_int {
|
||||
return sqlite3_api.*.get_autocommit.?(db);
|
||||
}
|
||||
pub export fn sqlite3_get_auxdata(pCtx: ?*c.sqlite3_context, iArg: c_int) ?*anyopaque {
|
||||
return sqlite3_api.*.get_auxdata.?(pCtx, iArg);
|
||||
}
|
||||
pub export fn sqlite3_get_table(db: ?*c.sqlite3, zSql: [*c]const u8, pazResult: [*c][*c][*c]u8, pnRow: [*c]c_int, pnColumn: [*c]c_int, pzErrMsg: [*c][*c]u8) c_int {
|
||||
return sqlite3_api.*.get_table.?(db, zSql, pazResult, pnRow, pnColumn, pzErrMsg);
|
||||
}
|
||||
pub export fn sqlite3_interrupt(db: ?*c.sqlite3) void {
|
||||
return sqlite3_api.*.interruptx.?(db);
|
||||
}
|
||||
pub export fn sqlite3_last_insert_rowid(db: ?*c.sqlite3) c.sqlite3_int64 {
|
||||
return sqlite3_api.*.last_insert_rowid.?(db);
|
||||
}
|
||||
pub export fn sqlite3_libversion() callconv(.c) [*c]const u8 {
|
||||
return sqlite3_api.*.libversion.?();
|
||||
}
|
||||
pub export fn sqlite3_libversion_number() c_int {
|
||||
return sqlite3_api.*.libversion_number.?();
|
||||
}
|
||||
pub export fn sqlite3_malloc(n: c_int) ?*anyopaque {
|
||||
return sqlite3_api.*.malloc.?(n);
|
||||
}
|
||||
pub export fn sqlite3_open(filename: [*c]const u8, ppDb: [*c]?*c.sqlite3) c_int {
|
||||
return sqlite3_api.*.open.?(filename, ppDb);
|
||||
}
|
||||
pub export fn sqlite3_open16(filename: ?*const anyopaque, ppDb: [*c]?*c.sqlite3) c_int {
|
||||
return sqlite3_api.*.open16.?(filename, ppDb);
|
||||
}
|
||||
pub export fn sqlite3_prepare(db: ?*c.sqlite3, zSql: [*c]const u8, nByte: c_int, ppStmt: [*c]?*c.sqlite3_stmt, pzTail: [*c][*c]const u8) c_int {
|
||||
return sqlite3_api.*.prepare.?(db, zSql, nByte, ppStmt, pzTail);
|
||||
}
|
||||
pub export fn sqlite3_prepare16(db: ?*c.sqlite3, zSql: ?*const anyopaque, nByte: c_int, ppStmt: [*c]?*c.sqlite3_stmt, pzTail: [*c]?*const anyopaque) c_int {
|
||||
return sqlite3_api.*.prepare16.?(db, zSql, nByte, ppStmt, pzTail);
|
||||
}
|
||||
pub export fn sqlite3_prepare_v2(db: ?*c.sqlite3, zSql: [*c]const u8, nByte: c_int, ppStmt: [*c]?*c.sqlite3_stmt, pzTail: [*c][*c]const u8) c_int {
|
||||
return sqlite3_api.*.prepare_v2.?(db, zSql, nByte, ppStmt, pzTail);
|
||||
}
|
||||
pub export fn sqlite3_prepare16_v2(db: ?*c.sqlite3, zSql: ?*const anyopaque, nByte: c_int, ppStmt: [*c]?*c.sqlite3_stmt, pzTail: [*c]?*const anyopaque) c_int {
|
||||
return sqlite3_api.*.prepare16_v2.?(db, zSql, nByte, ppStmt, pzTail);
|
||||
}
|
||||
pub export fn sqlite3_profile(db: ?*c.sqlite3, xProfile: ?*const fn (?*anyopaque, [*c]const u8, c.sqlite3_uint64) callconv(.c) void, pArg: ?*anyopaque) ?*anyopaque {
|
||||
return sqlite3_api.*.profile.?(db, xProfile, pArg);
|
||||
}
|
||||
pub export fn sqlite3_progress_handler(db: ?*c.sqlite3, nOps: c_int, xProgress: ?*const fn (?*anyopaque) callconv(.c) c_int, pArg: ?*anyopaque) void {
|
||||
return sqlite3_api.*.progress_handler.?(db, nOps, xProgress, pArg);
|
||||
}
|
||||
pub export fn sqlite3_realloc(pOld: ?*anyopaque, n: c_int) ?*anyopaque {
|
||||
return sqlite3_api.*.realloc.?(pOld, n);
|
||||
}
|
||||
pub export fn sqlite3_reset(pStmt: ?*c.sqlite3_stmt) c_int {
|
||||
return sqlite3_api.*.reset.?(pStmt);
|
||||
}
|
||||
pub export fn sqlite3_result_blob(pCtx: ?*c.sqlite3_context, z: ?*const anyopaque, n: c_int, xDel: ?*const fn (?*anyopaque) callconv(.c) void) void {
|
||||
return sqlite3_api.*.result_blob.?(pCtx, z, n, xDel);
|
||||
}
|
||||
|
||||
pub export fn sqlite3_result_double(pCtx: ?*c.sqlite3_context, rVal: f64) void {
|
||||
return sqlite3_api.*.result_double.?(pCtx, rVal);
|
||||
}
|
||||
|
||||
pub export fn sqlite3_result_error(pCtx: ?*c.sqlite3_context, z: [*c]const u8, n: c_int) void {
|
||||
return sqlite3_api.*.result_error.?(pCtx, z, n);
|
||||
}
|
||||
pub export fn sqlite3_result_error16(pCtx: ?*c.sqlite3_context, z: ?*const anyopaque, n: c_int) void {
|
||||
return sqlite3_api.*.result_error16.?(pCtx, z, n);
|
||||
}
|
||||
pub export fn sqlite3_result_int(pCtx: ?*c.sqlite3_context, iVal: c_int) void {
|
||||
return sqlite3_api.*.result_int.?(pCtx, iVal);
|
||||
}
|
||||
pub export fn sqlite3_result_int64(pCtx: ?*c.sqlite3_context, iVal: c.sqlite3_int64) void {
|
||||
return sqlite3_api.*.result_int64.?(pCtx, iVal);
|
||||
}
|
||||
pub export fn sqlite3_result_null(pCtx: ?*c.sqlite3_context) void {
|
||||
return sqlite3_api.*.result_null.?(pCtx);
|
||||
}
|
||||
pub export fn sqlite3_result_text(pCtx: ?*c.sqlite3_context, z: [*c]const u8, n: c_int, xDel: ?*const fn (?*anyopaque) callconv(.c) void) void {
|
||||
return sqlite3_api.*.result_text.?(pCtx, z, n, xDel);
|
||||
}
|
||||
pub export fn sqlite3_result_text16(pCtx: ?*c.sqlite3_context, z: ?*const anyopaque, n: c_int, xDel: ?*const fn (?*anyopaque) callconv(.c) void) void {
|
||||
return sqlite3_api.*.result_text16.?(pCtx, z, n, xDel);
|
||||
}
|
||||
pub export fn sqlite3_result_text16be(pCtx: ?*c.sqlite3_context, z: ?*const anyopaque, n: c_int, xDel: ?*const fn (?*anyopaque) callconv(.c) void) void {
|
||||
return sqlite3_api.*.result_text16be.?(pCtx, z, n, xDel);
|
||||
}
|
||||
pub export fn sqlite3_result_text16le(pCtx: ?*c.sqlite3_context, z: ?*const anyopaque, n: c_int, xDel: ?*const fn (?*anyopaque) callconv(.c) void) void {
|
||||
return sqlite3_api.*.result_text16le.?(pCtx, z, n, xDel);
|
||||
}
|
||||
pub export fn sqlite3_result_value(pCtx: ?*c.sqlite3_context, pValue: ?*c.sqlite3_value) void {
|
||||
return sqlite3_api.*.result_value.?(pCtx, pValue);
|
||||
}
|
||||
pub export fn sqlite3_rollback_hook(db: ?*c.sqlite3, xCallback: ?*const fn (?*anyopaque) callconv(.c) void, pArg: ?*anyopaque) ?*anyopaque {
|
||||
return sqlite3_api.*.rollback_hook.?(db, xCallback, pArg);
|
||||
}
|
||||
pub export fn sqlite3_set_authorizer(db: ?*c.sqlite3, xAuth: ?*const fn (?*anyopaque, c_int, [*c]const u8, [*c]const u8, [*c]const u8, [*c]const u8) callconv(.c) c_int, pArg: ?*anyopaque) c_int {
|
||||
return sqlite3_api.*.set_authorizer.?(db, xAuth, pArg);
|
||||
}
|
||||
pub export fn sqlite3_set_auxdata(pCtx: ?*c.sqlite3_context, iArg: c_int, pAux: ?*anyopaque, xDelete: ?*const fn (?*anyopaque) callconv(.c) void) void {
|
||||
return sqlite3_api.*.set_auxdata.?(pCtx, iArg, pAux, xDelete);
|
||||
}
|
||||
pub export fn sqlite3_step(pStmt: ?*c.sqlite3_stmt) c_int {
|
||||
return sqlite3_api.*.step.?(pStmt);
|
||||
}
|
||||
pub export fn sqlite3_table_column_metadata(db: ?*c.sqlite3, zDbName: [*c]const u8, zTableName: [*c]const u8, zColumnName: [*c]const u8, pzDataType: [*c][*c]const u8, pzCollSeq: [*c][*c]const u8, pNotNull: [*c]c_int, pPrimaryKey: [*c]c_int, pAutoinc: [*c]c_int) c_int {
|
||||
return sqlite3_api.*.table_column_metadata.?(db, zDbName, zTableName, zColumnName, pzDataType, pzCollSeq, pNotNull, pPrimaryKey, pAutoinc);
|
||||
}
|
||||
pub export fn sqlite3_thread_cleanup() void {
|
||||
return sqlite3_api.*.thread_cleanup.?();
|
||||
}
|
||||
pub export fn sqlite3_total_changes(db: ?*c.sqlite3) c_int {
|
||||
return sqlite3_api.*.total_changes.?(db);
|
||||
}
|
||||
pub export fn sqlite3_trace(db: ?*c.sqlite3, xTrace: ?*const fn (?*anyopaque, [*c]const u8) callconv(.c) void, pArg: ?*anyopaque) ?*anyopaque {
|
||||
return sqlite3_api.*.trace.?(db, xTrace, pArg);
|
||||
}
|
||||
pub export fn sqlite3_update_hook(db: ?*c.sqlite3, xCallback: ?*const fn (?*anyopaque, c_int, [*c]const u8, [*c]const u8, c.sqlite3_int64) callconv(.c) void, pArg: ?*anyopaque) ?*anyopaque {
|
||||
return sqlite3_api.*.update_hook.?(db, xCallback, pArg);
|
||||
}
|
||||
pub export fn sqlite3_user_data(pCtx: ?*c.sqlite3_context) ?*anyopaque {
|
||||
return sqlite3_api.*.user_data.?(pCtx);
|
||||
}
|
||||
pub export fn sqlite3_value_blob(pVal: ?*c.sqlite3_value) ?*const anyopaque {
|
||||
return sqlite3_api.*.value_blob.?(pVal);
|
||||
}
|
||||
pub export fn sqlite3_value_bytes(pVal: ?*c.sqlite3_value) c_int {
|
||||
return sqlite3_api.*.value_bytes.?(pVal);
|
||||
}
|
||||
pub export fn sqlite3_value_bytes16(pVal: ?*c.sqlite3_value) c_int {
|
||||
return sqlite3_api.*.value_bytes16.?(pVal);
|
||||
}
|
||||
pub export fn sqlite3_value_double(pVal: ?*c.sqlite3_value) f64 {
|
||||
return sqlite3_api.*.value_double.?(pVal);
|
||||
}
|
||||
pub export fn sqlite3_value_int(pVal: ?*c.sqlite3_value) c_int {
|
||||
return sqlite3_api.*.value_int.?(pVal);
|
||||
}
|
||||
pub export fn sqlite3_value_int64(pVal: ?*c.sqlite3_value) c.sqlite3_int64 {
|
||||
return sqlite3_api.*.value_int64.?(pVal);
|
||||
}
|
||||
pub export fn sqlite3_value_numeric_type(pVal: ?*c.sqlite3_value) c_int {
|
||||
return sqlite3_api.*.value_numeric_type.?(pVal);
|
||||
}
|
||||
pub export fn sqlite3_value_text(pVal: ?*c.sqlite3_value) [*c]const u8 {
|
||||
return sqlite3_api.*.value_text.?(pVal);
|
||||
}
|
||||
pub export fn sqlite3_value_text16(pVal: ?*c.sqlite3_value) ?*const anyopaque {
|
||||
return sqlite3_api.*.value_text16.?(pVal);
|
||||
}
|
||||
pub export fn sqlite3_value_text16be(pVal: ?*c.sqlite3_value) ?*const anyopaque {
|
||||
return sqlite3_api.*.value_text16be.?(pVal);
|
||||
}
|
||||
pub export fn sqlite3_value_text16le(pVal: ?*c.sqlite3_value) ?*const anyopaque {
|
||||
return sqlite3_api.*.value_text16le.?(pVal);
|
||||
}
|
||||
pub export fn sqlite3_value_type(pVal: ?*c.sqlite3_value) c_int {
|
||||
return sqlite3_api.*.value_type.?(pVal);
|
||||
}
|
||||
pub export fn sqlite3_overload_function(db: ?*c.sqlite3, zFuncName: [*c]const u8, nArg: c_int) c_int {
|
||||
return sqlite3_api.*.overload_function.?(db, zFuncName, nArg);
|
||||
}
|
||||
pub export fn sqlite3_clear_bindings(pStmt: ?*c.sqlite3_stmt) c_int {
|
||||
return sqlite3_api.*.clear_bindings.?(pStmt);
|
||||
}
|
||||
pub export fn sqlite3_bind_zeroblob(pStmt: ?*c.sqlite3_stmt, i: c_int, n: c_int) c_int {
|
||||
return sqlite3_api.*.bind_zeroblob.?(pStmt, i, n);
|
||||
}
|
||||
pub export fn sqlite3_blob_bytes(pBlob: ?*c.sqlite3_blob) c_int {
|
||||
return sqlite3_api.*.blob_bytes.?(pBlob);
|
||||
}
|
||||
pub export fn sqlite3_blob_close(pBlob: ?*c.sqlite3_blob) c_int {
|
||||
return sqlite3_api.*.blob_close.?(pBlob);
|
||||
}
|
||||
pub export fn sqlite3_blob_open(db: ?*c.sqlite3, zDb: [*c]const u8, zTable: [*c]const u8, zColumn: [*c]const u8, iRow: c.sqlite3_int64, flags: c_int, ppBlob: [*c]?*c.sqlite3_blob) c_int {
|
||||
return sqlite3_api.*.blob_open.?(db, zDb, zTable, zColumn, iRow, flags, ppBlob);
|
||||
}
|
||||
pub export fn sqlite3_blob_read(pBlob: ?*c.sqlite3_blob, z: ?*anyopaque, n: c_int, iOffset: c_int) c_int {
|
||||
return sqlite3_api.*.blob_read.?(pBlob, z, n, iOffset);
|
||||
}
|
||||
pub export fn sqlite3_blob_write(pBlob: ?*c.sqlite3_blob, z: ?*const anyopaque, n: c_int, iOffset: c_int) c_int {
|
||||
return sqlite3_api.*.blob_write.?(pBlob, z, n, iOffset);
|
||||
}
|
||||
pub export fn sqlite3_create_collation_v2(db: ?*c.sqlite3, zName: [*c]const u8, eTextRep: c_int, pCtx: ?*anyopaque, xCompare: ?*const fn (?*anyopaque, c_int, ?*const anyopaque, c_int, ?*const anyopaque) callconv(.c) c_int, xDel: ?*const fn (?*anyopaque) callconv(.c) void) c_int {
|
||||
return sqlite3_api.*.create_collation_v2.?(db, zName, eTextRep, pCtx, xCompare, xDel);
|
||||
}
|
||||
pub export fn sqlite3_file_control(db: ?*c.sqlite3, zDbName: [*c]const u8, op: c_int, pArg: ?*anyopaque) c_int {
|
||||
return sqlite3_api.*.file_control.?(db, zDbName, op, pArg);
|
||||
}
|
||||
pub export fn sqlite3_memory_highwater(resetFlag: c_int) c.sqlite3_int64 {
|
||||
return sqlite3_api.*.memory_highwater.?(resetFlag);
|
||||
}
|
||||
pub export fn sqlite3_memory_used() c.sqlite3_int64 {
|
||||
return sqlite3_api.*.memory_used.?();
|
||||
}
|
||||
pub export fn sqlite3_mutex_alloc(id: c_int) ?*c.sqlite3_mutex {
|
||||
return sqlite3_api.*.mutex_alloc.?(id);
|
||||
}
|
||||
pub export fn sqlite3_mutex_enter(p: ?*c.sqlite3_mutex) void {
|
||||
return sqlite3_api.*.mutex_enter.?(p);
|
||||
}
|
||||
pub export fn sqlite3_mutex_free(p: ?*c.sqlite3_mutex) void {
|
||||
return sqlite3_api.*.mutex_free.?(p);
|
||||
}
|
||||
pub export fn sqlite3_mutex_leave(p: ?*c.sqlite3_mutex) void {
|
||||
return sqlite3_api.*.mutex_leave.?(p);
|
||||
}
|
||||
pub export fn sqlite3_mutex_try(p: ?*c.sqlite3_mutex) c_int {
|
||||
return sqlite3_api.*.mutex_try.?(p);
|
||||
}
|
||||
pub export fn sqlite3_open_v2(filename: [*c]const u8, ppDb: [*c]?*c.sqlite3, flags: c_int, zVfs: [*c]const u8) c_int {
|
||||
return sqlite3_api.*.open_v2.?(filename, ppDb, flags, zVfs);
|
||||
}
|
||||
pub export fn sqlite3_release_memory(n: c_int) c_int {
|
||||
return sqlite3_api.*.release_memory.?(n);
|
||||
}
|
||||
pub export fn sqlite3_result_error_nomem(pCtx: ?*c.sqlite3_context) void {
|
||||
return sqlite3_api.*.result_error_nomem.?(pCtx);
|
||||
}
|
||||
pub export fn sqlite3_result_error_toobig(pCtx: ?*c.sqlite3_context) void {
|
||||
return sqlite3_api.*.result_error_toobig.?(pCtx);
|
||||
}
|
||||
pub export fn sqlite3_sleep(ms: c_int) c_int {
|
||||
return sqlite3_api.*.sleep.?(ms);
|
||||
}
|
||||
pub export fn sqlite3_soft_heap_limit(n: c_int) void {
|
||||
return sqlite3_api.*.soft_heap_limit.?(n);
|
||||
}
|
||||
pub export fn sqlite3_vfs_find(zVfsName: [*c]const u8) [*c]c.sqlite3_vfs {
|
||||
return sqlite3_api.*.vfs_find.?(zVfsName);
|
||||
}
|
||||
pub export fn sqlite3_vfs_register(pVfs: [*c]c.sqlite3_vfs, makeDflt: c_int) c_int {
|
||||
return sqlite3_api.*.vfs_register.?(pVfs, makeDflt);
|
||||
}
|
||||
pub export fn sqlite3_vfs_unregister(pVfs: [*c]c.sqlite3_vfs) c_int {
|
||||
return sqlite3_api.*.vfs_unregister.?(pVfs);
|
||||
}
|
||||
pub export fn sqlite3_threadsafe() c_int {
|
||||
return sqlite3_api.*.xthreadsafe.?();
|
||||
}
|
||||
pub export fn sqlite3_result_zeroblob(pCtx: ?*c.sqlite3_context, n: c_int) void {
|
||||
return sqlite3_api.*.result_zeroblob.?(pCtx, n);
|
||||
}
|
||||
pub export fn sqlite3_result_error_code(pCtx: ?*c.sqlite3_context, errCode: c_int) void {
|
||||
return sqlite3_api.*.result_error_code.?(pCtx, errCode);
|
||||
}
|
||||
pub export fn sqlite3_randomness(N: c_int, pBuf: ?*anyopaque) void {
|
||||
return sqlite3_api.*.randomness.?(N, pBuf);
|
||||
}
|
||||
pub export fn sqlite3_context_db_handle(pCtx: ?*c.sqlite3_context) ?*c.sqlite3 {
|
||||
return sqlite3_api.*.context_db_handle.?(pCtx);
|
||||
}
|
||||
pub export fn sqlite3_extended_result_codes(pCtx: ?*c.sqlite3, onoff: c_int) c_int {
|
||||
return sqlite3_api.*.extended_result_codes.?(pCtx, onoff);
|
||||
}
|
||||
pub export fn sqlite3_limit(db: ?*c.sqlite3, id: c_int, newVal: c_int) c_int {
|
||||
return sqlite3_api.*.limit.?(db, id, newVal);
|
||||
}
|
||||
pub export fn sqlite3_next_stmt(pDb: ?*c.sqlite3, pStmt: ?*c.sqlite3_stmt) ?*c.sqlite3_stmt {
|
||||
return sqlite3_api.*.next_stmt.?(pDb, pStmt);
|
||||
}
|
||||
pub export fn sqlite3_sql(pStmt: ?*c.sqlite3_stmt) [*c]const u8 {
|
||||
return sqlite3_api.*.sql.?(pStmt);
|
||||
}
|
||||
pub export fn sqlite3_status(op: c_int, pCurrent: [*c]c_int, pHighwater: [*c]c_int, resetFlag: c_int) c_int {
|
||||
return sqlite3_api.*.status.?(op, pCurrent, pHighwater, resetFlag);
|
||||
}
|
||||
pub export fn sqlite3_backup_finish(p: ?*c.sqlite3_backup) c_int {
|
||||
return sqlite3_api.*.backup_finish.?(p);
|
||||
}
|
||||
pub export fn sqlite3_backup_init(pDest: ?*c.sqlite3, zDestName: [*c]const u8, pSource: ?*c.sqlite3, zSourceName: [*c]const u8) ?*c.sqlite3_backup {
|
||||
return sqlite3_api.*.backup_init.?(pDest, zDestName, pSource, zSourceName);
|
||||
}
|
||||
pub export fn sqlite3_backup_pagecount(p: ?*c.sqlite3_backup) c_int {
|
||||
return sqlite3_api.*.backup_pagecount.?(p);
|
||||
}
|
||||
pub export fn sqlite3_backup_remaining(p: ?*c.sqlite3_backup) c_int {
|
||||
return sqlite3_api.*.backup_remaining.?(p);
|
||||
}
|
||||
pub export fn sqlite3_backup_step(p: ?*c.sqlite3_backup, nPage: c_int) c_int {
|
||||
return sqlite3_api.*.backup_step.?(p, nPage);
|
||||
}
|
||||
pub export fn sqlite3_compileoption_get(N: c_int) [*c]const u8 {
|
||||
return sqlite3_api.*.compileoption_get.?(N);
|
||||
}
|
||||
pub export fn sqlite3_compileoption_used(zOptName: [*c]const u8) c_int {
|
||||
return sqlite3_api.*.compileoption_used.?(zOptName);
|
||||
}
|
||||
pub export fn sqlite3_create_function_v2(
|
||||
db: ?*c.sqlite3,
|
||||
zFunctionName: [*c]const u8,
|
||||
nArg: c_int,
|
||||
eTextRep: c_int,
|
||||
pApp: ?*anyopaque,
|
||||
xFunc: ?*const fn (?*c.sqlite3_context, c_int, [*c]?*c.sqlite3_value) callconv(.c) void,
|
||||
xStep: ?*const fn (?*c.sqlite3_context, c_int, [*c]?*c.sqlite3_value) callconv(.c) void,
|
||||
xFinal: ?*const fn (?*c.sqlite3_context) callconv(.c) void,
|
||||
xDestroy: ?*const fn (?*anyopaque) callconv(.c) void,
|
||||
) c_int {
|
||||
return sqlite3_api.*.create_function_v2.?(db, zFunctionName, nArg, eTextRep, pApp, xFunc, xStep, xFinal, xDestroy);
|
||||
}
|
||||
pub export fn sqlite3_db_mutex(db: ?*c.sqlite3) ?*c.sqlite3_mutex {
|
||||
return sqlite3_api.*.db_mutex.?(db);
|
||||
}
|
||||
pub export fn sqlite3_db_status(db: ?*c.sqlite3, op: c_int, pCurrent: [*c]c_int, pHighwater: [*c]c_int, resetFlag: c_int) c_int {
|
||||
return sqlite3_api.*.db_status.?(db, op, pCurrent, pHighwater, resetFlag);
|
||||
}
|
||||
pub export fn sqlite3_extended_errcode(db: ?*c.sqlite3) c_int {
|
||||
return sqlite3_api.*.extended_errcode.?(db);
|
||||
}
|
||||
pub export fn sqlite3_soft_heap_limit64(N: c.sqlite3_int64) c.sqlite3_int64 {
|
||||
return sqlite3_api.*.soft_heap_limit64.?(N);
|
||||
}
|
||||
pub export fn sqlite3_sourceid() [*c]const u8 {
|
||||
return sqlite3_api.*.sourceid.?();
|
||||
}
|
||||
pub export fn sqlite3_stmt_status(pStmt: ?*c.sqlite3_stmt, op: c_int, resetFlag: c_int) c_int {
|
||||
return sqlite3_api.*.stmt_status.?(pStmt, op, resetFlag);
|
||||
}
|
||||
pub export fn sqlite3_strnicmp(zLeft: [*c]const u8, zRight: [*c]const u8, N: c_int) c_int {
|
||||
return sqlite3_api.*.strnicmp.?(zLeft, zRight, N);
|
||||
}
|
||||
pub export fn sqlite3_unlock_notify(pBlocked: ?*c.sqlite3, xNotify: ?*const fn ([*c]?*anyopaque, c_int) callconv(.c) void, pNotifyArg: ?*anyopaque) c_int {
|
||||
return sqlite3_api.*.unlock_notify.?(pBlocked, xNotify, pNotifyArg);
|
||||
}
|
||||
pub export fn sqlite3_wal_autocheckpoint(db: ?*c.sqlite3, N: c_int) c_int {
|
||||
return sqlite3_api.*.wal_autocheckpoint.?(db, N);
|
||||
}
|
||||
pub export fn sqlite3_wal_checkpoint(db: ?*c.sqlite3, zDb: [*c]const u8) c_int {
|
||||
return sqlite3_api.*.wal_checkpoint.?(db, zDb);
|
||||
}
|
||||
pub export fn sqlite3_wal_hook(db: ?*c.sqlite3, xCallback: ?*const fn (?*anyopaque, ?*c.sqlite3, [*c]const u8, c_int) callconv(.c) c_int, pArg: ?*anyopaque) ?*anyopaque {
|
||||
return sqlite3_api.*.wal_hook.?(db, xCallback, pArg);
|
||||
}
|
||||
pub export fn sqlite3_blob_reopen(pBlob: ?*c.sqlite3_blob, iRow: c.sqlite3_int64) c_int {
|
||||
return sqlite3_api.*.blob_reopen.?(pBlob, iRow);
|
||||
}
|
||||
pub export fn sqlite3_vtab_on_conflict(db: ?*c.sqlite3) c_int {
|
||||
return sqlite3_api.*.vtab_on_conflict.?(db);
|
||||
}
|
||||
pub export fn sqlite3_close_v2(db: ?*c.sqlite3) c_int {
|
||||
return sqlite3_api.*.close_v2.?(db);
|
||||
}
|
||||
pub export fn sqlite3_db_filename(db: ?*c.sqlite3, zDbName: [*c]const u8) [*c]const u8 {
|
||||
return sqlite3_api.*.db_filename.?(db, zDbName);
|
||||
}
|
||||
pub export fn sqlite3_db_readonly(db: ?*c.sqlite3, zDbName: [*c]const u8) c_int {
|
||||
return sqlite3_api.*.db_readonly.?(db, zDbName);
|
||||
}
|
||||
pub export fn sqlite3_db_release_memory(db: ?*c.sqlite3) c_int {
|
||||
return sqlite3_api.*.db_release_memory.?(db);
|
||||
}
|
||||
pub export fn sqlite3_errstr(rc: c_int) [*c]const u8 {
|
||||
return sqlite3_api.*.errstr.?(rc);
|
||||
}
|
||||
pub export fn sqlite3_stmt_busy(pStmt: ?*c.sqlite3_stmt) c_int {
|
||||
return sqlite3_api.*.stmt_busy.?(pStmt);
|
||||
}
|
||||
pub export fn sqlite3_stmt_readonly(pStmt: ?*c.sqlite3_stmt) c_int {
|
||||
return sqlite3_api.*.stmt_readonly.?(pStmt);
|
||||
}
|
||||
pub export fn sqlite3_stricmp(zLeft: [*c]const u8, zRight: [*c]const u8) c_int {
|
||||
return sqlite3_api.*.stricmp.?(zLeft, zRight);
|
||||
}
|
||||
pub export fn sqlite3_uri_boolean(zFile: [*c]const u8, zParam: [*c]const u8, bDefault: c_int) c_int {
|
||||
return sqlite3_api.*.uri_boolean.?(zFile, zParam, bDefault);
|
||||
}
|
||||
pub export fn sqlite3_uri_int64(zFilename: [*c]const u8, zParam: [*c]const u8, bDflt: c.sqlite3_int64) c.sqlite3_int64 {
|
||||
return sqlite3_api.*.uri_int64.?(zFilename, zParam, bDflt);
|
||||
}
|
||||
pub export fn sqlite3_uri_parameter(zFilename: [*c]const u8, zParam: [*c]const u8) [*c]const u8 {
|
||||
return sqlite3_api.*.uri_parameter.?(zFilename, zParam);
|
||||
}
|
||||
pub export fn sqlite3_wal_checkpoint_v2(db: ?*c.sqlite3, zDb: [*c]const u8, eMode: c_int, pnLog: [*c]c_int, pnCkpt: [*c]c_int) c_int {
|
||||
return sqlite3_api.*.wal_checkpoint_v2.?(db, zDb, eMode, pnLog, pnCkpt);
|
||||
}
|
||||
pub export fn sqlite3_auto_extension(xEntryPoint: ?*const fn () callconv(.c) void) c_int {
|
||||
return sqlite3_api.*.auto_extension.?(xEntryPoint);
|
||||
}
|
||||
pub export fn sqlite3_bind_blob64(pStmt: ?*c.sqlite3_stmt, i: c_int, zData: ?*const anyopaque, nData: c.sqlite3_uint64, xDel: ?*const fn (?*anyopaque) callconv(.c) void) c_int {
|
||||
return sqlite3_api.*.bind_blob64.?(pStmt, i, zData, nData, xDel);
|
||||
}
|
||||
pub export fn sqlite3_bind_text64(pStmt: ?*c.sqlite3_stmt, i: c_int, zData: [*c]const u8, nData: c.sqlite3_uint64, xDel: ?*const fn (?*anyopaque) callconv(.c) void, encoding: u8) c_int {
|
||||
return sqlite3_api.*.bind_text64.?(pStmt, i, zData, nData, xDel, encoding);
|
||||
}
|
||||
pub export fn sqlite3_cancel_auto_extension(xEntryPoint: ?*const fn () callconv(.c) void) c_int {
|
||||
return sqlite3_api.*.cancel_auto_extension.?(xEntryPoint);
|
||||
}
|
||||
pub export fn sqlite3_load_extension(db: ?*c.sqlite3, zFile: [*c]const u8, zProc: [*c]const u8, pzErrMsg: [*c][*c]u8) c_int {
|
||||
return sqlite3_api.*.load_extension.?(db, zFile, zProc, pzErrMsg);
|
||||
}
|
||||
pub export fn sqlite3_malloc64(n: c.sqlite3_uint64) ?*anyopaque {
|
||||
return sqlite3_api.*.malloc64.?(n);
|
||||
}
|
||||
pub export fn sqlite3_msize(p: ?*anyopaque) c.sqlite3_uint64 {
|
||||
return sqlite3_api.*.msize.?(p);
|
||||
}
|
||||
pub export fn sqlite3_realloc64(pOld: ?*anyopaque, n: c.sqlite3_uint64) ?*anyopaque {
|
||||
return sqlite3_api.*.realloc64.?(pOld, n);
|
||||
}
|
||||
pub export fn sqlite3_reset_auto_extension() void {
|
||||
return sqlite3_api.*.reset_auto_extension.?();
|
||||
}
|
||||
pub export fn sqlite3_result_blob64(pCtx: ?*c.sqlite3_context, z: ?*const anyopaque, n: c.sqlite3_uint64, xDel: ?*const fn (?*anyopaque) callconv(.c) void) void {
|
||||
return sqlite3_api.*.result_blob64.?(pCtx, z, n, xDel);
|
||||
}
|
||||
pub export fn sqlite3_result_text64(pCtx: ?*c.sqlite3_context, z: [*c]const u8, n: c.sqlite3_uint64, xDel: ?*const fn (?*anyopaque) callconv(.c) void, encoding: u8) void {
|
||||
return sqlite3_api.*.result_text64.?(pCtx, z, n, xDel, encoding);
|
||||
}
|
||||
pub export fn sqlite3_strglob(zGlob: [*c]const u8, zStr: [*c]const u8) c_int {
|
||||
return sqlite3_api.*.strglob.?(zGlob, zStr);
|
||||
}
|
||||
pub export fn sqlite3_value_dup(pOrig: ?*const c.sqlite3_value) ?*c.sqlite3_value {
|
||||
return sqlite3_api.*.value_dup.?(pOrig);
|
||||
}
|
||||
pub export fn sqlite3_value_free(pOld: ?*c.sqlite3_value) void {
|
||||
return sqlite3_api.*.value_free.?(pOld);
|
||||
}
|
||||
pub export fn sqlite3_result_zeroblob64(pCtx: ?*c.sqlite3_context, n: c.sqlite3_uint64) c_int {
|
||||
return sqlite3_api.*.result_zeroblob64.?(pCtx, n);
|
||||
}
|
||||
pub export fn sqlite3_bind_zeroblob64(pStmt: ?*c.sqlite3_stmt, i: c_int, n: c.sqlite3_uint64) c_int {
|
||||
return sqlite3_api.*.bind_zeroblob64.?(pStmt, i, n);
|
||||
}
|
||||
pub export fn sqlite3_value_subtype(pVal: ?*c.sqlite3_value) c_uint {
|
||||
return sqlite3_api.*.value_subtype.?(pVal);
|
||||
}
|
||||
pub export fn sqlite3_result_subtype(pCtx: ?*c.sqlite3_context, eSubtype: c_uint) void {
|
||||
return sqlite3_api.*.result_subtype.?(pCtx, eSubtype);
|
||||
}
|
||||
pub export fn sqlite3_status64(op: c_int, pCurrent: [*c]c.sqlite3_int64, pHighwater: [*c]c.sqlite3_int64, resetFlag: c_int) c_int {
|
||||
return sqlite3_api.*.status64.?(op, pCurrent, pHighwater, resetFlag);
|
||||
}
|
||||
pub export fn sqlite3_strlike(zGlob: [*c]const u8, zStr: [*c]const u8, cEsc: c_uint) c_int {
|
||||
return sqlite3_api.*.strlike.?(zGlob, zStr, cEsc);
|
||||
}
|
||||
pub export fn sqlite3_db_cacheflush(db: ?*c.sqlite3) c_int {
|
||||
return sqlite3_api.*.db_cacheflush.?(db);
|
||||
}
|
||||
pub export fn sqlite3_system_errno(db: ?*c.sqlite3) c_int {
|
||||
return sqlite3_api.*.system_errno.?(db);
|
||||
}
|
||||
pub export fn sqlite3_trace_v2(db: ?*c.sqlite3, uMask: c_uint, xCallback: ?*const fn (c_uint, ?*anyopaque, ?*anyopaque, ?*anyopaque) callconv(.c) c_int, pCtx: ?*anyopaque) c_int {
|
||||
return sqlite3_api.*.trace_v2.?(db, uMask, xCallback, pCtx);
|
||||
}
|
||||
pub export fn sqlite3_expanded_sql(pStmt: ?*c.sqlite3_stmt) [*c]u8 {
|
||||
return sqlite3_api.*.expanded_sql.?(pStmt);
|
||||
}
|
||||
pub export fn sqlite3_set_last_insert_rowid(db: ?*c.sqlite3, iRowid: c.sqlite3_int64) void {
|
||||
return sqlite3_api.*.set_last_insert_rowid.?(db, iRowid);
|
||||
}
|
||||
pub export fn sqlite3_prepare_v3(db: ?*c.sqlite3, zSql: [*c]const u8, nByte: c_int, prepFlags: c_uint, ppStmt: [*c]?*c.sqlite3_stmt, pzTail: [*c][*c]const u8) c_int {
|
||||
return sqlite3_api.*.prepare_v3.?(db, zSql, nByte, prepFlags, ppStmt, pzTail);
|
||||
}
|
||||
pub export fn sqlite3_prepare16_v3(db: ?*c.sqlite3, zSql: ?*const anyopaque, nByte: c_int, prepFlags: c_uint, ppStmt: [*c]?*c.sqlite3_stmt, pzTail: [*c]?*const anyopaque) c_int {
|
||||
return sqlite3_api.*.prepare16_v3.?(db, zSql, nByte, prepFlags, ppStmt, pzTail);
|
||||
}
|
||||
pub export fn sqlite3_bind_pointer(pStmt: ?*c.sqlite3_stmt, i: c_int, pPtr: ?*anyopaque, zPTtype: [*c]const u8, xDestructor: ?*const fn (?*anyopaque) callconv(.c) void) c_int {
|
||||
return sqlite3_api.*.bind_pointer.?(pStmt, i, pPtr, zPTtype, xDestructor);
|
||||
}
|
||||
pub export fn sqlite3_result_pointer(pCtx: ?*c.sqlite3_context, pPtr: ?*anyopaque, zPType: [*c]const u8, xDestructor: ?*const fn (?*anyopaque) callconv(.c) void) void {
|
||||
return sqlite3_api.*.result_pointer.?(pCtx, pPtr, zPType, xDestructor);
|
||||
}
|
||||
pub export fn sqlite3_value_pointer(pVal: ?*c.sqlite3_value, zPType: [*c]const u8) ?*anyopaque {
|
||||
return sqlite3_api.*.value_pointer.?(pVal, zPType);
|
||||
}
|
||||
pub export fn sqlite3_vtab_nochange(pCtx: ?*c.sqlite3_context) c_int {
|
||||
return sqlite3_api.*.vtab_nochange.?(pCtx);
|
||||
}
|
||||
pub export fn sqlite3_value_nochange(pVal: ?*c.sqlite3_value) c_int {
|
||||
return sqlite3_api.*.value_nochange.?(pVal);
|
||||
}
|
||||
pub export fn sqlite3_vtab_collation(pIdxInfo: [*c]c.sqlite3_index_info, iCons: c_int) [*c]const u8 {
|
||||
return sqlite3_api.*.vtab_collation.?(pIdxInfo, iCons);
|
||||
}
|
||||
pub export fn sqlite3_keyword_count() c_int {
|
||||
return sqlite3_api.*.keyword_count.?();
|
||||
}
|
||||
pub export fn sqlite3_keyword_name(i: c_int, pzName: [*c][*c]const u8, pnName: [*c]c_int) c_int {
|
||||
return sqlite3_api.*.keyword_name.?(i, pzName, pnName);
|
||||
}
|
||||
pub export fn sqlite3_keyword_check(zName: [*c]const u8, nName: c_int) c_int {
|
||||
return sqlite3_api.*.keyword_check.?(zName, nName);
|
||||
}
|
||||
pub export fn sqlite3_str_new(db: ?*c.sqlite3) ?*c.sqlite3_str {
|
||||
return sqlite3_api.*.str_new.?(db);
|
||||
}
|
||||
pub export fn sqlite3_str_finish(p: ?*c.sqlite3_str) [*c]u8 {
|
||||
return sqlite3_api.*.str_finish.?(p);
|
||||
}
|
||||
pub export fn sqlite3_str_append(p: ?*c.sqlite3_str, zIn: [*c]const u8, N: c_int) void {
|
||||
return sqlite3_api.*.str_append.?(p, zIn, N);
|
||||
}
|
||||
pub export fn sqlite3_str_appendall(p: ?*c.sqlite3_str, zIn: [*c]const u8) void {
|
||||
return sqlite3_api.*.str_appendall.?(p, zIn);
|
||||
}
|
||||
pub export fn sqlite3_str_appendchar(p: ?*c.sqlite3_str, N: c_int, C: u8) void {
|
||||
return sqlite3_api.*.str_appendchar.?(p, N, C);
|
||||
}
|
||||
pub export fn sqlite3_str_reset(p: ?*c.sqlite3_str) void {
|
||||
return sqlite3_api.*.str_reset.?(p);
|
||||
}
|
||||
pub export fn sqlite3_str_errcode(p: ?*c.sqlite3_str) c_int {
|
||||
return sqlite3_api.*.str_errcode.?(p);
|
||||
}
|
||||
pub export fn sqlite3_str_length(p: ?*c.sqlite3_str) c_int {
|
||||
return sqlite3_api.*.str_length.?(p);
|
||||
}
|
||||
pub export fn sqlite3_str_value(p: ?*c.sqlite3_str) [*c]u8 {
|
||||
return sqlite3_api.*.str_value.?(p);
|
||||
}
|
||||
pub export fn sqlite3_create_window_function(
|
||||
db: ?*c.sqlite3,
|
||||
zFunctionName: [*c]const u8,
|
||||
nArg: c_int,
|
||||
eTextRep: c_int,
|
||||
pArg: ?*anyopaque,
|
||||
xStep: ?*const fn (?*c.sqlite3_context, c_int, [*c]?*c.sqlite3_value) callconv(.c) void,
|
||||
xFinal: ?*const fn (?*c.sqlite3_context) callconv(.c) void,
|
||||
xValue: ?*const fn (?*c.sqlite3_context) callconv(.c) void,
|
||||
xInverse: ?*const fn (?*c.sqlite3_context, c_int, [*c]?*c.sqlite3_value) callconv(.c) void,
|
||||
xDestroy: ?*const fn (?*anyopaque) callconv(.c) void,
|
||||
) c_int {
|
||||
return sqlite3_api.*.create_window_function.?(
|
||||
db,
|
||||
zFunctionName,
|
||||
nArg,
|
||||
eTextRep,
|
||||
pArg,
|
||||
xStep,
|
||||
xFinal,
|
||||
xValue,
|
||||
xInverse,
|
||||
xDestroy,
|
||||
);
|
||||
}
|
||||
pub export fn sqlite3_stmt_isexplain(pStmt: ?*c.sqlite3_stmt) c_int {
|
||||
return sqlite3_api.*.stmt_isexplain.?(pStmt);
|
||||
}
|
||||
pub export fn sqlite3_value_frombind(pVal: ?*c.sqlite3_value) c_int {
|
||||
return sqlite3_api.*.value_frombind.?(pVal);
|
||||
}
|
||||
pub export fn sqlite3_drop_modules(db: ?*c.sqlite3, azKeep: [*c][*c]const u8) c_int {
|
||||
return sqlite3_api.*.drop_modules.?(db, azKeep);
|
||||
}
|
||||
pub export fn sqlite3_hard_heap_limit64(N: c.sqlite3_int64) c.sqlite3_int64 {
|
||||
return sqlite3_api.*.hard_heap_limit64.?(N);
|
||||
}
|
||||
pub export fn sqlite3_uri_key(zFilename: [*c]const u8, N: c_int) [*c]const u8 {
|
||||
return sqlite3_api.*.uri_key.?(zFilename, N);
|
||||
}
|
||||
pub export fn sqlite3_filename_database(zFilename: [*c]const u8) [*c]const u8 {
|
||||
return sqlite3_api.*.filename_database.?(zFilename);
|
||||
}
|
||||
pub export fn sqlite3_filename_journal(zFilename: [*c]const u8) [*c]const u8 {
|
||||
return sqlite3_api.*.filename_journal.?(zFilename);
|
||||
}
|
||||
pub export fn sqlite3_filename_wal(zFilename: [*c]const u8) [*c]const u8 {
|
||||
return sqlite3_api.*.filename_wal.?(zFilename);
|
||||
}
|
||||
pub export fn sqlite3_create_filename(zDatabase: [*c]const u8, zJournal: [*c]const u8, zWal: [*c]const u8, nParam: c_int, azParam: [*c][*c]const u8) [*c]const u8 {
|
||||
return sqlite3_api.*.create_filename.?(zDatabase, zJournal, zWal, nParam, azParam);
|
||||
}
|
||||
pub export fn sqlite3_free_filename(p: [*c]u8) void {
|
||||
return sqlite3_api.*.free_filename.?(p);
|
||||
}
|
||||
pub export fn sqlite3_database_file_object(zName: [*c]const u8) [*c]c.sqlite3_file {
|
||||
return sqlite3_api.*.database_file_object.?(zName);
|
||||
}
|
||||
pub export fn sqlite3_txn_state(db: ?*c.sqlite3, zSchema: [*c]const u8) c_int {
|
||||
return sqlite3_api.*.txn_state.?(db, zSchema);
|
||||
}
|
||||
pub export fn sqlite3_changes64(db: ?*c.sqlite3) c.sqlite3_int64 {
|
||||
return sqlite3_api.*.changes64.?(db);
|
||||
}
|
||||
pub export fn sqlite3_total_changes64(db: ?*c.sqlite3) c.sqlite3_int64 {
|
||||
return sqlite3_api.*.total_changes64.?(db);
|
||||
}
|
||||
pub export fn sqlite3_autovacuum_pages(db: ?*c.sqlite3, xCallback: ?*const fn (?*anyopaque, [*c]const u8, c_uint, c_uint, c_uint) callconv(.c) c_uint, pArg: ?*anyopaque, xDestructor: ?*const fn (?*anyopaque) callconv(.c) void) c_int {
|
||||
return sqlite3_api.*.autovacuum_pages.?(db, xCallback, pArg, xDestructor);
|
||||
}
|
||||
pub export fn sqlite3_error_offset(db: ?*c.sqlite3) c_int {
|
||||
return sqlite3_api.*.error_offset.?(db);
|
||||
}
|
||||
pub export fn sqlite3_vtab_rhs_value(pIdxInfo: [*c]c.sqlite3_index_info, iCons: c_int, ppVal: [*c]?*c.sqlite3_value) c_int {
|
||||
return sqlite3_api.*.vtab_rhs_value.?(pIdxInfo, iCons, ppVal);
|
||||
}
|
||||
pub export fn sqlite3_vtab_distinct(pIdxInfo: [*c]c.sqlite3_index_info) c_int {
|
||||
return sqlite3_api.*.vtab_distinct.?(pIdxInfo);
|
||||
}
|
||||
pub export fn sqlite3_vtab_in(pIdxInfo: [*c]c.sqlite3_index_info, iCons: c_int, bHandle: c_int) c_int {
|
||||
return sqlite3_api.*.vtab_in.?(pIdxInfo, iCons, bHandle);
|
||||
}
|
||||
pub export fn sqlite3_vtab_in_first(pVal: ?*c.sqlite3_value, ppOut: [*c]?*c.sqlite3_value) c_int {
|
||||
return sqlite3_api.*.vtab_in_first.?(pVal, ppOut);
|
||||
}
|
||||
pub export fn sqlite3_vtab_in_next(pVal: ?*c.sqlite3_value, ppOut: [*c]?*c.sqlite3_value) c_int {
|
||||
return sqlite3_api.*.vtab_in_next.?(pVal, ppOut);
|
||||
}
|
||||
pub export fn sqlite3_deserialize(db: ?*c.sqlite3, zSchema: [*c]const u8, pData: [*c]u8, szDb: c.sqlite3_int64, szBuf: c.sqlite3_int64, mFlags: c_uint) c_int {
|
||||
return sqlite3_api.*.deserialize.?(db, zSchema, pData, szDb, szBuf, mFlags);
|
||||
}
|
||||
pub export fn sqlite3_serialize(db: ?*c.sqlite3, zSchema: [*c]const u8, piSize: [*c]c.sqlite3_int64, mFlags: c_uint) [*c]u8 {
|
||||
return sqlite3_api.*.serialize.?(db, zSchema, piSize, mFlags);
|
||||
}
|
||||
pub export fn sqlite3_db_name(db: ?*c.sqlite3, N: c_int) [*c]const u8 {
|
||||
return sqlite3_api.*.db_name.?(db, N);
|
||||
}
|
||||
5
zig-vendor/zig-sqlite/c/workaround.c
Normal file
5
zig-vendor/zig-sqlite/c/workaround.c
Normal file
@@ -0,0 +1,5 @@
|
||||
#include "workaround.h"
|
||||
|
||||
my_sqlite3_destructor_type sqliteTransientAsDestructor() {
|
||||
return (my_sqlite3_destructor_type)-1;
|
||||
}
|
||||
3
zig-vendor/zig-sqlite/c/workaround.h
Normal file
3
zig-vendor/zig-sqlite/c/workaround.h
Normal file
@@ -0,0 +1,3 @@
|
||||
typedef void (*my_sqlite3_destructor_type)(void *);
|
||||
|
||||
my_sqlite3_destructor_type sqliteTransientAsDestructor();
|
||||
311
zig-vendor/zig-sqlite/errors.zig
Normal file
311
zig-vendor/zig-sqlite/errors.zig
Normal file
@@ -0,0 +1,311 @@
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
|
||||
const c = @import("c.zig").c;
|
||||
const versionGreaterThanOrEqualTo = @import("c.zig").versionGreaterThanOrEqualTo;
|
||||
|
||||
pub const SQLiteExtendedIOError = error{
|
||||
SQLiteIOErrRead,
|
||||
SQLiteIOErrShortRead,
|
||||
SQLiteIOErrWrite,
|
||||
SQLiteIOErrFsync,
|
||||
SQLiteIOErrDirFsync,
|
||||
SQLiteIOErrTruncate,
|
||||
SQLiteIOErrFstat,
|
||||
SQLiteIOErrUnlock,
|
||||
SQLiteIOErrRDLock,
|
||||
SQLiteIOErrDelete,
|
||||
SQLiteIOErrBlocked,
|
||||
SQLiteIOErrNoMem,
|
||||
SQLiteIOErrAccess,
|
||||
SQLiteIOErrCheckReservedLock,
|
||||
SQLiteIOErrLock,
|
||||
SQLiteIOErrClose,
|
||||
SQLiteIOErrDirClose,
|
||||
SQLiteIOErrSHMOpen,
|
||||
SQLiteIOErrSHMSize,
|
||||
SQLiteIOErrSHMLock,
|
||||
SQLiteIOErrSHMMap,
|
||||
SQLiteIOErrSeek,
|
||||
SQLiteIOErrDeleteNoEnt,
|
||||
SQLiteIOErrMmap,
|
||||
SQLiteIOErrGetTempPath,
|
||||
SQLiteIOErrConvPath,
|
||||
SQLiteIOErrVnode,
|
||||
SQLiteIOErrAuth,
|
||||
SQLiteIOErrBeginAtomic,
|
||||
SQLiteIOErrCommitAtomic,
|
||||
SQLiteIOErrRollbackAtomic,
|
||||
SQLiteIOErrData,
|
||||
SQLiteIOErrCorruptFS,
|
||||
};
|
||||
|
||||
pub const SQLiteExtendedCantOpenError = error{
|
||||
SQLiteCantOpenNoTempDir,
|
||||
SQLiteCantOpenIsDir,
|
||||
SQLiteCantOpenFullPath,
|
||||
SQLiteCantOpenConvPath,
|
||||
SQLiteCantOpenDirtyWAL,
|
||||
SQLiteCantOpenSymlink,
|
||||
};
|
||||
|
||||
pub const SQLiteExtendedReadOnlyError = error{
|
||||
SQLiteReadOnlyRecovery,
|
||||
SQLiteReadOnlyCantLock,
|
||||
SQLiteReadOnlyRollback,
|
||||
SQLiteReadOnlyDBMoved,
|
||||
SQLiteReadOnlyCantInit,
|
||||
SQLiteReadOnlyDirectory,
|
||||
};
|
||||
|
||||
pub const SQLiteExtendedConstraintError = error{
|
||||
SQLiteConstraintCheck,
|
||||
SQLiteConstraintCommitHook,
|
||||
SQLiteConstraintForeignKey,
|
||||
SQLiteConstraintFunction,
|
||||
SQLiteConstraintNotNull,
|
||||
SQLiteConstraintPrimaryKey,
|
||||
SQLiteConstraintTrigger,
|
||||
SQLiteConstraintUnique,
|
||||
SQLiteConstraintVTab,
|
||||
SQLiteConstraintRowID,
|
||||
SQLiteConstraintPinned,
|
||||
};
|
||||
|
||||
pub const SQLiteExtendedError = error{
|
||||
SQLiteErrorMissingCollSeq,
|
||||
SQLiteErrorRetry,
|
||||
SQLiteErrorSnapshot,
|
||||
|
||||
SQLiteLockedSharedCache,
|
||||
SQLiteLockedVTab,
|
||||
|
||||
SQLiteBusyRecovery,
|
||||
SQLiteBusySnapshot,
|
||||
SQLiteBusyTimeout,
|
||||
|
||||
SQLiteCorruptVTab,
|
||||
SQLiteCorruptSequence,
|
||||
SQLiteCorruptIndex,
|
||||
|
||||
SQLiteAbortRollback,
|
||||
};
|
||||
|
||||
pub const SQLiteError = error{
|
||||
SQLiteError,
|
||||
SQLiteInternal,
|
||||
SQLitePerm,
|
||||
SQLiteAbort,
|
||||
SQLiteBusy,
|
||||
SQLiteLocked,
|
||||
SQLiteNoMem,
|
||||
SQLiteReadOnly,
|
||||
SQLiteInterrupt,
|
||||
SQLiteIOErr,
|
||||
SQLiteCorrupt,
|
||||
SQLiteNotFound,
|
||||
SQLiteFull,
|
||||
SQLiteCantOpen,
|
||||
SQLiteProtocol,
|
||||
SQLiteEmpty,
|
||||
SQLiteSchema,
|
||||
SQLiteTooBig,
|
||||
SQLiteConstraint,
|
||||
SQLiteMismatch,
|
||||
SQLiteMisuse,
|
||||
SQLiteNoLFS,
|
||||
SQLiteAuth,
|
||||
SQLiteRange,
|
||||
SQLiteNotADatabase,
|
||||
SQLiteNotice,
|
||||
SQLiteWarning,
|
||||
};
|
||||
|
||||
pub const Error = SQLiteError ||
|
||||
SQLiteExtendedError ||
|
||||
SQLiteExtendedIOError ||
|
||||
SQLiteExtendedCantOpenError ||
|
||||
SQLiteExtendedReadOnlyError ||
|
||||
SQLiteExtendedConstraintError;
|
||||
|
||||
pub fn errorFromResultCode(code: c_int) Error {
|
||||
// These errors are only available since 3.22.0.
|
||||
if (comptime versionGreaterThanOrEqualTo(3, 22, 0)) {
|
||||
switch (code) {
|
||||
c.SQLITE_ERROR_MISSING_COLLSEQ => return error.SQLiteErrorMissingCollSeq,
|
||||
c.SQLITE_ERROR_RETRY => return error.SQLiteErrorRetry,
|
||||
c.SQLITE_READONLY_CANTINIT => return error.SQLiteReadOnlyCantInit,
|
||||
c.SQLITE_READONLY_DIRECTORY => return error.SQLiteReadOnlyDirectory,
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
// These errors are only available since 3.25.0.
|
||||
if (comptime versionGreaterThanOrEqualTo(3, 25, 0)) {
|
||||
switch (code) {
|
||||
c.SQLITE_ERROR_SNAPSHOT => return error.SQLiteErrorSnapshot,
|
||||
c.SQLITE_LOCKED_VTAB => return error.SQLiteLockedVTab,
|
||||
c.SQLITE_CANTOPEN_DIRTYWAL => return error.SQLiteCantOpenDirtyWAL,
|
||||
c.SQLITE_CORRUPT_SEQUENCE => return error.SQLiteCorruptSequence,
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
// These errors are only available since 3.31.0.
|
||||
if (comptime versionGreaterThanOrEqualTo(3, 31, 0)) {
|
||||
switch (code) {
|
||||
c.SQLITE_CANTOPEN_SYMLINK => return error.SQLiteCantOpenSymlink,
|
||||
c.SQLITE_CONSTRAINT_PINNED => return error.SQLiteConstraintPinned,
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
// These errors are only available since 3.32.0.
|
||||
if (comptime versionGreaterThanOrEqualTo(3, 32, 0)) {
|
||||
switch (code) {
|
||||
c.SQLITE_IOERR_DATA => return error.SQLiteIOErrData, // See https://sqlite.org/cksumvfs.html
|
||||
c.SQLITE_BUSY_TIMEOUT => return error.SQLiteBusyTimeout,
|
||||
c.SQLITE_CORRUPT_INDEX => return error.SQLiteCorruptIndex,
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
// These errors are only available since 3.34.0.
|
||||
if (comptime versionGreaterThanOrEqualTo(3, 34, 0)) {
|
||||
switch (code) {
|
||||
c.SQLITE_IOERR_CORRUPTFS => return error.SQLiteIOErrCorruptFS,
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
switch (code) {
|
||||
c.SQLITE_ERROR => return error.SQLiteError,
|
||||
c.SQLITE_INTERNAL => return error.SQLiteInternal,
|
||||
c.SQLITE_PERM => return error.SQLitePerm,
|
||||
c.SQLITE_ABORT => return error.SQLiteAbort,
|
||||
c.SQLITE_BUSY => return error.SQLiteBusy,
|
||||
c.SQLITE_LOCKED => return error.SQLiteLocked,
|
||||
c.SQLITE_NOMEM => return error.SQLiteNoMem,
|
||||
c.SQLITE_READONLY => return error.SQLiteReadOnly,
|
||||
c.SQLITE_INTERRUPT => return error.SQLiteInterrupt,
|
||||
c.SQLITE_IOERR => return error.SQLiteIOErr,
|
||||
c.SQLITE_CORRUPT => return error.SQLiteCorrupt,
|
||||
c.SQLITE_NOTFOUND => return error.SQLiteNotFound,
|
||||
c.SQLITE_FULL => return error.SQLiteFull,
|
||||
c.SQLITE_CANTOPEN => return error.SQLiteCantOpen,
|
||||
c.SQLITE_PROTOCOL => return error.SQLiteProtocol,
|
||||
c.SQLITE_EMPTY => return error.SQLiteEmpty,
|
||||
c.SQLITE_SCHEMA => return error.SQLiteSchema,
|
||||
c.SQLITE_TOOBIG => return error.SQLiteTooBig,
|
||||
c.SQLITE_CONSTRAINT => return error.SQLiteConstraint,
|
||||
c.SQLITE_MISMATCH => return error.SQLiteMismatch,
|
||||
c.SQLITE_MISUSE => return error.SQLiteMisuse,
|
||||
c.SQLITE_NOLFS => return error.SQLiteNoLFS,
|
||||
c.SQLITE_AUTH => return error.SQLiteAuth,
|
||||
c.SQLITE_RANGE => return error.SQLiteRange,
|
||||
c.SQLITE_NOTADB => return error.SQLiteNotADatabase,
|
||||
c.SQLITE_NOTICE => return error.SQLiteNotice,
|
||||
c.SQLITE_WARNING => return error.SQLiteWarning,
|
||||
|
||||
c.SQLITE_IOERR_READ => return error.SQLiteIOErrRead,
|
||||
c.SQLITE_IOERR_SHORT_READ => return error.SQLiteIOErrShortRead,
|
||||
c.SQLITE_IOERR_WRITE => return error.SQLiteIOErrWrite,
|
||||
c.SQLITE_IOERR_FSYNC => return error.SQLiteIOErrFsync,
|
||||
c.SQLITE_IOERR_DIR_FSYNC => return error.SQLiteIOErrDirFsync,
|
||||
c.SQLITE_IOERR_TRUNCATE => return error.SQLiteIOErrTruncate,
|
||||
c.SQLITE_IOERR_FSTAT => return error.SQLiteIOErrFstat,
|
||||
c.SQLITE_IOERR_UNLOCK => return error.SQLiteIOErrUnlock,
|
||||
c.SQLITE_IOERR_RDLOCK => return error.SQLiteIOErrRDLock,
|
||||
c.SQLITE_IOERR_DELETE => return error.SQLiteIOErrDelete,
|
||||
c.SQLITE_IOERR_BLOCKED => return error.SQLiteIOErrBlocked,
|
||||
c.SQLITE_IOERR_NOMEM => return error.SQLiteIOErrNoMem,
|
||||
c.SQLITE_IOERR_ACCESS => return error.SQLiteIOErrAccess,
|
||||
c.SQLITE_IOERR_CHECKRESERVEDLOCK => return error.SQLiteIOErrCheckReservedLock,
|
||||
c.SQLITE_IOERR_LOCK => return error.SQLiteIOErrLock,
|
||||
c.SQLITE_IOERR_CLOSE => return error.SQLiteIOErrClose,
|
||||
c.SQLITE_IOERR_DIR_CLOSE => return error.SQLiteIOErrDirClose,
|
||||
c.SQLITE_IOERR_SHMOPEN => return error.SQLiteIOErrSHMOpen,
|
||||
c.SQLITE_IOERR_SHMSIZE => return error.SQLiteIOErrSHMSize,
|
||||
c.SQLITE_IOERR_SHMLOCK => return error.SQLiteIOErrSHMLock,
|
||||
c.SQLITE_IOERR_SHMMAP => return error.SQLiteIOErrSHMMap,
|
||||
c.SQLITE_IOERR_SEEK => return error.SQLiteIOErrSeek,
|
||||
c.SQLITE_IOERR_DELETE_NOENT => return error.SQLiteIOErrDeleteNoEnt,
|
||||
c.SQLITE_IOERR_MMAP => return error.SQLiteIOErrMmap,
|
||||
c.SQLITE_IOERR_GETTEMPPATH => return error.SQLiteIOErrGetTempPath,
|
||||
c.SQLITE_IOERR_CONVPATH => return error.SQLiteIOErrConvPath,
|
||||
c.SQLITE_IOERR_VNODE => return error.SQLiteIOErrVnode,
|
||||
c.SQLITE_IOERR_AUTH => return error.SQLiteIOErrAuth,
|
||||
c.SQLITE_IOERR_BEGIN_ATOMIC => return error.SQLiteIOErrBeginAtomic,
|
||||
c.SQLITE_IOERR_COMMIT_ATOMIC => return error.SQLiteIOErrCommitAtomic,
|
||||
c.SQLITE_IOERR_ROLLBACK_ATOMIC => return error.SQLiteIOErrRollbackAtomic,
|
||||
|
||||
c.SQLITE_LOCKED_SHAREDCACHE => return error.SQLiteLockedSharedCache,
|
||||
|
||||
c.SQLITE_BUSY_RECOVERY => return error.SQLiteBusyRecovery,
|
||||
c.SQLITE_BUSY_SNAPSHOT => return error.SQLiteBusySnapshot,
|
||||
|
||||
c.SQLITE_CANTOPEN_NOTEMPDIR => return error.SQLiteCantOpenNoTempDir,
|
||||
c.SQLITE_CANTOPEN_ISDIR => return error.SQLiteCantOpenIsDir,
|
||||
c.SQLITE_CANTOPEN_FULLPATH => return error.SQLiteCantOpenFullPath,
|
||||
c.SQLITE_CANTOPEN_CONVPATH => return error.SQLiteCantOpenConvPath,
|
||||
|
||||
c.SQLITE_CORRUPT_VTAB => return error.SQLiteCorruptVTab,
|
||||
|
||||
c.SQLITE_READONLY_RECOVERY => return error.SQLiteReadOnlyRecovery,
|
||||
c.SQLITE_READONLY_CANTLOCK => return error.SQLiteReadOnlyCantLock,
|
||||
c.SQLITE_READONLY_ROLLBACK => return error.SQLiteReadOnlyRollback,
|
||||
c.SQLITE_READONLY_DBMOVED => return error.SQLiteReadOnlyDBMoved,
|
||||
|
||||
c.SQLITE_ABORT_ROLLBACK => return error.SQLiteAbortRollback,
|
||||
|
||||
c.SQLITE_CONSTRAINT_CHECK => return error.SQLiteConstraintCheck,
|
||||
c.SQLITE_CONSTRAINT_COMMITHOOK => return error.SQLiteConstraintCommitHook,
|
||||
c.SQLITE_CONSTRAINT_FOREIGNKEY => return error.SQLiteConstraintForeignKey,
|
||||
c.SQLITE_CONSTRAINT_FUNCTION => return error.SQLiteConstraintFunction,
|
||||
c.SQLITE_CONSTRAINT_NOTNULL => return error.SQLiteConstraintNotNull,
|
||||
c.SQLITE_CONSTRAINT_PRIMARYKEY => return error.SQLiteConstraintPrimaryKey,
|
||||
c.SQLITE_CONSTRAINT_TRIGGER => return error.SQLiteConstraintTrigger,
|
||||
c.SQLITE_CONSTRAINT_UNIQUE => return error.SQLiteConstraintUnique,
|
||||
c.SQLITE_CONSTRAINT_VTAB => return error.SQLiteConstraintVTab,
|
||||
c.SQLITE_CONSTRAINT_ROWID => return error.SQLiteConstraintRowID,
|
||||
|
||||
else => std.debug.panic("invalid result code {}", .{code}),
|
||||
}
|
||||
}
|
||||
|
||||
/// DetailedError contains a SQLite error code and error message.
|
||||
pub const DetailedError = struct {
|
||||
code: usize,
|
||||
near: i32,
|
||||
message: []const u8,
|
||||
|
||||
pub fn format(self: @This(), writer: anytype) !void {
|
||||
_ = try writer.print("{{code: {}, near: {d}, message: {s}}}", .{ self.code, self.near, self.message });
|
||||
}
|
||||
};
|
||||
|
||||
pub fn getDetailedErrorFromResultCode(code: c_int) DetailedError {
|
||||
return .{
|
||||
.code = @intCast(code),
|
||||
.near = -1,
|
||||
.message = blk: {
|
||||
const msg = c.sqlite3_errstr(code);
|
||||
break :blk mem.sliceTo(msg, 0);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn getErrorOffset(db: *c.sqlite3) i32 {
|
||||
if (comptime versionGreaterThanOrEqualTo(3, 38, 0)) {
|
||||
return c.sqlite3_error_offset(db);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
pub fn getLastDetailedErrorFromDb(db: *c.sqlite3) DetailedError {
|
||||
return .{
|
||||
.code = @intCast(c.sqlite3_extended_errcode(db)),
|
||||
.near = getErrorOffset(db),
|
||||
.message = blk: {
|
||||
const msg = c.sqlite3_errmsg(db);
|
||||
break :blk mem.sliceTo(msg, 0);
|
||||
},
|
||||
};
|
||||
}
|
||||
59
zig-vendor/zig-sqlite/examples/zigcrypto.zig
Normal file
59
zig-vendor/zig-sqlite/examples/zigcrypto.zig
Normal file
@@ -0,0 +1,59 @@
|
||||
const std = @import("std");
|
||||
const Blake3 = std.crypto.hash.Blake3;
|
||||
const Sha3_512 = std.crypto.hash.sha3.Sha3_512;
|
||||
|
||||
const sqlite = @import("sqlite");
|
||||
const c = sqlite.c;
|
||||
|
||||
const name = "zigcrypto";
|
||||
|
||||
pub const loadable_extension = true;
|
||||
|
||||
var module_allocator: std.heap.GeneralPurposeAllocator(.{}) = undefined;
|
||||
var module_context: sqlite.vtab.ModuleContext = undefined;
|
||||
|
||||
const logger = std.log.scoped(.zigcrypto);
|
||||
|
||||
fn createAllFunctions(db: *sqlite.Db) !void {
|
||||
try db.createScalarFunction(
|
||||
"blake3",
|
||||
struct {
|
||||
fn run(input: []const u8) [Blake3.digest_length]u8 {
|
||||
var output: [Blake3.digest_length]u8 = undefined;
|
||||
Blake3.hash(input, output[0..], .{});
|
||||
return output;
|
||||
}
|
||||
}.run,
|
||||
.{},
|
||||
);
|
||||
try db.createScalarFunction(
|
||||
"sha3_512",
|
||||
struct {
|
||||
fn run(input: []const u8) [Sha3_512.digest_length]u8 {
|
||||
var output: [Sha3_512.digest_length]u8 = undefined;
|
||||
Sha3_512.hash(input, output[0..], .{});
|
||||
return output;
|
||||
}
|
||||
}.run,
|
||||
.{},
|
||||
);
|
||||
}
|
||||
|
||||
pub export fn sqlite3_zigcrypto_init(raw_db: *c.sqlite3, err_msg: [*c][*c]u8, api: *c.sqlite3_api_routines) callconv(.c) c_int {
|
||||
_ = err_msg;
|
||||
|
||||
c.sqlite3_api = api;
|
||||
|
||||
module_allocator = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
|
||||
var db = sqlite.Db{
|
||||
.db = raw_db,
|
||||
};
|
||||
|
||||
createAllFunctions(&db) catch |err| {
|
||||
logger.err("unable to create all SQLite functions, err: {!}", .{err});
|
||||
return c.SQLITE_ERROR;
|
||||
};
|
||||
|
||||
return c.SQLITE_OK;
|
||||
}
|
||||
56
zig-vendor/zig-sqlite/examples/zigcrypto_test.zig
Normal file
56
zig-vendor/zig-sqlite/examples/zigcrypto_test.zig
Normal file
@@ -0,0 +1,56 @@
|
||||
const builtin = @import("builtin");
|
||||
const std = @import("std");
|
||||
const debug = std.debug;
|
||||
const mem = std.mem;
|
||||
|
||||
const sqlite = @import("sqlite");
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
var arena = std.heap.ArenaAllocator.init(gpa.allocator());
|
||||
defer arena.deinit();
|
||||
const allocator = arena.allocator();
|
||||
|
||||
//
|
||||
|
||||
var db = try sqlite.Db.init(.{
|
||||
.mode = sqlite.Db.Mode{ .Memory = {} },
|
||||
.open_flags = .{ .write = true },
|
||||
});
|
||||
defer db.deinit();
|
||||
|
||||
{
|
||||
const result = sqlite.c.sqlite3_enable_load_extension(db.db, 1);
|
||||
debug.assert(result == sqlite.c.SQLITE_OK);
|
||||
}
|
||||
|
||||
{
|
||||
const extension_path = if (builtin.os.tag == .windows)
|
||||
"./zig-out/bin/zigcrypto.dll"
|
||||
else
|
||||
"./zig-out/lib/libzigcrypto";
|
||||
|
||||
var pzErrMsg: [*c]u8 = undefined;
|
||||
const result = sqlite.c.sqlite3_load_extension(db.db, extension_path, null, &pzErrMsg);
|
||||
if (result != sqlite.c.SQLITE_OK) {
|
||||
const err = sqlite.c.sqlite3_errstr(result);
|
||||
std.debug.panic("unable to load extension at path {s}, err: {s}, err message: {s}\n", .{ extension_path, err, std.mem.sliceTo(pzErrMsg, 0) });
|
||||
}
|
||||
}
|
||||
|
||||
var diags = sqlite.Diagnostics{};
|
||||
|
||||
const blake3_digest = db.oneAlloc([]const u8, allocator, "SELECT hex(blake3('foobar'))", .{ .diags = &diags }, .{}) catch |err| {
|
||||
debug.print("unable to get blake3 hash, err: {}, diags: {f}\n", .{ err, diags });
|
||||
return err;
|
||||
};
|
||||
debug.assert(blake3_digest != null);
|
||||
debug.assert(mem.eql(u8, "AA51DCD43D5C6C5203EE16906FD6B35DB298B9B2E1DE3FCE81811D4806B76B7D", blake3_digest.?));
|
||||
|
||||
const sha3_digest = db.oneAlloc([]const u8, allocator, "SELECT hex(sha3_512('foobar'))", .{ .diags = &diags }, .{}) catch |err| {
|
||||
debug.print("unable to get sha3 hash, err: {}, diags: {f}\n", .{ err, diags });
|
||||
return err;
|
||||
};
|
||||
debug.assert(sha3_digest != null);
|
||||
debug.assert(mem.eql(u8, "FF32A30C3AF5012EA395827A3E99A13073C3A8D8410A708568FF7E6EB85968FCCFEBAEA039BC21411E9D43FDB9A851B529B9960FFEA8679199781B8F45CA85E2", sha3_digest.?));
|
||||
}
|
||||
104
zig-vendor/zig-sqlite/helpers.zig
Normal file
104
zig-vendor/zig-sqlite/helpers.zig
Normal file
@@ -0,0 +1,104 @@
|
||||
const std = @import("std");
|
||||
const debug = std.debug;
|
||||
|
||||
const c = @import("c.zig").c;
|
||||
|
||||
const Blob = @import("sqlite.zig").Blob;
|
||||
const Text = @import("sqlite.zig").Text;
|
||||
|
||||
/// Sets the result of a function call in the context `ctx`.
|
||||
///
|
||||
/// Determines at compile time which sqlite3_result_XYZ function to use based on the type of `result`.
|
||||
pub fn setResult(ctx: ?*c.sqlite3_context, result: anytype) void {
|
||||
const ResultType = @TypeOf(result);
|
||||
|
||||
switch (ResultType) {
|
||||
Text => c.sqlite3_result_text(ctx, result.data.ptr, @intCast(result.data.len), c.sqliteTransientAsDestructor()),
|
||||
Blob => c.sqlite3_result_blob(ctx, result.data.ptr, @intCast(result.data.len), c.sqliteTransientAsDestructor()),
|
||||
else => switch (@typeInfo(ResultType)) {
|
||||
.int => |info| if ((info.bits + if (info.signedness == .unsigned) 1 else 0) <= 32) {
|
||||
c.sqlite3_result_int(ctx, result);
|
||||
} else if ((info.bits + if (info.signedness == .unsigned) 1 else 0) <= 64) {
|
||||
c.sqlite3_result_int64(ctx, result);
|
||||
} else {
|
||||
@compileError("integer " ++ @typeName(ResultType) ++ " is not representable in sqlite");
|
||||
},
|
||||
.float => c.sqlite3_result_double(ctx, result),
|
||||
.bool => c.sqlite3_result_int(ctx, if (result) 1 else 0),
|
||||
.array => |arr| switch (arr.child) {
|
||||
u8 => c.sqlite3_result_blob(ctx, &result, arr.len, c.sqliteTransientAsDestructor()),
|
||||
else => @compileError("cannot use a result of type " ++ @typeName(ResultType)),
|
||||
},
|
||||
.pointer => |ptr| switch (ptr.size) {
|
||||
.slice => switch (ptr.child) {
|
||||
u8 => c.sqlite3_result_text(ctx, result.ptr, @intCast(result.len), c.sqliteTransientAsDestructor()),
|
||||
else => @compileError("cannot use a result of type " ++ @typeName(ResultType)),
|
||||
},
|
||||
else => @compileError("cannot use a result of type " ++ @typeName(ResultType)),
|
||||
},
|
||||
else => @compileError("cannot use a result of type " ++ @typeName(ResultType)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets a type using the provided value.
|
||||
///
|
||||
/// Determines at compile time which sqlite3_value_XYZ function to use based on the type `ArgType`.
|
||||
pub fn setTypeFromValue(comptime ArgType: type, arg: *ArgType, sqlite_value: *c.sqlite3_value) void {
|
||||
switch (ArgType) {
|
||||
Text => arg.*.data = sliceFromValue(sqlite_value),
|
||||
Blob => arg.*.data = sliceFromValue(sqlite_value),
|
||||
else => switch (@typeInfo(ArgType)) {
|
||||
.int => |info| if ((info.bits + if (info.signedness == .unsigned) 1 else 0) <= 32) {
|
||||
const value = c.sqlite3_value_int(sqlite_value);
|
||||
arg.* = @intCast(value);
|
||||
} else if ((info.bits + if (info.signedness == .unsigned) 1 else 0) <= 64) {
|
||||
const value = c.sqlite3_value_int64(sqlite_value);
|
||||
arg.* = @intCast(value);
|
||||
} else {
|
||||
@compileError("integer " ++ @typeName(ArgType) ++ " is not representable in sqlite");
|
||||
},
|
||||
.float => {
|
||||
const value = c.sqlite3_value_double(sqlite_value);
|
||||
arg.* = @floatCast(value);
|
||||
},
|
||||
.bool => {
|
||||
const value = c.sqlite3_value_int(sqlite_value);
|
||||
arg.* = value > 0;
|
||||
},
|
||||
.pointer => |ptr| switch (ptr.size) {
|
||||
.slice => switch (ptr.child) {
|
||||
u8 => arg.* = sliceFromValue(sqlite_value),
|
||||
else => @compileError("cannot use an argument of type " ++ @typeName(ArgType)),
|
||||
},
|
||||
else => @compileError("cannot use an argument of type " ++ @typeName(ArgType)),
|
||||
},
|
||||
else => @compileError("cannot use an argument of type " ++ @typeName(ArgType)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn sliceFromValue(sqlite_value: *c.sqlite3_value) []const u8 {
|
||||
const size: usize = @intCast(c.sqlite3_value_bytes(sqlite_value));
|
||||
|
||||
const value = c.sqlite3_value_text(sqlite_value);
|
||||
debug.assert(value != null); // TODO(vincent): how do we handle this properly ?
|
||||
|
||||
return value[0..size];
|
||||
}
|
||||
|
||||
// Returns true if the type T has a function named `name`.
|
||||
pub fn hasFn(comptime T: type, comptime name: []const u8) bool {
|
||||
if (!@hasDecl(T, name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const decl = @field(T, name);
|
||||
const decl_type = @TypeOf(decl);
|
||||
const decl_type_info = @typeInfo(decl_type);
|
||||
|
||||
return switch (decl_type_info) {
|
||||
.@"fn" => true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
2
zig-vendor/zig-sqlite/mise.toml
Normal file
2
zig-vendor/zig-sqlite/mise.toml
Normal file
@@ -0,0 +1,2 @@
|
||||
[tools]
|
||||
zig = "master"
|
||||
464
zig-vendor/zig-sqlite/query.zig
Normal file
464
zig-vendor/zig-sqlite/query.zig
Normal file
@@ -0,0 +1,464 @@
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const testing = std.testing;
|
||||
|
||||
const Blob = @import("sqlite.zig").Blob;
|
||||
const Text = @import("sqlite.zig").Text;
|
||||
|
||||
const BindMarker = struct {
|
||||
/// Name of the bind parameter in case it's named.
|
||||
name: ?[]const u8 = null,
|
||||
/// Contains the expected type for a bind parameter which will be checked
|
||||
/// at comptime when calling bind on a statement.
|
||||
///
|
||||
/// A null means the bind parameter is untyped so there won't be comptime checking.
|
||||
typed: ?type = null,
|
||||
};
|
||||
|
||||
fn isNamedIdentifierChar(c: u8) bool {
|
||||
return std.ascii.isAlphabetic(c) or std.ascii.isDigit(c) or c == '_';
|
||||
}
|
||||
|
||||
fn bindMarkerForName(comptime markers: []const BindMarker, comptime name: []const u8) ?BindMarker {
|
||||
for (markers) |marker| {
|
||||
if (marker.name != null and std.mem.eql(u8, marker.name.?, name))
|
||||
return marker;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn ParsedQuery(comptime tmp_query: []const u8) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
|
||||
const result = parse();
|
||||
|
||||
pub const bind_markers = result.bind_markers[0..result.bind_markers_len];
|
||||
|
||||
pub fn getQuery() []const u8 {
|
||||
return Self.result.query[0..Self.result.query_len];
|
||||
}
|
||||
|
||||
const ParsedQueryResult = struct {
|
||||
bind_markers: [128]BindMarker,
|
||||
bind_markers_len: usize,
|
||||
query: [tmp_query.len]u8,
|
||||
query_len: usize,
|
||||
};
|
||||
|
||||
fn parse() ParsedQueryResult {
|
||||
// This contains the final SQL query after parsing with our
|
||||
// own typed bind markers removed.
|
||||
var buf: [tmp_query.len]u8 = undefined;
|
||||
var pos = 0;
|
||||
var state = .start;
|
||||
|
||||
// This holds the starting character of the string while
|
||||
// state is .inside_string so that we know which type of
|
||||
// string we're exiting from
|
||||
var string_starting_character: u8 = undefined;
|
||||
|
||||
var current_bind_marker_type: [256]u8 = undefined;
|
||||
var current_bind_marker_type_pos = 0;
|
||||
|
||||
// becomes part of our result
|
||||
var tmp_bind_markers: [128]BindMarker = undefined;
|
||||
var nb_tmp_bind_markers: usize = 0;
|
||||
|
||||
// used for capturing slices, such as bind parameter name
|
||||
var hold_pos = 0;
|
||||
|
||||
for (tmp_query) |c| {
|
||||
switch (state) {
|
||||
.start => switch (c) {
|
||||
'?', ':', '@', '$' => {
|
||||
tmp_bind_markers[nb_tmp_bind_markers] = BindMarker{};
|
||||
current_bind_marker_type_pos = 0;
|
||||
state = .bind_marker;
|
||||
buf[pos] = c;
|
||||
pos += 1;
|
||||
},
|
||||
'\'', '"', '[', '`' => {
|
||||
state = .inside_string;
|
||||
string_starting_character = c;
|
||||
buf[pos] = c;
|
||||
pos += 1;
|
||||
},
|
||||
else => {
|
||||
buf[pos] = c;
|
||||
pos += 1;
|
||||
},
|
||||
},
|
||||
.inside_string => switch (c) {
|
||||
'\'' => {
|
||||
if (string_starting_character == '\'') state = .start;
|
||||
buf[pos] = c;
|
||||
pos += 1;
|
||||
},
|
||||
'"' => {
|
||||
if (string_starting_character == '"') state = .start;
|
||||
buf[pos] = c;
|
||||
pos += 1;
|
||||
},
|
||||
']' => {
|
||||
if (string_starting_character == '[') state = .start;
|
||||
buf[pos] = c;
|
||||
pos += 1;
|
||||
},
|
||||
'`' => {
|
||||
if (string_starting_character == '`') state = .start;
|
||||
buf[pos] = c;
|
||||
pos += 1;
|
||||
},
|
||||
else => {
|
||||
buf[pos] = c;
|
||||
pos += 1;
|
||||
},
|
||||
},
|
||||
.bind_marker => switch (c) {
|
||||
'?', ':', '@', '$' => @compileError("invalid multiple '?', ':', '$' or '@'."),
|
||||
'{' => {
|
||||
state = .bind_marker_type;
|
||||
},
|
||||
else => {
|
||||
if (isNamedIdentifierChar(c)) {
|
||||
// This is the start of a named bind marker.
|
||||
state = .bind_marker_identifier;
|
||||
hold_pos = pos + 1;
|
||||
} else {
|
||||
// This is a unnamed, untyped bind marker.
|
||||
state = .start;
|
||||
|
||||
tmp_bind_markers[nb_tmp_bind_markers].typed = null;
|
||||
nb_tmp_bind_markers += 1;
|
||||
}
|
||||
buf[pos] = c;
|
||||
pos += 1;
|
||||
},
|
||||
},
|
||||
.bind_marker_identifier => switch (c) {
|
||||
'?', ':', '@', '$' => @compileError("unregconised multiple '?', ':', '$' or '@'."),
|
||||
'{' => {
|
||||
state = .bind_marker_type;
|
||||
current_bind_marker_type_pos = 0;
|
||||
},
|
||||
else => {
|
||||
if (!isNamedIdentifierChar(c)) {
|
||||
// This marks the end of the named bind marker.
|
||||
state = .start;
|
||||
const name = buf[hold_pos - 1 .. pos];
|
||||
// TODO(vincent): name retains a pointer to a comptime var, FIX !
|
||||
if (bindMarkerForName(tmp_bind_markers[0..nb_tmp_bind_markers], name) == null) {
|
||||
const new_buf = buf;
|
||||
tmp_bind_markers[nb_tmp_bind_markers].name = new_buf[hold_pos - 1 .. pos];
|
||||
nb_tmp_bind_markers += 1;
|
||||
}
|
||||
}
|
||||
buf[pos] = c;
|
||||
pos += 1;
|
||||
},
|
||||
},
|
||||
.bind_marker_type => switch (c) {
|
||||
'}' => {
|
||||
state = .start;
|
||||
|
||||
const type_info_string = current_bind_marker_type[0..current_bind_marker_type_pos];
|
||||
// Handles optional types
|
||||
const typ = if (type_info_string[0] == '?') blk: {
|
||||
const child_type = ParseType(type_info_string[1..]);
|
||||
break :blk ?child_type;
|
||||
} else blk: {
|
||||
break :blk ParseType(type_info_string);
|
||||
};
|
||||
|
||||
tmp_bind_markers[nb_tmp_bind_markers].typed = typ;
|
||||
nb_tmp_bind_markers += 1;
|
||||
},
|
||||
else => {
|
||||
current_bind_marker_type[current_bind_marker_type_pos] = c;
|
||||
current_bind_marker_type_pos += 1;
|
||||
},
|
||||
},
|
||||
else => {
|
||||
@compileError("invalid state " ++ @tagName(state));
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// The last character was a bind marker prefix so this must be an untyped bind marker.
|
||||
switch (state) {
|
||||
.bind_marker => {
|
||||
tmp_bind_markers[nb_tmp_bind_markers].typed = null;
|
||||
nb_tmp_bind_markers += 1;
|
||||
},
|
||||
.bind_marker_identifier => {
|
||||
const new_buf = buf;
|
||||
tmp_bind_markers[nb_tmp_bind_markers].name = @as([]const u8, new_buf[hold_pos - 1 .. pos]);
|
||||
nb_tmp_bind_markers += 1;
|
||||
},
|
||||
.start => {},
|
||||
else => @compileError("invalid final state " ++ @tagName(state) ++ ", this means you wrote an incomplete bind marker type"),
|
||||
}
|
||||
|
||||
const final_bind_markers = tmp_bind_markers;
|
||||
const final_bind_markers_len = nb_tmp_bind_markers;
|
||||
const final_buf = buf;
|
||||
const final_query_len = pos;
|
||||
|
||||
return .{
|
||||
.bind_markers = final_bind_markers,
|
||||
.bind_markers_len = final_bind_markers_len,
|
||||
.query = final_buf,
|
||||
.query_len = final_query_len,
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn ParseType(comptime type_info: []const u8) type {
|
||||
if (type_info.len <= 0) @compileError("invalid type info " ++ type_info);
|
||||
|
||||
// Integer
|
||||
if (mem.eql(u8, "usize", type_info)) return usize;
|
||||
if (mem.eql(u8, "isize", type_info)) return isize;
|
||||
|
||||
if (type_info[0] == 'u' or type_info[0] == 'i') {
|
||||
const signedness = switch (type_info[0]) {
|
||||
'u' => .unsigned,
|
||||
'i' => .signed,
|
||||
};
|
||||
return @Int(signedness, std.fmt.parseInt(usize, type_info[1..type_info.len], 10) catch {
|
||||
@compileError("invalid type info " ++ type_info);
|
||||
});
|
||||
}
|
||||
|
||||
// Float
|
||||
if (mem.eql(u8, "f16", type_info)) return f16;
|
||||
if (mem.eql(u8, "f32", type_info)) return f32;
|
||||
if (mem.eql(u8, "f64", type_info)) return f64;
|
||||
if (mem.eql(u8, "f128", type_info)) return f128;
|
||||
|
||||
// Bool
|
||||
if (mem.eql(u8, "bool", type_info)) return bool;
|
||||
|
||||
// Strings
|
||||
if (mem.eql(u8, "[]const u8", type_info) or mem.eql(u8, "[]u8", type_info)) {
|
||||
return []const u8;
|
||||
}
|
||||
if (mem.eql(u8, "text", type_info)) return Text;
|
||||
if (mem.eql(u8, "blob", type_info)) return Blob;
|
||||
|
||||
@compileError("invalid type info " ++ type_info);
|
||||
}
|
||||
|
||||
test "parsed query: query" {
|
||||
const testCase = struct {
|
||||
query: []const u8,
|
||||
expected_query: []const u8,
|
||||
};
|
||||
|
||||
const testCases = &[_]testCase{
|
||||
.{
|
||||
.query = "INSERT INTO user(id, name, age) VALUES(?{usize}, ?{[]const u8}, ?{u32})",
|
||||
.expected_query = "INSERT INTO user(id, name, age) VALUES(?, ?, ?)",
|
||||
},
|
||||
.{
|
||||
.query = "SELECT id, name, age FROM user WHER age > ?{u32} AND age < ?{u32}",
|
||||
.expected_query = "SELECT id, name, age FROM user WHER age > ? AND age < ?",
|
||||
},
|
||||
.{
|
||||
.query = "SELECT id, name, age FROM user WHER age > ? AND age < ?",
|
||||
.expected_query = "SELECT id, name, age FROM user WHER age > ? AND age < ?",
|
||||
},
|
||||
};
|
||||
|
||||
inline for (testCases) |tc| {
|
||||
@setEvalBranchQuota(100000);
|
||||
const parsed_query = ParsedQuery(tc.query);
|
||||
try testing.expectEqualStrings(tc.expected_query, parsed_query.getQuery());
|
||||
}
|
||||
}
|
||||
|
||||
test "parsed query: bind markers types" {
|
||||
const testCase = struct {
|
||||
query: []const u8,
|
||||
expected_marker: BindMarker,
|
||||
};
|
||||
|
||||
const prefixes = &[_][]const u8{
|
||||
"?",
|
||||
"?123",
|
||||
":",
|
||||
":hello",
|
||||
"$",
|
||||
"$foobar",
|
||||
"@",
|
||||
"@name",
|
||||
};
|
||||
|
||||
inline for (prefixes) |prefix| {
|
||||
const testCases = &[_]testCase{
|
||||
.{
|
||||
.query = "foobar " ++ prefix ++ "{usize}",
|
||||
.expected_marker = .{ .typed = usize },
|
||||
},
|
||||
.{
|
||||
.query = "foobar " ++ prefix ++ "{text}",
|
||||
.expected_marker = .{ .typed = Text },
|
||||
},
|
||||
.{
|
||||
.query = "foobar " ++ prefix ++ "{blob}",
|
||||
.expected_marker = .{ .typed = Blob },
|
||||
},
|
||||
.{
|
||||
.query = "foobar " ++ prefix,
|
||||
.expected_marker = .{ .typed = null },
|
||||
},
|
||||
.{
|
||||
.query = "foobar " ++ prefix ++ "{?[]const u8}",
|
||||
.expected_marker = .{ .typed = ?[]const u8 },
|
||||
},
|
||||
};
|
||||
|
||||
inline for (testCases) |tc| {
|
||||
@setEvalBranchQuota(100000);
|
||||
const parsed_query = comptime ParsedQuery(tc.query);
|
||||
|
||||
try testing.expectEqual(1, parsed_query.bind_markers.len);
|
||||
|
||||
const bind_marker = parsed_query.bind_markers[0];
|
||||
try testing.expectEqual(tc.expected_marker.typed, bind_marker.typed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test "parsed query: bind markers identifier" {
|
||||
const testCase = struct {
|
||||
query: []const u8,
|
||||
expected_marker: BindMarker,
|
||||
};
|
||||
|
||||
const testCases = &[_]testCase{
|
||||
.{
|
||||
.query = "foobar @ABC{usize}",
|
||||
.expected_marker = .{ .typed = usize },
|
||||
},
|
||||
.{
|
||||
.query = "foobar ?123{text}",
|
||||
.expected_marker = .{ .typed = Text },
|
||||
},
|
||||
.{
|
||||
.query = "foobar $abc{blob}",
|
||||
.expected_marker = .{ .typed = Blob },
|
||||
},
|
||||
.{
|
||||
.query = "foobar :430{u32}",
|
||||
.expected_marker = .{ .typed = u32 },
|
||||
},
|
||||
.{
|
||||
.query = "foobar ?123",
|
||||
.expected_marker = .{ .typed = null, .name = "123" },
|
||||
},
|
||||
.{
|
||||
.query = "foobar :hola",
|
||||
.expected_marker = .{ .typed = null, .name = "hola" },
|
||||
},
|
||||
.{
|
||||
.query = "foobar @foo",
|
||||
.expected_marker = .{ .typed = null, .name = "foo" },
|
||||
},
|
||||
};
|
||||
|
||||
inline for (testCases) |tc| {
|
||||
const parsed_query = comptime ParsedQuery(tc.query);
|
||||
|
||||
try testing.expectEqual(@as(usize, 1), parsed_query.bind_markers.len);
|
||||
|
||||
const bind_marker = parsed_query.bind_markers[0];
|
||||
if (bind_marker.name) |name| {
|
||||
try testing.expectEqualStrings(tc.expected_marker.name.?, name);
|
||||
}
|
||||
try testing.expectEqual(tc.expected_marker.typed, bind_marker.typed);
|
||||
}
|
||||
}
|
||||
|
||||
test "parsed query: query bind identifier" {
|
||||
const testCase = struct {
|
||||
query: []const u8,
|
||||
expected_query: []const u8,
|
||||
expected_nb_bind_markers: usize,
|
||||
};
|
||||
|
||||
const testCases = &[_]testCase{
|
||||
.{
|
||||
.query = "INSERT INTO user(id, name, age) VALUES(@id{usize}, :name{[]const u8}, $age{u32})",
|
||||
.expected_query = "INSERT INTO user(id, name, age) VALUES(@id, :name, $age)",
|
||||
.expected_nb_bind_markers = 3,
|
||||
},
|
||||
.{
|
||||
.query = "INSERT INTO user(id, name, age) VALUES($id, $name, $age)",
|
||||
.expected_query = "INSERT INTO user(id, name, age) VALUES($id, $name, $age)",
|
||||
.expected_nb_bind_markers = 3,
|
||||
},
|
||||
.{
|
||||
.query = "SELECT id, name, age FROM user WHER age > :ageGT{u32} AND age < @ageLT{u32}",
|
||||
.expected_query = "SELECT id, name, age FROM user WHER age > :ageGT AND age < @ageLT",
|
||||
.expected_nb_bind_markers = 2,
|
||||
},
|
||||
.{
|
||||
.query = "SELECT id, name, age FROM user WHER age > :ageGT AND age < $ageLT",
|
||||
.expected_query = "SELECT id, name, age FROM user WHER age > :ageGT AND age < $ageLT",
|
||||
.expected_nb_bind_markers = 2,
|
||||
},
|
||||
.{
|
||||
.query = "SELECT id, name, age FROM user WHER age > $my_age{i32} AND age < :your_age{i32}",
|
||||
.expected_query = "SELECT id, name, age FROM user WHER age > $my_age AND age < :your_age",
|
||||
.expected_nb_bind_markers = 2,
|
||||
},
|
||||
};
|
||||
|
||||
inline for (testCases) |tc| {
|
||||
@setEvalBranchQuota(100000);
|
||||
|
||||
comptime {
|
||||
const parsed_query = ParsedQuery(tc.query);
|
||||
|
||||
try testing.expectEqual(tc.expected_nb_bind_markers, parsed_query.bind_markers.len);
|
||||
try testing.expectEqualStrings(tc.expected_query, parsed_query.getQuery());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test "parsed query: bind marker character inside string" {
|
||||
const testCase = struct {
|
||||
query: []const u8,
|
||||
exp_bind_markers: comptime_int,
|
||||
exp: []const u8,
|
||||
};
|
||||
|
||||
const testCases = &[_]testCase{
|
||||
.{
|
||||
.query = "SELECT json_extract(metadata, '$.name') AS name FROM foobar",
|
||||
.exp_bind_markers = 0,
|
||||
.exp = "SELECT json_extract(metadata, '$.name') AS name FROM foobar",
|
||||
},
|
||||
.{
|
||||
.query = "SELECT json_extract(metadata, '$.name') AS name FROM foobar WHERE name = $name{text}",
|
||||
.exp_bind_markers = 1,
|
||||
.exp = "SELECT json_extract(metadata, '$.name') AS name FROM foobar WHERE name = $name",
|
||||
},
|
||||
.{
|
||||
.query = "SELECT json_extract(metadata, '$[0]') AS name FROM foobar",
|
||||
.exp_bind_markers = 0,
|
||||
.exp = "SELECT json_extract(metadata, '$[0]') AS name FROM foobar",
|
||||
},
|
||||
};
|
||||
|
||||
inline for (testCases) |tc| {
|
||||
@setEvalBranchQuota(100000);
|
||||
const parsed_query = ParsedQuery(tc.query);
|
||||
|
||||
try testing.expectEqual(@as(usize, tc.exp_bind_markers), parsed_query.bind_markers.len);
|
||||
try testing.expectEqualStrings(tc.exp, parsed_query.getQuery());
|
||||
}
|
||||
}
|
||||
4120
zig-vendor/zig-sqlite/sqlite.zig
Normal file
4120
zig-vendor/zig-sqlite/sqlite.zig
Normal file
File diff suppressed because it is too large
Load Diff
50
zig-vendor/zig-sqlite/test.zig
Normal file
50
zig-vendor/zig-sqlite/test.zig
Normal file
@@ -0,0 +1,50 @@
|
||||
const std = @import("std");
|
||||
const build_options = @import("build_options");
|
||||
const mem = std.mem;
|
||||
const testing = std.testing;
|
||||
|
||||
const Db = @import("sqlite.zig").Db;
|
||||
|
||||
pub fn getTestDb() !Db {
|
||||
var buf: [1024]u8 = undefined;
|
||||
var fba = std.heap.FixedBufferAllocator.init(&buf);
|
||||
|
||||
const mode = dbMode(fba.allocator());
|
||||
|
||||
return try Db.init(.{
|
||||
.open_flags = .{
|
||||
.write = true,
|
||||
.create = true,
|
||||
},
|
||||
.mode = mode,
|
||||
});
|
||||
}
|
||||
|
||||
fn tmpDbPath(allocator: mem.Allocator) ![:0]const u8 {
|
||||
const tmp_dir = testing.tmpDir(.{});
|
||||
|
||||
const path = try std.fs.path.join(allocator, &[_][]const u8{
|
||||
"zig-cache",
|
||||
"tmp",
|
||||
&tmp_dir.sub_path,
|
||||
"zig-sqlite.db",
|
||||
});
|
||||
defer allocator.free(path);
|
||||
|
||||
return allocator.dupeZ(u8, path);
|
||||
}
|
||||
|
||||
fn dbMode(allocator: mem.Allocator) Db.Mode {
|
||||
return if (build_options.in_memory) blk: {
|
||||
break :blk .{ .Memory = {} };
|
||||
} else blk: {
|
||||
if (build_options.dbfile) |dbfile| {
|
||||
return .{ .File = allocator.dupeZ(u8, dbfile) catch unreachable };
|
||||
}
|
||||
|
||||
const path = tmpDbPath(allocator) catch unreachable;
|
||||
|
||||
std.fs.cwd().deleteFile(path) catch {};
|
||||
break :blk .{ .File = path };
|
||||
};
|
||||
}
|
||||
1315
zig-vendor/zig-sqlite/vtab.zig
Normal file
1315
zig-vendor/zig-sqlite/vtab.zig
Normal file
File diff suppressed because it is too large
Load Diff
16
zig-vendor/zig-sqlite/zig.mod
vendored
Normal file
16
zig-vendor/zig-sqlite/zig.mod
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
id: nj8usqhaks6kkewaj3pbp0arfh4281me25bl7tf9das1vbqv
|
||||
name: sqlite
|
||||
main: sqlite.zig
|
||||
license: MIT
|
||||
description: Thin SQLite wrapper
|
||||
c_include_dirs:
|
||||
- c
|
||||
c_source_files:
|
||||
- c/workaround.c
|
||||
dependencies:
|
||||
- src: http https://sqlite.org/2025/sqlite-amalgamation-3480000.zip sha256-d9a15a42db7c78f88fe3d3c5945acce2f4bfe9e4da9f685cd19f6ea1d40aa884
|
||||
license: blessing
|
||||
c_include_dirs:
|
||||
- sqlite-amalgamation-3480000
|
||||
c_source_files:
|
||||
- sqlite-amalgamation-3480000/sqlite3.c
|
||||
1
zig-vendor/zig-sqlite/zigmod.lock
Normal file
1
zig-vendor/zig-sqlite/zigmod.lock
Normal file
@@ -0,0 +1 @@
|
||||
2
|
||||
Reference in New Issue
Block a user