This commit is contained in:
2025-09-13 18:19:53 +02:00
parent 200e200a75
commit 22c238fbf8
6 changed files with 371 additions and 10 deletions

View File

@@ -0,0 +1,36 @@
#!/usr/bin/env -S v -n -w -cg -gc none -cc tcc -d use_openssl -enable-globals run
import freeflowuniverse.herolib.core.redisclient
import freeflowuniverse.herolib.hero.heromodels
mut mydb := heromodels.new()!
// Create a new chat group
mut chat_group := mydb.chat_group.new(
name: 'General Discussion'
description: 'A public channel for general discussions'
chat_type: .public_channel
last_activity: 0
is_archived: false
)!
// Save to database
oid := mydb.chat_group.set(chat_group)!
println('Created chat group with ID: ${oid}')
// Retrieve from database
mut chat_group2 := mydb.chat_group.get(oid)!
println('Retrieved chat group: ${chat_group2}')
// List all chat groups
mut chat_groups := mydb.chat_group.list()!
println('All chat groups: ${chat_groups}')
// Update the chat group
chat_group2.is_archived = true
chat_group2.last_activity = 1672531200
mydb.chat_group.set(chat_group2)!
// Retrieve updated chat group
mut chat_group3 := mydb.chat_group.get(oid)!
println('Updated chat group: ${chat_group3}')

View File

@@ -0,0 +1,51 @@
#!/usr/bin/env -S v -n -w -cg -gc none -cc tcc -d use_openssl -enable-globals run
import freeflowuniverse.herolib.core.redisclient
import freeflowuniverse.herolib.hero.heromodels
mut mydb := heromodels.new()!
// First create a chat group to reference
mut chat_group := mydb.chat_group.new(
name: 'General Discussion'
description: 'A public channel for general discussions'
chat_type: .public_channel
last_activity: 0
is_archived: false
)!
chat_group_id := mydb.chat_group.set(chat_group)!
// Create a new chat message
mut chat_message := mydb.chat_message.new(
name: 'Hello World Message'
description: 'A simple hello world message'
content: 'Hello, world!'
chat_group_id: chat_group_id
sender_id: 1
parent_messages: []
fs_files: []
message_type: .text
status: .sent
reactions: []
mentions: []
)!
// Save to database
oid := mydb.chat_message.set(chat_message)!
println('Created chat message with ID: ${oid}')
// Retrieve from database
mut chat_message2 := mydb.chat_message.get(oid)!
println('Retrieved chat message: ${chat_message2}')
// List all chat messages
mut chat_messages := mydb.chat_message.list()!
println('All chat messages: ${chat_messages}')
// Update the chat message
chat_message2.status = .read
mydb.chat_message.set(chat_message2)!
// Retrieve updated chat message
mut chat_message3 := mydb.chat_message.get(oid)!
println('Updated chat message: ${chat_message3}')

View File

@@ -1,20 +1,17 @@
module heromodels
import time
import crypto.blake3
import json
import freeflowuniverse.herolib.data.encoder
import freeflowuniverse.herolib.data.ourtime
import freeflowuniverse.herolib.hero.db
// ChatGroup represents a chat channel or conversation
@[heap]
pub struct ChatGroup {
db.Base
pub mut:
chat_type ChatType
messages []u32 // IDs of chat messages
created_at i64
updated_at i64
last_activity i64
is_archived bool
tags []string
}
pub enum ChatType {
@@ -23,3 +20,80 @@ pub enum ChatType {
direct_message
group_message
}
pub struct DBChatGroup {
pub mut:
db &db.DB @[skip; str: skip]
}
pub fn (self ChatGroup) type_name() string {
return 'chat_group'
}
pub fn (self ChatGroup) dump(mut e &encoder.Encoder) ! {
e.add_u8(u8(self.chat_type))
e.add_i64(self.last_activity)
e.add_bool(self.is_archived)
}
fn (mut self DBChatGroup) load(mut o ChatGroup, mut e &encoder.Decoder) ! {
o.chat_type = unsafe { ChatType(e.get_u8()!) }
o.last_activity = e.get_i64()!
o.is_archived = e.get_bool()!
}
@[params]
pub struct ChatGroupArg {
pub mut:
name string
description string
chat_type ChatType
last_activity i64
is_archived bool
securitypolicy u32
tags []string
comments []db.CommentArg
}
// get new chat group, not from the DB
pub fn (mut self DBChatGroup) new(args ChatGroupArg) !ChatGroup {
mut o := ChatGroup{
chat_type: args.chat_type
last_activity: args.last_activity
is_archived: args.is_archived
}
// Set base fields
o.name = args.name
o.description = args.description
o.securitypolicy = args.securitypolicy
o.tags = self.db.tags_get(args.tags)!
o.comments = self.db.comments_get(args.comments)!
o.updated_at = ourtime.now().unix()
return o
}
pub fn (mut self DBChatGroup) set(o ChatGroup) !u32 {
// Use db set function which now returns the ID
return self.db.set[ChatGroup](o)!
}
pub fn (mut self DBChatGroup) delete(id u32) ! {
self.db.delete[ChatGroup](id)!
}
pub fn (mut self DBChatGroup) exist(id u32) !bool {
return self.db.exists[ChatGroup](id)!
}
pub fn (mut self DBChatGroup) get(id u32) !ChatGroup {
mut o, data := self.db.get_data[ChatGroup](id)!
mut e_decoder := encoder.decoder_new(data)
self.load(mut o, mut e_decoder)!
return o
}
pub fn (mut self DBChatGroup) list() ![]ChatGroup {
return self.db.list[ChatGroup]()!.map(self.get(it)!)
}

View File

@@ -1,12 +1,13 @@
module heromodels
import time
import crypto.blake3
import json
import freeflowuniverse.herolib.data.encoder
import freeflowuniverse.herolib.data.ourtime
import freeflowuniverse.herolib.hero.db
// ChatMessage represents a message in a chat group
@[heap]
pub struct ChatMessage {
db.Base
pub mut:
content string
chat_group_id u32 // Associated chat group
@@ -56,3 +57,147 @@ pub mut:
emoji string
timestamp i64
}
pub struct DBChatMessage {
pub mut:
db &db.DB @[skip; str: skip]
}
pub fn (self ChatMessage) type_name() string {
return 'chat_message'
}
pub fn (self ChatMessage) dump(mut e &encoder.Encoder) ! {
e.add_string(self.content)
e.add_u32(self.chat_group_id)
e.add_u32(self.sender_id)
// Encode parent_messages array
e.add_u16(u16(self.parent_messages.len))
for link in self.parent_messages {
e.add_u32(link.message_id)
e.add_u8(u8(link.link_type))
}
e.add_list_u32(self.fs_files)
e.add_u8(u8(self.message_type))
e.add_u8(u8(self.status))
// Encode reactions array
e.add_u16(u16(self.reactions.len))
for reaction in self.reactions {
e.add_u32(reaction.user_id)
e.add_string(reaction.emoji)
e.add_i64(reaction.timestamp)
}
e.add_list_u32(self.mentions)
}
fn (mut self DBChatMessage) load(mut o ChatMessage, mut e &encoder.Decoder) ! {
o.content = e.get_string()!
o.chat_group_id = e.get_u32()!
o.sender_id = e.get_u32()!
// Decode parent_messages array
parent_messages_len := e.get_u16()!
mut parent_messages := []MessageLink{}
for _ in 0 .. parent_messages_len {
message_id := e.get_u32()!
link_type := unsafe { MessageLinkType(e.get_u8()!) }
parent_messages << MessageLink{
message_id: message_id
link_type: link_type
}
}
o.parent_messages = parent_messages
o.fs_files = e.get_list_u32()!
o.message_type = unsafe { MessageType(e.get_u8()!) }
o.status = unsafe { MessageStatus(e.get_u8()!) }
// Decode reactions array
reactions_len := e.get_u16()!
mut reactions := []MessageReaction{}
for _ in 0 .. reactions_len {
user_id := e.get_u32()!
emoji := e.get_string()!
timestamp := e.get_i64()!
reactions << MessageReaction{
user_id: user_id
emoji: emoji
timestamp: timestamp
}
}
o.reactions = reactions
o.mentions = e.get_list_u32()!
}
@[params]
pub struct ChatMessageArg {
pub mut:
name string
description string
content string
chat_group_id u32
sender_id u32
parent_messages []MessageLink
fs_files []u32
message_type MessageType
status MessageStatus
reactions []MessageReaction
mentions []u32
securitypolicy u32
tags []string
comments []db.CommentArg
}
// get new chat message, not from the DB
pub fn (mut self DBChatMessage) new(args ChatMessageArg) !ChatMessage {
mut o := ChatMessage{
content: args.content
chat_group_id: args.chat_group_id
sender_id: args.sender_id
parent_messages: args.parent_messages
fs_files: args.fs_files
message_type: args.message_type
status: args.status
reactions: args.reactions
mentions: args.mentions
}
// Set base fields
o.name = args.name
o.description = args.description
o.securitypolicy = args.securitypolicy
o.tags = self.db.tags_get(args.tags)!
o.comments = self.db.comments_get(args.comments)!
o.updated_at = ourtime.now().unix()
return o
}
pub fn (mut self DBChatMessage) set(o ChatMessage) !u32 {
// Use db set function which now returns the ID
return self.db.set[ChatMessage](o)!
}
pub fn (mut self DBChatMessage) delete(id u32) ! {
self.db.delete[ChatMessage](id)!
}
pub fn (mut self DBChatMessage) exist(id u32) !bool {
return self.db.exists[ChatMessage](id)!
}
pub fn (mut self DBChatMessage) get(id u32) !ChatMessage {
mut o, data := self.db.get_data[ChatMessage](id)!
mut e_decoder := encoder.decoder_new(data)
self.load(mut o, mut e_decoder)!
return o
}
pub fn (mut self DBChatMessage) list() ![]ChatMessage {
return self.db.list[ChatMessage]()!.map(self.get(it)!)
}

View File

@@ -11,6 +11,8 @@ pub mut:
user DBUser
project DBProject
project_issue DBProjectIssue
chat_group DBChatGroup
chat_message DBChatMessage
}
pub fn new() !ModelsFactory {
@@ -37,5 +39,11 @@ pub fn new() !ModelsFactory {
project_issue: DBProjectIssue{
db: &mydb
}
chat_group: DBChatGroup{
db: &mydb
}
chat_message: DBChatMessage{
db: &mydb
}
}
}

47
test_chat_models.vsh Normal file
View File

@@ -0,0 +1,47 @@
#!/usr/bin/env -S v -n -w -cg -gc none -cc tcc -d use_openssl -enable-globals run
import freeflowuniverse.herolib.hero.heromodels
fn main() {
mut mydb := heromodels.new()!
// Test chat group creation
mut chat_group := mydb.chat_group.new(
name: 'Test Group'
description: 'A test chat group'
chat_type: .public_channel
last_activity: 1672531200
is_archived: false
)!
// Save chat group
chat_group_id := mydb.chat_group.set(chat_group)!
println('Created chat group with ID: ${chat_group_id}')
// Retrieve chat group
mut retrieved_group := mydb.chat_group.get(chat_group_id)!
println('Retrieved chat group: ${retrieved_group}')
// Test chat message creation
mut chat_message := mydb.chat_message.new(
name: 'Test Message'
description: 'A test chat message'
content: 'This is a test message'
chat_group_id: chat_group_id
sender_id: 1
parent_messages: []
fs_files: []
message_type: .text
status: .sent
reactions: []
mentions: []
)!
// Save chat message
message_id := mydb.chat_message.set(chat_message)!
println('Created chat message with ID: ${message_id}')
// Retrieve chat message
mut retrieved_message := mydb.chat_message.get(message_id)!
println('Retrieved chat message: ${retrieved_message}')
}