backend/source/repositories/resource.ts
Fenris Wolf a17b7dd785 [fix]
2024-09-25 15:28:25 +02:00

447 lines
9.9 KiB
TypeScript

namespace _zeitbild.repository.resource
{
/**
*/
var _local_resource_event_chest : (
null
|
lib_plankton.storage.type_chest<
Array<any>,
Record<string, any>,
lib_plankton.database.type_description_create_table,
lib_plankton.storage.sql_table_common.type_sql_table_common_search_term,
Record<string, any>
>
) = null;
/**
*/
var _local_resource_core_store : (
null
|
lib_plankton.storage.type_store<
int,
Record<string, any>,
{},
lib_plankton.storage.type_sql_table_autokey_search_term,
Record<string, any>
>
) = null;
/**
*/
var _caldav_resource_store : (
null
|
lib_plankton.storage.type_store<
int,
Record<string, any>,
{},
lib_plankton.storage.type_sql_table_autokey_search_term,
Record<string, any>
>
) = null;
/**
*/
var _resource_core_store : (
null
|
lib_plankton.storage.type_store<
_zeitbild.type_resource_id,
Record<string, any>,
{},
lib_plankton.storage.type_sql_table_autokey_search_term,
Record<string, any>
>
) = null;
/**
*/
function get_local_resource_event_chest(
) : lib_plankton.storage.type_chest<
Array<any>,
Record<string, any>,
lib_plankton.database.type_description_create_table,
lib_plankton.storage.sql_table_common.type_sql_table_common_search_term,
Record<string, any>
>
{
if (_local_resource_event_chest === null) {
_local_resource_event_chest = lib_plankton.storage.sql_table_common.chest(
{
"database_implementation": _zeitbild.database.get_implementation(),
"table_name": "local_resource_events",
"key_names": ["local_resource_id","event_id"],
}
);
}
else {
// do nothing
}
return _local_resource_event_chest;
}
/**
*/
function get_local_resource_core_store(
) : lib_plankton.storage.type_store<
int,
Record<string, any>,
{},
lib_plankton.storage.type_sql_table_autokey_search_term,
Record<string, any>
>
{
if (_local_resource_core_store === null) {
_local_resource_core_store = lib_plankton.storage.sql_table_autokey_store(
{
"database_implementation": _zeitbild.database.get_implementation(),
"table_name": "local_resources",
"key_name": "id",
}
);
}
else {
// do nothing
}
return _local_resource_core_store;
}
/**
*/
function get_caldav_resource_store(
) : lib_plankton.storage.type_store<
int,
Record<string, any>,
{},
lib_plankton.storage.type_sql_table_autokey_search_term,
Record<string, any>
>
{
if (_caldav_resource_store === null) {
_caldav_resource_store = lib_plankton.storage.sql_table_autokey_store(
{
"database_implementation": _zeitbild.database.get_implementation(),
"table_name": "caldav_resources",
"key_name": "id",
}
);
}
else {
// do nothing
}
return _caldav_resource_store;
}
/**
*/
function get_resource_core_store(
) : lib_plankton.storage.type_store<
_zeitbild.type_resource_id,
Record<string, any>,
{},
lib_plankton.storage.type_sql_table_autokey_search_term,
Record<string, any>
>
{
if (_resource_core_store === null) {
_resource_core_store = lib_plankton.storage.sql_table_autokey_store(
{
"database_implementation": _zeitbild.database.get_implementation(),
"table_name": "resources",
"key_name": "id",
}
);
}
else {
// do nothing
}
return _resource_core_store;
}
/**
*/
/*
function encode_resource_core(
stuff : {
object : _zeitbild.type_resource_object;
sub_id : int;
}
) : Record<string, any>
{
return {
"kind": stuff.object.kind,
"sub_id": stuff.sub_id
};
}
*/
/**
* @todo data
*/
/*
function decode_resource_core(
row : Record<string, any>
) : {
object : _zeitbild.type_resource_object;
sub_id : int;
}
{
return {
"object": {
"kind": row["kind"],
"data": null,
},
"sub_id": row["sub_id"],
};
}
*/
/**
*/
export async function read(
resource_id : _zeitbild.type_resource_id
) : Promise<_zeitbild.type_resource_object>
{
const dataset_core : Record<string, any> = await get_resource_core_store().read(resource_id);
switch (dataset_core.kind) {
case "local": {
const dataset_extra_local_core : Record<string, any> = await get_local_resource_core_store().read(dataset_core.sub_id);
const datasets_extra_local_event_ids : Array<Record<string, any>> = await get_local_resource_event_chest().search(
{
"expression": "(local_resource_id = $local_resource_id)",
"arguments": {
"local_resource_id": dataset_core.sub_id,
}
}
);
return Promise.resolve<_zeitbild.type_resource_object>(
{
"kind": "local",
"data": {
"event_ids": (
datasets_extra_local_event_ids
.map((hit) => hit.preview["event_id"])
)
}
}
);
}
case "caldav": {
const dataset_extra_caldav : Record<string, any> = await get_caldav_resource_store().read(dataset_core.sub_id);
return Promise.resolve<_zeitbild.type_resource_object>(
{
"kind": "caldav",
"data": {
"url": dataset_extra_caldav["url"],
"read_only": dataset_extra_caldav["read_only"],
}
}
);
break;
}
default: {
return Promise.reject<_zeitbild.type_resource_object>(
new Error("invalid resource kind: " + dataset_core.kind)
);
break;
}
}
}
/**
*/
export async function create(
resource_object : _zeitbild.type_resource_object
) : Promise<_zeitbild.type_resource_id>
{
switch (resource_object.kind) {
case "local": {
const local_resource_id : int = await get_local_resource_core_store().create(
{
"_dummy": null,
}
);
for await (const event_id of resource_object.data.event_ids) {
await get_local_resource_event_chest().write(
[local_resource_id, event_id],
{
}
)
}
const resource_id : _zeitbild.type_resource_id = await get_resource_core_store().create(
{
"kind": "local",
"sub_id": local_resource_id,
}
);
return Promise.resolve<_zeitbild.type_resource_id>(resource_id);
break;
}
case "caldav": {
const caldav_resource_id : int = await get_caldav_resource_store().create(
{
"url": resource_object.data.url,
"read_only": resource_object.data.read_only,
}
);
const resource_id : _zeitbild.type_resource_id = await get_resource_core_store().create(
{
"kind": "caldav",
"sub_id": caldav_resource_id,
}
);
return Promise.resolve<_zeitbild.type_resource_id>(resource_id);
break;
}
default: {
// @ts-ignore
throw (new Error("invalid resource kind: " + resource_object.kind));
break;
}
}
}
/**
* @todo allow kind change?
*/
export async function update(
resource_id : _zeitbild.type_resource_id,
resource_object : _zeitbild.type_resource_object
) : Promise<void>
{
const dataset_core : Record<string, any> = await get_resource_core_store().read(resource_id);
if (dataset_core["kind"] !== resource_object.kind) {
return Promise.reject(new Error("resource kind may not be altered"));
}
else {
switch (resource_object.kind) {
case "local": {
// event_id list may not be altered directly
/*
const current_event_id_rows : {key : int; preview : Array<Record<string, any>>;} = await get_local_resource_event_chest().search(
{
"expression": "(local_resource_id = $local_resource_id)",
"arguments": {
"local_resource_id": dataset_core["sub_id"]
}
}
);
const contrast : {
only_left : Array<{key : int; left : any;}>;
both : Array<{key : int; left : any; right : any;}>;
only_right : Array<{key : int; right : any;}>;
} = lib_plankton.list.contrast<
{key : Array<any>; preview : Record<string, any>;},
_zeitbild.type_local_resource_event_id
>(
event_rows,
(hit => hit.key),
resource_object.data.event_ids,
(x => x)
);
// TODO: single delete?
for await (const entry of constrast.only_left) {
await get_local_resource_event_store().delete(
entry.key
);
}
/*
for await (const entry of contrast.both) {
await get_local_resource_event_store().update(
entry.left.key,
encode_event(entry.right.object)
);
}
for await (const entry of contrast.only_right) {
const event_id : type_local_resource_event_id = await get_local_resource_event_store().create(
encode_event(entry.right.object)
);
}
*/
break;
}
case "caldav": {
await get_caldav_resource_store().update(
dataset_core["sub_id"],
{
"url": resource_object.data.url,
"read_only": resource_object.data.read_only,
}
);
break;
}
default: {
// @ts-ignore
throw (new Error("invalid resource kind: " + resource_object.kind));
break;
}
}
}
}
/**
*/
export async function local_resource_event_add(
resource_id : _zeitbild.type_resource_id,
event_id : _zeitbild.type_event_id
) : Promise<void>
{
const dataset_core : Record<string, any> = await get_resource_core_store().read(resource_id);
if (! (dataset_core.kind === "local")) {
throw (new Error("not a local resource"));
}
else {
return (
get_local_resource_event_chest().write(
[dataset_core["sub_id"], event_id],
{}
)
.then(
() => Promise.resolve(undefined)
)
);
}
}
/**
*/
export async function local_resource_event_delete(
resource_id : _zeitbild.type_resource_id,
event_id : _zeitbild.type_event_id
) : Promise<void>
{
const dataset_core : Record<string, any> = await get_resource_core_store().read(resource_id);
if (! (dataset_core.kind === "local")) {
throw (new Error("not a local resource"));
}
else {
return (
get_local_resource_event_chest().delete(
[dataset_core["sub_id"], event_id]
)
.then(
() => Promise.resolve(undefined)
)
);
}
}
}