- Update delete functions to return bool indicating success - Add existence checks before deleting items - Return 404 error for non-existent items in RPC delete operations - Remove unused 'new_response_ok' result from RPC delete operations
277 lines
6.8 KiB
V
277 lines
6.8 KiB
V
module heromodels
|
|
|
|
import freeflowuniverse.herolib.data.encoder
|
|
import freeflowuniverse.herolib.data.ourtime
|
|
import freeflowuniverse.herolib.hero.db
|
|
import freeflowuniverse.herolib.schemas.jsonrpc { Response, new_error, new_response, new_response_false, new_response_int, new_response_true }
|
|
import freeflowuniverse.herolib.hero.user { UserRef }
|
|
import json
|
|
|
|
@[heap]
|
|
pub struct Message {
|
|
db.Base
|
|
pub mut:
|
|
// id u32
|
|
subject string
|
|
message string
|
|
parent u32 // id of parent message if any, 0 means none
|
|
author u32 // links to user
|
|
to []u32 // if message/message has been sent to someone specifically
|
|
cc []u32 // like to but then for cc
|
|
send_log []SendLog
|
|
}
|
|
|
|
pub struct SendLog {
|
|
pub mut:
|
|
to []u32 // if message/message has been sent to someone specifically
|
|
cc []u32 // like to but then for cc
|
|
status SendStatus
|
|
timestamp u64 // when was it done
|
|
}
|
|
|
|
enum SendStatus {
|
|
sent
|
|
received
|
|
acknowledged
|
|
}
|
|
|
|
//////////TO BE GENERATED BY AI////////////////////////////////
|
|
///BASIC CRUD FUNCTIONS
|
|
|
|
pub struct DBMessages {
|
|
pub mut:
|
|
db &db.DB @[skip; str: skip]
|
|
}
|
|
|
|
@[params]
|
|
pub struct MessageListArg {
|
|
pub mut:
|
|
parent u32
|
|
author u32
|
|
limit int = 100 // Default limit is 100
|
|
}
|
|
|
|
pub fn (self Message) type_name() string {
|
|
return 'messages'
|
|
}
|
|
|
|
// return example rpc call and result for each methodname
|
|
pub fn (self Message) description(methodname string) string {
|
|
match methodname {
|
|
'set' {
|
|
return 'Create or update a message. Returns the ID of the message.'
|
|
}
|
|
'get' {
|
|
return 'Retrieve a message by ID. Returns the message object.'
|
|
}
|
|
'delete' {
|
|
return 'Delete a message by ID. Returns true if successful.'
|
|
}
|
|
'exist' {
|
|
return 'Check if a message exists by ID. Returns true or false.'
|
|
}
|
|
'list' {
|
|
return 'List all messages. Returns an array of message objects.'
|
|
}
|
|
else {
|
|
return 'This is generic method for the root object, TODO fill in, ...'
|
|
}
|
|
}
|
|
}
|
|
|
|
// return example rpc call and result for each methodname
|
|
pub fn (self Message) example(methodname string) (string, string) {
|
|
match methodname {
|
|
'set' {
|
|
return '{"message": {"subject": "Test Subject", "message": "This is a test message.", "parent": 0, "author": 1, "to": [2, 3], "cc": [4], "send_log": [{"to": [2], "cc": [], "status": "sent", "timestamp": 1678886400}]}}', '1'
|
|
}
|
|
'get' {
|
|
return '{"id": 1}', '{"subject": "Test Subject", "message": "This is a test message.", "parent": 0, "author": 1, "to": [2, 3], "cc": [4], "send_log": [{"to": [2], "cc": [], "status": "sent", "timestamp": 1678886400}]}'
|
|
}
|
|
'delete' {
|
|
return '{"id": 1}', 'true'
|
|
}
|
|
'exist' {
|
|
return '{"id": 1}', 'true'
|
|
}
|
|
'list' {
|
|
return '{}', '[{"subject": "Test Subject", "message": "This is a test message.", "parent": 0, "author": 1, "to": [2, 3], "cc": [4], "send_log": [{"to": [2], "cc": [], "status": "sent", "timestamp": 1678886400}]}]'
|
|
}
|
|
else {
|
|
return '{}', '{}'
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn (self Message) dump(mut e encoder.Encoder) ! {
|
|
e.add_string(self.subject)
|
|
e.add_string(self.message)
|
|
e.add_u32(self.parent)
|
|
e.add_u32(self.author)
|
|
e.add_list_u32(self.to)
|
|
e.add_list_u32(self.cc)
|
|
// Encode send_log array
|
|
e.add_u16(u16(self.send_log.len))
|
|
for log_entry in self.send_log {
|
|
e.add_list_u32(log_entry.to)
|
|
e.add_list_u32(log_entry.cc)
|
|
e.add_u8(u8(log_entry.status))
|
|
e.add_u64(log_entry.timestamp)
|
|
}
|
|
}
|
|
|
|
pub fn (mut self DBMessages) load(mut o Message, mut e encoder.Decoder) ! {
|
|
o.subject = e.get_string()!
|
|
o.message = e.get_string()!
|
|
o.parent = e.get_u32()!
|
|
o.author = e.get_u32()!
|
|
o.to = e.get_list_u32()!
|
|
o.cc = e.get_list_u32()!
|
|
// Decode send_log array
|
|
send_log_len := e.get_u16()!
|
|
mut send_logs := []SendLog{}
|
|
for _ in 0 .. send_log_len {
|
|
to_list := e.get_list_u32()!
|
|
cc_list := e.get_list_u32()!
|
|
status := unsafe { SendStatus(e.get_u8()!) }
|
|
timestamp := e.get_u64()!
|
|
|
|
send_logs << SendLog{
|
|
to: to_list
|
|
cc: cc_list
|
|
status: status
|
|
timestamp: timestamp
|
|
}
|
|
}
|
|
o.send_log = send_logs
|
|
}
|
|
|
|
@[params]
|
|
pub struct MessageArg {
|
|
pub mut:
|
|
subject string
|
|
message string @[required]
|
|
parent u32
|
|
author u32
|
|
to []u32
|
|
cc []u32
|
|
}
|
|
|
|
// get new message, not from the DB
|
|
pub fn (mut self DBMessages) new(args MessageArg) !Message {
|
|
mut o := Message{
|
|
subject: args.subject
|
|
message: args.message
|
|
parent: args.parent
|
|
author: args.author
|
|
to: args.to
|
|
cc: args.cc
|
|
send_log: []SendLog{} // Initialize as empty
|
|
updated_at: ourtime.now().unix()
|
|
}
|
|
return o
|
|
}
|
|
|
|
pub fn (mut self DBMessages) set(o Message) !Message {
|
|
// Use db set function which returns the object with assigned ID
|
|
return self.db.set[Message](o)!
|
|
}
|
|
|
|
pub fn (mut self DBMessages) delete(id u32) !bool {
|
|
// Check if the item exists before trying to delete
|
|
if !self.db.exists[Message](id)! {
|
|
return false
|
|
}
|
|
self.db.delete[Message](id)!
|
|
return true
|
|
}
|
|
|
|
pub fn (mut self DBMessages) exist(id u32) !bool {
|
|
return self.db.exists[Message](id)!
|
|
}
|
|
|
|
pub fn (mut self DBMessages) get(id u32) !Message {
|
|
mut o, data := self.db.get_data[Message](id)!
|
|
mut e_decoder := encoder.decoder_new(data)
|
|
self.load(mut o, mut e_decoder)!
|
|
return o
|
|
}
|
|
|
|
pub fn (mut self DBMessages) list(args MessageListArg) ![]Message {
|
|
// Get all messages from the database
|
|
all_messages := self.db.list[Message]()!.map(self.get(it)!)
|
|
|
|
// Apply filters
|
|
mut filtered_messages := []Message{}
|
|
for message in all_messages {
|
|
// Filter by parent if provided
|
|
if args.parent != 0 && message.parent != args.parent {
|
|
continue
|
|
}
|
|
|
|
// Filter by author if provided
|
|
if args.author != 0 && message.author != args.author {
|
|
continue
|
|
}
|
|
|
|
filtered_messages << message
|
|
}
|
|
|
|
// Limit results to 100 or the specified limit
|
|
mut limit := args.limit
|
|
if limit > 100 {
|
|
limit = 100
|
|
}
|
|
if filtered_messages.len > limit {
|
|
return filtered_messages[..limit]
|
|
}
|
|
|
|
return filtered_messages
|
|
}
|
|
|
|
pub fn message_handle(mut f ModelsFactory, rpcid int, servercontext map[string]string, userref UserRef, method string, params string) !Response {
|
|
match method {
|
|
'get' {
|
|
id := db.decode_u32(params)!
|
|
res := f.messages.get(id)!
|
|
return new_response(rpcid, json.encode(res))
|
|
}
|
|
'set' {
|
|
mut o := db.decode_generic[Message](params)!
|
|
o = f.messages.set(o)!
|
|
return new_response_int(rpcid, int(o.id))
|
|
}
|
|
'delete' {
|
|
id := db.decode_u32(params)!
|
|
deleted := f.messages.delete(id)!
|
|
if deleted {
|
|
return new_response_true(rpcid)
|
|
} else {
|
|
return new_error(rpcid,
|
|
code: 404
|
|
message: 'Message with ID ${id} not found'
|
|
)
|
|
}
|
|
}
|
|
'exist' {
|
|
id := db.decode_u32(params)!
|
|
if f.messages.exist(id)! {
|
|
return new_response_true(rpcid)
|
|
} else {
|
|
return new_response_false(rpcid)
|
|
}
|
|
}
|
|
'list' {
|
|
args := db.decode_generic[MessageListArg](params)!
|
|
res := f.messages.list(args)!
|
|
return new_response(rpcid, json.encode(res))
|
|
}
|
|
else {
|
|
return new_error(rpcid,
|
|
code: 32601
|
|
message: 'Method ${method} not found on message'
|
|
)
|
|
}
|
|
}
|
|
}
|