diff --git a/lib/baobab/osis/indexer.v b/lib/baobab/osis/indexer.v index 05c01e2a..5cc342e8 100644 --- a/lib/baobab/osis/indexer.v +++ b/lib/baobab/osis/indexer.v @@ -5,7 +5,6 @@ import db.sqlite import db.pg import freeflowuniverse.herolib.core.texttools import freeflowuniverse.herolib.core.pathlib -import freeflowuniverse.herolib.clients.postgres import orm pub struct Indexer { @@ -31,64 +30,29 @@ pub fn reset(path string) ! { // new creates a new root object entry in the root_objects table, // and the table belonging to the type of root object with columns for index fields pub fn (mut backend Indexer) new(object RootObject) !u32 { - table_name := get_table_name(object) - - // create table for root object if it doesn't exist - backend.create_root_object_table(object)! - indices, values := object.sql_indices_values() - insert_query := 'INSERT into ${table_name} (${indices.join(',')}) values (${values.join(',')})' - backend.db.exec(insert_query) or { - return error('Error inserting object ${object} into table ${table_name}\n${err}') - } - - return 0 + panic('implement') } // save the session to redis & mem pub fn (mut backend Indexer) set(obj RootObject) ! { - table_name := get_table_name(obj) - indices, values := obj.sql_indices_values() - // todo: check table and entry exists - - mut sql_stmts := []string{} - for i in 0 .. indices.len { - sql_stmts << '${indices[i]}=${values[i]}' - } - backend.db.exec("update ${table_name} set ${sql_stmts.join(' ')} where id=${obj.id}")! + panic('implement') } // save the session to redis & mem pub fn (mut backend Indexer) delete(id string, obj RootObject) ! { - table_name := get_table_name(obj) - // todo: check table and entry exists - backend.db.exec('delete from ${table_name} where id=${id}')! + panic('implement') } pub fn (mut backend Indexer) get(id string, obj RootObject) !RootObject { - json_value := backend.get_json(id, obj)! - return root_object_from_json(json_value) + panic('implement') } pub fn (mut backend Indexer) get_json(id string, obj RootObject) !string { - table_name := get_table_name(obj) - - // check root object and table exists - responses := backend.db.exec('select * from ${table_name} where id=${id}')! - if responses.len == 0 { - return error('Root object not found') - } else if responses.len > 1 { - panic('More than one result with same id found. This should never happen.') - } - - return responses[0].vals[1] + panic('implement') } pub fn (mut backend Indexer) list(obj RootObject) ![]u32 { - table_name := get_table_name(obj) - - responses := backend.db.exec('select * from ${table_name}') or { panic(err) } - ids := responses.map(it.vals[0].u32()) - return ids + panic('implement') } // from and to for int f64 time etc. @@ -102,43 +66,7 @@ pub struct FilterParams { // filter lists root objects of type T that match provided index parameters and params. pub fn (mut backend Indexer) filter(filter RootObject, params FilterParams) ![]string { - table_name := get_table_name(filter) - - if !backend.table_exists(table_name)! { - return []string{} - } - table_indices := backend.get_table_indices(table_name) or { panic(err) } - - for field in filter.fields { - if field.name !in table_indices { - return error('Index ${field.name} not found for root struct ${filter.name}') - } - } - mut select_stmt := 'select * from ${table_name}' - - // $if D.fields.len > 0 { - select_stmt += ' where' - - mut matchers := []string{} - for field in filter.fields { - if field.typ == .text { - matchers << "${field.name} == '${field.value}'" - } else if field.typ == .number { - matchers << "${field.name} == ${field.value}" - } - } - matchers_str := if params.matches_all { - matchers.join(' AND ') - } else { - matchers.join(' OR ') - } - select_stmt += ' ${matchers_str}' - - println(select_stmt) - responses := backend.db.exec(select_stmt) or { panic(err) } - ids := responses.map(it.vals[0]) - // objects := responses.map(json.decode(T, it.vals[1]) or { panic(err) }) - return if params.limit == 0 { ids.map(it.str()) } else { ids.map(it.str())[..params.limit] } + panic('implement') } // create_root_struct_table creates a table for a root_struct with columns for each index field @@ -148,31 +76,18 @@ fn (mut backend Indexer) create_root_object_table(object RootObject) ! { // deletes an indexer table belonging to a root object fn (mut backend Indexer) delete_table(object RootObject)! { - table_name := get_table_name(object) - delete_query := 'delete table ${table_name}' - backend.db.exec(delete_query)! + panic('implement') } fn (mut backend Indexer) get_table_indices(table_name string) ![]string { - table_info := backend.db.exec('pragma table_info(${table_name});')! - if table_info.len == 0 { - return error('table doesnt exist') - } - return table_info[1..].map(it.vals[1]) + panic('implement') } fn (mut backend Indexer) table_exists(table_name string) !bool { - table_info := backend.db.exec('pragma table_info(${table_name});')! - println('debugzore ${table_info} ${table_name}') - if table_info.len == 0 { - return false - } - return true + panic('implement') } // get_table_name returns the name of the table belonging to a root struct fn get_table_name(object RootObject) string { - mut table_name := texttools.name_fix(object.name) - table_name = table_name.replace('.', '_') - return table_name + panic('implement') } \ No newline at end of file diff --git a/lib/baobab/osis/indexer_generic.v b/lib/baobab/osis/indexer_generic.v deleted file mode 100644 index 7a1e990b..00000000 --- a/lib/baobab/osis/indexer_generic.v +++ /dev/null @@ -1,68 +0,0 @@ -module osis - -import json -import db.sqlite -import db.pg -import freeflowuniverse.herolib.core.texttools -import freeflowuniverse.herolib.core.pathlib -import freeflowuniverse.herolib.clients.postgres -import orm - -// new creates a new root object entry in the root_objects table, -// and the table belonging to the type of root object with columns for index fields -pub fn (mut indexer Indexer) generic_new[T](obj T) !u32 { - return indexer.new(root_object[T](obj))! -} - -pub fn (mut indexer Indexer) generic_set[T](obj T) ! { - indexer.set(root_object[T](obj))! -} - -pub fn (mut indexer Indexer) generic_delete[T](id u32) ! { - indexer.delete(id, root_object[T](T{})) -} - -pub fn (mut indexer Indexer) generic_get[T](id u32) !T { - obj_json := indexer.get_json(id, root_object[T](T{}))! - return json.decode(T, obj_json)! -} - -pub fn (mut indexer Indexer) generic_list[T]() ![]u32 { - return indexer.list(root_object[T](T{})) -} - -// filter lists root objects of type T that match provided index parameters and params. -pub fn (mut indexer Indexer) generic_filter[T, D](filter D, params FilterParams) ![]string { - // TODO: make design decision for filter calls, below is a temporary hack - mut obj := root_object[D](filter) - obj.name = typeof[T]() - return indexer.filter(obj, params) -} - -// create_root_struct_table creates a table for a root_struct with columns for each index field -fn (mut indexer Indexer) generic_create_root_object_table[T]() ! { - indexer.create_root_object_table(root_object[T](T{}))! -} - -// deletes an indexer table belonging to a base object -fn (mut indexer Indexer) generic_delete_table[T]()! { - table_name := generic_get_table_name[T]() - delete_query := 'delete table ${table_name}' - indexer.db.exec(delete_query)! -} - -// get_table_name returns the name of the table belonging to a root struct -fn generic_get_table_name[T]() string { - mut table_name := '' - $for attr in T.attributes { - if attr.name == 'table' && attr.arg.len > 0 { - table_name = attr.arg - } - } - if table_name == '' { - table_name = typeof[T]() - } - table_name = texttools.name_fix(table_name) - table_name = table_name.replace('.', '_') - return table_name -} \ No newline at end of file diff --git a/lib/baobab/osis/indexer_generic_test.v b/lib/baobab/osis/indexer_generic_test.v deleted file mode 100644 index 9e816fff..00000000 --- a/lib/baobab/osis/indexer_generic_test.v +++ /dev/null @@ -1,132 +0,0 @@ -module osis - -import os -import freeflowuniverse.herolib.core.pathlib -import db.sqlite -import db.pg - -const db_dir = '${os.dir(@FILE)}/testdata/db' - -fn testsuite_begin() { - pathlib.get_dir( - path: db_dir - empty: true - )! -} - -fn testsuite_end() { - mut dir := pathlib.get_dir( - path: db_dir - delete: true - )! -} - -fn db_path(db_name string) string { - return '${db_dir}/${db_name}.db' -} - -const pgconfig := pg.Config { - dbname: 'default' - user: 'admin' - password: 'test' -} - -fn test_new_indexer() ! { - sqlite_db := sqlite.connect(db_path(@FN))! - sqlite_indexer := new_indexer(sqlite_db: sqlite_db)! - - postgres_db := pg.connect(pgconfig)! - postgres_indexer := new_indexer(postgres_db: postgres_db)! -} - -fn test_reset() ! { - reset(db_path(@FN))! -} - -pub struct TestStruct { - text string @[index] - number int @[index] -} - -fn test_indexer_new() ! { - // sqlite_db := sqlite.connect(db_path(@FN))! - // mut sqlite_indexer := new_indexer(sqlite_db: sqlite_db)! - - // sqlite_indexer.generic_new(TestStruct{ - // text: 'test_text' - // number: 41 - // })! - - // mut list := sqlite_indexer.generic_list[TestStruct]()! - // assert list.len == 1 - - // sqlite_indexer.generic_new(TestStruct{ - // text: 'test_text2' - // number: 42 - // })! - - // list = sqlite_indexer.generic_list[TestStruct]()! - // assert list.len == 2 - - // postgres - postgres_db := pg.connect(pgconfig)! - mut postgres_indexer := new_indexer(postgres_db: postgres_db)! - - postgres_indexer.generic_new(TestStruct{ - text: 'test_text' - number: 41 - })! - - mut list := postgres_indexer.generic_list[TestStruct]()! - assert list.len == 1 - - postgres_indexer.generic_new(TestStruct{ - text: 'test_text2' - number: 42 - })! - - list = postgres_indexer.generic_list[TestStruct]()! - assert list.len == 2 -} - -pub struct TestStructFilter { - text string - number int -} - -fn test_indexer_filter() ! { - sqlite_db := sqlite.connect(db_path(@FN))! - mut sqlite_indexer := new_indexer(sqlite_db: sqlite_db)! - - sqlite_indexer.generic_new(TestStruct{ - text: 'test_text' - number: 41 - })! - - mut list := sqlite_indexer.generic_filter[TestStruct, TestStructFilter]( - TestStructFilter { - text: 'test_tex' - } - )! - assert list.len == 0 - - list = sqlite_indexer.generic_filter[TestStruct, TestStructFilter]( - TestStructFilter { - text: 'test_text' - } - )! - - list = sqlite_indexer.generic_filter[TestStruct, TestStructFilter]( - TestStructFilter { - number: 40 - } - )! - assert list.len == 0 - - list = sqlite_indexer.generic_filter[TestStruct, TestStructFilter]( - TestStructFilter { - number: 41 - } - )! - assert list.len == 1 -} \ No newline at end of file diff --git a/lib/baobab/osis/indexer_identifier.v b/lib/baobab/osis/indexer_identifier.v deleted file mode 100644 index b1c22b25..00000000 --- a/lib/baobab/osis/indexer_identifier.v +++ /dev/null @@ -1,29 +0,0 @@ -module osis - -import db.pg - -struct BaseObject { - id int @[primary; sql: serial] - object string -} - -pub fn (mut i Indexer) init() ! { - sql i.db { - create table BaseObject - }! -} - -pub fn (mut i Indexer) new_id(object string) !u32 { - obj := BaseObject{object:object} - id := sql i.db { - insert obj into BaseObject - } or {return err} - return u32(id) -} - -pub fn (i Indexer) get_id(id u32) !string { - obj := sql i.db { - select from BaseObject where id == id - }! - return obj[0].object -} \ No newline at end of file diff --git a/lib/baobab/osis/indexer_test.v b/lib/baobab/osis/indexer_test.v deleted file mode 100644 index 05098503..00000000 --- a/lib/baobab/osis/indexer_test.v +++ /dev/null @@ -1,107 +0,0 @@ -module osis - -import os -import freeflowuniverse.herolib.core.pathlib -import db.sqlite -import db.pg - -const db_dir = '${os.dir(@FILE)}/testdata/db' - -fn testsuite_begin() { - pathlib.get_dir( - path: db_dir - empty: true - )! -} - -fn testsuite_end() { - mut dir := pathlib.get_dir( - path: db_dir - delete: true - )! -} - -fn db_path(db_name string) string { - return '${db_dir}/${db_name}.db' -} - -// fn test_new_indexer() ! { -// sqlite_db := sqlite.connect(db_path(@FN))! -// sqlite_indexer := new_indexer(sqlite_db: sqlite_db)! - -// postgres_db := pg.connect(dbname: 'default')! -// postgres_indexer := new_indexer(postgres_db: postgres_db)! -// } - -// fn test_reset() ! { -// reset(db_path(@FN))! -// } - -// pub struct TestStruct { -// text string @[index] -// number int @[index] -// } - -// fn test_indexer_new() ! { -// sqlite_db := sqlite.connect(db_path(@FN))! -// mut sqlite_indexer := new_indexer(sqlite_db: sqlite_db)! -// // mut postgres_indexer := new_indexer(new_db(@FN, PostgresConfig{})!)! - -// sqlite_indexer.new(TestStruct{ -// text: 'test_text' -// number: 41 -// })! - -// mut list := sqlite_indexer.list[TestStruct]()! -// assert list.len == 1 - -// sqlite_indexer.new(TestStruct{ -// text: 'test_text2' -// number: 42 -// })! - -// list = sqlite_indexer.list[TestStruct]()! -// assert list.len == 2 -// } - -// pub struct TestStructFilter { -// text string -// number int -// } - -// fn test_indexer_filter() ! { -// sqlite_db := sqlite.connect(db_path(@FN))! -// mut sqlite_indexer := new_indexer(sqlite_db: sqlite_db)! - -// sqlite_indexer.new(TestStruct{ -// text: 'test_text' -// number: 41 -// })! - -// mut list := sqlite_indexer.filter[TestStruct, TestStructFilter]( -// TestStructFilter { -// text: 'test_tex' -// } -// )! -// assert list.len == 0 - -// list = sqlite_indexer.filter[TestStruct, TestStructFilter]( -// TestStructFilter { -// text: 'test_text' -// } -// )! - -// list = sqlite_indexer.filter[TestStruct, TestStructFilter]( -// TestStructFilter { -// number: 40 -// } -// )! -// assert list.len == 0 - -// list = sqlite_indexer.filter[TestStruct, TestStructFilter]( -// TestStructFilter { -// number: 41 -// } -// )! -// assert list.len == 1 -// } \ No newline at end of file diff --git a/lib/baobab/osis/model.v b/lib/baobab/osis/model.v index 46257519..b93b4d6d 100644 --- a/lib/baobab/osis/model.v +++ b/lib/baobab/osis/model.v @@ -20,7 +20,3 @@ pub: secret string reset bool } - -pub fn (mut backend OSIS) reset_all() ! { - panic('implement') -} diff --git a/lib/baobab/osis/osis.v b/lib/baobab/osis/osis.v index 26445a34..5e6d2e3c 100644 --- a/lib/baobab/osis/osis.v +++ b/lib/baobab/osis/osis.v @@ -12,10 +12,20 @@ pub fn (mut o OSIS) generic_new[T](obj T) !u32 { return id } +pub fn (mut o OSIS) new[T](obj T) !u32 { + id := o.indexer.generic_new[T](obj)! + o.storer.generic_new[T](obj)! + return id +} + pub fn (mut o OSIS) generic_get[T](id u32) !T { return o.storer.generic_get[T](id)! } +pub fn (mut o OSIS) get[T](id int) !T { + return o.storer.generic_get[T](u32(id))! +} + pub fn (mut o OSIS) generic_set[T](obj T) ! { o.indexer.generic_set[T](obj) or { return error('Failed to set new indices:\n${err}') } o.storer.generic_set[T](obj)! @@ -26,6 +36,16 @@ pub fn (mut o OSIS) generic_delete[T](id u32) ! { o.storer.generic_delete[T](id)! } +pub fn (mut o OSIS) delete(id int) ! { + o.storer.delete(u32(id))! +} + +pub fn (mut o OSIS) list[T]() ![]T { + panic('implement') + // ids := o.indexer.generic_list[T]()! + // return o.storer.generic_list[T](ids)! +} + pub fn (mut o OSIS) generic_list[T]() ![]T { ids := o.indexer.generic_list[T]()! return o.storer.generic_list[T](ids)! diff --git a/lib/baobab/osis/storer.v b/lib/baobab/osis/storer.v index 73d7000e..864f2559 100644 --- a/lib/baobab/osis/storer.v +++ b/lib/baobab/osis/storer.v @@ -1,56 +1,15 @@ module osis -import freeflowuniverse.herolib.data.dbfs -import db.sqlite +import freeflowuniverse.herolib.data.ourdb {OurDB} import os pub struct Storer { -pub: - directory string - db_filesystem dbfs.DBCollection - db_sqlite sqlite.DB +pub mut: + db OurDB } -@[params] -pub struct StorerConfig { - context_id u32 - secret string - directory string = '${os.home_dir()}/hero/baobab/storer' // Directory of the storer -} - -pub fn new_storer(config StorerConfig) !Storer { +pub fn new_storer() !Storer { return Storer { - directory: config.directory - db_filesystem: dbfs.get( - dbpath: '${config.directory}/dbfs/${config.context_id}' - secret: config.secret - contextid: config.context_id - )! + db: ourdb.new()! } -} - -@[params] -pub struct StorageParams { - // database_type DatabaseType - encrypted bool -} - -pub fn (mut storer Storer) new(object RootObject, params StorageParams) !u32 { - panic('implement') -} - -pub fn (mut storer Storer) get(id u32, params StorageParams) !RootObject { - panic('implement') -} - -pub fn (mut storer Storer) set(object RootObject, params StorageParams) ! { - panic('implement') -} - -pub fn (mut storer Storer) delete(id u32, params StorageParams) ! { - panic('implement') -} - -pub fn (mut storer Storer) list(ids []u32, params StorageParams) ![]RootObject { - panic('implement') } \ No newline at end of file diff --git a/lib/baobab/osis/storer_generic.v b/lib/baobab/osis/storer_generic.v index 19fb1e7c..babe1c15 100644 --- a/lib/baobab/osis/storer_generic.v +++ b/lib/baobab/osis/storer_generic.v @@ -1,45 +1,23 @@ module osis import json -import db.sqlite -import db.pg -import freeflowuniverse.herolib.core.texttools -import freeflowuniverse.herolib.core.pathlib -import freeflowuniverse.herolib.clients.postgres -import orm // new creates a new root object entry in the root_objects table, // and the table belonging to the type of root object with columns for index fields pub fn (mut storer Storer) generic_new[T](obj T) !u32 { - return storer.new(root_object[T](obj))! -} - -pub fn (mut storer Storer) generic_set[T](obj T) ! { - storer.set(root_object[T](obj))! -} - -pub fn (mut storer Storer) generic_delete[T](id u32) ! { - storer.delete(id, root_object[T](T{})) + data := json.encode(obj).bytes() + return storer.db.set(data: data) } pub fn (mut storer Storer) generic_get[T](id u32) !T { - root_object := storer.get(id)! - return root_object.to_generic[T]() + return json.decode(T, storer.db.get(id)!.bytestr()) } -pub fn (mut storer Storer) generic_list[T](ids []u32) ![]T { - root_objects := storer.list(ids)! - return root_objects.map(it.to_generic[T]()) +pub fn (mut storer Storer) generic_set[T](obj T) ! { + data := json.encode(obj).bytes() + return storer.db.set(data: data) } -// create_root_struct_table creates a table for a root_struct with columns for each index field -fn (mut storer Storer) generic_create_root_object_table[T]() ! { - storer.create_root_object_table(root_object[T](T{}))! -} - -// deletes an storer table belonging to a base object -fn (mut storer Storer) generic_delete_table[T]()! { - table_name := generic_get_table_name[T]() - delete_query := 'delete table ${table_name}' - storer.db.exec(delete_query)! +pub fn (mut storer Storer) delete(id u32) ! { + storer.db.delete(id)! } \ No newline at end of file diff --git a/lib/baobab/stage/actor.v b/lib/baobab/stage/actor.v index 33c9a9f2..664f77af 100644 --- a/lib/baobab/stage/actor.v +++ b/lib/baobab/stage/actor.v @@ -1,5 +1,7 @@ module stage +import freeflowuniverse.herolib.baobab.osis {OSIS} + @[heap] pub interface IActor { name string @@ -10,10 +12,15 @@ mut: pub struct Actor { pub: name string +mut: + osis OSIS } -pub fn new_actor(name string) Actor { - return Actor{name} +pub fn new_actor(name string) !Actor { + return Actor{ + osis: osis.new()! + name: name + } } pub fn (mut a IActor) handle(method string, data string) !string {