Skip to content

Commit

Permalink
Implement where exists
Browse files Browse the repository at this point in the history
  • Loading branch information
elpete committed Nov 28, 2016
1 parent edf8f66 commit d4174e3
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 11 deletions.
40 changes: 38 additions & 2 deletions models/Query/Builder.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,10 @@ component displayname="Builder" accessors="true" {
type = "basic"
} );

var binding = utils.extractBinding( arguments.value );
arrayAppend( bindings.where, binding );
if ( ! isInstanceOf( arguments.value, "Quick.models.Query.Expression" ) ) {
var binding = utils.extractBinding( arguments.value );
arrayAppend( bindings.where, binding );
}

return this;
}
Expand Down Expand Up @@ -250,6 +252,40 @@ component displayname="Builder" accessors="true" {
return whereColumn( argumentCollection = arguments );
}

public Builder function whereExists( callback, combinator = "and", negate = false ) {
var query = newQuery();
callback( query );
return addWhereExistsQuery( query, combinator, negate );
}

private Builder function addWhereExistsQuery( query, combinator, negate ) {
var type = negate ? "notExists" : "exists";
variables.wheres.append( {
type = type,
query = arguments.query,
combinator = arguments.combinator
} );
query.getBindings().each( function( binding ) {
variables.bindings.where.append( binding );
} );
return this;
}

public Builder function orWhereExists( callback, negate = false ) {
arguments.combinator = "or";
return whereExists( argumentCollection = arguments );
}

public Builder function whereNotExists( callback, combinator = "and" ) {
arguments.negate = true;
return whereExists( argumentCollection = arguments );
}
public Builder function orWhereNotExists( callback ) {
arguments.combinator = "or";
arguments.negate = true;
return whereExists( argumentCollection = arguments );
}

private Builder function whereNested( required callback, combinator = "and" ) {
var query = forNestedWhere();
callback( query );
Expand Down
29 changes: 20 additions & 9 deletions models/Query/Grammars/Grammar.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ component displayname="Grammar" accessors="true" {
}

public string function compileSelect( required Quick.models.Query.Builder query ) {

var sql = [];

for ( var component in selectComponents ) {
Expand Down Expand Up @@ -84,39 +83,51 @@ component displayname="Grammar" accessors="true" {
return "WHERE #arrayToList( wheresArray, " " )#";
}

private function whereBasic( requried struct where, required Builder query ) {
private string function whereBasic( requried struct where, required Builder query ) {
if ( ! isStruct( where ) ) {
return;
}

where.column = wrapValue( where.column );
where.column = wrapColumn( where.column );

var placeholder = "?";
if ( where.operator == "in" || where.operator == "not in" ) {
placeholder = "(#placeholder#)";
}

if ( isInstanceOf( where.value, "Quick.models.Query.Expression" ) ) {
placeholder = where.value.getSql();
}

return "#where.column# #uCase( where.operator )# #placeholder#";
}

private function whereRaw( required struct where, required Builder query ) {
private string function whereRaw( required struct where, required Builder query ) {
return where.sql;
}

private function whereColumn( required struct where, required Builder query ) {
private string function whereColumn( required struct where, required Builder query ) {
return "#wrapColumn( where.first )# #where.operator# #wrapColumn( where.second )#";
}

private function whereNested( required struct where, required Builder query ) {
private string function whereNested( required struct where, required Builder query ) {
var sql = compileWheres( arguments.where.query, arguments.where.query.getWheres() );
// cut off the first 7 characters to account for the extra "WHERE"
return "(#mid( sql, 7 )#)";
}

private function whereSub( required struct where, required Builder query ) {
private string function whereSub( required struct where, required Builder query ) {
return "#wrapIdentifier( where.column )# #where.operator# (#compileSelect( where.query )#)";
}

private string function whereExists( required struct where, required Builder query ) {
return "EXISTS (#compileSelect( where.query )#)";
}

private string function whereNotExists( required struct where, required Builder query ) {
return "NOT EXISTS (#compileSelect( where.query )#)";
}

private string function concatenate( required array sql ) {
return arrayToList( arrayFilter( sql, function( item ) {
return item != "";
Expand All @@ -130,13 +141,13 @@ component displayname="Grammar" accessors="true" {
private string function wrapTable( required any table ) {
var alias = "";
if ( table.find( " as " ) ) {
alias = table.listToArray( " as ", false, true )[ 2 ];
alias = wrapTable( table.listToArray( " as ", false, true )[ 2 ] );
table = table.listToArray( " as ", false, true )[ 1 ];
}
table = table.listToArray( "." ).map( function( tablePart, index ) {
return wrapValue( index == 1 ? getTablePrefix() & tablePart : tablePart );
} ).toList( "." );
return alias == "" ? table : table & " AS " & wrapTable( alias );
return alias == "" ? table : table & " AS " & alias;
}

private string function wrapColumn( required any column ) {
Expand Down

0 comments on commit d4174e3

Please sign in to comment.