|
|
|
@ -165,7 +165,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
let data; |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
data = (await this.execAndParse(qb))?.[0]; |
|
|
|
|
data = await this.execAndParse(qb, null, { first: true }); |
|
|
|
|
} catch (e) { |
|
|
|
|
if (validateFormula || !haveFormulaColumn(await this.model.getColumns())) |
|
|
|
|
throw e; |
|
|
|
@ -194,7 +194,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
qb.where(_wherePk(pks, id)).first(); |
|
|
|
|
return !!(await qb); |
|
|
|
|
return !!(await this.execAndParse(qb, null, { raw: true, first: true })); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// todo: add support for sortArrJson
|
|
|
|
@ -240,7 +240,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
let data; |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
data = await qb.first(); |
|
|
|
|
data = await this.execAndParse(qb, null, { first: true }); |
|
|
|
|
} catch (e) { |
|
|
|
|
if (validateFormula || !haveFormulaColumn(await this.model.getColumns())) |
|
|
|
|
throw e; |
|
|
|
@ -452,10 +452,8 @@ class BaseModelSqlv2 {
|
|
|
|
|
sql = unsanitize(qb.toQuery()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const res = (await this.dbDriver.raw(sql)) as any; |
|
|
|
|
|
|
|
|
|
return (this.isPg || this.isSnowflake ? res.rows[0] : res[0][0] ?? res[0]) |
|
|
|
|
.count; |
|
|
|
|
return (await this.execAndParse(sql, null, { raw: true, first: true })) |
|
|
|
|
?.count; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async groupByAndAggregate( |
|
|
|
@ -516,7 +514,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
qb.orderBy(args.sortBy.column_name, args.sortBy.direction); |
|
|
|
|
} |
|
|
|
|
applyPaginate(qb, rest); |
|
|
|
|
return await qb; |
|
|
|
|
return await this.execAndParse(qb); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async groupBy(args: { |
|
|
|
@ -680,7 +678,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
qb.groupBy(...groupBySelectors); |
|
|
|
|
|
|
|
|
|
applyPaginate(qb, rest); |
|
|
|
|
return await qb; |
|
|
|
|
return await this.execAndParse(qb); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async groupByCount(args: { |
|
|
|
@ -819,7 +817,8 @@ class BaseModelSqlv2 {
|
|
|
|
|
.count('*', { as: 'count' }) |
|
|
|
|
.from(qb.as('groupby')); |
|
|
|
|
|
|
|
|
|
return (await qbP.first())?.count; |
|
|
|
|
return (await this.execAndParse(qbP, null, { raw: true, first: true })) |
|
|
|
|
?.count; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async multipleHmList( |
|
|
|
@ -947,22 +946,26 @@ class BaseModelSqlv2 {
|
|
|
|
|
const childTn = this.getTnPath(childTable); |
|
|
|
|
const parentTn = this.getTnPath(parentTable); |
|
|
|
|
|
|
|
|
|
const children = await this.dbDriver.unionAll( |
|
|
|
|
ids.map((p) => { |
|
|
|
|
const query = this.dbDriver(childTn) |
|
|
|
|
.count(`${chilCol?.column_name} as count`) |
|
|
|
|
.whereIn( |
|
|
|
|
chilCol.column_name, |
|
|
|
|
this.dbDriver(parentTn) |
|
|
|
|
.select(parentCol.column_name) |
|
|
|
|
// .where(parentTable.primaryKey.cn, p)
|
|
|
|
|
.where(_wherePk(parentTable.primaryKeys, p)), |
|
|
|
|
) |
|
|
|
|
.first(); |
|
|
|
|
const children = await this.execAndParse( |
|
|
|
|
this.dbDriver.unionAll( |
|
|
|
|
ids.map((p) => { |
|
|
|
|
const query = this.dbDriver(childTn) |
|
|
|
|
.count(`${chilCol?.column_name} as count`) |
|
|
|
|
.whereIn( |
|
|
|
|
chilCol.column_name, |
|
|
|
|
this.dbDriver(parentTn) |
|
|
|
|
.select(parentCol.column_name) |
|
|
|
|
// .where(parentTable.primaryKey.cn, p)
|
|
|
|
|
.where(_wherePk(parentTable.primaryKeys, p)), |
|
|
|
|
) |
|
|
|
|
.first(); |
|
|
|
|
|
|
|
|
|
return this.isSqlite ? this.dbDriver.select().from(query) : query; |
|
|
|
|
}), |
|
|
|
|
!this.isSqlite, |
|
|
|
|
return this.isSqlite ? this.dbDriver.select().from(query) : query; |
|
|
|
|
}), |
|
|
|
|
!this.isSqlite, |
|
|
|
|
), |
|
|
|
|
null, |
|
|
|
|
{ raw: true }, |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
return children.map(({ count }) => count); |
|
|
|
@ -1069,7 +1072,8 @@ class BaseModelSqlv2 {
|
|
|
|
|
|
|
|
|
|
await conditionV2(this, filterObj, query); |
|
|
|
|
|
|
|
|
|
return (await query.first())?.count; |
|
|
|
|
return (await this.execAndParse(query, null, { raw: true, first: true })) |
|
|
|
|
?.count; |
|
|
|
|
} catch (e) { |
|
|
|
|
console.log(e); |
|
|
|
|
throw e; |
|
|
|
@ -1249,22 +1253,26 @@ class BaseModelSqlv2 {
|
|
|
|
|
.count(`${vtn}.${vcn}`, { as: 'count' }); |
|
|
|
|
|
|
|
|
|
// await childModel.selectObject({ qb });
|
|
|
|
|
const children = await this.dbDriver.unionAll( |
|
|
|
|
parentIds.map((id) => { |
|
|
|
|
const query = qb |
|
|
|
|
.clone() |
|
|
|
|
.whereIn( |
|
|
|
|
`${vtn}.${vcn}`, |
|
|
|
|
this.dbDriver(parentTn) |
|
|
|
|
.select(cn) |
|
|
|
|
// .where(parentTable.primaryKey.cn, id)
|
|
|
|
|
.where(_wherePk(parentTable.primaryKeys, id)), |
|
|
|
|
) |
|
|
|
|
.select(this.dbDriver.raw('? as ??', [id, GROUP_COL])); |
|
|
|
|
// this._paginateAndSort(query, { sort, limit, offset }, null, true);
|
|
|
|
|
return this.isSqlite ? this.dbDriver.select().from(query) : query; |
|
|
|
|
}), |
|
|
|
|
!this.isSqlite, |
|
|
|
|
const children = await this.execAndParse( |
|
|
|
|
this.dbDriver.unionAll( |
|
|
|
|
parentIds.map((id) => { |
|
|
|
|
const query = qb |
|
|
|
|
.clone() |
|
|
|
|
.whereIn( |
|
|
|
|
`${vtn}.${vcn}`, |
|
|
|
|
this.dbDriver(parentTn) |
|
|
|
|
.select(cn) |
|
|
|
|
// .where(parentTable.primaryKey.cn, id)
|
|
|
|
|
.where(_wherePk(parentTable.primaryKeys, id)), |
|
|
|
|
) |
|
|
|
|
.select(this.dbDriver.raw('? as ??', [id, GROUP_COL])); |
|
|
|
|
// this._paginateAndSort(query, { sort, limit, offset }, null, true);
|
|
|
|
|
return this.isSqlite ? this.dbDriver.select().from(query) : query; |
|
|
|
|
}), |
|
|
|
|
!this.isSqlite, |
|
|
|
|
), |
|
|
|
|
null, |
|
|
|
|
{ raw: true }, |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
const gs = groupBy(children, GROUP_COL); |
|
|
|
@ -1312,7 +1320,8 @@ class BaseModelSqlv2 {
|
|
|
|
|
const filterObj = extractFilterFromXwhere(where, aliasColObjMap); |
|
|
|
|
|
|
|
|
|
await conditionV2(this, filterObj, qb); |
|
|
|
|
return (await qb.first())?.count; |
|
|
|
|
return (await this.execAndParse(qb, null, { raw: true, first: true })) |
|
|
|
|
?.count; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// todo: naming & optimizing
|
|
|
|
@ -1363,7 +1372,8 @@ class BaseModelSqlv2 {
|
|
|
|
|
const filterObj = extractFilterFromXwhere(where, aliasColObjMap); |
|
|
|
|
|
|
|
|
|
await conditionV2(this, filterObj, qb); |
|
|
|
|
return (await qb.first())?.count; |
|
|
|
|
return (await this.execAndParse(qb, null, { raw: true, first: true })) |
|
|
|
|
?.count; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// todo: naming & optimizing
|
|
|
|
@ -1486,7 +1496,8 @@ class BaseModelSqlv2 {
|
|
|
|
|
|
|
|
|
|
await conditionV2(this, filterObj, qb); |
|
|
|
|
|
|
|
|
|
return (await qb.first())?.count; |
|
|
|
|
return (await this.execAndParse(qb, null, { raw: true, first: true })) |
|
|
|
|
?.count; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// todo: naming & optimizing
|
|
|
|
@ -1601,7 +1612,8 @@ class BaseModelSqlv2 {
|
|
|
|
|
const filterObj = extractFilterFromXwhere(where, aliasColObjMap); |
|
|
|
|
|
|
|
|
|
await conditionV2(this, filterObj, qb); |
|
|
|
|
return (await qb.first())?.count; |
|
|
|
|
return (await this.execAndParse(qb, null, { raw: true, first: true })) |
|
|
|
|
?.count; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// todo: naming & optimizing
|
|
|
|
@ -2256,16 +2268,24 @@ class BaseModelSqlv2 {
|
|
|
|
|
if (this.isSqlite) { |
|
|
|
|
// sqlite doesnt return id after insert
|
|
|
|
|
id = ( |
|
|
|
|
await this.dbDriver(this.tnPath) |
|
|
|
|
.select(ai.column_name) |
|
|
|
|
.max(ai.column_name, { as: 'id' }) |
|
|
|
|
await this.execAndParse( |
|
|
|
|
this.dbDriver(this.tnPath) |
|
|
|
|
.select(ai.column_name) |
|
|
|
|
.max(ai.column_name, { as: 'id' }), |
|
|
|
|
null, |
|
|
|
|
{ raw: true }, |
|
|
|
|
) |
|
|
|
|
)[0].id; |
|
|
|
|
} else if (this.isSnowflake) { |
|
|
|
|
id = ( |
|
|
|
|
(await this.dbDriver(this.tnPath).max(ai.column_name, { |
|
|
|
|
as: 'id', |
|
|
|
|
})) as any |
|
|
|
|
)[0].id; |
|
|
|
|
await this.execAndParse( |
|
|
|
|
this.dbDriver(this.tnPath).max(ai.column_name, { |
|
|
|
|
as: 'id', |
|
|
|
|
}), |
|
|
|
|
null, |
|
|
|
|
{ raw: true, first: true }, |
|
|
|
|
) |
|
|
|
|
).id; |
|
|
|
|
} |
|
|
|
|
response = await this.readByPk( |
|
|
|
|
id, |
|
|
|
@ -2399,23 +2419,31 @@ class BaseModelSqlv2 {
|
|
|
|
|
let cnt = 0; |
|
|
|
|
if (colOptions.type === RelationTypes.HAS_MANY) { |
|
|
|
|
cnt = +( |
|
|
|
|
await this.dbDriver(this.getTnPath(childModel.table_name)) |
|
|
|
|
.count(childColumn.column_name, { as: 'cnt' }) |
|
|
|
|
.where(childColumn.column_name, rowId) |
|
|
|
|
)[0].cnt; |
|
|
|
|
await this.execAndParse( |
|
|
|
|
this.dbDriver(this.getTnPath(childModel.table_name)) |
|
|
|
|
.count(childColumn.column_name, { as: 'cnt' }) |
|
|
|
|
.where(childColumn.column_name, rowId), |
|
|
|
|
null, |
|
|
|
|
{ raw: true, first: true }, |
|
|
|
|
) |
|
|
|
|
).cnt; |
|
|
|
|
} else if (colOptions.type === RelationTypes.MANY_TO_MANY) { |
|
|
|
|
const mmModel = await colOptions.getMMModel(); |
|
|
|
|
const mmChildColumn = await colOptions.getMMChildColumn(); |
|
|
|
|
cnt = +( |
|
|
|
|
await this.dbDriver(this.getTnPath(mmModel.table_name)) |
|
|
|
|
.where( |
|
|
|
|
`${this.getTnPath(mmModel.table_name)}.${ |
|
|
|
|
mmChildColumn.column_name |
|
|
|
|
}`,
|
|
|
|
|
rowId, |
|
|
|
|
) |
|
|
|
|
.count(mmChildColumn.column_name, { as: 'cnt' }) |
|
|
|
|
)[0].cnt; |
|
|
|
|
await this.execAndParse( |
|
|
|
|
this.dbDriver(this.getTnPath(mmModel.table_name)) |
|
|
|
|
.where( |
|
|
|
|
`${this.getTnPath(mmModel.table_name)}.${ |
|
|
|
|
mmChildColumn.column_name |
|
|
|
|
}`,
|
|
|
|
|
rowId, |
|
|
|
|
) |
|
|
|
|
.count(mmChildColumn.column_name, { as: 'cnt' }), |
|
|
|
|
null, |
|
|
|
|
{ first: true }, |
|
|
|
|
) |
|
|
|
|
).cnt; |
|
|
|
|
} |
|
|
|
|
if (cnt) { |
|
|
|
|
res.push( |
|
|
|
@ -2569,7 +2597,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
query.returning( |
|
|
|
|
`${this.model.primaryKey.column_name} as ${this.model.primaryKey.title}`, |
|
|
|
|
); |
|
|
|
|
response = await query; |
|
|
|
|
response = await this.execAndParse(query); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const ai = this.model.columns.find((c) => c.ai); |
|
|
|
@ -2580,23 +2608,37 @@ class BaseModelSqlv2 {
|
|
|
|
|
if (response?.length) { |
|
|
|
|
rowId = response[0]; |
|
|
|
|
} else { |
|
|
|
|
rowId = (await query)[0]; |
|
|
|
|
rowId = await this.execAndParse(query, null, { |
|
|
|
|
raw: true, |
|
|
|
|
first: true, |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (ai) { |
|
|
|
|
if (this.isSqlite) { |
|
|
|
|
// sqlite doesnt return id after insert
|
|
|
|
|
rowId = ( |
|
|
|
|
await this.dbDriver(this.tnPath) |
|
|
|
|
.select(ai.column_name) |
|
|
|
|
.max(ai.column_name, { as: 'id' }) |
|
|
|
|
)[0].id; |
|
|
|
|
await this.execAndParse( |
|
|
|
|
this.dbDriver(this.tnPath) |
|
|
|
|
.select(ai.column_name) |
|
|
|
|
.max(ai.column_name, { as: 'id' }), |
|
|
|
|
null, |
|
|
|
|
{ |
|
|
|
|
raw: true, |
|
|
|
|
first: true, |
|
|
|
|
}, |
|
|
|
|
) |
|
|
|
|
)?.id; |
|
|
|
|
} else if (this.isSnowflake) { |
|
|
|
|
rowId = ( |
|
|
|
|
(await this.dbDriver(this.tnPath).max(ai.column_name, { |
|
|
|
|
as: 'id', |
|
|
|
|
})) as any |
|
|
|
|
).rows[0].id; |
|
|
|
|
await this.execAndParse( |
|
|
|
|
this.dbDriver(this.tnPath).max(ai.column_name, { |
|
|
|
|
as: 'id', |
|
|
|
|
}), |
|
|
|
|
null, |
|
|
|
|
{ raw: true, first: true }, |
|
|
|
|
) |
|
|
|
|
)?.id; |
|
|
|
|
} |
|
|
|
|
// response = await this.readByPk(
|
|
|
|
|
// id,
|
|
|
|
@ -2921,7 +2963,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
|
|
|
|
|
for (const insertData of insertDatas) { |
|
|
|
|
const query = trx(this.tnPath).insert(insertData); |
|
|
|
|
const id = (await query)[0]; |
|
|
|
|
const id = await query; |
|
|
|
|
response.push(aiPkCol ? { [aiPkCol.title]: id } : id); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
@ -3115,9 +3157,16 @@ class BaseModelSqlv2 {
|
|
|
|
|
|
|
|
|
|
await conditionV2(this, conditionObj, qb); |
|
|
|
|
|
|
|
|
|
count = ( |
|
|
|
|
await this.execAndParse(qb.clone().count(), null, { |
|
|
|
|
raw: true, |
|
|
|
|
first: true, |
|
|
|
|
}) |
|
|
|
|
)?.count; |
|
|
|
|
|
|
|
|
|
qb.update(updateData); |
|
|
|
|
|
|
|
|
|
count = (await qb) as any; |
|
|
|
|
await this.execAndParse(qb, null, { raw: true }); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
await this.afterBulkUpdate(null, count, this.dbDriver, cookie, true); |
|
|
|
@ -3704,52 +3753,68 @@ class BaseModelSqlv2 {
|
|
|
|
|
.where(_wherePk(childTable.primaryKeys, rowId)) |
|
|
|
|
.first(); |
|
|
|
|
|
|
|
|
|
await this.dbDriver.raw( |
|
|
|
|
`INSERT INTO ?? (??, ??) SELECT (${parentPK.toQuery()}), (${childPK.toQuery()})`, |
|
|
|
|
[vTn, vParentCol.column_name, vChildCol.column_name], |
|
|
|
|
await this.execAndParse( |
|
|
|
|
this.dbDriver.raw( |
|
|
|
|
`INSERT INTO ?? (??, ??) SELECT (${parentPK.toQuery()}), (${childPK.toQuery()})`, |
|
|
|
|
[vTn, vParentCol.column_name, vChildCol.column_name], |
|
|
|
|
) as any, |
|
|
|
|
null, |
|
|
|
|
{ raw: true }, |
|
|
|
|
); |
|
|
|
|
} else { |
|
|
|
|
await this.dbDriver(vTn).insert({ |
|
|
|
|
[vParentCol.column_name]: this.dbDriver(parentTn) |
|
|
|
|
.select(parentColumn.column_name) |
|
|
|
|
.where(_wherePk(parentTable.primaryKeys, childId)) |
|
|
|
|
.first(), |
|
|
|
|
[vChildCol.column_name]: this.dbDriver(childTn) |
|
|
|
|
.select(childColumn.column_name) |
|
|
|
|
.where(_wherePk(childTable.primaryKeys, rowId)) |
|
|
|
|
.first(), |
|
|
|
|
}); |
|
|
|
|
await this.execAndParse( |
|
|
|
|
this.dbDriver(vTn).insert({ |
|
|
|
|
[vParentCol.column_name]: this.dbDriver(parentTn) |
|
|
|
|
.select(parentColumn.column_name) |
|
|
|
|
.where(_wherePk(parentTable.primaryKeys, childId)) |
|
|
|
|
.first(), |
|
|
|
|
[vChildCol.column_name]: this.dbDriver(childTn) |
|
|
|
|
.select(childColumn.column_name) |
|
|
|
|
.where(_wherePk(childTable.primaryKeys, rowId)) |
|
|
|
|
.first(), |
|
|
|
|
}), |
|
|
|
|
null, |
|
|
|
|
{ raw: true }, |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case RelationTypes.HAS_MANY: |
|
|
|
|
{ |
|
|
|
|
await this.dbDriver(childTn) |
|
|
|
|
.update({ |
|
|
|
|
[childColumn.column_name]: this.dbDriver.from( |
|
|
|
|
this.dbDriver(parentTn) |
|
|
|
|
.select(parentColumn.column_name) |
|
|
|
|
.where(_wherePk(parentTable.primaryKeys, rowId)) |
|
|
|
|
.first() |
|
|
|
|
.as('___cn_alias'), |
|
|
|
|
), |
|
|
|
|
}) |
|
|
|
|
.where(_wherePk(childTable.primaryKeys, childId)); |
|
|
|
|
await this.execAndParse( |
|
|
|
|
this.dbDriver(childTn) |
|
|
|
|
.update({ |
|
|
|
|
[childColumn.column_name]: this.dbDriver.from( |
|
|
|
|
this.dbDriver(parentTn) |
|
|
|
|
.select(parentColumn.column_name) |
|
|
|
|
.where(_wherePk(parentTable.primaryKeys, rowId)) |
|
|
|
|
.first() |
|
|
|
|
.as('___cn_alias'), |
|
|
|
|
), |
|
|
|
|
}) |
|
|
|
|
.where(_wherePk(childTable.primaryKeys, childId)), |
|
|
|
|
null, |
|
|
|
|
{ raw: true }, |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case RelationTypes.BELONGS_TO: |
|
|
|
|
{ |
|
|
|
|
await this.dbDriver(childTn) |
|
|
|
|
.update({ |
|
|
|
|
[childColumn.column_name]: this.dbDriver.from( |
|
|
|
|
this.dbDriver(parentTn) |
|
|
|
|
.select(parentColumn.column_name) |
|
|
|
|
.where(_wherePk(parentTable.primaryKeys, childId)) |
|
|
|
|
.first() |
|
|
|
|
.as('___cn_alias'), |
|
|
|
|
), |
|
|
|
|
}) |
|
|
|
|
.where(_wherePk(childTable.primaryKeys, rowId)); |
|
|
|
|
await this.execAndParse( |
|
|
|
|
this.dbDriver(childTn) |
|
|
|
|
.update({ |
|
|
|
|
[childColumn.column_name]: this.dbDriver.from( |
|
|
|
|
this.dbDriver(parentTn) |
|
|
|
|
.select(parentColumn.column_name) |
|
|
|
|
.where(_wherePk(parentTable.primaryKeys, childId)) |
|
|
|
|
.first() |
|
|
|
|
.as('___cn_alias'), |
|
|
|
|
), |
|
|
|
|
}) |
|
|
|
|
.where(_wherePk(childTable.primaryKeys, rowId)), |
|
|
|
|
null, |
|
|
|
|
{ raw: true }, |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
@ -3827,44 +3892,56 @@ class BaseModelSqlv2 {
|
|
|
|
|
|
|
|
|
|
const vTn = this.getTnPath(vTable); |
|
|
|
|
|
|
|
|
|
await this.dbDriver(vTn) |
|
|
|
|
.where({ |
|
|
|
|
[vParentCol.column_name]: this.dbDriver(parentTn) |
|
|
|
|
.select(parentColumn.column_name) |
|
|
|
|
.where(_wherePk(parentTable.primaryKeys, childId)) |
|
|
|
|
.first(), |
|
|
|
|
[vChildCol.column_name]: this.dbDriver(childTn) |
|
|
|
|
.select(childColumn.column_name) |
|
|
|
|
.where(_wherePk(childTable.primaryKeys, rowId)) |
|
|
|
|
.first(), |
|
|
|
|
}) |
|
|
|
|
.delete(); |
|
|
|
|
await this.execAndParse( |
|
|
|
|
this.dbDriver(vTn) |
|
|
|
|
.where({ |
|
|
|
|
[vParentCol.column_name]: this.dbDriver(parentTn) |
|
|
|
|
.select(parentColumn.column_name) |
|
|
|
|
.where(_wherePk(parentTable.primaryKeys, childId)) |
|
|
|
|
.first(), |
|
|
|
|
[vChildCol.column_name]: this.dbDriver(childTn) |
|
|
|
|
.select(childColumn.column_name) |
|
|
|
|
.where(_wherePk(childTable.primaryKeys, rowId)) |
|
|
|
|
.first(), |
|
|
|
|
}) |
|
|
|
|
.delete(), |
|
|
|
|
null, |
|
|
|
|
{ raw: true }, |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case RelationTypes.HAS_MANY: |
|
|
|
|
{ |
|
|
|
|
await this.dbDriver(childTn) |
|
|
|
|
// .where({
|
|
|
|
|
// [childColumn.cn]: this.dbDriver(parentTable.tn)
|
|
|
|
|
// .select(parentColumn.cn)
|
|
|
|
|
// .where(parentTable.primaryKey.cn, rowId)
|
|
|
|
|
// .first()
|
|
|
|
|
// })
|
|
|
|
|
.where(_wherePk(childTable.primaryKeys, childId)) |
|
|
|
|
.update({ [childColumn.column_name]: null }); |
|
|
|
|
await this.execAndParse( |
|
|
|
|
this.dbDriver(childTn) |
|
|
|
|
// .where({
|
|
|
|
|
// [childColumn.cn]: this.dbDriver(parentTable.tn)
|
|
|
|
|
// .select(parentColumn.cn)
|
|
|
|
|
// .where(parentTable.primaryKey.cn, rowId)
|
|
|
|
|
// .first()
|
|
|
|
|
// })
|
|
|
|
|
.where(_wherePk(childTable.primaryKeys, childId)) |
|
|
|
|
.update({ [childColumn.column_name]: null }), |
|
|
|
|
null, |
|
|
|
|
{ raw: true }, |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case RelationTypes.BELONGS_TO: |
|
|
|
|
{ |
|
|
|
|
await this.dbDriver(childTn) |
|
|
|
|
// .where({
|
|
|
|
|
// [childColumn.cn]: this.dbDriver(parentTable.tn)
|
|
|
|
|
// .select(parentColumn.cn)
|
|
|
|
|
// .where(parentTable.primaryKey.cn, childId)
|
|
|
|
|
// .first()
|
|
|
|
|
// })
|
|
|
|
|
.where(_wherePk(childTable.primaryKeys, rowId)) |
|
|
|
|
.update({ [childColumn.column_name]: null }); |
|
|
|
|
await this.execAndParse( |
|
|
|
|
this.dbDriver(childTn) |
|
|
|
|
// .where({
|
|
|
|
|
// [childColumn.cn]: this.dbDriver(parentTable.tn)
|
|
|
|
|
// .select(parentColumn.cn)
|
|
|
|
|
// .where(parentTable.primaryKey.cn, childId)
|
|
|
|
|
// .first()
|
|
|
|
|
// })
|
|
|
|
|
.where(_wherePk(childTable.primaryKeys, rowId)) |
|
|
|
|
.update({ [childColumn.column_name]: null }), |
|
|
|
|
null, |
|
|
|
|
{ raw: true }, |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
@ -3931,9 +4008,11 @@ class BaseModelSqlv2 {
|
|
|
|
|
} else { |
|
|
|
|
groupingValues = new Set( |
|
|
|
|
( |
|
|
|
|
await this.dbDriver(this.tnPath) |
|
|
|
|
.select(column.column_name) |
|
|
|
|
.distinct() |
|
|
|
|
await this.execAndParse( |
|
|
|
|
this.dbDriver(this.tnPath).select(column.column_name).distinct(), |
|
|
|
|
null, |
|
|
|
|
{ raw: true }, |
|
|
|
|
) |
|
|
|
|
).map((row) => row[column.column_name]), |
|
|
|
|
); |
|
|
|
|
groupingValues.add(null); |
|
|
|
@ -4132,13 +4211,36 @@ class BaseModelSqlv2 {
|
|
|
|
|
columns: [new Column({ ...column, title: 'key' })], |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
return await qb; |
|
|
|
|
return await this.execAndParse(qb); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected async execAndParse(qb: Knex.QueryBuilder, childTable?: Model) { |
|
|
|
|
let query = qb.toQuery(); |
|
|
|
|
public async execAndParse( |
|
|
|
|
qb: Knex.QueryBuilder | string, |
|
|
|
|
childTable?: Model, |
|
|
|
|
options: { |
|
|
|
|
skipDateConversion?: boolean; |
|
|
|
|
skipAttachmentConversion?: boolean; |
|
|
|
|
raw?: boolean; // alias for skipDateConversion and skipAttachmentConversion
|
|
|
|
|
first?: boolean; |
|
|
|
|
} = { |
|
|
|
|
skipDateConversion: false, |
|
|
|
|
skipAttachmentConversion: false, |
|
|
|
|
raw: false, |
|
|
|
|
first: false, |
|
|
|
|
}, |
|
|
|
|
) { |
|
|
|
|
if (options.raw) { |
|
|
|
|
options.skipDateConversion = true; |
|
|
|
|
options.skipAttachmentConversion = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (options.first && typeof qb !== 'string') { |
|
|
|
|
qb = qb.limit(1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
let query = typeof qb === 'string' ? qb : qb.toQuery(); |
|
|
|
|
if (!this.isPg && !this.isMssql && !this.isSnowflake) { |
|
|
|
|
query = unsanitize(qb.toQuery()); |
|
|
|
|
query = unsanitize(query); |
|
|
|
|
} else { |
|
|
|
|
query = sanitize(query); |
|
|
|
|
} |
|
|
|
@ -4153,10 +4255,18 @@ class BaseModelSqlv2 {
|
|
|
|
|
: await this.dbDriver.raw(query); |
|
|
|
|
|
|
|
|
|
// update attachment fields
|
|
|
|
|
data = await this.convertAttachmentType(data, childTable); |
|
|
|
|
if (!options.skipAttachmentConversion) { |
|
|
|
|
data = await this.convertAttachmentType(data, childTable); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// update date time fields
|
|
|
|
|
data = this.convertDateFormat(data, childTable); |
|
|
|
|
if (!options.skipDateConversion) { |
|
|
|
|
data = this.convertDateFormat(data, childTable); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (options.first) { |
|
|
|
|
return data?.[0]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return data; |
|
|
|
|
} |
|
|
|
@ -4543,7 +4653,9 @@ class BaseModelSqlv2 {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// todo: use bulk insert
|
|
|
|
|
await this.dbDriver(vTn).insert(insertData); |
|
|
|
|
await this.execAndParse(this.dbDriver(vTn).insert(insertData), null, { |
|
|
|
|
raw: true, |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case RelationTypes.HAS_MANY: |
|
|
|
@ -4613,7 +4725,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
: childIds, |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
await updateQb; |
|
|
|
|
await this.execAndParse(updateQb, null, { raw: true }); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case RelationTypes.BELONGS_TO: |
|
|
|
@ -4634,18 +4746,22 @@ class BaseModelSqlv2 {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
await this.dbDriver(childTn) |
|
|
|
|
.update({ |
|
|
|
|
[childColumn.column_name]: this.dbDriver.from( |
|
|
|
|
this.dbDriver(parentTn) |
|
|
|
|
.select(parentColumn.column_name) |
|
|
|
|
.where(_wherePk(parentTable.primaryKeys, childIds[0])) |
|
|
|
|
// .whereIn(parentTable.primaryKey.column_name, childIds)
|
|
|
|
|
.first() |
|
|
|
|
.as('___cn_alias'), |
|
|
|
|
), |
|
|
|
|
}) |
|
|
|
|
.where(_wherePk(childTable.primaryKeys, rowId)); |
|
|
|
|
await this.execAndParse( |
|
|
|
|
this.dbDriver(childTn) |
|
|
|
|
.update({ |
|
|
|
|
[childColumn.column_name]: this.dbDriver.from( |
|
|
|
|
this.dbDriver(parentTn) |
|
|
|
|
.select(parentColumn.column_name) |
|
|
|
|
.where(_wherePk(parentTable.primaryKeys, childIds[0])) |
|
|
|
|
// .whereIn(parentTable.primaryKey.column_name, childIds)
|
|
|
|
|
.first() |
|
|
|
|
.as('___cn_alias'), |
|
|
|
|
), |
|
|
|
|
}) |
|
|
|
|
.where(_wherePk(childTable.primaryKeys, rowId)), |
|
|
|
|
null, |
|
|
|
|
{ raw: true }, |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
@ -4777,7 +4893,7 @@ class BaseModelSqlv2 {
|
|
|
|
|
) |
|
|
|
|
: childIds, |
|
|
|
|
); |
|
|
|
|
await delQb; |
|
|
|
|
await this.execAndParse(delQb, null, { raw: true }); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case RelationTypes.HAS_MANY: |
|
|
|
@ -4823,7 +4939,11 @@ class BaseModelSqlv2 {
|
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
await childRowsQb.update({ [childColumn.column_name]: null }); |
|
|
|
|
await this.execAndParse( |
|
|
|
|
childRowsQb.update({ [childColumn.column_name]: null }), |
|
|
|
|
null, |
|
|
|
|
{ raw: true }, |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case RelationTypes.BELONGS_TO: |
|
|
|
@ -4849,16 +4969,20 @@ class BaseModelSqlv2 {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
await this.dbDriver(childTn) |
|
|
|
|
// .where({
|
|
|
|
|
// [childColumn.cn]: this.dbDriver(parentTable.tn)
|
|
|
|
|
// .select(parentColumn.cn)
|
|
|
|
|
// .where(parentTable.primaryKey.cn, childId)
|
|
|
|
|
// .first()
|
|
|
|
|
// })
|
|
|
|
|
// .where(_wherePk(childTable.primaryKeys, rowId))
|
|
|
|
|
.where(childTable.primaryKey.column_name, rowId) |
|
|
|
|
.update({ [childColumn.column_name]: null }); |
|
|
|
|
await this.execAndParse( |
|
|
|
|
this.dbDriver(childTn) |
|
|
|
|
// .where({
|
|
|
|
|
// [childColumn.cn]: this.dbDriver(parentTable.tn)
|
|
|
|
|
// .select(parentColumn.cn)
|
|
|
|
|
// .where(parentTable.primaryKey.cn, childId)
|
|
|
|
|
// .first()
|
|
|
|
|
// })
|
|
|
|
|
// .where(_wherePk(childTable.primaryKeys, rowId))
|
|
|
|
|
.where(childTable.primaryKey.column_name, rowId) |
|
|
|
|
.update({ [childColumn.column_name]: null }), |
|
|
|
|
null, |
|
|
|
|
{ raw: true }, |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
@ -4887,9 +5011,11 @@ class BaseModelSqlv2 {
|
|
|
|
|
(c) => c.id === colId, |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
const row = await this.dbDriver(this.tnPath) |
|
|
|
|
.where(await this._wherePk(id)) |
|
|
|
|
.first(); |
|
|
|
|
const row = await this.execAndParse( |
|
|
|
|
this.dbDriver(this.tnPath).where(await this._wherePk(id)), |
|
|
|
|
null, |
|
|
|
|
{ raw: true, first: true }, |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
// validate rowId
|
|
|
|
|
if (!row) { |
|
|
|
@ -4927,7 +5053,9 @@ class BaseModelSqlv2 {
|
|
|
|
|
|
|
|
|
|
await parentModel.selectObject({ qb, fieldsSet: args.fieldSet }); |
|
|
|
|
|
|
|
|
|
const parent = (await this.execAndParse(qb, childTable))?.[0]; |
|
|
|
|
const parent = await this.execAndParse(qb, childTable, { |
|
|
|
|
first: true, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const proto = await parentModel.getProto(); |
|
|
|
|
|
|
|
|
|