finesse / micro-db
A simple database connector for using pure men's SQL with bindings 💪
Installs: 1 583
Dependents: 1
Suggesters: 0
Security: 0
Stars: 1
Watchers: 2
Forks: 2
Open Issues: 0
Requires
- php: >=7.0
- ext-pdo: *
Requires (Dev)
- ext-gd: *
- ext-pdo_sqlite: *
- ext-reflection: *
- mockery/mockery: ^1.0
- phpunit/phpunit: ^6.4
README
Like to use pure SQL but don't like to suffer from PDO, mysqli or etc.? Try this.
$database = Connection::create('mysql:host=localhost;dbname=my_database', 'user', 'pass'); $items = $database->select('SELECT * FROM items WHERE category_id = ?', [3]);
Key features:
- No silly query builder, only a good old SQL.
- Very light, no external dependencies. It required only the PDO extension which is available by default in most of servers.
- Database object is delivered explicitly, not through a static class.
- Exceptions on errors.
You can combine it with a third-party SQL query builder to rock the database. Examples of suitable query builders: Query Scribe, Nilportugues SQL Query Builder, Aura.SqlQuery, Latitude, Koine Query Builder, Phossa2 Query, Hydrahon.
Installation
Using Composer
Run in a console
composer require finesse/micro-db
Reference
Create a Connection
instance
To create a new Connection
instance call the create
method passing
PDO constructor arguments.
use Finesse\MicroDB\Connection; $database = Connection::create('dsn:string', 'username', 'password, ['options']);
Or pass a PDO
instance to the constructor. But be careful: Connection
changes the given PDO
object and you
must not change the given object, otherwise something unexpected will happen.
use Finesse\MicroDB\Connection; $pdo = new PDO(/* ... */); $database = new Connection($pdo);
Select
Select many rows:
$rows = $database->select('SELECT * FROM table'); // [['id' => 1, 'name' => 'Bill'], ['id' => 2, 'name' => 'John']]
Select one row:
$row = $database->selectFirst('SELECT * FROM table'); // ['id' => 1, 'name' => 'Bill']
The cell values are returned as they are returned by PDO. They are not casted automatically because casting can cause data loss.
Insert
Insert and get the number of the inserted rows:
$insertedCount = $database->insert('INSERT INTO table (id, price) VALUES (1, 45), (2, 98)'); // 2
Insert and get the identifier of the last inserted row:
$id = $database->insertGetId('INSERT INTO table (weight, price) VALUES (12.3, 45)'); // 3
Update
Update rows and get the number of the updated rows:
$updatedCount = $database->update('UPDATE table SET status = 1 WHERE price < 1000');
Delete
Delete rows and get the number of the deleted rows:
$deletedCount = $database->delete('DELETE FROM table WHERE price > 1000');
Other queries
Perform any other statement:
$database->statement('CREATE TABLE table(id INTEGER PRIMARY KEY ASC, name TEXT, price NUMERIC)');
If the query contains multiple statements separated by a semicolon, only the first statement will be executed. You can execute multiple statements using the other method:
$database->statements(" CREATE TABLE table(id INTEGER PRIMARY KEY ASC, name TEXT, price NUMERIC); INSERT INTO table (name, price) VALUES ('Donald', 1000000); ");
The lack of this method is that it doesn't take values to bind.
Execute a file
Execute the query from an SQL file:
$database->import('path/to/file.sql');
Or from a resource:
$stream = fopen('path/to/file.sql', 'r'); $database->import($stream);
Binding values
You should not insert values right to an SQL query because it can cause SQL injections. Instead use the binding:
// WRONG! Don't do it or you will be fired $rows = $database->select("SELECT * FROM table WHERE name = '$name' LIMIT $limit"); // Good $rows = $database->select('SELECT * FROM table WHERE name = ? LIMIT ?', [$name, $limit]);
Database server replaces the placeholders (?
s) safely with the given values. Almost all the above methods accepts
the list of the bound values as the second argument.
You can also use named parameters:
$rows = $database->select('SELECT * FROM table WHERE name = :name LIMIT :limit', [':name' => $name, ':limit' => $limit]);
You can even pass named and anonymous parameters in the same array but it works only when the array of values has the same order as the placeholders in the query text.
All the scalar types of values are supported: string, integer, float, boolean and null.
Error handling
The Finesse\MicroDB\Exceptions\PDOException
is thrown in case of every database query error. If an error is caused
by an SQL query, the exception has the query text and bound values in the message. They are also available through the
methods:
$sql = $exception->getQuery(); $bindings = $exception->getValues();
The Finesse\MicroDB\Exceptions\InvalidArgumentException
is thrown when the method arguments have a wrong format.
The Finesse\MicroDB\Exceptions\FileException
is thrown on a file read error.
All the exceptions implement Finesse\MicroDB\IException
.
Retrieve the underlying PDO
object
$pdo = $database->getPDO();
You must not change the retrieved object, otherwise something unexpected will happen.
Known problems
insertGetId
doesn't return the inserted row identifier for SQL Server and PostgreSQL.statements
andimport
don't throw an exception if the second or a next statement of the query has an error. This is a PDO bug.
Make a pull request or an issue if you need a problem to be fixed.
Versions compatibility
The project follows the Semantic Versioning.
License
MIT. See the LICENSE file for details.