160 lines
4.1 KiB
JavaScript
160 lines
4.1 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',
|
|
'warehouse',
|
|
'printer',
|
|
'labeltemplate',
|
|
'stock',
|
|
'propertyname',
|
|
'articleproperty',
|
|
'attributename',
|
|
'attributevalue',
|
|
'articleattributevalue',
|
|
];
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
}
|