backend/source/database.ts
2024-04-22 21:19:04 +02:00

252 lines
5.3 KiB
TypeScript

namespace _espe.database
{
/**
*/
enum enum_revision {
r0 = 0,
r1 = 1,
}
/**
*/
const _revision_order : Array<enum_revision> = [
enum_revision.r0,
enum_revision.r1,
];
/**
*/
export function get_implementation(
) : lib_plankton.database.type_database
{
switch (_espe.conf.get().database.kind) {
case "sqlite": {
return lib_plankton.database.sqlite_database(
{
"path": _espe.conf.get().database.data["path"],
"verbose": false,
}
);
break;
}
default: {
throw (new Error("database implementation not available: " + _espe.conf.get().database.kind));
}
}
}
/**
*/
function get_revision(
) : Promise<enum_revision>
{
return (
(
get_implementation().query_select(
{
"source": "meta",
"fields": ["revision"],
}
)
.then<int>(
(rows) => Promise.resolve<int>(rows[0]["revision"])
)
.catch<int>(
() => Promise.resolve<int>(0)
)
)
.then<enum_revision>(
(revision_raw) => Promise.resolve<enum_revision>(revision_raw)
)
);
}
/**
*/
async function advance(
) : Promise<boolean>
{
const implementation : lib_plankton.database.type_database = get_implementation();
const revision_current : enum_revision = await get_revision();
const index_current : int = _revision_order.indexOf(revision_current);
const index_next : (null | int) = (
(index_current < (_revision_order.length - 1))
? (index_current + 1)
: null
);
const revision_next : (null | enum_revision) = (
(index_next !== null)
? _revision_order[index_next]
: null
);
if (revision_next !== null) {
lib_plankton.log.notice(
"database_advancement_necessary",
{
"revision_current": revision_current,
"revision_next": revision_next,
}
);
switch (revision_next) {
case enum_revision.r1: {
// structure
{
await implementation.query_create_table(
{
"name": "meta",
"data_fields": [
{
"name": "revision",
"type": lib_plankton.database.enum_type.integer,
"nullable": false,
},
],
}
);
await implementation.query_create_table(
{
"name": "members",
"key_field": {
"name": "id"
},
"data_fields": [
{
"name": "membership_number",
"type": lib_plankton.database.enum_type.string_short,
"nullable": false
},
{
"name": "enabled",
"type": lib_plankton.database.enum_type.boolean,
"nullable": false
},
{
"name": "name_login",
"type": lib_plankton.database.enum_type.string_short,
"nullable": true
},
{
"name": "password_image",
"type": lib_plankton.database.enum_type.string_medium,
"nullable": true
},
{
"name": "name_real_value",
"type": lib_plankton.database.enum_type.string_medium,
"nullable": false
},
{
"name": "name_real_extension",
"type": lib_plankton.database.enum_type.string_short,
"nullable": true
},
{
"name": "name_display",
"type": lib_plankton.database.enum_type.string_medium,
"nullable": true
},
{
"name": "salutation",
"type": lib_plankton.database.enum_type.string_short,
"nullable": true
},
{
"name": "email_address_private_value",
"type": lib_plankton.database.enum_type.string_short,
"nullable": true
},
{
"name": "email_address_numberbased_use",
"type": lib_plankton.database.enum_type.boolean,
"nullable": false
},
{
"name": "email_address_namebased_use",
"type": lib_plankton.database.enum_type.boolean,
"nullable": false
},
{
"name": "email_redirect_to_private",
"type": lib_plankton.database.enum_type.boolean,
"nullable": false
}
],
"constraints": [
{
"kind": "unique",
"parameters": {
"fields": ["membership_number"]
}
},
{
"kind": "unique",
"parameters": {
"fields": ["name_real_value","name_real_extension"]
}
},
{
"kind": "unique",
"parameters": {
"fields": ["name_login"]
}
}
]
}
);
}
// data
{
await implementation.query_insert(
{
"table_name": "meta",
"values": {
"revision": revision_next,
}
}
);
}
return Promise.resolve<boolean>(true);
break;
}
default: {
return Promise.reject<boolean>("unhandled advancement step");
break;
}
}
}
else {
lib_plankton.log.notice(
"database_up_to_date",
{
"revision_current": revision_current,
}
);
return Promise.resolve<boolean>(false);
}
}
/**
*/
export async function advance_all(
) : Promise<void>
{
while (true) {
const modified : boolean = await advance();
if (modified) {
// do nothing
}
else {
break;
}
}
}
}