├── stubs ├── Repositories │ ├── Redis │ │ ├── create │ │ │ ├── base.temporary_cache_strategy.stub │ │ │ ├── base.query_cache_strategy.stub │ │ │ ├── base.single_key_cache_strategy.stub │ │ │ └── base.clearable_temporary_cache_strategy.stub │ │ ├── update │ │ │ ├── base.temporary_cache_strategy.stub │ │ │ ├── base.query_cache_strategy.stub │ │ │ ├── base.single_key_cache_strategy.stub │ │ │ └── base.clearable_temporary_cache_strategy.stub │ │ ├── base.clear.stub │ │ ├── getAllBy │ │ │ ├── base.single_key_cache_strategy.stub │ │ │ ├── base.query_cache_strategy.stub │ │ │ ├── base.temporary_cache_strategy.stub │ │ │ └── base.clearable_temporary_cache_strategy.stub │ │ └── getOneBy │ │ │ ├── base.single_key_cache_strategy.stub │ │ │ ├── base.temporary_cache_strategy.stub │ │ │ ├── base.query_cache_strategy.stub │ │ │ └── base.clearable_temporary_cache_strategy.stub │ ├── Mysql │ │ ├── mysql.timeField.stub │ │ ├── mysql.getter.stub │ │ ├── mysql.setter.stub │ │ ├── mysql.construct.stub │ │ ├── mysql.undelete.stub │ │ ├── mysql.delete.stub │ │ ├── mysql.update.stub │ │ ├── mysql.getAllBy.stub │ │ ├── mysql.create.stub │ │ ├── mysql.getOneBy.stub │ │ ├── mysql.deleteAndUndelete.stub │ │ └── mysql.class.stub │ ├── Base │ │ ├── base.construct.stub │ │ ├── base.attribute.sql.stub │ │ ├── base.setter.sql.stub │ │ ├── base.construct_redis.stub │ │ └── base.function.stub │ └── Interface │ │ ├── interface.update.stub │ │ ├── interface.create.stub │ │ ├── interface.getAllBy.stub │ │ ├── interface.getOneBy.stub │ │ ├── interface.deleteAndUndelete.stub │ │ └── interface.class.stub ├── Enums │ └── enum.attribute.stub ├── Entities │ └── entity.attribute.stub ├── Resources │ ├── resource.getter.default.stub │ ├── resource.function.getter.stub │ ├── resource.getter.foreign.stub │ ├── resource.function.foreign.stub │ └── resource.class.stub ├── Factories │ ├── factory.set.stub │ └── factory.class.stub ├── base.enum.stub └── base.class.stub ├── .gitignore ├── src ├── Models │ ├── Resources │ │ ├── IResource.php │ │ └── Resource.php │ ├── Factories │ │ ├── IFactory.php │ │ └── Factory.php │ ├── Repositories │ │ ├── CacheStrategies │ │ │ ├── SingleKeyCacheStrategy.php │ │ │ ├── TemporaryCacheStrategy.php │ │ │ ├── QueryCacheStrategy.php │ │ │ └── ClearableTemporaryCacheStrategy.php │ │ ├── RedisRepository.php │ │ └── MySqlRepository.php │ ├── Enums │ │ ├── Enum.php │ │ ├── GriewFilterOperator.php │ │ └── DataTypeEnum.php │ └── Entity │ │ └── Entity.php ├── Creators │ ├── IClassCreator.php │ ├── CreatorRedisRepository.php │ ├── CreatorEnum.php │ ├── CreatorFactory.php │ ├── CreatorResource.php │ ├── CreatorEntity.php │ ├── BaseCreator.php │ ├── CreatorMySqlRepository.php │ └── CreatorRepository.php ├── Commands │ ├── MakeMySqlRepository.php │ ├── MakeEntity.php │ ├── MakeRedisRepository.php │ ├── MakeFactory.php │ ├── MakeResource.php │ ├── MakeAll.php │ ├── MakeEnum.php │ ├── MakeRepository.php │ ├── BaseCommand.php │ └── MakeInterfaceRepository.php ├── DatabaseRepositoryServiceProvider.php └── CustomMySqlQueries.php ├── composer.json ├── config └── repository.php └── Readme.md /stubs/Repositories/Redis/create/base.temporary_cache_strategy.stub: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /stubs/Repositories/Redis/update/base.temporary_cache_strategy.stub: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | /.idea 3 | /.vagrant 4 | .vscode 5 | composer.lock -------------------------------------------------------------------------------- /stubs/Repositories/Redis/base.clear.stub: -------------------------------------------------------------------------------- 1 | $this->redisRepository->clear(); 2 | -------------------------------------------------------------------------------- /stubs/Enums/enum.attribute.stub: -------------------------------------------------------------------------------- 1 | case {{ AttributeName }} = '{{ AttributeString }}'; 2 | -------------------------------------------------------------------------------- /stubs/Entities/entity.attribute.stub: -------------------------------------------------------------------------------- 1 | public {{ AttributeType }} ${{ AttributeName }}; 2 | -------------------------------------------------------------------------------- /stubs/Repositories/Mysql/mysql.timeField.stub: -------------------------------------------------------------------------------- 1 | '{{ ColumnName }}' => date('Y-m-d H:i:s'), 2 | -------------------------------------------------------------------------------- /stubs/Repositories/Redis/create/base.query_cache_strategy.stub: -------------------------------------------------------------------------------- 1 | $this->redisRepository->clear(); 2 | -------------------------------------------------------------------------------- /stubs/Repositories/Redis/update/base.query_cache_strategy.stub: -------------------------------------------------------------------------------- 1 | $this->redisRepository->clear(); 2 | -------------------------------------------------------------------------------- /stubs/Repositories/Redis/create/base.single_key_cache_strategy.stub: -------------------------------------------------------------------------------- 1 | $this->redisRepository->clear(); 2 | -------------------------------------------------------------------------------- /stubs/Repositories/Redis/update/base.single_key_cache_strategy.stub: -------------------------------------------------------------------------------- 1 | $this->redisRepository->clear(); 2 | -------------------------------------------------------------------------------- /stubs/Repositories/Mysql/mysql.getter.stub: -------------------------------------------------------------------------------- 1 | '{{ ColumnName }}' => ${{ EntityVariableName }}->{{ AttributeName }}, 2 | -------------------------------------------------------------------------------- /stubs/Repositories/Mysql/mysql.setter.stub: -------------------------------------------------------------------------------- 1 | ${{ EntityVariableName }}->{{ AttributeName }} = date('Y-m-d H:i:s'); 2 | -------------------------------------------------------------------------------- /stubs/Resources/resource.getter.default.stub: -------------------------------------------------------------------------------- 1 | '{{ ColumnName }}' => ${{ EntityVariableName }}->{{ AttributeName }}, 2 | -------------------------------------------------------------------------------- /stubs/Factories/factory.set.stub: -------------------------------------------------------------------------------- 1 | ${{ EntityVariableName }}->{{ AttributeName }} = $entity->{{ DatabaseAttributeName }}; 2 | -------------------------------------------------------------------------------- /stubs/Repositories/Base/base.construct.stub: -------------------------------------------------------------------------------- 1 | public function __construct() 2 | { 3 | {{ Setters }} 4 | } 5 | -------------------------------------------------------------------------------- /stubs/base.enum.stub: -------------------------------------------------------------------------------- 1 | {{ SqlRepositoryVariable }} = new {{ SqlRepositoryName }}(); 2 | $this->{{ RedisRepositoryVariable }} = new {{ RedisRepositoryName }}(); 3 | -------------------------------------------------------------------------------- /stubs/Resources/resource.function.getter.stub: -------------------------------------------------------------------------------- 1 | public function toArray(${{ EntityVariableName }}): array 2 | { 3 | return [ 4 | {{ Getters }} 5 | ]; 6 | } 7 | -------------------------------------------------------------------------------- /stubs/base.class.stub: -------------------------------------------------------------------------------- 1 | cacheTag = {{ CacheTag }}; 6 | parent::__construct(); 7 | } 8 | -------------------------------------------------------------------------------- /stubs/Repositories/Base/base.function.stub: -------------------------------------------------------------------------------- 1 | public function {{ FunctionName }}({{ AttributeType }} ${{ AttributeName }}): {{ FunctionReturnType }} 2 | { 3 | {{redisFunction}} 4 | {{returnResult}} 5 | } 6 | -------------------------------------------------------------------------------- /stubs/Resources/resource.getter.foreign.stub: -------------------------------------------------------------------------------- 1 | '{{ AttributeName }}' => ${{ EntityVariableName }}->get{{ GetterName }}() ? (new {{ AttributeType }}Resource())->toArray(${{ EntityVariableName }}->get{{ GetterName }}()) : null, 2 | -------------------------------------------------------------------------------- /stubs/Repositories/Interface/interface.deleteAndUndelete.stub: -------------------------------------------------------------------------------- 1 | 2 | public function remove({{ EntityName }} ${{ EntityVariableName }}): int; 3 | 4 | public function restore({{ EntityName }} ${{ EntityVariableName }}): int; 5 | -------------------------------------------------------------------------------- /stubs/Repositories/Redis/update/base.clearable_temporary_cache_strategy.stub: -------------------------------------------------------------------------------- 1 | $cacheKey = $this->redisRepository->makeKey([ 2 | 'function_name' => 'update', 3 | 'id' => $id, 4 | ]); 5 | 6 | $this->redisRepository->clear($cacheKey); 7 | -------------------------------------------------------------------------------- /stubs/Resources/resource.function.foreign.stub: -------------------------------------------------------------------------------- 1 | public function toArrayWithForeignKeys(${{ EntityVariableName }}): array 2 | { 3 | return $this->toArray(${{ EntityVariableName }}) + [ 4 | {{ ForeignGetterFunctions }} 5 | ]; 6 | } 7 | -------------------------------------------------------------------------------- /stubs/Factories/factory.class.stub: -------------------------------------------------------------------------------- 1 | public function makeEntityFromStdClass(stdClass $entity): {{ EntityName }} 2 | { 3 | ${{ EntityVariableName }} = new {{ EntityName }}(); 4 | 5 | {{ Sets }} 6 | return ${{ EntityVariableName }}; 7 | } 8 | -------------------------------------------------------------------------------- /stubs/Repositories/Redis/create/base.clearable_temporary_cache_strategy.stub: -------------------------------------------------------------------------------- 1 | $cacheKey = $this->redisRepository->makeKey([ 2 | 'function_name' => 'create', 3 | 'id' => $id, 4 | ]); 5 | 6 | $this->redisRepository->clear($cacheKey); 7 | -------------------------------------------------------------------------------- /stubs/Repositories/Interface/interface.class.stub: -------------------------------------------------------------------------------- 1 | redisRepository->get(); 2 | 3 | if ($entity === null) { 4 | $entities = $this->repository->{{ FunctionName }}(${{ ColumnName }}); 5 | $this->redisRepository->put($entities); 6 | } 7 | -------------------------------------------------------------------------------- /stubs/Repositories/Redis/getOneBy/base.single_key_cache_strategy.stub: -------------------------------------------------------------------------------- 1 | $entity = $this->redisRepository->get(); 2 | 3 | if ($entity === null) { 4 | $entity = $this->repository->{{ FunctionName }}(${{ ColumnName }}); 5 | $this->redisRepository->put($entity); 6 | } 7 | -------------------------------------------------------------------------------- /stubs/Repositories/Mysql/mysql.construct.stub: -------------------------------------------------------------------------------- 1 | public function __construct() 2 | { 3 | $this->table = '{{ TableName }}'; 4 | $this->primaryKey = 'id'; 5 | $this->softDelete = {{ HasSoftDelete }}; 6 | $this->factory = new {{ FactoryName }}(); 7 | 8 | parent::__construct(); 9 | } 10 | -------------------------------------------------------------------------------- /stubs/Repositories/Mysql/mysql.undelete.stub: -------------------------------------------------------------------------------- 1 | public function restore({{ EntityName }} ${{ EntityVariableName }}): int 2 | { 3 | return $this->newQuery() 4 | ->where($this->primaryKey, ${{ EntityVariableName }}->getPrimaryKey()) 5 | ->update([ 6 | 'deleted_at' => null, 7 | ]); 8 | } 9 | -------------------------------------------------------------------------------- /stubs/Repositories/Mysql/mysql.delete.stub: -------------------------------------------------------------------------------- 1 | public function remove({{ EntityName }} ${{ EntityVariableName }}): int 2 | { 3 | return $this->newQuery() 4 | ->where($this->primaryKey, ${{ EntityVariableName }}->getPrimaryKey()) 5 | ->update([ 6 | 'deleted_at' => date('Y-m-d H:i:s'), 7 | ]); 8 | } 9 | -------------------------------------------------------------------------------- /src/Models/Resources/IResource.php: -------------------------------------------------------------------------------- 1 | newQuery() 6 | ->where($this->primaryKey, ${{ EntityVariableName }}->getPrimaryKey()) 7 | ->update([ 8 | {{ GetterFunctions }} 9 | ]); 10 | } 11 | -------------------------------------------------------------------------------- /stubs/Repositories/Mysql/mysql.getAllBy.stub: -------------------------------------------------------------------------------- 1 | public function getAllBy{{ FunctionNamePlural }}(array ${{ AttributeNamePlural }}): Collection 2 | { 3 | ${{ EntityVariableName }} = $this->newQuery() 4 | ->whereIn('{{ ColumnName }}', ${{ AttributeNamePlural }}) 5 | ->get(); 6 | 7 | return $this->factory->makeCollectionOfEntities(${{ EntityVariableName }}); 8 | } 9 | -------------------------------------------------------------------------------- /stubs/Repositories/Mysql/mysql.create.stub: -------------------------------------------------------------------------------- 1 | public function create({{ EntityName }} ${{ EntityVariableName }}): {{ EntityName }} 2 | { 3 | {{ SetterFunctions }} 4 | 5 | $id = $this->newQuery() 6 | ->insertGetId([ 7 | {{ GetterFunctions }} 8 | ]); 9 | 10 | ${{ EntityVariableName }}->id = $id; 11 | 12 | return ${{ EntityVariableName }}; 13 | } 14 | -------------------------------------------------------------------------------- /src/Models/Factories/IFactory.php: -------------------------------------------------------------------------------- 1 | newQuery() 4 | ->where('{{ ColumnName }}', ${{ AttributeName }}) 5 | ->first(); 6 | 7 | return ${{ EntityVariableName }} ? $this->factory->makeEntityFromStdClass(${{ EntityVariableName }}) : null; 8 | } 9 | -------------------------------------------------------------------------------- /stubs/Repositories/Redis/getOneBy/base.temporary_cache_strategy.stub: -------------------------------------------------------------------------------- 1 | $cacheKey = $this->redisRepository->makeKey([ 2 | 'function_name' => '{{ FunctionName }}', 3 | '{{ ColumnName }}' => ${{ ColumnName }}, 4 | ]); 5 | 6 | $data = $this->redisRepository->get($cacheKey); 7 | 8 | if (is_null($data)) { 9 | $data = $this->repository->{{ FunctionName }}(${{ ColumnName }}); 10 | $this->redisRepository->put($cacheKey, $data, Time::HALF_HOUR_BY_SECOND); 11 | } 12 | -------------------------------------------------------------------------------- /stubs/Repositories/Redis/getOneBy/base.query_cache_strategy.stub: -------------------------------------------------------------------------------- 1 | $cacheKey = $this->redisRepository->makeKey([ 2 | 'function_name' => '{{ FunctionName }}', 3 | '{{ ColumnName }}' => ${{ ColumnName }}, 4 | ]); 5 | 6 | $entity = $this->redisRepository->get($cacheKey); 7 | 8 | if ($entity === null) { 9 | $entity = $this->repository->{{ FunctionName }}(${{ ColumnName }}); 10 | $this->redisRepository->put($cacheKey, $entity); 11 | } 12 | -------------------------------------------------------------------------------- /stubs/Repositories/Redis/getAllBy/base.query_cache_strategy.stub: -------------------------------------------------------------------------------- 1 | $cacheKey = $this->redisRepository->makeKey([ 2 | 'function_name' => '{{ FunctionName }}', 3 | '{{ ColumnNameSingle }}' => ${{ ColumnName }}, 4 | ]); 5 | 6 | $entities = $this->redisRepository->get($cacheKey); 7 | 8 | if ($entities === null) { 9 | $entities = $this->repository->{{ FunctionName }}(${{ ColumnName }}); 10 | $this->redisRepository->put($cacheKey, $entities); 11 | } 12 | -------------------------------------------------------------------------------- /stubs/Repositories/Redis/getAllBy/base.temporary_cache_strategy.stub: -------------------------------------------------------------------------------- 1 | $cacheKey = $this->redisRepository->makeKey([ 2 | 'function_name' => '{{ FunctionName }}', 3 | '{{ ColumnNameSingle }}' => ${{ ColumnName }}, 4 | ]); 5 | 6 | $data = $this->redisRepository->get($cacheKey); 7 | 8 | if (is_null($data)) { 9 | $data = $this->repository->{{ FunctionName }}(${{ ColumnName }}); 10 | $this->redisRepository->put($cacheKey, $data, Time::HALF_HOUR_BY_SECOND); 11 | } 12 | -------------------------------------------------------------------------------- /stubs/Repositories/Redis/getOneBy/base.clearable_temporary_cache_strategy.stub: -------------------------------------------------------------------------------- 1 | $cacheKey = $this->redisRepository->makeKey([ 2 | 'function_name' => '{{ FunctionName }}', 3 | '{{ ColumnName }}' => ${{ ColumnName }}, 4 | ]); 5 | 6 | $data = $this->redisRepository->get($cacheKey); 7 | 8 | if (is_null($data)) { 9 | $data = $this->repository->{{ FunctionName }}(${{ ColumnName }}); 10 | $this->redisRepository->put($cacheKey, $data, Time::HALF_HOUR_BY_SECOND); 11 | } 12 | -------------------------------------------------------------------------------- /stubs/Repositories/Redis/getAllBy/base.clearable_temporary_cache_strategy.stub: -------------------------------------------------------------------------------- 1 | $cacheKey = $this->redisRepository->makeKey([ 2 | 'function_name' => '{{ FunctionName }}', 3 | '{{ ColumnNameSingle }}' => ${{ ColumnName }}, 4 | ]); 5 | 6 | $data = $this->redisRepository->get($cacheKey); 7 | 8 | if (is_null($data)) { 9 | $data = $this->repository->{{ FunctionName }}(${{ ColumnName }}); 10 | $this->redisRepository->put($cacheKey, $data, Time::HALF_HOUR_BY_SECOND); 11 | } 12 | -------------------------------------------------------------------------------- /src/Creators/IClassCreator.php: -------------------------------------------------------------------------------- 1 | toArray($_entity); 18 | } 19 | 20 | return $entityArray; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /stubs/Repositories/Mysql/mysql.deleteAndUndelete.stub: -------------------------------------------------------------------------------- 1 | public function remove({{ EntityName }} ${{ EntityVariableName }}): int 2 | { 3 | return $this->newQuery() 4 | ->where($this->primaryKey, ${{ EntityVariableName }}->getPrimaryKey()) 5 | ->update([ 6 | 'deleted_at' => date('Y-m-d H:i:s'), 7 | ]); 8 | } 9 | 10 | public function restore({{ EntityName }} ${{ EntityVariableName }}): int 11 | { 12 | return $this->newQuery() 13 | ->where($this->primaryKey, ${{ EntityVariableName }}->getPrimaryKey()) 14 | ->update([ 15 | 'deleted_at' => null, 16 | ]); 17 | } 18 | -------------------------------------------------------------------------------- /stubs/Resources/resource.class.stub: -------------------------------------------------------------------------------- 1 | toArray(${{ EntityVariableName }}) + [ 21 | {{ ForeignGetterFunctions }} 22 | ]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /stubs/Repositories/Mysql/mysql.class.stub: -------------------------------------------------------------------------------- 1 | table = '{{ TableName }}'; 15 | $this->primaryKey = 'id'; 16 | $this->softDelete = {{ HasSoftDelete }}; 17 | $this->factory = new {{ FactoryName }}(); 18 | 19 | parent::__construct(); 20 | } 21 | 22 | {{ Functions }} 23 | } 24 | -------------------------------------------------------------------------------- /src/Models/Factories/Factory.php: -------------------------------------------------------------------------------- 1 | push($this->makeEntityFromStdClass($_entity)); 22 | } 23 | 24 | return $entityCollection; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Models/Repositories/CacheStrategies/SingleKeyCacheStrategy.php: -------------------------------------------------------------------------------- 1 | getCache()->forever($this->cacheKey, $entities); 18 | } 19 | 20 | /** 21 | * @return mixed 22 | */ 23 | public function get() 24 | { 25 | return $this->getCache()->get($this->cacheKey); 26 | } 27 | 28 | /** 29 | * @return mixed 30 | */ 31 | public function clear() 32 | { 33 | return $this->getCache()->forget($this->cacheKey); 34 | } 35 | } -------------------------------------------------------------------------------- /src/Models/Enums/Enum.php: -------------------------------------------------------------------------------- 1 | getConstants(); 12 | } 13 | 14 | public function getValue(int|string $key): null|string 15 | { 16 | $list = $this->getList(); 17 | $keys = array_keys($list); 18 | $key = is_numeric($key) ? (int)$key : $key; 19 | 20 | if (is_int($key) && $key < count($keys)) { 21 | $value = $list[$keys[$key]]; 22 | } else { 23 | $value = $list[strtoupper($key)]; 24 | } 25 | 26 | return $value; 27 | } 28 | 29 | public function indexOf(int|string $value): false|int|string 30 | { 31 | $list = $this->getList(); 32 | $values = array_values($list); 33 | 34 | return array_search($value, $values, true); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Models/Repositories/CacheStrategies/TemporaryCacheStrategy.php: -------------------------------------------------------------------------------- 1 | getCache()->tags($this->cacheTag)->get($cacheKey); 28 | } 29 | 30 | /** 31 | * @param string $cacheKey 32 | * @param mixed $data 33 | * @param DateInterval|DateTimeInterface|int $ttl 34 | * @return bool 35 | */ 36 | public function put(string $cacheKey, mixed $data, DateInterval|DateTimeInterface|int $ttl): bool 37 | { 38 | return $this->getCache()->tags($this->cacheTag)->put($cacheKey, $data, $ttl); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Models/Repositories/CacheStrategies/QueryCacheStrategy.php: -------------------------------------------------------------------------------- 1 | getCache()->tags($this->cacheTag)->get($cacheKey); 26 | } 27 | 28 | /** 29 | * @param string $cacheKey 30 | * @param mixed $data 31 | * @return mixed 32 | */ 33 | public function put(string $cacheKey, $data) 34 | { 35 | return $this->getCache()->tags($this->cacheTag)->forever($cacheKey, $data); 36 | } 37 | 38 | /** 39 | * @return mixed 40 | */ 41 | public function clear() 42 | { 43 | return $this->getCache()->tags($this->cacheTag)->flush(); 44 | } 45 | } -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eghamat24/database-repository", 3 | "description": "Repository Pattern", 4 | "type": "library", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Mohammad-Reza Sharifi", 9 | "email": "mrsharifi76@gmail.com" 10 | } 11 | ], 12 | "require": { 13 | "php": "^8.1", 14 | "ext-pdo": "*", 15 | "ext-json": "*", 16 | "illuminate/console": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", 17 | "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", 18 | "illuminate/cache": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", 19 | "illuminate/database": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0" 20 | }, 21 | "require-dev": { 22 | "laravel/framework": "^8.0|^9.0|^10.0|^11.0|^12.0" 23 | }, 24 | "autoload": { 25 | "psr-4": { 26 | "Eghamat24\\DatabaseRepository\\": "src/" 27 | } 28 | }, 29 | "extra": { 30 | "laravel": { 31 | "providers": [ 32 | "Eghamat24\\DatabaseRepository\\DatabaseRepositoryServiceProvider" 33 | ] 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Models/Repositories/CacheStrategies/ClearableTemporaryCacheStrategy.php: -------------------------------------------------------------------------------- 1 | getCache()->tags($this->cacheTag)->get($cacheKey); 26 | } 27 | 28 | /** 29 | * @param string $cacheKey 30 | * @param mixed $data 31 | * @param $time 32 | * @return mixed 33 | */ 34 | public function put(string $cacheKey, $data, $seconds) 35 | { 36 | $this->getCache()->tags($this->cacheTag)->put($cacheKey, $data, $seconds); 37 | } 38 | 39 | /** 40 | * @return mixed 41 | */ 42 | public function clear($cacheKey) 43 | { 44 | return $this->getCache()->tags($this->cacheTag)->forget($cacheKey); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /config/repository.php: -------------------------------------------------------------------------------- 1 | env('REPOSITORY_PHP_VERSION', '8.0'), 6 | 7 | 'default_db' => 'MySql',# Options: ( Redis, MySql ) 8 | 9 | 'path' => [ 10 | 'namespace' => [ 11 | 'entities' => 'App\Models\Entities', 12 | 'enums' => 'App\Models\Enums', 13 | 'factories' => 'App\Models\Factories', 14 | 'resources' => 'App\Models\Resources', 15 | 'repositories' => 'App\Models\Repositories', 16 | ], 17 | 18 | 'stub' => [ 19 | 'entities' => 'stubs/Entities/entity.', 20 | 'enums' => 'stubs/Enums/enum.', 21 | 'factories' => 'stubs/Factories/factory.', 22 | 'resources' => 'stubs/Resources/resource.', 23 | 'repositories' => [ 24 | 'base' => 'stubs/Repositories/Base/base.', 25 | 'mysql' => 'stubs/Repositories/Mysql/mysql.', 26 | 'interface' => 'stubs/Repositories/Interface/interface.', 27 | ] 28 | ], 29 | 30 | 'relative' => [ 31 | 'entities' => 'app/Models/Entities/', 32 | 'enums' => 'app/Models/Enums/', 33 | 'factories' => 'app/Models/Factories/', 34 | 'resources' => 'app/Models/Resources/', 35 | 'repositories' => 'app/Models/Repositories/', 36 | ], 37 | 38 | ] 39 | 40 | ]; 41 | -------------------------------------------------------------------------------- /src/Models/Enums/GriewFilterOperator.php: -------------------------------------------------------------------------------- 1 | redisRepositoryNamespace . '\\' . $this->entityName; 21 | } 22 | 23 | public function createUses(): array 24 | { 25 | return [ 26 | 'use Eghamat24\DatabaseRepository\Models\Repositories\RedisRepository;', 27 | 'use Eghamat24\DatabaseRepository\Models\Repositories\CacheStrategies\\' . $this->strategyName . ';' 28 | ]; 29 | } 30 | 31 | public function getClassName(): string 32 | { 33 | return $this->redisRepositoryName; 34 | } 35 | 36 | public function getExtendSection(): string 37 | { 38 | return 'extends RedisRepository'; 39 | } 40 | 41 | public function createAttributes(): array 42 | { 43 | return []; 44 | } 45 | 46 | public function createFunctions(): array 47 | { 48 | $constructStub = file_get_contents($this->repositoryStubsPath . 'construct_redis.stub'); 49 | $functions = []; 50 | $functions['__construct'] = $this->getConstructRedis($constructStub); 51 | return $functions; 52 | } 53 | 54 | public function getConstructRedis(string $constructStub): array|string 55 | { 56 | return str_replace('{{Strategy}}', $this->strategyName, $constructStub); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/Creators/CreatorEnum.php: -------------------------------------------------------------------------------- 1 | enum as $_enum) { 24 | 25 | $attributes[strtoupper($_enum)] = $this->writeAttribute( 26 | $this->attributeStub, 27 | strtoupper($_enum), 28 | $_enum 29 | ); 30 | } 31 | 32 | return $attributes; 33 | } 34 | 35 | public function createFunctions(): array 36 | { 37 | return []; 38 | } 39 | 40 | public function createUses(): array 41 | { 42 | return []; 43 | } 44 | 45 | public function getExtendSection(): string 46 | { 47 | return ''; 48 | } 49 | 50 | public function getNameSpace(): string 51 | { 52 | return $this->enumNamespace; 53 | } 54 | 55 | public function getClassName(): string 56 | { 57 | return $this->enumName . ' : string'; 58 | } 59 | 60 | private function writeAttribute(string $attributeStub, string $attributeName, string $attributeString): string 61 | { 62 | $replaceMapping = [ 63 | '{{ AttributeName }}' => $attributeName, 64 | '{{ AttributeString }}' => $attributeString, 65 | ]; 66 | 67 | return str_replace(array_keys($replaceMapping), array_values($replaceMapping), $attributeStub); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Models/Enums/DataTypeEnum.php: -------------------------------------------------------------------------------- 1 | self::BOOLEAN_TYPE, 49 | 50 | self::BIT, 51 | self::JSON, 52 | self::CHAR, 53 | self::VARCHAR, 54 | self::BINARY, 55 | self::VARBINARY, 56 | self::DATETIME, 57 | self::TIME, 58 | self::DATE, 59 | self::ENUM, 60 | self::LONGBLOB, 61 | self::LONGTEXT, 62 | self::MEDIUMBLOB, 63 | self::MEDIUMTEXT, 64 | self::BLOB, 65 | self::TEXT, 66 | self::TINYTEXT, 67 | self::TINYBLOB, 68 | self::TIMESTAMP, 69 | self::POINT => self::STRING_TYPE, 70 | 71 | self::INT, 72 | self::INTEGER, 73 | self::TINYINT, 74 | self::SMALLINT, 75 | self::MEDIUMINT, 76 | self::BIGINT => self::INTEGER_TYPE, 77 | 78 | self::FLOAT, 79 | self::DOUBLE => self::FLOAT_TYPE, 80 | }; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/Creators/CreatorFactory.php: -------------------------------------------------------------------------------- 1 | factoryNamespace; 27 | } 28 | 29 | public function createAttributes(): array 30 | { 31 | $setStub = file_get_contents($this->factoryStubsPath . 'set.stub'); 32 | $sets = ''; 33 | foreach ($this->columns as $_column) { 34 | $replacementTokens = [ 35 | '{{ AttributeName }}' => Str::camel($_column->COLUMN_NAME), 36 | '{{ DatabaseAttributeName }}' => Str::snake($_column->COLUMN_NAME) 37 | ]; 38 | 39 | $sets .= str_replace(array_keys($replacementTokens), array_values($replacementTokens), $setStub) . "\t\t"; 40 | } 41 | 42 | return ['makeEntityFromStdClass' => 43 | str_replace(['{{ Sets }}', '{{ EntityName }}', '{{ EntityVariableName }}'], 44 | [$sets, $this->entityName, $this->entityVariableName], 45 | $this->baseContent) 46 | ]; 47 | return []; 48 | } 49 | 50 | public function createFunctions(): array 51 | { 52 | return []; 53 | } 54 | 55 | public function createUses(): array 56 | { 57 | return [ 58 | "use $this->entityNamespace\\$this->entityName;", 59 | 'use Eghamat24\DatabaseRepository\Models\Factories\Factory;', 60 | 'use stdClass;' 61 | ]; 62 | 63 | } 64 | 65 | public function getExtendSection(): string 66 | { 67 | return 'extends ' . self::PARENT_NAME; 68 | } 69 | 70 | public function getClassName(): string 71 | { 72 | return $this->factoryName; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Commands/MakeMySqlRepository.php: -------------------------------------------------------------------------------- 1 | setArguments(); 38 | 39 | $filenameWithPath = $this->getFileNameWithPath( 40 | $this->relativeMysqlRepositoryPath, 41 | $this->mysqlRepositoryName 42 | ); 43 | 44 | $this->checkAndPrepare($filenameWithPath); 45 | 46 | $this->finalized( 47 | $filenameWithPath, 48 | $this->mysqlRepositoryName, 49 | $this->generateBaseContent($filenameWithPath) 50 | ); 51 | } 52 | 53 | 54 | private function getFileNameWithPath(string $relativePath, string $sectionName): string 55 | { 56 | return $relativePath . $sectionName . '.php'; 57 | } 58 | 59 | 60 | private function checkAndPrepare(string $filenameWithPath) 61 | { 62 | $this->checkDelete($filenameWithPath, $this->mysqlRepositoryName, self::OBJECT_NAME); 63 | $this->checkDirectory($this->relativeMysqlRepositoryPath); 64 | $this->checkClassExist($this->repositoryNamespace, $this->mysqlRepositoryName, self::OBJECT_NAME); 65 | } 66 | 67 | 68 | private function getColumnsOf(string $tableName): Collection 69 | { 70 | $columns = $this->getAllColumnsInTable($tableName); 71 | $this->checkEmpty($columns, $tableName); 72 | 73 | return $columns; 74 | } 75 | 76 | 77 | private function generateBaseContent(string $filenameWithPath): string 78 | { 79 | $mysqlRepoCreator = $this->makeMySqlRepoCreator(); 80 | 81 | return (new BaseCreator($mysqlRepoCreator))->createClass($filenameWithPath, $this); 82 | } 83 | 84 | /** 85 | * @return CreatorMySqlRepository 86 | */ 87 | private function makeMySqlRepoCreator(): CreatorMySqlRepository 88 | { 89 | return new CreatorMySqlRepository( 90 | $this->getColumnsOf($this->tableName), 91 | $this->tableName, 92 | $this->entityName, 93 | $this->entityVariableName, 94 | $this->factoryName, 95 | $this->entityNamespace, 96 | $this->factoryNamespace, 97 | $this->mysqlRepositoryName, 98 | $this->repositoryNamespace, 99 | $this->interfaceName, 100 | $this->mysqlRepositoryStubsPath, 101 | $this->detectForeignKeys 102 | ); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/Commands/MakeEntity.php: -------------------------------------------------------------------------------- 1 | setArguments(); 41 | $filenameWithPath = $this->relativeEntitiesPath . $this->entityName . '.php'; 42 | 43 | $this->checkAndPrepare($filenameWithPath); 44 | $columns = $this->getColumnsOf($this->tableName); 45 | 46 | foreach ($columns as $_column) { 47 | $_column->COLUMN_NAME = Str::camel($_column->COLUMN_NAME); 48 | } 49 | 50 | $entityCreator = $this->getCreatorEntity($columns); 51 | $baseContent = $this->getBaseContent($entityCreator, $filenameWithPath); 52 | 53 | $this->finalized($filenameWithPath, $this->entityName, $baseContent); 54 | } 55 | 56 | /** 57 | * @param string $tableName 58 | * @return Collection 59 | */ 60 | private function getColumnsOf(string $tableName): Collection 61 | { 62 | $columns = $this->getAllColumnsInTable($tableName); 63 | $this->checkEmpty($columns, $tableName); 64 | 65 | return $columns; 66 | } 67 | 68 | /** 69 | * @param string $filenameWithPath 70 | * @return void 71 | */ 72 | private function checkAndPrepare(string $filenameWithPath): void 73 | { 74 | $this->checkDelete($filenameWithPath, $this->entityName, self::OBJECT_NAME); 75 | $this->checkDirectory($this->relativeEntitiesPath); 76 | $this->checkClassExist($this->entityNamespace, $this->entityName, self::OBJECT_NAME); 77 | } 78 | 79 | /** 80 | * @param Collection $columns 81 | * @return CreatorEntity 82 | */ 83 | private function getCreatorEntity(Collection $columns): CreatorEntity 84 | { 85 | return new CreatorEntity($columns, 86 | $this->detectForeignKeys, 87 | $this->tableName, 88 | $this->entityName, 89 | $this->entityNamespace, 90 | $this->entityStubsPath 91 | ); 92 | } 93 | 94 | /** 95 | * @param CreatorEntity $entityCreator 96 | * @param string $filenameWithPath 97 | * @return string 98 | */ 99 | private function getBaseContent(CreatorEntity $entityCreator, string $filenameWithPath): string 100 | { 101 | $creator = new BaseCreator($entityCreator); 102 | return $creator->createClass($filenameWithPath, $this); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/Models/Entity/Entity.php: -------------------------------------------------------------------------------- 1 | $attributeValue) { 31 | $this->$attributeName = null; 32 | } 33 | return $this; 34 | } 35 | 36 | public function getPrimaryKey(): int 37 | { 38 | return $this->getId(); 39 | } 40 | 41 | /** 42 | * Fill the model 43 | */ 44 | public function fill() 45 | { 46 | 47 | } 48 | 49 | /** 50 | * get an Array of current Attributes value 51 | */ 52 | public function toArray(): array 53 | { 54 | $attributes = get_object_vars($this); 55 | 56 | unset($attributes['originals']); 57 | 58 | return $attributes; 59 | } 60 | 61 | /** 62 | * store an array of attributes original value 63 | */ 64 | public function storeOriginals() 65 | { 66 | $this->originals = $this->toArray(); 67 | } 68 | 69 | /** 70 | * empty an array of attributes original value 71 | */ 72 | public function emptyOriginals() 73 | { 74 | $this->originals = []; 75 | } 76 | 77 | /** 78 | * get an Array of Changed Attributes 79 | */ 80 | public function changedAttributesName(): array 81 | { 82 | $changedAttributes = []; 83 | $attributes = $this->toArray(); 84 | foreach ($attributes as $key => $value) { 85 | if (isset($this->originals[$key]) && $value !== $this->originals[$key] && !((is_array($this->originals[$key]) || is_object($this->originals[$key])))) { 86 | $changedAttributes[] = $key; 87 | } 88 | } 89 | return $changedAttributes; 90 | } 91 | 92 | /** 93 | * get an Array of Changed Attributes with new values 94 | */ 95 | public function getDirty(): array 96 | { 97 | $dirty = []; 98 | $attributes = $this->toArray(); 99 | 100 | foreach ($this->changedAttributesName() as $key) { 101 | $dirty[$key] = $attributes[$key]; 102 | } 103 | 104 | return $dirty; 105 | } 106 | 107 | /** 108 | * get an Array of Changed Attributes with original values 109 | */ 110 | public function getChanges(): array 111 | { 112 | $changes = []; 113 | 114 | foreach ($this->changedAttributesName() as $key) { 115 | $changes[$key] = $this->originals[$key]; 116 | } 117 | 118 | return $changes; 119 | } 120 | 121 | /** 122 | * is any attribute changed? 123 | */ 124 | public function isDirty(): bool 125 | { 126 | return count($this->changedAttributesName()) > 0; 127 | } 128 | 129 | public function jsonSerialize() 130 | { 131 | return $this->toArray(); 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /src/Commands/MakeRedisRepository.php: -------------------------------------------------------------------------------- 1 | checkStrategyName(); 37 | $this->setArguments(); 38 | 39 | $redisRepositoryName = "Redis$this->entityName" . 'Repository'; 40 | $relativeRedisRepositoryPath = config('repository.path.relative.repositories') . $this->entityName . DIRECTORY_SEPARATOR; 41 | $filenameWithPath = $relativeRedisRepositoryPath . $redisRepositoryName . '.php'; 42 | 43 | $this->checkAndPrepare($filenameWithPath, $redisRepositoryName, $relativeRedisRepositoryPath); 44 | $this->getColumnsOf($this->tableName); 45 | 46 | $redisRepositoryCreator = $this->getRedisRepositoryCreator($redisRepositoryName); 47 | $baseContent = $this->getBaseContent($redisRepositoryCreator, $filenameWithPath); 48 | 49 | $this->finalized($filenameWithPath, $redisRepositoryName, $baseContent); 50 | } 51 | 52 | 53 | private function getColumnsOf(string $tableName): Collection 54 | { 55 | $columns = $this->getAllColumnsInTable($tableName); 56 | $this->checkEmpty($columns, $tableName); 57 | 58 | return $columns; 59 | } 60 | 61 | 62 | private function getRedisRepositoryCreator(string $redisRepositoryName): CreatorRedisRepository 63 | { 64 | $redisRepositoryNamespace = config('repository.path.namespace.repositories'); 65 | $repositoryStubsPath = __DIR__ . '/../../' . config('repository.path.stub.repositories.base'); 66 | 67 | return new CreatorRedisRepository( 68 | $redisRepositoryName, 69 | $redisRepositoryNamespace, 70 | $this->entityName, 71 | $this->strategyName, 72 | $repositoryStubsPath 73 | ); 74 | } 75 | 76 | /** 77 | * @param CreatorRedisRepository $redisRepositoryCreator 78 | * @param string $filenameWithPath 79 | * @return string 80 | */ 81 | private function getBaseContent(CreatorRedisRepository $redisRepositoryCreator, string $filenameWithPath): string 82 | { 83 | $creator = new BaseCreator($redisRepositoryCreator); 84 | return $creator->createClass($filenameWithPath, $this); 85 | } 86 | 87 | /** 88 | * @param string $filenameWithPath 89 | * @param string $redisRepositoryName 90 | * @param string $relativeRedisRepositoryPath 91 | * @return void 92 | */ 93 | private function checkAndPrepare(string $filenameWithPath, string $redisRepositoryName, string $relativeRedisRepositoryPath): void 94 | { 95 | $this->checkDelete($filenameWithPath, $redisRepositoryName, self::OBJECT_NAME); 96 | $this->checkDirectory($relativeRedisRepositoryPath); 97 | $this->checkClassExist($this->repositoryNamespace, $redisRepositoryName, self::OBJECT_NAME); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/DatabaseRepositoryServiceProvider.php: -------------------------------------------------------------------------------- 1 | offerPublishing(); 35 | 36 | // Automatically apply the package configuration 37 | $this->mergeConfigFrom(__DIR__ . '/../config/repository.php', 'repository'); 38 | 39 | $this->registerCommands(); 40 | } 41 | 42 | public function offerPublishing(): void 43 | { 44 | if ($this->app->runningInConsole()) { 45 | $this->publishes([ 46 | __DIR__ . '/../config/repository.php' => $this->app->configPath('repository.php'), 47 | ], 'database-repository-config'); 48 | 49 | } 50 | } 51 | 52 | /** 53 | * Register custom commands. 54 | */ 55 | private function registerCommands(): void 56 | { 57 | if ($this->app->runningInConsole()) { 58 | $this->app->singleton('repository.make-all-repository', function () { 59 | return new MakeAll(); 60 | }); 61 | 62 | $this->app->singleton('repository.make-entity', function () { 63 | return new MakeEntity(); 64 | }); 65 | 66 | $this->app->singleton('repository.make-enum', function () { 67 | return new MakeEnum(); 68 | }); 69 | 70 | $this->app->singleton('repository.make-factory', function () { 71 | return new MakeFactory(); 72 | }); 73 | 74 | $this->app->singleton('repository.make-interface-repository', function () { 75 | return new MakeInterfaceRepository(); 76 | }); 77 | 78 | $this->app->singleton('repository.make-mysql-repository', function () { 79 | return new MakeMySqlRepository(); 80 | }); 81 | 82 | $this->app->singleton('repository.make-redis-repository', function () { 83 | return new MakeRedisRepository(); 84 | }); 85 | 86 | $this->app->singleton('repository.make-repository', function () { 87 | return new MakeRepository(); 88 | }); 89 | 90 | $this->app->singleton('repository.make-resource', function () { 91 | return new MakeResource(); 92 | }); 93 | 94 | $this->commands([ 95 | MakeAll::class, 96 | MakeEntity::class, 97 | MakeEnum::class, 98 | MakeFactory::class, 99 | MakeInterfaceRepository::class, 100 | MakeMySqlRepository::class, 101 | MakeRedisRepository::class, 102 | MakeRepository::class, 103 | MakeResource::class, 104 | 105 | 106 | ]); 107 | } 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /src/Commands/MakeFactory.php: -------------------------------------------------------------------------------- 1 | setArguments(); 44 | 45 | $filenameWithPath = $this->relativeFactoriesPath . $this->factoryName . '.php'; 46 | 47 | $this->checkAndPrepare($filenameWithPath); 48 | 49 | $columns = $this->getColumnsOf($this->tableName); 50 | 51 | foreach ($columns as $_column) { 52 | $_column->COLUMN_NAME = Str::camel($_column->COLUMN_NAME); 53 | } 54 | 55 | $baseContent = file_get_contents($this->factoryStubsPath . 'class.stub'); 56 | 57 | $factoryCreator = $this->getCreatorFactory($columns, $baseContent); 58 | $baseContent = $this->generateBaseContent($factoryCreator, $filenameWithPath); 59 | 60 | $this->finalized($filenameWithPath, $this->factoryName, $baseContent); 61 | } 62 | 63 | /** 64 | * @param string $filenameWithPath 65 | * @return void 66 | */ 67 | public function checkAndPrepare(string $filenameWithPath): void 68 | { 69 | $this->checkDelete($filenameWithPath, $this->entityName, self::OBJECT_NAME); 70 | $this->checkDirectory($this->relativeFactoriesPath); 71 | $this->checkClassExist($this->factoryNamespace, $this->entityName, self::OBJECT_NAME); 72 | } 73 | 74 | /** 75 | * @param string $tableName 76 | * @return Collection 77 | */ 78 | public function getColumnsOf(string $tableName): Collection 79 | { 80 | $columns = $this->getAllColumnsInTable($tableName); 81 | $this->checkEmpty($columns, $tableName); 82 | 83 | return $columns; 84 | } 85 | 86 | /** 87 | * @param Collection $columns 88 | * @param bool|string $baseContent 89 | * @return CreatorFactory 90 | */ 91 | public function getCreatorFactory(Collection $columns, bool|string $baseContent): CreatorFactory 92 | { 93 | return new CreatorFactory( 94 | $columns, 95 | $this->entityName, 96 | $this->entityNamespace, 97 | $this->factoryStubsPath, 98 | $this->factoryNamespace, 99 | $this->entityVariableName, 100 | $this->factoryName, 101 | $baseContent 102 | ); 103 | } 104 | 105 | /** 106 | * @param CreatorFactory $factoryCreator 107 | * @param string $filenameWithPath 108 | * @return string 109 | */ 110 | public function generateBaseContent(CreatorFactory $factoryCreator, string $filenameWithPath): string 111 | { 112 | $creator = new BaseCreator($factoryCreator); 113 | return $creator->createClass($filenameWithPath, $this); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/Commands/MakeResource.php: -------------------------------------------------------------------------------- 1 | setArguments(); 37 | $resourceName = $this->entityName . self::OBJECT_NAME; 38 | $resourceNamespace = config('repository.path.namespace.resources'); 39 | $relativeResourcesPath = config('repository.path.relative.resources'); 40 | 41 | $filenameWithPath = $relativeResourcesPath . $resourceName . '.php'; 42 | 43 | $this->checkAndPrepare($filenameWithPath, $resourceName, $relativeResourcesPath, $resourceNamespace); 44 | 45 | $RepoCreator = $this->getResourceCreator($resourceNamespace, $resourceName); 46 | $baseContent = $this->generateBaseContent($RepoCreator, $filenameWithPath); 47 | 48 | $this->finalized($filenameWithPath, $resourceName, $baseContent); 49 | } 50 | 51 | /** 52 | * @param string $filenameWithPath 53 | * @param string $resourceName 54 | * @param mixed $relativeResourcesPath 55 | * @param mixed $resourceNamespace 56 | * @return void 57 | */ 58 | private function checkAndPrepare(string $filenameWithPath, string $resourceName, mixed $relativeResourcesPath, mixed $resourceNamespace): void 59 | { 60 | $this->checkDelete($filenameWithPath, $resourceName, self::OBJECT_NAME); 61 | $this->checkDirectory($relativeResourcesPath); 62 | $this->checkClassExist($resourceNamespace, $resourceName, self::OBJECT_NAME); 63 | } 64 | 65 | /** 66 | * @param string $tableName 67 | * @return Collection 68 | */ 69 | private function getColumnsOf(string $tableName): Collection 70 | { 71 | $columns = $this->getAllColumnsInTable($tableName); 72 | $this->checkEmpty($columns, $tableName); 73 | 74 | return $columns; 75 | } 76 | 77 | /** 78 | * @param mixed $resourceNamespace 79 | * @param string $resourceName 80 | * @return CreatorResource 81 | */ 82 | private function getResourceCreator(mixed $resourceNamespace, string $resourceName): CreatorResource 83 | { 84 | $resourceStubsPath = __DIR__ . '/../../' . config('repository.path.stub.resources'); 85 | 86 | return new CreatorResource($this->getColumnsOf($this->tableName), 87 | $this->tableName, 88 | $this->entityName, 89 | $this->entityNamespace, 90 | $resourceNamespace, 91 | $resourceName, 92 | $resourceStubsPath, 93 | $this->detectForeignKeys, 94 | $this->entityVariableName); 95 | } 96 | 97 | /** 98 | * @param CreatorResource $RepoCreator 99 | * @param string $filenameWithPath 100 | * @return string 101 | */ 102 | private function generateBaseContent(CreatorResource $RepoCreator, string $filenameWithPath): string 103 | { 104 | $creator = new BaseCreator($RepoCreator); 105 | return $creator->createClass($filenameWithPath, $this); 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/Commands/MakeAll.php: -------------------------------------------------------------------------------- 1 | option('strategy_name'); 46 | 47 | if ($strategy !== null && in_array($strategy, $strategyNames) === false) { 48 | $this->alert('This pattern strategy does not exist !!! '); 49 | exit; 50 | } 51 | 52 | $selectedDb = $this->option('selected_db') ?: config('repository.default_db'); 53 | 54 | $force = $this->option('force'); 55 | $delete = $this->option('delete'); 56 | $detectForeignKeys = $this->option('foreign-keys'); 57 | $addToGit = $this->option('add-to-git'); 58 | 59 | if ($this->option('all-tables')) { 60 | $tableNames = $this->getAllTableNames()->pluck('TABLE_NAME'); 61 | } else if ($this->option('table_names')) { 62 | $tableNames = explode(',', $this->option('table_names')); 63 | } else { 64 | $this->alert("Please choose one of two options '--all-tables' or '--table_names=' "); 65 | die; 66 | } 67 | 68 | foreach ($tableNames as $_tableName) { 69 | 70 | $arguments = [ 71 | 'table_name' => $_tableName, 72 | '--foreign-keys' => $detectForeignKeys, 73 | '--delete' => $delete, 74 | '--force' => $force, 75 | '--add-to-git' => $addToGit 76 | ]; 77 | 78 | $this->runCommandsWithArguments($arguments, $strategy, $selectedDb); 79 | } 80 | } 81 | 82 | /** 83 | * @param array $arguments 84 | * @param bool|array|string|null $strategy 85 | * @param mixed $selectedDb 86 | * @return void 87 | */ 88 | private function runCommandsWithArguments(array $arguments, bool|array|string|null $strategy, mixed $selectedDb): void 89 | { 90 | $commands = [ 91 | 'repository:make-entity' => $arguments, 92 | 'repository:make-enum' => array_diff_key($arguments, ['--foreign-keys' => null]), 93 | 'repository:make-factory' => array_diff_key($arguments, ['--foreign-keys' => null]), 94 | 'repository:make-resource' => $arguments, 95 | 'repository:make-interface-repository' => $arguments, 96 | 'repository:make-mysql-repository' => $arguments, 97 | 'repository:make-repository' => $arguments + ['strategy' => $strategy, 'selected_db' => $selectedDb] 98 | ]; 99 | 100 | if ($strategy !== null) { 101 | $commands['repository:make-redis-repository'] = $arguments + ['strategy' => $strategy]; 102 | } 103 | 104 | foreach ($commands as $command => $args) { 105 | $this->call($command, $args); 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/Creators/CreatorResource.php: -------------------------------------------------------------------------------- 1 | resourceNamespace; 30 | } 31 | 32 | public function createUses(): array 33 | { 34 | return [ 35 | "use $this->entityNamespace\\$this->entityName;", 36 | 'use Eghamat24\DatabaseRepository\Models\Entity\Entity;', 37 | 'use Eghamat24\DatabaseRepository\Models\Resources\Resource;' 38 | ]; 39 | } 40 | 41 | public function getClassName(): string 42 | { 43 | return $this->resourceName; 44 | } 45 | 46 | public function getExtendSection(): string 47 | { 48 | return 'extends Resource'; 49 | } 50 | 51 | public function createAttributes(): array 52 | { 53 | return []; 54 | } 55 | 56 | public function createFunctions(): array 57 | { 58 | $getsStub = file_get_contents($this->resourceStubsPath . 'getter.default.stub'); 59 | $foreignGetterStub = file_get_contents($this->resourceStubsPath . 'getter.foreign.stub'); 60 | $foreignFunStub = file_get_contents($this->resourceStubsPath . 'function.foreign.stub'); 61 | $getterFunStub = file_get_contents($this->resourceStubsPath . 'function.getter.stub'); 62 | 63 | $getters = ''; 64 | foreach ($this->columns as $_column) { 65 | $getters .= $this->writeGet($getsStub, $_column->COLUMN_NAME, Str::camel($_column->COLUMN_NAME)) . "\t\t\t"; 66 | } 67 | 68 | $foreignGetterFunctions = ''; 69 | if ($this->detectForeignKeys) { 70 | $foreignKeys = $this->extractForeignKeys($this->tableName); 71 | foreach ($foreignKeys as $_foreignKey) { 72 | $foreignGetterFunctions .= $this->writeForeignGetter($foreignGetterStub, $_foreignKey->VARIABLE_NAME, $_foreignKey->ENTITY_DATA_TYPE); 73 | } 74 | } 75 | 76 | $functions = []; 77 | $functions['toArray'] = str_replace(['{{ Getters }}'], [$getters], $getterFunStub); 78 | $functions['toArray'] = str_replace(['{{ EntityVariableName }}'], [$this->entityVariableName], $functions['toArray']); 79 | $functions['toArrayWithForeignKeys'] = str_replace(['{{ ForeignGetterFunctions }}'], [$foreignGetterFunctions], $foreignFunStub); 80 | $functions['toArrayWithForeignKeys'] = str_replace(['{{ EntityVariableName }}'], [$this->entityVariableName], $functions['toArrayWithForeignKeys']); 81 | 82 | return $functions; 83 | } 84 | 85 | public function writeGet(string $getterStub, string $columnName, string $attributeName): array|string 86 | { 87 | $replaceMapping = [ 88 | '{{ ColumnName }}' => $columnName, 89 | '{{ AttributeName }}' => Str::camel($attributeName), 90 | ]; 91 | 92 | return str_replace(array_keys($replaceMapping), array_values($replaceMapping), $getterStub); 93 | } 94 | 95 | public function writeForeignGetter(string $foreignGetterStub, string $columnName, string $attributeName): array|string 96 | { 97 | $replaceMapping = [ 98 | '{{ AttributeName }}' => Str::snake($columnName), 99 | '{{ GetterName }}' => ucfirst($columnName), 100 | '{{ AttributeType }}' => ucfirst($attributeName) 101 | ]; 102 | 103 | return str_replace(array_keys($replaceMapping), array_values($replaceMapping), $foreignGetterStub); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/Commands/MakeEnum.php: -------------------------------------------------------------------------------- 1 | setArguments(); 37 | $columns = $this->getColumnsOf($this->tableName); 38 | $enums = $this->extractEnumsFromColumns($columns); 39 | 40 | $attributeStub = file_get_contents($this->enumStubPath . 'attribute.stub'); 41 | 42 | foreach ($enums as $enumName => $enum) { 43 | $filenameWithPath = $this->relativeEnumsPath . $enumName . '.php'; 44 | 45 | $this->checkAndPrepare($enumName); 46 | $baseContent = $this->getBaseCreator($columns, $attributeStub, $enum, $enumName) 47 | ->createClass($filenameWithPath, $this); 48 | 49 | $this->finalized($filenameWithPath, $enumName, $baseContent); 50 | } 51 | } 52 | 53 | 54 | /** 55 | * @param Collection $columns 56 | * @return array 57 | */ 58 | public function extractEnumsFromColumns(Collection $columns): array 59 | { 60 | $enums = []; 61 | foreach ($columns as $_column) { 62 | 63 | if ($_column->DATA_TYPE !== 'enum') { 64 | continue; 65 | } 66 | 67 | $enumClassName = $this->getEnumClassName($_column); 68 | $enums[$enumClassName] = $this->extractEnumValues($_column->COLUMN_TYPE); 69 | 70 | $this->checkDelete( 71 | $this->relativeEnumsPath . $enumClassName . '.php', 72 | $enumClassName, 73 | self::OBJECT_NAME 74 | ); 75 | } 76 | 77 | return $enums; 78 | } 79 | 80 | private function getEnumClassName(mixed $_column): string 81 | { 82 | $tableName = ucfirst(Str::camel($_column->TABLE_NAME)); 83 | $columnName = $_column->COLUMN_NAME; 84 | 85 | return Str::studly(Str::singular($tableName) . '_' . $columnName) . self::OBJECT_NAME; 86 | } 87 | 88 | private function extractEnumValues($columnType): array 89 | { 90 | $items = explode(',', str_replace(['enum(', '\'', ')'], ['', '', ''], $columnType)); 91 | 92 | return array_filter($items); 93 | } 94 | 95 | /** 96 | * @param Collection $columns 97 | * @param bool|string $attributeStub 98 | * @param mixed $enum 99 | * @param int|string $enumName 100 | * @return BaseCreator 101 | */ 102 | private function getBaseCreator(Collection $columns, bool|string $attributeStub, mixed $enum, int|string $enumName): BaseCreator 103 | { 104 | $enumCreator = new CreatorEnum($columns, $attributeStub, $enum, $enumName, $this->enumNamespace); 105 | 106 | return new BaseCreator($enumCreator); 107 | } 108 | 109 | /** 110 | * @param string $table 111 | * @return Collection 112 | */ 113 | public function getColumnsOf(string $table): Collection 114 | { 115 | $columns = $this->getAllColumnsInTable($table); 116 | $this->checkEmpty($columns, $table); 117 | 118 | return $columns; 119 | } 120 | 121 | /** 122 | * @param int|string $enumName 123 | * @return void 124 | */ 125 | public function checkAndPrepare(int|string $enumName): void 126 | { 127 | $this->checkDirectory($this->enumNamespace); 128 | $this->checkClassExist($this->relativeEnumsPath, $enumName, self::OBJECT_NAME); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/Commands/MakeRepository.php: -------------------------------------------------------------------------------- 1 | checkDatabasesExist(); 37 | $this->checkStrategyName(); 38 | 39 | $this->setArguments(); 40 | $repositoryName = $this->entityName . self::OBJECT_NAME; 41 | $relativeRepositoryPath = config('repository.path.relative.repositories') . "$this->entityName" . DIRECTORY_SEPARATOR; 42 | 43 | $filenameWithPath = $relativeRepositoryPath . $repositoryName . '.php'; 44 | $this->checkAndPrepare($filenameWithPath, $repositoryName, $relativeRepositoryPath); 45 | 46 | $repositoryCreator = $this->getRepositoryCreator($repositoryName); 47 | $baseContent = $this->createBaseContent($repositoryCreator, $filenameWithPath); 48 | 49 | $this->finalized($filenameWithPath, $repositoryName, $baseContent); 50 | } 51 | 52 | /** 53 | * @param string $repositoryName 54 | * @return CreatorRepository 55 | */ 56 | private function getRepositoryCreator(string $repositoryName): CreatorRepository 57 | { 58 | $sqlRepositoryName = ucwords($this->selectedDb) . $repositoryName; 59 | $repositoryStubsPath = __DIR__ . '/../../' . config('repository.path.stub.repositories.base'); 60 | 61 | return new CreatorRepository( 62 | $this->getColumnsOf($this->tableName), 63 | 'repository', 64 | $sqlRepositoryName, 65 | $repositoryStubsPath, 66 | $this->detectForeignKeys, 67 | $this->tableName, 68 | $this->entityVariableName, 69 | $this->entityName, 70 | $this->entityNamespace, 71 | $repositoryName, 72 | $this->interfaceName, 73 | $this->repositoryNamespace, 74 | $this->selectedDb, 75 | 'redisRepository', 76 | 'Redis' . $repositoryName, 77 | $this->strategyName 78 | ); 79 | } 80 | 81 | /** 82 | * @param string $tableName 83 | * @return Collection 84 | */ 85 | private function getColumnsOf(string $tableName): Collection 86 | { 87 | $columns = $this->getAllColumnsInTable($tableName); 88 | $this->checkEmpty($columns, $tableName); 89 | 90 | return $columns; 91 | } 92 | 93 | /** 94 | * @param CreatorRepository $RepoCreator 95 | * @param string $filenameWithPath 96 | * @return string 97 | */ 98 | private function createBaseContent(CreatorRepository $RepoCreator, string $filenameWithPath): string 99 | { 100 | $creator = new BaseCreator($RepoCreator); 101 | return $creator->createClass($filenameWithPath, $this); 102 | } 103 | 104 | /** 105 | * @param string $filenameWithPath 106 | * @param string $repositoryName 107 | * @param string $relativeRepositoryPath 108 | * @return void 109 | */ 110 | private function checkAndPrepare(string $filenameWithPath, string $repositoryName, string $relativeRepositoryPath): void 111 | { 112 | $this->checkDelete($filenameWithPath, $repositoryName, self::OBJECT_NAME); 113 | $this->checkDirectory($relativeRepositoryPath); 114 | $this->checkClassExist($this->repositoryNamespace, $repositoryName, self::OBJECT_NAME); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/CustomMySqlQueries.php: -------------------------------------------------------------------------------- 1 | 'bool', 13 | 'boolean' => 'bool', 14 | 'bit' => 'string', 15 | 'int' => 'int', 16 | 'integer' => 'int', 17 | 'tinyint' => 'int', 18 | 'smallint' => 'int', 19 | 'mediumint' => 'int', 20 | 'bigint' => 'int', 21 | 'float' => 'float', 22 | 'decimal' => 'float', 23 | 'double' => 'float', 24 | 'json' => 'string', 25 | 'char' => 'string', 26 | 'varchar' => 'string', 27 | 'binary' => 'string', 28 | 'varbinary' => 'string', 29 | 'tinyblob' => 'string', 30 | 'tinytext' => 'string', 31 | 'text' => 'string', 32 | 'blob' => 'string', 33 | 'mediumtext' => 'string', 34 | 'mediumblob' => 'string', 35 | 'longtext' => 'string', 36 | 'longblob' => 'string', 37 | 'enum' => 'string', 38 | 'date' => 'string', 39 | 'time' => 'string', 40 | 'datetime' => 'string', 41 | 'timestamp' => 'string', 42 | 'point' => 'string', 43 | ]; 44 | 45 | protected array $columnTypes = [ 46 | 'tinyint(1)' => 'bool' 47 | ]; 48 | 49 | /** 50 | * Extract all columns from a given table. 51 | */ 52 | public function getAllColumnsInTable(string $tableName): Collection 53 | { 54 | return DB::table('INFORMATION_SCHEMA.COLUMNS') 55 | ->where('TABLE_SCHEMA', config('database.connections.mysql.database')) 56 | ->where('TABLE_NAME', $tableName) 57 | ->orderBy('ORDINAL_POSITION') 58 | ->get(); 59 | } 60 | 61 | /** 62 | * Extract all table names. 63 | */ 64 | public function getAllTableNames(): Collection 65 | { 66 | return DB::table('INFORMATION_SCHEMA.TABLES') 67 | ->select('TABLE_NAME') 68 | ->where('TABLE_SCHEMA', config('database.connections.mysql.database')) 69 | ->where('TABLE_NAME', '<>', 'migrations') 70 | ->get(); 71 | } 72 | 73 | /** 74 | * Extract all foreign keys from a given table. Foreign key's relations must define in MySql! 75 | */ 76 | public function extractForeignKeys(string $tableName): Collection 77 | { 78 | $foreignKeys = DB::table('INFORMATION_SCHEMA.KEY_COLUMN_USAGE') 79 | ->where('TABLE_SCHEMA', config('database.connections.mysql.database')) 80 | ->where('TABLE_NAME', $tableName) 81 | ->whereNotNull('REFERENCED_TABLE_NAME') 82 | ->orderBy('ORDINAL_POSITION') 83 | ->get(); 84 | 85 | $foreignKeys->each(function ($foreignKey) { 86 | $foreignKey->VARIABLE_NAME = Str::camel(str_replace('_id', '', $foreignKey->COLUMN_NAME)); 87 | $foreignKey->ENTITY_DATA_TYPE = ucfirst(Str::camel(Str::singular($foreignKey->REFERENCED_TABLE_NAME))); 88 | }); 89 | 90 | return $foreignKeys; 91 | } 92 | 93 | /** 94 | * Extract all indexes from a given table! 95 | */ 96 | public function extractIndexes(string $tableName): Collection 97 | { 98 | $indexes = DB::table('INFORMATION_SCHEMA.KEY_COLUMN_USAGE') 99 | ->where('TABLE_SCHEMA', config('database.connections.mysql.database')) 100 | ->where('TABLE_NAME', $tableName) 101 | ->where('CONSTRAINT_NAME', '!=', 'PRIMARY') 102 | ->whereNull('REFERENCED_TABLE_NAME') 103 | ->orderBy('ORDINAL_POSITION') 104 | ->get(); 105 | 106 | $indexesData = DB::select("SHOW INDEX FROM $tableName WHERE Key_name != 'PRIMARY'"); 107 | 108 | collect($indexes)->each(function ($index) use ($indexesData) { 109 | $indexesData = collect($indexesData)->where('Column_name', $index->COLUMN_NAME)->first(); 110 | $index->Non_unique = $indexesData->Non_unique; 111 | $index->Index_type = $indexesData->Index_type; 112 | }); 113 | 114 | return $indexes; 115 | } 116 | 117 | public function getDataType(string $columnType, string $dataType): string 118 | { 119 | if (array_key_exists($columnType, $this->columnTypes)) { 120 | return $this->columnTypes[$columnType]; 121 | } 122 | 123 | return $this->dataTypes[$dataType]; 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/Creators/CreatorEntity.php: -------------------------------------------------------------------------------- 1 | columns as $_column) { 38 | 39 | $dataType = $this->getDataType($_column->COLUMN_TYPE, $_column->DATA_TYPE); 40 | 41 | $defaultValue = null; 42 | if ($_column->COLUMN_DEFAULT !== null) { 43 | $defaultValue = $_column->COLUMN_DEFAULT; 44 | 45 | if ($dataType === DataTypeEnum::INTEGER_TYPE) { 46 | $defaultValue = intval($defaultValue); 47 | } 48 | 49 | if ($dataType === self::BOOL_TYPE) { 50 | if (in_array($defaultValue, [0, '', "''"])) { 51 | $defaultValue = 'false'; 52 | } elseif (in_array($defaultValue, [1, '1'])) { 53 | $defaultValue = 'true'; 54 | } 55 | } 56 | } 57 | 58 | $columnString = $_column->COLUMN_NAME; 59 | 60 | if (!in_array($_column->COLUMN_DEFAULT, [null, 'NULL'])) { 61 | $columnString .= ' = ' . $defaultValue; 62 | } 63 | 64 | if ($_column->IS_NULLABLE === 'YES') { 65 | $columnString .= ' = null'; 66 | } 67 | 68 | $attributes[$_column->COLUMN_NAME] = 69 | $this->writeAttribute( 70 | $this->entityStubsPath, 71 | $columnString, 72 | ($_column->IS_NULLABLE === 'YES' ? 'null|' : '') . $dataType 73 | ); 74 | } 75 | 76 | if ($this->detectForeignKeys) { 77 | $foreignKeys = $this->extractForeignKeys($this->tableName); 78 | 79 | // Create Additional Attributes from Foreign Keys 80 | foreach ($foreignKeys as $_foreignKey) { 81 | $attributes[$_column->COLUMN_NAME] = 82 | $this->writeAttribute( 83 | $this->entityStubsPath, 84 | $_foreignKey->VARIABLE_NAME, 85 | $_foreignKey->ENTITY_DATA_TYPE 86 | ); 87 | } 88 | } 89 | 90 | return $attributes; 91 | } 92 | 93 | public function createUses(): array 94 | { 95 | return ['use Eghamat24\DatabaseRepository\Models\Entity\Entity;']; 96 | } 97 | 98 | public function createFunctions(): array 99 | { 100 | return []; 101 | } 102 | 103 | private function writeAttribute(string $entityStubsPath, string $attributeName, string $attributeType): string 104 | { 105 | $attributeStub = file_get_contents($entityStubsPath . 'attribute.stub'); 106 | 107 | $replaceMapping = [ 108 | '{{ AttributeType }}' => $attributeType, 109 | '{{ AttributeName }}' => $attributeName, 110 | ]; 111 | 112 | return str_replace(array_keys($replaceMapping), array_values($replaceMapping), $attributeStub); 113 | } 114 | 115 | private function writeAccessors(string $entityStubsPath, string $attributeName, string $attributeType, string $type): string 116 | { 117 | $accessorStub = file_get_contents($entityStubsPath . $type . '.stub'); 118 | 119 | $replaceMapping = [ 120 | '{{ AttributeType }}' => $attributeType, 121 | '{{ AttributeName }}' => $attributeName, 122 | '{{ GetterName }}' => ucfirst($attributeName), 123 | '{{ SetterName }}' => ucfirst($attributeName) 124 | ]; 125 | 126 | return str_replace(array_keys($replaceMapping), array_values($replaceMapping), $accessorStub); 127 | } 128 | 129 | public function getNameSpace(): string 130 | { 131 | return $this->entityNamespace; 132 | } 133 | 134 | public function getClassName(): string 135 | { 136 | return $this->entityName; 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/Models/Repositories/RedisRepository.php: -------------------------------------------------------------------------------- 1 | cache = app('cache'); 14 | } 15 | 16 | protected function getCache(): CacheManager 17 | { 18 | return $this->cache; 19 | } 20 | 21 | /** 22 | * @param Collection $entities 23 | * @param Filter[]|Collection $filters 24 | * @return Collection 25 | */ 26 | protected function processFilterWithCollection($entities, $filters) 27 | { 28 | foreach ($filters as $filter) { 29 | $columnName = camel_case($filter->getColumnName()); 30 | $value = $filter->getValue(); 31 | 32 | switch ($filter->getOperand()) { 33 | case 'IsEqualTo': 34 | $entities = $entities->where($columnName, '=', $value); 35 | break; 36 | case 'IsEqualToOrNull': 37 | $entities = $entities->filter(function ($entity, $key) use ($columnName, $value) { 38 | return ($entity->$columnName == $value || empty($entity->$columnName)); 39 | }); 40 | break; 41 | case 'IsNull': 42 | $entities = $entities->whereNull($columnName); 43 | break; 44 | case 'IsNotEqualTo': 45 | $entities = $entities->where($columnName, '<>', $value); 46 | break; 47 | case 'IsNotNull': 48 | $entities = $entities->whereNotNull($columnName); 49 | break; 50 | case 'StartWith': 51 | $entities = $entities->filter(function ($entity) use ($columnName, $value) { 52 | return false !== Str::startsWith($entity->$columnName, $value); 53 | }); 54 | break; 55 | case 'DoesNotContains': 56 | $entities = $entities->filter(function ($entity) use ($columnName, $value) { 57 | return false === Str::contains($entity->$columnName, $value); 58 | }); 59 | break; 60 | case 'Contains': 61 | $entities = $entities->filter(function ($entity) use ($columnName, $value) { 62 | return false !== Str::contains($entity->$columnName, $value); 63 | }); 64 | break; 65 | case 'EndsWith': 66 | $entities = $entities->filter(function ($entity) use ($columnName, $value) { 67 | return false !== Str::endsWith($entity->$columnName, $value); 68 | }); 69 | break; 70 | case 'In': 71 | $entities = $entities->whereIn($columnName, $value); 72 | break; 73 | case 'NotIn': 74 | $entities = $entities->whereNotIn($columnName, $value); 75 | break; 76 | case 'Between': 77 | $entities = $entities->whereBetween($columnName, $value); 78 | break; 79 | case 'IsGreaterThanOrEqualTo': 80 | $entities = $entities->where($columnName, '>=', $value); 81 | break; 82 | case 'IsGreaterThanOrNull': 83 | $entities = $entities->filter(function ($entity) use ($columnName, $value) { 84 | return ($entity->$columnName > $value || empty($entity->$columnName)); 85 | }); 86 | break; 87 | case 'IsGreaterThan': 88 | $entities = $entities->where($columnName, '>', $value); 89 | break; 90 | case 'IsLessThanOrEqualTo': 91 | $entities = $entities->where($columnName, '<=', $value); 92 | break; 93 | case 'IsLessThan': 94 | $entities = $entities->where($columnName, '<', $value); 95 | break; 96 | case 'IsAfterThanOrEqualTo': 97 | $entities = $entities->where($columnName, '>=', $value); 98 | break; 99 | case 'IsAfterThan': 100 | $entities = $entities->where($columnName, '>', $value); 101 | break; 102 | case 'IsBeforeThanOrEqualTo': 103 | $entities = $entities->where($columnName, '<=', $value); 104 | break; 105 | case 'IsBeforeThan': 106 | $entities = $entities->where($columnName, '<', $value); 107 | break; 108 | } 109 | } 110 | 111 | return $entities; 112 | } 113 | 114 | /** 115 | * @param Collection $entities 116 | * @param Order[]|Collection $orders 117 | * @return Collection 118 | */ 119 | protected function processOrderWithCollection($entities, $orders) 120 | { 121 | $sortBy = []; 122 | foreach ($orders as $order) { 123 | $sortBy[$order->getColumnName()] = $order->getValue(); 124 | } 125 | 126 | return $entities->sortBy($sortBy); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Database Repository / PHP Repository / Laravel Repository 2 | 3 | ## Installation 4 | Use the following command to add this package to the composer development requirement. 5 | ```bash 6 | composer require eghamat24/database-repository --dev 7 | ``` 8 | 9 | ### Setup Laravel Repository 10 | Then run the following command in the console to publish the necessary assets in your project directory. 11 | ```bash 12 | php artisan vendor:publish --tag=database-repository-config 13 | ``` 14 | 15 | ### Setup Lumen Repository 16 | Navigate to `app.php` in `bootstrap` folder and add the following line after service providers registrations: 17 | ```php 18 | // snip 19 | if ($app->environment('local', 'testing')) { 20 | $app->register(Eghamat24\DatabaseRepository\DatabaseRepositoryServiceProvider::class); 21 | } 22 | // snip 23 | ``` 24 | Copy [repository.php](config/repository.php) to the project config folder located at the project root. 25 | 26 | Note: Make sure to run `composer dump-autoload` after these changes. 27 | 28 | ## Usage 29 | To use this package easily, you can run the following command. It will create all the required components such as Entity, IRepository, Repository, MySqlRepository, RedisRepository, Resource, and Factory for the users table. 30 | ```bash 31 | php artisan repository:make-all --table_names=users --strategy_name=QueryCacheStrategy 32 | ``` 33 | List of artisan commands: 34 | 35 | | Command | Inputs | Options | Description | 36 | |----------------------------------------|---------------------------------------------------------------------------|--------------------|-----------------------------------| 37 | | `repository:make-entity` | table_name | -f, -d, -k, -g | Create new Entity | 38 | | `repository:make-enum` | table_name | -f, -d, -g | Create new Enum | 39 | | `repository:make-factory` | table_name | -f, -d, -g | Create new Factory | 40 | | `repository:make-resource` | table_name | -f, -d, -k, -g | Create new Resource | 41 | | `repository:make-interface-repository` | table_name | -f, -d, -k, -g | Create new Repository Interface | 42 | | `repository:make-repository` | table_name, selected_db(optional) | -f, -d, -k, -g | Create new Base Repository | 43 | | `repository:make-mysql-repository` | table_name | -f, -d, -k, -g | Create new MySql Repository class | 44 | | `repository:make-redis-repository` | table_name | -f, -d, -k, -g | Create new Redis Repository class | 45 | | `repository:make-all` | --table_names=table_names(optional)
--selected_db=database(optional) | -a, -f, -d, -k, -g | Run all of the above commands | 46 | 47 | 48 | ### Options Explanation 49 | - `-f|--force`: Force commands to override existing files. 50 | - `-d|--delete`: Delete already created files. 51 | - `-k|--foreign-keys`: Try to detect foreign keys of a table. 52 | - `-g|--add-to-git`: Add created files to the git repository. 53 | - `-a|--all-tables`: Use all existing tables. 54 | - `--table_names=`: Add table names, separate names with comma. 55 | - `--selected_db=` : Use between `Mysql`,`Redis`, If it does not send, the value will return from `config/repository.php` 56 | - `--strategy_name=` : add a trait to your Redis repository based on the strategy you choose 57 | 58 | Example 1. Create a new Entity for a table named 'users'. 59 | ```bash 60 | php artisan repository:make-entity users 61 | ``` 62 | 63 | Example 2. Create all necessary classes for two tables named 'users' and 'customers' with an enabled foreign key option. 64 | ```bash 65 | php artisan repository:make-all --table_names=users,customers -k 66 | ``` 67 | 68 | Example 3. Create all necessary classes for all tables with an enabled foreign key option(this may be used for new projects). 69 | ```bash 70 | php artisan repository:make-all -a -k 71 | ``` 72 | 73 | ## Cache Strategy 74 | We created some strategies for caching data, based on the number of records and change frequency 75 | 76 | ### SingleKeyCacheStrategy 77 | SingleKeyCacheStrategy is a good choice for tables with very few rows, such as less than 50 records. This strategy creates one cache key and stores all the data on it. Then, when the app queries data, it loops through the data and returns the result. 78 | 79 | This strategy has one cache key and clears all the cached data whenever there is a change. This ensures that the data is always updated and valid. 80 | 81 | ### QueryCacheStrategy 82 | QueryCacheStrategy is suitable for tables that have low change frequency and not too many records. For example, if the table has less than 10,000 rows or if it has more than that but the queries are not very unique and there are similar queries, this strategy works well. 83 | 84 | This strategy assigns a tag to each cache of the repository and clears all the cached data whenever there is a change. This ensures that the data is always updated and valid. 85 | 86 | ### TemporaryCacheStrategy 87 | TemporaryCacheStrategy is useful when we have a large or diverse amount of data and the data user can tolerate some delay in the updates. We cache every request and delay the changes that are not critical to be reflected in real time. For example, if we have a post and we edit its content, we can cache the old version until the cache expires. We set the cache expiration time for each data item based on the maximum delay the user can accept. This way, we use this strategy to cache data temporarily. 88 | 89 | ### ClearableTemporaryCacheStrategy 90 | Sometimes, we need to clear the data from a temporary cache when some critical changes occur. ClearableTemporaryCacheStrategy is suitable for these situations. 91 | 92 | ```bash 93 | php artisan repository:make-all --table_names=users --strategy_name=QueryCacheStrategy 94 | ``` 95 | -------------------------------------------------------------------------------- /src/Creators/BaseCreator.php: -------------------------------------------------------------------------------- 1 | creator = $creator; 21 | } 22 | 23 | public function createClass(string $filenameWithPath, BaseCommand $command): string 24 | { 25 | $attributesArray = $this->creator->createAttributes(); 26 | $functionsArray = $this->creator->createFunctions(); 27 | $usesArray = $this->creator->createUses(); 28 | 29 | $specificPattern = "/(?public|private|protected)\sfunction\s+(?\w+)\s*\((?[^\)]*)\)\s*:?\s*(?.{0,100})\s*(?\{(?:[^{}]+|(?&body))*\})/"; 30 | $functionsArray = $this->checkDiffrence($filenameWithPath, $functionsArray, $command, $specificPattern); 31 | $generalPattern = "/class\s*[^$]*\{(?[^}]*)((public|protected|private) function |})/isU"; 32 | $specificPattern = '/(public|protected|private) [^\s]* \$*(?[^\s;\=]*)\s*[^;]*;/is'; 33 | $attributesArray = $this->checkDiffrence($filenameWithPath, $attributesArray, $command, $specificPattern, $generalPattern); 34 | 35 | $attributes = trim(implode("\n\t", $attributesArray)); 36 | 37 | $functions = ''; 38 | if (count($functionsArray) > 0) { 39 | $functions = trim(implode("\n", $functionsArray)); 40 | $functions = (!empty($attributes)) ? "\n\n\t" . $functions : $functions; 41 | } 42 | 43 | $uses = implode(PHP_EOL, $usesArray); 44 | 45 | $type = (isset($this->creator->enum)) ? self::ENUM_TYPE : self::CLASS_TYPE; 46 | $basePath = __DIR__ . "/../../stubs/base.$type.stub"; 47 | 48 | $this->creator->baseContent = str_replace(['{{ Namespace }}', '{{ UseSection }}', '{{ ClassName }}', '{{ ExtendSection }}', '{{ Parameters }}', '{{ Functions }}', '{{ CacheTag }}'], 49 | [ 50 | $this->creator->getNameSpace(), 51 | $uses, 52 | $this->creator->getClassName(), 53 | $this->creator->getExtendSection(), 54 | $attributes, 55 | $functions, 56 | $this->setCachetag($command) 57 | ], 58 | file_get_contents($basePath)); 59 | 60 | return $this->creator->baseContent; 61 | } 62 | 63 | public function checkDiffrence(string $filenameWithPath, array $newParamsArray, BaseCommand $command, string $specificPattern, string $generalPattern = '/(?.*)/is'): array 64 | { 65 | if (file_exists($filenameWithPath)) { 66 | $file = file_get_contents($filenameWithPath); 67 | if (preg_match($generalPattern, $file, $matches)) { 68 | if (preg_match_all($specificPattern, $matches['main_part'], $attributMatches)) { 69 | for ($i = 0; $i < count($attributMatches['name']); $i++) { 70 | if (array_search($this->getChoice(), self::ALL_OPTIONS) < 2) 71 | $this->setChoice(null); 72 | if (!isset($newParamsArray[$attributMatches['name'][$i]])) { 73 | $newParamsArray[$attributMatches['name'][$i]] = ''; 74 | } 75 | $attr = $newParamsArray[$attributMatches['name'][$i]]; 76 | 77 | if (preg_replace('/\s+/', '', $attr) === preg_replace('/\s+/', '', $attributMatches[0][$i])) { 78 | $command->info("There is no diffrence between '" . $attributMatches['name'][$i] . "' "); 79 | } else { 80 | $command->warn("WARN: '" . $attributMatches['name'][$i] . "'s are not the same"); 81 | if (is_null($this->getChoice()) && array_search($this->getChoice(), self::ALL_OPTIONS) < 2) { 82 | // $command->table( ['Current','new'], [['Current'=>trim($attributMatches[0][$i]),'New'=>trim($attr)]],'default'); 83 | $command->line("######################## CURRENT #########################", 'fg=magenta'); 84 | $command->line(trim($attributMatches[0][$i]), 'fg=magenta'); 85 | $command->line("##########################################################", 'fg=magenta'); 86 | $command->line(" ", 'fg=magenta'); 87 | $command->line("########################## NEW ###########################", 'fg=cyan'); 88 | $command->line(trim($attr), 'fg=cyan'); 89 | $command->line("##########################################################", 'fg=cyan'); 90 | $this->setChoice($command->choice('Choose one version', self::ALL_OPTIONS, 0)); 91 | if (array_search($this->getChoice(), self::ALL_OPTIONS) % 2 == 0) { 92 | $newParamsArray[$attributMatches['name'][$i]] = trim($attributMatches[0][$i]) . PHP_EOL; 93 | $command->warn("Action: Current version selected for '" . $attributMatches['name'][$i] . "', "); 94 | } 95 | } elseif (array_search($this->getChoice(), self::ALL_OPTIONS) == 2) { 96 | $newParamsArray[$attributMatches['name'][$i]] = trim($attributMatches[0][$i]) . PHP_EOL; 97 | $command->warn("Action: Current version selected for '" . $attributMatches['name'][$i] . "', "); 98 | } else { 99 | $command->warn("Action: New version replaced for '" . $attributMatches['name'][$i] . "', "); 100 | } 101 | } 102 | } 103 | } 104 | } 105 | } 106 | return $newParamsArray; 107 | } 108 | 109 | private function setCacheTag(BaseCommand $command) 110 | { 111 | return (isset($command->strategyName) && in_array($command->strategyName, [self::QUERY_CACHE_STRATEGY, self::SINGLE_KEY_CACHE_STRATEGY])) ? "'$command->tableName'" : "''"; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/Commands/BaseCommand.php: -------------------------------------------------------------------------------- 1 | selectedDb = $this->hasArgument('selected_db') && $this->argument('selected_db') ? $this->argument('selected_db') : config('repository.default_db'); 41 | $this->tableName = $this->argument('table_name'); 42 | if ($this->hasOption('foreign-keys')) $this->detectForeignKeys = $this->option('foreign-keys'); 43 | $this->entityName = Str::singular(ucfirst(Str::camel($this->tableName))); 44 | $this->entityNamespace = config('repository.path.namespace.entities'); 45 | $this->relativeEntitiesPath = config('repository.path.relative.entities'); 46 | $this->entityStubsPath = __DIR__ . '/../../' . config('repository.path.stub.entities'); 47 | 48 | $this->enumNamespace = config('repository.path.namespace.enums'); 49 | $this->relativeEnumsPath = config('repository.path.relative.enums'); 50 | $this->enumStubPath = __DIR__ . '/../../' . config('repository.path.stub.enums'); 51 | 52 | $this->entityVariableName = Str::camel($this->entityName); 53 | $this->factoryName = $this->entityName . 'Factory'; 54 | $this->factoryNamespace = config('repository.path.namespace.factories'); 55 | $this->relativeFactoriesPath = config('repository.path.relative.factories'); 56 | $this->factoryStubsPath = __DIR__ . '/../../' . config('repository.path.stub.factories'); 57 | 58 | $this->interfaceName = "I$this->entityName" . "Repository"; 59 | $this->repositoryNamespace = config('repository.path.namespace.repositories'); 60 | $this->relativeInterfacePath = config('repository.path.relative.repositories') . "$this->entityName" . DIRECTORY_SEPARATOR; 61 | $this->interfaceRepositoryStubsPath = __DIR__ . '/../../' . config('repository.path.stub.repositories.interface'); 62 | 63 | $this->mysqlRepositoryName = 'MySql' . $this->entityName . 'Repository'; 64 | $this->relativeMysqlRepositoryPath = config('repository.path.relative.repositories') . "$this->entityName" . DIRECTORY_SEPARATOR; 65 | $this->mysqlRepositoryStubsPath = __DIR__ . '/../../' . config('repository.path.stub.repositories.mysql'); 66 | if ($this->hasArgument('strategy')) { 67 | $this->strategyName = $this->argument('strategy'); 68 | } 69 | } 70 | 71 | public function checkDelete(string $filenameWithPath, string $entityName, string $objectName): void 72 | { 73 | if (file_exists($filenameWithPath) && $this->option('delete')) { 74 | \unlink($filenameWithPath); 75 | $this->info("$objectName '$entityName' has been deleted."); 76 | } 77 | } 78 | 79 | public function checkDirectory(string $relativeEntitiesPath): void 80 | { 81 | if (!file_exists($relativeEntitiesPath) && !mkdir($relativeEntitiesPath, 0775, true) && !is_dir($relativeEntitiesPath)) { 82 | $this->alert("Directory \"$relativeEntitiesPath\" was not created"); 83 | exit; 84 | } 85 | } 86 | 87 | public function checkClassExist(string $nameSpace, string $entityName, string $objectName): void 88 | { 89 | if (class_exists($nameSpace . '\\' . $entityName) && !$this->option('force')) { 90 | $this->alert("$objectName \"$entityName\" is already exist!"); 91 | exit; 92 | } 93 | } 94 | 95 | public function finalized(string $filenameWithPath, string $entityName, string $baseContent): void 96 | { 97 | file_put_contents($filenameWithPath, $baseContent); 98 | if ($this->option('add-to-git')) { 99 | shell_exec('git add ' . $filenameWithPath); 100 | } 101 | 102 | $this->info("\"$entityName\" has been created."); 103 | } 104 | 105 | public function checkEmpty(Collection $columns, string $tableName): void 106 | { 107 | if ($columns->isEmpty()) { 108 | $this->alert("Couldn't retrieve columns from table \"$tableName\"! Perhaps table's name is misspelled."); 109 | exit; 110 | } 111 | } 112 | 113 | public function setChoice($choice): void 114 | { 115 | \config(['replacement.choice' => $choice]); 116 | } 117 | 118 | public function getChoice(): null|string 119 | { 120 | return \config('replacement.choice'); 121 | } 122 | 123 | public function checkStrategyName() 124 | { 125 | $strategyNames = [ 126 | 'ClearableTemporaryCacheStrategy', 127 | 'QueryCacheStrategy', 128 | 'SingleKeyCacheStrategy', 129 | 'TemporaryCacheStrategy' 130 | ]; 131 | 132 | if (!in_array($this->argument('strategy'), $strategyNames)) { 133 | $this->alert('This pattern strategy does not exist !!! '); 134 | exit; 135 | } 136 | } 137 | 138 | public function checkDatabasesExist() 139 | { 140 | $entityName = Str::singular(ucfirst(Str::camel($this->argument('table_name')))); 141 | $mysql = config('repository.path.relative.repositories') . DIRECTORY_SEPARATOR . $entityName . DIRECTORY_SEPARATOR . 'MySql' . $entityName . 'Repository.php'; 142 | $redis = config('repository.path.relative.repositories') . DIRECTORY_SEPARATOR . $entityName . DIRECTORY_SEPARATOR . 'Redis' . $entityName . 'Repository.php'; 143 | 144 | if (!(file_exists($mysql) || file_exists($redis))) { 145 | $this->alert("First create the class databases!!!"); 146 | exit; 147 | } 148 | } 149 | 150 | } 151 | -------------------------------------------------------------------------------- /src/Models/Repositories/MySqlRepository.php: -------------------------------------------------------------------------------- 1 | alternativeDbConnection = null; 30 | } 31 | 32 | /** 33 | * Notice: this function cannot be used in async jobs because the connection is not serializable! 34 | */ 35 | public function changeDatabaseConnection($connection) 36 | { 37 | $this->alternativeDbConnection = $connection; 38 | } 39 | 40 | public function newQuery(): Builder 41 | { 42 | if (is_null($this->alternativeDbConnection)) { 43 | $query = app('db')->table($this->table); 44 | } else { 45 | $query = $this->alternativeDbConnection->table($this->table); 46 | } 47 | 48 | // if ($this->softDelete) { 49 | // if (!$this->withTrashed) { 50 | // $query = $query->whereNull('deleted_at'); 51 | // } else { 52 | // $this->withTrashed = false; 53 | // } 54 | // } 55 | 56 | return $query; 57 | } 58 | 59 | // public function withTrashed(): MySqlRepository 60 | // { 61 | // $this->withTrashed = true; 62 | // 63 | // return $this; 64 | // } 65 | 66 | public function getAllForGridView(null|int &$total, int $offset = 0, int $count = 0, array $orders = [], array $filters = []): Collection 67 | { 68 | $query = $this->newQuery(); 69 | 70 | $result = $this->processGridViewQuery($query, $total, $offset, $count, $orders, $filters)->get(); 71 | 72 | return $this->factory->makeCollectionOfEntities($result); 73 | } 74 | 75 | public function raw($str) 76 | { 77 | if (is_null($this->alternativeDbConnection)) { 78 | return app('db')->raw($str); 79 | } 80 | return $this->alternativeDbConnection->raw($str); 81 | } 82 | 83 | public function exists($columnValue, $columnName = null) 84 | { 85 | if (is_null($columnName)) { 86 | $columnName = $this->primaryKey; 87 | } 88 | return $this->newQuery()->where($columnName, $columnValue)->exists(); 89 | } 90 | 91 | /** 92 | * this is for validation purpose look at AppServiceProvider 93 | */ 94 | public function valueExists($attribute, $value, $ignoredPrimaryKey = null) 95 | { 96 | $query = $this->newQuery(); 97 | 98 | if ($this->softDelete) { 99 | $query->whereNull('deleted_at'); 100 | } 101 | 102 | $query->where($attribute, $value); 103 | 104 | if (!is_null($ignoredPrimaryKey)) { 105 | $query->where($this->primaryKey, '<>', $ignoredPrimaryKey); 106 | } 107 | 108 | return $query->exists(); 109 | } 110 | 111 | public function updateOrCreate(Entity $model) 112 | { 113 | if ($this->exists($model->getPrimaryKey())) { 114 | $this->update($model); 115 | } else { 116 | $this->create($model); 117 | } 118 | } 119 | 120 | /** 121 | * @param Entity $model 122 | */ 123 | public function createIfNotExists(Entity $model) 124 | { 125 | if (!$this->exists($model->getPrimaryKey())) { 126 | $this->create($model); 127 | } 128 | } 129 | 130 | /** 131 | * It returns maximum row Id 132 | * @return int|mixed 133 | */ 134 | public function getMaxId() 135 | { 136 | $entity = $this->newQuery()->orderByDesc($this->primaryKey)->first(); 137 | if ($entity) { 138 | return $entity->id; 139 | } else { 140 | return 0; 141 | } 142 | } 143 | 144 | protected function processGridViewQuery(Builder $query, null|int &$total, int $offset = 0, int $count = 0, array $orders = [], array $filters = []): Builder 145 | { 146 | if ($orders) { 147 | $query = $this->processOrder($query, $orders); 148 | } 149 | 150 | if ($filters) { 151 | $query = $this->processFilter($query, $filters); 152 | } 153 | 154 | $total = $query->count(); 155 | 156 | if ($count) { 157 | $query->offset($offset); 158 | $query->limit($count); 159 | } 160 | 161 | return $query; 162 | } 163 | 164 | /** 165 | * @param Builder $query 166 | * @param array $orders 167 | * @return Builder 168 | */ 169 | protected function processOrder(Builder $query, array $orders): Builder 170 | { 171 | foreach ($orders as $order) { 172 | $query->orderBy($order->name, $order->type); 173 | } 174 | return $query; 175 | } 176 | 177 | /** 178 | * @param Builder $query 179 | * @param array $filters 180 | * @return Builder 181 | */ 182 | protected function processFilter(Builder $query, array $filters): Builder 183 | { 184 | foreach ($filters as $filter) { 185 | switch (strtolower(Str::snake($filter->operator))) { 186 | case GriewFilterOperator::IS_NULL: 187 | $query->whereNull($filter->name); 188 | break; 189 | case GriewFilterOperator::IS_NOT_NULL: 190 | $query->whereNotNull($filter->name); 191 | break; 192 | case GriewFilterOperator::IS_EQUAL_TO: 193 | if (is_string($filter->operand1) && Str::contains($filter->operand1, '|')) { 194 | // create in functionality with equal string 195 | $arr = array_filter(explode('|', $filter->operand1)); 196 | $query->whereIn($filter->name, $arr); 197 | } else { 198 | $query->where($filter->name, '=', $filter->operand1); 199 | } 200 | break; 201 | case GriewFilterOperator::IS_NOT_EQUAL_TO: 202 | if (is_string($filter->operand1) && Str::contains($filter->operand1, '|')) { 203 | // create in functionality with equal string 204 | $arr = array_filter(explode('|', $filter->operand1)); 205 | $query->whereNotIn($filter->name, $arr); 206 | } else { 207 | $query->where($filter->name, '<>', $filter->operand1); 208 | } 209 | break; 210 | case GriewFilterOperator::START_WITH: 211 | $query->where($filter->name, 'LIKE', $filter->operand1 . '%'); 212 | break; 213 | case GriewFilterOperator::DOES_NOT_CONTAINS: 214 | $query->where($filter->name, 'NOT LIKE', '%' . $filter->operand1 . '%'); 215 | break; 216 | case GriewFilterOperator::CONTAINS: 217 | $query->where($filter->name, 'LIKE', '%' . $filter->operand1 . '%'); 218 | break; 219 | case GriewFilterOperator::ENDS_WITH: 220 | $query->where($filter->name, 'LIKE', '%' . $filter->operand1); 221 | break; 222 | case GriewFilterOperator::IN: 223 | $query->whereIn($filter->name, $filter->operand1); 224 | break; 225 | case GriewFilterOperator::NOT_IN: 226 | $query->whereNotIn($filter->name, $filter->operand1); 227 | break; 228 | case GriewFilterOperator::BETWEEN: 229 | $query->whereBetween($filter->name, array($filter->operand1, $filter->operand2)); 230 | break; 231 | case GriewFilterOperator::IS_AFTER_THAN_OR_EQUAL_TO: 232 | case GriewFilterOperator::IS_GREATER_THAN_OR_EQUAL_TO: 233 | $query->where($filter->name, '>=', $filter->operand1); 234 | break; 235 | case GriewFilterOperator::IS_AFTER_THAN: 236 | case GriewFilterOperator::IS_GREATER_THAN: 237 | $query->where($filter->name, '>', $filter->operand1); 238 | break; 239 | case GriewFilterOperator::IS_LESS_THAN_OR_EQUAL_TO: 240 | case GriewFilterOperator::IS_BEFORE_THAN_OR_EQUAL_TO: 241 | $query->where($filter->name, '<=', $filter->operand1); 242 | break; 243 | case GriewFilterOperator::IS_LESS_THAN: 244 | case GriewFilterOperator::IS_BEFORE_THAN: 245 | $query->where($filter->name, '<', $filter->operand1); 246 | break; 247 | } 248 | } 249 | 250 | return $query; 251 | } 252 | } 253 | -------------------------------------------------------------------------------- /src/Commands/MakeInterfaceRepository.php: -------------------------------------------------------------------------------- 1 | setArguments(); 36 | $filenameWithPath = $this->relativeInterfacePath . $this->interfaceName . '.php'; 37 | 38 | $this->checkAndPrepare($filenameWithPath); 39 | 40 | [ 41 | 'basedContent' => $baseContent, 42 | 'getOneStub' => $getOneStub, 43 | 'getAllStub' => $getAllStub, 44 | 'createFunctionStub' => $createFunctionStub, 45 | 'updateFunctionStub' => $updateFunctionStub, 46 | 'deleteAndUndeleteStub' => $deleteAndUndeleteStub 47 | ] = $this->getStubContents($this->interfaceRepositoryStubsPath); 48 | 49 | $baseContent = $this->writeFunctionOnBaseContent( 50 | $baseContent, $this->writeGetOneFunction($getOneStub, 'id', DataTypeEnum::INTEGER_TYPE) 51 | ); 52 | 53 | $baseContent = $this->writeFunctionOnBaseContent( 54 | $baseContent, $this->writeGetAllFunction($getAllStub, 'id', DataTypeEnum::INTEGER_TYPE) 55 | ); 56 | 57 | $columns = $this->getColumnsOf($this->tableName); 58 | $indexes = $this->extractIndexes($this->tableName); 59 | $baseContent = $this->writeGetFunctionByIndexColumnOnBaseContent($indexes, $columns, $baseContent, $getOneStub, $getAllStub); 60 | $baseContent = $this->writeGetFunctionByForeignKeyOnBaseContent($baseContent, $getOneStub, $getAllStub); 61 | 62 | $allColumns = $columns->pluck('COLUMN_NAME')->toArray(); 63 | $baseContent = $this->setTimestampsColumnOnBaseContent( 64 | $allColumns, $baseContent, $createFunctionStub, $updateFunctionStub, $deleteAndUndeleteStub 65 | ); 66 | 67 | $baseContent = $this->replaceDataOnInterfaceContent($baseContent); 68 | 69 | $this->finalized($filenameWithPath, $this->entityName, $baseContent); 70 | } 71 | 72 | private function writeFunctionOnBaseContent($baseContent, string $writeFunction): string|array 73 | { 74 | return \substr_replace($baseContent, $writeFunction, -2, 0); 75 | } 76 | 77 | private function writeFunction(string $stub, string $columnName, string $attributeType, array $placeHolders): array|string 78 | { 79 | $replaceValues = \array_map(function ($placeholder) use ($columnName, $attributeType) { 80 | 81 | return match ($placeholder) { 82 | '{{ FunctionName }}' => ucfirst(Str::camel($columnName)), 83 | '{{ ColumnName }}' => $columnName, 84 | '{{ AttributeType }}' => $attributeType, 85 | '{{ AttributeName }}' => Str::camel($columnName), 86 | '{{ FunctionNamePlural }}' => ucfirst(Str::plural(Str::camel($columnName))), 87 | '{{ AttributeNamePlural }}' => Str::plural(Str::camel($columnName)), 88 | default => $placeholder, 89 | }; 90 | }, $placeHolders); 91 | 92 | return str_replace($placeHolders, $replaceValues, $stub); 93 | } 94 | 95 | private function writeGetOneFunction(string $getOneStub, string $columnName, string $attributeType): string 96 | { 97 | $placeHolders = ['{{ FunctionName }}', '{{ ColumnName }}', '{{ AttributeType }}', '{{ AttributeName }}']; 98 | return $this->writeFunction($getOneStub, $columnName, $attributeType, $placeHolders); 99 | } 100 | 101 | private function writeGetAllFunction(string $getAllStub, string $columnName, string $attributeType): string 102 | { 103 | $placeHolders = ['{{ FunctionNamePlural }}', '{{ AttributeType }}', '{{ AttributeNamePlural }}']; 104 | return $this->writeFunction($getAllStub, $columnName, $attributeType, $placeHolders); 105 | } 106 | 107 | private function getColumnsOf(string $tableName): Collection 108 | { 109 | $columns = $this->getAllColumnsInTable($tableName); 110 | $this->checkEmpty($columns, $tableName); 111 | 112 | return $columns; 113 | } 114 | 115 | private function checkAndPrepare(string $filenameWithPath): void 116 | { 117 | $this->checkDelete($filenameWithPath, $this->interfaceName, 'Interface'); 118 | $this->checkDirectory($this->relativeInterfacePath); 119 | $this->checkClassExist($this->repositoryNamespace, $this->interfaceName, 'Interface'); 120 | } 121 | 122 | private function setTimestampsColumnOnBaseContent( 123 | array $allColumns, 124 | array|string $baseContent, 125 | bool|string $createFunctionStub, 126 | bool|string $updateFunctionStub, 127 | bool|string $deleteAndUndeleteStub): string|array 128 | { 129 | if (in_array('created_at', $allColumns, true)) { 130 | $baseContent = substr_replace($baseContent, $createFunctionStub, -2, 0); 131 | } 132 | 133 | if (in_array('updated_at', $allColumns, true)) { 134 | $baseContent = substr_replace($baseContent, $updateFunctionStub, -2, 0); 135 | } 136 | 137 | if (in_array('deleted_at', $allColumns, true)) { 138 | $baseContent = substr_replace($baseContent, $deleteAndUndeleteStub, -2, 0); 139 | } 140 | 141 | return $baseContent; 142 | } 143 | 144 | private function getStubContents(string $basePath): array 145 | { 146 | $stubs = [ 147 | 'basedContent' => 'class.stub', 148 | 'getOneStub' => 'getOneBy.stub', 149 | 'getAllStub' => 'getAllBy.stub', 150 | 'createFunctionStub' => 'create.stub', 151 | 'updateFunctionStub' => 'update.stub', 152 | 'deleteAndUndeleteStub' => 'deleteAndUndelete.stub', 153 | ]; 154 | 155 | $stubsContent = []; 156 | 157 | foreach ($stubs as $name => $endWith) { 158 | $stubsContent[$name] = file_get_contents($basePath . $endWith); 159 | } 160 | 161 | return $stubsContent; 162 | } 163 | 164 | private function replaceDataOnInterfaceContent(array|string $baseContent): string|array 165 | { 166 | $placeHolders = [ 167 | '{{ EntityName }}' => $this->entityName, 168 | '{{ EntityNamespace }}' => $this->entityNamespace, 169 | '{{ EntityVariableName }}' => $this->entityVariableName, 170 | '{{ InterfaceRepositoryName }}' => $this->interfaceName, 171 | '{{ RepositoryNamespace }}' => $this->repositoryNamespace 172 | ]; 173 | 174 | return \str_replace(\array_keys($placeHolders), \array_values($placeHolders), $baseContent); 175 | } 176 | 177 | private function writeGetFunctionByIndexColumnOnBaseContent(Collection $indexes, Collection $columns, mixed $baseContent, $getOneStub, $getAllStub): mixed 178 | { 179 | foreach ($indexes as $index) { 180 | $columnInfo = collect($columns)->where('COLUMN_NAME', $index->COLUMN_NAME)->first(); 181 | 182 | $baseContent = $this->writeFunctionOnBaseContent($baseContent, 183 | $this->writeGetOneFunction( 184 | $getOneStub, $index->COLUMN_NAME, $this->getDataType($columnInfo->COLUMN_TYPE, $columnInfo->DATA_TYPE) 185 | ) 186 | ); 187 | 188 | if ($index->Non_unique == 1) { 189 | 190 | $baseContent = $this->writeFunctionOnBaseContent($baseContent, 191 | $this->writeGetOneFunction( 192 | $getAllStub, $index->COLUMN_NAME, $this->getDataType($columnInfo->COLUMN_TYPE, $columnInfo->DATA_TYPE) 193 | ) 194 | ); 195 | } 196 | } 197 | 198 | return $baseContent; 199 | } 200 | 201 | public function writeGetFunctionByForeignKeyOnBaseContent(array|string $baseContent, $getOneStub, $getAllStub): string|array 202 | { 203 | if (empty($this->detectForeignKeys)) { 204 | return $baseContent; 205 | } 206 | 207 | $foreignKeys = $this->extractForeignKeys($this->tableName); 208 | 209 | foreach ($foreignKeys as $_foreignKey) { 210 | 211 | $baseContent = $this->writeFunctionOnBaseContent( 212 | $baseContent, $this->writeGetOneFunction($getOneStub, $_foreignKey->COLUMN_NAME, $this->entityName) 213 | ); 214 | 215 | $baseContent = $this->writeFunctionOnBaseContent( 216 | $baseContent, $this->writeGetAllFunction($getAllStub, $_foreignKey->COLUMN_NAME, $this->entityName) 217 | ); 218 | } 219 | 220 | return $baseContent; 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /src/Creators/CreatorMySqlRepository.php: -------------------------------------------------------------------------------- 1 | repositoryNamespace . '\\' . $this->entityName; 35 | } 36 | 37 | public function createUses(): array 38 | { 39 | return [ 40 | "use $this->entityNamespace\\$this->entityName;", 41 | "use $this->factoryNamespace\\$this->factoryName;", 42 | 'use Illuminate\Support\Collection;', 43 | 'use Eghamat24\DatabaseRepository\Models\Repositories\MySqlRepository;' 44 | ]; 45 | } 46 | 47 | public function getClassName(): string 48 | { 49 | return $this->mysqlRepositoryName; 50 | } 51 | 52 | public function getExtendSection(): string 53 | { 54 | return 'extends MySqlRepository implements ' . $this->interfaceName; 55 | } 56 | 57 | public function createAttributes(): array 58 | { 59 | return []; 60 | } 61 | 62 | public function createFunctions(): array 63 | { 64 | 65 | $stubList = [ 66 | 'baseContent' => 'class.stub', 67 | 'constructContent' => 'construct.stub', 68 | 'getOneStub' => 'getOneBy.stub', 69 | 'getAllStub' => 'getAllBy.stub', 70 | 'createFunctionStub' => 'create.stub', 71 | 'updateFunctionStub' => 'update.stub', 72 | 'deleteStub' => 'delete.stub', 73 | 'undeleteStub' => 'undelete.stub', 74 | 'getterStub' => 'getter.stub', 75 | 'setterStub' => 'setter.stub', 76 | 'timeFieldStub' => 'timeField.stub', 77 | ]; 78 | 79 | $stubContent = []; 80 | foreach ($stubList as $stubKey => $stubName) { 81 | $stubContent[$stubKey] = file_get_contents($this->mysqlRepositoryStubsPath . $stubName); 82 | } 83 | 84 | $hasSoftDelete = in_array('deleted_at', $this->columns->pluck('COLUMN_NAME')->toArray(), true); 85 | 86 | $functions = []; 87 | $functions['__construct'] = $this->getConstruct($this->tableName, $this->factoryName, $hasSoftDelete, $stubContent['constructContent']); 88 | $functions['getOneById'] = $this->writeGetOneFunction($stubContent['getOneStub'], 'id', DataTypeEnum::INTEGER_TYPE); 89 | $functions['getAllByIds'] = $this->writeGetAllFunction($stubContent['getAllStub'], 'id', DataTypeEnum::INTEGER_TYPE); 90 | $columnsInfo = $this->getAllColumnsInTable($this->tableName); 91 | 92 | $indexes = $this->extractIndexes($this->tableName); 93 | foreach ($indexes as $index) { 94 | $columnInfo = collect($columnsInfo)->where('COLUMN_NAME', $index->COLUMN_NAME)->first(); 95 | $indx = 'getOneBy' . ucfirst(Str::camel($index->COLUMN_NAME)); 96 | $functions[$indx] = $this->writeGetOneFunction( 97 | $stubContent['getOneStub'], 98 | $index->COLUMN_NAME, 99 | $this->getDataType($columnInfo->COLUMN_TYPE, $columnInfo->DATA_TYPE) 100 | ); 101 | 102 | if ($index->Non_unique == 1) { 103 | $indx = 'getAllBy' . ucfirst(Str::plural(Str::camel($index->COLUMN_NAME))); 104 | $functions[$indx] = $this->writeGetAllFunction($stubContent['getAllStub'], $index->COLUMN_NAME, $this->entityName); 105 | } 106 | } 107 | 108 | if ($this->detectForeignKeys) { 109 | $foreignKeys = $this->extractForeignKeys($this->tableName); 110 | foreach ($foreignKeys as $_foreignKey) { 111 | $indx = 'getOneBy' . ucfirst(Str::camel($_foreignKey->COLUMN_NAME)); 112 | $functions[$indx] = $this->writeGetOneFunction($stubContent['getOneStub'], $_foreignKey->COLUMN_NAME, $this->entityName); 113 | $indx = 'getAllBy' . ucfirst(Str::plural(Str::camel($_foreignKey->COLUMN_NAME))); 114 | $functions[$indx] = $this->writeGetAllFunction($stubContent['getAllStub'], $_foreignKey->COLUMN_NAME, $this->entityName); 115 | } 116 | } 117 | 118 | $getterFunctions = ''; 119 | $setterFunctions = ''; 120 | $functions = $this->makeCreateFunction($stubContent, $getterFunctions, $setterFunctions, $functions); 121 | 122 | $getterFunctions = ''; 123 | $setterFunctions = ''; 124 | $functions = $this->makeUpdateFunction($stubContent, $getterFunctions, $setterFunctions, $functions); 125 | 126 | // Create "delete" and "undelete" functions if necessary 127 | if ($hasSoftDelete) { 128 | $functions['remove'] = $stubContent['deleteStub']; 129 | $functions['restore'] = $stubContent['undeleteStub']; 130 | } 131 | 132 | foreach ($functions as &$func) { 133 | $func = str_replace(['{{ EntityName }}', '{{ EntityVariableName }}'], 134 | [$this->entityName, $this->entityVariableName], 135 | $func 136 | ); 137 | } 138 | 139 | return $functions; 140 | } 141 | 142 | private function writeGetOneFunction(string $getOneStub, string $columnName, string $attributeType): string 143 | { 144 | return str_replace(['{{ FunctionName }}', '{{ ColumnName }}', '{{ AttributeType }}', '{{ AttributeName }}'], 145 | [ucfirst(Str::camel($columnName)), $columnName, $attributeType, Str::camel($columnName)], 146 | $getOneStub); 147 | } 148 | 149 | private function writeGetAllFunction(string $getOneStub, string $columnName, string $attributeType): string 150 | { 151 | return str_replace(['{{ FunctionNamePlural }}', '{{ ColumnName }}', '{{ AttributeType }}', '{{ AttributeNamePlural }}'], 152 | [ucfirst(Str::plural(Str::camel($columnName))), $columnName, $attributeType, Str::plural(Str::camel($columnName))], 153 | $getOneStub); 154 | } 155 | 156 | private function getConstruct(string $tableName, string $factoryName, bool $hasSoftDelete, string $constructContent) 157 | { 158 | return str_replace( 159 | ['{{ TableName }}', '{{ FactoryName }}', '{{ HasSoftDelete }}'], 160 | [$tableName, $factoryName, $hasSoftDelete ? 'true' : 'false'], 161 | $constructContent); 162 | } 163 | 164 | /** 165 | * @param array $stubContent 166 | * @param string $getterFunctions 167 | * @param string $setterFunctions 168 | * @param array $functions 169 | * @return array 170 | */ 171 | public function makeCreateFunction(array &$stubContent, string &$getterFunctions, string &$setterFunctions, array &$functions): array 172 | { 173 | foreach ($this->columns as $_column) { 174 | if (!in_array($_column->COLUMN_NAME, ['id', 'deleted_at'])) { 175 | $getterFunctions .= trim(str_replace(['{{ ColumnName }}', '{{ AttributeName }}'], [$_column->COLUMN_NAME, Str::camel($_column->COLUMN_NAME)], $stubContent['getterStub'])) . "\n\t\t\t\t"; 176 | } 177 | 178 | if (in_array($_column->COLUMN_NAME, ['created_at', 'updated_at'], true)) { 179 | $setterFunctions .= trim(str_replace('{{ AttributeName }}', Str::camel($_column->COLUMN_NAME), $stubContent['setterStub'])) . "\n\t\t"; 180 | } 181 | } 182 | 183 | $createFunctionStub = str_replace(["{{ GetterFunctions }}", "{{ SetterFunctions }}"], 184 | [trim(substr($getterFunctions, 0, -1)), trim(substr($setterFunctions, 0, -1))], 185 | $stubContent['createFunctionStub'] 186 | ); 187 | 188 | $functions['create'] = $createFunctionStub; 189 | 190 | return $functions; 191 | } 192 | 193 | /** 194 | * @param array $stubContent 195 | * @param string $getterFunctions 196 | * @param string $setterFunctions 197 | * @param array $functions 198 | * @return array 199 | */ 200 | public function makeUpdateFunction(array &$stubContent, string &$getterFunctions, string &$setterFunctions, array &$functions): array 201 | { 202 | foreach ($this->columns as $_column) { 203 | 204 | if (!in_array($_column->COLUMN_NAME, ['id', 'created_at', 'deleted_at'])) { 205 | $getterFunctions .= trim(str_replace(['{{ ColumnName }}', '{{ AttributeName }}'], [$_column->COLUMN_NAME, Str::camel($_column->COLUMN_NAME)], $stubContent['getterStub'])) . "\n\t\t\t\t";; 206 | } 207 | 208 | if ($_column->COLUMN_NAME === 'updated_at') { 209 | $setterFunctions .= trim(str_replace('{{ AttributeName }}', Str::camel($_column->COLUMN_NAME), $stubContent['setterStub'])). "\n\t\t";; 210 | } 211 | } 212 | 213 | $updateFunctionStub = str_replace(['{{ GetterFunctions }}', '{{ UpdateFieldSetter }}'], 214 | [trim(substr($getterFunctions, 0, -1)), trim(substr($setterFunctions, 0, -1))], 215 | $stubContent['updateFunctionStub'] 216 | ); 217 | 218 | $functions['update'] = $updateFunctionStub; 219 | 220 | return $functions; 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /src/Creators/CreatorRepository.php: -------------------------------------------------------------------------------- 1 | getRedisCashFunctionGetOneBy($this->strategyName); 49 | $returnResult = 'return $entity;'; 50 | } elseif ($functionName === 'getAllBy') { 51 | $functionReturnType = 'Collection'; 52 | $functionName .= ucfirst(Str::plural(Str::camel($columnName))); 53 | $columnName = Str::plural(Str::camel($columnName)); 54 | $redisCashFunction = $this->getRedisCashFunctionGetAllBy($this->strategyName); 55 | $returnResult = 'return $entities;'; 56 | } elseif ($functionName === 'create') { 57 | $functionReturnType = $attributeType; 58 | $redisCashFunction = $this->getRedisCashFunctionCreate($this->strategyName); 59 | $returnResult = 'return $this->{{ SqlRepositoryVariable }}->{{ FunctionName }}(${{ AttributeName }});'; 60 | } elseif (in_array($functionName, ['update', 'remove', 'restore'])) { 61 | $functionReturnType = 'int'; 62 | $redisCashFunction = $this->getRedisCashFunctionUpdate($this->strategyName); 63 | $returnResult = 'return $this->{{ SqlRepositoryVariable }}->{{ FunctionName }}(${{ AttributeName }});'; 64 | } 65 | 66 | $redisCashFunction = str_replace(['{{ FunctionName }}', '{{ ColumnName }}', '{{ ColumnNameSingle }}'], [$functionName, $columnName, $columnNameSingle], $redisCashFunction); 67 | 68 | $returnResult = str_replace(['{{ SqlRepositoryVariable }}', '{{ FunctionName }}', '{{ AttributeName }}'], [$this->sqlRepositoryVariable, $functionName, Str::camel($columnName)], $returnResult); 69 | 70 | return str_replace(['{{ FunctionName }}', '{{ AttributeType }}', '{{ AttributeName }}', '{{ FunctionReturnType }}', '{{redisFunction}}', '{{returnResult}}'], 71 | [$functionName, $attributeType, Str::camel($columnName), $functionReturnType, $redisCashFunction, $returnResult], 72 | $functionStub); 73 | } 74 | 75 | private function writeSqlAttribute(string $attributeStub, string $sqlRepositoryVariable, string $sqlRepositoryName): string 76 | { 77 | return str_replace(['{{ SqlRepositoryVariable }}', '{{ SqlRepositoryName }}'], 78 | [$sqlRepositoryVariable, $sqlRepositoryName], 79 | $attributeStub); 80 | } 81 | 82 | public function writeRedisAttribute(string $attributeStub, string $redisRepositoryVariable, string $redisRepositoryName): string 83 | { 84 | return str_replace(['{{ RedisRepositoryVariable }}', '{{ RedisRepositoryName }}'], 85 | [$redisRepositoryVariable, $redisRepositoryName], 86 | $attributeStub); 87 | } 88 | 89 | public function getNameSpace(): string 90 | { 91 | return $this->repositoryNamespace . '\\' . $this->entityName; 92 | } 93 | 94 | public function createUses(): array 95 | { 96 | return [ 97 | "use $this->entityNamespace\\$this->entityName;", 98 | "use Illuminate\Support\Collection;" 99 | ]; 100 | } 101 | 102 | public function getClassName(): string 103 | { 104 | return $this->repositoryName; 105 | } 106 | 107 | public function getExtendSection(): string 108 | { 109 | return 'implements ' . $this->interfaceName; 110 | } 111 | 112 | public function createAttributes(): array 113 | { 114 | $attributeSqlStub = file_get_contents($this->repositoryStubsPath . 'attribute.sql.stub'); 115 | $attributes = []; 116 | $attributes['repository'] = 'private ' . $this->interfaceName . ' $repository;'; 117 | $attributes['redisRepository'] = 'private ' . $this->redisRepositoryName . ' $redisRepository;'; 118 | return $attributes; 119 | } 120 | 121 | public function createFunctions(): array 122 | { 123 | $constructStub = file_get_contents($this->repositoryStubsPath . 'construct.stub'); 124 | $functionStub = file_get_contents($this->repositoryStubsPath . 'function.stub'); 125 | $setterSqlStub = file_get_contents($this->repositoryStubsPath . 'setter.sql.stub'); 126 | $functions = []; 127 | $functions['__construct'] = $this->getConstruct($setterSqlStub, $constructStub); 128 | $functions['__construct'] = $this->getConstructRedis($setterSqlStub, $constructStub); 129 | $functions['getOneById'] = $this->writeFunction($functionStub, 'getOneBy', 'id', 'int'); 130 | $functions['getAllByIds'] = $this->writeFunction($functionStub, 'getAllBy', 'id', 'array'); 131 | $columnsInfo = $this->getAllColumnsInTable($this->tableName); 132 | 133 | $indexes = $this->extractIndexes($this->tableName); 134 | foreach ($indexes as $index) { 135 | $columnInfo = collect($columnsInfo)->where('COLUMN_NAME', $index->COLUMN_NAME)->first(); 136 | $fun_name = ucfirst(Str::camel($index->COLUMN_NAME)); 137 | $functions['getOneBy' . $fun_name] = $this->writeFunction($functionStub, 'getOneBy', $index->COLUMN_NAME, $this->getDataType($columnInfo->COLUMN_TYPE, $columnInfo->DATA_TYPE)); 138 | 139 | if ($index->Non_unique == 1) { 140 | $fun_name = ucfirst(Str::plural(Str::camel($index->COLUMN_NAME))); 141 | $functions['getAllBy' . $fun_name] = $this->writeFunction($functionStub, 'getAllBy', $index->COLUMN_NAME, 'array'); 142 | } 143 | } 144 | if ($this->detectForeignKeys) { 145 | $foreignKeys = $this->extractForeignKeys($this->tableName); 146 | 147 | foreach ($foreignKeys as $_foreignKey) { 148 | $fun_name = ucfirst(Str::camel($_foreignKey->COLUMN_NAME)); 149 | $functions['getOneBy' . $fun_name] = $this->writeFunction($functionStub, 'getOneBy', $_foreignKey->COLUMN_NAME, 'int'); 150 | $fun_name = ucfirst(Str::plural(Str::camel($_foreignKey->COLUMN_NAME))); 151 | $functions['getAllBy' . $fun_name] = $this->writeFunction($functionStub, 'getAllBy', $_foreignKey->COLUMN_NAME, 'array'); 152 | } 153 | } 154 | $functions['create'] = $this->writeFunction($functionStub, 'create', $this->entityVariableName, $this->entityName); 155 | $functions['update'] = $this->writeFunction($functionStub, 'update', $this->entityVariableName, $this->entityName); 156 | if (in_array('deleted_at', $this->columns->pluck('COLUMN_NAME')->toArray(), true)) { 157 | $functions['remove'] = $this->writeFunction($functionStub, 'remove', $this->entityVariableName, $this->entityName); 158 | $functions['restore'] = $this->writeFunction($functionStub, 'restore', $this->entityVariableName, $this->entityName); 159 | } 160 | foreach ($functions as &$func) { 161 | $func = str_replace(["{{ SqlRepositoryVariable }}", '{{ SqlRepositoryName }}', '{{ EntityName }}'], 162 | [$this->sqlRepositoryVariable, $this->sqlRepositoryName, $this->entityName], 163 | $func 164 | ); 165 | } 166 | return $functions; 167 | } 168 | 169 | public function getConstruct(string $setterSqlStub, string $constructStub) 170 | { 171 | return str_replace("{{ Setters }}", trim($this->writeSqlAttribute($setterSqlStub, $this->sqlRepositoryVariable, $this->sqlRepositoryName, $this->redisRepositoryVariable, $this->redisRepositoryName)), $constructStub); 172 | } 173 | 174 | public function getConstructRedis(string $setterSqlStub, string $constructStub) 175 | { 176 | return str_replace("{{ Setters }}", trim($this->writeRedisAttribute($setterSqlStub, $this->redisRepositoryVariable, $this->redisRepositoryName)), $constructStub); 177 | } 178 | 179 | private function getRedisCashFunctionGetOneBy($strategyName) 180 | { 181 | $repositoryRedisStubsPath = __DIR__ . '/../../' . 'stubs/Repositories/Redis/getOneBy/base.'; 182 | return match ($strategyName) { 183 | 'QueryCacheStrategy' => file_get_contents($repositoryRedisStubsPath . 'query_cache_strategy.stub'), 184 | 'SingleKeyCacheStrategy' => file_get_contents($repositoryRedisStubsPath . 'single_key_cache_strategy.stub'), 185 | 'ClearableTemporaryCacheStrategy' => file_get_contents($repositoryRedisStubsPath . 'clearable_temporary_cache_strategy.stub'), 186 | 'TemporaryCacheStrategy' => file_get_contents($repositoryRedisStubsPath . 'temporary_cache_strategy.stub'), 187 | }; 188 | } 189 | 190 | private function getRedisCashFunctionGetAllBy($strategyName) 191 | { 192 | $repositoryRedisStubsPath = __DIR__ . '/../../' . 'stubs/Repositories/Redis/getAllBy/base.'; 193 | return match ($strategyName) { 194 | 'QueryCacheStrategy' => file_get_contents($repositoryRedisStubsPath . 'query_cache_strategy.stub'), 195 | 'SingleKeyCacheStrategy' => file_get_contents($repositoryRedisStubsPath . 'single_key_cache_strategy.stub'), 196 | 'ClearableTemporaryCacheStrategy' => file_get_contents($repositoryRedisStubsPath . 'clearable_temporary_cache_strategy.stub'), 197 | 'TemporaryCacheStrategy' => file_get_contents($repositoryRedisStubsPath . 'temporary_cache_strategy.stub'), 198 | }; 199 | } 200 | 201 | private function getRedisCashFunctionCreate($strategyName) 202 | { 203 | $repositoryRedisStubsPath = __DIR__ . '/../../' . 'stubs/Repositories/Redis/create/base.'; 204 | return match ($strategyName) { 205 | 'QueryCacheStrategy' => file_get_contents($repositoryRedisStubsPath . 'query_cache_strategy.stub'), 206 | 'SingleKeyCacheStrategy' => file_get_contents($repositoryRedisStubsPath . 'single_key_cache_strategy.stub'), 207 | 'ClearableTemporaryCacheStrategy' => file_get_contents($repositoryRedisStubsPath . 'clearable_temporary_cache_strategy.stub'), 208 | 'TemporaryCacheStrategy' => file_get_contents($repositoryRedisStubsPath . 'temporary_cache_strategy.stub'), 209 | }; 210 | } 211 | 212 | private function getRedisCashFunctionUpdate($strategyName) 213 | { 214 | $repositoryRedisStubsPath = __DIR__ . '/../../' . 'stubs/Repositories/Redis/update/base.'; 215 | return match ($strategyName) { 216 | 'QueryCacheStrategy' => file_get_contents($repositoryRedisStubsPath . 'query_cache_strategy.stub'), 217 | 'SingleKeyCacheStrategy' => file_get_contents($repositoryRedisStubsPath . 'single_key_cache_strategy.stub'), 218 | 'ClearableTemporaryCacheStrategy' => file_get_contents($repositoryRedisStubsPath . 'clearable_temporary_cache_strategy.stub'), 219 | 'TemporaryCacheStrategy' => file_get_contents($repositoryRedisStubsPath . 'temporary_cache_strategy.stub'), 220 | }; 221 | } 222 | } 223 | --------------------------------------------------------------------------------