Skip to content

Commit

Permalink
feat(QueryBuilder): Add andWhere method for more readable chains.
Browse files Browse the repository at this point in the history
`andWhere` behaves exactly like `where`.  It is provided for
a more readable method chain if desired.
  • Loading branch information
elpete committed Jun 4, 2018
1 parent 6ed68ee commit 309f4d8
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 2 deletions.
31 changes: 30 additions & 1 deletion models/Query/QueryBuilder.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,26 @@ component displayname="QueryBuilder" accessors="true" {
return this;
}

/**
* Adds a WHERE clause to the query.
* Alias for `where`.
*
* @column The name of the column with which to constrain the query. A closure can be passed to begin a nested where statement.
* @operator The operator to use for the constraint (i.e. "=", "<", ">=", etc.). A value can be passed as the `operator` and the `value` left null as a shortcut for equals (e.g. where( "column", 1 ) == where( "column", "=", 1 ) ).
* @value The value with which to constrain the column. An expression (`builder.raw()`) can be passed as well.
* @combinator The boolean combinator for the clause (e.g. "and" or "or"). Default: "and"
*
* @return qb.models.Query.QueryBuilder
*/
public QueryBuilder function andWhere(
column,
operator,
value,
string combinator = "and"
) {
return where( argumentCollection = arguments );
}

/**
* Adds a where clause where the value is a subquery.
*
Expand Down Expand Up @@ -2020,7 +2040,7 @@ component displayname="QueryBuilder" accessors="true" {
/**
* onMissingMethod serves the following purpose for Builder:
*
* Magic `where` methods. If a method starts with `where` or `orWhere`
* Magic `where` methods. If a method starts with `where`, `andWhere`, or `orWhere`
* but doesn't match any other methods, Builder assumes that what
* comes after is the column name to constrain.
* All the other arguments to `where` are shifted accordingly.
Expand All @@ -2036,6 +2056,15 @@ component displayname="QueryBuilder" accessors="true" {
return where( argumentCollection = args );
}

if ( ! arrayIsEmpty( REMatchNoCase( "^andWhere(.+)", missingMethodName ) ) ) {
var args = { "1" = mid( missingMethodName, 9, len( missingMethodName ) - 8 ) };
for ( var key in missingMethodArguments ) {
args[ key + 1 ] = missingMethodArguments[ key ];
}

return andWhere( argumentCollection = args );
}

if ( ! arrayIsEmpty( REMatchNoCase( "^orWhere(.+)", missingMethodName ) ) ) {
var args = { "1" = mid( missingMethodName, 8, len( missingMethodName ) - 7 ) };
for ( var key in missingMethodArguments ) {
Expand Down
2 changes: 1 addition & 1 deletion tests/Application.cfc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
component {
this.mappings[ "/tests" ] = getDirectoryFromPath( getCurrentTemplatePath() );
this.mappings[ "/qb" ] = expandPath( "/" );
}
}
10 changes: 10 additions & 0 deletions tests/resources/AbstractQueryBuilderSpec.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,16 @@ component extends="testbox.system.BaseSpec" {
}, orWhere() );
} );

it( "can add and where statements", function() {
testCase( function( builder ) {
builder
.select( "*" )
.from( "users" )
.where( "id", "=", 1 )
.andWhere( "email", "foo" );
}, andWhere() );
} );

it( "can add raw where statements", function() {
testCase( function( builder ) {
builder.select( "*" ).from( "users" ).whereRaw( "id = ? OR email = ?", [ 1, "foo" ] );
Expand Down
7 changes: 7 additions & 0 deletions tests/specs/Query/MSSQLQueryBuilderSpec.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ component extends="tests.resources.AbstractQueryBuilderSpec" {
};
}

function andWhere() {
return {
sql = "SELECT * FROM [users] WHERE [id] = ? AND [email] = ?",
bindings = [ 1, "foo" ]
};
}

function whereRaw() {
return {
sql = "SELECT * FROM [users] WHERE id = ? OR email = ?",
Expand Down
7 changes: 7 additions & 0 deletions tests/specs/Query/MySQLQueryBuilderSpec.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ component extends="tests.resources.AbstractQueryBuilderSpec" {
};
}

function andWhere() {
return {
sql = "SELECT * FROM `users` WHERE `id` = ? AND `email` = ?",
bindings = [ 1, "foo" ]
};
}

function whereRaw() {
return {
sql = "SELECT * FROM `users` WHERE id = ? OR email = ?",
Expand Down
7 changes: 7 additions & 0 deletions tests/specs/Query/OracleQueryBuilderSpec.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ component extends="tests.resources.AbstractQueryBuilderSpec" {
};
}

function andWhere() {
return {
sql = "SELECT * FROM ""USERS"" WHERE ""ID"" = ? AND ""EMAIL"" = ?",
bindings = [ 1, "foo" ]
};
}

function whereRaw() {
return {
sql = "SELECT * FROM ""USERS"" WHERE id = ? OR email = ?",
Expand Down
7 changes: 7 additions & 0 deletions tests/specs/Query/PostgresQueryBuilderSpec.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ component extends="tests.resources.AbstractQueryBuilderSpec" {
};
}

function andWhere() {
return {
sql = "SELECT * FROM ""users"" WHERE ""id"" = ? AND ""email"" = ?",
bindings = [ 1, "foo" ]
};
}

function whereRaw() {
return {
sql = "SELECT * FROM ""users"" WHERE id = ? OR email = ?",
Expand Down

0 comments on commit 309f4d8

Please sign in to comment.