diff --git a/lib/circles/actionprocessor/factory.v b/lib/circles/actionprocessor/factory.v index 3ddfc69d..d7b76ad7 100644 --- a/lib/circles/actionprocessor/factory.v +++ b/lib/circles/actionprocessor/factory.v @@ -1,10 +1,9 @@ module actionprocessor -import freeflowuniverse.herolib.circles.models.core +import freeflowuniverse.herolib.circles.dbs.core import freeflowuniverse.herolib.circles.models import freeflowuniverse.herolib.core.texttools -import os __global ( circle_global map[string]&CircleCoordinator @@ -17,10 +16,10 @@ __global ( pub struct CircleCoordinator { pub mut: name string //is a unique name on planetary scale is a dns name - agents &core.AgentManager - circles &core.CircleManager - names &core.NameManager - session_state model.SessionState + agents &core.AgentDB + // circles &core.CircleDB + // names &core.NameDB + session_state models.SessionState } @@ -29,7 +28,8 @@ pub struct CircleCoordinatorArgs{ pub mut: name string = "local" pubkey string // pubkey of user who called this - addr string //mycelium address + addr string //mycelium address + path string } // new creates a new CircleCoordinator instance @@ -38,12 +38,11 @@ pub fn new(args_ CircleCoordinatorArgs) !&CircleCoordinator { args.name = texttools.name_fix(args.name) if args.name in circle_global { - mut c:=circle_global[args.name] - c.args = args + mut c:=circle_global[args.name] or {panic("bug")} return c } - mut session_state:=models.new(name: args.name, pubkey: args.pubkey, addr: args.addr, path: args.path)! + mut session_state:=models.new_session(name: args.name, pubkey: args.pubkey, addr: args.addr, path: args.path)! // os.mkdir_all(mypath)! // Create the directories if they don't exist// SHOULD BE AUTOMATIC @@ -53,15 +52,15 @@ pub fn new(args_ CircleCoordinatorArgs) !&CircleCoordinator { // os.mkdir_all(os.join_path(mypath, 'meta_mcc'))! //message, contacts, calendar - // Initialize the managers with proper ourdb instances - mut agent_manager := core.new_agentmanager(session_state)! - mut circle_manager := core.new_circlemanager(session_state)! - mut name_manager := core.new_namemanager(session_state)! + // Initialize the db handlers with proper ourdb instances + mut agent_db := core.new_agentdb(session_state)! + // mut circle_db := core.new_circledb(session_state)! + // mut name_db := core.new_namedb(session_state)! mut cm := &CircleCoordinator{ - agents: &agent_manager - circles: &circle_manager - names: &name_manager + agents: &agent_db + // circles: &circle_db + // names: &name_db session_state: session_state } diff --git a/lib/circles/dbs/core/agent_db.v b/lib/circles/dbs/core/agent_db.v new file mode 100644 index 00000000..5d53d038 --- /dev/null +++ b/lib/circles/dbs/core/agent_db.v @@ -0,0 +1,121 @@ +module core + +import freeflowuniverse.herolib.data.ourtime +import freeflowuniverse.herolib.circles.models { DBHandler, SessionState } +import freeflowuniverse.herolib.circles.models.core { Agent, AgentService, AgentServiceAction, AgentState } + + +@[heap] +pub struct AgentDB { +pub mut: + db DBHandler[Agent] +} + +pub fn new_agentdb(session_state SessionState) !AgentDB { + return AgentDB{ + db:models.new_dbhandler[Agent]('agent', session_state) + } +} + +pub fn (mut m AgentDB) new() Agent { + return Agent{} +} + +// set adds or updates an agent +pub fn (mut m AgentDB) set(agent Agent) !Agent { + return m.db.set(agent)! +} + +// get retrieves an agent by its ID +pub fn (mut m AgentDB) get(id u32) !Agent { + return m.db.get(id)! +} +// list returns all agent IDs +pub fn (mut m AgentDB) list() ![]u32 { + return m.db.list()! +} + +pub fn (mut m AgentDB) getall() ![]Agent { + return m.db.getall()! +} + +// delete removes an agent by its ID +pub fn (mut m AgentDB) delete(id u32) ! { + m.db.delete(id)! +} + +//////////////////CUSTOM METHODS////////////////////////////////// + +// get_by_pubkey retrieves an agent by its public key +pub fn (mut m AgentDB) get_by_pubkey(pubkey string) !Agent { + return m.db.get_by_key('pubkey', pubkey)! +} + +// delete_by_pubkey removes an agent by its public key +pub fn (mut m AgentDB) delete_by_pubkey(pubkey string) ! { + // Get the agent by pubkey + agent := m.get_by_pubkey(pubkey) or { + // Agent not found, nothing to delete + return + } + + // Delete the agent by ID + m.delete(agent.id)! +} + +// update_status updates just the status of an agent +pub fn (mut m AgentDB) update_status(pubkey string, status AgentState) !Agent { + // Get the agent by pubkey + mut agent := m.get_by_pubkey(pubkey)! + + // Update the status + agent.status.status = status + agent.status.timestamp_last = ourtime.now() + + // Save the updated agent + return m.set(agent)! +} + +// get_all_agent_pubkeys returns all agent pubkeys +pub fn (mut m AgentDB) get_all_agent_pubkeys() ![]string { + // Get all agent IDs + agent_ids := m.list()! + + // Get pubkeys for all agents + mut pubkeys := []string{} + for id in agent_ids { + agent := m.get(id) or { continue } + pubkeys << agent.pubkey + } + + return pubkeys +} + +// get_by_service returns all agents that provide a specific service +pub fn (mut m AgentDB) get_by_service(actor string, action string) ![]Agent { + mut matching_agents := []Agent{} + + // Get all agent IDs + agent_ids := m.list()! + + // Filter agents that provide the specified service + for id in agent_ids { + // Get the agent by ID + agent := m.get(id) or { continue } + + // Check if agent provides the specified service + for service in agent.services { + if service.actor == actor { + for service_action in service.actions { + if service_action.action == action { + matching_agents << agent + break + } + } + break + } + } + } + + return matching_agents +} diff --git a/lib/circles/models/toooodo/agent_db_test.v b/lib/circles/dbs/core/agent_db_test.v similarity index 85% rename from lib/circles/models/toooodo/agent_db_test.v rename to lib/circles/dbs/core/agent_db_test.v index 826b2ee4..7ba2bbaf 100755 --- a/lib/circles/models/toooodo/agent_db_test.v +++ b/lib/circles/dbs/core/agent_db_test.v @@ -2,14 +2,15 @@ module core import os import rand - -fn test_agents_model() { +import freeflowuniverse.herolib.circles.actionprocessor +import freeflowuniverse.herolib.circles.models.core +fn test_agent_db() { // Create a temporary directory for testing test_dir := os.join_path(os.temp_dir(), 'hero_agent_test_${rand.intn(9000) or { 0 } + 1000}') os.mkdir_all(test_dir) or { panic(err) } defer { os.rmdir_all(test_dir) or {} } - mut runner := new(path: test_dir)! + mut runner := actionprocessor.new(path: test_dir)! // Create multiple agents for testing mut agent1 := runner.agents.new() @@ -27,30 +28,20 @@ fn test_agents_model() { agent3.address = '127.0.0.3' agent3.description = 'Test Agent 3' - // Create a service action - mut action := AgentServiceAction{ - action: 'start' - description: 'Start a VM' - params: { - 'name': 'string' - } - params_example: { - 'name': 'myvm' - } - status: .ok - public: true + // Create a service using the factory method + mut service := agent1.new_service(actor: 'vm_manager', description: 'VM Management Service') + + // Create a service action using the factory method + mut action := service.new_action(action:'start', description: 'Start a VM') + + // Set additional properties for the action + action.params = { + 'name': 'string' } - - // Create a service - mut service := AgentService{ - actor: 'vm_manager' - actions: [action] - description: 'VM Management Service' - status: .ok + action.params_example = { + 'name': 'myvm' } - agent1.services = [service] - // Add the agents println('Adding agent 1') agent1 = runner.agents.set(agent1)! @@ -72,11 +63,14 @@ fn test_agents_model() { println('Agent IDs in list: ${agent_ids}') // Debug: Print the 'all' key from the radix tree - if all_bytes := runner.agents.manager.db_meta.search('agent:all') { + all_bytes := runner.agents.db.session_state.dbs.db_meta_core.get('agent:id') or { + println('No agent:id key found in radix tree') + []u8{} + } + + if all_bytes.len > 0 { all_str := all_bytes.bytestr() - println('Raw agent:all key content: "${all_str}"') - } else { - println('No agent:all key found in radix tree') + println('Raw agent:id key content: "${all_str}"') } // Get all agents @@ -174,7 +168,7 @@ fn test_agents_model() { agents_after_all_deleted := runner.agents.getall() or { // This is expected to fail with 'No agents found' error assert err.msg() == 'No agents found' - []Agent{} + []core.Agent{cap: 0} } assert agents_after_all_deleted.len == 0, 'Expected 0 agents after all deletions, got ${agents_after_all_deleted.len}' diff --git a/lib/circles/models/core/agent.v b/lib/circles/models/core/agent.v index a8fc7a0d..c26b5918 100644 --- a/lib/circles/models/core/agent.v +++ b/lib/circles/models/core/agent.v @@ -3,19 +3,58 @@ module core import freeflowuniverse.herolib.data.ourtime import freeflowuniverse.herolib.data.encoder -// Agent represents a service provider that can execute jobs +// Agent represents self service provider that can execute jobs pub struct Agent { pub mut: id u32 pubkey string // pubkey using ed25519 address string // where we can find the agent - port int // default 9999 + port u16 // default 9999 description string // optional status AgentStatus services []AgentService // these are the public services signature string // signature as done by private key of $address+$port+$description+$status } +@[params] +pub struct ServiceParams { +pub mut: + actor string + description string +} + +// new_service creates self new AgentService for this agent +pub fn (mut self Agent) new_service(args ServiceParams) &AgentService { + mut service := AgentService{ + actor: args.actor + description: args.description + status: .ok + public: true + } + self.services << service + return &self.services[self.services.len - 1] +} + +@[params] +pub struct ActionParams { +pub mut: + action string + description string +} + + +// new_service_action creates self new AgentServiceAction for the specified service +pub fn (mut service AgentService) new_action(args ActionParams) &AgentServiceAction { + mut service_action := AgentServiceAction{ + action: args.action + description: args.description + status: .ok + public: true + } + service.actions << service_action + return &service.actions[service.actions.len - 1] +} + // AgentStatus represents the current state of an agent pub struct AgentStatus { pub mut: @@ -25,7 +64,7 @@ pub mut: status AgentState // current state of the agent } -// AgentService represents a service provided by an agent +// AgentService represents self service provided by an agent pub struct AgentService { pub mut: actor string // name of the actor providing the service @@ -35,7 +74,7 @@ pub mut: public bool // if everyone can use then true, if restricted means only certain people can use } -// AgentServiceAction represents an action that can be performed by a service +// AgentServiceAction represents an action that can be performed by self service pub struct AgentServiceAction { pub mut: action string // which action @@ -62,34 +101,34 @@ pub enum AgentServiceState { halted // service/action has been manually stopped } -pub fn (c Agent) index_keys() map[string]string { - return {"pubkey": c.pubkey} +pub fn (self Agent) index_keys() map[string]string { + return {"pubkey": self.pubkey} } // dumps serializes the Agent struct to binary format using the encoder -pub fn (a Agent) dumps() ![]u8 { +pub fn (self Agent) dumps() ![]u8 { mut e := encoder.new() // Add unique encoding ID to identify this type of data e.add_u16(100) // Encode Agent fields - e.add_string(a.pubkey) - e.add_string(a.address) - e.add_int(a.port) - e.add_string(a.description) + e.add_string(self.pubkey) + e.add_string(self.address) + e.add_u16(self.port) + e.add_string(self.description) // Encode AgentStatus - e.add_string(a.status.guid) - e.add_ourtime(a.status.timestamp_first) - e.add_ourtime(a.status.timestamp_last) - e.add_u8(u8(a.status.status)) + e.add_string(self.status.guid) + e.add_ourtime(self.status.timestamp_first) + e.add_ourtime(self.status.timestamp_last) + e.add_u8(u8(self.status.status)) // Encode services array - e.add_u16(u16(a.services.len)) - for service in a.services { + e.add_u16(u16(self.services.len)) + for service in self.services { // Encode AgentService fields e.add_string(service.actor) e.add_string(service.description) @@ -114,34 +153,35 @@ pub fn (a Agent) dumps() ![]u8 { } // Encode signature - e.add_string(a.signature) + e.add_string(self.signature) return e.data } // loads deserializes binary data into an Agent struct -pub fn Agent.loads(data []u8) !Agent { +pub fn agent_loads(data []u8) !Agent { mut d := encoder.decoder_new(data) - mut agent := Agent{} // Check encoding ID to verify this is the correct type of data encoding_id := d.get_u16()! if encoding_id != 100 { return error('Wrong file type: expected encoding ID 100, got ${encoding_id}, for agent') } + + mut self:=Agent{} // Decode Agent fields - agent.pubkey = d.get_string()! - agent.address = d.get_string()! - agent.port = d.get_int()! - agent.description = d.get_string()! + self.pubkey = d.get_string()! + self.address = d.get_string()! + self.port = d.get_u16()! + self.description = d.get_string()! // Decode AgentStatus - agent.status.guid = d.get_string()! - agent.status.timestamp_first = d.get_ourtime()! - agent.status.timestamp_last = d.get_ourtime()! + self.status.guid = d.get_string()! + self.status.timestamp_first = d.get_ourtime()! + self.status.timestamp_last = d.get_ourtime()! status_val := d.get_u8()! - agent.status.status = match status_val { + self.status.status = match status_val { 0 { AgentState.ok } 1 { AgentState.down } 2 { AgentState.error } @@ -151,7 +191,7 @@ pub fn Agent.loads(data []u8) !Agent { // Decode services array services_len := d.get_u16()! - agent.services = []AgentService{len: int(services_len)} + self.services = []AgentService{len: int(services_len)} for i in 0 .. services_len { mut service := AgentService{} @@ -196,11 +236,12 @@ pub fn Agent.loads(data []u8) !Agent { service.actions[j] = action } - agent.services[i] = service + self.services[i] = service } // Decode signature - agent.signature = d.get_string()! + self.signature = d.get_string()! + + return self - return agent } diff --git a/lib/circles/models/dbhandler.v b/lib/circles/models/dbhandler.v index 100b453b..23a05556 100644 --- a/lib/circles/models/dbhandler.v +++ b/lib/circles/models/dbhandler.v @@ -1,9 +1,6 @@ module models -import freeflowuniverse.herolib.data.radixtree -import freeflowuniverse.herolib.data.ourdb -import json - +import freeflowuniverse.herolib.circles.models.core { agent_loads, Agent } pub struct DBHandler[T] { pub mut: @@ -25,7 +22,7 @@ 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(id: item.id, data: item.dumps()!)! + item.id = m.session_state.dbs.db_data_core.set(data: item.dumps()!)! // Update index keys for key, value in m.index_keys(item)! { @@ -42,13 +39,23 @@ pub fn (mut m DBHandler[T]) get(id u32) !T { item_data := m.session_state.dbs.db_data_core.get(id) or { return error('Item data not found for ID ${id}') } - mut o:=T.loads(item_data)! + mut o:= T{} + match o { + Agent { + o=agent_loads(item_data)! + }else{ + return panic('Not implemented object') + } + } + + // o.loads(item_data)! o.id = id return o } pub fn (mut m DBHandler[T]) exists(id u32) !bool { - return m.db_data.get(id) or { return false } != []u8{} + item_data := m.session_state.dbs.db_data_core.get(id) or { return false } + return item_data != []u8{} } @@ -99,12 +106,33 @@ fn (mut m DBHandler[T]) index_keys(item T) !map[string]string { return keymap } -// list returns all ids from the manager +// 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 - defaultkey:=m.index_keys(T{})[0] or {panic('no index keys')} - keys := m.session_state.dbs.db_meta_core.getall('${m.prefix}:${defaultkey}')! - return keys + 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 } diff --git a/lib/circles/models/sessionstate.v b/lib/circles/models/sessionstate.v index 44be877a..730a7fce 100644 --- a/lib/circles/models/sessionstate.v +++ b/lib/circles/models/sessionstate.v @@ -11,6 +11,7 @@ pub mut: name string pubkey string // pubkey of user who called this addr string //mycelium address + dbs Databases } pub struct Databases{ @@ -42,22 +43,27 @@ pub fn new_session(args_ StateArgs) !SessionState { mypath:=os.join_path(args.path, args.name) - mut dbs:=Databases{ - db_data_core : ourdb.new( + mut db_data_core := ourdb.new( path: os.join_path(mypath, 'data_core') incremental_mode: true )! - db_meta_core : radixtree.new( + mut db_meta_core := radixtree.new( path: os.join_path(mypath, 'meta_core') )! - db_data_mcc : ourdb.new( + mut db_data_mcc := ourdb.new( path: os.join_path(mypath, 'data_mcc') incremental_mode: false )! - db_meta_mcc : radixtree.new( + mut db_meta_mcc := radixtree.new( path: os.join_path(mypath, 'meta_mcc') )! - } + + mut dbs := Databases{ + db_data_core: &db_data_core + db_meta_core: &db_meta_core + db_data_mcc: &db_data_mcc + db_meta_mcc: &db_meta_mcc + } mut s := SessionState{ name: args.name diff --git a/lib/circles/models/core/agent_db.v b/lib/circles/models/toooodo/agent_db.v similarity index 69% rename from lib/circles/models/core/agent_db.v rename to lib/circles/models/toooodo/agent_db.v index c8c77fd8..ee8fd52b 100644 --- a/lib/circles/models/core/agent_db.v +++ b/lib/circles/models/toooodo/agent_db.v @@ -1,59 +1,58 @@ module core import freeflowuniverse.herolib.data.ourtime -import freeflowuniverse.herolib.data.ourdb -import freeflowuniverse.herolib.data.radixtree -import freeflowuniverse.herolib.circles.models +import freeflowuniverse.herolib.circles.models { DBHandler, SessionState } +import freeflowuniverse.herolib.circles.models.core { Agent, AgentService, AgentServiceAction, AgentState } @[heap] -pub struct AgentManager { +pub struct AgentDB { pub mut: db models.DBHandler[Agent] } -pub fn new_agentdb(session_state SessionState) AgentManager { - return AgentManager{ +pub fn new_agentdb(session_state SessionState) !AgentDB { + return AgentDB{ db:models.new_dbhandler[Agent]('agent', session_state) } } -pub fn (mut m AgentManager) new() Agent { +pub fn (mut m AgentDB) new() Agent { return Agent{} } // set adds or updates an agent -pub fn (mut m AgentManager) set(agent Agent) !Agent { +pub fn (mut m AgentDB) set(agent Agent) !Agent { return m.db.set(agent)! } // get retrieves an agent by its ID -pub fn (mut m AgentManager) get(id u32) !Agent { +pub fn (mut m AgentDB) get(id u32) !Agent { return m.db.get(id)! } // list returns all agent IDs -pub fn (mut m AgentManager) list() ![]u32 { +pub fn (mut m AgentDB) list() ![]u32 { return m.db.list()! } -pub fn (mut m AgentManager) getall() ![]Agent { +pub fn (mut m AgentDB) getall() ![]Agent { return m.db.getall()! } // delete removes an agent by its ID -pub fn (mut m AgentManager) delete(id u32) ! { +pub fn (mut m AgentDB) delete(id u32) ! { m.db.delete(id)! } //////////////////CUSTOM METHODS////////////////////////////////// // get_by_pubkey retrieves an agent by its public key -pub fn (mut m AgentManager) get_by_pubkey(pubkey string) !Agent { +pub fn (mut m AgentDB) get_by_pubkey(pubkey string) !Agent { return m.db.get_by_key('pubkey', pubkey)! } // delete_by_pubkey removes an agent by its public key -pub fn (mut m AgentManager) delete_by_pubkey(pubkey string) ! { +pub fn (mut m AgentDB) delete_by_pubkey(pubkey string) ! { // Get the agent by pubkey agent := m.get_by_pubkey(pubkey) or { // Agent not found, nothing to delete @@ -65,7 +64,7 @@ pub fn (mut m AgentManager) delete_by_pubkey(pubkey string) ! { } // update_status updates just the status of an agent -pub fn (mut m AgentManager) update_status(pubkey string, status AgentState) !Agent { +pub fn (mut m AgentDB) update_status(pubkey string, status AgentState) !Agent { // Get the agent by pubkey mut agent := m.get_by_pubkey(pubkey)! @@ -78,7 +77,7 @@ pub fn (mut m AgentManager) update_status(pubkey string, status AgentState) !Age } // get_all_agent_pubkeys returns all agent pubkeys -fn (mut m AgentManager) get_all_agent_pubkeys() ![]string { +pub fn (mut m AgentDB) get_all_agent_pubkeys() ![]string { // Get all agent IDs agent_ids := m.list()! @@ -93,7 +92,7 @@ fn (mut m AgentManager) get_all_agent_pubkeys() ![]string { } // get_by_service returns all agents that provide a specific service -pub fn (mut m AgentManager) get_by_service(actor string, action string) ![]Agent { +pub fn (mut m AgentDB) get_by_service(actor string, action string) ![]Agent { mut matching_agents := []Agent{} // Get all agent IDs diff --git a/lib/circles/models/core/agent_test.v b/lib/circles/models/toooodo/agent_test.v similarity index 97% rename from lib/circles/models/core/agent_test.v rename to lib/circles/models/toooodo/agent_test.v index 3cc80197..5f8a97a7 100644 --- a/lib/circles/models/core/agent_test.v +++ b/lib/circles/models/toooodo/agent_test.v @@ -70,7 +70,8 @@ fn test_agent_dumps_loads() { } // Test binary decoding - decoded_agent := agent_loads(binary_data) or { + mut decoded_agent := Agent{} + decoded_agent.loads(binary_data) or { assert false, 'Failed to decode agent: ${err}' return } @@ -232,7 +233,8 @@ fn test_agent_complex_structure() { } // Test binary decoding - decoded_agent := agent_loads(binary_data) or { + mut decoded_agent := Agent{} + decoded_agent.loads(binary_data) or { assert false, 'Failed to decode complex agent: ${err}' return } @@ -303,7 +305,8 @@ fn test_agent_empty_structures() { } // Test binary decoding - decoded_agent := agent_loads(binary_data) or { + mut decoded_agent := Agent{} + decoded_agent.loads(binary_data) or { assert false, 'Failed to decode empty agent: ${err}' return } diff --git a/lib/circles/models/toooodo/circle_manager.v b/lib/circles/models/toooodo/circle_db.v similarity index 80% rename from lib/circles/models/toooodo/circle_manager.v rename to lib/circles/models/toooodo/circle_db.v index 97678b61..d8995072 100644 --- a/lib/circles/models/toooodo/circle_manager.v +++ b/lib/circles/models/toooodo/circle_db.v @@ -3,56 +3,57 @@ module core import freeflowuniverse.herolib.data.ourdb import freeflowuniverse.herolib.data.radixtree import freeflowuniverse.herolib.core.playbook +import freeflowuniverse.herolib.circles.models @[heap] -pub struct CircleManager { +pub struct CircleDB { pub mut: - manager DBSession[Circle] + db models.DBHandler[Circle] } -pub fn new_circlemanager(db_data &ourdb.OurDB, db_meta &radixtree.RadixTree) CircleManager { - return CircleManager{ - manager: session.new_dbsession[Circle](db_data, db_meta, 'circle') +pub fn new_circledb(session_state models.SessionState) !CircleDB { + return CircleDB{ + db: models.new_dbhandler[Circle]('circle', session_state) } } -pub fn (mut m CircleManager) new() Circle { +pub fn (mut m CircleDB) new() Circle { return Circle{} } // set adds or updates a circle -pub fn (mut m CircleManager) set(circle Circle) !Circle { - return m.manager.set(circle)! +pub fn (mut m CircleDB) set(circle Circle) !Circle { + return m.db.set(circle)! } // get retrieves a circle by its ID -pub fn (mut m CircleManager) get(id u32) !Circle { - return m.manager.get(id)! +pub fn (mut m CircleDB) get(id u32) !Circle { + return m.db.get(id)! } // list returns all circle IDs -pub fn (mut m CircleManager) list() ![]u32 { - return m.manager.list()! +pub fn (mut m CircleDB) list() ![]u32 { + return m.db.list()! } -pub fn (mut m CircleManager) getall() ![]Circle { - return m.manager.getall()! +pub fn (mut m CircleDB) getall() ![]Circle { + return m.db.getall()! } // delete removes a circle by its ID -pub fn (mut m CircleManager) delete(id u32) ! { - m.manager.delete(id)! +pub fn (mut m CircleDB) delete(id u32) ! { + m.db.delete(id)! } //////////////////CUSTOM METHODS////////////////////////////////// // get_by_name retrieves a circle by its name -pub fn (mut m CircleManager) get_by_name(name string) !Circle { - return m.manager.get_by_key('name', name)! +pub fn (mut m CircleDB) get_by_name(name string) !Circle { + return m.db.get_by_key('name', name)! } // delete_by_name removes a circle by its name -pub fn (mut m CircleManager) delete_by_name(name string) ! { +pub fn (mut m CircleDB) delete_by_name(name string) ! { // Get the circle by name circle := m.get_by_name(name) or { // Circle not found, nothing to delete @@ -64,7 +65,7 @@ pub fn (mut m CircleManager) delete_by_name(name string) ! { } // add_member adds a member to a circle -pub fn (mut m CircleManager) add_member(circle_id u32, member Member) !Circle { +pub fn (mut m CircleDB) add_member(circle_id u32, member Member) !Circle { // Get the circle by ID mut circle := m.get(circle_id)! @@ -91,7 +92,7 @@ pub fn (mut m CircleManager) add_member(circle_id u32, member Member) !Circle { } // remove_member removes a member from a circle by pubkey -pub fn (mut m CircleManager) remove_member(circle_id u32, pubkey string) !Circle { +pub fn (mut m CircleDB) remove_member(circle_id u32, pubkey string) !Circle { // Get the circle by ID mut circle := m.get(circle_id)! @@ -127,7 +128,7 @@ pub fn (mut m CircleManager) remove_member(circle_id u32, pubkey string) !Circle } // update_member_role updates the role of a member in a circle -pub fn (mut m CircleManager) update_member_role(circle_id u32, pubkey string, role Role) !Circle { +pub fn (mut m CircleDB) update_member_role(circle_id u32, pubkey string, role Role) !Circle { // Get the circle by ID mut circle := m.get(circle_id)! @@ -156,7 +157,7 @@ pub fn (mut m CircleManager) update_member_role(circle_id u32, pubkey string, ro } // get_members returns all members of a circle -pub fn (mut m CircleManager) get_members(circle_id u32) ![]Member { +pub fn (mut m CircleDB) get_members(circle_id u32) ![]Member { // Get the circle by ID circle := m.get(circle_id)! @@ -164,7 +165,7 @@ pub fn (mut m CircleManager) get_members(circle_id u32) ![]Member { } // get_members_by_role returns all members of a circle with a specific role -pub fn (mut m CircleManager) get_members_by_role(circle_id u32, role Role) ![]Member { +pub fn (mut m CircleDB) get_members_by_role(circle_id u32, role Role) ![]Member { // Get the circle by ID circle := m.get(circle_id)! @@ -181,7 +182,7 @@ pub fn (mut m CircleManager) get_members_by_role(circle_id u32, role Role) ![]Me } // play processes heroscript commands for circles -pub fn play_circle(mut cm CircleManager, mut plbook playbook.PlayBook) ! { +pub fn play_circle(mut cm CircleDB, mut plbook playbook.PlayBook) ! { // Find all actions that start with 'circle.' circle_actions := plbook.actions_find(actor: 'circle')! if circle_actions.len == 0 { diff --git a/lib/circles/models/toooodo/circle_manager_test.v b/lib/circles/models/toooodo/circle_db_test.v similarity index 99% rename from lib/circles/models/toooodo/circle_manager_test.v rename to lib/circles/models/toooodo/circle_db_test.v index 9d585a46..fa0ae20f 100644 --- a/lib/circles/models/toooodo/circle_manager_test.v +++ b/lib/circles/models/toooodo/circle_db_test.v @@ -3,7 +3,7 @@ module core import os import rand -fn test_circle_manager() { +fn test_circle_db() { // Create a temporary directory for testing test_dir := os.join_path(os.temp_dir(), 'hero_circle_test_${rand.intn(9000) or { 0 } + 1000}') os.mkdir_all(test_dir) or { panic(err) } diff --git a/lib/circles/models/toooodo/name_manager.v b/lib/circles/models/toooodo/name_db.v similarity index 83% rename from lib/circles/models/toooodo/name_manager.v rename to lib/circles/models/toooodo/name_db.v index a72c8779..b7734510 100644 --- a/lib/circles/models/toooodo/name_manager.v +++ b/lib/circles/models/toooodo/name_db.v @@ -3,56 +3,57 @@ module core import freeflowuniverse.herolib.data.ourdb import freeflowuniverse.herolib.data.radixtree import freeflowuniverse.herolib.core.playbook +import freeflowuniverse.herolib.circles.models @[heap] -pub struct NameManager { +pub struct NameDB { pub mut: - manager DBSession[Name] + db models.DBHandler[Name] } -pub fn new_namemanager(db_data &ourdb.OurDB, db_meta &radixtree.RadixTree) NameManager { - return NameManager{ - manager: session.new_dbsession[Name](db_data, db_meta, 'name') +pub fn new_namedb(session_state models.SessionState) !NameDB { + return NameDB{ + db: models.new_dbhandler[Name]('name', session_state) } } -pub fn (mut m NameManager) new() Name { +pub fn (mut m NameDB) new() Name { return Name{} } // set adds or updates a name -pub fn (mut m NameManager) set(name Name) !Name { - return m.manager.set(name)! +pub fn (mut m NameDB) set(name Name) !Name { + return m.db.set(name)! } // get retrieves a name by its ID -pub fn (mut m NameManager) get(id u32) !Name { - return m.manager.get(id)! +pub fn (mut m NameDB) get(id u32) !Name { + return m.db.get(id)! } // list returns all name IDs -pub fn (mut m NameManager) list() ![]u32 { - return m.manager.list()! +pub fn (mut m NameDB) list() ![]u32 { + return m.db.list()! } -pub fn (mut m NameManager) getall() ![]Name { - return m.manager.getall()! +pub fn (mut m NameDB) getall() ![]Name { + return m.db.getall()! } // delete removes a name by its ID -pub fn (mut m NameManager) delete(id u32) ! { - m.manager.delete(id)! +pub fn (mut m NameDB) delete(id u32) ! { + m.db.delete(id)! } //////////////////CUSTOM METHODS////////////////////////////////// // get_by_domain retrieves a name by its domain -pub fn (mut m NameManager) get_by_domain(domain string) !Name { - return m.manager.get_by_key('domain', domain)! +pub fn (mut m NameDB) get_by_domain(domain string) !Name { + return m.db.get_by_key('domain', domain)! } // delete_by_domain removes a name by its domain -pub fn (mut m NameManager) delete_by_domain(domain string) ! { +pub fn (mut m NameDB) delete_by_domain(domain string) ! { // Get the name by domain name := m.get_by_domain(domain) or { // Name not found, nothing to delete @@ -64,7 +65,7 @@ pub fn (mut m NameManager) delete_by_domain(domain string) ! { } // add_record adds a record to a name -pub fn (mut m NameManager) add_record(name_id u32, record Record) !Name { +pub fn (mut m NameDB) add_record(name_id u32, record Record) !Name { // Get the name by ID mut name := m.get(name_id)! @@ -83,7 +84,7 @@ pub fn (mut m NameManager) add_record(name_id u32, record Record) !Name { } // remove_record removes a record from a name by name and category -pub fn (mut m NameManager) remove_record(name_id u32, record_name string, category RecordType) !Name { +pub fn (mut m NameDB) remove_record(name_id u32, record_name string, category RecordType) !Name { // Get the name by ID mut name := m.get(name_id)! @@ -111,7 +112,7 @@ pub fn (mut m NameManager) remove_record(name_id u32, record_name string, catego } // update_record updates a record in a name -pub fn (mut m NameManager) update_record(name_id u32, record_name string, category RecordType, new_record Record) !Name { +pub fn (mut m NameDB) update_record(name_id u32, record_name string, category RecordType, new_record Record) !Name { // Get the name by ID mut name := m.get(name_id)! @@ -145,7 +146,7 @@ pub fn (mut m NameManager) update_record(name_id u32, record_name string, catego } // get_records returns all records of a name -pub fn (mut m NameManager) get_records(name_id u32) ![]Record { +pub fn (mut m NameDB) get_records(name_id u32) ![]Record { // Get the name by ID name := m.get(name_id)! @@ -153,7 +154,7 @@ pub fn (mut m NameManager) get_records(name_id u32) ![]Record { } // get_records_by_category returns all records of a name with a specific category -pub fn (mut m NameManager) get_records_by_category(name_id u32, category RecordType) ![]Record { +pub fn (mut m NameDB) get_records_by_category(name_id u32, category RecordType) ![]Record { // Get the name by ID name := m.get(name_id)! @@ -170,7 +171,7 @@ pub fn (mut m NameManager) get_records_by_category(name_id u32, category RecordT } // add_admin adds an admin to a name -pub fn (mut m NameManager) add_admin(name_id u32, pubkey string) !Name { +pub fn (mut m NameDB) add_admin(name_id u32, pubkey string) !Name { // Get the name by ID mut name := m.get(name_id)! @@ -189,7 +190,7 @@ pub fn (mut m NameManager) add_admin(name_id u32, pubkey string) !Name { } // remove_admin removes an admin from a name -pub fn (mut m NameManager) remove_admin(name_id u32, pubkey string) !Name { +pub fn (mut m NameDB) remove_admin(name_id u32, pubkey string) !Name { // Get the name by ID mut name := m.get(name_id)! @@ -222,7 +223,7 @@ pub fn (mut m NameManager) remove_admin(name_id u32, pubkey string) !Name { } // play processes heroscript commands for names -pub fn (mut m NameManager) play(mut plbook playbook.PlayBook) ! { +pub fn (mut m NameDB) play(mut plbook playbook.PlayBook) ! { // Find all actions that start with 'name.' name_actions := plbook.actions_find(actor: 'name')! if name_actions.len == 0 { diff --git a/lib/circles/models/toooodo/name_manager_test.v b/lib/circles/models/toooodo/name_db_test.v similarity index 99% rename from lib/circles/models/toooodo/name_manager_test.v rename to lib/circles/models/toooodo/name_db_test.v index 71726b56..1517662c 100644 --- a/lib/circles/models/toooodo/name_manager_test.v +++ b/lib/circles/models/toooodo/name_db_test.v @@ -3,7 +3,7 @@ module core import os import rand -fn test_name_manager() { +fn test_name_db() { // Create a temporary directory for testing test_dir := os.join_path(os.temp_dir(), 'hero_name_test_${rand.intn(9000) or { 0 } + 1000}') os.mkdir_all(test_dir) or { panic(err) } diff --git a/lib/data/encoder/encoder_decode.v b/lib/data/encoder/encoder_decode.v index b2ff1c81..675f0a5e 100644 --- a/lib/data/encoder/encoder_decode.v +++ b/lib/data/encoder/encoder_decode.v @@ -122,15 +122,14 @@ pub fn (mut d Decoder) get_i64() !i64 { } pub fn (mut d Decoder) get_time() !time.Time { - nano_time := d.get_i64()! - seconds := nano_time / int(1e9) - nano_seconds := int(nano_time % int(1e9)) - return time.unix_nanosecond(seconds, nano_seconds) + secs_:=d.get_u32()! + secs := i64(secs_) + return time.unix(secs) } pub fn (mut d Decoder) get_ourtime() !ourtime.OurTime { return ourtime.OurTime{ - unixt: d.get_i64()! + unixt: d.get_u32()! } } diff --git a/lib/data/encoder/encoder_encode.v b/lib/data/encoder/encoder_encode.v index b38e4882..439c9f2d 100644 --- a/lib/data/encoder/encoder_encode.v +++ b/lib/data/encoder/encoder_encode.v @@ -86,11 +86,11 @@ pub fn (mut b Encoder) add_i64(data i64) { } pub fn (mut b Encoder) add_time(data time.Time) { - b.add_u64(u64(data.unix_nano())) // add as epoch time + b.add_u32(u32(data.unix())) // add as epoch time } pub fn (mut b Encoder) add_ourtime(data ourtime.OurTime) { - b.add_i64(data.unixt) + b.add_u32(u32(data.unixt)) } pub fn (mut b Encoder) add_list_string(data []string) { diff --git a/lib/data/radixtree/radixtree.v b/lib/data/radixtree/radixtree.v index 54e53020..3c3a6a46 100644 --- a/lib/data/radixtree/radixtree.v +++ b/lib/data/radixtree/radixtree.v @@ -1,7 +1,7 @@ module radixtree import freeflowuniverse.herolib.data.ourdb -import freeflowuniverse.herolib.ui.console +// import freeflowuniverse.herolib.ui.console // Represents a node in the radix tree struct Node { @@ -34,7 +34,7 @@ pub mut: } // Creates a new radix tree with the specified database path -pub fn new(args NewArgs) !&RadixTree { +pub fn new(args NewArgs) !RadixTree { mut db := ourdb.new( path: args.path record_size_max: 1024 * 4 // 4KB max record size @@ -58,11 +58,12 @@ pub fn new(args NewArgs) !&RadixTree { } else { //console.print_debug('Debug: Using existing root node') root_data := db.get(1)! // Get root node with ID 1 - root_node := deserialize_node(root_data)! + // root_node := + deserialize_node(root_data)! //console.print_debug('Debug: Root node has ${root_node.children.len} children') } - return &RadixTree{ + return RadixTree{ db: &db root_id: root_id } @@ -128,7 +129,7 @@ pub fn (mut rt RadixTree) set(key string, value []u8) ! { // First verify we can deserialize the data correctly //console.print_debug('Debug: Verifying serialization...') - if test_node := deserialize_node(parent_data) { + if _ := deserialize_node(parent_data) { //console.print_debug('Debug: Serialization test successful - node has ${test_node.children.len} children') } else { //console.print_debug('Debug: ERROR - Failed to deserialize test data')