This commit is contained in:
seb
2026-07-31 00:08:50 +02:00
parent 93e52cd513
commit 6bdac7e543
17 changed files with 520 additions and 24 deletions

30
src/index.js Normal file
View File

@@ -0,0 +1,30 @@
import companyuserGetByEmail from './store/companyuser/getByEmail.js';
import companyGetByCompanyUserId from './store/company/getByCompanyUserId.js';
import categoryGetTree from './store/category/getTree.js';
import storePurge from './store/purge.js';
import storeInitialize from './store/initialize.js';
export default class LibDashStore {
constructor(pool) {
this.pool = pool;
this.companyuser = {
getByEmail: companyuserGetByEmail(pool),
};
this.company = {
getByCompanyUserId: companyGetByCompanyUserId(pool),
};
this.category = {
getTree: categoryGetTree(pool),
};
this.purge = storePurge(pool);
this.initialize = storeInitialize(pool);
return this.initialize().then(() => this);
}
}
export { SCHEMA_SCRIPTS } from './schema.js';

View File

@@ -487,9 +487,10 @@ export const INIT_COMPANYUSER = `
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'companyuser')
BEGIN
CREATE TABLE companyuser (
id INT IDENTITY(1,1) PRIMARY KEY,
google_auth_id INT NOT NULL,
company_id INT NOT NULL,
CONSTRAINT PK_companyuser PRIMARY KEY (google_auth_id, company_id),
CONSTRAINT UQ_companyuser_google_auth_company UNIQUE (google_auth_id, company_id),
CONSTRAINT FK_companyuser_google_auth FOREIGN KEY (google_auth_id) REFERENCES google_auth(id) ON DELETE CASCADE,
CONSTRAINT FK_companyuser_company FOREIGN KEY (company_id) REFERENCES company(id) ON DELETE CASCADE
);

16
src/sql/category.js Normal file
View File

@@ -0,0 +1,16 @@
export const GET_TREE = `
WITH tree AS (
SELECT id, parent_id, sort
FROM category
WHERE id = @rootId
UNION ALL
SELECT c.id, c.parent_id, c.sort
FROM category c
INNER JOIN tree t ON c.parent_id = t.id
)
SELECT id, parent_id, sort
FROM tree
ORDER BY sort, id
`;

10
src/sql/company.js Normal file
View File

@@ -0,0 +1,10 @@
export const GET_BY_COMPANY_USER_ID = `
SELECT
c.id,
c.default_language_id,
c.root_category_id,
c.name
FROM company c
INNER JOIN companyuser cu ON cu.company_id = c.id
WHERE cu.id = @companyUserId
`;

6
src/sql/companyuser.js Normal file
View File

@@ -0,0 +1,6 @@
export const GET_BY_EMAIL = `
SELECT cu.id
FROM companyuser cu
INNER JOIN google_auth ga ON ga.id = cu.google_auth_id
WHERE ga.email = @email
`;

49
src/sql/purge.js Normal file
View File

@@ -0,0 +1,49 @@
/** Drop order = reverse of schema create dependency order. */
export const TABLES = [
'companyuser',
'numbers',
'manifestarticle',
'manifest',
'price',
'articletext',
'categorytext',
'categorypic',
'categoryarticle',
'optionslistarticle',
'articlelistarticle',
'brandpic',
'articlepic',
'articleean',
'articlehistory',
'article',
'brand',
'articlelist',
'optionslist',
'unittext',
'unit',
'entity',
'customergroup',
'company',
'pic',
'category',
'tax',
'language',
'google_auth',
'meta',
];
export const PROCEDURES = ['getnextnumberwithprefixandpadding'];
export function buildPurgeSql() {
const drops = [
...PROCEDURES.map(
(name) =>
`IF OBJECT_ID(N'dbo.${name}', N'P') IS NOT NULL DROP PROCEDURE dbo.[${name}];`,
),
...TABLES.map(
(name) =>
`IF OBJECT_ID(N'dbo.${name}', N'U') IS NOT NULL DROP TABLE dbo.[${name}];`,
),
];
return drops.join('\n');
}

View File

@@ -0,0 +1,38 @@
import sql from 'mssql';
import { GET_TREE } from '../../sql/category.js';
function buildTree(rows, rootId) {
const byId = new Map();
for (const row of rows) {
byId.set(row.id, {
id: row.id,
parent_id: row.parent_id,
sort: row.sort,
children: [],
});
}
let root = null;
for (const node of byId.values()) {
if (node.id === rootId) {
root = node;
continue;
}
const parent = byId.get(node.parent_id);
if (parent) parent.children.push(node);
}
return root;
}
export default function getTree(pool) {
return async (rootId) => {
const result = await pool
.request()
.input('rootId', sql.Int, rootId)
.query(GET_TREE);
if (result.recordset.length === 0) return null;
return buildTree(result.recordset, rootId);
};
}

View File

@@ -0,0 +1,16 @@
import sql from 'mssql';
import { GET_BY_COMPANY_USER_ID } from '../../sql/company.js';
export default function getByCompanyUserId(pool) {
return async (companyUserId) => {
const result = await pool
.request()
.input('companyUserId', sql.Int, companyUserId)
.query(GET_BY_COMPANY_USER_ID);
const row = result.recordset[0];
if (!row) return null;
return [row.id, row.default_language_id, row.root_category_id, row.name];
};
}

View File

@@ -0,0 +1,13 @@
import sql from 'mssql';
import { GET_BY_EMAIL } from '../../sql/companyuser.js';
export default function getByEmail(pool) {
return async (email) => {
const result = await pool
.request()
.input('email', sql.NVarChar(320), email)
.query(GET_BY_EMAIL);
return result.recordset[0]?.id ?? null;
};
}

12
src/store/initialize.js Normal file
View File

@@ -0,0 +1,12 @@
import { SCHEMA_SCRIPTS } from '../schema.js';
import purge from './purge.js';
export default function initialize(pool) {
const doPurge = purge(pool);
return async () => {
await doPurge();
for (const script of SCHEMA_SCRIPTS) {
await pool.request().query(script);
}
};
}

7
src/store/purge.js Normal file
View File

@@ -0,0 +1,7 @@
import { buildPurgeSql } from '../sql/purge.js';
export default function purge(pool) {
return async () => {
await pool.request().query(buildPurgeSql());
};
}