@opengis/fastify-table 1.2.69 → 1.2.71
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/package.json +1 -1
- package/server/plugins/pg/funcs/init.js +2 -1
- package/server/plugins/table/funcs/getFilterSQL/index.js +7 -6
- package/server/plugins/table/funcs/metaFormat/getSelectVal.js +3 -1
- package/server/routes/crud/controllers/table.js +92 -92
- package/server/routes/table/controllers/data.js +22 -12
- package/server/routes/table/controllers/filter.js +6 -23
package/package.json
CHANGED
|
@@ -70,7 +70,7 @@ async function init(client) {
|
|
|
70
70
|
|
|
71
71
|
async function queryCache(q, param = {}) {
|
|
72
72
|
const { table, args = [], time = 15 } = param;
|
|
73
|
-
const seconds = typeof time !== 'number' || time < 0 ?
|
|
73
|
+
const seconds = typeof time !== 'number' || time < 0 ? 0 : time * 60;
|
|
74
74
|
|
|
75
75
|
// CRUD table state
|
|
76
76
|
const keyCacheTable = `pg:${table}:crud`;
|
|
@@ -92,6 +92,7 @@ async function init(client) {
|
|
|
92
92
|
if (seconds > 0) {
|
|
93
93
|
rclient.set(keyCache, JSON.stringify(data), 'EX', seconds);
|
|
94
94
|
}
|
|
95
|
+
|
|
95
96
|
// console.log('no cache', table, crudInc, query);
|
|
96
97
|
return data;
|
|
97
98
|
}
|
|
@@ -44,16 +44,17 @@ export default async function getFilterSQL({
|
|
|
44
44
|
// console.log('extra getFilterSQL', extraDataTable, pg.pk?.[extraDataTable]);
|
|
45
45
|
|
|
46
46
|
// check sql inline fields count
|
|
47
|
-
if (!checkInline[body
|
|
48
|
-
const filterSql = body.sql.filter(el => el.inline ?? true);
|
|
49
|
-
const
|
|
47
|
+
if (!checkInline[body?.table] && body?.sql?.length && body.table) {
|
|
48
|
+
const filterSql = body.sql.filter(el => !el?.disabled && (el.inline ?? true));
|
|
49
|
+
const sqlTable = filterSql.map((el, i) => ` left join lateral (${el.sql}) ${el.name || `t${i}`} on 1=1 `)?.join('') || '';
|
|
50
|
+
const d = await Promise.all(filterSql.map((el, i) => pg.query(`select ${el.name || `t${i}`}.* from(select * from ${body.table})t ${sqlTable} limit 0`).then(el => el.fields)))
|
|
50
51
|
d.forEach((el, i) => {
|
|
51
52
|
filterSql[i].inline = el.length == 1 ? true : false;
|
|
52
53
|
filterSql[i].fields = el.map(f => f.name);
|
|
53
54
|
});
|
|
54
|
-
checkInline[table] = body.sql;
|
|
55
|
-
} else if (checkInline[table]) {
|
|
56
|
-
body.sql = checkInline[table]
|
|
55
|
+
checkInline[body?.table] = body.sql;
|
|
56
|
+
} else if (checkInline[body?.table]) {
|
|
57
|
+
body.sql = checkInline[body?.table]
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
const sqlTable = body?.sql?.length
|
|
@@ -30,7 +30,9 @@ export default async function getSelectVal({
|
|
|
30
30
|
const filteredValues = values.filter(el => !cache[el]);
|
|
31
31
|
|
|
32
32
|
// query select
|
|
33
|
-
|
|
33
|
+
|
|
34
|
+
const q = `with c(id,text) as (select * from (${cls.sql})q where ${id} = any('{${filteredValues.join(',').replace(/\"/g, '\\"')}}')) select * from c`;
|
|
35
|
+
|
|
34
36
|
const data = filteredValues.length ? await pg.query(q).then(el => el.rows) : [];
|
|
35
37
|
|
|
36
38
|
const clsObj = { ...cache, ...data.reduce((p, el) => ({ ...p, [el.id.toString()]: el.color ? el : el.text }), {}) };
|
|
@@ -1,92 +1,92 @@
|
|
|
1
|
-
import {
|
|
2
|
-
config, getAccess, getTemplate, getMeta, setToken, applyHook, getToken, pgClients,
|
|
3
|
-
} from '../../../../utils.js';
|
|
4
|
-
|
|
5
|
-
export default async function tableAPI(req) {
|
|
6
|
-
const {
|
|
7
|
-
pg = pgClients.client, params, user = {}, query = {},
|
|
8
|
-
} = req;
|
|
9
|
-
const tokenData = await getToken({ token: params?.table, uid: user.uid, json: 1 }) || {};
|
|
10
|
-
|
|
11
|
-
const hookData = await applyHook('preTable', {
|
|
12
|
-
pg, table: params?.table, id: params?.id, ...tokenData || {}, user,
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
if (hookData?.message && hookData?.status) {
|
|
16
|
-
return { message: hookData?.message, status: hookData?.status };
|
|
17
|
-
}
|
|
18
|
-
const tableName1 = hookData?.table || tokenData.table || params.table;
|
|
19
|
-
|
|
20
|
-
const loadTable = await getTemplate('table', tableName1) || {};
|
|
21
|
-
if (!loadTable && !pg.pk?.[tokenData.table]) {
|
|
22
|
-
return { message: 'not found', status: 404 };
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const { table, /* columns, */ form } = loadTable;
|
|
26
|
-
|
|
27
|
-
const templateName = hookData?.table || tokenData.table || params.table;
|
|
28
|
-
const tableName = table || templateName;
|
|
29
|
-
|
|
30
|
-
const id = hookData?.id || tokenData.id || params.id;
|
|
31
|
-
|
|
32
|
-
if (tokenData && !id) return { message: {} };
|
|
33
|
-
if (!tableName && !id) {
|
|
34
|
-
return { message: 'not enough params', status: 400 };
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const { actions = [], query: accessQuery } = await getAccess({ table: templateName, id, user }, pg) || {};
|
|
38
|
-
|
|
39
|
-
if (!actions.includes('edit') && !config?.local && !tokenData) {
|
|
40
|
-
return { message: 'access restricted', status: 403 };
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const { pk, columns: dbColumns = [] } = await getMeta({ pg, table: tableName });
|
|
44
|
-
if (!pk) return { message: `table not found: ${table}`, status: 404 };
|
|
45
|
-
|
|
46
|
-
// const cols = columns.map((el) => el.name || el).join(',');
|
|
47
|
-
const formName = hookData?.form || tokenData?.form || form;
|
|
48
|
-
const formData = await getTemplate('form', formName) || {};
|
|
49
|
-
const schema = formData?.schema || formData || {};
|
|
50
|
-
// skip DataTable from another table
|
|
51
|
-
const extraKeys = Object.keys(schema).filter((key) => schema[key]?.type === 'DataTable' && schema[key]?.table && schema[key]?.parent_id && schema[key]?.colModel?.length);
|
|
52
|
-
// skip non-existing columns
|
|
53
|
-
const columnList = dbColumns.map((el) => el.name || el).join(',');
|
|
54
|
-
|
|
55
|
-
const { fields = [] } = !loadTable?.table ? await pg.query(`select * from ${tableName} limit 0`) : {};
|
|
56
|
-
const cols = loadTable?.table
|
|
57
|
-
? Object.keys(schema || {}).filter((col) => columnList.includes(col) && !extraKeys.includes(col))?.map((col) => (col?.includes('geom') && schema?.[col]?.type === 'Geom' ? `st_asgeojson(${col})::json as "${col}"` : `"${col}"`))?.join(',')
|
|
58
|
-
: fields.map((el) => (el?.name?.includes('geom') && pg.pgType[el?.dataTypeID] === 'geometry' ? `st_asgeojson(${el.name})::json as "${el.name}"` : `"${el?.name}"`)).join(',');
|
|
59
|
-
const where = [`"${pk}" = $1`, loadTable.query, accessQuery].filter((el) => el);
|
|
60
|
-
const geom = dbColumns.find((el) => el.name === 'geom' && pg.pgType[el.dataTypeID] === 'geometry') ? ',st_asgeojson(geom)::json as geom' : '';
|
|
61
|
-
const q = `select "${pk}" as id, ${cols || '*'} ${geom} from ${tableName} t where ${where.join(' and ') || 'true'} limit 1`;
|
|
62
|
-
|
|
63
|
-
if (query?.sql === '1') return q;
|
|
64
|
-
|
|
65
|
-
const data = await pg.query(q, [id]).then(el => el.rows[0]);
|
|
66
|
-
if (!data) return { message: 'not found', status: 404 };
|
|
67
|
-
|
|
68
|
-
Object.keys(schema).filter(key => schema[key]?.type === 'DataTable').forEach(key => {
|
|
69
|
-
if (data[key] && !Array.isArray(data[key])) { data[key] = null };
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
if (extraKeys?.length) {
|
|
73
|
-
await Promise.all(extraKeys?.map(async (key) => {
|
|
74
|
-
const { colModel, table: extraTable, parent_id: parentId } = schema[key];
|
|
75
|
-
const q1 = `select ${parentId} as parent, ${colModel.map((col) => col.name || col.key).join(',')} from ${extraTable} a where ${parentId}=$1`;
|
|
76
|
-
// console.log(tableName, formName, q1);
|
|
77
|
-
const { rows: extraRows } = await pg.query(q1, [hookData?.id || tokenData?.id || params?.id]);
|
|
78
|
-
Object.assign(data, { [key]: extraRows });
|
|
79
|
-
}));
|
|
80
|
-
}
|
|
81
|
-
if (user?.uid && actions?.includes?.('edit')) {
|
|
82
|
-
data.token = tokenData?.table ? params.table : setToken({
|
|
83
|
-
ids: [JSON.stringify({ id, table: tableName, form: loadTable.form })],
|
|
84
|
-
uid: user.uid,
|
|
85
|
-
array: 1,
|
|
86
|
-
})[0];
|
|
87
|
-
}
|
|
88
|
-
const res = await applyHook('afterTable', {
|
|
89
|
-
pg, table: tableName, payload: [data], user,
|
|
90
|
-
});
|
|
91
|
-
return res || data || {};
|
|
92
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
config, getAccess, getTemplate, getMeta, setToken, applyHook, getToken, pgClients,
|
|
3
|
+
} from '../../../../utils.js';
|
|
4
|
+
|
|
5
|
+
export default async function tableAPI(req) {
|
|
6
|
+
const {
|
|
7
|
+
pg = pgClients.client, params, user = {}, query = {},
|
|
8
|
+
} = req;
|
|
9
|
+
const tokenData = await getToken({ token: params?.table, uid: user.uid, json: 1 }) || {};
|
|
10
|
+
|
|
11
|
+
const hookData = await applyHook('preTable', {
|
|
12
|
+
pg, table: params?.table, id: params?.id, ...tokenData || {}, user,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
if (hookData?.message && hookData?.status) {
|
|
16
|
+
return { message: hookData?.message, status: hookData?.status };
|
|
17
|
+
}
|
|
18
|
+
const tableName1 = hookData?.table || tokenData.table || params.table;
|
|
19
|
+
|
|
20
|
+
const loadTable = await getTemplate('table', tableName1) || {};
|
|
21
|
+
if (!loadTable && !pg.pk?.[tokenData.table]) {
|
|
22
|
+
return { message: 'not found', status: 404 };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const { table, /* columns, */ form } = loadTable;
|
|
26
|
+
|
|
27
|
+
const templateName = hookData?.table || tokenData.table || params.table;
|
|
28
|
+
const tableName = table || templateName;
|
|
29
|
+
|
|
30
|
+
const id = hookData?.id || tokenData.id || params.id;
|
|
31
|
+
|
|
32
|
+
if (tokenData && !id) return { message: {} };
|
|
33
|
+
if (!tableName && !id) {
|
|
34
|
+
return { message: 'not enough params', status: 400 };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const { actions = [], query: accessQuery } = await getAccess({ table: templateName, id, user }, pg) || {};
|
|
38
|
+
|
|
39
|
+
if (!actions.includes('edit') && !config?.local && !tokenData) {
|
|
40
|
+
return { message: 'access restricted', status: 403 };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const { pk, columns: dbColumns = [] } = await getMeta({ pg, table: tableName });
|
|
44
|
+
if (!pk) return { message: `table not found: ${table}`, status: 404 };
|
|
45
|
+
|
|
46
|
+
// const cols = columns.map((el) => el.name || el).join(',');
|
|
47
|
+
const formName = hookData?.form || tokenData?.form || form;
|
|
48
|
+
const formData = await getTemplate('form', formName) || {};
|
|
49
|
+
const schema = formData?.schema || formData || {};
|
|
50
|
+
// skip DataTable from another table
|
|
51
|
+
const extraKeys = Object.keys(schema).filter((key) => schema[key]?.type === 'DataTable' && schema[key]?.table && schema[key]?.parent_id && schema[key]?.colModel?.length);
|
|
52
|
+
// skip non-existing columns
|
|
53
|
+
const columnList = dbColumns.map((el) => el.name || el).join(',');
|
|
54
|
+
|
|
55
|
+
const { fields = [] } = !loadTable?.table ? await pg.query(`select * from ${tableName} limit 0`) : {};
|
|
56
|
+
const cols = loadTable?.table
|
|
57
|
+
? Object.keys(schema || {}).filter((col) => columnList.includes(col) && !extraKeys.includes(col))?.map((col) => (col?.includes('geom') && schema?.[col]?.type === 'Geom' ? `st_asgeojson(${col})::json as "${col}"` : `"${col}"`))?.join(',')
|
|
58
|
+
: fields.map((el) => (el?.name?.includes('geom') && pg.pgType[el?.dataTypeID] === 'geometry' ? `st_asgeojson(${el.name})::json as "${el.name}"` : `"${el?.name}"`)).join(',');
|
|
59
|
+
const where = [`"${pk}" = $1`, loadTable.query, accessQuery].filter((el) => el);
|
|
60
|
+
const geom = dbColumns.find((el) => el.name === 'geom' && pg.pgType[el.dataTypeID] === 'geometry') ? ',st_asgeojson(geom)::json as geom' : '';
|
|
61
|
+
const q = `select "${pk}" as id, ${cols || '*'} ${geom} from ${tableName} t where ${where.join(' and ') || 'true'} limit 1`;
|
|
62
|
+
|
|
63
|
+
if (query?.sql === '1') return q;
|
|
64
|
+
|
|
65
|
+
const data = await pg.query(q, [id]).then(el => el.rows[0]);
|
|
66
|
+
if (!data) return { message: 'not found', status: 404 };
|
|
67
|
+
|
|
68
|
+
Object.keys(schema).filter(key => schema[key]?.type === 'DataTable').forEach(key => {
|
|
69
|
+
if (data[key] && !Array.isArray(data[key])) { data[key] = null };
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
if (extraKeys?.length) {
|
|
73
|
+
await Promise.all(extraKeys?.map(async (key) => {
|
|
74
|
+
const { colModel, table: extraTable, parent_id: parentId } = schema[key];
|
|
75
|
+
const q1 = `select ${parentId} as parent, ${colModel.map((col) => col.name || col.key).join(',')} from ${extraTable} a where ${parentId}=$1`;
|
|
76
|
+
// console.log(tableName, formName, q1);
|
|
77
|
+
const { rows: extraRows } = await pg.query(q1, [hookData?.id || tokenData?.id || params?.id]);
|
|
78
|
+
Object.assign(data, { [key]: extraRows });
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
if (user?.uid && actions?.includes?.('edit')) {
|
|
82
|
+
data.token = tokenData?.table ? params.table : setToken({
|
|
83
|
+
ids: [JSON.stringify({ id, table: tableName, form: loadTable.form })],
|
|
84
|
+
uid: user.uid,
|
|
85
|
+
array: 1,
|
|
86
|
+
})[0];
|
|
87
|
+
}
|
|
88
|
+
const res = await applyHook('afterTable', {
|
|
89
|
+
pg, table: tableName, payload: [data], user,
|
|
90
|
+
});
|
|
91
|
+
return res || data || {};
|
|
92
|
+
}
|
|
@@ -19,7 +19,7 @@ export default async function dataAPI(req, reply, called) {
|
|
|
19
19
|
} = req;
|
|
20
20
|
|
|
21
21
|
const time = Date.now();
|
|
22
|
-
|
|
22
|
+
const timeArr = [Date.now()];
|
|
23
23
|
const { uid } = user;
|
|
24
24
|
|
|
25
25
|
const hookData = await applyHook('preData', {
|
|
@@ -63,7 +63,7 @@ export default async function dataAPI(req, reply, called) {
|
|
|
63
63
|
} = loadTable || tokenData;
|
|
64
64
|
|
|
65
65
|
const tableMeta = await getMeta({ pg, table });
|
|
66
|
-
|
|
66
|
+
timeArr.push(Date.now())
|
|
67
67
|
if (tableMeta?.view) {
|
|
68
68
|
if (!loadTable?.key && !tokenData?.key) return { message: `key not found: ${table}`, status: 404 };
|
|
69
69
|
Object.assign(tableMeta, { pk: loadTable?.key || tokenData?.key });
|
|
@@ -78,7 +78,8 @@ export default async function dataAPI(req, reply, called) {
|
|
|
78
78
|
const cardSqlFiltered = hookData?.id || params.id ? (cardSql?.filter?.((el) => !el?.disabled && el?.name && el?.sql?.replace) || []) : [];
|
|
79
79
|
const cardSqlTable = cardSqlFiltered.length ? cardSqlFiltered.map((el, i) => ` left join lateral (${el.sql.replace('{{uid}}', uid)}) ct${i} on 1=1 `).join('\n') || '' : '';
|
|
80
80
|
|
|
81
|
-
const
|
|
81
|
+
const sqlInline = loadTable.sql?.filter?.(el => el.inline).map(el => `,(${el.sql})`).join('');
|
|
82
|
+
const { fields = [] } = pg.queryCache ? await pg.queryCache(`select * ${sqlInline} from ${table} t ${sqlTable} ${cardSqlTable} limit 0`) : {};
|
|
82
83
|
const dbColumnsTable = fields.map(el => el.name);
|
|
83
84
|
const cols = columns.filter((el) => el.name !== 'geom' && dbColumnsTable.includes(el.name)).map((el) => el.name || el).join(',');
|
|
84
85
|
const metaCols = Object.keys(loadTable?.meta?.cls || {}).filter((el) => !cols.includes(el)).length
|
|
@@ -109,10 +110,10 @@ export default async function dataAPI(req, reply, called) {
|
|
|
109
110
|
uid,
|
|
110
111
|
json: 1,
|
|
111
112
|
}) : {};
|
|
112
|
-
|
|
113
|
+
timeArr.push(Date.now())
|
|
113
114
|
const keyQuery = query.key && (loadTable?.key || tokenData?.key) && !(hookData?.id || tokenData?.id || params.id) ? `${loadTable?.key || tokenData?.key}=$1` : null;
|
|
114
115
|
|
|
115
|
-
const limit = Math.min(maxLimit, +(query.limit || 20));
|
|
116
|
+
const limit = called ? (query.limit || 20) : Math.min(maxLimit, +(query.limit || 20));
|
|
116
117
|
|
|
117
118
|
const offset = query.page && query.page > 0 ? ` offset ${(query.page - 1) * limit}` : '';
|
|
118
119
|
// id, query, filter
|
|
@@ -135,11 +136,9 @@ export default async function dataAPI(req, reply, called) {
|
|
|
135
136
|
const q = `select ${pk ? `"${pk}" as id,` : ''}
|
|
136
137
|
${params.id || query.key ? '*' : sqlColumns || cols || '*'}
|
|
137
138
|
${metaCols}
|
|
138
|
-
|
|
139
|
-
? `,${sql?.filter(el => el.inline && el.fields).map(el => el.fields).join(',')}` || ''
|
|
140
|
-
: ''}
|
|
139
|
+
|
|
141
140
|
${dbColumns.find((el) => el.name === 'geom' && pg.pgType?.[el.dataTypeID] === 'geometry') ? ',st_asgeojson(geom)::json as geom' : ''}
|
|
142
|
-
from (select * ${sql?.filter(el => el.inline).map(el => `,(${el.sql})`).join('') || ''} from ${table} t
|
|
141
|
+
from (select * ${sql?.filter(el => el.inline).map(el => `,(${el.sql})`).join('') || ''} from ${table} t ) t
|
|
143
142
|
${sqlTable}
|
|
144
143
|
${params.id ? cardSqlTable : ''}
|
|
145
144
|
where ${where.join(' and ') || 'true'}
|
|
@@ -152,6 +151,8 @@ export default async function dataAPI(req, reply, called) {
|
|
|
152
151
|
|
|
153
152
|
const { rows = [] } = await pg.query(q, (tokenData?.id || hookData?.id || params.id ? [tokenData?.id || hookData?.id || params.id] : null) || (query.key && loadTable.key ? [query.key] : []));
|
|
154
153
|
|
|
154
|
+
timeArr.push(Date.now())
|
|
155
|
+
|
|
155
156
|
if (uid && rows.length && editable) {
|
|
156
157
|
rows.forEach(row => {
|
|
157
158
|
row.token = setToken({
|
|
@@ -178,15 +179,16 @@ export default async function dataAPI(req, reply, called) {
|
|
|
178
179
|
|
|
179
180
|
const counts = keyQuery || tokenData?.id || hookData?.id || params.id
|
|
180
181
|
? { total: rows.length, filtered: rows.length }
|
|
181
|
-
: await pg.queryCache?.(qCount, { table: loadTable?.table || tokenData?.table, time: 5 }).then(el => el?.rows[0] || {});
|
|
182
|
+
: await pg.queryCache?.(qCount, { table: loadTable?.table || tokenData?.table, time: 5 * 60 }).then(el => el?.rows[0] || {});
|
|
182
183
|
|
|
184
|
+
timeArr.push(Date.now())
|
|
183
185
|
const { total, filtered } = counts || {};
|
|
184
186
|
const agg = Object.keys(counts).filter(el => !['total', 'filtered'].includes(el)).reduce((acc, el) => ({ ...acc, [el]: counts[el] }), {});
|
|
185
187
|
|
|
186
188
|
await extraDataGet({ rows, table: loadTable?.table, form }, pg);
|
|
187
189
|
|
|
188
190
|
await metaFormat({ rows, table: tokenData?.table || hookData?.table || params.table }, pg);
|
|
189
|
-
|
|
191
|
+
timeArr.push(Date.now())
|
|
190
192
|
const status = [];
|
|
191
193
|
if (loadTable?.meta?.status) {
|
|
192
194
|
const statusColumn = loadTable.meta?.cls?.[loadTable.meta?.status]
|
|
@@ -273,7 +275,15 @@ export default async function dataAPI(req, reply, called) {
|
|
|
273
275
|
}
|
|
274
276
|
|
|
275
277
|
const res = {
|
|
276
|
-
time:
|
|
278
|
+
time: {
|
|
279
|
+
total: Date.now() - time,
|
|
280
|
+
init: timeArr[1] - timeArr[0],
|
|
281
|
+
filter: timeArr[2] - timeArr[1],
|
|
282
|
+
data: timeArr[3] - timeArr[2],
|
|
283
|
+
count: timeArr[4] - timeArr[3],
|
|
284
|
+
format: timeArr[5] - timeArr[4],
|
|
285
|
+
},
|
|
286
|
+
|
|
277
287
|
public: ispublic,
|
|
278
288
|
tokens,
|
|
279
289
|
card: loadTable?.card,
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { logger, autoIndex, getSelect, getFilterSQL, getTemplate, getSelectVal, pgClients } from '../../../../utils.js';
|
|
2
2
|
|
|
3
|
-
const checkInline = {};
|
|
4
|
-
|
|
5
3
|
export default async function filterAPI(req) {
|
|
6
4
|
const time = Date.now();
|
|
7
5
|
|
|
@@ -12,38 +10,23 @@ export default async function filterAPI(req) {
|
|
|
12
10
|
const loadTable = await getTemplate('table', params.table);
|
|
13
11
|
if (!loadTable) { return { status: 404, message: 'not found' }; }
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const filterSql = loadTable.sql.filter(el => el.inline ?? true);
|
|
18
|
-
const d = await Promise.all(filterSql.map(el => pg.query(`select q.* from(select * from ${loadTable.table})t left join lateral(${el.sql})q on 1=1 limit 0`).then(el => el.fields)))
|
|
19
|
-
d.forEach((el, i) => {
|
|
20
|
-
filterSql[i].inline = el.length == 1 ? true : false;
|
|
21
|
-
filterSql[i].fields = el.map(f => f.name);
|
|
22
|
-
});
|
|
23
|
-
checkInline[params?.table] = loadTable.sql;
|
|
24
|
-
} else if (checkInline[params?.table]) {
|
|
25
|
-
loadTable.sql = checkInline[params?.table]
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const sqlTable = false ? loadTable.sql?.filter?.((el) => !el.inline && !el?.disabled && el?.sql?.replace).map((el, i) => ` left join lateral (${el.sql.replace('{{uid}}', user?.uid)}) ${el.name || `t${i}`} on 1=1 `)?.join('') || '' : '';
|
|
29
|
-
const sqlInline = loadTable.sql?.filter?.(el => el.inline).map(el => `,(${el.sql})`).join('');
|
|
30
|
-
const { fields: columns = [] } = await pg.query(`select q.* from (select * ${sqlInline || ''} from ${loadTable.table} t ${sqlTable} limit 0)q`);
|
|
13
|
+
const sqlTable = loadTable.sql?.filter?.((el) => !el?.disabled && el?.sql?.replace).map((el, i) => ` left join lateral (${el.sql.replace('{{uid}}', user?.uid)}) ${el.name || `t${i}`} on 1=1 `)?.join('') || '';
|
|
14
|
+
const { fields: columns = [] } = await pg.query(`select * from ${loadTable.table} t ${sqlTable} limit 0`);
|
|
31
15
|
const { fields = [] } = await pg.query(`select * from ${loadTable.table} t limit 0`);
|
|
32
16
|
|
|
33
17
|
const {
|
|
34
18
|
filter, custom, state, search,
|
|
35
19
|
} = query;
|
|
36
20
|
|
|
37
|
-
const { extra } = loadTable?.form ? await getTemplate('form', loadTable?.form) || {} : {};
|
|
21
|
+
// const { extra } = loadTable?.form ? await getTemplate('form', loadTable?.form) || {} : {};
|
|
38
22
|
|
|
39
|
-
const { optimizedSQL = `select *
|
|
23
|
+
const { optimizedSQL = `select * from ${loadTable.table}` } = false ? await getFilterSQL({
|
|
40
24
|
pg,
|
|
41
25
|
table: params.table,
|
|
42
26
|
filter,
|
|
43
27
|
custom,
|
|
44
28
|
state,
|
|
45
29
|
search,
|
|
46
|
-
uid: user?.uid,
|
|
47
30
|
}) : {};
|
|
48
31
|
|
|
49
32
|
const filters = (loadTable?.filter_list || loadTable?.filters || loadTable?.filterList || []).concat(loadTable?.filterSql || []);
|
|
@@ -64,8 +47,8 @@ export default async function filterAPI(req) {
|
|
|
64
47
|
await Promise.all(filters.filter((el) => el.data && el.id && el.type !== 'Autocomplete').map(async (el) => {
|
|
65
48
|
const cls = await getSelect(el.data, pg);
|
|
66
49
|
|
|
50
|
+
if (!cls || !loadTable.table) return;
|
|
67
51
|
const { dataTypeID } = columns.find((item) => item.name === el.id) || {};
|
|
68
|
-
if (!cls || !loadTable.table || !dataTypeID) return;
|
|
69
52
|
|
|
70
53
|
if (el.extra && el.type === 'select' && Array.isArray(cls)) {
|
|
71
54
|
const countArr = await pg.query(`select value_text as id, count(*) from crm.extra_data where property_key=$1 and property_entity=$2 group by value_text`, [el.id, params.table]);
|
|
@@ -159,4 +142,4 @@ export default async function filterAPI(req) {
|
|
|
159
142
|
inline: loadTable?.filterInline,
|
|
160
143
|
state: loadTable?.filterState,
|
|
161
144
|
};
|
|
162
|
-
}
|
|
145
|
+
}
|