197 lines
4.9 KiB
V
197 lines
4.9 KiB
V
module models
|
|
|
|
import freeflowuniverse.herolib.circles.core.models { agent_loads, Agent, circle_loads, Circle, name_loads, Name }
|
|
import freeflowuniverse.herolib.circles.mcc.models { Email, email_loads, CalendarEvent, calendar_event_loads }
|
|
import freeflowuniverse.herolib.circles.actions.models { Job, job_loads }
|
|
|
|
pub struct DBHandler[T] {
|
|
pub mut:
|
|
prefix string
|
|
session_state SessionState
|
|
|
|
}
|
|
// new_dbhandler creates a new DBHandler for type T
|
|
pub fn new_dbhandler[T](prefix string, session_state SessionState) DBHandler[T] {
|
|
|
|
return DBHandler[T]{
|
|
prefix: prefix
|
|
session_state: session_state
|
|
}
|
|
}
|
|
// set adds or updates an item
|
|
pub fn (mut m DBHandler[T]) set(item_ T) !T {
|
|
|
|
mut item := item_
|
|
|
|
// Store the item data in the database and get the assigned ID
|
|
item.id = m.session_state.dbs.db_data_core.set(data: item.dumps()!)!
|
|
|
|
// Update index keys
|
|
for key, value in m.index_keys(item)! {
|
|
index_key := '${m.prefix}:${key}:${value}'
|
|
m.session_state.dbs.db_meta_core.set(index_key, item.id.str().bytes())!
|
|
}
|
|
|
|
return item
|
|
}
|
|
|
|
// get retrieves an item by its ID
|
|
pub fn (mut m DBHandler[T]) get(id u32) !T {
|
|
// Get the item data from the database
|
|
item_data := m.session_state.dbs.db_data_core.get(id) or {
|
|
return error('Item data not found for ID ${id}')
|
|
}
|
|
|
|
//THIS IS SUPER ANNOYING AND NOT NICE
|
|
$if T is Agent {
|
|
mut o:= agent_loads(item_data)!
|
|
o.id = id
|
|
return o
|
|
} $else $if T is Circle {
|
|
mut o:= circle_loads(item_data)!
|
|
o.id = id
|
|
return o
|
|
} $else $if T is Name {
|
|
mut o:= name_loads(item_data)!
|
|
o.id = id
|
|
return o
|
|
} $else $if T is Email {
|
|
mut o:= email_loads(item_data)!
|
|
o.id = id
|
|
return o
|
|
} $else $if T is CalendarEvent {
|
|
mut o:= calendar_event_loads(item_data)!
|
|
o.id = id
|
|
return o
|
|
} $else $if T is Job {
|
|
mut o:= job_loads(item_data)!
|
|
o.id = id
|
|
return o
|
|
} $else {
|
|
return error('Unsupported type for deserialization')
|
|
}
|
|
panic("bug")
|
|
}
|
|
|
|
pub fn (mut m DBHandler[T]) exists(id u32) !bool {
|
|
item_data := m.session_state.dbs.db_data_core.get(id) or { return false }
|
|
return item_data != []u8{}
|
|
}
|
|
|
|
|
|
// get_by_key retrieves an item by a specific key field and value
|
|
pub fn (mut m DBHandler[T]) get_by_key(key_field string, key_value string) !T {
|
|
// Create the key for the radix tree
|
|
key := '${m.prefix}:${key_field}:${key_value}'
|
|
|
|
// Get the ID from the radix tree
|
|
id_bytes := m.session_state.dbs.db_meta_core.get(key) or {
|
|
return error('Item with ${key_field}=${key_value} not found')
|
|
}
|
|
|
|
// Convert the ID bytes to u32
|
|
id_str := id_bytes.bytestr()
|
|
id := id_str.u32()
|
|
|
|
// Get the item using the ID
|
|
return m.get(id)
|
|
}
|
|
|
|
// delete removes an item by its ID
|
|
pub fn (mut m DBHandler[T]) delete(id u32) ! {
|
|
|
|
exists := m.exists(id)!
|
|
if !exists {
|
|
return
|
|
}
|
|
|
|
// Get the item before deleting it to remove index keys
|
|
item := m.get(id)!
|
|
|
|
for key, value in m.index_keys(item)! {
|
|
index_key := '${m.prefix}:${key}:${value}'
|
|
m.session_state.dbs.db_meta_core.delete(index_key)!
|
|
}
|
|
|
|
// Delete the item data from the database
|
|
m.session_state.dbs.db_data_core.delete(id)!
|
|
}
|
|
|
|
//internal function to always have at least one index key, the default is id
|
|
fn (mut m DBHandler[T]) index_keys(item T) !map[string]string {
|
|
mut keymap := item.index_keys()
|
|
if keymap.len==0{
|
|
keymap["id"]=item.id.str()
|
|
}
|
|
return keymap
|
|
}
|
|
|
|
// list returns all ids from the db handler
|
|
pub fn (mut m DBHandler[T]) list() ![]u32 {
|
|
// Use the RadixTree's prefix capabilities to list all items
|
|
mut empty_item := T{}
|
|
mut keys_map := m.index_keys(empty_item)!
|
|
if keys_map.len == 0 {
|
|
return error('No index keys defined for this type')
|
|
}
|
|
|
|
// Get the first key from the map
|
|
mut default_key := ''
|
|
for k, _ in keys_map {
|
|
default_key = k
|
|
break
|
|
}
|
|
|
|
// Get all IDs from the meta database
|
|
id_bytes := m.session_state.dbs.db_meta_core.getall('${m.prefix}:${default_key}')!
|
|
|
|
// Convert bytes to u32 IDs
|
|
mut result := []u32{}
|
|
for id_byte in id_bytes {
|
|
id_str := id_byte.bytestr()
|
|
result << id_str.u32()
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
|
|
pub fn (mut m DBHandler[T]) getall() ![]T {
|
|
mut items := []T{}
|
|
for id in m.list()! {
|
|
items << m.get(id)!
|
|
}
|
|
return items
|
|
}
|
|
|
|
// list_by_prefix returns all items that match a specific prefix pattern
|
|
pub fn (mut m DBHandler[T]) list_by_prefix(key_field string, prefix_value string) ![]u32 {
|
|
// Create the prefix for the radix tree
|
|
prefix := '${m.prefix}:${key_field}:${prefix_value}'
|
|
|
|
// Use RadixTree's list method to get all keys with this prefix
|
|
keys := m. session_state.dbs.db_meta_core.list(prefix)!
|
|
|
|
// Extract IDs from the values stored in these keys
|
|
mut ids := []u32{}
|
|
for key in keys {
|
|
if id_bytes := m.session_state.dbs.db_meta_core.get(key) {
|
|
id_str := id_bytes.bytestr()
|
|
if id_str.len > 0 {
|
|
ids << id_str.u32()
|
|
}
|
|
}
|
|
}
|
|
|
|
return ids
|
|
}
|
|
|
|
// getall_by_prefix returns all items that match a specific prefix pattern
|
|
pub fn (mut m DBHandler[T]) getall_by_prefix(key_field string, prefix_value string) ![]T {
|
|
mut items := []T{}
|
|
for id in m.list_by_prefix(key_field, prefix_value)! {
|
|
items << m.get(id)!
|
|
}
|
|
return items
|
|
}
|