Skip to content
This repository has been archived by the owner on Jan 5, 2025. It is now read-only.

Commit

Permalink
virtual table context struct
Browse files Browse the repository at this point in the history
  • Loading branch information
dgllghr committed Feb 7, 2024
1 parent 3515e6a commit 1b13440
Show file tree
Hide file tree
Showing 13 changed files with 400 additions and 399 deletions.
51 changes: 27 additions & 24 deletions src/BlobManager.zig
Original file line number Diff line number Diff line change
Expand Up @@ -7,49 +7,52 @@ const sqlite = @import("sqlite3.zig");
const Blob = sqlite.Blob;
const Conn = sqlite.Conn;

const VtabCtxSchemaless = @import("ctx.zig").VtabCtxSchemaless;
const prep_stmt = @import("prepared_stmt.zig");

conn: Conn,
ctx: *const VtabCtxSchemaless,

/// The full name of the shadow table so it can be passed to `Blob.open` without allocating
table_name: [:0]const u8,

insert_stmt: StmtCell,
delete_stmt: StmtCell,

const Self = @This();

const StmtCell = prep_stmt.Cell(Self);
const StmtCell = prep_stmt.Cell(VtabCtxSchemaless);

const blob_column_name = "blob";

pub fn init(
lifetime_arena: *ArenaAllocator,
tmp_arena: *ArenaAllocator,
conn: Conn,
vtab_table_name: []const u8,
ctx: *const VtabCtxSchemaless,
) !Self {
try setup(tmp_arena, conn, vtab_table_name);
try setup(tmp_arena, ctx.*);

const table_name = try fmt.allocPrintZ(
lifetime_arena.allocator(),
"{s}_blobs",
.{vtab_table_name},
.{ctx.vtabName()},
);

return .{
.conn = conn,
.ctx = ctx,
.table_name = table_name,
.insert_stmt = StmtCell.init(&insertDml),
.delete_stmt = StmtCell.init(&deleteDml),
};
}

fn setup(tmp_arena: *ArenaAllocator, conn: Conn, vtab_table_name: []const u8) !void {
fn setup(tmp_arena: *ArenaAllocator, ctx: VtabCtxSchemaless) !void {
const query = try fmt.allocPrintZ(tmp_arena.allocator(),
\\CREATE TABLE IF NOT EXISTS "{s}_blobs" (
\\ id INTEGER NOT NULL PRIMARY KEY,
\\ blob BLOB NOT NULL
\\)
, .{vtab_table_name});
try conn.exec(query);
, .{ctx.vtabName()});
try ctx.conn().exec(query);
}

pub fn deinit(self: *Self) void {
Expand All @@ -60,11 +63,11 @@ pub fn deinit(self: *Self) void {
pub fn destroy(self: *Self, tmp_arena: *ArenaAllocator) !void {
const query = try fmt.allocPrintZ(
tmp_arena.allocator(),
\\DROP TABLE "{s}"
\\DROP TABLE "{s}_blobs"
,
.{self.table_name},
.{self.ctx.vtabName()},
);
try self.conn.exec(query);
try self.ctx.conn().exec(query);
}

pub const Handle = struct {
Expand Down Expand Up @@ -102,34 +105,34 @@ pub const Handle = struct {
};

pub fn create(self: *Self, tmp_arena: *ArenaAllocator, size: u32) !Handle {
const stmt = try self.insert_stmt.acquire(tmp_arena, self);
const stmt = try self.insert_stmt.acquire(tmp_arena, self.ctx.*);
defer self.insert_stmt.release();

try stmt.bind(.Int64, 1, @as(i64, @intCast(size)));

try stmt.exec();
const id = self.conn.lastInsertRowid();
const id = self.ctx.conn().lastInsertRowid();
errdefer self.delete(tmp_arena, id) catch |e| {
log.err("unable to destroy segment {}: {}", .{ id, e });
};

const blob = try Blob.open(self.conn, self.table_name, blob_column_name, id);
const blob = try Blob.open(self.ctx.conn(), self.table_name, blob_column_name, id);
return .{
.ctx = self,
.id = id,
.blob = blob,
};
}

fn insertDml(self: *const Self, arena: *ArenaAllocator) ![]const u8 {
fn insertDml(ctx: VtabCtxSchemaless, arena: *ArenaAllocator) ![]const u8 {
return fmt.allocPrintZ(arena.allocator(),
\\INSERT INTO "{s}" (blob)
\\INSERT INTO "{s}_blobs" (blob)
\\VALUES (ZEROBLOB(?))
, .{self.table_name});
, .{ctx.vtabName()});
}

pub fn open(self: *Self, id: i64) !Handle {
const blob = try Blob.open(self.conn, self.table_name, blob_column_name, id);
const blob = try Blob.open(self.ctx.conn(), self.table_name, blob_column_name, id);
return .{
.ctx = self,
.id = id,
Expand All @@ -138,15 +141,15 @@ pub fn open(self: *Self, id: i64) !Handle {
}

pub fn delete(self: *Self, tmp_arena: *ArenaAllocator, id: i64) !void {
const stmt = try self.delete_stmt.acquire(tmp_arena, self);
const stmt = try self.delete_stmt.acquire(tmp_arena, self.ctx.*);
defer self.delete_stmt.release();

try stmt.bind(.Int64, 1, @as(i64, @intCast(id)));
try stmt.exec();
}

fn deleteDml(self: *const Self, arena: *ArenaAllocator) ![]const u8 {
fn deleteDml(ctx: VtabCtxSchemaless, arena: *ArenaAllocator) ![]const u8 {
return fmt.allocPrintZ(arena.allocator(),
\\DELETE FROM "{s}" WHERE id = ?
, .{self.table_name});
\\DELETE FROM "{s}_blobs" WHERE id = ?
, .{ctx.vtabName()});
}
Loading

0 comments on commit 1b13440

Please sign in to comment.