|
|
|
@ -24,7 +24,7 @@ import {
|
|
|
|
|
RelationTypes, |
|
|
|
|
SortType, |
|
|
|
|
UITypes, |
|
|
|
|
ViewTypes |
|
|
|
|
ViewTypes, |
|
|
|
|
} from 'nocodb-sdk'; |
|
|
|
|
import formSubmissionEmailTemplate from '../../../../utils/common/formSubmissionEmailTemplate'; |
|
|
|
|
import ejs from 'ejs'; |
|
|
|
@ -34,7 +34,7 @@ import Hook from '../../../../models/Hook';
|
|
|
|
|
import NcPluginMgrv2 from '../../../../meta/helpers/NcPluginMgrv2'; |
|
|
|
|
import { |
|
|
|
|
_transformSubmittedFormDataForEmail, |
|
|
|
|
invokeWebhook |
|
|
|
|
invokeWebhook, |
|
|
|
|
} from '../../../../meta/helpers/webhookHelpers'; |
|
|
|
|
import Validator from 'validator'; |
|
|
|
|
import { customValidators } from './customValidators'; |
|
|
|
@ -73,13 +73,13 @@ class BaseModelSqlv2 {
|
|
|
|
|
private config: any = { |
|
|
|
|
limitDefault: Math.max(+process.env.DB_QUERY_LIMIT_DEFAULT || 25, 1), |
|
|
|
|
limitMin: Math.max(+process.env.DB_QUERY_LIMIT_MIN || 1, 1), |
|
|
|
|
limitMax: Math.max(+process.env.DB_QUERY_LIMIT_MAX || 1000, 1) |
|
|
|
|
limitMax: Math.max(+process.env.DB_QUERY_LIMIT_MAX || 1000, 1), |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
constructor({ |
|
|
|
|
dbDriver, |
|
|
|
|
model, |
|
|
|
|
viewId |
|
|
|
|
viewId, |
|
|
|
|
}: { |
|
|
|
|
[key: string]: any; |
|
|
|
|
model: Model; |
|
|
|
@ -135,14 +135,14 @@ class BaseModelSqlv2 {
|
|
|
|
|
new Filter({ |
|
|
|
|
children: args.filterArr || [], |
|
|
|
|
is_group: true, |
|
|
|
|
logical_op: 'and' |
|
|
|
|
logical_op: 'and', |
|
|
|
|
}), |
|
|
|
|
new Filter({ |
|
|
|
|
children: filterObj, |
|
|
|
|
is_group: true, |
|
|
|
|
logical_op: 'and' |
|
|
|
|
logical_op: 'and', |
|
|
|
|
}), |
|
|
|
|
...(args.filterArr || []) |
|
|
|
|
...(args.filterArr || []), |
|
|
|
|
], |
|
|
|
|
qb, |
|
|
|
|
this.dbDriver |
|
|
|
@ -189,19 +189,19 @@ class BaseModelSqlv2 {
|
|
|
|
|
new Filter({ |
|
|
|
|
children: |
|
|
|
|
(await Filter.rootFilterList({ viewId: this.viewId })) || [], |
|
|
|
|
is_group: true |
|
|
|
|
is_group: true, |
|
|
|
|
}), |
|
|
|
|
new Filter({ |
|
|
|
|
children: args.filterArr || [], |
|
|
|
|
is_group: true, |
|
|
|
|
logical_op: 'and' |
|
|
|
|
logical_op: 'and', |
|
|
|
|
}), |
|
|
|
|
new Filter({ |
|
|
|
|
children: filterObj, |
|
|
|
|
is_group: true, |
|
|
|
|
logical_op: 'and' |
|
|
|
|
logical_op: 'and', |
|
|
|
|
}), |
|
|
|
|
...(args.filterArr || []) |
|
|
|
|
...(args.filterArr || []), |
|
|
|
|
], |
|
|
|
|
qb, |
|
|
|
|
this.dbDriver |
|
|
|
@ -219,14 +219,14 @@ class BaseModelSqlv2 {
|
|
|
|
|
new Filter({ |
|
|
|
|
children: args.filterArr || [], |
|
|
|
|
is_group: true, |
|
|
|
|
logical_op: 'and' |
|
|
|
|
logical_op: 'and', |
|
|
|
|
}), |
|
|
|
|
new Filter({ |
|
|
|
|
children: filterObj, |
|
|
|
|
is_group: true, |
|
|
|
|
logical_op: 'and' |
|
|
|
|
logical_op: 'and', |
|
|
|
|
}), |
|
|
|
|
...(args.filterArr || []) |
|
|
|
|
...(args.filterArr || []), |
|
|
|
|
], |
|
|
|
|
qb, |
|
|
|
|
this.dbDriver |
|
|
|
@ -241,7 +241,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
// if autogenerated string sort by created_at column if present
|
|
|
|
|
if (this.model.primaryKey && this.model.primaryKey.ai) { |
|
|
|
|
qb.orderBy(this.model.primaryKey.column_name); |
|
|
|
|
} else if (this.model.columns.find(c => c.column_name === 'created_at')) { |
|
|
|
|
} else if (this.model.columns.find((c) => c.column_name === 'created_at')) { |
|
|
|
|
qb.orderBy('created_at'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -249,7 +249,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
const proto = await this.getProto(); |
|
|
|
|
const data = await this.extractRawQueryAndExec(qb); |
|
|
|
|
|
|
|
|
|
return data?.map(d => { |
|
|
|
|
return data?.map((d) => { |
|
|
|
|
d.__proto__ = proto; |
|
|
|
|
return d; |
|
|
|
|
}); |
|
|
|
@ -274,19 +274,19 @@ class BaseModelSqlv2 {
|
|
|
|
|
new Filter({ |
|
|
|
|
children: |
|
|
|
|
(await Filter.rootFilterList({ viewId: this.viewId })) || [], |
|
|
|
|
is_group: true |
|
|
|
|
is_group: true, |
|
|
|
|
}), |
|
|
|
|
new Filter({ |
|
|
|
|
children: args.filterArr || [], |
|
|
|
|
is_group: true, |
|
|
|
|
logical_op: 'and' |
|
|
|
|
logical_op: 'and', |
|
|
|
|
}), |
|
|
|
|
new Filter({ |
|
|
|
|
children: filterObj, |
|
|
|
|
is_group: true, |
|
|
|
|
logical_op: 'and' |
|
|
|
|
logical_op: 'and', |
|
|
|
|
}), |
|
|
|
|
...(args.filterArr || []) |
|
|
|
|
...(args.filterArr || []), |
|
|
|
|
], |
|
|
|
|
qb, |
|
|
|
|
this.dbDriver |
|
|
|
@ -297,14 +297,14 @@ class BaseModelSqlv2 {
|
|
|
|
|
new Filter({ |
|
|
|
|
children: args.filterArr || [], |
|
|
|
|
is_group: true, |
|
|
|
|
logical_op: 'and' |
|
|
|
|
logical_op: 'and', |
|
|
|
|
}), |
|
|
|
|
new Filter({ |
|
|
|
|
children: filterObj, |
|
|
|
|
is_group: true, |
|
|
|
|
logical_op: 'and' |
|
|
|
|
logical_op: 'and', |
|
|
|
|
}), |
|
|
|
|
...(args.filterArr || []) |
|
|
|
|
...(args.filterArr || []), |
|
|
|
|
], |
|
|
|
|
qb, |
|
|
|
|
this.dbDriver |
|
|
|
@ -312,7 +312,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
qb.count(sanitize(this.model.primaryKey?.column_name) || '*', { |
|
|
|
|
as: 'count' |
|
|
|
|
as: 'count', |
|
|
|
|
}).first(); |
|
|
|
|
const res = (await this.dbDriver.raw(unsanitize(qb.toQuery()))) as any; |
|
|
|
|
return (this.isPg ? res.rows[0] : res[0][0] ?? res[0]).count; |
|
|
|
@ -326,7 +326,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
offset?; |
|
|
|
|
sort?: string | string[]; |
|
|
|
|
} = { |
|
|
|
|
column_name: '' |
|
|
|
|
column_name: '', |
|
|
|
|
} |
|
|
|
|
) { |
|
|
|
|
const { where, ...rest } = this._getListArgs(args as any); |
|
|
|
@ -345,8 +345,8 @@ class BaseModelSqlv2 {
|
|
|
|
|
new Filter({ |
|
|
|
|
children: filterObj, |
|
|
|
|
is_group: true, |
|
|
|
|
logical_op: 'and' |
|
|
|
|
}) |
|
|
|
|
logical_op: 'and', |
|
|
|
|
}), |
|
|
|
|
], |
|
|
|
|
qb, |
|
|
|
|
this.dbDriver |
|
|
|
@ -364,16 +364,20 @@ class BaseModelSqlv2 {
|
|
|
|
|
|
|
|
|
|
// const { cn } = this.hasManyRelations.find(({ tn }) => tn === child) || {};
|
|
|
|
|
const relColumn = (await this.model.getColumns()).find( |
|
|
|
|
c => c.id === colId |
|
|
|
|
(c) => c.id === colId |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
const chilCol = await ((await relColumn.getColOptions()) as LinkToAnotherRecordColumn).getChildColumn(); |
|
|
|
|
const chilCol = await ( |
|
|
|
|
(await relColumn.getColOptions()) as LinkToAnotherRecordColumn |
|
|
|
|
).getChildColumn(); |
|
|
|
|
const childTable = await chilCol.getModel(); |
|
|
|
|
const parentCol = await ((await relColumn.getColOptions()) as LinkToAnotherRecordColumn).getParentColumn(); |
|
|
|
|
const parentCol = await ( |
|
|
|
|
(await relColumn.getColOptions()) as LinkToAnotherRecordColumn |
|
|
|
|
).getParentColumn(); |
|
|
|
|
const parentTable = await parentCol.getModel(); |
|
|
|
|
const childModel = await Model.getBaseModelSQL({ |
|
|
|
|
model: childTable, |
|
|
|
|
dbDriver: this.dbDriver |
|
|
|
|
dbDriver: this.dbDriver, |
|
|
|
|
}); |
|
|
|
|
await parentTable.getColumns(); |
|
|
|
|
|
|
|
|
@ -383,7 +387,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
const childQb = this.dbDriver.queryBuilder().from( |
|
|
|
|
this.dbDriver |
|
|
|
|
.unionAll( |
|
|
|
|
ids.map(p => { |
|
|
|
|
ids.map((p) => { |
|
|
|
|
const query = qb |
|
|
|
|
.clone() |
|
|
|
|
.select(this.dbDriver.raw('? as ??', [p, GROUP_COL])) |
|
|
|
@ -409,12 +413,12 @@ class BaseModelSqlv2 {
|
|
|
|
|
const proto = await ( |
|
|
|
|
await Model.getBaseModelSQL({ |
|
|
|
|
id: childTable.id, |
|
|
|
|
dbDriver: this.dbDriver |
|
|
|
|
dbDriver: this.dbDriver, |
|
|
|
|
}) |
|
|
|
|
).getProto(); |
|
|
|
|
|
|
|
|
|
return _.groupBy( |
|
|
|
|
children.map(c => { |
|
|
|
|
children.map((c) => { |
|
|
|
|
c.__proto__ = proto; |
|
|
|
|
return c; |
|
|
|
|
}), |
|
|
|
@ -430,16 +434,20 @@ class BaseModelSqlv2 {
|
|
|
|
|
try { |
|
|
|
|
// const { cn } = this.hasManyRelations.find(({ tn }) => tn === child) || {};
|
|
|
|
|
const relColumn = (await this.model.getColumns()).find( |
|
|
|
|
c => c.id === colId |
|
|
|
|
(c) => c.id === colId |
|
|
|
|
); |
|
|
|
|
const chilCol = await ((await relColumn.getColOptions()) as LinkToAnotherRecordColumn).getChildColumn(); |
|
|
|
|
const chilCol = await ( |
|
|
|
|
(await relColumn.getColOptions()) as LinkToAnotherRecordColumn |
|
|
|
|
).getChildColumn(); |
|
|
|
|
const childTable = await chilCol.getModel(); |
|
|
|
|
const parentCol = await ((await relColumn.getColOptions()) as LinkToAnotherRecordColumn).getParentColumn(); |
|
|
|
|
const parentCol = await ( |
|
|
|
|
(await relColumn.getColOptions()) as LinkToAnotherRecordColumn |
|
|
|
|
).getParentColumn(); |
|
|
|
|
const parentTable = await parentCol.getModel(); |
|
|
|
|
await parentTable.getColumns(); |
|
|
|
|
|
|
|
|
|
const children = await this.dbDriver.unionAll( |
|
|
|
|
ids.map(p => { |
|
|
|
|
ids.map((p) => { |
|
|
|
|
const query = this.dbDriver(childTable.table_name) |
|
|
|
|
.count(`${chilCol?.column_name} as count`) |
|
|
|
|
.whereIn( |
|
|
|
@ -468,16 +476,20 @@ class BaseModelSqlv2 {
|
|
|
|
|
// todo: get only required fields
|
|
|
|
|
|
|
|
|
|
const relColumn = (await this.model.getColumns()).find( |
|
|
|
|
c => c.id === colId |
|
|
|
|
(c) => c.id === colId |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
const chilCol = await ((await relColumn.getColOptions()) as LinkToAnotherRecordColumn).getChildColumn(); |
|
|
|
|
const chilCol = await ( |
|
|
|
|
(await relColumn.getColOptions()) as LinkToAnotherRecordColumn |
|
|
|
|
).getChildColumn(); |
|
|
|
|
const childTable = await chilCol.getModel(); |
|
|
|
|
const parentCol = await ((await relColumn.getColOptions()) as LinkToAnotherRecordColumn).getParentColumn(); |
|
|
|
|
const parentCol = await ( |
|
|
|
|
(await relColumn.getColOptions()) as LinkToAnotherRecordColumn |
|
|
|
|
).getParentColumn(); |
|
|
|
|
const parentTable = await parentCol.getModel(); |
|
|
|
|
const childModel = await Model.getBaseModelSQL({ |
|
|
|
|
model: childTable, |
|
|
|
|
dbDriver: this.dbDriver |
|
|
|
|
dbDriver: this.dbDriver, |
|
|
|
|
}); |
|
|
|
|
await parentTable.getColumns(); |
|
|
|
|
|
|
|
|
@ -501,11 +513,11 @@ class BaseModelSqlv2 {
|
|
|
|
|
const proto = await ( |
|
|
|
|
await Model.getBaseModelSQL({ |
|
|
|
|
id: childTable.id, |
|
|
|
|
dbDriver: this.dbDriver |
|
|
|
|
dbDriver: this.dbDriver, |
|
|
|
|
}) |
|
|
|
|
).getProto(); |
|
|
|
|
|
|
|
|
|
return children.map(c => { |
|
|
|
|
return children.map((c) => { |
|
|
|
|
c.__proto__ = proto; |
|
|
|
|
return c; |
|
|
|
|
}); |
|
|
|
@ -519,11 +531,15 @@ class BaseModelSqlv2 {
|
|
|
|
|
try { |
|
|
|
|
// const { cn } = this.hasManyRelations.find(({ tn }) => tn === child) || {};
|
|
|
|
|
const relColumn = (await this.model.getColumns()).find( |
|
|
|
|
c => c.id === colId |
|
|
|
|
(c) => c.id === colId |
|
|
|
|
); |
|
|
|
|
const chilCol = await ((await relColumn.getColOptions()) as LinkToAnotherRecordColumn).getChildColumn(); |
|
|
|
|
const chilCol = await ( |
|
|
|
|
(await relColumn.getColOptions()) as LinkToAnotherRecordColumn |
|
|
|
|
).getChildColumn(); |
|
|
|
|
const childTable = await chilCol.getModel(); |
|
|
|
|
const parentCol = await ((await relColumn.getColOptions()) as LinkToAnotherRecordColumn).getParentColumn(); |
|
|
|
|
const parentCol = await ( |
|
|
|
|
(await relColumn.getColOptions()) as LinkToAnotherRecordColumn |
|
|
|
|
).getParentColumn(); |
|
|
|
|
const parentTable = await parentCol.getModel(); |
|
|
|
|
await parentTable.getColumns(); |
|
|
|
|
|
|
|
|
@ -546,8 +562,11 @@ class BaseModelSqlv2 {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public async multipleMmList({ colId, parentIds }, args?: { limit; offset }) { |
|
|
|
|
const relColumn = (await this.model.getColumns()).find(c => c.id === colId); |
|
|
|
|
const relColOptions = (await relColumn.getColOptions()) as LinkToAnotherRecordColumn; |
|
|
|
|
const relColumn = (await this.model.getColumns()).find( |
|
|
|
|
(c) => c.id === colId |
|
|
|
|
); |
|
|
|
|
const relColOptions = |
|
|
|
|
(await relColumn.getColOptions()) as LinkToAnotherRecordColumn; |
|
|
|
|
|
|
|
|
|
// const tn = this.model.tn;
|
|
|
|
|
// const cn = (await relColOptions.getChildColumn()).title;
|
|
|
|
@ -561,7 +580,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
await parentTable.getColumns(); |
|
|
|
|
const childModel = await Model.getBaseModelSQL({ |
|
|
|
|
dbDriver: this.dbDriver, |
|
|
|
|
model: childTable |
|
|
|
|
model: childTable, |
|
|
|
|
}); |
|
|
|
|
const rtn = childTable.table_name; |
|
|
|
|
const rtnId = childTable.id; |
|
|
|
@ -570,7 +589,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
|
|
|
|
|
await childModel.selectObject({ qb }); |
|
|
|
|
const finalQb = this.dbDriver.unionAll( |
|
|
|
|
parentIds.map(id => { |
|
|
|
|
parentIds.map((id) => { |
|
|
|
|
const query = qb |
|
|
|
|
.clone() |
|
|
|
|
.whereIn( |
|
|
|
@ -595,22 +614,25 @@ class BaseModelSqlv2 {
|
|
|
|
|
const proto = await ( |
|
|
|
|
await Model.getBaseModelSQL({ |
|
|
|
|
id: rtnId, |
|
|
|
|
dbDriver: this.dbDriver |
|
|
|
|
dbDriver: this.dbDriver, |
|
|
|
|
}) |
|
|
|
|
).getProto(); |
|
|
|
|
const gs = _.groupBy( |
|
|
|
|
children.map(c => { |
|
|
|
|
children.map((c) => { |
|
|
|
|
c.__proto__ = proto; |
|
|
|
|
return c; |
|
|
|
|
}), |
|
|
|
|
GROUP_COL |
|
|
|
|
); |
|
|
|
|
return parentIds.map(id => gs[id] || []); |
|
|
|
|
return parentIds.map((id) => gs[id] || []); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public async mmList({ colId, parentId }, args?: { limit; offset }) { |
|
|
|
|
const relColumn = (await this.model.getColumns()).find(c => c.id === colId); |
|
|
|
|
const relColOptions = (await relColumn.getColOptions()) as LinkToAnotherRecordColumn; |
|
|
|
|
const relColumn = (await this.model.getColumns()).find( |
|
|
|
|
(c) => c.id === colId |
|
|
|
|
); |
|
|
|
|
const relColOptions = |
|
|
|
|
(await relColumn.getColOptions()) as LinkToAnotherRecordColumn; |
|
|
|
|
|
|
|
|
|
// const tn = this.model.tn;
|
|
|
|
|
// const cn = (await relColOptions.getChildColumn()).title;
|
|
|
|
@ -624,7 +646,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
await parentTable.getColumns(); |
|
|
|
|
const childModel = await Model.getBaseModelSQL({ |
|
|
|
|
dbDriver: this.dbDriver, |
|
|
|
|
model: childTable |
|
|
|
|
model: childTable, |
|
|
|
|
}); |
|
|
|
|
const rtn = childTable.table_name; |
|
|
|
|
const rtnId = childTable.id; |
|
|
|
@ -649,15 +671,18 @@ class BaseModelSqlv2 {
|
|
|
|
|
await Model.getBaseModelSQL({ id: rtnId, dbDriver: this.dbDriver }) |
|
|
|
|
).getProto(); |
|
|
|
|
|
|
|
|
|
return children.map(c => { |
|
|
|
|
return children.map((c) => { |
|
|
|
|
c.__proto__ = proto; |
|
|
|
|
return c; |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public async multipleMmListCount({ colId, parentIds }) { |
|
|
|
|
const relColumn = (await this.model.getColumns()).find(c => c.id === colId); |
|
|
|
|
const relColOptions = (await relColumn.getColOptions()) as LinkToAnotherRecordColumn; |
|
|
|
|
const relColumn = (await this.model.getColumns()).find( |
|
|
|
|
(c) => c.id === colId |
|
|
|
|
); |
|
|
|
|
const relColOptions = |
|
|
|
|
(await relColumn.getColOptions()) as LinkToAnotherRecordColumn; |
|
|
|
|
|
|
|
|
|
const vtn = (await relColOptions.getMMModel()).table_name; |
|
|
|
|
const vcn = (await relColOptions.getMMChildColumn()).column_name; |
|
|
|
@ -678,7 +703,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
|
|
|
|
|
// await childModel.selectObject({ qb });
|
|
|
|
|
const children = await this.dbDriver.unionAll( |
|
|
|
|
parentIds.map(id => { |
|
|
|
|
parentIds.map((id) => { |
|
|
|
|
const query = qb |
|
|
|
|
.clone() |
|
|
|
|
.whereIn( |
|
|
|
@ -696,12 +721,15 @@ class BaseModelSqlv2 {
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
const gs = _.groupBy(children, GROUP_COL); |
|
|
|
|
return parentIds.map(id => gs?.[id]?.[0] || []); |
|
|
|
|
return parentIds.map((id) => gs?.[id]?.[0] || []); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public async mmListCount({ colId, parentId }) { |
|
|
|
|
const relColumn = (await this.model.getColumns()).find(c => c.id === colId); |
|
|
|
|
const relColOptions = (await relColumn.getColOptions()) as LinkToAnotherRecordColumn; |
|
|
|
|
const relColumn = (await this.model.getColumns()).find( |
|
|
|
|
(c) => c.id === colId |
|
|
|
|
); |
|
|
|
|
const relColOptions = |
|
|
|
|
(await relColumn.getColOptions()) as LinkToAnotherRecordColumn; |
|
|
|
|
|
|
|
|
|
const vtn = (await relColOptions.getMMModel()).table_name; |
|
|
|
|
const vcn = (await relColOptions.getMMChildColumn()).column_name; |
|
|
|
@ -738,8 +766,11 @@ class BaseModelSqlv2 {
|
|
|
|
|
{ colId, pid = null }, |
|
|
|
|
args |
|
|
|
|
): Promise<any> { |
|
|
|
|
const relColumn = (await this.model.getColumns()).find(c => c.id === colId); |
|
|
|
|
const relColOptions = (await relColumn.getColOptions()) as LinkToAnotherRecordColumn; |
|
|
|
|
const relColumn = (await this.model.getColumns()).find( |
|
|
|
|
(c) => c.id === colId |
|
|
|
|
); |
|
|
|
|
const relColOptions = |
|
|
|
|
(await relColumn.getColOptions()) as LinkToAnotherRecordColumn; |
|
|
|
|
|
|
|
|
|
const vtn = (await relColOptions.getMMModel()).table_name; |
|
|
|
|
const vcn = (await relColOptions.getMMChildColumn()).column_name; |
|
|
|
@ -752,7 +783,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
const rtn = childTable.table_name; |
|
|
|
|
const qb = this.dbDriver(rtn) |
|
|
|
|
.count(`*`, { as: 'count' }) |
|
|
|
|
.where(qb => { |
|
|
|
|
.where((qb) => { |
|
|
|
|
qb.whereNotIn( |
|
|
|
|
rcn, |
|
|
|
|
this.dbDriver(rtn) |
|
|
|
@ -780,8 +811,11 @@ class BaseModelSqlv2 {
|
|
|
|
|
{ colId, pid = null }, |
|
|
|
|
args |
|
|
|
|
): Promise<any> { |
|
|
|
|
const relColumn = (await this.model.getColumns()).find(c => c.id === colId); |
|
|
|
|
const relColOptions = (await relColumn.getColOptions()) as LinkToAnotherRecordColumn; |
|
|
|
|
const relColumn = (await this.model.getColumns()).find( |
|
|
|
|
(c) => c.id === colId |
|
|
|
|
); |
|
|
|
|
const relColOptions = |
|
|
|
|
(await relColumn.getColOptions()) as LinkToAnotherRecordColumn; |
|
|
|
|
|
|
|
|
|
const vtn = (await relColOptions.getMMModel()).table_name; |
|
|
|
|
const vcn = (await relColOptions.getMMChildColumn()).column_name; |
|
|
|
@ -791,13 +825,13 @@ class BaseModelSqlv2 {
|
|
|
|
|
const childTable = await (await relColOptions.getParentColumn()).getModel(); |
|
|
|
|
const childModel = await Model.getBaseModelSQL({ |
|
|
|
|
dbDriver: this.dbDriver, |
|
|
|
|
model: childTable |
|
|
|
|
model: childTable, |
|
|
|
|
}); |
|
|
|
|
const parentTable = await (await relColOptions.getChildColumn()).getModel(); |
|
|
|
|
await parentTable.getColumns(); |
|
|
|
|
const rtn = childTable.table_name; |
|
|
|
|
|
|
|
|
|
const qb = this.dbDriver(rtn).where(qb => |
|
|
|
|
const qb = this.dbDriver(rtn).where((qb) => |
|
|
|
|
qb |
|
|
|
|
.whereNotIn( |
|
|
|
|
rcn, |
|
|
|
@ -825,7 +859,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
|
|
|
|
|
const proto = await childModel.getProto(); |
|
|
|
|
|
|
|
|
|
return (await qb).map(c => { |
|
|
|
|
return (await qb).map((c) => { |
|
|
|
|
c.__proto__ = proto; |
|
|
|
|
return c; |
|
|
|
|
}); |
|
|
|
@ -836,8 +870,11 @@ class BaseModelSqlv2 {
|
|
|
|
|
{ colId, pid = null }, |
|
|
|
|
args |
|
|
|
|
): Promise<any> { |
|
|
|
|
const relColumn = (await this.model.getColumns()).find(c => c.id === colId); |
|
|
|
|
const relColOptions = (await relColumn.getColOptions()) as LinkToAnotherRecordColumn; |
|
|
|
|
const relColumn = (await this.model.getColumns()).find( |
|
|
|
|
(c) => c.id === colId |
|
|
|
|
); |
|
|
|
|
const relColOptions = |
|
|
|
|
(await relColumn.getColOptions()) as LinkToAnotherRecordColumn; |
|
|
|
|
|
|
|
|
|
const cn = (await relColOptions.getChildColumn()).column_name; |
|
|
|
|
const rcn = (await relColOptions.getParentColumn()).column_name; |
|
|
|
@ -851,7 +888,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
|
|
|
|
|
const qb = this.dbDriver(tn) |
|
|
|
|
.count(`*`, { as: 'count' }) |
|
|
|
|
.where(qb => { |
|
|
|
|
.where((qb) => { |
|
|
|
|
qb.whereNotIn( |
|
|
|
|
cn, |
|
|
|
|
this.dbDriver(rtn) |
|
|
|
@ -874,8 +911,11 @@ class BaseModelSqlv2 {
|
|
|
|
|
{ colId, pid = null }, |
|
|
|
|
args |
|
|
|
|
): Promise<any> { |
|
|
|
|
const relColumn = (await this.model.getColumns()).find(c => c.id === colId); |
|
|
|
|
const relColOptions = (await relColumn.getColOptions()) as LinkToAnotherRecordColumn; |
|
|
|
|
const relColumn = (await this.model.getColumns()).find( |
|
|
|
|
(c) => c.id === colId |
|
|
|
|
); |
|
|
|
|
const relColOptions = |
|
|
|
|
(await relColumn.getColOptions()) as LinkToAnotherRecordColumn; |
|
|
|
|
|
|
|
|
|
const cn = (await relColOptions.getChildColumn()).column_name; |
|
|
|
|
const rcn = (await relColOptions.getParentColumn()).column_name; |
|
|
|
@ -885,14 +925,14 @@ class BaseModelSqlv2 {
|
|
|
|
|
).getModel(); |
|
|
|
|
const childModel = await Model.getBaseModelSQL({ |
|
|
|
|
dbDriver: this.dbDriver, |
|
|
|
|
model: childTable |
|
|
|
|
model: childTable, |
|
|
|
|
}); |
|
|
|
|
await parentTable.getColumns(); |
|
|
|
|
|
|
|
|
|
const tn = childTable.table_name; |
|
|
|
|
const rtn = parentTable.table_name; |
|
|
|
|
|
|
|
|
|
const qb = this.dbDriver(tn).where(qb => { |
|
|
|
|
const qb = this.dbDriver(tn).where((qb) => { |
|
|
|
|
qb.whereNotIn( |
|
|
|
|
cn, |
|
|
|
|
this.dbDriver(rtn) |
|
|
|
@ -912,7 +952,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
|
|
|
|
|
const proto = await childModel.getProto(); |
|
|
|
|
|
|
|
|
|
return (await this.extractRawQueryAndExec(qb)).map(c => { |
|
|
|
|
return (await this.extractRawQueryAndExec(qb)).map((c) => { |
|
|
|
|
c.__proto__ = proto; |
|
|
|
|
return c; |
|
|
|
|
}); |
|
|
|
@ -923,8 +963,11 @@ class BaseModelSqlv2 {
|
|
|
|
|
{ colId, cid = null }, |
|
|
|
|
args |
|
|
|
|
): Promise<any> { |
|
|
|
|
const relColumn = (await this.model.getColumns()).find(c => c.id === colId); |
|
|
|
|
const relColOptions = (await relColumn.getColOptions()) as LinkToAnotherRecordColumn; |
|
|
|
|
const relColumn = (await this.model.getColumns()).find( |
|
|
|
|
(c) => c.id === colId |
|
|
|
|
); |
|
|
|
|
const relColOptions = |
|
|
|
|
(await relColumn.getColOptions()) as LinkToAnotherRecordColumn; |
|
|
|
|
|
|
|
|
|
const rcn = (await relColOptions.getParentColumn()).column_name; |
|
|
|
|
const parentTable = await ( |
|
|
|
@ -938,7 +981,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
await childTable.getColumns(); |
|
|
|
|
|
|
|
|
|
const qb = this.dbDriver(rtn) |
|
|
|
|
.where(qb => { |
|
|
|
|
.where((qb) => { |
|
|
|
|
qb.whereNotIn( |
|
|
|
|
rcn, |
|
|
|
|
this.dbDriver(tn) |
|
|
|
@ -961,8 +1004,11 @@ class BaseModelSqlv2 {
|
|
|
|
|
{ colId, cid = null }, |
|
|
|
|
args |
|
|
|
|
): Promise<any> { |
|
|
|
|
const relColumn = (await this.model.getColumns()).find(c => c.id === colId); |
|
|
|
|
const relColOptions = (await relColumn.getColOptions()) as LinkToAnotherRecordColumn; |
|
|
|
|
const relColumn = (await this.model.getColumns()).find( |
|
|
|
|
(c) => c.id === colId |
|
|
|
|
); |
|
|
|
|
const relColOptions = |
|
|
|
|
(await relColumn.getColOptions()) as LinkToAnotherRecordColumn; |
|
|
|
|
|
|
|
|
|
const rcn = (await relColOptions.getParentColumn()).column_name; |
|
|
|
|
const parentTable = await ( |
|
|
|
@ -972,13 +1018,13 @@ class BaseModelSqlv2 {
|
|
|
|
|
const childTable = await (await relColOptions.getChildColumn()).getModel(); |
|
|
|
|
const parentModel = await Model.getBaseModelSQL({ |
|
|
|
|
dbDriver: this.dbDriver, |
|
|
|
|
model: parentTable |
|
|
|
|
model: parentTable, |
|
|
|
|
}); |
|
|
|
|
const rtn = parentTable.table_name; |
|
|
|
|
const tn = childTable.table_name; |
|
|
|
|
await childTable.getColumns(); |
|
|
|
|
|
|
|
|
|
const qb = this.dbDriver(rtn).where(qb => { |
|
|
|
|
const qb = this.dbDriver(rtn).where((qb) => { |
|
|
|
|
qb.whereNotIn( |
|
|
|
|
rcn, |
|
|
|
|
this.dbDriver(tn) |
|
|
|
@ -998,7 +1044,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
applyPaginate(qb, args); |
|
|
|
|
|
|
|
|
|
const proto = await parentModel.getProto(); |
|
|
|
|
return (await this.extractRawQueryAndExec(qb)).map(c => { |
|
|
|
|
return (await this.extractRawQueryAndExec(qb)).map((c) => { |
|
|
|
|
c.__proto__ = proto; |
|
|
|
|
return c; |
|
|
|
|
}); |
|
|
|
@ -1028,15 +1074,16 @@ class BaseModelSqlv2 {
|
|
|
|
|
(await Column.get({ colId: colOptions.fk_relation_column_id })) |
|
|
|
|
?.title, |
|
|
|
|
(await Column.get({ colId: colOptions.fk_lookup_column_id })) |
|
|
|
|
?.title |
|
|
|
|
] |
|
|
|
|
?.title, |
|
|
|
|
], |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case UITypes.LinkToAnotherRecord: |
|
|
|
|
{ |
|
|
|
|
this._columns[column.title] = column; |
|
|
|
|
const colOptions = (await column.getColOptions()) as LinkToAnotherRecordColumn; |
|
|
|
|
const colOptions = |
|
|
|
|
(await column.getColOptions()) as LinkToAnotherRecordColumn; |
|
|
|
|
// const parentColumn = await colOptions.getParentColumn();
|
|
|
|
|
|
|
|
|
|
if (colOptions?.type === 'hm') { |
|
|
|
@ -1046,7 +1093,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
const data = await this.multipleHmList( |
|
|
|
|
{ |
|
|
|
|
colId: column.id, |
|
|
|
|
ids |
|
|
|
|
ids, |
|
|
|
|
}, |
|
|
|
|
(listLoader as any).args |
|
|
|
|
); |
|
|
|
@ -1056,10 +1103,10 @@ class BaseModelSqlv2 {
|
|
|
|
|
await this.hmList( |
|
|
|
|
{ |
|
|
|
|
colId: column.id, |
|
|
|
|
id: ids[0] |
|
|
|
|
id: ids[0], |
|
|
|
|
}, |
|
|
|
|
(listLoader as any).args |
|
|
|
|
) |
|
|
|
|
), |
|
|
|
|
]; |
|
|
|
|
} |
|
|
|
|
} catch (e) { |
|
|
|
@ -1069,7 +1116,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
}); |
|
|
|
|
const self: BaseModelSqlv2 = this; |
|
|
|
|
|
|
|
|
|
proto[column.title] = async function(args): Promise<any> { |
|
|
|
|
proto[column.title] = async function (args): Promise<any> { |
|
|
|
|
(listLoader as any).args = args; |
|
|
|
|
return listLoader.load( |
|
|
|
|
getCompositePk(self.model.primaryKeys, this) |
|
|
|
@ -1090,7 +1137,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
const data = await this.multipleMmList( |
|
|
|
|
{ |
|
|
|
|
parentIds: ids, |
|
|
|
|
colId: column.id |
|
|
|
|
colId: column.id, |
|
|
|
|
}, |
|
|
|
|
(listLoader as any).args |
|
|
|
|
); |
|
|
|
@ -1101,10 +1148,10 @@ class BaseModelSqlv2 {
|
|
|
|
|
await this.mmList( |
|
|
|
|
{ |
|
|
|
|
parentId: ids[0], |
|
|
|
|
colId: column.id |
|
|
|
|
colId: column.id, |
|
|
|
|
}, |
|
|
|
|
(listLoader as any).args |
|
|
|
|
) |
|
|
|
|
), |
|
|
|
|
]; |
|
|
|
|
} |
|
|
|
|
} catch (e) { |
|
|
|
@ -1115,7 +1162,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
|
|
|
|
|
const self: BaseModelSqlv2 = this; |
|
|
|
|
// const childColumn = await colOptions.getChildColumn();
|
|
|
|
|
proto[column.title] = async function(args): Promise<any> { |
|
|
|
|
proto[column.title] = async function (args): Promise<any> { |
|
|
|
|
(listLoader as any).args = args; |
|
|
|
|
return await listLoader.load( |
|
|
|
|
getCompositePk(self.model.primaryKeys, this) |
|
|
|
@ -1123,24 +1170,25 @@ class BaseModelSqlv2 {
|
|
|
|
|
}; |
|
|
|
|
} else if (colOptions.type === 'bt') { |
|
|
|
|
// @ts-ignore
|
|
|
|
|
const colOptions = (await column.getColOptions()) as LinkToAnotherRecordColumn; |
|
|
|
|
const colOptions = |
|
|
|
|
(await column.getColOptions()) as LinkToAnotherRecordColumn; |
|
|
|
|
const pCol = await Column.get({ |
|
|
|
|
colId: colOptions.fk_parent_column_id |
|
|
|
|
colId: colOptions.fk_parent_column_id, |
|
|
|
|
}); |
|
|
|
|
const cCol = await Column.get({ |
|
|
|
|
colId: colOptions.fk_child_column_id |
|
|
|
|
colId: colOptions.fk_child_column_id, |
|
|
|
|
}); |
|
|
|
|
const readLoader = new DataLoader(async (ids: string[]) => { |
|
|
|
|
try { |
|
|
|
|
const data = await ( |
|
|
|
|
await Model.getBaseModelSQL({ |
|
|
|
|
id: pCol.fk_model_id, |
|
|
|
|
dbDriver: this.dbDriver |
|
|
|
|
dbDriver: this.dbDriver, |
|
|
|
|
}) |
|
|
|
|
).list( |
|
|
|
|
{ |
|
|
|
|
// limit: ids.length,
|
|
|
|
|
where: `(${pCol.column_name},in,${ids.join(',')})` |
|
|
|
|
where: `(${pCol.column_name},in,${ids.join(',')})`, |
|
|
|
|
}, |
|
|
|
|
true |
|
|
|
|
); |
|
|
|
@ -1153,7 +1201,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
// defining HasMany count method within GQL Type class
|
|
|
|
|
proto[column.title] = async function() { |
|
|
|
|
proto[column.title] = async function () { |
|
|
|
|
if ( |
|
|
|
|
this?.[cCol?.title] === null || |
|
|
|
|
this?.[cCol?.title] === undefined |
|
|
|
@ -1214,7 +1262,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
qb.select( |
|
|
|
|
this.dbDriver.raw(`?? as ??`, [ |
|
|
|
|
selectQb.builder, |
|
|
|
|
sanitize(column.title) |
|
|
|
|
sanitize(column.title), |
|
|
|
|
]) |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
@ -1226,7 +1274,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
// tn: this.title,
|
|
|
|
|
knex: this.dbDriver, |
|
|
|
|
// column,
|
|
|
|
|
columnOptions: (await column.getColOptions()) as RollupColumn |
|
|
|
|
columnOptions: (await column.getColOptions()) as RollupColumn, |
|
|
|
|
}) |
|
|
|
|
).builder.as(sanitize(column.title)) |
|
|
|
|
); |
|
|
|
@ -1269,7 +1317,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
response = await this.extractRawQueryAndExec(query); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const ai = this.model.columns.find(c => c.ai); |
|
|
|
|
const ai = this.model.columns.find((c) => c.ai); |
|
|
|
|
if ( |
|
|
|
|
!response || |
|
|
|
|
(typeof response?.[0] !== 'object' && response?.[0] !== null) |
|
|
|
@ -1397,14 +1445,13 @@ class BaseModelSqlv2 {
|
|
|
|
|
const postInsertOps = []; |
|
|
|
|
|
|
|
|
|
const nestedCols = (await this.model.getColumns()).filter( |
|
|
|
|
c => c.uidt === UITypes.LinkToAnotherRecord |
|
|
|
|
(c) => c.uidt === UITypes.LinkToAnotherRecord |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
for (const col of nestedCols) { |
|
|
|
|
if (col.title in data) { |
|
|
|
|
const colOptions = await col.getColOptions< |
|
|
|
|
LinkToAnotherRecordColumn |
|
|
|
|
>(); |
|
|
|
|
const colOptions = |
|
|
|
|
await col.getColOptions<LinkToAnotherRecordColumn>(); |
|
|
|
|
|
|
|
|
|
// parse data if it's JSON string
|
|
|
|
|
const nestedData = |
|
|
|
@ -1429,11 +1476,11 @@ class BaseModelSqlv2 {
|
|
|
|
|
postInsertOps.push(async () => { |
|
|
|
|
await this.dbDriver(childModel.table_name) |
|
|
|
|
.update({ |
|
|
|
|
[childCol.column_name]: rowId |
|
|
|
|
[childCol.column_name]: rowId, |
|
|
|
|
}) |
|
|
|
|
.whereIn( |
|
|
|
|
childModel.primaryKey.column_name, |
|
|
|
|
nestedData?.map(r => r[childModel.primaryKey.title]) |
|
|
|
|
nestedData?.map((r) => r[childModel.primaryKey.title]) |
|
|
|
|
); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
@ -1442,15 +1489,15 @@ class BaseModelSqlv2 {
|
|
|
|
|
postInsertOps.push(async () => { |
|
|
|
|
const parentModel = await colOptions |
|
|
|
|
.getParentColumn() |
|
|
|
|
.then(c => c.getModel()); |
|
|
|
|
.then((c) => c.getModel()); |
|
|
|
|
await parentModel.getColumns(); |
|
|
|
|
const parentMMCol = await colOptions.getMMParentColumn(); |
|
|
|
|
const childMMCol = await colOptions.getMMChildColumn(); |
|
|
|
|
const mmModel = await colOptions.getMMModel(); |
|
|
|
|
|
|
|
|
|
const rows = nestedData.map(r => ({ |
|
|
|
|
const rows = nestedData.map((r) => ({ |
|
|
|
|
[parentMMCol.column_name]: r[parentModel.primaryKey.title], |
|
|
|
|
[childMMCol.column_name]: rowId |
|
|
|
|
[childMMCol.column_name]: rowId, |
|
|
|
|
})); |
|
|
|
|
await this.dbDriver(mmModel.table_name).insert(rows); |
|
|
|
|
}); |
|
|
|
@ -1473,7 +1520,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
response = await query; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const ai = this.model.columns.find(c => c.ai); |
|
|
|
|
const ai = this.model.columns.find((c) => c.ai); |
|
|
|
|
if ( |
|
|
|
|
!response || |
|
|
|
|
(typeof response?.[0] !== 'object' && response?.[0] !== null) |
|
|
|
@ -1503,7 +1550,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
rowId = |
|
|
|
|
response[this.model.primaryKey.title] || |
|
|
|
|
response[this.model.primaryKey.column_name]; |
|
|
|
|
await Promise.all(postInsertOps.map(f => f())); |
|
|
|
|
await Promise.all(postInsertOps.map((f) => f())); |
|
|
|
|
|
|
|
|
|
// if (!trx) {
|
|
|
|
|
// await driver.commit();
|
|
|
|
@ -1525,14 +1572,14 @@ class BaseModelSqlv2 {
|
|
|
|
|
async bulkInsert( |
|
|
|
|
datas: any[], |
|
|
|
|
{ |
|
|
|
|
chunkSize: _chunkSize = 100 |
|
|
|
|
chunkSize: _chunkSize = 100, |
|
|
|
|
}: { |
|
|
|
|
chunkSize?: number; |
|
|
|
|
} = {} |
|
|
|
|
) { |
|
|
|
|
try { |
|
|
|
|
const insertDatas = await Promise.all( |
|
|
|
|
datas.map(async d => { |
|
|
|
|
datas.map(async (d) => { |
|
|
|
|
await populatePk(this.model, d); |
|
|
|
|
return this.model.mapAliasToColumn(d); |
|
|
|
|
}) |
|
|
|
@ -1571,7 +1618,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
let transaction; |
|
|
|
|
try { |
|
|
|
|
const updateDatas = await Promise.all( |
|
|
|
|
datas.map(d => this.model.mapAliasToColumn(d)) |
|
|
|
|
datas.map((d) => this.model.mapAliasToColumn(d)) |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
transaction = await this.dbDriver.transaction(); |
|
|
|
@ -1627,14 +1674,14 @@ class BaseModelSqlv2 {
|
|
|
|
|
new Filter({ |
|
|
|
|
children: args.filterArr || [], |
|
|
|
|
is_group: true, |
|
|
|
|
logical_op: 'and' |
|
|
|
|
logical_op: 'and', |
|
|
|
|
}), |
|
|
|
|
new Filter({ |
|
|
|
|
children: filterObj, |
|
|
|
|
is_group: true, |
|
|
|
|
logical_op: 'and' |
|
|
|
|
logical_op: 'and', |
|
|
|
|
}), |
|
|
|
|
...(args.filterArr || []) |
|
|
|
|
...(args.filterArr || []), |
|
|
|
|
], |
|
|
|
|
qb, |
|
|
|
|
this.dbDriver |
|
|
|
@ -1689,14 +1736,14 @@ class BaseModelSqlv2 {
|
|
|
|
|
new Filter({ |
|
|
|
|
children: args.filterArr || [], |
|
|
|
|
is_group: true, |
|
|
|
|
logical_op: 'and' |
|
|
|
|
logical_op: 'and', |
|
|
|
|
}), |
|
|
|
|
new Filter({ |
|
|
|
|
children: filterObj, |
|
|
|
|
is_group: true, |
|
|
|
|
logical_op: 'and' |
|
|
|
|
logical_op: 'and', |
|
|
|
|
}), |
|
|
|
|
...(args.filterArr || []) |
|
|
|
|
...(args.filterArr || []), |
|
|
|
|
], |
|
|
|
|
qb, |
|
|
|
|
this.dbDriver |
|
|
|
@ -1730,7 +1777,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
), |
|
|
|
|
// details: JSON.stringify(data),
|
|
|
|
|
ip: req?.clientIp, |
|
|
|
|
user: req?.user?.email |
|
|
|
|
user: req?.user?.email, |
|
|
|
|
}); |
|
|
|
|
// }
|
|
|
|
|
} |
|
|
|
@ -1774,7 +1821,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
description: DOMPurify.sanitize(`${id} deleted from ${this.model.title}`), |
|
|
|
|
// details: JSON.stringify(data),
|
|
|
|
|
ip: req?.clientIp, |
|
|
|
|
user: req?.user?.email |
|
|
|
|
user: req?.user?.email, |
|
|
|
|
}); |
|
|
|
|
// }
|
|
|
|
|
await this.handleHooks('After.delete', data, req); |
|
|
|
@ -1790,8 +1837,8 @@ class BaseModelSqlv2 {
|
|
|
|
|
try { |
|
|
|
|
const formView = await view.getView<FormView>(); |
|
|
|
|
const emails = Object.entries(JSON.parse(formView?.email) || {}) |
|
|
|
|
.filter(a => a[1]) |
|
|
|
|
.map(a => a[0]); |
|
|
|
|
.filter((a) => a[1]) |
|
|
|
|
.map((a) => a[0]); |
|
|
|
|
if (emails?.length) { |
|
|
|
|
const transformedData = _transformSubmittedFormDataForEmail( |
|
|
|
|
data, |
|
|
|
@ -1805,8 +1852,8 @@ class BaseModelSqlv2 {
|
|
|
|
|
html: ejs.render(formSubmissionEmailTemplate, { |
|
|
|
|
data: transformedData, |
|
|
|
|
tn: this.model.table_name, |
|
|
|
|
_tn: this.model.title |
|
|
|
|
}) |
|
|
|
|
_tn: this.model.title, |
|
|
|
|
}), |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
} catch (e) { |
|
|
|
@ -1819,7 +1866,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
const hooks = await Hook.list({ |
|
|
|
|
fk_model_id: this.model.id, |
|
|
|
|
event, |
|
|
|
|
operation |
|
|
|
|
operation, |
|
|
|
|
}); |
|
|
|
|
for (const hook of hooks) { |
|
|
|
|
invokeWebhook(hook, this.model, data, req?.user); |
|
|
|
@ -1889,14 +1936,14 @@ class BaseModelSqlv2 {
|
|
|
|
|
async addChild({ |
|
|
|
|
colId, |
|
|
|
|
rowId, |
|
|
|
|
childId |
|
|
|
|
childId, |
|
|
|
|
}: { |
|
|
|
|
colId: string; |
|
|
|
|
rowId: string; |
|
|
|
|
childId: string; |
|
|
|
|
}) { |
|
|
|
|
const columns = await this.model.getColumns(); |
|
|
|
|
const column = columns.find(c => c.id === colId); |
|
|
|
|
const column = columns.find((c) => c.id === colId); |
|
|
|
|
|
|
|
|
|
if (!column || column.uidt !== UITypes.LinkToAnotherRecord) |
|
|
|
|
NcError.notFound('Column not found'); |
|
|
|
@ -1925,7 +1972,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
[vChildCol.column_name]: this.dbDriver(childTable.table_name) |
|
|
|
|
.select(childColumn.column_name) |
|
|
|
|
.where(_wherePk(childTable.primaryKeys, rowId)) |
|
|
|
|
.first() |
|
|
|
|
.first(), |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
@ -1939,7 +1986,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
.where(_wherePk(parentTable.primaryKeys, rowId)) |
|
|
|
|
.first() |
|
|
|
|
.as('___cn_alias') |
|
|
|
|
) |
|
|
|
|
), |
|
|
|
|
}) |
|
|
|
|
.where(_wherePk(childTable.primaryKeys, childId)); |
|
|
|
|
} |
|
|
|
@ -1954,7 +2001,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
.where(_wherePk(parentTable.primaryKeys, childId)) |
|
|
|
|
.first() |
|
|
|
|
.as('___cn_alias') |
|
|
|
|
) |
|
|
|
|
), |
|
|
|
|
}) |
|
|
|
|
.where(_wherePk(childTable.primaryKeys, rowId)); |
|
|
|
|
} |
|
|
|
@ -1965,14 +2012,14 @@ class BaseModelSqlv2 {
|
|
|
|
|
async removeChild({ |
|
|
|
|
colId, |
|
|
|
|
rowId, |
|
|
|
|
childId |
|
|
|
|
childId, |
|
|
|
|
}: { |
|
|
|
|
colId: string; |
|
|
|
|
rowId: string; |
|
|
|
|
childId: string; |
|
|
|
|
}) { |
|
|
|
|
const columns = await this.model.getColumns(); |
|
|
|
|
const column = columns.find(c => c.id === colId); |
|
|
|
|
const column = columns.find((c) => c.id === colId); |
|
|
|
|
|
|
|
|
|
if (!column || column.uidt !== UITypes.LinkToAnotherRecord) |
|
|
|
|
NcError.notFound('Column not found'); |
|
|
|
@ -2002,7 +2049,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
[vChildCol.column_name]: this.dbDriver(childTable.table_name) |
|
|
|
|
.select(childColumn.column_name) |
|
|
|
|
.where(_wherePk(childTable.primaryKeys, rowId)) |
|
|
|
|
.first() |
|
|
|
|
.first(), |
|
|
|
|
}) |
|
|
|
|
.delete(); |
|
|
|
|
} |
|
|
|
@ -2063,7 +2110,7 @@ function extractSortsObject(
|
|
|
|
|
|
|
|
|
|
if (!Array.isArray(sorts)) sorts = sorts.split(','); |
|
|
|
|
|
|
|
|
|
return sorts.map(s => { |
|
|
|
|
return sorts.map((s) => { |
|
|
|
|
const sort: SortType = { direction: 'asc' }; |
|
|
|
|
if (s.startsWith('-')) { |
|
|
|
|
sort.direction = 'desc'; |
|
|
|
@ -2133,7 +2180,7 @@ function extractFilterFromXwhere(
|
|
|
|
|
children: extractFilterFromXwhere( |
|
|
|
|
str.substring(openIndex + 1, closingIndex + 1), |
|
|
|
|
aliasColObjMap |
|
|
|
|
) |
|
|
|
|
), |
|
|
|
|
}), |
|
|
|
|
// RHS of nested query(recursion)
|
|
|
|
|
...extractFilterFromXwhere(str.substring(closingIndex + 2), aliasColObjMap) |
|
|
|
@ -2142,7 +2189,7 @@ function extractFilterFromXwhere(
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function extractCondition(nestedArrayConditions, aliasColObjMap) { |
|
|
|
|
return nestedArrayConditions?.map(str => { |
|
|
|
|
return nestedArrayConditions?.map((str) => { |
|
|
|
|
// eslint-disable-next-line prefer-const
|
|
|
|
|
let [logicOp, alias, op, value] = |
|
|
|
|
str.match(/(?:~(and|or|not))?\((.*?),(\w+),(.*)\)/)?.slice(1) || []; |
|
|
|
@ -2152,7 +2199,7 @@ function extractCondition(nestedArrayConditions, aliasColObjMap) {
|
|
|
|
|
comparison_op: op, |
|
|
|
|
fk_column_id: aliasColObjMap[alias]?.id, |
|
|
|
|
logical_op: logicOp, |
|
|
|
|
value |
|
|
|
|
value, |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
@ -2162,7 +2209,7 @@ function applyPaginate(
|
|
|
|
|
{ |
|
|
|
|
limit = 20, |
|
|
|
|
offset = 0, |
|
|
|
|
ignoreLimit = false |
|
|
|
|
ignoreLimit = false, |
|
|
|
|
}: XcFilter & { ignoreLimit?: boolean } |
|
|
|
|
) { |
|
|
|
|
query.offset(offset); |
|
|
|
@ -2181,7 +2228,7 @@ function _wherePk(primaryKeys: Column[], id) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function getCompositePk(primaryKeys: Column[], row) { |
|
|
|
|
return primaryKeys.map(c => row[c.title]).join('___'); |
|
|
|
|
return primaryKeys.map((c) => row[c.title]).join('___'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
export { BaseModelSqlv2 }; |
|
|
|
|