/* Espe | Ein schlichtes Werkzeug zur Mitglieder-Verwaltung | Backend Copyright (C) 2024 Christian Fraß This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ namespace _espe.repository.invite { /** */ type type_group_chest = lib_plankton.storage.type_chest< Array, Record, lib_plankton.database.type_description_create_table, lib_plankton.storage.sql_table_common.type_sql_table_common_search_term, Record >; /** */ var _core_store : ( null | lib_plankton.storage.type_store< _espe.type.invite_id, Record, {}, lib_plankton.storage.type_sql_table_autokey_search_term, Record > ) = null; /** */ var _group_chest : ( null | type_group_chest ) = null; /** */ function get_core_store( ) : lib_plankton.storage.type_store< _espe.type.invite_id, Record, {}, lib_plankton.storage.type_sql_table_autokey_search_term, Record > { if (_core_store === null) { _core_store = lib_plankton.storage.sql_table_autokey_store( { "database_implementation": _espe.helpers.database_implementation(), "table_name": "invites", "key_name": "id", } ); } else { // do nothing } return _core_store; } /** */ function get_group_chest( ) : type_group_chest { if (_group_chest === null) { _group_chest = lib_plankton.storage.sql_table_common.chest( { "database_implementation": _espe.helpers.database_implementation(), "table_name": "invite_groups", "key_names": ["invite_id","group_name"], } ); } else { // do nothing } return _group_chest; } /** */ type type_dispersal = { core_row : Record; group_rows : Array< Record >; }; /** */ function encode( object : _espe.type.invite_object ) : type_dispersal { return { "core_row": { "key": object.key, "expiry": object.expiry, "membership_number_changeable": _espe.helpers.dbbool_encode(object.membership_number_changeable), "membership_number_value": object.membership_number_value, "name_changeable": _espe.helpers.dbbool_encode(object.name_changeable), "name_value": object.name_value, "email_address_changeable": _espe.helpers.dbbool_encode(object.email_address_changeable), "email_address_value": object.email_address_value, "groups_changeable": _espe.helpers.dbbool_encode(object.groups_changeable), }, "group_rows": ( object.groups_value .map( group => ({ "group_name": group, }) ) ) }; } /** */ function decode( dispersal : type_dispersal ) : _espe.type.invite_object { return { "key": dispersal.core_row["key"], "expiry": dispersal.core_row["expiry"], "membership_number_changeable": _espe.helpers.dbbool_decode(dispersal.core_row["membership_number_changeable"]), "membership_number_value": dispersal.core_row["membership_number_value"], "name_changeable": _espe.helpers.dbbool_decode(dispersal.core_row["name_changeable"]), "name_value": dispersal.core_row["name_value"], "email_address_changeable": _espe.helpers.dbbool_decode(dispersal.core_row["email_address_changeable"]), "email_address_value": dispersal.core_row["email_address_value"], "groups_changeable": _espe.helpers.dbbool_decode(dispersal.core_row["groups_changeable"]), "groups_value": lib_plankton.list.sorted( dispersal.group_rows.map(row => row["group_name"]), { "compare_element": (group1, group2) => (group1 <= group2) } ), }; } /** * @todo optimize */ export async function list( search_term : (null | string) ) : Promise< Array< { id : _espe.type.invite_id; preview : { name : string; }; } > > { return ( (await get_core_store().search(null)) .filter( ({"key": key, "preview": preview}) => ( (search_term === null) ? true : (preview["key"] === search_term) ) ) .map( ({"key": key, "preview": preview}) => ({ "id": key, "preview": { "name": preview["name_value"], } }) ) ); } /** */ export async function read( id : _espe.type.invite_id ) : Promise<_espe.type.invite_object> { const core_row : Record = await get_core_store().read(id); const group_hits : Array<{key : Record; preview : Record;}> = await get_group_chest().search( { "expression": "invite_id = $invite_id", "arguments": {"invite_id": id} } ); const dispersal : type_dispersal = { "core_row": core_row, "group_rows": group_hits.map( hit => ({ "group_name": hit.preview["group_name"] }) ), }; return decode(dispersal); } /** */ export async function create( value : _espe.type.invite_object ) : Promise<_espe.type.invite_id> { const dispersal : type_dispersal = encode(value); // core const id : _espe.type.invite_id = await get_core_store().create(dispersal.core_row); // groups for await (const group_row of dispersal.group_rows) { await get_group_chest().write( [ id, group_row["group_name"], ], { "_dummy": null, } ); } return id; } /** */ export async function delete_( id : _espe.type.invite_id ) : Promise { // groups const hits : Array<{key : Array; preview : Record;}> = await get_group_chest().search( { "expression": "invite_id = $invite_id", "arguments": {"invite_id": id} } ); for (const hit of hits) { await get_group_chest().delete(hit.key); } // core await get_core_store().delete(id); } /** * @todo optimize */ export async function identify( key : _espe.type.invite_key ) : Promise<_espe.type.invite_id> { const hits : Array<{id : _espe.type.invite_id; preview : any;}> = await list(key); return ( (hits.length !== 1) ? Promise.reject<_espe.type.invite_id>(new Error("not found")) : Promise.resolve<_espe.type.invite_id>(hits[0].id) ); } /** */ export async function dump( ) : Promise< Array< { id : _espe.type.invite_id; object : _espe.type.invite_object; } > > { return ( Promise.all( (await get_core_store().search(null)) .map(hit => hit.key) .map( id => ( read(id) .then( (object) => ({ "id": id, "object": object }) ) ) ) ) ); } }