136 lines
2.9 KiB
V
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
|
|
}
|