diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..622e165 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +/.idea/ +/.vs/ +/.vscode/ +/vendor/ +/composer.lock +/.phpunit.result.cache +/nbproject/private/ +/*.log \ No newline at end of file diff --git a/Connection/Connection.php b/Connection/Connection.php new file mode 100644 index 0000000..24ea921 --- /dev/null +++ b/Connection/Connection.php @@ -0,0 +1,498 @@ + + * @copyright Copyright © 2023 Muhammet ŞAFAK + * @license ./LICENSE MIT + * @version 1.0 + * @link https://www.muhammetsafak.com.tr + */ + +declare(strict_types=1); +namespace InitORM\DBAL\Connection; + +use InitORM\DBAL\Connection\Exceptions\SQLExecuteException; +use InitORM\DBAL\Connection\Interfaces\ConnectionInterface; +use InitORM\DBAL\Connection\Exceptions\ValidConnectionAvailableException; +use InitORM\DBAL\Connection\Exceptions\ConnectionException; +use InitORM\DBAL\DataMapper\DataMapperFactory; +use InitORM\DBAL\DataMapper\Interfaces\DataMapperFactoryInterface; +use InitORM\DBAL\DataMapper\Interfaces\DataMapperInterface; +use PDO; +use Throwable; + +use const PHP_EOL; + +class Connection implements ConnectionInterface +{ + + /** + * @var array + */ + protected array $credentials = [ + 'dsn' => '', + 'username' => null, + 'password' => null, + 'charset' => 'utf8mb4', + 'collation' => 'utf8mb4_unicode_ci', + 'options' => [], + + 'driver' => 'mysql', + 'host' => '127.0.0.1', + 'port' => 3306, + 'database' => '', + + 'queryOptions' => [], + + 'log' => null, + 'debug' => false, + 'queryLogs' => false, + ]; + + /** + * @var PDO|null + */ + private ?PDO $pdo = null; + + /** + * @var array + */ + private array $queryLogs = []; + + /** + * @var DataMapperFactoryInterface + */ + private DataMapperFactoryInterface $dataMapperFactory; + + /** + * @inheritDoc + */ + public function __construct(array $credentials = []) + { + $this->credentials = array_merge($this->credentials, $credentials); + + $this->dataMapperFactory = new DataMapperFactory(); + } + + /** + * @param $name + * @param $arguments + * @return Connection|mixed + * @throws ConnectionException + */ + public function __call($name, $arguments) + { + $res = $this->getPDO()->{$name}(...$arguments); + + return ($res instanceof PDO) ? $this : $res; + } + + /** + * @inheritDoc + */ + public function clone(): self + { + return new self($this->credentials); + } + + /** + * @inheritDoc + */ + public function getPDO(): PDO + { + !isset($this->pdo) && $this->connect(); + + return $this->pdo; + } + + /** + * @inheritDoc + */ + public function connect(): bool + { + try { + $this->pdo = new PDO($this->getDsn(), $this->getUsername(), $this->getPassword(), $this->getOptions()); + + if ($charset = $this->getCharset()) { + if ($collation = $this->getCollation()) { + $this->pdo->exec("SET NAMES '" . $charset . "' COLLATE '" . $collation . "'"); + } + $this->pdo->exec("SET CHARACTER SET '" . $charset . "'"); + } + + if (!isset($this->credentials['driver'])) { + $this->credentials['driver'] = $this->pdo->getAttribute(PDO::ATTR_DRIVER_NAME); + } + + return true; + } catch (Throwable $e) { + throw new ConnectionException($e->getMessage(), (int)$e->getCode(), $e->getPrevious()); + } + } + + /** + * @inheritDoc + */ + public function disconnect(): bool + { + $this->pdo = null; + + return true; + } + + /** + * @inheritDoc + */ + public function setDatabase(string $database): self + { + if (isset($this->pdo)) { + throw new ValidConnectionAvailableException(); + } + + $this->credentials['database'] = $database; + + return $this; + } + + /** + * @inheritDoc + */ + public function getDatabase(): ?string + { + return $this->credentials['database'] ?? null; + } + + /** + * @inheritDoc + */ + public function setHost(string $host): self + { + if (isset($this->pdo)) { + throw new ValidConnectionAvailableException(); + } + + $this->credentials['host'] = $host; + + return $this; + } + + /** + * @inheritDoc + */ + public function getHost(): ?string + { + return $this->credentials['host'] ?? null; + } + + /** + * @inheritDoc + */ + public function setPort($port): self + { + if (isset($this->pdo)) { + throw new ValidConnectionAvailableException(); + } + + $this->credentials['port'] = $port; + + return $this; + } + + /** + * @inheritDoc + */ + public function getPort() + { + return $this->credentials['port'] ?? null; + } + + /** + * @inheritDoc + */ + public function setCharset(string $charset = 'utf8mb4', ?string $collation = null): self + { + if (isset($this->pdo)) { + throw new ValidConnectionAvailableException(); + } + + $this->credentials['charset'] = $charset; + $this->credentials['collation'] = empty($collation) ? $charset . '_unicode_ci' : $collation; + + return $this; + } + + /** + * @inheritDoc + */ + public function getCharset(): string + { + return $this->credentials['charset']; + } + + /** + * @inheritDoc + */ + public function getCollation(): string + { + return $this->credentials['collation']; + } + + /** + * @inheritDoc + */ + public function setDsn(string $dsn): self + { + if (isset($this->pdo)) { + throw new ValidConnectionAvailableException(); + } + + $this->credentials['dsn'] = $dsn; + + return $this; + } + + /** + * @inheritDoc + */ + public function getDsn(): string + { + if (!isset($this->credentials['dsn'])) { + $dsn = $this->credentials['driver'] . ':host=' . $this->credentials['host'] + . ';port=' . $this->credentials['port'] . ';dbname=' . $this->credentials['charset'] + . ';charset=' . $this->credentials['charset']; + + $this->credentials['dsn'] = $dsn; + } + + return $this->credentials['dsn']; + } + + /** + * @inheritDoc + */ + public function setUsername(?string $username): self + { + if (isset($this->pdo)) { + throw new ValidConnectionAvailableException(); + } + + $this->credentials['username'] = $username; + + return $this; + } + + /** + * @inheritDoc + */ + public function getUsername(): ?string + { + return $this->credentials['username'] ?? null; + } + + /** + * @inheritDoc + */ + public function setPassword(?string $password = null): self + { + if (isset($this->pdo)) { + throw new ValidConnectionAvailableException(); + } + + $this->credentials['password'] = $password; + + return $this; + } + + /** + * @inheritDoc + */ + public function getPassword(): ?string + { + return $this->credentials['password'] ?? null; + } + + /** + * @inheritDoc + */ + public function setDriver(string $driver): self + { + if (isset($this->pdo)) { + throw new ValidConnectionAvailableException(); + } + + $this->credentials['driver'] = $driver; + + return $this; + } + + /** + * @inheritDoc + */ + public function getDriver(): string + { + return $this->credentials['driver']; + } + + /** + * @inheritDoc + */ + public function setOptions(array $options = []): self + { + if (isset($this->pdo)) { + throw new ValidConnectionAvailableException(); + } + + !empty($options) && $this->credentials['options'] = array_merge($this->credentials['options'], $options); + + return $this; + } + + /** + * @inheritDoc + */ + public function getOptions(): array + { + return array_merge([ + PDO::ATTR_EMULATE_PREPARES => false, + PDO::ATTR_PERSISTENT => true, + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_CLASS, + ], $this->credentials['options']); + } + + /** + * @inheritDoc + */ + public function addQueryLog(string $query, ?array $args = null, $startTime = null): void + { + if (!$this->credentials['queryLogs']) { + return; + } + $this->queryLogs[] = [ + 'query' => $query, + 'args' => $args, + 'timer' => round(microtime(true) - $startTime, 6), + ]; + } + + /** + * @inheritDoc + */ + public function getQueryLogs(): array + { + return $this->queryLogs; + } + + /** + * @inheritDoc + */ + public function setQueryLogs(bool $status = false): self + { + $this->credentials['queryLogs'] = $status; + + return $this; + } + + /** + * @inheritDoc + */ + public function createLog(string $message, ?array $context = null): bool + { + if (empty($this->credentials['log'])) { + return false; + } + + !empty($context) && $message = strtr($message, $context); + + if (is_callable($this->credentials['log'])) { + call_user_func_array($this->credentials['log'], [$message]); + + return true; + } + + if (is_string($this->credentials['log'])) { + $path = strtr($this->credentials['log'], [ + '{timestamp}' => time(), + '{date}' => date("Y-m-d"), + '{datetime}' => date("Y-m-d-H-i-s"), + '{year}' => date("Y"), + '{month}' => date("m"), + '{day}' => date("d"), + '{hour}' => date("H"), + '{minute}' => date("i"), + '{second}' => date("s"), + ]); + + return (bool)@file_put_contents($path, $message, FILE_APPEND); + } + + if (is_object($this->credentials['log']) && method_exists($this->credentials['log'], 'critical')) { + call_user_func_array([$this->credentials['log'], 'critical'], [$message]); + + return true; + } + + return false; + } + + /** + * @inheritDoc + */ + public function setDebug(bool $status = false): self + { + $this->credentials['debug'] = $status; + + return $this; + } + + /** + * @inheritDoc + */ + public function getDebug(): bool + { + return $this->credentials['debug']; + } + + /** + * @inheritDoc + * @throws Throwable + */ + public function query(string $sqlQuery, ?array $parameters = null, ?array $options = null): DataMapperInterface + { + $startTime = microtime(true); + try { + $stmt = $this->getPDO()->prepare($sqlQuery, array_merge($this->credentials['queryOptions'], $options ?? [])); + if (!$stmt) { + throw new SQLExecuteException('The SQL query could not be prepared.'); + } + $dataMapper = $this->dataMapperFactory->createDataMapper($stmt); + + !empty($parameters) && $dataMapper->bindValues($parameters); + + if (!$dataMapper->execute()) { + throw new SQLExecuteException('The SQL query could not be executed.'); + } + $this->addQueryLog($sqlQuery, $parameters, $startTime); + + $errorCode = $stmt->errorCode(); + if ($errorCode !== null && !empty(trim($errorCode, "0 \n\r\t\v\0"))) { + $errorInfo = $stmt->errorInfo(); + if (isset($errorInfo[2])) { + $message = $errorCode . ' - ' . $errorInfo[2]; + throw new SQLExecuteException($message); + } + } + + return $dataMapper; + } catch (Throwable $e) { + $this->addQueryLog($sqlQuery, $parameters, $startTime); + $message = $e->getMessage() . PHP_EOL . 'SQL : "' . strtr($sqlQuery, $parameters ?? []) . '"'; + $this->createLog($message); + throw $e; + } + } + +} diff --git a/Connection/ConnectionFactory.php b/Connection/ConnectionFactory.php new file mode 100644 index 0000000..8bbc11d --- /dev/null +++ b/Connection/ConnectionFactory.php @@ -0,0 +1,31 @@ + + * @copyright Copyright © 2023 Muhammet ŞAFAK + * @license ./LICENSE MIT + * @version 1.0 + * @link https://www.muhammetsafak.com.tr + */ + +declare(strict_types=1); +namespace InitORM\DBAL\Connection; + +use InitORM\DBAL\Connection\Interfaces\ConnectionFactoryInterface; +use InitORM\DBAL\Connection\Interfaces\ConnectionInterface; + +class ConnectionFactory implements ConnectionFactoryInterface +{ + + /** + * @inheritDoc + */ + public function createConnection(array $credentials = []): ConnectionInterface + { + return new Connection($credentials); + } + +} diff --git a/Connection/Exceptions/ConnectionException.php b/Connection/Exceptions/ConnectionException.php new file mode 100644 index 0000000..101332d --- /dev/null +++ b/Connection/Exceptions/ConnectionException.php @@ -0,0 +1,21 @@ + + * @copyright Copyright © 2023 Muhammet ŞAFAK + * @license ./LICENSE MIT + * @version 1.0 + * @link https://www.muhammetsafak.com.tr + */ + +declare(strict_types=1); +namespace InitORM\DBAL\Connection\Exceptions; + +use Exception; + +class ConnectionException extends Exception +{ +} diff --git a/Connection/Exceptions/ConnectionInvalidArgumentException.php b/Connection/Exceptions/ConnectionInvalidArgumentException.php new file mode 100644 index 0000000..835ac94 --- /dev/null +++ b/Connection/Exceptions/ConnectionInvalidArgumentException.php @@ -0,0 +1,21 @@ + + * @copyright Copyright © 2023 Muhammet ŞAFAK + * @license ./LICENSE MIT + * @version 1.0 + * @link https://www.muhammetsafak.com.tr + */ + +declare(strict_types=1); +namespace InitORM\DBAL\Connection\Exceptions; + +use InvalidArgumentException; + +class ConnectionInvalidArgumentException extends InvalidArgumentException +{ +} diff --git a/Connection/Exceptions/SQLExecuteException.php b/Connection/Exceptions/SQLExecuteException.php new file mode 100644 index 0000000..9b1eb81 --- /dev/null +++ b/Connection/Exceptions/SQLExecuteException.php @@ -0,0 +1,19 @@ + + * @copyright Copyright © 2023 Muhammet ŞAFAK + * @license ./LICENSE MIT + * @version 1.0 + * @link https://www.muhammetsafak.com.tr + */ + +declare(strict_types=1); +namespace InitORM\DBAL\Connection\Exceptions; + +class SQLExecuteException extends ConnectionException +{ +} diff --git a/Connection/Exceptions/ValidConnectionAvailableException.php b/Connection/Exceptions/ValidConnectionAvailableException.php new file mode 100644 index 0000000..184f768 --- /dev/null +++ b/Connection/Exceptions/ValidConnectionAvailableException.php @@ -0,0 +1,19 @@ + + * @copyright Copyright © 2023 Muhammet ŞAFAK + * @license ./LICENSE MIT + * @version 1.0 + * @link https://www.muhammetsafak.com.tr + */ + +declare(strict_types=1); +namespace InitORM\DBAL\Connection\Exceptions; + +class ValidConnectionAvailableException extends ConnectionException +{ +} diff --git a/Connection/Interfaces/ConnectionFactoryInterface.php b/Connection/Interfaces/ConnectionFactoryInterface.php new file mode 100644 index 0000000..561da46 --- /dev/null +++ b/Connection/Interfaces/ConnectionFactoryInterface.php @@ -0,0 +1,26 @@ + + * @copyright Copyright © 2023 Muhammet ŞAFAK + * @license ./LICENSE MIT + * @version 1.0 + * @link https://www.muhammetsafak.com.tr + */ + +declare(strict_types=1); +namespace InitORM\DBAL\Connection\Interfaces; + +interface ConnectionFactoryInterface +{ + + /** + * @param array $credentials + * @return ConnectionInterface + */ + public function createConnection(array $credentials = []): ConnectionInterface; + +} diff --git a/Connection/Interfaces/ConnectionInterface.php b/Connection/Interfaces/ConnectionInterface.php new file mode 100644 index 0000000..1a59e40 --- /dev/null +++ b/Connection/Interfaces/ConnectionInterface.php @@ -0,0 +1,210 @@ + + * @copyright Copyright © 2023 Muhammet ŞAFAK + * @license ./LICENSE MIT + * @version 1.0 + * @link https://www.muhammetsafak.com.tr + */ + +declare(strict_types=1); +namespace InitORM\DBAL\Connection\Interfaces; + +use InitORM\DBAL\DataMapper\Interfaces\DataMapperInterface; +use PDO; +use InitORM\DBAL\Connection\Exceptions\ConnectionException; +use InitORM\DBAL\Connection\Exceptions\ValidConnectionAvailableException; + +interface ConnectionInterface +{ + + /** + * @param array $credentials + */ + public function __construct(array $credentials = []); + + /** + * @return self + */ + public function clone(): self; + + /** + * @return PDO + * @throws ConnectionException + */ + public function getPDO(): PDO; + + /** + * @param string $sqlQuery + * @param array|null $parameters + * @param array|null $options + * @return DataMapperInterface + */ + public function query(string $sqlQuery, ?array $parameters = null, ?array $options = null): DataMapperInterface; + + /** + * @return bool + * @throws ConnectionException + */ + public function connect(): bool; + + /** + * @return bool + */ + public function disconnect(): bool; + + /** + * @param string $database + * @return self + * @throws ValidConnectionAvailableException + */ + public function setDatabase(string $database): self; + + /** + * @return string|null + */ + public function getDatabase(): ?string; + + /** + * @param string $host + * @return self + * @throws ValidConnectionAvailableException + */ + public function setHost(string $host): self; + + /** + * @return string|null + */ + public function getHost(): ?string; + + /** + * @param int|string $port + * @return self + * @throws ValidConnectionAvailableException + */ + public function setPort($port): self; + + /** + * @return string|int|null + */ + public function getPort(); + + /** + * @param string $charset + * @param string|null $collation

IS NULL => {$charset}_unicode_ci

+ * @return self + * @throws ValidConnectionAvailableException + */ + public function setCharset(string $charset = 'utf8mb4', ?string $collation = null): self; + + /** + * @return string + */ + public function getCharset(): string; + + /** + * @return string + */ + public function getCollation(): string; + + /** + * @param string $dsn + * @return self + * @throws ValidConnectionAvailableException + */ + public function setDsn(string $dsn): self; + + /** + * @return string + */ + public function getDsn(): string; + + /** + * @param string|null $username + * @return self + * @throws ValidConnectionAvailableException + */ + public function setUsername(?string $username): self; + + /** + * @return string|null + */ + public function getUsername(): ?string; + + /** + * @param null|string $password + * @return self + * @throws ValidConnectionAvailableException + */ + public function setPassword(?string $password = null): self; + + /** + * @return string|null + */ + public function getPassword(): ?string; + + /** + * @param string $driver + * @return self + * @throws ValidConnectionAvailableException + */ + public function setDriver(string $driver): self; + + /** + * @return string + */ + public function getDriver(): string; + + /** + * @param array $options + * @return self + * @throws ValidConnectionAvailableException + */ + public function setOptions(array $options = []): self; + + /** + * @return array + */ + public function getOptions(): array; + + /** + * @param string $query + * @param array|null $args + * @param float|string $startTime

microtime(true)

+ * @return void + */ + public function addQueryLog(string $query, ?array $args = null, $startTime = null): void; + + /** + * @return array + */ + public function getQueryLogs(): array; + + /** + * @param bool $status + * @return self + */ + public function setQueryLogs(bool $status = false): self; + + /** + * @param string $message + * @param array|null $context + * @return bool + */ + public function createLog(string $message, ?array $context = null): bool; + + /** + * @param bool $status + * @return self + */ + public function setDebug(bool $status = false): self; + + /** + * @return bool + */ + public function getDebug(): bool; +} diff --git a/DataMapper/DataMapper.php b/DataMapper/DataMapper.php new file mode 100644 index 0000000..591860d --- /dev/null +++ b/DataMapper/DataMapper.php @@ -0,0 +1,216 @@ + + * @copyright Copyright © 2023 Muhammet ŞAFAK + * @license ./LICENSE MIT + * @version 1.0 + * @link https://www.muhammetsafak.com.tr + */ + +declare(strict_types=1); +namespace InitORM\DBAL\DataMapper; + +use InitORM\DBAL\DataMapper\Interfaces\DataMapperInterface; +use PDO; +use PDOStatement; +use InitORM\DBAL\DataMapper\Exceptions\DataMapperException; + +class DataMapper implements DataMapperInterface +{ + + private PDOStatement $statement; + + public function __construct(PDOStatement $statement) + { + $this->statement = $statement; + } + + /** + * @throws DataMapperException + */ + public function __call($name, $arguments) + { + $res = $this->getStatement()->{$name}(...$arguments); + + return ($res instanceof PDOStatement) ? $this : $res; + } + + /** + * @param $name + * @return mixed + * @throws DataMapperException + */ + public function __get($name) + { + return $this->getStatement()->{$name}; + } + + /** + * @param $name + * @return bool + * @throws DataMapperException + */ + public function __isset($name) + { + return isset($this->getStatement()->{$name}); + } + + /** + * @inheritDoc + */ + public function getStatement(): PDOStatement + { + if (!isset($this->statement)) { + throw new DataMapperException(); + } + + return $this->statement; + } + + /** + * @inheritDoc + */ + public function execute(?array $params = null): bool + { + return $this->getStatement()->execute($params); + } + + /** + * @inheritDoc + */ + public function getQuery(): string + { + return $this->getStatement()->queryString; + } + + /** + * @inheritDoc + */ + public function bindValue(string $key, $value): bool + { + $key = ':' . ltrim($key, ':'); + + return $this->getStatement()->bindValue($key, $value, $this->bind($value)); + } + + /** + * @inheritDoc + */ + public function bindValues(array $fields): bool + { + foreach ($fields as $key => $value) { + $this->bindValue($key, $value); + } + + return true; + } + + /** + * @inheritDoc + */ + public function bind($value): int + { + switch (true) { + case is_int($value): + case is_bool($value): + return PDO::PARAM_INT; + case is_null($value): + return PDO::PARAM_NULL; + default: + return PDO::PARAM_STR; + } + } + + /** + * @inheritDoc + */ + public function numRows(): int + { + $count = $this->getStatement()->rowCount(); + + return empty($count) ? 0 : $count; + } + + /** + * @inheritDoc + */ + public function asClass(?string $class = null): self + { + $this->getStatement()->setFetchMode(PDO::FETCH_CLASS, $class); + + return $this; + } + + /** + * @inheritDoc + */ + public function asObject(): self + { + $this->getStatement()->setFetchMode(PDO::FETCH_OBJ); + + return $this; + } + + /** + * @inheritDoc + */ + public function asAssoc(): self + { + $this->getStatement()->setFetchMode(PDO::FETCH_ASSOC); + + return $this; + } + + /** + * @inheritDoc + */ + public function asLazy(): self + { + $this->getStatement()->setFetchMode(PDO::FETCH_LAZY); + + return $this; + } + + /** + * @inheritDoc + */ + public function asArray(): self + { + $this->getStatement()->setFetchMode(PDO::FETCH_BOTH); + return $this; + } + + /** + * @inheritDoc + */ + public function asBoth(): self + { + return $this->asArray(); + } + + /** + * @inheritDoc + */ + public function row() + { + $res = $this->getStatement()->fetch(); + + return !empty($res) ? $res : null; + } + + /** + * @inheritDoc + */ + public function rows(): ?array + { + $res = $this->getStatement()->fetchAll(); + + return !empty($res) ? $res : null; + } + + +} diff --git a/DataMapper/DataMapperFactory.php b/DataMapper/DataMapperFactory.php new file mode 100644 index 0000000..244c0e1 --- /dev/null +++ b/DataMapper/DataMapperFactory.php @@ -0,0 +1,29 @@ + + * @copyright Copyright © 2023 Muhammet ŞAFAK + * @license ./LICENSE MIT + * @version 1.0 + * @link https://www.muhammetsafak.com.tr + */ + +declare(strict_types=1); +namespace InitORM\DBAL\DataMapper; + +use InitORM\DBAL\DataMapper\Interfaces\DataMapperFactoryInterface; +use InitORM\DBAL\DataMapper\Interfaces\DataMapperInterface; +use PDOStatement; + +class DataMapperFactory implements Interfaces\DataMapperFactoryInterface +{ + + public function createDataMapper(PDOStatement $statement): DataMapperInterface + { + return new DataMapper($statement); + } + +} diff --git a/DataMapper/Exceptions/DataMapperException.php b/DataMapper/Exceptions/DataMapperException.php new file mode 100644 index 0000000..f4685c8 --- /dev/null +++ b/DataMapper/Exceptions/DataMapperException.php @@ -0,0 +1,21 @@ + + * @copyright Copyright © 2023 Muhammet ŞAFAK + * @license ./LICENSE MIT + * @version 1.0 + * @link https://www.muhammetsafak.com.tr + */ + +declare(strict_types=1); +namespace InitORM\DBAL\DataMapper\Exceptions; + +use Exception; + +class DataMapperException extends Exception +{ +} diff --git a/DataMapper/Exceptions/DataMapperInvalidArgumentException.php b/DataMapper/Exceptions/DataMapperInvalidArgumentException.php new file mode 100644 index 0000000..98b3528 --- /dev/null +++ b/DataMapper/Exceptions/DataMapperInvalidArgumentException.php @@ -0,0 +1,21 @@ + + * @copyright Copyright © 2023 Muhammet ŞAFAK + * @license ./LICENSE MIT + * @version 1.0 + * @link https://www.muhammetsafak.com.tr + */ + +declare(strict_types=1); +namespace InitORM\DBAL\DataMapper\Exceptions; + +use InvalidArgumentException; + +class DataMapperInvalidArgumentException extends InvalidArgumentException +{ +} diff --git a/DataMapper/Interfaces/DataMapperFactoryInterface.php b/DataMapper/Interfaces/DataMapperFactoryInterface.php new file mode 100644 index 0000000..b518762 --- /dev/null +++ b/DataMapper/Interfaces/DataMapperFactoryInterface.php @@ -0,0 +1,24 @@ + + * @copyright Copyright © 2023 Muhammet ŞAFAK + * @license ./LICENSE MIT + * @version 1.0 + * @link https://www.muhammetsafak.com.tr + */ + +declare(strict_types=1); +namespace InitORM\DBAL\DataMapper\Interfaces; + +use PDOStatement; + +interface DataMapperFactoryInterface +{ + + public function createDataMapper(PDOStatement $statement): DataMapperInterface; + +} diff --git a/DataMapper/Interfaces/DataMapperInterface.php b/DataMapper/Interfaces/DataMapperInterface.php new file mode 100644 index 0000000..3bb1189 --- /dev/null +++ b/DataMapper/Interfaces/DataMapperInterface.php @@ -0,0 +1,127 @@ + + * @copyright Copyright © 2023 Muhammet ŞAFAK + * @license ./LICENSE MIT + * @version 1.0 + * @link https://www.muhammetsafak.com.tr + */ + +declare(strict_types=1); +namespace InitORM\DBAL\DataMapper\Interfaces; + +use InitORM\DBAL\DataMapper\Exceptions\DataMapperException; +use PDOStatement; + +/** + * @mixin PDOStatement + */ +interface DataMapperInterface +{ + + public function __construct(PDOStatement $statement); + + /** + * @return PDOStatement + * @throws DataMapperException + */ + public function getStatement(): PDOStatement; + + /** + * @param array|null $params + * @return bool + * @throws DataMapperException + */ + public function execute(?array $params = null): bool; + + + /** + * @return string + * @throws DataMapperException + */ + public function getQuery(): string; + + /** + * @param string $key + * @param mixed $value + * @return bool + * @throws DataMapperException + */ + public function bindValue(string $key, $value): bool; + + /** + * @param array $fields + * @return bool + * @throws DataMapperException + */ + public function bindValues(array $fields): bool; + + /** + * @param mixed $value + * @return int + * @throws DataMapperException + */ + public function bind($value): int; + + /** + * @return int + * @throws DataMapperException + * @see PDOStatement::rowCount() + */ + public function numRows(): int; + + /** + * @param string|null $class + * @return self + * @throws DataMapperException + */ + public function asClass(?string $class = null): self; + + /** + * @return self + * @throws DataMapperException + */ + public function asObject(): self; + + /** + * @return self + * @throws DataMapperException + */ + public function asAssoc(): self; + + /** + * @return self + * @throws DataMapperException + */ + public function asLazy(): self; + + /** + * @return self + * @throws DataMapperException + */ + public function asArray(): self; + + /** + * @return self + * @throws DataMapperException + * @see self::asArray() + */ + public function asBoth(): self; + + /** + * @return array|object|null + * @throws DataMapperException + */ + public function row(); + + /** + * @return array|object[]|null + * @throws DataMapperException + */ + public function rows(): ?array; + +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..266379d --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 InitORM + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..a27a5b1 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# InitORM DBAL + +``` +composer require initorm/dbal +``` \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..c5d6cd5 --- /dev/null +++ b/composer.json @@ -0,0 +1,25 @@ +{ + "name": "initorm/dbal", + "description": "InitORM Database Abstract Layer", + "type": "library", + "license": "MIT", + "autoload": { + "psr-4": { + "InitORM\\DBAL\\Connection\\": "Connection/", + "InitORM\\DBAL\\DataMapper\\": "DataMapper/" + } + }, + "authors": [ + { + "name": "Muhammet ŞAFAK", + "email": "info@muhammetsafak.com.tr", + "role": "Developer", + "homepage": "https://www.muhammetsafak.com.tr" + } + ], + "minimum-stability": "stable", + "require": { + "php": ">=7.4", + "ext-pdo": "*" + } +}