@ -151,6 +151,19 @@ export async function getColumnName(column: Column<any>, columns?: Column[]) {
}
}
}
}
export function replaceDynamicFieldWithValue (
_row : any ,
_rowId ,
_tableColumns : Column [ ] ,
_readByPk : typeof BaseModelSqlv2 . prototype . readByPk ,
_queryParams? : Record < string , string > ,
) {
const replaceWithValue = async ( conditions : Filter [ ] ) = > {
return conditions ;
} ;
return replaceWithValue ;
}
/ * *
/ * *
* Base class for models
* Base class for models
*
*
@ -322,6 +335,7 @@ class BaseModelSqlv2 {
fieldsSet? : Set < string > ;
fieldsSet? : Set < string > ;
limitOverride? : number ;
limitOverride? : number ;
pks? : string ;
pks? : string ;
customConditions? : Filter [ ] ;
} = { } ,
} = { } ,
options : {
options : {
ignoreViewFilterAndSort? : boolean ;
ignoreViewFilterAndSort? : boolean ;
@ -372,6 +386,14 @@ class BaseModelSqlv2 {
await conditionV2 (
await conditionV2 (
this ,
this ,
[
[
. . . ( args . customConditions
? [
new Filter ( {
children : args.customConditions ,
is_group : true ,
} ) ,
]
: [ ] ) ,
new Filter ( {
new Filter ( {
children :
children :
( await Filter . rootFilterList ( { viewId : this.viewId } ) ) || [ ] ,
( await Filter . rootFilterList ( { viewId : this.viewId } ) ) || [ ] ,
@ -403,6 +425,14 @@ class BaseModelSqlv2 {
await conditionV2 (
await conditionV2 (
this ,
this ,
[
[
. . . ( args . customConditions
? [
new Filter ( {
children : args.customConditions ,
is_group : true ,
} ) ,
]
: [ ] ) ,
new Filter ( {
new Filter ( {
children : args.filterArr || [ ] ,
children : args.filterArr || [ ] ,
is_group : true ,
is_group : true ,
@ -475,7 +505,12 @@ class BaseModelSqlv2 {
}
}
public async count (
public async count (
args : { where? : string ; limit ? ; filterArr? : Filter [ ] } = { } ,
args : {
where? : string ;
limit ? ;
filterArr? : Filter [ ] ;
customConditions? : Filter [ ] ;
} = { } ,
ignoreViewFilterAndSort = false ,
ignoreViewFilterAndSort = false ,
throwErrorIfInvalidParams = false ,
throwErrorIfInvalidParams = false ,
) : Promise < any > {
) : Promise < any > {
@ -496,6 +531,14 @@ class BaseModelSqlv2 {
await conditionV2 (
await conditionV2 (
this ,
this ,
[
[
. . . ( args . customConditions
? [
new Filter ( {
children : args.customConditions ,
is_group : true ,
} ) ,
]
: [ ] ) ,
new Filter ( {
new Filter ( {
children :
children :
( await Filter . rootFilterList ( { viewId : this.viewId } ) ) || [ ] ,
( await Filter . rootFilterList ( { viewId : this.viewId } ) ) || [ ] ,
@ -521,6 +564,14 @@ class BaseModelSqlv2 {
await conditionV2 (
await conditionV2 (
this ,
this ,
[
[
. . . ( args . customConditions
? [
new Filter ( {
children : args.customConditions ,
is_group : true ,
} ) ,
]
: [ ] ) ,
new Filter ( {
new Filter ( {
children : args.filterArr || [ ] ,
children : args.filterArr || [ ] ,
is_group : true ,
is_group : true ,
@ -1009,8 +1060,6 @@ class BaseModelSqlv2 {
const { where , sort , . . . rest } = this . _getListArgs ( args as any ) ;
const { where , sort , . . . rest } = this . _getListArgs ( args as any ) ;
// todo: get only required fields
// todo: get only required fields
// const { cn } = this.hasManyRelations.find(({ tn }) => tn === child) || {};
const relColumn = ( await this . model . getColumns ( ) ) . find (
const relColumn = ( await this . model . getColumns ( ) ) . find (
( c ) = > c . id === colId ,
( c ) = > c . id === colId ,
) ;
) ;
@ -1065,8 +1114,6 @@ class BaseModelSqlv2 {
. as ( 'list' ) ,
. as ( 'list' ) ,
) ;
) ;
// console.log(childQb.toQuery())
const children = await this . execAndParse (
const children = await this . execAndParse (
childQb ,
childQb ,
await childTable . getColumns ( ) ,
await childTable . getColumns ( ) ,
@ -1090,24 +1137,77 @@ class BaseModelSqlv2 {
}
}
}
}
protected async applySortAndFilter ( {
public async mmList (
table ,
{ colId , parentId } ,
args : { limit ? ; offset ? ; fieldsSet? : Set < string > } = { } ,
selectAllRecords = false ,
) {
const { where , sort , . . . rest } = this . _getListArgs ( args as any ) ;
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;
const mmTable = await relColOptions . getMMModel ( ) ;
const vtn = this . getTnPath ( mmTable ) ;
const vcn = ( await relColOptions . getMMChildColumn ( ) ) . column_name ;
const vrcn = ( await relColOptions . getMMParentColumn ( ) ) . column_name ;
const rcn = ( await relColOptions . getParentColumn ( ) ) . column_name ;
const cn = ( await relColOptions . getChildColumn ( ) ) . column_name ;
const childTable = await ( await relColOptions . getParentColumn ( ) ) . getModel ( ) ;
const parentTable = await ( await relColOptions . getChildColumn ( ) ) . getModel ( ) ;
await parentTable . getColumns ( ) ;
const childModel = await Model . getBaseModelSQL ( {
dbDriver : this.dbDriver ,
model : childTable ,
} ) ;
const childTn = this . getTnPath ( childTable ) ;
const parentTn = this . getTnPath ( parentTable ) ;
const rtn = childTn ;
const rtnId = childTable . id ;
const qb = this . dbDriver ( rtn )
. join ( vtn , ` ${ vtn } . ${ vrcn } ` , ` ${ rtn } . ${ rcn } ` )
. whereIn (
` ${ vtn } . ${ vcn } ` ,
this . dbDriver ( parentTn )
. select ( cn )
// .where(parentTable.primaryKey.cn, id)
. where ( _wherePk ( parentTable . primaryKeys , parentId ) ) ,
) ;
await childModel . selectObject ( {
qb ,
fieldsSet : args.fieldsSet ,
} ) ;
await this . applySortAndFilter ( {
table : childTable ,
where ,
where ,
qb ,
qb ,
sort ,
sort ,
} : {
} ) ;
table : Model ;
where : string ;
qb ;
sort : string ;
} ) {
const childAliasColMap = await table . getAliasColObjMap ( ) ;
const filter = extractFilterFromXwhere ( where , childAliasColMap ) ;
// todo: sanitize
await conditionV2 ( this , filter , qb ) ;
if ( ! selectAllRecords ) {
if ( ! sort ) return ;
qb . limit ( + rest ? . limit || 25 ) ;
const sortObj = extractSortsObject ( sort , childAliasColMap ) ;
}
if ( sortObj ) await sortV2 ( this , sortObj , qb ) ;
qb . offset ( selectAllRecords ? 0 : + rest ? . offset || 0 ) ;
const children = await this . execAndParse ( qb , await childTable . getColumns ( ) ) ;
const proto = await (
await Model . getBaseModelSQL ( { id : rtnId , dbDriver : this.dbDriver } )
) . getProto ( ) ;
return children . map ( ( c ) = > {
c . __proto__ = proto ;
return c ;
} ) ;
}
}
async multipleHmListCount ( { colId , ids } ) {
async multipleHmListCount ( { colId , ids } ) {
@ -1200,7 +1300,17 @@ class BaseModelSqlv2 {
qb . limit ( + rest ? . limit || 25 ) ;
qb . limit ( + rest ? . limit || 25 ) ;
qb . offset ( + rest ? . offset || 0 ) ;
qb . offset ( + rest ? . offset || 0 ) ;
await childModel . selectObject ( { qb , fieldsSet : args.fieldSet } ) ;
await childModel . selectObject ( {
qb ,
fieldsSet : args.fieldSet ,
} ) ;
await this . applySortAndFilter ( {
table : childTable ,
where ,
qb ,
sort ,
} ) ;
const children = await this . execAndParse (
const children = await this . execAndParse (
qb ,
qb ,
@ -1254,7 +1364,17 @@ class BaseModelSqlv2 {
const aliasColObjMap = await childTable . getAliasColObjMap ( ) ;
const aliasColObjMap = await childTable . getAliasColObjMap ( ) ;
const filterObj = extractFilterFromXwhere ( where , aliasColObjMap ) ;
const filterObj = extractFilterFromXwhere ( where , aliasColObjMap ) ;
await conditionV2 ( this , filterObj , query ) ;
await conditionV2 (
this ,
[
new Filter ( {
children : filterObj ,
is_group : true ,
logical_op : 'and' ,
} ) ,
] ,
query ,
) ;
return ( await this . execAndParse ( query , null , { raw : true , first : true } ) )
return ( await this . execAndParse ( query , null , { raw : true , first : true } ) )
? . count ;
? . count ;
@ -1314,7 +1434,12 @@ class BaseModelSqlv2 {
await childModel . selectObject ( { qb , fieldsSet : args.fieldsSet } ) ;
await childModel . selectObject ( { qb , fieldsSet : args.fieldsSet } ) ;
await this . applySortAndFilter ( { table : childTable , where , qb , sort } ) ;
await this . applySortAndFilter ( {
table : childTable ,
where ,
qb ,
sort ,
} ) ;
const finalQb = this . dbDriver . unionAll (
const finalQb = this . dbDriver . unionAll (
parentIds . map ( ( id ) = > {
parentIds . map ( ( id ) = > {
@ -1359,20 +1484,18 @@ class BaseModelSqlv2 {
return _parentIds . map ( ( id ) = > gs [ id ] || [ ] ) ;
return _parentIds . map ( ( id ) = > gs [ id ] || [ ] ) ;
}
}
public async mmList (
// todo: naming & optimizing
{ colId , parentId } ,
public async getMmChildrenExcludedListCount (
args : { limit ? ; offset ? ; fieldsSet? : Set < string > } = { } ,
{ colId , pid = null } ,
selectAllRecords = false ,
args ,
) {
) : Promise < any > {
const { where , sort , . . . rest } = this . _getListArgs ( args as any ) ;
const { where } = this . _getListArgs ( args as any ) ;
const relColumn = ( await this . model . getColumns ( ) ) . find (
const relColumn = ( await this . model . getColumns ( ) ) . find (
( c ) = > c . id === colId ,
( c ) = > c . id === colId ,
) ;
) ;
const relColOptions =
const relColOptions =
( await relColumn . getColOptions ( ) ) as LinkToAnotherRecordColumn ;
( await relColumn . getColOptions ( ) ) as LinkToAnotherRecordColumn ;
// const tn = this.model.tn;
// const cn = (await relColOptions.getChildColumn()).title;
const mmTable = await relColOptions . getMMModel ( ) ;
const mmTable = await relColOptions . getMMModel ( ) ;
const vtn = this . getTnPath ( mmTable ) ;
const vtn = this . getTnPath ( mmTable ) ;
const vcn = ( await relColOptions . getMMChildColumn ( ) ) . column_name ;
const vcn = ( await relColOptions . getMMChildColumn ( ) ) . column_name ;
@ -1380,48 +1503,69 @@ class BaseModelSqlv2 {
const rcn = ( await relColOptions . getParentColumn ( ) ) . column_name ;
const rcn = ( await relColOptions . getParentColumn ( ) ) . column_name ;
const cn = ( await relColOptions . getChildColumn ( ) ) . column_name ;
const cn = ( await relColOptions . getChildColumn ( ) ) . column_name ;
const childTable = await ( await relColOptions . getParentColumn ( ) ) . getModel ( ) ;
const childTable = await ( await relColOptions . getParentColumn ( ) ) . getModel ( ) ;
const parentTable = await ( await relColOptions . getChildColumn ( ) ) . getModel ( ) ;
await parentTable . getColumns ( ) ;
const childView = await relColOptions . getChildView ( ) ;
const childModel = await Model . getBaseModelSQL ( {
let listArgs : any = { } ;
dbDriver : this.dbDriver ,
if ( childView ) {
const { dependencyFields } = await getAst ( {
model : childTable ,
model : childTable ,
query : { } ,
view : childView ,
throwErrorIfInvalidParams : false ,
} ) ;
} ) ;
listArgs = dependencyFields ;
try {
listArgs . filterArr = JSON . parse ( listArgs . filterArrJson ) ;
} catch ( e ) { }
try {
listArgs . sortArr = JSON . parse ( listArgs . sortArrJson ) ;
} catch ( e ) { }
}
const parentTable = await ( await relColOptions . getChildColumn ( ) ) . getModel ( ) ;
await parentTable . getColumns ( ) ;
const childTn = this . getTnPath ( childTable ) ;
const childTn = this . getTnPath ( childTable ) ;
const parentTn = this . getTnPath ( parentTable ) ;
const parentTn = this . getTnPath ( parentTable ) ;
const rtn = childTn ;
const rtn = childTn ;
const rtnId = childTable . id ;
const qb = this . dbDriver ( rtn )
const qb = this . dbDriver ( rtn )
. join ( vtn , ` ${ vtn } . ${ vrcn } ` , ` ${ rtn } . ${ rcn } ` )
. count ( ` * ` , { as : 'count' } )
. where ( ( qb ) = > {
qb . whereNotIn (
rcn ,
this . dbDriver ( rtn )
. select ( ` ${ rtn } . ${ rcn } ` )
. join ( vtn , ` ${ rtn } . ${ rcn } ` , ` ${ vtn } . ${ vrcn } ` )
. whereIn (
. whereIn (
` ${ vtn } . ${ vcn } ` ,
` ${ vtn } . ${ vcn } ` ,
this . dbDriver ( parentTn )
this . dbDriver ( parentTn )
. select ( cn )
. select ( cn )
// .where(parentTable.primaryKey.cn, id)
// .where(parentTable.primaryKey.cn, pid)
. where ( _wherePk ( parentTable . primaryKeys , parentId ) ) ,
. where ( _wherePk ( parentTable . primaryKeys , pid ) ) ,
) ;
) ,
) . orWhereNull ( rcn ) ;
await childModel . selectObject ( { qb , fieldsSet : args.fieldsSet } ) ;
} ) ;
await this . applySortAndFilter ( { table : childTable , where , qb , sort } ) ;
// todo: sanitize
if ( ! selectAllRecords ) {
qb . limit ( + rest ? . limit || 25 ) ;
}
qb . offset ( selectAllRecords ? 0 : + rest ? . offset || 0 ) ;
const children = await this . execAndParse ( qb , await childTable . getColumns ( ) ) ;
const aliasColObjMap = await childTable . getAliasColObjMap ( ) ;
const proto = await (
const filterObj = extractFilterFromXwhere ( where , aliasColObjMap ) ;
await Model . getBaseModelSQL ( { id : rtnId , dbDriver : this.dbDriver } )
) . getProto ( ) ;
return children . map ( ( c ) = > {
await this . getCustomConditionsAndApply ( {
c . __proto__ = proto ;
column : relColumn ,
return c ;
view : childView ,
filters : filterObj ,
args ,
qb ,
rowId : pid ,
} ) ;
} ) ;
return (
await this . execAndParse ( qb , await childTable . getColumns ( ) , {
raw : true ,
first : true ,
} )
) ? . count ;
}
}
public async multipleMmListCount ( { colId , parentIds } ) {
public async multipleMmListCount ( { colId , parentIds } ) {
@ -1496,6 +1640,7 @@ class BaseModelSqlv2 {
const rcn = ( await relColOptions . getParentColumn ( ) ) . column_name ;
const rcn = ( await relColOptions . getParentColumn ( ) ) . column_name ;
const cn = ( await relColOptions . getChildColumn ( ) ) . column_name ;
const cn = ( await relColOptions . getChildColumn ( ) ) . column_name ;
const childTable = await ( await relColOptions . getParentColumn ( ) ) . getModel ( ) ;
const childTable = await ( await relColOptions . getParentColumn ( ) ) . getModel ( ) ;
const parentTable = await ( await relColOptions . getChildColumn ( ) ) . getModel ( ) ;
const parentTable = await ( await relColOptions . getChildColumn ( ) ) . getModel ( ) ;
await parentTable . getColumns ( ) ;
await parentTable . getColumns ( ) ;
@ -1520,17 +1665,27 @@ class BaseModelSqlv2 {
const aliasColObjMap = await childTable . getAliasColObjMap ( ) ;
const aliasColObjMap = await childTable . getAliasColObjMap ( ) ;
const filterObj = extractFilterFromXwhere ( where , aliasColObjMap ) ;
const filterObj = extractFilterFromXwhere ( where , aliasColObjMap ) ;
await conditionV2 ( this , filterObj , qb ) ;
await conditionV2 (
this ,
[
new Filter ( {
children : filterObj ,
is_group : true ,
logical_op : 'and' ,
} ) ,
] ,
qb ,
) ;
return ( await this . execAndParse ( qb , null , { raw : true , first : true } ) )
return ( await this . execAndParse ( qb , null , { raw : true , first : true } ) )
? . count ;
? . count ;
}
}
// todo: naming & optimizing
// todo: naming & optimizing
public async getMmChildrenExcludedListCount (
public async getMmChildrenExcludedList (
{ colId , pid = null } ,
{ colId , pid = null } ,
args ,
args ,
) : Promise < any > {
) : Promise < any > {
const { where } = this . _getListArgs ( args as any ) ;
const { where , . . . rest } = this . _getListArgs ( args as any ) ;
const relColumn = ( await this . model . getColumns ( ) ) . find (
const relColumn = ( await this . model . getColumns ( ) ) . find (
( c ) = > c . id === colId ,
( c ) = > c . id === colId ,
) ;
) ;
@ -1544,6 +1699,22 @@ class BaseModelSqlv2 {
const rcn = ( await relColOptions . getParentColumn ( ) ) . column_name ;
const rcn = ( await relColOptions . getParentColumn ( ) ) . column_name ;
const cn = ( await relColOptions . getChildColumn ( ) ) . column_name ;
const cn = ( await relColOptions . getChildColumn ( ) ) . column_name ;
const childTable = await ( await relColOptions . getParentColumn ( ) ) . getModel ( ) ;
const childTable = await ( await relColOptions . getParentColumn ( ) ) . getModel ( ) ;
const childModel = await Model . getBaseModelSQL ( {
dbDriver : this.dbDriver ,
model : childTable ,
} ) ;
const childView = await relColOptions . getChildView ( ) ;
let listArgs : any = { } ;
if ( childView ) {
const { dependencyFields } = await getAst ( {
model : childTable ,
query : { } ,
view : childView ,
throwErrorIfInvalidParams : false ,
} ) ;
listArgs = dependencyFields ;
}
const parentTable = await ( await relColOptions . getChildColumn ( ) ) . getModel ( ) ;
const parentTable = await ( await relColOptions . getChildColumn ( ) ) . getModel ( ) ;
await parentTable . getColumns ( ) ;
await parentTable . getColumns ( ) ;
@ -1551,10 +1722,10 @@ class BaseModelSqlv2 {
const parentTn = this . getTnPath ( parentTable ) ;
const parentTn = this . getTnPath ( parentTable ) ;
const rtn = childTn ;
const rtn = childTn ;
const qb = this . dbDriver ( rtn )
. count ( ` * ` , { as : 'count' } )
const qb = this . dbDriver ( rtn ) . where ( ( qb ) = >
. where ( ( qb ) = > {
qb
qb . whereNotIn (
. whereNotIn (
rcn ,
rcn ,
this . dbDriver ( rtn )
this . dbDriver ( rtn )
. select ( ` ${ rtn } . ${ rcn } ` )
. select ( ` ${ rtn } . ${ rcn } ` )
@ -1566,19 +1737,52 @@ class BaseModelSqlv2 {
// .where(parentTable.primaryKey.cn, pid)
// .where(parentTable.primaryKey.cn, pid)
. where ( _wherePk ( parentTable . primaryKeys , pid ) ) ,
. where ( _wherePk ( parentTable . primaryKeys , pid ) ) ,
) ,
) ,
) . orWhereNull ( rcn ) ;
)
. orWhereNull ( rcn ) ,
) ;
if ( + rest ? . shuffle ) {
await this . shuffle ( { qb } ) ;
}
await childModel . selectObject ( {
qb ,
fieldsSet : listArgs?.fieldsSet ,
viewId : childView?.id ,
} ) ;
} ) ;
const aliasColObjMap = await childTable . getAliasColObjMap ( ) ;
const aliasColObjMap = await childTable . getAliasColObjMap ( ) ;
const filterObj = extractFilterFromXwhere ( where , aliasColObjMap ) ;
const filterObj = extractFilterFromXwhere ( where , aliasColObjMap ) ;
await conditionV2 ( this , filterObj , qb ) ;
await this . getCustomConditionsAndApply ( {
return ( await this . execAndParse ( qb , null , { raw : true , first : true } ) )
column : relColumn ,
? . count ;
view : childView ,
filters : filterObj ,
args ,
qb ,
rowId : pid ,
} ) ;
// sort by primary key if not autogenerated string
// if autogenerated string sort by created_at column if present
if ( childTable . primaryKey && childTable . primaryKey . ai ) {
qb . orderBy ( childTable . primaryKey . column_name ) ;
} else if ( childTable . columns . find ( ( c ) = > c . column_name === 'created_at' ) ) {
qb . orderBy ( 'created_at' ) ;
}
applyPaginate ( qb , rest ) ;
const proto = await childModel . getProto ( ) ;
const data = await this . execAndParse ( qb , await childTable . getColumns ( ) ) ;
return data . map ( ( c ) = > {
c . __proto__ = proto ;
return c ;
} ) ;
}
}
// todo: naming & optimizing
// todo: naming & optimizing
public async getMmChildrenExcludedList (
public async getH mChildrenExcludedList (
{ colId , pid = null } ,
{ colId , pid = null } ,
args ,
args ,
) : Promise < any > {
) : Promise < any > {
@ -1589,42 +1793,35 @@ class BaseModelSqlv2 {
const relColOptions =
const relColOptions =
( await relColumn . getColOptions ( ) ) as LinkToAnotherRecordColumn ;
( await relColumn . getColOptions ( ) ) as LinkToAnotherRecordColumn ;
const mmTable = await relColOptions . getMMModel ( ) ;
const vtn = this . getTnPath ( mmTable ) ;
const vcn = ( await relColOptions . getMMChildColumn ( ) ) . column_name ;
const vrcn = ( await relColOptions . getMMParentColumn ( ) ) . column_name ;
const rcn = ( await relColOptions . getParentColumn ( ) ) . column_name ;
const cn = ( await relColOptions . getChildColumn ( ) ) . column_name ;
const cn = ( await relColOptions . getChildColumn ( ) ) . column_name ;
const childTable = await ( await relColOptions . getParentColumn ( ) ) . getModel ( ) ;
const rcn = ( await relColOptions . getParentColumn ( ) ) . column_name ;
const childTable = await ( await relColOptions . getChildColumn ( ) ) . getModel ( ) ;
const parentTable = await (
await relColOptions . getParentColumn ( )
) . getModel ( ) ;
const childModel = await Model . getBaseModelSQL ( {
const childModel = await Model . getBaseModelSQL ( {
dbDriver : this.dbDriver ,
dbDriver : this.dbDriver ,
model : childTable ,
model : childTable ,
} ) ;
} ) ;
const parentTable = await ( await relColOptions . getChildColumn ( ) ) . getModel ( ) ;
await parentTable . getColumns ( ) ;
await parentTable . getColumns ( ) ;
const childView = await relColOptions . getChildView ( ) ;
const childTn = this . getTnPath ( childTable ) ;
const childTn = this . getTnPath ( childTable ) ;
const parentTn = this . getTnPath ( parentTable ) ;
const parentTn = this . getTnPath ( parentTable ) ;
const rtn = childTn ;
const tn = childTn ;
const rtn = parentTn ;
const qb = this . dbDriver ( rtn ) . where ( ( qb ) = >
const qb = this . dbDriver ( tn ) . where ( ( qb ) = > {
qb
qb . whereNotIn (
. whereNotIn (
cn ,
rcn ,
this . dbDriver ( rtn )
this . dbDriver ( rtn )
. select ( ` ${ rtn } . ${ rcn } ` )
. select ( rcn )
. join ( vtn , ` ${ rtn } . ${ rcn } ` , ` ${ vtn } . ${ vrcn } ` )
. whereIn (
` ${ vtn } . ${ vcn } ` ,
this . dbDriver ( parentTn )
. select ( cn )
// .where(parentTable.primaryKey.cn, pid)
// .where(parentTable.primaryKey.cn, pid)
. where ( _wherePk ( parentTable . primaryKeys , pid ) ) ,
. where ( _wherePk ( parentTable . primaryKeys , pid ) ) ,
) ,
) . orWhereNull ( cn ) ;
)
} ) ;
. orWhereNull ( rcn ) ,
) ;
if ( + rest ? . shuffle ) {
if ( + rest ? . shuffle ) {
await this . shuffle ( { qb } ) ;
await this . shuffle ( { qb } ) ;
@ -1634,8 +1831,14 @@ class BaseModelSqlv2 {
const aliasColObjMap = await childTable . getAliasColObjMap ( ) ;
const aliasColObjMap = await childTable . getAliasColObjMap ( ) ;
const filterObj = extractFilterFromXwhere ( where , aliasColObjMap ) ;
const filterObj = extractFilterFromXwhere ( where , aliasColObjMap ) ;
await conditionV2 ( this , filterObj , qb ) ;
await this . getCustomConditionsAndApply ( {
column : relColumn ,
view : childView ,
filters : filterObj ,
args ,
qb ,
rowId : pid ,
} ) ;
// sort by primary key if not autogenerated string
// sort by primary key if not autogenerated string
// if autogenerated string sort by created_at column if present
// if autogenerated string sort by created_at column if present
if ( childTable . primaryKey && childTable . primaryKey . ai ) {
if ( childTable . primaryKey && childTable . primaryKey . ai ) {
@ -1648,6 +1851,7 @@ class BaseModelSqlv2 {
const proto = await childModel . getProto ( ) ;
const proto = await childModel . getProto ( ) ;
const data = await this . execAndParse ( qb , await childTable . getColumns ( ) ) ;
const data = await this . execAndParse ( qb , await childTable . getColumns ( ) ) ;
return data . map ( ( c ) = > {
return data . map ( ( c ) = > {
c . __proto__ = proto ;
c . __proto__ = proto ;
return c ;
return c ;
@ -1663,6 +1867,7 @@ class BaseModelSqlv2 {
const relColumn = ( await this . model . getColumns ( ) ) . find (
const relColumn = ( await this . model . getColumns ( ) ) . find (
( c ) = > c . id === colId ,
( c ) = > c . id === colId ,
) ;
) ;
const relColOptions =
const relColOptions =
( await relColumn . getColOptions ( ) ) as LinkToAnotherRecordColumn ;
( await relColumn . getColOptions ( ) ) as LinkToAnotherRecordColumn ;
@ -1673,6 +1878,8 @@ class BaseModelSqlv2 {
await relColOptions . getParentColumn ( )
await relColOptions . getParentColumn ( )
) . getModel ( ) ;
) . getModel ( ) ;
const childView = await relColOptions . getChildView ( ) ;
const childTn = this . getTnPath ( childTable ) ;
const childTn = this . getTnPath ( childTable ) ;
const parentTn = this . getTnPath ( parentTable ) ;
const parentTn = this . getTnPath ( parentTable ) ;
@ -1695,15 +1902,22 @@ class BaseModelSqlv2 {
const aliasColObjMap = await childTable . getAliasColObjMap ( ) ;
const aliasColObjMap = await childTable . getAliasColObjMap ( ) ;
const filterObj = extractFilterFromXwhere ( where , aliasColObjMap ) ;
const filterObj = extractFilterFromXwhere ( where , aliasColObjMap ) ;
await conditionV2 ( this , filterObj , qb ) ;
await this . getCustomConditionsAndApply ( {
column : relColumn ,
view : childView ,
filters : filterObj ,
args ,
qb ,
rowId : pid ,
} ) ;
return ( await this . execAndParse ( qb , null , { raw : true , first : true } ) )
return ( await this . execAndParse ( qb , null , { raw : true , first : true } ) )
? . count ;
? . count ;
}
}
// todo: naming & optimizing
// todo: naming & optimizing
public async getHmChildrenExcludedList (
public async getExcludedOneToOneChildren List (
{ colId , p id = null } ,
{ colId , c id = null } ,
args ,
args ,
) : Promise < any > {
) : Promise < any > {
const { where , . . . rest } = this . _getListArgs ( args as any ) ;
const { where , . . . rest } = this . _getListArgs ( args as any ) ;
@ -1713,56 +1927,90 @@ class BaseModelSqlv2 {
const relColOptions =
const relColOptions =
( await relColumn . getColOptions ( ) ) as LinkToAnotherRecordColumn ;
( await relColumn . getColOptions ( ) ) as LinkToAnotherRecordColumn ;
const cn = ( await relColOptions . getChildColumn ( ) ) . column_name ;
const rcn = ( await relColOptions . getParentColumn ( ) ) . column_name ;
const rcn = ( await relColOptions . getParentColumn ( ) ) . column_name ;
const childTable = await ( await relColOptions . getChildColumn ( ) ) . getModel ( ) ;
const parentTable = await (
const parentTable = await (
await relColOptions . getParentColumn ( )
await relColOptions . getParentColumn ( )
) . getModel ( ) ;
) . getModel ( ) ;
const cn = ( await relColOptions . getChildColumn ( ) ) . column_name ;
const childTable = await ( await relColOptions . getChildColumn ( ) ) . getModel ( ) ;
const parentModel = await Model . getBaseModelSQL ( {
dbDriver : this.dbDriver ,
model : parentTable ,
} ) ;
const childModel = await Model . getBaseModelSQL ( {
const childModel = await Model . getBaseModelSQL ( {
dbDriver : this.dbDriver ,
dbDriver : this.dbDriver ,
model : childTable ,
model : childTable ,
} ) ;
} ) ;
await parentTable . getColumns ( ) ;
const childTn = this . getTnPath ( childTable ) ;
const childView = await relColOptions . getChildView ( ) ;
const parentTn = this . getTnPath ( parentTable ) ;
let listArgs : any = { } ;
if ( childView ) {
const { dependencyFields } = await getAst ( {
model : childTable ,
query : { } ,
view : childView ,
throwErrorIfInvalidParams : false ,
} ) ;
listArgs = dependencyFields ;
}
const tn = childTn ;
const rtn = this . getTnPath ( parentTable ) ;
const rtn = parentTn ;
const tn = this . getTnPath ( childTable ) ;
await childTable . getColumns ( ) ;
const qb = this . dbDriver ( tn ) . where ( ( qb ) = > {
// one-to-one relation is combination of both hm and bt to identify table which have
// foreign key column(similar to bt) we are adding a boolean flag `bt` under meta
const isBt = relColumn . meta ? . bt ;
const qb = this . dbDriver ( isBt ? rtn : tn ) . where ( ( qb ) = > {
qb . whereNotIn (
qb . whereNotIn (
cn ,
isBt ? rcn : cn ,
this . dbDriver ( rtn )
this . dbDriver ( isBt ? tn : rtn )
. select ( rcn )
. select ( isBt ? cn : rcn )
// .where(parentTable.primaryKey.cn, pid)
. where ( _wherePk ( ( isBt ? childTable : parentTable ) . primaryKeys , cid ) )
. where ( _wherePk ( parentTable . primaryKeys , pid ) ) ,
. whereNotNull ( isBt ? cn : rcn ) ,
) . orWhereNull ( cn ) ;
) . orWhereNull ( isBt ? rcn : cn ) ;
} ) ;
} ) ;
if ( + rest ? . shuffle ) {
if ( + rest ? . shuffle ) {
await this . shuffle ( { qb } ) ;
await this . shuffle ( { qb } ) ;
}
}
await childModel . selectObject ( { qb } ) ;
await ( isBt ? parentModel : childModel ) . selectObject ( {
qb ,
fieldsSet : listArgs.fieldsSet ,
viewId : childView?.id ,
} ) ;
const aliasColObjMap = await childTable . getAliasColObjMap ( ) ;
const aliasColObjMap = await parent Table. getAliasColObjMap ( ) ;
const filterObj = extractFilterFromXwhere ( where , aliasColObjMap ) ;
const filterObj = extractFilterFromXwhere ( where , aliasColObjMap ) ;
await conditionV2 ( this , filterObj , qb ) ;
await this . getCustomConditionsAndApply ( {
column : relColumn ,
view : childView ,
filters : filterObj ,
args ,
qb ,
rowId : cid ,
} ) ;
// sort by primary key if not autogenerated string
// sort by primary key if not autogenerated string
// if autogenerated string sort by created_at column if present
// if autogenerated string sort by created_at column if present
if ( childTable . primaryKey && childTable . primaryKey . ai ) {
if ( parentTable . primaryKey && parentTable . primaryKey . ai ) {
qb . orderBy ( childTable . primaryKey . column_name ) ;
qb . orderBy ( parentTable . primaryKey . column_name ) ;
} else if ( childTable . columns . find ( ( c ) = > c . column_name === 'created_at' ) ) {
} else if (
parentTable . columns . find ( ( c ) = > c . column_name === 'created_at' )
) {
qb . orderBy ( 'created_at' ) ;
qb . orderBy ( 'created_at' ) ;
}
}
applyPaginate ( qb , rest ) ;
applyPaginate ( qb , rest ) ;
const proto = await childModel . getProto ( ) ;
const proto = await ( isBt ? parentModel : childModel ) . getProto ( ) ;
const data = await this . execAndParse ( qb , await childTable . getColumns ( ) ) ;
const data = await this . execAndParse (
qb ,
await ( isBt ? parentTable : childTable ) . getColumns ( ) ,
) ;
return data . map ( ( c ) = > {
return data . map ( ( c ) = > {
c . __proto__ = proto ;
c . __proto__ = proto ;
@ -1812,7 +2060,17 @@ class BaseModelSqlv2 {
const aliasColObjMap = await parentTable . getAliasColObjMap ( ) ;
const aliasColObjMap = await parentTable . getAliasColObjMap ( ) ;
const filterObj = extractFilterFromXwhere ( where , aliasColObjMap ) ;
const filterObj = extractFilterFromXwhere ( where , aliasColObjMap ) ;
await conditionV2 ( this , filterObj , qb ) ;
const targetView = await relColOptions . getChildView ( ) ;
await this . getCustomConditionsAndApply ( {
column : relColumn ,
view : targetView ,
filters : filterObj ,
args ,
qb ,
rowId : cid ,
} ) ;
return ( await this . execAndParse ( qb , null , { raw : true , first : true } ) )
return ( await this . execAndParse ( qb , null , { raw : true , first : true } ) )
? . count ;
? . count ;
}
}
@ -1836,6 +2094,8 @@ class BaseModelSqlv2 {
const cn = ( await relColOptions . getChildColumn ( ) ) . column_name ;
const cn = ( await relColOptions . getChildColumn ( ) ) . column_name ;
const childTable = await ( await relColOptions . getChildColumn ( ) ) . getModel ( ) ;
const childTable = await ( await relColOptions . getChildColumn ( ) ) . getModel ( ) ;
const childView = await relColOptions . getChildView ( ) ;
const childTn = this . getTnPath ( childTable ) ;
const childTn = this . getTnPath ( childTable ) ;
const parentTn = this . getTnPath ( parentTable ) ;
const parentTn = this . getTnPath ( parentTable ) ;
@ -1862,7 +2122,15 @@ class BaseModelSqlv2 {
const aliasColObjMap = await parentTable . getAliasColObjMap ( ) ;
const aliasColObjMap = await parentTable . getAliasColObjMap ( ) ;
const filterObj = extractFilterFromXwhere ( where , aliasColObjMap ) ;
const filterObj = extractFilterFromXwhere ( where , aliasColObjMap ) ;
await conditionV2 ( this , filterObj , qb ) ;
await this . getCustomConditionsAndApply ( {
column : relColumn ,
view : childView ,
filters : filterObj ,
args ,
qb ,
rowId : cid ,
} ) ;
return ( await this . execAndParse ( qb , null , { raw : true , first : true } ) )
return ( await this . execAndParse ( qb , null , { raw : true , first : true } ) )
? . count ;
? . count ;
}
}
@ -1916,7 +2184,16 @@ class BaseModelSqlv2 {
const aliasColObjMap = await parentTable . getAliasColObjMap ( ) ;
const aliasColObjMap = await parentTable . getAliasColObjMap ( ) ;
const filterObj = extractFilterFromXwhere ( where , aliasColObjMap ) ;
const filterObj = extractFilterFromXwhere ( where , aliasColObjMap ) ;
await conditionV2 ( this , filterObj , qb ) ;
const targetView = await relColOptions . getChildView ( ) ;
await this . getCustomConditionsAndApply ( {
column : relColumn ,
view : targetView ,
filters : filterObj ,
args ,
qb ,
rowId : cid ,
} ) ;
// sort by primary key if not autogenerated string
// sort by primary key if not autogenerated string
// if autogenerated string sort by created_at column if present
// if autogenerated string sort by created_at column if present
@ -1939,83 +2216,41 @@ class BaseModelSqlv2 {
} ) ;
} ) ;
}
}
// todo: naming & optimizing
protected async applySortAndFilter ( {
public async getExcludedOneToOneChildrenList (
table ,
{ colId , cid = null } ,
view ,
args ,
where ,
) : Promise < any > {
qb ,
const { where , . . . rest } = this . _getListArgs ( args as any ) ;
sort ,
const relColumn = ( await this . model . getColumns ( ) ) . find (
} : {
( c ) = > c . id === colId ,
table : Model ;
) ;
view? : View ;
const relColOptions =
where : string ;
( await relColumn . getColOptions ( ) ) as LinkToAnotherRecordColumn ;
qb ;
sort : string ;
const rcn = ( await relColOptions . getParentColumn ( ) ) . column_name ;
} ) {
const parentTable = await (
const childAliasColMap = await table . getAliasColObjMap ( ) ;
await relColOptions . getParentColumn ( )
) . getModel ( ) ;
const cn = ( await relColOptions . getChildColumn ( ) ) . column_name ;
const childTable = await ( await relColOptions . getChildColumn ( ) ) . getModel ( ) ;
const parentModel = await Model . getBaseModelSQL ( {
dbDriver : this.dbDriver ,
model : parentTable ,
} ) ;
const childModel = await Model . getBaseModelSQL ( {
dbDriver : this.dbDriver ,
model : childTable ,
} ) ;
const rtn = this . getTnPath ( parentTable ) ;
const tn = this . getTnPath ( childTable ) ;
await childTable . getColumns ( ) ;
// one-to-one relation is combination of both hm and bt to identify table which have
// foreign key column(similar to bt) we are adding a boolean flag `bt` under meta
const isBt = relColumn . meta ? . bt ;
const qb = this . dbDriver ( isBt ? rtn : tn ) . where ( ( qb ) = > {
qb . whereNotIn (
isBt ? rcn : cn ,
this . dbDriver ( isBt ? tn : rtn )
. select ( isBt ? cn : rcn )
. where ( _wherePk ( ( isBt ? childTable : parentTable ) . primaryKeys , cid ) )
. whereNotNull ( isBt ? cn : rcn ) ,
) . orWhereNull ( isBt ? rcn : cn ) ;
} ) ;
if ( + rest ? . shuffle ) {
await this . shuffle ( { qb } ) ;
}
await ( isBt ? parentModel : childModel ) . selectObject ( { qb } ) ;
const aliasColObjMap = await parentTable . getAliasColObjMap ( ) ;
const filterObj = extractFilterFromXwhere ( where , aliasColObjMap ) ;
await conditionV2 ( this , filterObj , qb ) ;
// sort by primary key if not autogenerated string
// if autogenerated string sort by created_at column if present
if ( parentTable . primaryKey && parentTable . primaryKey . ai ) {
qb . orderBy ( parentTable . primaryKey . column_name ) ;
} else if (
parentTable . columns . find ( ( c ) = > c . column_name === 'created_at' )
) {
qb . orderBy ( 'created_at' ) ;
}
applyPaginate ( qb , rest ) ;
const proto = await ( isBt ? parentModel : childModel ) . getProto ( ) ;
const filter = extractFilterFromXwhere ( where , childAliasColMap ) ;
const data = await this . execAndParse (
await conditionV2 (
this ,
[
. . . ( view
? [
new Filter ( {
children :
( await Filter . rootFilterList ( { viewId : view.id } ) ) || [ ] ,
is_group : true ,
} ) ,
]
: [ ] ) ,
. . . filter ,
] ,
qb ,
qb ,
await ( isBt ? parentTable : childTable ) . getColumns ( ) ,
) ;
) ;
if ( ! sort ) return ;
return data . map ( ( c ) = > {
const sortObj = extractSortsObject ( sort , childAliasColMap ) ;
c . __proto__ = proto ;
if ( sortObj ) await sortV2 ( this , sortObj , qb ) ;
return c ;
} ) ;
}
}
protected async getSelectQueryBuilderForFormula (
protected async getSelectQueryBuilderForFormula (
@ -6663,6 +6898,18 @@ class BaseModelSqlv2 {
. utc ( )
. utc ( )
. format ( this . isMySQL ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD HH:mm:ssZ' ) ;
. format ( this . isMySQL ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD HH:mm:ssZ' ) ;
}
}
async getCustomConditionsAndApply ( _params : {
view? : View ;
column : Column < any > ;
qb ? ;
filters ? ;
args ;
rowId ;
columns? : Column [ ] ;
} ) : Promise < any > {
return ;
}
}
}
export function extractSortsObject (
export function extractSortsObject (