Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2.0.8 #15

Merged
merged 2 commits into from
Mar 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
515 changes: 134 additions & 381 deletions src/Database.php

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions src/Exceptions/QueryBuilderException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php
/**
* Exceptions/QueryBuilderException
*
* This file is part of InitPHP Database.
*
* @author Muhammet ŞAFAK <info@muhammetsafak.com.tr>
* @copyright Copyright © 2022 Muhammet ŞAFAK
* @license ./LICENSE MIT
* @version 2.0.8
* @link https://www.muhammetsafak.com.tr
*/

namespace InitPHP\Database\Exceptions;

class QueryBuilderException extends \Exception
{
}
18 changes: 18 additions & 0 deletions src/Exceptions/QueryGeneratorException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php
/**
* Exceptions/QueryGeneratorException
*
* This file is part of InitPHP Database.
*
* @author Muhammet ŞAFAK <info@muhammetsafak.com.tr>
* @copyright Copyright © 2022 Muhammet ŞAFAK
* @license ./LICENSE MIT
* @version 2.0.8
* @link https://www.muhammetsafak.com.tr
*/

namespace InitPHP\Database\Exceptions;

class QueryGeneratorException extends QueryBuilderException
{
}
18 changes: 18 additions & 0 deletions src/Exceptions/ValueException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php
/**
* Exceptions/ValueException
*
* This file is part of InitPHP Database.
*
* @author Muhammet ŞAFAK <info@muhammetsafak.com.tr>
* @copyright Copyright © 2022 Muhammet ŞAFAK
* @license ./LICENSE MIT
* @version 2.0.8
* @link https://www.muhammetsafak.com.tr
*/

namespace InitPHP\Database\Exceptions;

class ValueException extends QueryBuilderException
{
}
35 changes: 32 additions & 3 deletions src/Helpers/Helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,21 @@
* @author Muhammet ŞAFAK <info@muhammetsafak.com.tr>
* @copyright Copyright © 2022 Muhammet ŞAFAK
* @license ./LICENSE MIT
* @version 2.0.7
* @version 2.0.8
* @link https://www.muhammetsafak.com.tr
*/

namespace InitPHP\Database\Helpers;

use InitPHP\Database\Exceptions\ModelRelationsException;
use InitPHP\Database\Model;
use InitPHP\Database\Raw;

final class Helper
{

private static array $modelInstance = [];

public static function str_starts_with(string $haystack, string $needle): bool
{
if(\function_exists('str_starts_with')){
Expand Down Expand Up @@ -50,11 +56,12 @@ public static function str_ends_with(string $haystack, string $needle): bool

public static function isSQLParameterOrFunction($value): bool
{
return (\is_string($value)) && (
return ((\is_string($value)) && (
$value === '?'
|| (bool)\preg_match('/^:[\w]+$/', $value)
|| (bool)\preg_match('/^[a-zA-Z_\.]+$/', $value)
|| (bool)\preg_match('/^[a-zA-Z_]+\(\)$/', $value)
);
)) || ($value instanceof Raw) || \is_int($value);
}

public static function isSQLParameter($value): bool
Expand Down Expand Up @@ -91,4 +98,26 @@ public static function snakeCaseToPascalCase($snake_case): string
return $camelCase;
}

public static function getModelInstance($model): Model
{
if ($model instanceof Model) {
$class = \get_class($model);
return self::$modelInstance[$class] = $model;
} elseif (\is_string($model) && \class_exists($model)) {
if (isset(self::$modelInstance[$model])) {
return self::$modelInstance[$model];
}
} else {
throw new \InvalidArgumentException();
}

$reflection = new \ReflectionClass($model);
if ($reflection->isSubclassOf(Model::class) === FALSE) {
throw new ModelRelationsException('The target class must be a subclass of \\InitPHP\\Database\\Model.');
}
$class = $reflection->getName();

return self::$modelInstance[$class] = $reflection->newInstance();
}

}
12 changes: 10 additions & 2 deletions src/Helpers/Parameters.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
* @author Muhammet ŞAFAK <info@muhammetsafak.com.tr>
* @copyright Copyright © 2022 Muhammet ŞAFAK
* @license ./LICENSE MIT
* @version 2.0.7
* @version 2.0.8
* @link https://www.muhammetsafak.com.tr
*/

namespace InitPHP\Database\Helpers;

use InitPHP\Database\Raw;

final class Parameters
{

Expand All @@ -33,8 +35,14 @@ public static function set(string $key, $value): void
self::$parameters[$key] = $value;
}

public static function add(string $key, $value): string
public static function add($key, $value): string
{
if ($value === null) {
return 'NULL';
}
if ($key instanceof Raw) {
$key = \md5((string)$key);
}
$originKey = \ltrim(\str_replace('.', '', $key), ':');
$i = 0;
do{
Expand Down
4 changes: 4 additions & 0 deletions src/Helpers/Validation.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

use InitPHP\Database\Database;
use InitPHP\Database\Exceptions\ValidationException;
use InitPHP\Database\Raw;

final class Validation
{
Expand Down Expand Up @@ -109,6 +110,9 @@ public function validation(string $column, $schemaID = null): bool
}

$data = $this->data[$column] ?? null;
if ($data instanceof Raw) {
return true;
}

if(Helper::isSQLParameter($data)){
$data = Parameters::getParam($data);
Expand Down
4 changes: 2 additions & 2 deletions src/Init.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@
* @author Muhammet ŞAFAK <info@muhammetsafak.com.tr>
* @copyright Copyright © 2022 Muhammet ŞAFAK
* @license ./LICENSE MIT
* @version 2.0.7
* @version 2.0.8
* @link https://www.muhammetsafak.com.tr
*/


declare(strict_types=1);
require_once __DIR__ . DIRECTORY_SEPARATOR . 'Helpers/Helper.php';
require_once __DIR__ . DIRECTORY_SEPARATOR . 'Helpers/Parameters.php';
require_once __DIR__ . DIRECTORY_SEPARATOR . 'Helpers/Validation.php';
Expand All @@ -26,6 +25,7 @@
require_once __DIR__ . DIRECTORY_SEPARATOR . 'Exceptions/UpdatableException.php';
require_once __DIR__ . DIRECTORY_SEPARATOR . 'Exceptions/ValidationException.php';
require_once __DIR__ . DIRECTORY_SEPARATOR . 'Exceptions/WritableException.php';
require_once __DIR__ . DIRECTORY_SEPARATOR . 'Exceptions/ValueException.php';
require_once __DIR__ . DIRECTORY_SEPARATOR . 'QueryBuilder.php';
require_once __DIR__ . DIRECTORY_SEPARATOR . 'Facade/DB.php';
require_once __DIR__ . DIRECTORY_SEPARATOR . 'Database.php';
Expand Down
81 changes: 48 additions & 33 deletions src/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @author Muhammet ŞAFAK <info@muhammetsafak.com.tr>
* @copyright Copyright © 2022 Muhammet ŞAFAK
* @license ./LICENSE MIT
* @version 2.0.7
* @version 2.0.8
* @link https://www.muhammetsafak.com.tr
*/

Expand All @@ -20,6 +20,7 @@
ReadableException,
UpdatableException,
WritableException};
use InitPHP\Database\Helpers\Helper;
use InitPHP\Database\Helpers\Parameters;

abstract class Model extends Database
Expand Down Expand Up @@ -457,58 +458,41 @@ final public function purgeDeleted(): bool
}

/**
* İki model arasında bir JOIN ilişkisi kurar.
*
* @param string|Model $model
* @param string|null $fromColumn
* @param string|null $targetColumn
* @param string|null $foreignKey
* @param string|null $localKey
* @param string $joinType
* @return $this
* @throws \ReflectionException
*/
final public function relation($model, ?string $fromColumn = null, ?string $targetColumn = null, string $joinType = 'INNER'): self
final public function relation($model, ?string $foreignKey = null, ?string $localKey = null, string $joinType = 'INNER'): self
{
$from = [
'tableSchema' => $this->getSchema(),
'tableSchemaID' => $this->getSchemaID(),
];
$ref = new \ReflectionClass($model);
if($ref->isSubclassOf(Model::class) === FALSE){
throw new ModelRelationsException('The target class must be a subclass of \\InitPHP\\Database\\Model.');
}
if(\defined('PHP_VERSION_ID') && \PHP_VERSION_ID >= 80000){
$target = $ref->getProperty('table');
$targetPrimaryKey = $ref->getProperty('primaryKey');
if(($targetSchema = $target->getDefaultValue()) === null){
$targetSchema = \strtolower($ref->getShortName());
}
$targetSchemaID = $targetPrimaryKey->getDefaultValue();
$target = [
'tableSchema' => $targetSchema,
'tableSchemaID' => $targetSchemaID,
];
}else{
if(!\is_object($model)){
$model = $ref->newInstance();
}
$target = [
'tableSchema' => $model->getSchema(),
'tableSchemaID' => $model->getSchemaID(),
];
}
if($fromColumn === null || $fromColumn === '{primaryKey}'){
$target = $this->getModelTableNameAndPrimaryKeyColumn($model);

if($localKey === null || $localKey === '{primaryKey}'){
if(empty($from['tableSchemaID'])){
throw new ModelRelationsException('To use relationships, the model must have a primary key column.');
}
}else{
$from['tableSchemaID'] = $fromColumn;
$from['tableSchemaID'] = $localKey;
}
if($targetColumn === null || $targetColumn === '{primaryKey}'){
if($foreignKey === null) {
$target['tableSchemaID'] = (Helper::str_ends_with($from['tableSchema'], 's') ? \substr($from['tableSchema'], -1) : $from['tableSchema'])
. '_' . $from['tableSchemaID'];
} elseif ($foreignKey === '{primaryKey}') {
if(empty($target['tableSchemaID'])){
throw new ModelRelationsException('To use relationships, the model must have a primary key column.');
}
}else{
$target['tableSchemaID'] = $targetColumn;
$target['tableSchemaID'] = $foreignKey;
}
$this->join($target['tableSchema'], ($from['tableSchema'] . '.' . $from['tableSchemaID'] . ' = ' . $target['tableSchema'] . '.' . $target['tableSchemaID']), $joinType);

return $this;
}

Expand Down Expand Up @@ -603,4 +587,35 @@ private function callbacksFunctionHandler(array $data, string $method)
return $data;
}

private function getModelTableNameAndPrimaryKeyColumn($model): array
{
$reflection = new \ReflectionClass($model);
if ($reflection->isSubclassOf(Model::class) === FALSE) {
throw new ModelRelationsException('The target class must be a subclass of \\InitPHP\\Database\\Model.');
}
if (\defined('PHP_VERSION_ID') && \PHP_VERSION_ID >= 80000) {
$tableReflection = $reflection->getProperty('table');
$primaryKeyReflection = $reflection->getProperty('primaryKey');
if (null === $tableName = $tableReflection->getDefaultValue()) {
$tableName = \strtolower($reflection->getShortName());
}
$primaryKey = $primaryKeyReflection->getDefaultValue();

return [
'tableSchema' => $tableName,
'tableSchemaID' => $primaryKey,
];
}

/** @var $model Model */
if (!\is_object($model)) {
$model = $reflection->newInstance();
}

return [
'tableSchema' => $model->getSchema(),
'tableSchemaID' => $model->getSchemaID(),
];
}

}
Loading