Files
herolib/libarchive/baobab/osis/root_object.v
2025-08-29 09:48:13 +02:00

136 lines
2.9 KiB
V

module osis
import x.json2
// describes a root object
pub struct RootObject {
pub mut:
id string
name string // Story
fields []FieldDescription
}
pub struct FieldDescription {
pub mut:
name string // name of field
typ FieldType
value string // value of field
is_secret bool // whether field should be encrypted upon storage
is_index bool // whether object is searchable by field
fts_enabled bool // whether full text search on field is enabled
}
// returns the sql type name of the field
pub fn (field FieldDescription) sql_type() string {
return match field.typ {
.text { 'TEXT' }
.number { 'INTEGER' }
}
}
pub enum FieldType {
number
text
}
pub fn (obj RootObject) to_json() string {
mut obj_map := map[string]json2.Any{}
for field in obj.fields {
obj_map[field.name] = field.value
}
return obj_map.str()
}
// returns the lists of the indices of a root objects db table, and corresponding values
pub fn (obj RootObject) sql_indices_values() ([]string, []string) {
obj_encoded := obj.to_json()
obj_val := "'${obj_encoded.replace("'", "''")}'"
// insert root object into its table
mut indices := ['data']
mut values := [obj_val]
for field in obj.fields {
if field.name == 'id' {
indices << '${field.name}'
values << '${field.value}'
}
if field.typ == .text {
if field.is_index {
indices << '${field.name}'
values << "'${field.value}'"
}
} else if field.typ == .number {
if field.is_index {
indices << '${field.name}'
values << '${field.value}'
}
}
}
println('debugzoni ${indices} ${values}')
return indices, values
}
// return the description of a given generic
pub fn root_object[T](object T) RootObject {
mut fields := []FieldDescription{}
$for field in T.fields {
mut typ := FieldType{}
$if field.typ is string {
typ = .text
} $else $if field.typ is int {
typ = .number
}
fields << FieldDescription{
name: field.name
typ: typ
value: object.$(field.name).str()
is_index: field.attrs.contains('index')
is_secret: field.attrs.contains('secret')
fts_enabled: field.attrs.contains('fts_enabled')
}
}
return RootObject{
name: typeof[T]()
fields: fields
}
}
// decodes root object into generic struct T
pub fn (object RootObject) to_generic[T]() T {
mut t := T{}
$for field in T.fields {
field_descrs := object.fields.filter(it.name == field.name)
if field_descrs.len == 1 {
$if field.typ is int {
t.$(field.name) = field_descrs[0].value.int()
} $else $if field.is_enum {
t.$(field.name) = field_descrs[0].value.int()
} $else {
t.$(field.name) = field_descrs[0].value
}
}
}
return t
}
pub fn root_object_from_json(json string) !RootObject {
raw_decode := json2.raw_decode(json)!
obj_map := raw_decode.as_map()
mut obj := RootObject{}
for key, val in obj_map {
obj.fields << FieldDescription{
name: key
value: val.str()
}
}
return obj
}