This commit is contained in:
2025-03-11 08:27:46 +01:00
parent 4358ba6471
commit ac583741a4
15 changed files with 374 additions and 181 deletions

View File

@@ -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
}
@@ -30,6 +29,7 @@ pub mut:
name string = "local"
pubkey string // pubkey of user who called this
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
}

View File

@@ -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
}

View File

@@ -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,29 +28,19 @@ 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: {
// 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'
}
params_example: {
action.params_example = {
'name': 'myvm'
}
status: .ok
public: true
}
// Create a service
mut service := AgentService{
actor: 'vm_manager'
actions: [action]
description: 'VM Management Service'
status: .ok
}
agent1.services = [service]
// Add the agents
println('Adding agent 1')
@@ -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}'

View File

@@ -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,15 +153,14 @@ 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()!
@@ -130,18 +168,20 @@ pub fn Agent.loads(data []u8) !Agent {
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
}

View File

@@ -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
}

View File

@@ -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,21 +43,26 @@ 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{

View File

@@ -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

View File

@@ -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
}

View File

@@ -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 {

View File

@@ -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) }

View File

@@ -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 {

View File

@@ -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) }

View File

@@ -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()!
}
}

View File

@@ -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) {

View File

@@ -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')