midorikocak / nanodb
Nano DB is a tiny php library that allows you to define easily usable repositories.
Requires
- php: ~7.4
- ext-json: *
- ext-pdo: *
- midorikocak/arraytools: ^1.0.2
- midorikocak/querymaker: ^1.4.3
- phpunit/php-token-stream: ^4.0
Requires (Dev)
- opsway/psr12-strict-coding-standard: ^0.3.0
- phpunit/phpunit: >=8.0
- squizlabs/php_codesniffer: ^3.5
README
Nano DB
Nano DB is a tiny php library that allows you to define easily usable repositories.
There are 3 handy classes and 1 example in this library. Let's start with basics:
Requirements
Strictly requires PHP 7.4.
Install
Via Composer
$ composer require midorikocak/nanodb
Usage
Database
To use database library, simple inject it with pdo.
use midorikocak\nanodb\Database; $pdo = new PDO('sqlite::memory:'); $db = new Database($pdo);
Alternatively, if you want to use a query object, you can inject it as well.
use midorikocak\nanodb\Database; $pdo = new PDO('sqlite::memory:'); $query = new QueryMaker(); $db = new Database($pdo, $query);
Operations are chained.
$db->insert($tableName, $data)->execute(); $lastInsertId = $db->lastInsertId(); $insertedItem = $db->select($tableName)->where('id', $lastInsertId)->fetch();
Select
If found, returns the data you need. If nothing found, empty array is returned.
print_r($db->select($tableName)->where('id', $id)->fetch());
Example output:
Array
(
[id] => 1
[username] => username
[email] => email@email.com
[password] => 123456789
)
Order by
To order results use the orderBy($fieldName)
method.
print_r($db->select($tableName)->where('id', $id)->orderBy('id', 'DESC')->fetch());
Offset and Limit
To limit and offset results use the limit($limit)
and offset($offset)
methods.
print_r($db->select($tableName)->where('id', $id)->limit(1)->offset(1)->fetch());
Insert
Insert using an array of data. Validation is your responsibility.
$db->select($tableName)->insert($tableName, $data)->executre();
Update
Insert using an array of data. Again validation is your responsibility. If id does not exist, throws exception.
$db->update($tableName, $data)->update($tableName, $data)->where('id', $id)->execute();
Delete
Returns affected rows. If id does not exist, throws exception.
$db->delete($tableName)->delete('id', $id)->execute();
RepositoryInterface
The repository interface is the interface of repositories.
<?php declare(strict_types=1); namespace midorikocak\nanodb; use midorikocak\querymaker\QueryInterface; interface RepositoryInterface { public function read(string $id); public function readAll(?QueryInterface $query = null): array; public function save($item); public function remove($data): int; }
If you want to use arrays to interact with your database, you can use the array repository.
use midorikocak\nanodb\ArrayRepository; $tableName = 'users'; $schema = [ 'username'=>'string', 'password'=>'string', 'email'=>'email' ]; $repository = new ArrayRepository($tableName, $this->db, $schema);
Here $schema
array is a simple optional array for Array validator, checked on every input with data. You can override it by extending ArrayValidator
class.
Class Repositories
Let's say you have a simple user class.
<?php declare(strict_types=1); class User { private ?string $id; private string $username; private string $email; private string $password; public function __construct(?string $id, string $username, string $email, string $password) { $this->id = $id; $this->username = $username; $this->password = $password; $this->email = $email; } public function getId(): ?string { return $this->id; } public function setId(string $id) { $this->id = $id; } public function getUsername(): string { return $this->username; } public function setUsername(string $username) { $this->username = $username; } public function getEmail(): string { return $this->email; } public function setEmail(string $email) { $this->email = $email; } public function getPassword(): string { return $this->password; } public function setPassword(string $password) { $this->password = $password; } }
You can create a Users
repository, by implementing the RepositoryInterface
.
<?php declare(strict_types=1); namespace midorikocak\nanodb; use Exception; use midorikocak\querymaker\QueryInterface; use function array_map; class Users implements RepositoryInterface { private DatabaseInterface $db; public function __construct(DatabaseInterface $db) { $this->db = $db; } /** * @return User */ public function read(string $id) { $data = $this->db->select('users')->where('id', $id)->fetch(); if (!$data) { throw new Exception('not found'); } return self::fromArray($data); } public function readAll(?QueryInterface $query = null): array { if ($query !== null) { $db = $this->db->query($query); } else { $db = $this->db->select('users'); } $db->execute(); return array_map(fn($data) => User::fromArray($data), $db->fetchAll()); } /** * @param User $user * @return User */ public function save($user) { if ($user->getId()) { $id = $user->getId(); $userData = self::toArray($user); unset($userData['id']); $this->db->update('users', $userData)->where('id', $id)->execute(); return $user; } $this->db->insert('users', self::toArray($user))->execute(); $lastInsertId = $this->db->lastInsertId(); $user->setId($lastInsertId); return $user; } /** * @param User $user */ public function remove($user): int { $id = $user->getId(); $this->db->delete('users')->where('id', $id)->execute(); return $this->db->rowCount(); } /** * @param User $user * @return User */ public static function fromArray(array $array): User { if (!isset($array['id'])) { $array['id'] = null; } return new User($array['id'], $array['username'], $array['email'], $array['password']); } /** * @param User $user * @return array */ public static function toArray(User $user): array { $toReturn = [ 'username' => $user->getUsername(), 'email' => $user->getEmail(), 'password' => $user->getPassword(), ]; if ($user->getId()) { $toReturn['id'] = $user->getId(); } return $toReturn; } }
Motivation and Warning
Mostly educational purposes. Please use at your own risk.
Change log
Please see CHANGELOG for more information on what has changed recently.
Testing
$ composer test
Contributing
Please see CONTRIBUTING and CODE_OF_CONDUCT for details.
Security
If you discover any security related issues, please email mtkocak@gmail.com instead of using the issue tracker.
Credits
License
The MIT License (MIT). Please see License File for more information.