Files
dashback/src/db/store.js
2026-09-24 23:26:50 +02:00

151 lines
3.9 KiB
JavaScript

import chalk from 'chalk';
import LibDashStore from 'libdashstore';
import { MssqlProvider } from 'libdashstore/providers/mssql';
import { BetterSqlite3Provider } from 'libdashstore/providers/better-sqlite3';
import env from '../config/env.js';
let provider;
let store;
let connecting;
const STORE_NAMESPACES = [
'companyuser',
'company',
'category',
'article',
'pic',
'unit',
'brand',
'lang',
'tax',
'google_auth',
'posterminal',
'supplier',
'delivery',
'customergroup',
'entity',
'entityaddress',
'entitycontact',
'quote',
'order',
'numbers',
'companysetting',
'articlesupplier',
'manifestattachment',
'ledger',
];
/**
* Wraps LibDashStore namespace methods so each call logs its duration.
* @param {InstanceType<typeof LibDashStore>} rawStore
* @returns {InstanceType<typeof LibDashStore>}
*/
function wrapStoreWithTiming(rawStore) {
for (const namespace of STORE_NAMESPACES) {
const api = rawStore[namespace];
if (!api || typeof api !== 'object') continue;
for (const [method, fn] of Object.entries(api)) {
if (typeof fn !== 'function') continue;
api[method] = async (...args) => {
const start = Date.now();
try {
const result = await fn(...args);
console.log(
`${chalk.magenta('libstore')} ${namespace}.${method} ${chalk.gray(`(${Date.now() - start}ms)`)}`
);
return result;
} catch (err) {
console.error(
`${chalk.magenta('libstore')} ${namespace}.${method} ${chalk.red('FAILED')} ` +
`${chalk.gray(`(${Date.now() - start}ms)`)} ${chalk.red(err.message)}`
);
throw err;
}
};
}
}
for (const method of ['purge']) {
const fn = rawStore[method];
if (typeof fn !== 'function') continue;
rawStore[method] = async (...args) => {
const start = Date.now();
try {
return await fn(...args);
} finally {
const duration = Date.now() - start;
console.log(`${chalk.magenta('libstore')} ${method} ${chalk.gray(`(${duration}ms)`)}`);
}
};
}
return rawStore;
}
function getMssqlConfig() {
const { server, database, user, password, port, encrypt, trustServerCertificate } = env.mssql;
if (!server || !database || !user || !password) {
throw new Error('MSSQL is not configured (MSSQL_SERVER, MSSQL_DATABASE, MSSQL_USER, MSSQL_PASSWORD required)');
}
return {
server,
database,
user,
password,
port,
pool: {
max: 10,
min: 0,
idleTimeoutMillis: 30_000,
},
options: {
encrypt,
trustServerCertificate,
},
};
}
/**
* Returns the initialized LibDashStore singleton.
* @returns {Promise<InstanceType<typeof LibDashStore>>}
*/
export async function getStore() {
if (store) {
return store;
}
if (!connecting) {
connecting = (async () => {
if (env.dbProvider === 'sqlite' || env.dbProvider === 'better-sqlite3') {
provider = new BetterSqlite3Provider(env.sqlite);
} else {
provider = new MssqlProvider(getMssqlConfig());
}
await provider.initialize();
store = wrapStoreWithTiming(await new LibDashStore(provider));
return store;
})().finally(() => {
connecting = undefined;
});
}
return connecting;
}
export async function ensureConnection() {
await getStore();
}
export async function closeStore() {
if (provider) {
await provider.close();
provider = undefined;
store = undefined;
}
}