changeset 1094:ea708c16e012

do: intermediate save before doing shit from scratch
author sam <sam@basx.dev>
date Sat, 06 Apr 2024 22:48:30 +0700
parents 7283373b3a22
children b6427706c7b1
files semicongine/storage.nim
diffstat 1 files changed, 25 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/semicongine/storage.nim	Sat Apr 06 21:26:31 2024 +0700
+++ b/semicongine/storage.nim	Sat Apr 06 22:48:30 2024 +0700
@@ -8,8 +8,6 @@
 import ./core
 
 const STORAGE_NAME = Path("storage.db")
-const KEY_VALUE_TABLE_NAME = "shelf"
-const KILL_SIGNAL_KEY = "__semicongine__kill_worker"
 
 type
   StorageType* = enum
@@ -22,9 +20,9 @@
     KillWorker
   Storage*[T] = object
     storageType: StorageType
-    keyChannel: Channel[(StorageOperation, string)] # false is read, true is write
-    dataChannel: Channel[T]
-    thread: Thread[(ptr Channel[string], ptr Channel[T])]
+    keyChannel: ptr Channel[(StorageOperation, string)] # false is read, true is write
+    dataChannel: ptr Channel[T]
+    thread: Thread[tuple[storageType: StorageType, keyChannel: ptr Channel[(StorageOperation, string)], dataChannel: ptr Channel[T]]]
 
 proc path(storageType: StorageType): Path =
   case storageType:
@@ -34,19 +32,22 @@
       Path(getDataDir()) / Path(AppName()) / STORAGE_NAME
 
 proc openDb(storageType: StorageType): DbConn =
+  const KEY_VALUE_TABLE_NAME = "shelf"
   result = open(string(storageType.path), "", "", "")
   result.exec(sql(&"""CREATE TABLE IF NOT EXISTS {KEY_VALUE_TABLE_NAME} (
     key TEXT NOT NULL UNIQUE,
-    value TEXT NOT NULL,
+    value TEXT NOT NULL
   )"""))
 
 proc store[T](db: DbConn, key: string, value: T) =
-  db.exec(sql(f"""INSERT INTO {KEY_VALUE_TABLE_NAME} VALUES(?, ?)
+  const KEY_VALUE_TABLE_NAME = "shelf"
+  db.exec(sql(&"""INSERT INTO {KEY_VALUE_TABLE_NAME} VALUES(?, ?)
   ON CONFLICT(key) DO UPDATE SET value=excluded.value
   """), key, $$value)
 
 proc load[T](db: DbConn, key: string, default = default(T)): T =
-  let dbResult = db.getValue(sql(f"""SELECT value FROM {KEY_VALUE_TABLE_NAME} WHERE key = ? """), key)
+  const KEY_VALUE_TABLE_NAME = "shelf"
+  let dbResult = db.getValue(sql(&"""SELECT value FROM {KEY_VALUE_TABLE_NAME} WHERE key = ? """), key)
   if dbResult == "":
     return default
   return to[T](dbResult)
@@ -54,35 +55,40 @@
 proc storageWorker[T](params: tuple[storageType: StorageType, keyChannel: ptr Channel[(StorageOperation, string)], dataChannel: ptr Channel[T]]) =
   var db = params.storageType.openDb()
   defer: db.close()
-  var key: (string, bool)
-  while key[0] != KILL_SIGNAL_KEY:
+  var key: (StorageOperation, string)
+  while true:
     key = params.keyChannel[].recv()
-    case key:
-      of Read: params.dataChannel[].send(db.load(key))
-      of Write: db.store(key, params.dataChannel[].recv())
+    case key[0]:
+      of Read: params.dataChannel[].send(load[T](db, key[1]))
+      of Write: store(db, key[1], params.dataChannel[].recv())
       of KillWorker: break
 
 proc openStorage*[T](storageType: StorageType): Storage[T] =
-  result.keyChannel = cast[ptr Channel[(string, bool)]](allocShared0(sizeof(Channel[(string, bool)])))
+  result.keyChannel = cast[ptr Channel[(StorageOperation, string)]](allocShared0(sizeof(Channel[(StorageOperation, string)])))
   result.keyChannel[].open()
   result.dataChannel = cast[ptr Channel[T]](allocShared0(sizeof(Channel[T])))
   result.dataChannel[].open()
-  createThread(result.thread, storageWorker, (storageType, result.keyChannel, result.dataChannel))
+  createThread(result.thread, storageWorker[T], (storageType, result.keyChannel, result.dataChannel))
 
-proc get[T](storage: Storage[T], key: string): Channel[T] =
+proc get*[T](storage: Storage[T], key: string): Channel[T] =
   storage.keyChannel.send((Read, key))
   return storage.dataChannel[]
 
-proc set[T](storage: Storage[T], key: string, value: T) =
+proc set*[T](storage: Storage[T], key: string, value: T) =
   storage.keyChannel.send((Write, key))
   storage.dataChannel.send(value)
 
+proc purge*[T](storage: var Storage[T]) =
+  storage.closeStorage()
+  storage.path().string.removeFile()
+
+
 proc closeStorage*[T](storage: var Storage[T]) =
   storage.keyChannel[].send((KillWorker, ""))
   storage.thread.joinThread()
 
   storage.keyChannel[].close()
-  storage.deallocShared(storage.keyChannel)
+  deallocShared(storage.keyChannel)
 
   storage.dataChannel[].close()
-  storage.deallocShared(storage.dataChannel)
+  deallocShared(storage.dataChannel)