Skip to content

Commit

Permalink
fix(JoinClause): Prevent duplicate joins when using closure syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
elpete committed May 4, 2020
1 parent 72d92b9 commit 8f5028a
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 13 deletions.
2 changes: 1 addition & 1 deletion ModuleConfig.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ component {
.to( "qb.models.Query.QueryBuilder" )
.initArg( name = "grammar", ref = settings.defaultGrammar )
.initArg( name = "utils", ref = "QueryUtils@qb" )
.initArg( name = "preventDuplicateJoints", value = settings.preventDuplicateJoins )
.initArg( name = "preventDuplicateJoints", value = settings.preventDuplicateJoins )
.initArg( name = "returnFormat", value = settings.defaultReturnFormat );

binder.map( alias = "SchemaBuilder@qb", force = true )
Expand Down
32 changes: 20 additions & 12 deletions models/Query/QueryBuilder.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -529,19 +529,17 @@ component displayname="QueryBuilder" accessors="true" {

var join = new qb.models.Query.JoinClause( parentQuery = this, type = arguments.type, table = arguments.table );

if ( arguments.preventDuplicateJoins ) {
var hasThisJoin = variables.joins.find( function( existingJoin ) {
return existingJoin.isEqualTo( join );
} );

if ( hasThisJoin ) {
return this;
}
}


if ( isClosure( arguments.first ) || isCustomFunction( arguments.first ) ) {
first( join );
if ( arguments.preventDuplicateJoins ) {
var hasThisJoin = variables.joins.find( function( existingJoin ) {
return existingJoin.isEqualTo( join );
} );

if ( hasThisJoin ) {
return this;
}
}
variables.joins.append( join );
addBindings( join.getBindings(), "join" );
return this;
Expand All @@ -550,7 +548,17 @@ component displayname="QueryBuilder" accessors="true" {
var method = where ? "where" : "on";
arguments.column = arguments.first;
arguments.value = isNull( arguments.second ) ? javacast( "null", "" ) : arguments.second;
variables.joins.append( invoke( join, method, arguments ) );
join = invoke( join, method, arguments );
if ( arguments.preventDuplicateJoins ) {
var hasThisJoin = variables.joins.find( function( existingJoin ) {
return existingJoin.isEqualTo( join );
} );

if ( hasThisJoin ) {
return this;
}
}
variables.joins.append( join );
addBindings( join.getBindings(), "join" );

return this;
Expand Down
10 changes: 10 additions & 0 deletions tests/specs/Query/Abstract/JoinClauseSpec.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,16 @@ component extends="testbox.system.BaseSpec" {
expect( variables.qb.getJoins().len() ).toBe( 1 );
} );

it( "will prevent an identical join from being added using the closure syntax when preventDuplicateJoins is true", function() {
variables.qb.join( "secondTable", function( j ) {
j.on( "secondTable.id", "firstTable.secondId" );
} );
variables.qb.join( "secondTable", function( j ) {
j.on( "secondTable.id", "firstTable.secondId" );
} );
expect( variables.qb.getJoins().len() ).toBe( 1 );
} );

it( "will allow an identical join from being added when preventDuplicateJoins is false", function() {
variables.qb.setPreventDuplicateJoins( false );
variables.qb.join( variables.join );
Expand Down

0 comments on commit 8f5028a

Please sign in to comment.