Skip to content
Draft
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
19 changes: 10 additions & 9 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -121,15 +121,15 @@ fn makeSQLiteLib(b: *std.Build, dep: *std.Build.Dependency, c_flags: []const []c
.root_module = mod,
});

lib.addIncludePath(dep.path("."));
lib.addIncludePath(b.path("c"));
lib.root_module.addIncludePath(dep.path("."));
lib.root_module.addIncludePath(b.path("c"));
if (sqlite_c == .with) {
lib.addCSourceFile(.{
lib.root_module.addCSourceFile(.{
.file = dep.path("sqlite3.c"),
.flags = c_flags,
});
}
lib.addCSourceFile(.{
lib.root_module.addCSourceFile(.{
.file = b.path("c/workaround.c"),
.flags = c_flags,
});
Expand Down Expand Up @@ -242,9 +242,9 @@ pub fn build(b: *std.Build) !void {
.name = test_name,
.root_module = mod,
});
tests.addIncludePath(b.path("c"));
tests.addIncludePath(sqlite_dep.path("."));
tests.linkLibrary(test_sqlite_lib);
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());
Expand Down Expand Up @@ -367,14 +367,15 @@ const PreprocessStep = struct {
fn make(step: *std.Build.Step, _: std.Build.Step.MakeOptions) !void {
const ps: *PreprocessStep = @fieldParentPtr("step", step);
const owner = step.owner;
var threaded: std.Io.Threaded = .init_single_threaded;

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);

try Preprocessor.sqlite3(owner.allocator, sqlite3_h, loadable_sqlite3_h);
try Preprocessor.sqlite3ext(owner.allocator, sqlite3ext_h, loadable_sqlite3ext_h);
try Preprocessor.sqlite3(owner.allocator, threaded.io(), sqlite3_h, loadable_sqlite3_h);
try Preprocessor.sqlite3ext(owner.allocator, threaded.io(), sqlite3ext_h, loadable_sqlite3ext_h);
}
};
35 changes: 18 additions & 17 deletions build/Preprocessor.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const std = @import("std");
const debug = std.debug;
const mem = std.mem;
const Io = std.Io;

// This tool is used to preprocess the sqlite3 headers to make them usable to build loadable extensions.
//
Expand All @@ -24,11 +25,11 @@ const mem = std.mem;
// 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(allocator: mem.Allocator, path: []const u8) ![]const u8 {
var file = try std.fs.cwd().openFile(path, .{});
defer file.close();
fn readOriginalData(allocator: mem.Allocator, io: Io, 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(&buf);
var reader = file.reader(io, &buf);

const data = reader.interface.readAlloc(allocator, 1024 * 1024);
return data;
Expand Down Expand Up @@ -153,8 +154,8 @@ const Processor = struct {
}
};

pub fn sqlite3(allocator: mem.Allocator, input_path: []const u8, output_path: []const u8) !void {
const data = try readOriginalData(allocator, input_path);
pub fn sqlite3(allocator: mem.Allocator, io: Io, input_path: []const u8, output_path: []const u8) !void {
const data = try readOriginalData(allocator, io, input_path);

var processor = try Processor.init(allocator, data);

Expand Down Expand Up @@ -192,17 +193,17 @@ pub fn sqlite3(allocator: mem.Allocator, input_path: []const u8, output_path: []

// Write the result

var output_file = try std.fs.cwd().createFile(output_path, .{ .mode = 0o0644 });
defer output_file.close();

try output_file.writeAll("/* sqlite3.h edited by the zig-sqlite build script */\n");
var output_file = try std.Io.Dir.cwd().createFile(io, output_path, .{}); // FIXME: Can't set .mode as an octal. Is it really necessary to have it 0644 instead of 0666?
defer output_file.close(io);
var buf: [1024]u8 = undefined;
var out_writer = output_file.writer(&buf);
var out_writer = output_file.writer(io, &buf);
try out_writer.interface.writeAll("/* sqlite3.h edited by the zig-sqlite build script */\n");

try processor.dump(&out_writer);
}

pub fn sqlite3ext(allocator: mem.Allocator, input_path: []const u8, output_path: []const u8) !void {
const data = try readOriginalData(allocator, input_path);
pub fn sqlite3ext(allocator: mem.Allocator, io: Io, input_path: []const u8, output_path: []const u8) !void {
const data = try readOriginalData(allocator, io, input_path);

var processor = try Processor.init(allocator, data);

Expand Down Expand Up @@ -230,11 +231,11 @@ pub fn sqlite3ext(allocator: mem.Allocator, input_path: []const u8, output_path:

// Write the result

var output_file = try std.fs.cwd().createFile(output_path, .{ .mode = 0o0644 });
defer output_file.close();
var output_file = try std.Io.Dir.cwd().createFile(io, output_path, .{}); // FIXME: Can't set .mode as an octal. Is it really necessary to have it 0644 instead of 0666?

try output_file.writeAll("/* sqlite3ext.h edited by the zig-sqlite build script */\n");
defer output_file.close(io);
var buf: [1024]u8 = undefined;
var out_writer = output_file.writer(&buf);
var out_writer = output_file.writer(io, &buf);
try out_writer.interface.writeAll("/* sqlite3ext.h edited by the zig-sqlite build script */\n");
try processor.dump(&out_writer);
}
29 changes: 8 additions & 21 deletions query.zig
Original file line number Diff line number Diff line change
Expand Up @@ -161,21 +161,8 @@ pub fn ParsedQuery(comptime tmp_query: []const u8) type {
.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 @Type(std.builtin.Type{
.optional = .{
.child = child_type,
},
});
} else blk: {
break :blk ParseType(type_info_string);
};

tmp_bind_markers[nb_tmp_bind_markers].typed = typ;
tmp_bind_markers[nb_tmp_bind_markers].typed = ParseType(type_info_string);
nb_tmp_bind_markers += 1;
},
else => {
Expand Down Expand Up @@ -222,18 +209,18 @@ pub fn ParsedQuery(comptime tmp_query: []const u8) type {
fn ParseType(comptime type_info: []const u8) type {
if (type_info.len <= 0) @compileError("invalid type info " ++ type_info);

if (type_info[0] == '?') {
const parsed_type = ParseType(type_info[1..]);
return ?parsed_type;
}

// 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') {
return @Type(std.builtin.Type{
.int = std.builtin.Type.Int{
.signedness = if (type_info[0] == 'i') .signed else .unsigned,
.bits = std.fmt.parseInt(usize, type_info[1..type_info.len], 10) catch {
@compileError("invalid type info " ++ type_info);
},
},
return @Int(if (type_info[0] == 'i') .signed else .unsigned, std.fmt.parseInt(usize, type_info[1..type_info.len], 10) catch {
@compileError("invalid type info " ++ type_info);
});
}

Expand Down
4 changes: 2 additions & 2 deletions sqlite.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1470,7 +1470,7 @@ pub fn Iterator(comptime Type: type) type {
},
inline .@"struct", .@"union" => |TI| {
if (TI.layout == .@"packed" and !@hasField(FieldType, "readField")) {
const Backing = @Type(.{ .int = .{ .signedness = .unsigned, .bits = @bitSizeOf(FieldType) } });
const Backing = @Int(.unsigned, @bitSizeOf(FieldType));
return @bitCast(self.readInt(Backing, i));
}

Expand Down Expand Up @@ -1701,7 +1701,7 @@ pub const DynamicStatement = struct {
},
.@"union" => |info| {
if (info.layout == .@"packed") {
const Backing = @Type(.{ .int = .{ .signedness = .unsigned, .bits = @bitSizeOf(FieldType) } });
const Backing = @Int(.unsigned, @bitSizeOf(FieldType));
try self.bindField(Backing, options, field_name, i, @as(Backing, @bitCast(field)));
return;
}
Expand Down