git » sdk » omemo » tree

[omemo] / snikket / persistence / SqliteDriver.hx

package snikket.persistence;

import haxe.io.Bytes;
import thenshim.Promise;
import sys.db.Connection;

// TODO: consider doing background threads for operations
class SqliteDriver {
	final db: Connection;

	public function new(dbfile: String) {
		db = sys.db.Sqlite.open(dbfile);
	}

	public function exec(sql: haxe.extern.EitherType<String, Array<String>>, ?params: Array<Dynamic>) {
		var result = null;
		final qs = if (Std.isOfType(sql, String)) {
			[sql];
		} else {
			cast (sql, Array<Dynamic>);
		}
		try {
			for (q in qs) {
				if (result == null) {
					final prepared = prepare(q, params ?? []);
					result = db.request(prepared);
				} else {
					db.request(q);
				}
			}
			return Promise.resolve(result);
		} catch (e) {
			return Promise.reject(e);
		}
	}

	private function prepare(sql:String, params: Array<Dynamic>): String {
		return ~/\?/gm.map(sql, f -> {
			var p = params.shift();
			return switch (Type.typeof(p)) {
				case TClass(String):
					db.quote(p);
				case TBool:
					p == true ? "1" : "0";
				case TFloat:
					Std.string(p);
				case TInt:
					Std.string(p);
				case TNull:
					"NULL";
				case TClass(Array):
					var bytes:Bytes = Bytes.ofData(p);
					"X'" + bytes.toHex() + "'";
				case TClass(haxe.io.Bytes):
					var bytes:Bytes = cast p;
					"X'" + bytes.toHex() + "'";
				case _:
					throw("UKNONWN: " + Type.typeof(p));
			}
		});
	}
}