...
This commit is contained in:
@@ -5,7 +5,7 @@ import freeflowuniverse.herolib.hero.db
|
||||
import freeflowuniverse.herolib.core.redisclient
|
||||
|
||||
@[heap]
|
||||
pub struct ModelsFactory {
|
||||
pub struct FSFactory {
|
||||
pub mut:
|
||||
fs DBFs
|
||||
fs_blob DBFsBlob
|
||||
@@ -21,9 +21,9 @@ pub mut:
|
||||
redis ?&redisclient.Redis
|
||||
}
|
||||
|
||||
pub fn new(args DBArgs) !ModelsFactory {
|
||||
pub fn new(args DBArgs) !FSFactory {
|
||||
mut mydb := db.new(redis: args.redis)!
|
||||
mut f := ModelsFactory{
|
||||
mut f := FSFactory{
|
||||
fs: DBFs{db: &mydb}
|
||||
fs_blob: DBFsBlob{db: &mydb}
|
||||
fs_blob_membership: DBFsBlobMembership{db: &mydb}
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
// Update struct:
|
||||
module herofs
|
||||
|
||||
import crypto.blake3
|
||||
import freeflowuniverse.herolib.data.encoder
|
||||
import freeflowuniverse.herolib.data.ourtime
|
||||
import freeflowuniverse.herolib.hero.db
|
||||
|
||||
// FsBlob represents binary data up to 1MB
|
||||
@[heap]
|
||||
pub struct FsBlob {
|
||||
db.Base
|
||||
@@ -12,93 +19,134 @@ pub mut:
|
||||
pub struct DBFsBlob {
|
||||
pub mut:
|
||||
db &db.DB @[skip; str: skip]
|
||||
factory &ModelsFactory = unsafe { nil } @[skip; str: skip]
|
||||
factory &FSFactory = unsafe { nil } @[skip; str: skip]
|
||||
}
|
||||
|
||||
// Add these methods:
|
||||
pub fn (self FsBlob) description(methodname string) string {
|
||||
match methodname {
|
||||
'set' {
|
||||
return 'Create or update a blob. Returns the ID of the blob.'
|
||||
}
|
||||
'get' {
|
||||
return 'Retrieve a blob by ID. Returns the blob object.'
|
||||
}
|
||||
'delete' {
|
||||
return 'Delete a blob by ID. Returns true if successful.'
|
||||
}
|
||||
'exist' {
|
||||
return 'Check if a blob exists by ID. Returns true or false.'
|
||||
}
|
||||
'get_by_hash' {
|
||||
return 'Retrieve a blob by hash. Returns the blob object.'
|
||||
}
|
||||
else {
|
||||
return 'This is generic method for the blob object.'
|
||||
}
|
||||
pub fn (self FsBlob) type_name() string {
|
||||
return 'fs_blob'
|
||||
}
|
||||
|
||||
pub fn (self FsBlob) dump(mut e encoder.Encoder) ! {
|
||||
e.add_string(self.hash)
|
||||
e.add_list_u8(self.data)
|
||||
e.add_int(self.size_bytes)
|
||||
}
|
||||
|
||||
fn (mut self DBFsBlob) load(mut o FsBlob, mut e encoder.Decoder) ! {
|
||||
o.hash = e.get_string()!
|
||||
o.data = e.get_list_u8()!
|
||||
o.size_bytes = e.get_int()!
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct FsBlobArg {
|
||||
pub mut:
|
||||
data []u8 @[required]
|
||||
}
|
||||
|
||||
pub fn (mut blob FsBlob) calculate_hash() {
|
||||
hash := blake3.sum256(blob.data)
|
||||
blob.hash = hash.hex()[..48] // blake192 = first 192 bits = 48 hex chars
|
||||
}
|
||||
|
||||
// get new blob, not from the DB
|
||||
pub fn (mut self DBFsBlob) new(args FsBlobArg) !FsBlob {
|
||||
if args.data.len > 1024 * 1024 { // 1MB limit
|
||||
return error('Blob size exceeds 1MB limit')
|
||||
}
|
||||
|
||||
mut o := FsBlob{
|
||||
data: args.data
|
||||
size_bytes: args.data.len
|
||||
}
|
||||
|
||||
// Calculate hash
|
||||
o.calculate_hash()
|
||||
|
||||
// Set base fields
|
||||
o.updated_at = ourtime.now().unix()
|
||||
|
||||
return o
|
||||
}
|
||||
|
||||
pub fn (mut self DBFsBlob) set(o_ FsBlob) !FsBlob {
|
||||
// Use db set function which now modifies the object in-place
|
||||
o := self.db.set[FsBlob](o_)!
|
||||
|
||||
// Store the hash -> id mapping for lookup
|
||||
self.db.redis.hset('fsblob:hashes', o.hash, o.id.str())!
|
||||
|
||||
return o
|
||||
}
|
||||
|
||||
pub fn (mut self DBFsBlob) delete(id u32) ! {
|
||||
// Get the blob to retrieve its hash
|
||||
mut blob := self.get(id)!
|
||||
|
||||
// Remove hash -> id mapping
|
||||
self.db.redis.hdel('fsblob:hashes', blob.hash)!
|
||||
|
||||
// Delete the blob
|
||||
self.db.delete[FsBlob](id)!
|
||||
}
|
||||
|
||||
pub fn (mut self DBFsBlob) delete_multi(ids []u32) ! {
|
||||
for id in ids {
|
||||
self.delete(id)!
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (self FsBlob) example(methodname string) (string, string) {
|
||||
match methodname {
|
||||
'set' {
|
||||
return '{"blob": {"data": "SGVsbG8gV29ybGQ="}}', '1'
|
||||
}
|
||||
'get' {
|
||||
return '{"id": 1}', '{"hash": "abc123...", "data": "SGVsbG8gV29ybGQ=", "size_bytes": 11}'
|
||||
}
|
||||
'delete' {
|
||||
return '{"id": 1}', 'true'
|
||||
}
|
||||
'exist' {
|
||||
return '{"id": 1}', 'true'
|
||||
}
|
||||
'get_by_hash' {
|
||||
return '{"hash": "abc123..."}', '{"hash": "abc123...", "data": "SGVsbG8gV29ybGQ=", "size_bytes": 11}'
|
||||
}
|
||||
else {
|
||||
return '{}', '{}'
|
||||
}
|
||||
}
|
||||
pub fn (mut self DBFsBlob) exist(id u32) !bool {
|
||||
return self.db.exists[FsBlob](id)!
|
||||
}
|
||||
|
||||
// Add RPC handler function at the end:
|
||||
pub fn fs_blob_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.fs_blob.get(id)!
|
||||
return new_response(rpcid, json.encode(res))
|
||||
}
|
||||
'set' {
|
||||
mut o := db.decode_generic[FsBlob](params)!
|
||||
o = f.fs_blob.set(o)!
|
||||
return new_response_int(rpcid, int(o.id))
|
||||
}
|
||||
'delete' {
|
||||
id := db.decode_u32(params)!
|
||||
f.fs_blob.delete(id)!
|
||||
return new_response_ok(rpcid)
|
||||
}
|
||||
'exist' {
|
||||
id := db.decode_u32(params)!
|
||||
if f.fs_blob.exist(id)! {
|
||||
return new_response_true(rpcid)
|
||||
} else {
|
||||
return new_response_false(rpcid)
|
||||
}
|
||||
}
|
||||
'get_by_hash' {
|
||||
hash := db.decode_string(params)!
|
||||
res := f.fs_blob.get_by_hash(hash)!
|
||||
return new_response(rpcid, json.encode(res))
|
||||
}
|
||||
else {
|
||||
console.print_stderr('Method not found on fs_blob: ${method}')
|
||||
return new_error(rpcid,
|
||||
code: 32601
|
||||
message: 'Method ${method} not found on fs_blob'
|
||||
)
|
||||
pub fn (mut self DBFsBlob) exist_multi(ids []u32) !bool {
|
||||
for id in ids {
|
||||
if !self.exist(id)! {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
pub fn (mut self DBFsBlob) get(id u32) !FsBlob {
|
||||
mut o, data := self.db.get_data[FsBlob](id)!
|
||||
mut e_decoder := encoder.decoder_new(data)
|
||||
self.load(mut o, mut e_decoder)!
|
||||
return o
|
||||
}
|
||||
|
||||
pub fn (mut self DBFsBlob) get_multi(id []u32) ![]FsBlob {
|
||||
mut blobs := []FsBlob{}
|
||||
for i in id {
|
||||
blobs << self.get(i)!
|
||||
}
|
||||
return blobs
|
||||
}
|
||||
|
||||
pub fn (mut self DBFsBlob) get_by_hash(hash string) !FsBlob {
|
||||
// Get blob ID from Redis hash mapping
|
||||
id_str := self.db.redis.hget('fsblob:hashes', hash)!
|
||||
if id_str == '' {
|
||||
return error('Blob with hash ${hash} not found')
|
||||
}
|
||||
|
||||
id := id_str.u32()
|
||||
return self.get(id)!
|
||||
}
|
||||
|
||||
pub fn (mut self DBFsBlob) exists_by_hash(hash string) !bool {
|
||||
// Check if hash exists in Redis mapping
|
||||
id_str := self.db.redis.hget('fsblob:hashes', hash)!
|
||||
return id_str != ''
|
||||
}
|
||||
|
||||
pub fn (blob FsBlob) verify_integrity() bool {
|
||||
hash := blake3.sum256(blob.data)
|
||||
return hash.hex()[..48] == blob.hash
|
||||
}
|
||||
|
||||
pub fn (mut self DBFsBlob) verify(hash string) !bool {
|
||||
blob := self.get_by_hash(hash)!
|
||||
return blob.verify_integrity()
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ pub mut:
|
||||
pub struct DBFsFile {
|
||||
pub mut:
|
||||
db &db.DB @[skip; str: skip]
|
||||
factory &ModelsFactory = unsafe { nil } @[skip; str: skip]
|
||||
factory &FSFactory = unsafe { nil } @[skip; str: skip]
|
||||
}
|
||||
|
||||
pub fn (self FsFile) type_name() string {
|
||||
@@ -365,7 +365,7 @@ pub fn (self FsFile) example(methodname string) (string, string) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fs_file_handle(mut f ModelsFactory, rpcid int, servercontext map[string]string, userref UserRef, method string, params string) !Response {
|
||||
pub fn fs_file_handle(mut f FSFactory, rpcid int, servercontext map[string]string, userref UserRef, method string, params string) !Response {
|
||||
match method {
|
||||
'get' {
|
||||
id := db.decode_u32(params)!
|
||||
|
||||
Reference in New Issue
Block a user