v-dem / queasy-db
Database access classes, part of QuEasy PHP framework
Installs: 163
Dependents: 2
Suggesters: 1
Security: 0
Stars: 4
Watchers: 2
Forks: 2
Open Issues: 13
pkg:composer/v-dem/queasy-db
Requires
- php: >=5.3.0
- ext-pdo: *
- psr/log: ~1.1
- v-dem/queasy-helper: ~1.1
Requires (Dev)
- ext-sqlite3: *
- ext-xdebug: *
- phpunit/phpunit: ~10
Suggests
- v-dem/queasy-config: Configuration provider package, supports PHP (and multifile configs in this case), INI, XML and JSON (and YAML in future) formats
- v-dem/queasy-log: PSR-3 compatible logger package, supports file system log writer, console and email (using mail() function)
README
QuEasy PHP Framework - Database
Package v-dem/queasy-db
QuEasy DB is a set of database access classes mainly for CRUD operations.
Some of the most usual queries can be built automatically (like SELECT by unique field, UPDATE, INSERT and DELETE).
Complex queries can be defined in database and/or tables config.
Also there's a simple query builder.
The main goal is to separate SQL queries out of PHP code and provide an easy way for CRUD operations.
Features
- QuEasy DB extends
PDOclass, so any project which usesPDOcan be seamlessly moved to use QuEasy DB. - Simple CRUD database operations in just one PHP code row.
- Simple query builder.
- Separating SQL queries from PHP code.
Requirements
- PHP version 5.3 or higher
Installation
composer require v-dem/queasy-db
This will also install v-dem/queasy-helper.
Usage
Notes
- You can use
setLogger()method which acceptsPsr\Log\LoggerInterfaceimplementation to log all queries, by defaultPsr\Log\NullLoggeris used. - By default error mode (
PDO::ATTR_ERRMODE) is set toPDO::ERRMODE_EXCEPTION(as in PHP8). If you need to use other error mode and are usingDb::trans()method then be sure to manually checkerrorInfo()and throw an exception inside transaction. - For PostgreSQL you may need to add option
Db::ATTR_USE_RETURNING => trueon initialization to makeDb::id()work (it will addRETURNING "id"to each singleINSERTstatement). - All table and column names in auto-generated SQL code are enclosed in double quotes (as per ANSI SQL standard) so check following notes:
- For MySQL need to set option
PDO::MYSQL_ATTR_INIT_COMMANDtoSET SQL_MODE = ANSI_QUOTESor run same query after initialization. - For MS SQL Server need to run
SET QUOTED_IDENTIFIER ONorSET ANSI_DEFAULTS ONquery after initialization.
Initialization
$db = new queasy\db\Db( [ 'connection' => [ 'dsn' => 'pgsql:host=localhost;dbname=test', 'user' => 'test_user', 'password' => 'test_password', 'options' => [ ...options... ] ] ] );
Or PDO-way:
$db = new queasy\db\Db('pgsql:host=localhost;dbname=test', 'test_user', 'test_password', $options);
If DSN is not set then SQLite in-memory database will be used:
$db = new queasy\db\Db();
Retrieving records
Get all records from users table
$users = $db->users->all();
Using foreach with users table
foreach ($db->users as $user) { // Do something }
Get single record from users table by id key
$user = $db->users->id[$userId];
It's possible to use select() method to pass PDO options; select() returns PDOStatement instance:
$users = $db->users->id->select($userId, $options);
Get multiple records
$users = $db->users->id[[$userId1, $userId2]];
Inserting records
Insert a record into users table using associative array
$db->users[] = [ 'email' => 'john.doe@example.com', 'password_hash' => sha1('myverystrongpassword') ];
Insert a record into users table by fields order
$db->users[] = [ 'john.doe@example.com', sha1('myverystrongpassword') ];
Insert many records into users table using associative array (it will generate single INSERT statement)
$db->users[] = [ [ 'email' => 'john.doe@example.com', 'password_hash' => sha1('myverystrongpassword') ], [ 'email' => 'mary.joe@example.com', 'password_hash' => sha1('herverystrongpassword') ] ];
Insert many records into users table by order
$db->users[] = [ [ 'john.doe@example.com', sha1('myverystrongpassword') ], [ 'mary.joe@example.com', sha1('herverystrongpassword') ] ];
Also it's possible to use insert() method (in the same way as above) when need to pass PDO options; returns last insert id for single insert and number of inserted rows for multiple inserts:
$userId = $db->users->insert([ 'email' => 'john.doe@example.com', 'password_hash' => sha1('myverystrongpassword') ], $options);
$insertedRowsCount = $db->users->insert([ [ 'email' => 'john.doe@example.com', 'password_hash' => sha1('myverystrongpassword') ], [ 'email' => 'mary.joe@example.com', 'password_hash' => sha1('herverystrongpassword') ] ], $options);
- Second argument (
$options) is optional, it will be passed toPDO::prepare()
Updating records
Update a record in users table by id key
$db->users->id[$userId] = [ 'password_hash' => sha1('mynewverystrongpassword') ]
$updatedRowsCount = $db->users->id->update($userId, [ 'password_hash' => sha1('mynewverystrongpassword') ], $options);
- Third argument (
$options) is optional, it will be passed toPDO::prepare()
Update multiple records
$db->users->id[[$userId1, $userId2]] = [ 'is_blocked' => true ]
Deleting records
Delete a record in users table by id key
unset($db->users->id[$userId]);
Delete multiple records
unset($db->users->id[[$userId1, $userId2]]);
$deletedRowsCount = $db->users->id->delete([[$userId1, $userId2]], $options);
- Second argument (
$options) is optional, it will be passed toPDO::prepare()
Other functions
Get last insert id (alias for lastInsertId() method)
$newUserId = $db->id();
Get count of all records in users table
$usersCount = count($db->users);
Using transactions
$db->trans(function() use($db) { // Run queries inside a transaction, for example: $db->users[] = [ 'john.doe@example.com', sha1('myverystrongpassword') ]; });
- On exception transaction is rolled back and exception re-thrown to outer code.
Run custom queries (returns PDOStatement)
$users = $db->run(' SELECT * FROM "users" WHERE "name" LIKE concat(\'%\', :searchName, \'%\')', [ ':searchName' => 'John' ], $options )->fetchAll();
- Third argument (
$options) is optional, it will be passed toPDO::prepare()
Run query predefined in configuration
This feature can help keep code cleaner and place SQL code outside PHP, somewhere in config files.
$db = new queasy\db\Db( [ 'connection' => [ 'dsn' => 'pgsql:host=localhost;dbname=test', 'user' => 'test_user', 'password' => 'test_password' ], 'queries' => [ 'searchUsersByName' => [ 'sql' => ' SELECT * FROM "users" WHERE "name" LIKE concat(\'%\', :searchName, \'%\')', 'returns' => Db::RETURN_ALL ] ] ] ); $users = $db->searchUsersByName([ 'searchName' => 'John' ]);
- Possible values for
returnsoption areDb::RETURN_STATEMENT(default, returnsPDOStatementinstance),Db::RETURN_ONE,Db::RETURN_ALL(usingPDOStatement::fetchAll()method),Db::RETURN_VALUE
Also it is possible to group predefined queries by tables:
$db = new queasy\db\Db( [ 'connection' => [ 'dsn' => 'pgsql:host=localhost;dbname=test', 'user' => 'test_user', 'password' => 'test_password' ], 'tables' => [ 'users' => [ 'searchByName' => [ 'sql' => ' SELECT * FROM "user_roles" WHERE "name" LIKE concat(\'%\', :searchName, \'%\')', 'returns' => Db::RETURN_ALL ] ] ] ] ); $users = $db->users->searchByName([ 'searchName' => 'John' ]);
Using v-dem/queasy-db together with v-dem/queasy-config and v-dem/queasy-log
config.php:
return [ 'db' => [ 'connection' => [ 'dsn' => 'pgsql:host=localhost;dbname=test', 'user' => 'test_user', 'password' => 'test_password' ], 'tables' => [ 'users' => [ 'searchByName' => [ 'sql' => ' SELECT * FROM "users" WHERE "name" LIKE concat(\'%\', :searchName, \'%\')', 'returns' => Db::RETURN_ALL ] ] ] ], 'logger' => [ [ 'class' => queasy\log\ConsoleLogger::class, 'minLevel' => Psr\Log\LogLevel::DEBUG ] ] ];
Initializing:
$config = new queasy\config\Config('config.php'); // Can be also INI, JSON or XML $logger = new queasy\log\Logger($config->logger); $db = new queasy\db\Db($config->db); $db->setLogger($logger); $users = $db->users->searchByName([ 'searchName' => 'John' ]);
- All queries will be logged with
Psr\Log\LogLevel::DEBUGlevel. Also it's possible to use any other logger class compatible with PSR-3.