From 69101f4fc5529706d7bf3cd97b3634cd67348e6e Mon Sep 17 00:00:00 2001 From: ketmar Date: Wed, 13 Oct 2021 14:44:30 +0000 Subject: [PATCH] sq3: better open API FossilOrigin-Name: c94864a36f912f4591dcc163b1dc065353e114c5c258a2d375286d58db6ca2b0 --- sq3.d | 44 +++++++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/sq3.d b/sq3.d index 80551fb..3d08a40 100644 --- a/sq3.d +++ b/sq3.d @@ -115,10 +115,18 @@ private: } public: + enum Mode { + ReadOnly, + ReadWrite, + ReadWriteCreate, + } + +public: // `null` schema means "open as R/O" // non-null, but empty schema means "open as r/w" - // non-empty scheme means "create is absend" - this (const(char)[] name, const(char)[] schema=null) { open(name, schema); } + // non-empty scheme means "create if absent" + this (const(char)[] name, Mode mode, const(char)[] pragmas, const(char)[] schema=null) { openEx(name, mode, pragmas, schema); } + this (const(char)[] name, const(char)[] schema) { openEx(name, (schema !is null ? Mode.ReadWriteCreate : Mode.ReadOnly), null, schema); } ~this () nothrow @trusted { close(); } this (this) nothrow @trusted @nogc { if (dbi !is null) ++dbi.rc; } @@ -132,12 +140,10 @@ public: if (dbi.db !is null) { clearStatements(); if (dbi.onClose !is null) { - char* errmsg; - auto rc = sqlite3_exec(dbi.db, dbi.onClose, null, null, &errmsg); + auto rc = sqlite3_exec(dbi.db, dbi.onClose, null, null, null); if (rc != SQLITE_OK) { import core.stdc.stdio : stderr, fprintf; - fprintf(stderr, "SQLITE ERROR: %s\n", errmsg); - sqlite3_free(errmsg); + fprintf(stderr, "SQLITE ERROR ON CLOSE: %s\n", sqlite3_errstr(sqlite3_extended_errcode(dbi.db))); } version(none) { import core.stdc.stdio : stderr, fprintf; @@ -184,15 +190,15 @@ public: // `null` schema means "open as R/O" // non-null, but empty schema means "open as r/w" // non-empty scheme means "create is absend" - void open (const(char)[] name, const(char)[] schema=null) { + void openEx (const(char)[] name, Mode mode, const(char)[] pragmas=null, const(char)[] schema=null) { close(); import core.stdc.stdlib : malloc, free; import std.internal.cstring; - bool allowCreate = false, allowWrite = false; - if (schema !is null) { - allowWrite = true; - while (schema.length && schema[0] <= ' ') schema = schema[1..$]; - allowCreate = (schema.length != 0); + immutable bool allowWrite = (mode == Mode.ReadWrite || mode == Mode.ReadWriteCreate); + bool allowCreate = (mode == Mode.ReadWriteCreate); + if (allowCreate) { + while (schema.length && schema[$-1] <= ' ') schema = schema[0..$-1]; + if (schema.length == 0) allowCreate = false; } dbi = cast(DBInfo *)malloc(DBInfo.sizeof); if (!dbi) throw new Error("out of memory"); @@ -205,7 +211,18 @@ public: sq3check(null, rc); } scope(failure) { close(); } - if (allowCreate) execute(schema); + execute(pragmas); + if (allowCreate && schema.length) execute(schema); + } + + // `null` schema means "open as R/O" + void open (const(char)[] name, const(char)[] schema=null) { + Mode mode = Mode.ReadOnly; + if (schema != null) { + while (schema.length && schema[$-1] <= ' ') schema = schema[0..$-1]; + mode = (schema.length ? Mode.ReadWriteCreate : Mode.ReadWrite); + } + return openEx(name, mode, null, schema); } ulong lastRowId () nothrow @trusted { return (isOpen ? sqlite3_last_insert_rowid(dbi.db) : 0); } @@ -252,6 +269,7 @@ public static bool isUTF8ValidSQ3 (const(char)[] str) pure nothrow @trusted @nog immutable(ubyte)* p = cast(immutable(ubyte)*)str.ptr; while (len--) { immutable ubyte b = *p++; + if (b == 0) return false; if (b < 128) continue; ubyte blen = (b&0xe0) == 0xc0 ? 1 : -- 2.11.4.GIT