Merge branch 'dev-publicity_calendars'

This commit is contained in:
Fenris Wolf 2024-10-12 12:06:02 +02:00
commit 7ffbf8f35e
17 changed files with 868 additions and 110 deletions

View file

@ -2381,6 +2381,99 @@ declare namespace lib_plankton.storage.sql_table_common {
}[]>;
}
}
declare namespace lib_plankton.cache {
/**
*/
type type_cache<type_value> = {
init: (() => Promise<void>);
clear: (() => Promise<void>);
query: ((key: string, retrieve: (() => Promise<type_value>)) => Promise<{
retrieved: boolean;
value: type_value;
}>);
};
}
declare namespace lib_plankton.cache {
/**
*/
function get<type_value>(cache: type_cache<type_value>, key: string, retrieve: (() => Promise<type_value>)): Promise<type_value>;
/**
*/
function get_complex<type_input, type_value>(cache: type_cache<type_value>, group: string, input: type_input, retrieve: ((input: type_input) => Promise<type_value>), options?: {
encode_input?: ((input: type_input) => string);
}): Promise<type_value>;
}
declare namespace lib_plankton.cache.never {
/**
* @author fenris
*/
type type_subject<type_value> = {};
/**
* @author fenris
*/
function make<type_value>(): type_subject<type_value>;
/**
*/
function implementation<type_value>(subject: type_subject<type_value>): type_cache<type_value>;
}
declare namespace lib_plankton.cache.always {
/**
* @author fenris
*/
type type_subject<type_value> = {
value: lib_plankton.pod.type_pod<type_value>;
};
/**
* @author fenris
*/
function make<type_value>(value: lib_plankton.pod.type_pod<type_value>): type_subject<type_value>;
/**
* @author fenris
*/
function clear<type_value>(subject: type_subject<type_value>): Promise<void>;
/**
* @author fenris
*/
function query<type_value>(subject: type_subject<type_value>, key: string, retrieve: (() => Promise<type_value>)): Promise<{
retrieved: boolean;
value: type_value;
}>;
/**
*/
function implementation<type_value>(subject: type_subject<type_value>): type_cache<type_value>;
}
declare namespace lib_plankton.cache.chest {
/**
* @author fenris
*/
type type_subject<type_value> = {
chest: lib_plankton.storage.type_chest<string, type_value, void, any, any>;
};
/**
* @author fenris
*/
function make<type_value>(options?: {
chest?: lib_plankton.storage.type_chest<string, type_value, void, any, any>;
}): type_subject<type_value>;
/**
* @author fenris
*/
function init<type_value>(subject: type_subject<type_value>): Promise<void>;
/**
* @author fenris
*/
function clear<type_value>(subject: type_subject<type_value>): Promise<void>;
/**
* @author fenris
*/
function query<type_value>(subject: type_subject<type_value>, key: string, retrieve: (() => Promise<type_value>)): Promise<{
retrieved: boolean;
value: type_value;
}>;
/**
*/
function implementation<type_value>(subject: type_subject<type_value>): type_cache<type_value>;
}
declare namespace lib_plankton.shape {
/**
* @todo
@ -2919,6 +3012,58 @@ declare namespace lib_plankton.session {
clear?: boolean;
}): Promise<void>;
}
declare namespace lib_plankton {
namespace order {
/**
*/
type type_order<type_value> = ((x: type_value, y: type_value) => boolean);
/**
*/
type type_comparator<type_value> = ((x: type_value, y: type_value) => int);
/**
*/
type type_sorter<type_element> = ((list: Array<type_element>) => Array<type_element>);
/**
*/
function from_comparator<type_value>(comparator: type_comparator<type_value>): type_order<type_value>;
/**
*/
function to_comparator<type_value>(order: type_order<type_value>): type_comparator<type_value>;
/**
*/
function order_default<type_value>(): type_order<type_value>;
/**
* @desc provide a total order given by a list
*/
function order_total<type_value>(list: Array<type_value>, options?: {
collation?: ((x: type_value, y: type_value) => boolean);
}): type_order<type_value>;
/**
* @desc lexicographic order
*/
function order_lexicographic_pair<type_value_first, type_value_second>(options?: {
order_first?: type_order<type_value_first>;
order_second?: type_order<type_value_second>;
}): type_order<lib_plankton.pair.type_pair<type_value_first, type_value_second>>;
/**
*/
function order_lexicographic_pair_wrapped<type_container, type_value_first, type_value_second>(extract_first: ((container: type_container) => type_value_first), extract_second: ((container: type_container) => type_value_second), options?: {
order_first?: type_order<type_value_first>;
order_second?: type_order<type_value_second>;
}): type_order<type_container>;
/**
* @desc lexicographic order
*/
function order_lexicographic_list<type_element>(options?: {
order?: type_order<type_element>;
}): type_order<Array<type_element>>;
/**
*/
function sorter_merge<type_element>(options?: {
order?: type_order<type_element>;
}): type_sorter<type_element>;
}
}
declare namespace lib_plankton.pit {
/**
*/

View file

@ -7423,6 +7423,289 @@ var lib_plankton;
})(storage = lib_plankton.storage || (lib_plankton.storage = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:cache«.
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>
»bacterio-plankton:cache« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
»bacterio-plankton:cache« 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:cache«. If not, see <http://www.gnu.org/licenses/>.
*/
/*
This file is part of »bacterio-plankton:cache«.
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>
»bacterio-plankton:cache« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
»bacterio-plankton:cache« 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:cache«. If not, see <http://www.gnu.org/licenses/>.
*/
var lib_plankton;
(function (lib_plankton) {
var cache;
(function (cache_1) {
/**
*/
function get(cache, key, retrieve) {
return cache.query(key, retrieve).then(result => result.value);
}
cache_1.get = get;
/**
*/
function get_complex(cache, group, input, retrieve, options = {}) {
options = Object.assign({
"encode_input": input => JSON.stringify(input),
}, options);
return get(cache, (group + "." + options.encode_input(input)), () => retrieve(input));
}
cache_1.get_complex = get_complex;
})(cache = lib_plankton.cache || (lib_plankton.cache = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:cache«.
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>
»bacterio-plankton:cache« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
»bacterio-plankton:cache« 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:cache«. If not, see <http://www.gnu.org/licenses/>.
*/
var lib_plankton;
(function (lib_plankton) {
var cache;
(function (cache) {
var never;
(function (never) {
/**
* @author fenris
*/
function make() {
return {};
}
never.make = make;
/**
* @author fenris
*/
function clear(subject) {
return Promise.resolve(undefined);
}
/**
* @author fenris
*/
async function query(subject, key, retrieve) {
return {
"retrieved": true,
"value": (await retrieve()),
};
}
/**
*/
function implementation(subject) {
return {
"init": () => Promise.resolve(undefined),
"clear": () => clear(subject),
"query": (key, retrieve) => query(subject, key, retrieve),
};
}
never.implementation = implementation;
})(never = cache.never || (cache.never = {}));
})(cache = lib_plankton.cache || (lib_plankton.cache = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:cache«.
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>
»bacterio-plankton:cache« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
»bacterio-plankton:cache« 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:cache«. If not, see <http://www.gnu.org/licenses/>.
*/
var lib_plankton;
(function (lib_plankton) {
var cache;
(function (cache) {
var always;
(function (always) {
/**
* @author fenris
*/
function make(value) {
return {
"value": value,
};
}
always.make = make;
/**
* @author fenris
*/
function clear(subject) {
return Promise.resolve(undefined);
}
always.clear = clear;
/**
* @author fenris
*/
function query(subject, key, retrieve) {
if (lib_plankton.pod.is_filled(subject.value)) {
return Promise.resolve({
"retrieved": false,
"value": lib_plankton.pod.cull(subject.value),
});
}
else {
return Promise.reject();
}
}
always.query = query;
/**
*/
function implementation(subject) {
return {
"init": () => Promise.resolve(undefined),
"clear": () => clear(subject),
"query": (key, retrieve) => query(subject, key, retrieve),
};
}
always.implementation = implementation;
})(always = cache.always || (cache.always = {}));
})(cache = lib_plankton.cache || (lib_plankton.cache = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:cache«.
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>
»bacterio-plankton:cache« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
»bacterio-plankton:cache« 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:cache«. If not, see <http://www.gnu.org/licenses/>.
*/
var lib_plankton;
(function (lib_plankton) {
var cache;
(function (cache) {
var chest;
(function (chest) {
/**
* @author fenris
*/
function make(options = {}) {
options = Object.assign({
"chest": lib_plankton.storage.memory.implementation_chest({}),
}, options);
return {
"chest": options.chest,
};
}
chest.make = make;
/**
* @author fenris
*/
function init(subject) {
return subject.chest.setup(undefined);
}
chest.init = init;
/**
* @author fenris
*/
function clear(subject) {
return subject.chest.clear();
}
chest.clear = clear;
/**
* @author fenris
*/
function query(subject, key, retrieve) {
return (subject.chest.read(key)
.then(value => (lib_plankton.log.info("cache.chest_hashed.known", {
"key": key,
})
,
Promise.resolve({
"retrieved": false,
"value": value,
})))
.catch(() => (lib_plankton.log.info("cache.chest_hashed.unknown", {
"key": key,
})
,
(retrieve()
.then((value) => (subject.chest.write(key, value)
.then(() => Promise.resolve({
"retrieved": true,
"value": value,
}))))
/*
.catch(
(reason) => Promise.reject<{retrieved : boolean; value : type_value}>(reason)
)
*/
))));
}
chest.query = query;
/**
*/
function implementation(subject) {
return {
"init": () => init(subject),
"clear": () => clear(subject),
"query": (key, retrieve) => query(subject, key, retrieve),
};
}
chest.implementation = implementation;
})(chest = cache.chest || (cache.chest = {}));
})(cache = lib_plankton.cache || (lib_plankton.cache = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:shape«.
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
@ -10098,6 +10381,198 @@ var lib_plankton;
})(session = lib_plankton.session || (lib_plankton.session = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:order«.
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>
»bacterio-plankton:order« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
»bacterio-plankton:order« 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:order«. If not, see <http://www.gnu.org/licenses/>.
*/
var lib_plankton;
(function (lib_plankton) {
var order;
(function (order_1) {
/**
*/
function from_comparator(comparator) {
return (function (x, y) { return (comparator(x, y) <= 0); });
}
order_1.from_comparator = from_comparator;
/**
*/
function to_comparator(order) {
return (function (x, y) { return (order(x, y) ? (order(y, x) ? 0 : -1) : 1); });
}
order_1.to_comparator = to_comparator;
/**
*/
function order_default() {
return (function (value1, value2) { return (value1 <= value2); });
}
order_1.order_default = order_default;
/**
* @desc provide a total order given by a list
*/
function order_total(list, options) {
if (options === void 0) { options = {}; }
options = Object.assign({
"collation": (function (x, y) { return (x === y); })
}, options);
return (function (value1, value2) {
var index1 = list.findIndex(function (value) { return options.collation(value, value1); });
var index2 = list.findIndex(function (value) { return options.collation(value, value2); });
return (index1 <= index2);
});
}
order_1.order_total = order_total;
/**
* @desc lexicographic order
*/
function order_lexicographic_pair(options) {
if (options === void 0) { options = {}; }
options = Object.assign({
"order_first": order_default(),
"order_second": order_default()
}, options);
return (function (pair1, pair2) {
var le_first = options.order_first(pair1.first, pair2.first);
var ge_first = options.order_first(pair2.first, pair1.first);
if (le_first && !ge_first) {
return true;
}
else if (!le_first && ge_first) {
return false;
}
else {
var le_second = options.order_second(pair1.second, pair2.second);
var ge_second = options.order_second(pair2.second, pair1.second);
if (le_second && !ge_second) {
return true;
}
else if (!le_second && ge_second) {
return false;
}
else {
return true;
}
}
});
}
order_1.order_lexicographic_pair = order_lexicographic_pair;
/**
*/
function order_lexicographic_pair_wrapped(extract_first, extract_second, options) {
if (options === void 0) { options = {}; }
return (function (container1, container2) { return order_lexicographic_pair({
"order_first": options.order_first,
"order_second": options.order_second
})({
"first": extract_first(container1),
"second": extract_second(container1)
}, {
"first": extract_first(container2),
"second": extract_second(container2)
}); });
}
order_1.order_lexicographic_pair_wrapped = order_lexicographic_pair_wrapped;
/**
* @desc lexicographic order
*/
function order_lexicographic_list(options) {
if (options === void 0) { options = {}; }
options = Object.assign({
"order": order_default()
}, options);
return (function (list1, list2) {
if (list1.length <= 0) {
if (list2.length <= 0) {
return true;
}
else {
return false;
}
}
else {
if (list2.length <= 0) {
return false;
}
else {
var element1 = list1[0];
var element2 = list2[0];
var le = options.order(element1, element2);
var ge = options.order(element2, element1);
if (le && !ge) {
return true;
}
else if (!le && ge) {
return false;
}
else {
return order_lexicographic_list({ "order": options.order })(list1.slice(1), list2.slice(1));
}
}
}
});
}
order_1.order_lexicographic_list = order_lexicographic_list;
/**
*/
function merger(options) {
if (options === void 0) { options = {}; }
options = Object.assign({
"order": order_default()
}, options);
return (function (list1, list2) {
if (list1.length <= 0) {
return list2;
}
else if (list2.length <= 0) {
return list1;
}
else {
var element1 = list1[0];
var element2 = list2[0];
return (options.order(element1, element2)
? ([element1].concat(merger({ "order": options.order })(list1.slice(1), list2)))
: ([element2].concat(merger({ "order": options.order })(list1, list2.slice(1)))));
}
});
}
/**
*/
function sorter_merge(options) {
if (options === void 0) { options = {}; }
options = Object.assign({
"order": order_default()
}, options);
return (function (list) {
if (list.length <= 0) {
return [];
}
else if (list.length === 1) {
return [list[0]];
}
else {
var n = ((list.length + 1) >> 1);
return merger({ "order": options.order })(sorter_merge({ "order": options.order })(list.slice(0, n)), sorter_merge({ "order": options.order })(list.slice(n)));
}
});
}
order_1.sorter_merge = sorter_merge;
})(order = lib_plankton.order || (lib_plankton.order = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:pit«.
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'

View file

@ -12,6 +12,7 @@ namespace _zeitbild.api
{
name : string;
access : {
public : boolean;
default_level : string;
attributed : Array<
{
@ -89,6 +90,7 @@ namespace _zeitbild.api
const calendar_object : _zeitbild.type_calendar_object = {
"name": stuff.input.name,
"access": {
"public": stuff.input.access.public,
"default_level": _zeitbild.value_object.access_level.from_string(stuff.input.access.default_level),
"attributed": lib_plankton.map.hashmap.implementation_map(
lib_plankton.map.hashmap.make(

View file

@ -12,6 +12,7 @@ namespace _zeitbild.api
{
name : string;
access : {
public : boolean;
default_level : ("none" | "view" | "edit" | "admin");
attributed : Array<
{
@ -54,6 +55,7 @@ namespace _zeitbild.api
const calendar_object_new : _zeitbild.type_calendar_object = {
"name": stuff.input.name,
"access": {
"public": stuff.input.access.public,
"default_level": _zeitbild.value_object.access_level.from_string(stuff.input.access.default_level),
"attributed": lib_plankton.map.hashmap.implementation_map(
lib_plankton.map.hashmap.make(

View file

@ -45,6 +45,7 @@ namespace _zeitbild.api
const result = {
"name": calendar_object.name,
"access": {
"public": calendar_object.access.public,
"default_level": _zeitbild.api.access_level_encode(calendar_object.access.default_level),
"attributed": lib_plankton.call.convey(
calendar_object.access.attributed,

View file

@ -54,10 +54,18 @@ namespace _zeitbild.api
],
}
}),
"restriction": restriction_logged_in,
"restriction": restriction_none,
"execution": async (stuff) => {
const session : {key : string; value : lib_plankton.session.type_session;} = await session_from_stuff(stuff);
const user_id : _zeitbild.type_user_id = await _zeitbild.service.user.identify(session.value.name);
const user_id : (null | _zeitbild.type_user_id) = await (
session_from_stuff(stuff)
.then(
(session : {key : string; value : lib_plankton.session.type_session;}) => (
_zeitbild.service.user.identify(session.value.name)
.catch(x => Promise.resolve(null))
)
)
.catch(x => Promise.resolve(null))
);
return (
_zeitbild.service.calendar.overview(user_id)

View file

@ -123,10 +123,18 @@ namespace _zeitbild.api
],
}
}),
"restriction": restriction_logged_in,
"restriction": restriction_none,
"execution": async (stuff) => {
const session : {key : string; value : lib_plankton.session.type_session;} = await session_from_stuff(stuff);
const user_id : _zeitbild.type_user_id = await _zeitbild.service.user.identify(session.value.name);
const user_id : (null | _zeitbild.type_user_id) = await (
session_from_stuff(stuff)
.then(
(session : {key : string; value : lib_plankton.session.type_session;}) => (
_zeitbild.service.user.identify(session.value.name)
.catch(x => Promise.resolve(null))
)
)
.catch(x => Promise.resolve(null))
);
const from : lib_plankton.pit.type_pit = parseInt(stuff.query_parameters["from"]);
const to : lib_plankton.pit.type_pit = parseInt(stuff.query_parameters["to"]);

8
source/base.ts Normal file
View file

@ -0,0 +1,8 @@
namespace _zeitbild
{
/**
*/
export var cache : lib_plankton.cache.type_cache<any>;
}

View file

@ -5,7 +5,7 @@ namespace _zeitbild.database
/**
*/
const _compatible_revisions : Array<string> = [
"r1",
"r2",
];

View file

@ -16,6 +16,7 @@ type type_data = {
id : int;
name : string;
access : {
public ?: boolean;
default_level : ("none" | "view" | "edit" | "admin");
attributed : Array<
{
@ -119,6 +120,7 @@ async function data_init(
const calendar_object : _zeitbild.type_calendar_object = {
"name": calendar_raw.name,
"access": {
"public": (calendar_raw.access.public ?? false),
"default_level": _zeitbild.value_object.access_level.from_string(calendar_raw.access.default_level),
"attributed": lib_plankton.map.hashmap.implementation_map(
lib_plankton.map.hashmap.make(
@ -258,6 +260,14 @@ async function main(
)
)
);
_zeitbild.cache = lib_plankton.cache.chest.implementation<any>(
lib_plankton.cache.chest.make<any>(
{
"chest": lib_plankton.storage.memory.implementation_chest<any>({}),
}
)
);
await _zeitbild.cache.init();
// exec
if (args["help"]) {

View file

@ -145,6 +145,7 @@ namespace _zeitbild.repository.calendar
return {
"core_row": {
"name": object.name,
"access_public": object.access.public,
"access_level_default": encode_access_level(object.access.default_level),
"resource_id": object.resource_id,
},
@ -171,6 +172,7 @@ namespace _zeitbild.repository.calendar
return {
"name": dispersal.core_row["name"],
"access": {
"public": dispersal.core_row["access_public"],
"default_level": decode_access_level(dispersal.core_row["access_level_default"]),
"attributed": lib_plankton.map.hashmap.implementation_map(
lib_plankton.map.hashmap.make<_zeitbild.type_user_id, _zeitbild.enum_access_level>(
@ -249,6 +251,7 @@ namespace _zeitbild.repository.calendar
{"level": access_attributed_row["level"]}
);
}
await _zeitbild.cache.clear();
return Promise.resolve<_zeitbild.type_calendar_id>(calendar_id);
}
@ -310,6 +313,7 @@ namespace _zeitbild.repository.calendar
);
}
}
await _zeitbild.cache.clear();
return Promise.resolve<void>(undefined);
}
@ -321,6 +325,7 @@ namespace _zeitbild.repository.calendar
calendar_id : _zeitbild.type_calendar_id
) : Promise<void>
{
await _zeitbild.cache.clear();
const core_store = get_core_store();
const access_attributed_chest = get_access_attributed_chest();
// attributed access
@ -351,19 +356,31 @@ namespace _zeitbild.repository.calendar
/**
*/
export async function overview(
user_id : _zeitbild.type_user_id
) : Promise<
Array<
{
type type_overview_entry = {
id : _zeitbild.type_calendar_id;
name : string;
access_level : _zeitbild.enum_access_level;
}
/**
* @todo caching
*/
export async function overview(
user_id : (null | _zeitbild.type_user_id)
) : Promise<
Array<
type_overview_entry
>
>
{
return (
return lib_plankton.cache.get_complex<any, Array<type_overview_entry>>(
_zeitbild.cache,
"calendar_overview",
{
"user_id": user_id,
},
() => (
lib_plankton.file.read("sql/calendar_overview.sql")
.then(
(template) => _zeitbild.database.get_implementation().query_free_get(
@ -377,17 +394,57 @@ namespace _zeitbild.repository.calendar
)
.then(
(rows) => Promise.resolve(
rows
.map(
(row) => ({
lib_plankton.call.convey(
rows,
[
(x : Array<Record<string, any>>) => x.map(
(row : Record<string, any>) => ({
"id": row["id"],
"name": row["name"],
"access_level": decode_access_level(row["access_level"]),
/**
* @todo unite with _zeitbild.service.calendar.get_access_level
*/
"access_level": decode_access_level(
Math.max(
(row["access_public"] ? 1 : 0),
(
(user_id === null)
?
0
:
(row["access_level_attributed"] ?? row["access_level_default"])
)
)
),
})
),
(x : Array<type_overview_entry>) => x.filter(
(row) => (
! _zeitbild.value_object.access_level.order(
row.access_level,
_zeitbild.enum_access_level.none
)
)
),
(x : Array<type_overview_entry>) => lib_plankton.list.sorted<type_overview_entry>(
x,
{
"compare_element": lib_plankton.order.order_lexicographic_pair_wrapped<type_overview_entry, _zeitbild.enum_access_level, int>(
row => row.access_level,
row => row.id,
{
"order_first": (a, b) => _zeitbild.value_object.access_level.order(b, a),
"order_second": (a, b) => (a <= b)
}
),
}
),
]
)
)
)
)
);
}
}

View file

@ -398,6 +398,7 @@ namespace _zeitbild.repository.resource
"sub_id": local_resource_id,
}
);
await _zeitbild.cache.clear();
return Promise.resolve<_zeitbild.type_resource_id>(resource_id);
break;
}
@ -414,6 +415,7 @@ namespace _zeitbild.repository.resource
"sub_id": caldav_resource_id,
}
);
await _zeitbild.cache.clear();
return Promise.resolve<_zeitbild.type_resource_id>(resource_id);
break;
}
@ -493,6 +495,7 @@ namespace _zeitbild.repository.resource
"read_only": resource_object.data.read_only,
}
);
await _zeitbild.cache.clear();
break;
}
default: {
@ -546,7 +549,7 @@ namespace _zeitbild.repository.resource
throw (new Error("not a local resource"));
}
else {
return get_local_resource_event_store().create(
const local_resource_event_id: _zeitbild.type_local_resource_event_id = await get_local_resource_event_store().create(
encode_local_resource_event(
{
"local_resource_id": dataset_core["sub_id"],
@ -554,6 +557,8 @@ namespace _zeitbild.repository.resource
}
)
);
await _zeitbild.cache.clear();
return Promise.resolve(local_resource_event_id);
}
}
@ -571,7 +576,7 @@ namespace _zeitbild.repository.resource
throw (new Error("not a local resource"));
}
else {
return get_local_resource_event_store().update(
await get_local_resource_event_store().update(
event_id,
encode_local_resource_event(
{
@ -580,6 +585,8 @@ namespace _zeitbild.repository.resource
}
)
);
await _zeitbild.cache.clear();
return Promise.resolve<void>(undefined);
}
}
@ -591,6 +598,7 @@ namespace _zeitbild.repository.resource
local_resource_event_id : _zeitbild.type_local_resource_event_id
) : Promise<void>
{
await _zeitbild.cache.clear();
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"));

View file

@ -1,20 +1,12 @@
SELECT
x.id AS id,
x.name AS name,
(
CASE
WHEN MAX(y.level) IS NULL THEN x.access_level_default
ELSE MAX(y.level)
END
) AS access_level
x.access_public AS access_public,
x.access_level_default AS access_level_default,
y.level AS access_level_attributed
FROM
calendars AS x
LEFT OUTER JOIN calendar_access_attributed AS y ON ((x.id = y.calendar_id) AND (y.user_id = $user_id))
GROUP BY
x.id
HAVING
(access_level > 0)
ORDER BY
access_level DESC,
id
;

View file

@ -3,18 +3,42 @@ namespace _zeitbild.service.calendar
{
/**
* checks if a user has a sufficient access level
*/
function get_access_level(
calendar_object : _zeitbild.type_calendar_object,
user_id : _zeitbild.type_user_id
user_id : (null | _zeitbild.type_user_id)
) : _zeitbild.enum_access_level
{
return calendar_object.access.attributed.get(
return (
lib_plankton.list.max<_zeitbild.enum_access_level, _zeitbild.enum_access_level>(
[
(
calendar_object.access.public
?
_zeitbild.enum_access_level.view
:
_zeitbild.enum_access_level.none
),
(
(user_id === null)
?
_zeitbild.enum_access_level.none
:
calendar_object.access.attributed.get(
user_id,
lib_plankton.pod.make_filled<_zeitbild.enum_access_level>(
calendar_object.access.default_level
)
)
),
],
x => x,
{
"compare_value": _zeitbild.value_object.access_level.order,
}
)?.value
??
_zeitbild.enum_access_level.none
);
}
@ -24,7 +48,7 @@ namespace _zeitbild.service.calendar
*/
function wrap_check_access_level<type_result>(
calendar_object : _zeitbild.type_calendar_object,
user_id : _zeitbild.type_user_id,
user_id : (null | _zeitbild.type_user_id),
threshold : _zeitbild.enum_access_level,
success_handler : (
(access_level : _zeitbild.enum_access_level)
@ -59,7 +83,7 @@ namespace _zeitbild.service.calendar
/**
*/
export function overview(
user_id : _zeitbild.type_user_id
user_id : (null | _zeitbild.type_user_id)
) : Promise<
Array<
{
@ -243,12 +267,13 @@ namespace _zeitbild.service.calendar
/**
* @todo optimize by reducing the number of database queries
*/
async function get_events(
calendar_id : _zeitbild.type_calendar_id,
from_pit : lib_plankton.pit.type_pit,
to_pit : lib_plankton.pit.type_pit,
user_id : _zeitbild.type_user_id
user_id : (null | _zeitbild.type_user_id)
) : Promise<
Array<
{
@ -401,15 +426,8 @@ namespace _zeitbild.service.calendar
/**
* @todo check access level
*/
export async function gather_events(
calendar_ids_wanted : (null | Array<_zeitbild.type_calendar_id>),
from_pit : lib_plankton.pit.type_pit,
to_pit : lib_plankton.pit.type_pit,
user_id : _zeitbild.type_user_id
) : Promise<
Array<
type type_gather_events_result = Array<
{
calendar_id : _zeitbild.type_calendar_id;
calendar_name : string;
@ -417,8 +435,17 @@ namespace _zeitbild.service.calendar
event_id : (null | _zeitbild.type_local_resource_event_id);
event_object : _zeitbild.type_event_object;
}
>
>
>;
/**
*/
export async function gather_events(
calendar_ids_wanted : (null | Array<_zeitbild.type_calendar_id>),
from_pit : lib_plankton.pit.type_pit,
to_pit : lib_plankton.pit.type_pit,
user_id : (null | _zeitbild.type_user_id)
) : Promise<type_gather_events_result>
{
const calendar_ids_allowed : Array<_zeitbild.type_calendar_id> = (
(await overview(user_id))
@ -440,7 +467,16 @@ namespace _zeitbild.service.calendar
)
);
calendar_ids.sort();
return (
return lib_plankton.cache.get_complex<any, type_gather_events_result>(
_zeitbild.cache,
"gather_events",
{
"user_id": user_id,
"from_pit": from_pit,
"to_pit": to_pit,
"calendar_ids": calendar_ids,
},
() => (
Promise.all(
calendar_ids
.map(
@ -484,6 +520,7 @@ namespace _zeitbild.service.calendar
[]
)
)
)
);
}

View file

@ -96,6 +96,7 @@ namespace _zeitbild
export type type_calendar_object = {
name : string;
access : {
public : boolean;
default_level : enum_access_level;
attributed : lib_plankton.map.type_map<
type_user_id,

View file

@ -36,6 +36,7 @@ ${dir_temp}/conf.ts: \
${dir_temp}/zeitbild-unlinked.js: \
${dir_lib}/plankton/plankton.d.ts \
${dir_source}/helpers.ts \
${dir_source}/base.ts \
${dir_source}/conf.ts \
${dir_source}/database.ts \
${dir_source}/auth.ts \

View file

@ -10,11 +10,14 @@ modules="${modules} call"
modules="${modules} log"
modules="${modules} conf"
modules="${modules} storage"
modules="${modules} cache"
modules="${modules} database"
modules="${modules} session"
modules="${modules} file"
modules="${modules} string"
modules="${modules} json"
modules="${modules} list"
modules="${modules} order"
modules="${modules} ical"
modules="${modules} url"
modules="${modules} http"