diff options
Diffstat (limited to 'sqlite.zig')
| -rw-r--r-- | sqlite.zig | 44 |
1 files changed, 29 insertions, 15 deletions
| @@ -18,6 +18,12 @@ pub const ThreadingMode = enum { | |||
| 18 | Serialized, | 18 | Serialized, |
| 19 | }; | 19 | }; |
| 20 | 20 | ||
| 21 | pub const InitOptions = struct { | ||
| 22 | mode: Db.Mode = .Memory, | ||
| 23 | open_flags: Db.OpenFlags = .{}, | ||
| 24 | threading_mode: ThreadingMode = .SingleThread, | ||
| 25 | }; | ||
| 26 | |||
| 21 | fn isThreadSafe() bool { | 27 | fn isThreadSafe() bool { |
| 22 | return c.sqlite3_threadsafe() > 0; | 28 | return c.sqlite3_threadsafe() > 0; |
| 23 | } | 29 | } |
| @@ -45,27 +51,38 @@ pub const Db = struct { | |||
| 45 | Memory, | 51 | Memory, |
| 46 | }; | 52 | }; |
| 47 | 53 | ||
| 54 | pub const OpenFlags = struct { | ||
| 55 | write: bool = false, | ||
| 56 | create: bool = false, | ||
| 57 | }; | ||
| 58 | |||
| 48 | /// init creates a database with the provided `mode`. | 59 | /// init creates a database with the provided `mode`. |
| 49 | pub fn init(self: *Self, allocator: *mem.Allocator, options: anytype) !void { | 60 | pub fn init(self: *Self, allocator: *mem.Allocator, options: InitOptions) !void { |
| 50 | self.allocator = allocator; | 61 | self.allocator = allocator; |
| 51 | 62 | ||
| 52 | const mode: Mode = if (@hasField(@TypeOf(options), "mode")) options.mode else .Memory; | ||
| 53 | // Validate the threading mode | 63 | // Validate the threading mode |
| 54 | if (options.threading_mode != .SingleThread and !isThreadSafe()) { | 64 | if (options.threading_mode != .SingleThread and !isThreadSafe()) { |
| 55 | return error.CannotUseSingleThreadedSQLite; | 65 | return error.CannotUseSingleThreadedSQLite; |
| 56 | } | 66 | } |
| 57 | 67 | ||
| 58 | switch (mode) { | 68 | // Compute the flags |
| 69 | var flags: c_int = 0; | ||
| 70 | flags |= @as(c_int, if (options.open_flags.write) c.SQLITE_OPEN_READWRITE else c.SQLITE_OPEN_READONLY); | ||
| 71 | if (options.open_flags.create) { | ||
| 72 | flags |= c.SQLITE_OPEN_CREATE; | ||
| 73 | } | ||
| 74 | switch (options.threading_mode) { | ||
| 75 | .MultiThread => flags |= c.SQLITE_OPEN_NOMUTEX, | ||
| 76 | .Serialized => flags |= c.SQLITE_OPEN_FULLMUTEX, | ||
| 77 | else => {}, | ||
| 78 | } | ||
| 79 | |||
| 80 | switch (options.mode) { | ||
| 59 | .File => |path| { | 81 | .File => |path| { |
| 60 | logger.info("opening {}", .{path}); | 82 | logger.info("opening {}", .{path}); |
| 61 | 83 | ||
| 62 | var db: ?*c.sqlite3 = undefined; | 84 | var db: ?*c.sqlite3 = undefined; |
| 63 | const result = c.sqlite3_open_v2( | 85 | const result = c.sqlite3_open_v2(path, &db, flags, null); |
| 64 | path, | ||
| 65 | &db, | ||
| 66 | c.SQLITE_OPEN_READWRITE | c.SQLITE_OPEN_CREATE, | ||
| 67 | null, | ||
| 68 | ); | ||
| 69 | if (result != c.SQLITE_OK or db == null) { | 86 | if (result != c.SQLITE_OK or db == null) { |
| 70 | logger.warn("unable to open database, result: {}", .{result}); | 87 | logger.warn("unable to open database, result: {}", .{result}); |
| 71 | return error.CannotOpenDatabase; | 88 | return error.CannotOpenDatabase; |
| @@ -76,13 +93,10 @@ pub const Db = struct { | |||
| 76 | .Memory => { | 93 | .Memory => { |
| 77 | logger.info("opening in memory", .{}); | 94 | logger.info("opening in memory", .{}); |
| 78 | 95 | ||
| 96 | flags |= c.SQLITE_OPEN_MEMORY; | ||
| 97 | |||
| 79 | var db: ?*c.sqlite3 = undefined; | 98 | var db: ?*c.sqlite3 = undefined; |
| 80 | const result = c.sqlite3_open_v2( | 99 | const result = c.sqlite3_open_v2(":memory:", &db, flags, null); |
| 81 | ":memory:", | ||
| 82 | &db, | ||
| 83 | c.SQLITE_OPEN_READWRITE | c.SQLITE_OPEN_MEMORY, | ||
| 84 | null, | ||
| 85 | ); | ||
| 86 | if (result != c.SQLITE_OK or db == null) { | 100 | if (result != c.SQLITE_OK or db == null) { |
| 87 | logger.warn("unable to open database, result: {}", .{result}); | 101 | logger.warn("unable to open database, result: {}", .{result}); |
| 88 | return error.CannotOpenDatabase; | 102 | return error.CannotOpenDatabase; |