Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ The plan is to support releases once Zig 1.0 is released but this can still chan
- [User defined SQL functions](#user-defined-sql-functions)
- [Scalar functions](#scalar-functions)
- [Aggregate functions](#aggregate-functions)
- [Setting Compile-time Options](#setting-compile-time-options)
<!--toc:end-->

# Requirements
Expand Down Expand Up @@ -88,6 +89,9 @@ const sqlite = b.dependency("sqlite", .{
exe.root_module.addImport("sqlite", sqlite.module("sqlite"));
```

If you'd like to use specific features that can only be accessed by setting
compile-time options (like FTS5, R*Tree), you can define them here as build options. See [Setting Compile-time Options](#setting-compile-time-options) for instructions.

# Usage

## Demo
Expand Down Expand Up @@ -650,3 +654,39 @@ 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.

# Setting Compile-time Options

SQLite compile-time options are added as build options for customizing the SQLite source code.

```zig
// This is an example of a recommended config.
const sqlite = b.dependency("sqlite", .{
.target = target,
.optimize = optimize,
.default_memstatus = 0,
.omit_deprecated = true,
.DQS = 0,
.null_trim = true,
.like_doesnt_match_blobs = true,
.omit_shared_cache = true,
.omit_autoinit = true,
.default_wal_synchronous = 1,
.strict_subtype = optimize == .Debug,
.api_armor = optimize == .Debug,
.max_expr_depth = if (optimize != .Debug) 0 else 1000,
.use_alloca = switch(target.result.os.tag) {
.linux, .windows => true,
else => false,
},
});
```

The options are shortened for easier reading. You can check them by running `zig build --help` in this project. Mostly they follow the rules below.

- Upper-cases are converted into lower-cases, unless the word is already shortened, like "DQS" for "double-quoted strings"
- `SQLITE_ENABLE_` is trimmed. For example, `SQLITE_ENABLE_API_ARMOR` translates to `api_armor`.
- Otherwise, `SQLITE_` is trimmed. For example, `SQLITE_ZERO_MALLOC` translates to `zero_malloc`.
- If the option doesn't receive argument, or receives 0 or 1, it's defined as `bool`.
- If the option only accepts `1`, it's defined as `u1`; a int must be used as the argument.
- "Not recommended", "No-op" and "Deprecated" options are not added as build options.
96 changes: 96 additions & 0 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,43 @@ pub fn build(b: *std.Build) !void {
}
}

inline for (std.meta.fields(BoolFeatureOptions)) |field| {
comptime var buf: [field.name.len]u8 = undefined;
const name = comptime std.ascii.upperString(&buf, field.name);
const opt = b.option(bool, field.name, "Set SQLITE_" ++ name);

if (opt) |v| {
const flag_value = if (v) "1" else "0";
const flag = try std.fmt.allocPrint(b.allocator, "-DSQLITE_" ++ name ++ "={s}", .{flag_value});

try flags.append(b.allocator, flag);
}
}

inline for (std.meta.fields(DefineFeatureOptions)) |field| {
comptime var buf: [field.name.len]u8 = undefined;
const name = comptime std.ascii.upperString(&buf, field.name);
const opt = b.option(bool, field.name, "Set SQLITE_" ++ name) orelse false;

if (opt) {
const flag = try std.fmt.allocPrint(b.allocator, "-DSQLITE_" ++ name, .{});

try flags.append(b.allocator, flag);
}
}

inline for (std.meta.fields(IntFeatureOptions)) |field| {
comptime var buf: [field.name.len]u8 = undefined;
const name = comptime std.ascii.upperString(&buf, field.name);
const opt = b.option(field.type, field.name, "Set SQLITE_" ++ name);

if (opt) |v| {
const flag = try std.fmt.allocPrint(b.allocator, "-DSQLITE_" ++ name ++ "={}", .{v});

try flags.append(b.allocator, flag);
}
}

const c_flags = flags.items;

//
Expand Down Expand Up @@ -337,8 +374,67 @@ fn addZigcryptoTestRun(b: *std.Build, sqlite_mod: *std.Build.Module, target: std

// See https://www.sqlite.org/compile.html for flags
const EnableOptions = struct {
api_armor: bool = false,
atomic_write: bool = false,
batch_atomic_write: bool = false,
carray: bool = false,
column_metadata: bool = false,
dbpage_vtab: bool = false,
dbstat_vtab: bool = false,
explain_comments: bool = false,
// https://www.sqlite.org/fts5.html
fts5: bool = false,
geopoly: bool = false,
hidden_columns: bool = false,
icu: bool = false,
math_functions: bool = false,
memsys3: bool = false,
memsys5: bool = false,
null_trim: bool = false,
offset_sql_func: bool = false,
percentile: bool = false,
preupdate_hook: bool = false,
RBU: bool = false,
rtree: bool = false,
session: bool = false,
sorter_reference: bool = false,
stmtvtab: bool = false,
stat4: bool = false,
};

/// `false` = won't be defined
/// `true` = will be defined
const DefineFeatureOptions = enum {
like_doesnt_match_blobs,
omit_decltype,
omit_deprecated,
omit_progress_callback,
omit_shared_cache,
omit_autoinit,
use_alloca,
zero_malloc,
debug,
memdebug,
win32_malloc,
win32_heap_create,
win32_malloc_validate,
};

/// - `null` = default
/// - `true` = `1`
/// - `false` = `0`
const BoolFeatureOptions = enum {
default_memstatus,
strict_subtype,
os_other,
};

/// The compile-time options with an int argument.
const IntFeatureOptions = struct {
DQS: std.math.IntFittingRange(0, 3),
threadsafe: std.math.IntFittingRange(0, 2),
default_wal_synchronous: std.math.IntFittingRange(0, 3),
max_expr_depth: c_int,
};

const PreprocessStep = struct {
Expand Down
Loading