diff --git a/README.md b/README.md index 2eb8b3e..914fd42 100644 --- a/README.md +++ b/README.md @@ -11,16 +11,26 @@ ## Introduction -Extra minimalist PHP database wrapper. +Minimalist modern PHP database wrapper. ## Features -- Currently only abstract pdo_mysql / mysqli drivers with minimal functions. +- Small, fast and modern database abstraction layer. +- Provides mysqli, pdo_mysql, pdo_sqlite driver implementations. +- Thoroughly tested and documented. +- Adhere to soluble standards. ## Requirements - PHP engine 5.4+, 7.0+ or HHVM >= 3.2. -- PHP extensions pfo, pdo_mysql and mysqli. + +## Motivations + +Initially the reason behind the development of `soluble/dbwrapper` was to get +a reliable, modern and lightweight library to abstract the `PDO_mysql` and `mysqli` driver interfaces. + +*If you are looking for a more complete library with extra drivers and a SQL abstraction, +take a look at the excellent [`zendframework/zend-db`](https://github.com/zendframework/zend-db) package.* ## Installation @@ -53,11 +63,12 @@ $conn = new \PDO("mysql:host=$hostname", $username, $password, [ ]); try { - $adapter = DbWrapperAdapterFactory::createFromConnection($conn); + $adapter = DbWrapperAdapterFactory::createAdapterFromResource($conn); +} catch (DbWrapper\Exception\UnsupportedDriverException $e) { + // ... } catch (DbWrapper\Exception\InvalidArgumentException $e) { // ... } - ``` Create an adapter from an existing Mysqli connection @@ -70,18 +81,37 @@ use Soluble\DbWrapper; $conn = new \mysqli($hostname,$username,$password,$database); $conn->set_charset($charset); -try { - $adapter = DbWrapper\AdapterFactory::createFromConnection($conn); -} catch (DbWrapper\Exception\InvalidArgumentException $e) { - // ... -} +$adapter = DbWrapper\AdapterFactory::createAdapterFromResource($conn); + +``` + +### Querying database +Execute +```php +query("select * from my_table"); +foreach($results as $result) { + echo $result['my_column']; +} ``` -### API methods -Once a `DbWrapper\Adapter\AdapterInterface is intitalized, you have access to the following methods +## API methods + +### AdapterFactory + +The `DbWrapper\AdapterFactory` allows to instanciate an Adapter from en existing connection link or resource. + +| Methods | Return | Comment | +|-----------------------------------------------|--------------------|-------------------------------------| +| static `createAdapterFromResource($resource)` | `AdapterInterface` | Create an adapter from existing resource | + + +### AdapterInterface + +Once a `DbWrapper\Adapter\AdapterInterface` is intitalized, you have access to the following methods | Methods | Return | Description | |---------------------------------|---------------|-----------------------------------------------| @@ -91,6 +121,15 @@ Once a `DbWrapper\Adapter\AdapterInterface is intitalized, you have access to th | `getCurrentSchema()` | `string|false`| Return current schema | | `getResource()` | `mixed` | Return internal connection (pdo, mysqli...) | +### Resultset + +The `DbWrapper\Result\Resultset` is can be easily iterated through a simple foreach loop. +Additionnaly you can call the following methods : + +| Methods | Return | Description | +|---------------------------------|---------------|-----------------------------------------------| +| `count()` | `int` | Count the number of results | + ## Supported drivers @@ -99,12 +138,14 @@ Currently only pdo_mysql and mysqli drivers are supported. | Drivers | DbWrapper\Adapter\AdapterInterface implementations | |--------------------|------------------------------------------------------| | pdo_mysql | `Soluble\DbWrapper\Adapter\PdoMysqlAdapter` | +| pdo_sqlite | `Soluble\DbWrapper\Adapter\PdoSqliteAdapter` | | mysqli | `Soluble\DbWrapper\Adapter\MysqliAdapter` | +You can easily add new drivers by implementing the `DbWrapper\Adapter\AdapterInterface`. ## Contributing -Contribution are welcome see [contribution guide](./CONTRIBUTING.md) +Contribution and pull request are more than welcome, see the [contribution guide](./CONTRIBUTING.md) ## Coding standards @@ -112,8 +153,3 @@ Contribution are welcome see [contribution guide](./CONTRIBUTING.md) * [PSR 2 Coding Style Guide](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) * [PSR 1 Coding Standards](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md) * [PSR 0 Autoloading standards](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md) - - - - - diff --git a/phpunit.xml.dist b/phpunit.xml.dist index eddb78b..fe1b8f0 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -24,7 +24,7 @@ - ./test/src/Soluble/DbWrapper + ./test/src/SolubleTest/DbWrapper diff --git a/src/Soluble/DbWrapper/Adapter/PdoSqliteAdapter.php b/src/Soluble/DbWrapper/Adapter/PdoSqliteAdapter.php new file mode 100644 index 0000000..1d66362 --- /dev/null +++ b/src/Soluble/DbWrapper/Adapter/PdoSqliteAdapter.php @@ -0,0 +1,41 @@ +getAttribute(\PDO::ATTR_DRIVER_NAME) != 'sqlite') { + $msg = __CLASS__ . " requires pdo connection to be 'sqlite'"; + throw new Exception\InvalidArgumentException($msg); + } + $this->resource = $connection; + } + + /** + * {@inheritdoc} + */ + public function getCurrentSchema() + { + throw new \Exception('nope'); + } +} diff --git a/src/Soluble/DbWrapper/AdapterFactory.php b/src/Soluble/DbWrapper/AdapterFactory.php index 6287978..fa880af 100644 --- a/src/Soluble/DbWrapper/AdapterFactory.php +++ b/src/Soluble/DbWrapper/AdapterFactory.php @@ -6,28 +6,49 @@ class AdapterFactory { /** - * Get an adapter from an existing connection + * Create adapter from an existing connection resource * - * @param \PDO|\mysqli $connection database connection object + * @param mixed $resource database connection object (mysqli, pdo_mysql,...) * @throws Exception\InvalidArgumentException + * @throws Exception\UnsupportedDriverException * @return Adapter\AdapterInterface */ - public static function createAdapterFromConnection($connection) + public static function createAdapterFromResource($resource) { - if ($connection instanceof \PDO) { - switch ($connection->getAttribute(\PDO::ATTR_DRIVER_NAME)) { - case 'mysql': - $adapter = new Adapter\PdoMysqlAdapter($connection); - break; - default: - $msg = "Currently only support 'pdo_mysql' connection"; - throw new Exception\InvalidArgumentException($msg); - } - } elseif ($connection instanceof \mysqli) { - $adapter = new Adapter\MysqliAdapter($connection); + if (is_scalar($resource) || is_array($resource)) { + throw new Exception\InvalidArgumentException("Resource param must be a valid 'resource' link (mysqli, pdo)"); + } if ($resource instanceof \PDO) { + $adapter = self::getAdapterFromPdo($resource); + } elseif (extension_loaded('mysqli') && $resource instanceof \mysqli) { + $adapter = new Adapter\MysqliAdapter($resource); + } elseif (is_object($resource)) { + $class = get_class($resource); + $msg = "Resource connection '$class' is either unsupported or php extension not enabled."; + throw new Exception\UnsupportedDriverException($msg); } else { - $msg = "Currently only support 'pdo' or 'mysqli' connections"; - throw new Exception\InvalidArgumentException($msg); + throw new Exception\InvalidArgumentException("Resource must be a valid connection link, like PDO or mysqli"); + } + return $adapter; + } + + + /** + * Get an adapter from an existing connection resource + * + * @param \PDO $resource database connection object + * @throws Exception\UnsupportedDriverException + * @return Adapter\AdapterInterface + */ + protected static function getAdapterFromPdo(\PDO $resource) { + + $driver = $resource->getAttribute(\PDO::ATTR_DRIVER_NAME); + switch ($driver) { + case 'mysql': + $adapter = new Adapter\PdoMysqlAdapter($resource); + break; + default: + $msg = "Driver 'PDO_$driver' is not currently supported."; + throw new Exception\UnsupportedDriverException($msg); } return $adapter; } diff --git a/src/Soluble/DbWrapper/Exception/UnsupportedDriverException.php b/src/Soluble/DbWrapper/Exception/UnsupportedDriverException.php new file mode 100644 index 0000000..068688d --- /dev/null +++ b/src/Soluble/DbWrapper/Exception/UnsupportedDriverException.php @@ -0,0 +1,7 @@ +add('Soluble', array($baseDir . '/src/', $baseDir . '/test/')); +$loader->add('SolubleTest', array($baseDir . '/src/', $baseDir . '/test/')); $loader->register(); diff --git a/test/src/Soluble/DbWrapper/AdapterFactoryTest.php b/test/src/SolubleTest/DbWrapper/AdapterFactoryTest.php similarity index 73% rename from test/src/Soluble/DbWrapper/AdapterFactoryTest.php rename to test/src/SolubleTest/DbWrapper/AdapterFactoryTest.php index 91fdb86..cb7c42b 100644 --- a/test/src/Soluble/DbWrapper/AdapterFactoryTest.php +++ b/test/src/SolubleTest/DbWrapper/AdapterFactoryTest.php @@ -1,6 +1,8 @@ assertInstanceOf('\Soluble\DbWrapper\Adapter\AdapterInterface', $adapter); $this->assertInstanceOf('\Soluble\DbWrapper\Adapter\MysqliAdapter', $adapter); } @@ -17,15 +19,15 @@ public function testCreateAdapterFromMysqliConnection() public function testCreateAdapterFromPDOMysqlConnection() { $conn = \SolubleTestFactories::getDbConnection('pdo:mysql'); - $adapter = AdapterFactory::createAdapterFromConnection($conn); + $adapter = AdapterFactory::createAdapterFromResource($conn); $this->assertInstanceOf('\Soluble\DbWrapper\Adapter\AdapterInterface', $adapter); $this->assertInstanceOf('\Soluble\DbWrapper\Adapter\PdoMysqlAdapter', $adapter); } public function testCreateAdapterThrowsException() { - $this->setExpectedException('Soluble\DbWrapper\Exception\InvalidArgumentException'); + $this->setExpectedException('Soluble\DbWrapper\Exception\UnsupportedDriverException'); $connection = new \PDO('sqlite::memory:'); - $adapter = AdapterFactory::createAdapterFromConnection($connection); + $adapter = AdapterFactory::createAdapterFromResource($connection); } } diff --git a/test/src/Soluble/DbWrapper/MysqliAdapterTest.php b/test/src/SolubleTest/DbWrapper/MysqliAdapterTest.php similarity index 96% rename from test/src/Soluble/DbWrapper/MysqliAdapterTest.php rename to test/src/SolubleTest/DbWrapper/MysqliAdapterTest.php index 983f6d6..fdd39f0 100644 --- a/test/src/Soluble/DbWrapper/MysqliAdapterTest.php +++ b/test/src/SolubleTest/DbWrapper/MysqliAdapterTest.php @@ -1,6 +1,8 @@