@opengis/fastify-table 1.0.34 → 1.0.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.cjs +42 -42
- package/Changelog.md +105 -101
- package/README.md +26 -26
- package/config.js +12 -12
- package/crud/controllers/deleteCrud.js +14 -14
- package/crud/controllers/insert.js +29 -29
- package/crud/controllers/update.js +31 -31
- package/crud/controllers/utils/checkXSS.js +45 -45
- package/crud/controllers/utils/xssInjection.js +72 -72
- package/crud/funcs/dataDelete.js +15 -15
- package/crud/funcs/dataInsert.js +24 -24
- package/crud/funcs/dataUpdate.js +24 -24
- package/crud/funcs/getOpt.js +10 -10
- package/crud/funcs/getToken.js +27 -27
- package/crud/funcs/isFileExists.js +13 -13
- package/crud/funcs/setOpt.js +16 -16
- package/crud/funcs/setToken.js +53 -53
- package/crud/index.js +29 -29
- package/helper.js +28 -28
- package/index.js +39 -39
- package/notification/controllers/userNotifications.js +19 -19
- package/notification/funcs/addNotification.js +8 -8
- package/notification/index.js +19 -19
- package/package.json +22 -22
- package/pg/funcs/getPG.js +29 -29
- package/pg/pgClients.js +20 -20
- package/policy/funcs/checkPolicy.js +74 -74
- package/policy/funcs/sqlInjection.js +33 -33
- package/policy/index.js +14 -14
- package/redis/client.js +8 -8
- package/redis/funcs/getRedis.js +23 -23
- package/redis/funcs/redisClients.js +2 -2
- package/redis/index.js +19 -19
- package/server/migrations/crm.sql +95 -95
- package/server/migrations/log.sql +41 -41
- package/server/templates/form/test.dataset.form.json +411 -411
- package/server/templates/select/test.storage.data.json +2 -2
- package/server/templates/table/test.dataset.table.json +24 -24
- package/server.js +14 -14
- package/table/controllers/data.js +57 -57
- package/table/controllers/filter.js +37 -32
- package/table/controllers/form.js +10 -10
- package/table/controllers/search.js +41 -41
- package/table/controllers/suggest.js +60 -60
- package/table/controllers/utils/getSelect.js +20 -20
- package/table/controllers/utils/getSelectMeta.js +66 -66
- package/table/controllers/utils/getTemplate.js +28 -28
- package/table/funcs/getFilterSQL/index.js +75 -75
- package/table/funcs/getFilterSQL/util/formatValue.js +142 -142
- package/table/funcs/getFilterSQL/util/getCustomQuery.js +13 -13
- package/table/funcs/getFilterSQL/util/getFilterQuery.js +73 -73
- package/table/funcs/getFilterSQL/util/getOptimizedQuery.js +12 -12
- package/table/funcs/getFilterSQL/util/getTableSql.js +34 -34
- package/table/funcs/metaFormat/getSelectVal.js +20 -20
- package/table/funcs/metaFormat/index.js +26 -26
- package/table/index.js +42 -42
- package/test/api/crud.test.js +56 -56
- package/test/api/crud.xss.test.js +71 -71
- package/test/api/notification.test.js +37 -37
- package/test/api/table.test.js +57 -57
- package/test/api/widget.test.js +114 -114
- package/test/config.example +18 -18
- package/test/funcs/crud.test.js +76 -76
- package/test/funcs/notification.test.js +31 -31
- package/test/funcs/pg.test.js +34 -34
- package/test/funcs/redis.test.js +19 -19
- package/test/templates/cls/test.json +9 -9
- package/test/templates/form/cp_building.form.json +32 -32
- package/test/templates/select/account_id.json +3 -3
- package/test/templates/select/storage.data.json +2 -2
- package/test/templates/table/gis.dataset.table.json +20 -20
- package/widget/controllers/utils/historyFormat.js +76 -76
- package/widget/controllers/utils/obj2db.js +13 -13
- package/widget/controllers/widget.del.js +41 -41
- package/widget/controllers/widget.get.js +77 -77
- package/widget/controllers/widget.set.js +64 -64
- package/widget/index.js +29 -29
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
{
|
|
2
|
-
"key": "dataset_id"
|
|
1
|
+
{
|
|
2
|
+
"key": "dataset_id"
|
|
3
3
|
}
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
{
|
|
2
|
-
"columns": [
|
|
3
|
-
{
|
|
4
|
-
"name": "dataset_id",
|
|
5
|
-
"title": "22"
|
|
6
|
-
},
|
|
7
|
-
{
|
|
8
|
-
"name": "dataset_name",
|
|
9
|
-
"title": "dataset_name"
|
|
10
|
-
}
|
|
11
|
-
],
|
|
12
|
-
"table": "gis.dataset",
|
|
13
|
-
"order": "dataset_name",
|
|
14
|
-
"meta": {
|
|
15
|
-
"title": "dataset_name",
|
|
16
|
-
"search": "dataset_name,dataset_id"
|
|
17
|
-
},
|
|
18
|
-
"filters": [
|
|
19
|
-
{
|
|
20
|
-
"ua": "Назва набору",
|
|
21
|
-
"name": "dataset_name",
|
|
22
|
-
"type": "text"
|
|
23
|
-
}
|
|
24
|
-
]
|
|
1
|
+
{
|
|
2
|
+
"columns": [
|
|
3
|
+
{
|
|
4
|
+
"name": "dataset_id",
|
|
5
|
+
"title": "22"
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
"name": "dataset_name",
|
|
9
|
+
"title": "dataset_name"
|
|
10
|
+
}
|
|
11
|
+
],
|
|
12
|
+
"table": "gis.dataset",
|
|
13
|
+
"order": "dataset_name",
|
|
14
|
+
"meta": {
|
|
15
|
+
"title": "dataset_name",
|
|
16
|
+
"search": "dataset_name,dataset_id"
|
|
17
|
+
},
|
|
18
|
+
"filters": [
|
|
19
|
+
{
|
|
20
|
+
"ua": "Назва набору",
|
|
21
|
+
"name": "dataset_name",
|
|
22
|
+
"type": "text"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
25
|
}
|
package/server.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
// This file contains code that we reuse
|
|
2
|
-
// between our tests.
|
|
3
|
-
import Fastify from 'fastify';
|
|
4
|
-
import config from './test/config.js';
|
|
5
|
-
import appService from './index.js';
|
|
6
|
-
|
|
7
|
-
const app = Fastify({ logger: false });
|
|
8
|
-
app.register(appService, config);
|
|
9
|
-
app.listen({ host: '0.0.0.0', port: process.env.PORT || 3000 }, (err) => {
|
|
10
|
-
if (err) {
|
|
11
|
-
app.log.error(err);
|
|
12
|
-
process.exit(1);
|
|
13
|
-
}
|
|
14
|
-
});
|
|
1
|
+
// This file contains code that we reuse
|
|
2
|
+
// between our tests.
|
|
3
|
+
import Fastify from 'fastify';
|
|
4
|
+
import config from './test/config.js';
|
|
5
|
+
import appService from './index.js';
|
|
6
|
+
|
|
7
|
+
const app = Fastify({ logger: false });
|
|
8
|
+
app.register(appService, config);
|
|
9
|
+
app.listen({ host: '0.0.0.0', port: process.env.PORT || 3000 }, (err) => {
|
|
10
|
+
if (err) {
|
|
11
|
+
app.log.error(err);
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
});
|
|
@@ -1,57 +1,57 @@
|
|
|
1
|
-
import getTemplate from './utils/getTemplate.js';
|
|
2
|
-
import getFilterSQL from '../funcs/getFilterSQL/index.js';
|
|
3
|
-
import getMeta from '../../pg/funcs/getMeta.js';
|
|
4
|
-
import metaFormat from '../funcs/metaFormat/index.js';
|
|
5
|
-
|
|
6
|
-
const maxLimit = 100;
|
|
7
|
-
export default async function data(req) {
|
|
8
|
-
const time = Date.now();
|
|
9
|
-
const {
|
|
10
|
-
pg, params, query = {},
|
|
11
|
-
} = req;
|
|
12
|
-
|
|
13
|
-
const loadTable = await getTemplate('table', params.table);
|
|
14
|
-
|
|
15
|
-
if (!loadTable) { return { status: 404, message: 'not found' }; }
|
|
16
|
-
|
|
17
|
-
const {
|
|
18
|
-
table, columns, sql, filters, form, meta,
|
|
19
|
-
} = loadTable;
|
|
20
|
-
const { pk } = await getMeta(table);
|
|
21
|
-
|
|
22
|
-
const cols = columns.map((el) => el.name || el).join(',');
|
|
23
|
-
const sqlTable = sql?.filter?.((el) => !el?.disabled && el?.sql?.replace).map((el, i) => ` left join lateral (${el.sql}) ${el.name || `t${i}`} on 1=1 `)?.join('') || '';
|
|
24
|
-
|
|
25
|
-
const fData = query.filter ? await getFilterSQL({
|
|
26
|
-
filter: query.filter,
|
|
27
|
-
table: params.table,
|
|
28
|
-
json: 1,
|
|
29
|
-
}) : {};
|
|
30
|
-
|
|
31
|
-
const keyQuery = query.key && loadTable.key && !params.id ? `${loadTable.key}=$1` : null;
|
|
32
|
-
|
|
33
|
-
const limit = Math.min(maxLimit, +(query.limit || 10));
|
|
34
|
-
|
|
35
|
-
const offset = query.page && query.page > 0 ? ` offset ${(query.page - 1) * limit}` : '';
|
|
36
|
-
// id, query, filter
|
|
37
|
-
const [orderColumn, orderDir] = (query.order || loadTable.order || '').split('-');
|
|
38
|
-
|
|
39
|
-
const order = cols.includes(orderColumn) && orderColumn?.length ? `order by ${orderColumn} ${query.desc || orderDir === 'desc' ? 'desc' : ''}` : '';
|
|
40
|
-
const state = loadTable.filterState && query.state ? loadTable.filterState[query.state]?.sql : null;
|
|
41
|
-
const custom = loadTable.filterCustom && query.custom ? loadTable.filterCustom[query.custom]?.sql : null;
|
|
42
|
-
const search = loadTable.meta?.search && query.search ? `(${loadTable.meta?.search.split(',').map(el => `${el} ilike '%${query.search}%'`).join(' or ')})` : null;
|
|
43
|
-
|
|
44
|
-
const where = [(params.id ? ` "${pk}" = $1` : null), keyQuery, loadTable.query, fData.q, state, custom, search].filter((el) => el);
|
|
45
|
-
const q = `select ${pk ? `"${pk}" as id,` : ''} ${query.id || query.key ? '*' : cols || '*'} from ${table} t ${sqlTable} where ${where.join(' and ') || 'true'} ${order} ${offset} limit ${limit}`;
|
|
46
|
-
|
|
47
|
-
if (query.sql === '1') { return q; }
|
|
48
|
-
|
|
49
|
-
const { rows } = await pg.query(q, (params.id ? [params.id] : null) || (query.key && loadTable.key ? [query.key] : []));
|
|
50
|
-
|
|
51
|
-
const total = keyQuery || params.id ? rows.length : await pg.queryCache(`select count(*) from ${table} t where ${where.join(' and ') || 'true'}`).then((el) => el?.rows[0]?.count);
|
|
52
|
-
|
|
53
|
-
await metaFormat({ rows, table: params.table });
|
|
54
|
-
return {
|
|
55
|
-
time: Date.now() - time, total, count: rows.length, pk, form, rows, meta, columns, filters,
|
|
56
|
-
};
|
|
57
|
-
}
|
|
1
|
+
import getTemplate from './utils/getTemplate.js';
|
|
2
|
+
import getFilterSQL from '../funcs/getFilterSQL/index.js';
|
|
3
|
+
import getMeta from '../../pg/funcs/getMeta.js';
|
|
4
|
+
import metaFormat from '../funcs/metaFormat/index.js';
|
|
5
|
+
|
|
6
|
+
const maxLimit = 100;
|
|
7
|
+
export default async function data(req) {
|
|
8
|
+
const time = Date.now();
|
|
9
|
+
const {
|
|
10
|
+
pg, params, query = {},
|
|
11
|
+
} = req;
|
|
12
|
+
|
|
13
|
+
const loadTable = await getTemplate('table', params.table);
|
|
14
|
+
|
|
15
|
+
if (!loadTable) { return { status: 404, message: 'not found' }; }
|
|
16
|
+
|
|
17
|
+
const {
|
|
18
|
+
table, columns, sql, filters, form, meta,
|
|
19
|
+
} = loadTable;
|
|
20
|
+
const { pk } = await getMeta(table);
|
|
21
|
+
|
|
22
|
+
const cols = columns.map((el) => el.name || el).join(',');
|
|
23
|
+
const sqlTable = sql?.filter?.((el) => !el?.disabled && el?.sql?.replace).map((el, i) => ` left join lateral (${el.sql}) ${el.name || `t${i}`} on 1=1 `)?.join('') || '';
|
|
24
|
+
|
|
25
|
+
const fData = query.filter ? await getFilterSQL({
|
|
26
|
+
filter: query.filter,
|
|
27
|
+
table: params.table,
|
|
28
|
+
json: 1,
|
|
29
|
+
}) : {};
|
|
30
|
+
|
|
31
|
+
const keyQuery = query.key && loadTable.key && !params.id ? `${loadTable.key}=$1` : null;
|
|
32
|
+
|
|
33
|
+
const limit = Math.min(maxLimit, +(query.limit || 10));
|
|
34
|
+
|
|
35
|
+
const offset = query.page && query.page > 0 ? ` offset ${(query.page - 1) * limit}` : '';
|
|
36
|
+
// id, query, filter
|
|
37
|
+
const [orderColumn, orderDir] = (query.order || loadTable.order || '').split('-');
|
|
38
|
+
|
|
39
|
+
const order = cols.includes(orderColumn) && orderColumn?.length ? `order by ${orderColumn} ${query.desc || orderDir === 'desc' ? 'desc' : ''}` : '';
|
|
40
|
+
const state = loadTable.filterState && query.state ? loadTable.filterState[query.state]?.sql : null;
|
|
41
|
+
const custom = loadTable.filterCustom && query.custom ? loadTable.filterCustom[query.custom]?.sql : null;
|
|
42
|
+
const search = loadTable.meta?.search && query.search ? `(${loadTable.meta?.search.split(',').map(el => `${el} ilike '%${query.search}%'`).join(' or ')})` : null;
|
|
43
|
+
|
|
44
|
+
const where = [(params.id ? ` "${pk}" = $1` : null), keyQuery, loadTable.query, fData.q, state, custom, search].filter((el) => el);
|
|
45
|
+
const q = `select ${pk ? `"${pk}" as id,` : ''} ${query.id || query.key ? '*' : cols || '*'} from ${table} t ${sqlTable} where ${where.join(' and ') || 'true'} ${order} ${offset} limit ${limit}`;
|
|
46
|
+
|
|
47
|
+
if (query.sql === '1') { return q; }
|
|
48
|
+
|
|
49
|
+
const { rows } = await pg.query(q, (params.id ? [params.id] : null) || (query.key && loadTable.key ? [query.key] : []));
|
|
50
|
+
|
|
51
|
+
const total = keyQuery || params.id ? rows.length : await pg.queryCache(`select count(*) from ${table} t where ${where.join(' and ') || 'true'}`).then((el) => el?.rows[0]?.count);
|
|
52
|
+
|
|
53
|
+
await metaFormat({ rows, table: params.table });
|
|
54
|
+
return {
|
|
55
|
+
time: Date.now() - time, total, count: rows.length, pk, form, rows, meta, columns, filters,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
@@ -1,32 +1,37 @@
|
|
|
1
|
-
import getTemplate from './utils/getTemplate.js';
|
|
2
|
-
import getSelect from './utils/getSelect.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
1
|
+
import getTemplate from './utils/getTemplate.js';
|
|
2
|
+
import getSelect from './utils/getSelect.js';
|
|
3
|
+
import getMeta from '../../pg/funcs/getMeta.js';
|
|
4
|
+
|
|
5
|
+
export default async function filter(req) {
|
|
6
|
+
const time = Date.now();
|
|
7
|
+
|
|
8
|
+
const {
|
|
9
|
+
params,
|
|
10
|
+
} = req;
|
|
11
|
+
const loadTable = await getTemplate('table', params.table);
|
|
12
|
+
if (!loadTable) { return { status: 404, message: 'not found' }; }
|
|
13
|
+
const { columns } = await getMeta({ table: loadTable.table });
|
|
14
|
+
|
|
15
|
+
const filters = loadTable?.filters || loadTable?.filterList || [];
|
|
16
|
+
await Promise.all(filters.filter((el) => el.data).map(async (el) => {
|
|
17
|
+
const cls = await getSelect(el.data);
|
|
18
|
+
if (!cls?.arr || !loadTable.table) return;
|
|
19
|
+
const { dataTypeID } = columns.find((item) => item.name === el.id) || {};
|
|
20
|
+
const countArr = req.pg.pgType[dataTypeID]?.includes('[]')
|
|
21
|
+
? await req.pg.queryCache(`select unnest(${el.id})::text as id,count(*) from ${loadTable.table} group by unnest(${el.id})`)
|
|
22
|
+
: await req.pg.queryCache(`select ${el.id}::text as id,count(*) from ${loadTable.table} group by ${el.id}`);
|
|
23
|
+
|
|
24
|
+
const options = countArr.rows.map(cel => {
|
|
25
|
+
const data = cls?.arr.find(c => c.id === cel.id);
|
|
26
|
+
return { ...cel, ...data };
|
|
27
|
+
});
|
|
28
|
+
Object.assign(el, { options });
|
|
29
|
+
}));
|
|
30
|
+
return {
|
|
31
|
+
time: Date.now() - time,
|
|
32
|
+
list: filters,
|
|
33
|
+
custom: loadTable?.filterCustom?.map(el => ({ label: el.label })),
|
|
34
|
+
inline: loadTable?.filterInline,
|
|
35
|
+
state: loadTable?.filterState?.map(el => ({ label: el.label })),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import getTemplate from './utils/getTemplate.js';
|
|
2
|
-
|
|
3
|
-
export default async function formFunction(req) {
|
|
4
|
-
const time = Date.now();
|
|
5
|
-
const { params } = req;
|
|
6
|
-
const form = await getTemplate('form', params.form);
|
|
7
|
-
if (!form) { return { status: 404, message: 'not found' }; }
|
|
8
|
-
|
|
9
|
-
return { time: Date.now() - time, form };
|
|
10
|
-
}
|
|
1
|
+
import getTemplate from './utils/getTemplate.js';
|
|
2
|
+
|
|
3
|
+
export default async function formFunction(req) {
|
|
4
|
+
const time = Date.now();
|
|
5
|
+
const { params } = req;
|
|
6
|
+
const form = await getTemplate('form', params.form);
|
|
7
|
+
if (!form) { return { status: 404, message: 'not found' }; }
|
|
8
|
+
|
|
9
|
+
return { time: Date.now() - time, form };
|
|
10
|
+
}
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
import getTemplate from './utils/getTemplate.js';
|
|
2
|
-
import getMeta from '../../pg/funcs/getMeta.js';
|
|
3
|
-
import metaFormat from '../funcs/metaFormat/index.js';
|
|
4
|
-
|
|
5
|
-
const maxLimit = 100;
|
|
6
|
-
|
|
7
|
-
export default async function data({
|
|
8
|
-
pg, query = {},
|
|
9
|
-
}) {
|
|
10
|
-
const time = Date.now();
|
|
11
|
-
|
|
12
|
-
const loadTable = await getTemplate('table', query.table);
|
|
13
|
-
|
|
14
|
-
if (!loadTable) { return { message: 'not found', status: 404 }; }
|
|
15
|
-
|
|
16
|
-
const { table, columns, meta } = loadTable;
|
|
17
|
-
const { pk } = await getMeta(table);
|
|
18
|
-
|
|
19
|
-
const cols = columns.map((el) => el.name || el).join(',');
|
|
20
|
-
const [orderColumn, orderDir] = (query.order || loadTable.order || '').split('-');
|
|
21
|
-
const order = cols.includes(orderColumn) && orderColumn?.length ? `order by ${orderColumn} ${query.desc || orderDir === 'desc' ? 'desc' : ''}` : '';
|
|
22
|
-
|
|
23
|
-
const limit = Math.min(maxLimit, +(query.limit || 10));
|
|
24
|
-
const offset = query.page && query.page > 0 ? ` offset ${(query.page - 1) * limit}` : '';
|
|
25
|
-
|
|
26
|
-
const search = meta?.search && query.key ? `(${meta?.search.concat(meta?.title ? `,${meta?.title}` : '').split(',').map(el => `${el} ilike '%${query.key}%'`).join(' or ')})` : null;
|
|
27
|
-
|
|
28
|
-
const where = [loadTable.query, search].filter((el) => el);
|
|
29
|
-
const q = `select ${pk ? `"${pk}" as id,` : ''} * from ${table} t where ${where.join(' and ') || 'true'} ${order} ${offset} limit ${limit}`;
|
|
30
|
-
|
|
31
|
-
if (query.sql === '1') return q;
|
|
32
|
-
|
|
33
|
-
const { rows } = await pg.query(q);
|
|
34
|
-
|
|
35
|
-
const total = await pg.queryCache(`select count(*) from ${table} t where ${where.join(' and ') || 'true'}`).then((el) => el?.rows[0]?.count);
|
|
36
|
-
|
|
37
|
-
await metaFormat({ rows, table: query.table });
|
|
38
|
-
return {
|
|
39
|
-
time: Date.now() - time, total, count: rows.length, rows,
|
|
40
|
-
};
|
|
41
|
-
}
|
|
1
|
+
import getTemplate from './utils/getTemplate.js';
|
|
2
|
+
import getMeta from '../../pg/funcs/getMeta.js';
|
|
3
|
+
import metaFormat from '../funcs/metaFormat/index.js';
|
|
4
|
+
|
|
5
|
+
const maxLimit = 100;
|
|
6
|
+
|
|
7
|
+
export default async function data({
|
|
8
|
+
pg, query = {},
|
|
9
|
+
}) {
|
|
10
|
+
const time = Date.now();
|
|
11
|
+
|
|
12
|
+
const loadTable = await getTemplate('table', query.table);
|
|
13
|
+
|
|
14
|
+
if (!loadTable) { return { message: 'not found', status: 404 }; }
|
|
15
|
+
|
|
16
|
+
const { table, columns, meta } = loadTable;
|
|
17
|
+
const { pk } = await getMeta(table);
|
|
18
|
+
|
|
19
|
+
const cols = columns.map((el) => el.name || el).join(',');
|
|
20
|
+
const [orderColumn, orderDir] = (query.order || loadTable.order || '').split('-');
|
|
21
|
+
const order = cols.includes(orderColumn) && orderColumn?.length ? `order by ${orderColumn} ${query.desc || orderDir === 'desc' ? 'desc' : ''}` : '';
|
|
22
|
+
|
|
23
|
+
const limit = Math.min(maxLimit, +(query.limit || 10));
|
|
24
|
+
const offset = query.page && query.page > 0 ? ` offset ${(query.page - 1) * limit}` : '';
|
|
25
|
+
|
|
26
|
+
const search = meta?.search && query.key ? `(${meta?.search.concat(meta?.title ? `,${meta?.title}` : '').split(',').map(el => `${el} ilike '%${query.key}%'`).join(' or ')})` : null;
|
|
27
|
+
|
|
28
|
+
const where = [loadTable.query, search].filter((el) => el);
|
|
29
|
+
const q = `select ${pk ? `"${pk}" as id,` : ''} * from ${table} t where ${where.join(' and ') || 'true'} ${order} ${offset} limit ${limit}`;
|
|
30
|
+
|
|
31
|
+
if (query.sql === '1') return q;
|
|
32
|
+
|
|
33
|
+
const { rows } = await pg.query(q);
|
|
34
|
+
|
|
35
|
+
const total = await pg.queryCache(`select count(*) from ${table} t where ${where.join(' and ') || 'true'}`).then((el) => el?.rows[0]?.count);
|
|
36
|
+
|
|
37
|
+
await metaFormat({ rows, table: query.table });
|
|
38
|
+
return {
|
|
39
|
+
time: Date.now() - time, total, count: rows.length, rows,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
import getSelectMeta from './utils/getSelectMeta.js';
|
|
2
|
-
import getPG from '../../pg/funcs/getPG.js';
|
|
3
|
-
|
|
4
|
-
const limit = 50;
|
|
5
|
-
const headers = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET', 'Cache-Control': 'no-cache' };
|
|
6
|
-
|
|
7
|
-
export default async function suggest(req) {
|
|
8
|
-
const { params, query, pg: pg1 } = req;
|
|
9
|
-
|
|
10
|
-
const lang = query.lang || 'ua';
|
|
11
|
-
const time = Date.now();
|
|
12
|
-
const parent = query.parent || '';
|
|
13
|
-
|
|
14
|
-
const selectName = query.sel || query.name || params.data;
|
|
15
|
-
if (!selectName) return { headers, status: 400, message: 'name is required' };
|
|
16
|
-
|
|
17
|
-
const meta = await getSelectMeta({ name: selectName });
|
|
18
|
-
const pg = meta.db ? getPG({ db: meta.db }) : pg1;
|
|
19
|
-
if (!meta) return { headers, status: 404, message: 'Not found query select ' };
|
|
20
|
-
|
|
21
|
-
const { arr, searchQuery } = meta;
|
|
22
|
-
|
|
23
|
-
if (arr) {
|
|
24
|
-
const lower = query.key?.toLowerCase();
|
|
25
|
-
const data = query.key || query.val
|
|
26
|
-
? arr?.filter((el) => !lower || (el[lang] || el.text)?.toLowerCase()?.indexOf(lower) !== -1)?.filter((el) => !query.val || el.id === query.val)
|
|
27
|
-
: arr;
|
|
28
|
-
return {
|
|
29
|
-
limit, count: data.length, mode: 'array', time: Date.now() - time, data,
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// search
|
|
34
|
-
const search = query.key ? searchQuery : null;
|
|
35
|
-
|
|
36
|
-
// val
|
|
37
|
-
const pk = meta.originalCols.split(',')[0];
|
|
38
|
-
const val = query.val ? ` ${pk}=any('{${query.val.replace(/'/g, "''")}}')` : '';
|
|
39
|
-
|
|
40
|
-
const sqlSuggest = `with rows(id,text) as (${meta.original.replace(/{{parent}}/gi, parent)} where ${[search, val].filter((el) => el).join(' and ') || 'true'}) select * from rows limit ${limit}`;
|
|
41
|
-
if (query.sql) return sqlSuggest;
|
|
42
|
-
|
|
43
|
-
// query
|
|
44
|
-
const { rows: dataNew } = meta.searchColumn ? { rows: [] } : await pg.query(sqlSuggest, query.key ? [`${query.key}%`] : []);
|
|
45
|
-
const { rows: dataNew1 } = dataNew.length < limit ? await pg.query(sqlSuggest, query.key ? [`%${query.key}%`] : []) : {};
|
|
46
|
-
const ids = dataNew.map((el) => el.id);
|
|
47
|
-
const data = dataNew.concat((dataNew1 || []).filter((el) => !ids?.includes(el.id)));
|
|
48
|
-
|
|
49
|
-
const message = {
|
|
50
|
-
time: Date.now() - time,
|
|
51
|
-
count: data.length,
|
|
52
|
-
total: meta.count - 0,
|
|
53
|
-
mode: 'sql',
|
|
54
|
-
db: meta.db,
|
|
55
|
-
sql: sqlSuggest,
|
|
56
|
-
data,
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
return message;
|
|
60
|
-
}
|
|
1
|
+
import getSelectMeta from './utils/getSelectMeta.js';
|
|
2
|
+
import getPG from '../../pg/funcs/getPG.js';
|
|
3
|
+
|
|
4
|
+
const limit = 50;
|
|
5
|
+
const headers = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET', 'Cache-Control': 'no-cache' };
|
|
6
|
+
|
|
7
|
+
export default async function suggest(req) {
|
|
8
|
+
const { params, query, pg: pg1 } = req;
|
|
9
|
+
|
|
10
|
+
const lang = query.lang || 'ua';
|
|
11
|
+
const time = Date.now();
|
|
12
|
+
const parent = query.parent || '';
|
|
13
|
+
|
|
14
|
+
const selectName = query.sel || query.name || params.data;
|
|
15
|
+
if (!selectName) return { headers, status: 400, message: 'name is required' };
|
|
16
|
+
|
|
17
|
+
const meta = await getSelectMeta({ name: selectName });
|
|
18
|
+
const pg = meta.db ? getPG({ db: meta.db }) : pg1;
|
|
19
|
+
if (!meta) return { headers, status: 404, message: 'Not found query select ' };
|
|
20
|
+
|
|
21
|
+
const { arr, searchQuery } = meta;
|
|
22
|
+
|
|
23
|
+
if (arr) {
|
|
24
|
+
const lower = query.key?.toLowerCase();
|
|
25
|
+
const data = query.key || query.val
|
|
26
|
+
? arr?.filter((el) => !lower || (el[lang] || el.text)?.toLowerCase()?.indexOf(lower) !== -1)?.filter((el) => !query.val || el.id === query.val)
|
|
27
|
+
: arr;
|
|
28
|
+
return {
|
|
29
|
+
limit, count: data.length, mode: 'array', time: Date.now() - time, data,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// search
|
|
34
|
+
const search = query.key ? searchQuery : null;
|
|
35
|
+
|
|
36
|
+
// val
|
|
37
|
+
const pk = meta.originalCols.split(',')[0];
|
|
38
|
+
const val = query.val ? ` ${pk}=any('{${query.val.replace(/'/g, "''")}}')` : '';
|
|
39
|
+
|
|
40
|
+
const sqlSuggest = `with rows(id,text) as (${meta.original.replace(/{{parent}}/gi, parent)} where ${[search, val].filter((el) => el).join(' and ') || 'true'}) select * from rows limit ${limit}`;
|
|
41
|
+
if (query.sql) return sqlSuggest;
|
|
42
|
+
|
|
43
|
+
// query
|
|
44
|
+
const { rows: dataNew } = meta.searchColumn ? { rows: [] } : await pg.query(sqlSuggest, query.key ? [`${query.key}%`] : []);
|
|
45
|
+
const { rows: dataNew1 } = dataNew.length < limit ? await pg.query(sqlSuggest, query.key ? [`%${query.key}%`] : []) : {};
|
|
46
|
+
const ids = dataNew.map((el) => el.id);
|
|
47
|
+
const data = dataNew.concat((dataNew1 || []).filter((el) => !ids?.includes(el.id)));
|
|
48
|
+
|
|
49
|
+
const message = {
|
|
50
|
+
time: Date.now() - time,
|
|
51
|
+
count: data.length,
|
|
52
|
+
total: meta.count - 0,
|
|
53
|
+
mode: 'sql',
|
|
54
|
+
db: meta.db,
|
|
55
|
+
sql: sqlSuggest,
|
|
56
|
+
data,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
return message;
|
|
60
|
+
}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import getTemplate from './getTemplate.js';
|
|
2
|
-
|
|
3
|
-
const loadCls = {};
|
|
4
|
-
|
|
5
|
-
export default async function getTable(name) {
|
|
6
|
-
if (loadCls[name]) return loadCls[name];
|
|
7
|
-
|
|
8
|
-
const clsData = await getTemplate('cls', name);
|
|
9
|
-
|
|
10
|
-
if (clsData) {
|
|
11
|
-
loadCls[name] = { arr: clsData };
|
|
12
|
-
return loadCls[name];
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const selectData = await getTemplate('select', name);
|
|
16
|
-
if (!selectData) { return null; }
|
|
17
|
-
|
|
18
|
-
loadCls[name] = selectData;
|
|
19
|
-
return loadCls[name];
|
|
20
|
-
}
|
|
1
|
+
import getTemplate from './getTemplate.js';
|
|
2
|
+
|
|
3
|
+
const loadCls = {};
|
|
4
|
+
|
|
5
|
+
export default async function getTable(name) {
|
|
6
|
+
if (loadCls[name]) return loadCls[name];
|
|
7
|
+
|
|
8
|
+
const clsData = await getTemplate('cls', name);
|
|
9
|
+
|
|
10
|
+
if (clsData) {
|
|
11
|
+
loadCls[name] = { arr: clsData };
|
|
12
|
+
return loadCls[name];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const selectData = await getTemplate('select', name);
|
|
16
|
+
if (!selectData) { return null; }
|
|
17
|
+
|
|
18
|
+
loadCls[name] = selectData;
|
|
19
|
+
return loadCls[name];
|
|
20
|
+
}
|