-
Notifications
You must be signed in to change notification settings - Fork 22
Getting Started
To install sqlbuilder, simply run composer require:
composer require corneltek/sqlbuilder 4.0.x-dev
SQLBuilder detects the database platform (mysql, pgsql, sqlite) by checking the driver object instance you pass to. There are 3 pre-defined driver classes:
SQLBuilder\Driver\MySQLDriverSQLBuilder\Driver\PgSQLDriverSQLBuilder\Driver\SQLiteDriver
The internal implementation uses the code below to check the driver type, and it's faster than comparing strings:
if ($driver instanceof MySQLDriver) {
// .. do something with MySQL
}To initialize a driver object is easy:
use SQLBuilder\Driver\MySQLDriver;
$driver = new MySQLDriver;And it's done.
These pre-defined driver classes derives from
SQLBuilder\Driver\BaseDriver, and
SQLBuilder\Driver\BaseDriver defines the core methods that
can quote strings, quote identifiers, deflate values and
so on...
You can also use the PDO* Drivers if you already have PDO connection object:
use SQLBuilder\Driver\PDOMySQLDriver;
use PDO;
$pdo = new PDO('mysql;....');
$driver = new PDOMySQLDriver($pdo);The constructor of PDO*Driver classes accepts PDO object as its first parameter. it will also setup PDO::quote method as the default quote handler.
To quote strings into SQL queries, you can specify the quote handler to your driver object, for example, PDO::quote method:
$driver->setQuoter(array($pdo, 'quote'));But if you're binding your string value with parameter marker, you don't actually need it. we will describe how to bind a value the later section.
SQLBuilder deflates your variables into the parameter markers, hence you need
to provide an object that can register arguments, that is, ArgumentArray.
Driver object and ArgumentArray is only used when calling toSQl method.
use SQLBuilder\ArgumentArray;
$args = new ArgumentArray;
$sql = $query->toSql($driver, $args);use SQLBuilder\Universal\Query\SelectQuery;
use SQLBuilder\Driver\MySQLDriver;
use SQLBuilder\ArgumentArray;
$args = new ArgumentArray;
$driver = new MySQLDriver;
$query = new SelectQuery;
$query->select(array('name', 'phone', 'address'))
->from('contacts')
;
$query->where('name LIKE :name', [ ':name' => '%John%' ]);
$sql = $query->toSql($driver, $args);And the generated SQL:
SELECT name, phone, address FROM contacts WHERE name LIKE :nameThe where() method we used in the above code can take a
string and an array as its arguments, and you can call this
method more than once to append conditions, e.g.,
$query->where('name LIKE :name', [ ':name' => '%John%' ])
->where('address LIKE :address', [ ':address' => '%223%' ])
;By default, conditions are appended with AND operator. if
you want to append a condition with OR operator, you can
use:
$query->where()...
->or()->where('...', ...);You can also explicitly specify AND operator:
$query->where()...
->and()->where('...', ...);The where() method also returns a
SQLBuilder\Universal\Syntax\Conditions object, and the
cascading method calls will be on this object as you
continue the fluent method calls. e.g.,
$query->where()
->equal('id', 3)
->is('confirmed' , true)
->in('code', [ 609, 3323, 689 ])
;And the above code would generate the following corresponding SQL:
... WHERE id = 3 AND confirmed IS TRUE AND code IN (609,3323,689)But don't worry about the injected parameters, these parameters were inserted via strict type checking, if you're worrying about security, you may check the source code here: https://github.com/c9s/SQLBuilder/blob/master/src/SQLBuilder/Driver/BaseDriver.php#L246
Even the parameter is deflating into the SQL query string, I
would still suggest you use parameter binding, we will
describe the magical Bind class in the next section.
Here is the table of the operator mapping:
| Operator | Method |
|---|---|
= |
equal($expr, $val) |
<> |
notEqual($expr, $val) |
< |
lessThan($expr, $val) |
<= |
lessThanOrEqual($expr, $val) |
> |
greaterThan($expr, $val) |
>= |
greaterThanOrEqual($expr, $val) |
IS |
is($expr, $boolean) |
IS NOT |
isNot($expr, $boolean) |
IN (...) |
in($expr, array $values) |
NOT IN (...) |
notIn($expr, array $values) |
LIKE |
like($expr, $pattern, $criteria) |
NOT LIKE |
notLike($expr, $pattern, $criteria) |
BETWEEN {min} AND {max} |
between($expr, $min, $max) |
( expr ) |
group() |
AND |
and() |
OR |
or() |
REGEXP |
regexp() |
Using Criteria for LIKE expr:
use SQLBuilder\Criteria;
$query->where()
->like('name', $pat, Criteria::CONTAINS);
$query->where()
->like('name', $pat, Criteria::STARTS_WITH);
$query->where()
->like('name', $pat, Criteria::ENDS_WITH);SQLBuilder provides a Bind class that helps you define an
argument that requires parameter binding, here is a short
example of using Bind class:
$query = new UpdateQuery;
$query->options('LOW_PRIORITY', 'IGNORE')->update('users')->set([
'name' => new Bind('name','Mary'),
]);
$query->where()
->equal('id', new Bind('id', 3));
$sql = $query->toSql($driver, $args);
// UPDATE LOW_PRIORITY IGNORE users SET name = :name WHERE id = :id'If you want to build a query with question mark, you can pass ParamMarker class to the query:
$query = new UpdateQuery;
$query->options('LOW_PRIORITY', 'IGNORE')->update('users')->set([
'name' => new ParamMarker('John'),
]);
$query->where()
->equal('id', new ParamMarker(3));
$sql = $query->toSql($driver, $args);
// UPDATE LOW_PRIORITY IGNORE users SET name = ? WHERE id = ?'The toSql method is actually an shared interface in SQLBuilder\ToSqlInterface, the prototype is:
public function toSql(BaseDriver $driver, ArgumentArray $args);That is, anything implemented with ToSqlInterface can be
deflated into SQL string through the driver object.
If you want to append raw SQL string with complex function call or expression,
you can use SQLBuilder\Raw to wrap your SQL expression up and pass it to the
query object like just you pass the arguments:
use SQLBuilder\Raw;
$query->update([ 'count' => new Raw('count + 3') ]);Anything implemented with SQLBuilder\ToSqlInterface interface can be passed to BaseDriver::deflate() method to generate SQL string and query arguments.