3183 get locale data for categories (#143)
This commit is contained in:
+111
-22
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user