3183 get locale data for categories (#143)

This commit is contained in:
Anders Gustafsson
2023-02-24 09:24:52 +01:00
committed by GitHub
parent 0a26a3143e
commit 74f89e9934
6 changed files with 135 additions and 26 deletions
+111 -22
View File
@@ -1,12 +1,47 @@
import DataLoader from 'dataloader';
import { ScopeAccess, Scopes } from '../cognito/access-control';
import { Category } from '../types/category-types';
import { Category, CategoryLocaleData } from '../types/category-types';
import { DataSourceOptions } from '../types/types';
import { BaseSQLDataSource } from './BaseSQLDataSource';
import { MINUTE } from './utils';
import { createQuestionMarksFromList, MINUTE } from './utils';
export class CategoryAPI extends BaseSQLDataSource {
private categoryLoader: DataLoader<number, Category>;
private localeDataLoader: DataLoader<number, CategoryLocaleData[]>;
private localeNamesLoader: DataLoader<number, JSON>;
constructor(options: DataSourceOptions, config) {
super(options, config);
this.categoryLoader = new DataLoader(async (keys: number[]) => {
const categoriesResult = await this.getCategories(keys);
return keys.map(
(key) =>
categoriesResult.find(
(categoryResult) => categoryResult.id === key,
) ?? null,
);
});
this.localeDataLoader = new DataLoader(async (keys: number[]) => {
const localeDataResults = await this.getLocaleDataForIds(keys);
return keys.map(
(key) =>
localeDataResults.filter(
(localeDataResult) => localeDataResult.id === key,
) ?? null,
);
});
this.localeNamesLoader = new DataLoader(async (keys: number[]) => {
const localeNameResults = await this.getLocaleNameForIds(keys);
return keys.map((key) => {
const row =
localeNameResults.find(
(localeDataResult) => localeDataResult.id === key,
) ?? null;
return row?.locale_names;
});
});
}
async getProductCategories(productId: number): Promise<Array<Category>> {
@@ -30,10 +65,30 @@ WHERE product_category.product_id = ?
return res;
}
async getCategories(): Promise<Array<Category>> {
ScopeAccess.validate(this.user).all([Scopes.CATEGORIES_READ]);
// @ts-ignore
return this.knex.select('*').from('v_categorytree').cache(MINUTE);
async getCategoryById(id: number): Promise<Category> {
// Dataloaders does not need scopes validation since they
// use other functions.
return this.categoryLoader.load(id);
}
async getCategories(ids: number[]): Promise<Array<Category>> {
ScopeAccess.validate(this.user).some([
Scopes.CATEGORIES_READ,
Scopes.CATEGORIES_PUBLIC_READ,
]);
return (
this.knex
.select('*')
.modify((queryBuilder) => {
if (ids) {
queryBuilder.whereIn('id', ids);
}
})
.from('v_categorytree')
// @ts-ignore
.cache(MINUTE)
);
}
async searchCategories(name: string): Promise<Array<Category>> {
@@ -44,29 +99,63 @@ WHERE product_category.product_id = ?
.whereRaw(`LOWER(name) LIKE ?`, [`${name}`]);
}
async getCategoryById(id: number): Promise<Category> {
ScopeAccess.validate(this.user).all([Scopes.CATEGORIES_READ]);
return (
this.knex
.select('*')
.from('v_categorytree')
.where('id', id)
.first()
// @ts-ignore
.cache(MINUTE)
);
async getLocaleNameForId(id: number): Promise<JSON> {
// Dataloaders does not need scopes validation since they
// use other functions.
return this.localeNamesLoader.load(id);
}
async getLocaleNameForId(id: number): Promise<JSON> {
ScopeAccess.validate(this.user).all([Scopes.LOCALES_READ]);
async getLocaleNameForIds(
ids: number[],
): Promise<{ id: number; locale_names: JSON }[]> {
ScopeAccess.validate(this.user).all([
Scopes.CATEGORIES_READ,
Scopes.LOCALES_READ,
]);
const res = await this.cachedRaw(
'SELECT json_object_agg(ec.locale, ec.name) as locale_names FROM v_esales_categorytree_i18n ec WHERE ec.id = ?',
[id],
`SELECT id, json_object_agg(locale, name) as locale_names FROM v_esales_categorytree_i18n WHERE id IN (${createQuestionMarksFromList(
ids,
)}) GROUP BY id`,
ids,
)
.cache(MINUTE * 5)
.then((data) => data.rows);
return res;
}
return res[0].locale_names;
async getLocaleDataForId(
id: number,
locale?: string,
): Promise<CategoryLocaleData[]> {
// Dataloaders does not need scopes validation since they
// use other functions.
const res = await this.localeDataLoader.load(id);
if (locale) {
return res.filter((row) => row.locale === locale);
}
return res;
}
async getLocaleDataForIds(
ids: number[],
locale?: string,
): Promise<CategoryLocaleData[]> {
ScopeAccess.validate(this.user).some([
Scopes.LOCALES_READ,
Scopes.CATEGORIES_PUBLIC_READ,
]);
const res = await this.cachedRaw(
`SELECT ec.id, ec.locale, getSafeXmlPath(ec.path, 2) as path, ec.name FROM v_esales_categorytree_i18n ec WHERE ec.id IN (${createQuestionMarksFromList(
ids,
)})`,
ids,
)
.cache(MINUTE * 5)
.then((data) => data.rows);
if (locale) {
return res.filter((row) => row.locale === locale);
}
return res;
}
/**