Skip to content

Commit

Permalink
feat builder template
Browse files Browse the repository at this point in the history
  • Loading branch information
zds-s committed Jan 13, 2024
1 parent 31e2a42 commit 6e1c026
Show file tree
Hide file tree
Showing 9 changed files with 210 additions and 33 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
},
"extra": {
"hyperf": {
"config": "Mine\\ServiceConfigProvider"
"config": "Mine\\Generator\\GeneratorConfigProvider"
}
}
}
11 changes: 10 additions & 1 deletion src/Abstracts/AbstractCurdService.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,23 @@
use Mine\Contract\SaveOrUpdateMapperContract;
use Mine\Contract\UpdateMapperContract;
use Mine\ServiceException;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

/**
* crud service
* @template Mapper
*/
abstract class AbstractCurdService
{
/**
* @return Mapper|PageMapperContract|DeleteMapperContract|SaveOrUpdateMapperContract|UpdateMapperContract
* @throws ServiceException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function getMapper()
: PageMapperContract | DeleteMapperContract | SaveOrUpdateMapperContract | UpdateMapperContract
: UpdateMapperContract|PageMapperContract|SaveOrUpdateMapperContract|DeleteMapperContract
{
$mapper = null;
if (property_exists($this,'mapper')){
Expand Down
10 changes: 9 additions & 1 deletion src/Abstracts/Mapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,19 @@
use Mine\Annotation\CrudModelCollector;
use Mine\ServiceException;

/**
* @template ModelClass
*/
abstract class Mapper
{
/**
* @var string|class-string<ModelClass>
*/
protected string $model;

/**
* 获取模型类名.
* @return string|Model
* @return ModelClass
* @throws ServiceException
*/
public function getModel(): string
Expand Down
4 changes: 2 additions & 2 deletions src/Annotation/Mapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
class Mapper extends AbstractAnnotation
{
public function __construct(
public string $mapper
public string $value
){}

public function collectClass(string $className): void
{
CrudModelCollector::collectMapper($className,$this->mapper);
CrudModelCollector::collectMapper($className,$this->value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
use Hyperf\Di\Annotation\AbstractAnnotation;

#[Attribute(Attribute::TARGET_CLASS)]
class mapperModel extends AbstractAnnotation
class MapperModel extends AbstractAnnotation
{
public function __construct(
public string $model
Expand Down
170 changes: 164 additions & 6 deletions src/Command/MineGenMapperCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,172 @@

namespace Mine\Command;

use Composer\InstalledVersions;
use Hyperf\Command\Command;
use Hyperf\Database\Model\Builder;
use Hyperf\DbConnection\Model\Model;
use Mine\Abstracts\CrudMapper;
use Mine\Abstracts\Mapper;
use Mine\Annotation\MapperModel;
use Mine\Contract\DeleteMapperContract;
use Mine\Contract\PageMapperContract;
use Mine\Contract\SaveOrUpdateMapperContract;
use Mine\Contract\UpdateMapperContract;
use Mine\Traits\DeleteMapperTrait;
use Mine\Traits\SaveOrUpdateMapperTrait;
use Mine\Traits\SelectMapperTrait;
use Mine\Traits\UpdateMapperTrait;
use Override;
use PhpParser\Builder\Class_;
use PhpParser\Builder\Namespace_;
use PhpParser\BuilderFactory;
use PhpParser\Node\Arg;
use PhpParser\Node\Attribute;
use PhpParser\Node\AttributeGroup;
use PhpParser\Node\Expr\AssignOp\Concat;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Name;
use PhpParser\Node\Scalar\MagicConst;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt;
use PhpParser\ParserFactory;
use PhpParser\PrettyPrinter\Standard;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use function Hyperf\Support\class_basename;

#[\Hyperf\Command\Annotation\Command]
class MineGenMapperCommand extends Command
{
protected ?string $signature = 'mine:gen-mapper
{path: The generated mapper root directory}
{--model=: The class name or absolute path of the model}
{--mode: Based on which strategy, the default is to only generate query contracts}
{--search-params: Field name to generate query conditions}
{--sort-field: sort fields,like id desc,created_at,desc}';
protected function configure()
{
$this->setDescription('快速生成 mapper');
$this->setName('mine:gen-mapper');
$this->addOption('model','model',InputOption::VALUE_REQUIRED,'model class');
$this->addOption('name','name',InputOption::VALUE_NONE,'build file name');
$this->addOption('path','path',InputOption::VALUE_NONE,'build path');
$this->addOption('mode','mode',InputOption::VALUE_NONE,'crud,get,set,up,del default = crud');
}

#[Override]
public function __invoke(): void
{
$model = $this->input->getOption('model');
if (empty($model)){
$this->error('no model');
return;
}
if (!str_contains($model,'App')){
$model = 'App\\Model\\' . $model;
}
if (!class_exists($model)){
$this->output->error('model not found');
return;
}
if (!$this->input->getOption('name')){
$name = class_basename($model).'Mapper';
}else{
$name = $this->input->getOption('name');
}
if (!$this->hasOption('path')){
$path = BASE_PATH.'/app/Mapper';
$namespace = 'App\\Mapper';
is_dir($path) || mkdir($path, 0777, true) || is_dir($path);
}else{
$path = $this->input->getOption('path');
$namespace = 'App\\Mapper\\'.str_replace('/','\\',$path);
$path = BASE_PATH.DIRECTORY_SEPARATOR.$path;
}
$filepath = $path.DIRECTORY_SEPARATOR.$name.'.php';
if (!$this->input->getOption('mode')){
$mode = ['all'];
}else{
$mode = explode(',',$this->input->getOption('mode'));
}

$factory = new BuilderFactory();
if (file_exists($filepath)) {
$this->error('now not reactor');
return;
}
$node=$this->build($factory,$mode,$model,$namespace,$name);
$prettyPrinter = new Standard();
$fileBody = $prettyPrinter->prettyPrintFile($node);
var_dump($fileBody);
file_put_contents($filepath,$fileBody);
}

public function build(BuilderFactory $factory,array $mode,string $model,string $namespace,$mapperName): array
{
$node = $factory->namespace($namespace)
->addStmts([
$factory->use($model)->as('Model'),
$factory->use(Mapper::class),
$factory->use(MapperModel::class),
]);
$class = $factory->class($mapperName)
->setDocComment(<<<DOCUMENT
/**
* @implements Mapper<Model>
*/
DOCUMENT
);
$class->addAttribute(new AttributeGroup([
new Attribute(new Name('MapperModel'),[new Arg(new ClassConstFetch(new Name('Model'),'class'))])
]));
if (in_array('all',$mode,true)){
$class->extend(new Name('Crud'));
$class->addStmt($factory
->method('handleSearch')
->makeProtected()
->addParams([
$factory->param('params')->setType('array')->getNode(),
$factory->param('query')
->setType(new Name\FullyQualified(Builder::class))
->getNode()
])
->addStmt(
new Stmt\Return_(new Variable('query'))
)
->setReturnType(new Name\FullyQualified(Builder::class))
);
$node->addStmts([
$factory->use(CrudMapper::class)->as('Crud'),
$class,
]);
}else{
$node->addStmts([
$factory->use(Mapper::class),
]);
foreach ($mode as $m){
if ($m === 'select'){
$node->addStmt($factory->use(PageMapperContract::class)->as('SelectContract'));
$node->addStmt($factory->use(SelectMapperTrait::class)->as('SelectTrait'));
$class->implement('SelectContract');
$class->addStmt($factory->useTrait('SelectTrait'));
}
if ($m === 'save'){
$node->addStmt($factory->use(SaveOrUpdateMapperContract::class)->as('SaveContract'));
$node->addStmt($factory->use(SaveOrUpdateMapperTrait::class)->as('SaveTrait'));
$class->implement('SaveContract');
$class->addStmt($factory->useTrait('SaveTrait'));
}
if ($m === 'update'){
$node->addStmt($factory->use(UpdateMapperContract::class)->as('UpdateContract'));
$node->addStmt($factory->use(UpdateMapperTrait::class)->as('UpdateTrait'));
$class->implement('UpdateContract');
$class->addStmt($factory->useTrait('UpdateTrait'));
}
if ($m === 'delete'){
$node->addStmt($factory->use(DeleteMapperContract::class)->as('DeleteContract'));
$node->addStmt($factory->use(DeleteMapperTrait::class)->as('DeleteTrait'));
$class->implement('DeleteContract');
$class->addStmt($factory->useTrait('DeleteTrait'));
}
}
$node->addStmt($class);
}
return $node->getNode()->stmts;
}
}
14 changes: 8 additions & 6 deletions src/Command/MineGenServiceCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,11 @@
namespace Mine\Command;

use Hyperf\Command\Command;
use Symfony\Component\Console\Input\InputOption;

#[\Hyperf\Command\Annotation\Command]
class MineGenServiceCommand extends Command
{
protected ?string $signature = 'mine:gen-crud-service
{path: the base path of project}
{--model=: The class name or absolute path of the model}
{--mode: Based on which strategy, the default is to only generate query contracts}
{--search-params: Field name to generate query conditions}
{--sort-field: sort fields,like id desc,created_at,desc}';

public function handle()
{
Expand All @@ -35,5 +31,11 @@ public function handle()
protected function configure()
{
$this->setDescription('基于 Ast语法树解析 快速生成Service');
$this->setDescription('快速生成 mapper');
$this->setName('mine:gen-service');
$this->addOption('name','n',InputOption::VALUE_NONE,'build file name');
$this->addOption('path','p',InputOption::VALUE_NONE,'build path');
$this->addOption('model','mo',InputOption::VALUE_REQUIRED,'model class');
}

}
10 changes: 5 additions & 5 deletions src/Contract/PageMapperContract.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,23 @@ interface PageMapperContract
{
/**
* 列表查询.
* @param mixed $params 查询条件
* @param array $params 查询条件
* @param int $page 页码
* @param int $size 页数
*/
public function page(mixed $params = null, int $page = 1, int $size = 10): LengthAwarePaginatorInterface;
public function page(array $params = [], int $page = 1, int $size = 10): LengthAwarePaginatorInterface;

/**
* 查询总记录数.
* @param null|mixed $params 查询条件
* @param array $params 查询条件
*/
public function count(mixed $params = null): int;
public function count(array $params = []): int;

/**
* 查询所有列表.
* @return Collection<string,T>
*/
public function list(mixed $params): Collection;
public function list(array $params = []): Collection;

/**
* 根据主键查询一条记录.
Expand Down
20 changes: 10 additions & 10 deletions src/Traits/SelectMapperTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,33 +24,33 @@ protected function handleSelect(Builder $query): Builder
/**
* @throws ServiceException
*/
public function page(mixed $params = null, int $page = 1, int $size = 10): LengthAwarePaginatorInterface
public function page(array $params = [], int $page = 1, int $size = 10): LengthAwarePaginatorInterface
{
return $this->handleSearch(
$params,
$this->handleSelect($this->preQuery())
$this->handleSelect($this->preQuery()),
$params
)->paginate(perPage: $size, page: $page);
}

/**
* @throws ServiceException
*/
public function count(mixed $params = null): int
public function count(array $params = []): int
{
return $this->handleSearch(
$params,
$this->preQuery()
$this->preQuery(),
$params
)->count();
}

/**
* @throws ServiceException
*/
public function list(mixed $params): Collection
public function list(array $params = []): Collection
{
return $this->handleSearch(
$params,
$this->handleSelect($this->preQuery())
$this->handleSelect($this->preQuery()),
$params
)->get();
}

Expand All @@ -74,7 +74,7 @@ protected function getSelectFields(): array
/**
* 查询处理.
*/
abstract protected function handleSearch(array $params, Builder $query): Builder;
abstract protected function handleSearch(Builder $query,array $params = []): Builder;

/**
* initialization DbBuilder.
Expand Down

0 comments on commit 6e1c026

Please sign in to comment.