Skip to content

Commit f9fe254

Browse files
committed
feat(HasOptions): Add 'get' method support for dynamic options
- Include 'get' prefix in dynamic method handling in HasOptions trait - Add doc comment template for 'get' methods in AddHasOptionsDocCommentRector - Improve usability by allowing retrieval of options using dynamic method calls
1 parent c5a5c3d commit f9fe254

File tree

6 files changed

+94
-20
lines changed

6 files changed

+94
-20
lines changed

baselines/loader.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# total 4 errors
1+
# total 3 errors
22
includes:
33
- disallowed.function.neon
44
- new.static.neon
Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
1-
# total 2 errors
1+
# total 1 error
22

33
parameters:
44
ignoreErrors:
55
-
66
message: '#^Parameters should have "array" types as the only types passed to this method$#'
77
count: 1
88
path: ../src/Soar.php
9-
10-
-
11-
message: '#^Parameters should have "string\|string\|null" types as the only types passed to this method$#'
12-
count: 1
13-
path: ../src/Soar.php

phpstan.neon

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ parameters:
5151
narrow_param: true
5252
narrow_return: true
5353
null_over_false: true
54-
no_mixed: true
54+
no_mixed: false
5555
no_mixed_property: true
56-
no_mixed_caller: true
56+
no_mixed_caller: false
5757
disallowedFunctionCalls:
5858
-
5959
function: 'env()'
@@ -67,14 +67,14 @@ parameters:
6767
ignoreErrors:
6868
- identifier: argument.templateType
6969
# - identifier: cast.string
70-
# - identifier: method.nonObject
7170
# - identifier: return.void
7271
# - identifier: typePerfect.noMixedMethodCaller
7372
- identifier: argument.type
7473
- identifier: binaryOp.invalid
7574
- identifier: encapsedStringPart.nonString
7675
- identifier: logicalAnd.resultUnused
76+
- identifier: method.nonObject
7777
- identifier: missingType.generics
7878
- identifier: missingType.iterableValue
7979
- identifier: return.type
80-
- identifier: symplify.noDynamicName
80+
- identifier: symplify.noDynamicName

src/Concerns/ConcreteScores.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public function markdownScores(array|string $sqls): string
7171
public function scores(array|string $sqls): string
7272
{
7373
if (\is_array($sqls)) {
74-
$sqls = implode($this->getDelimiter(), $sqls);
74+
$sqls = implode($this->getDelimiter(';'), $sqls);
7575
}
7676

7777
return $this->clone()->withQuery($sqls)->run();

src/Concerns/HasOptions.php

Lines changed: 78 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?php
22

3+
/** @noinspection LongLine */
34
/** @noinspection PhpFullyQualifiedNameUsageInspection */
45

56
declare(strict_types=1);
@@ -172,6 +173,82 @@
172173
* @method \Guanguans\SoarPHP\Soar withUniqueKeyPrefix(string $uniqueKeyPrefix) // UkPrefix (default "uk_")
173174
* @method \Guanguans\SoarPHP\Soar withVerbose(bool $verbose) // Verbose
174175
* @method \Guanguans\SoarPHP\Soar withVersion(null|bool $version) // Print version info
176+
* @method null|string getConfig(mixed $default = null) // Config file path
177+
* @method null|array|string getTestDsn(mixed $default = null) // TestDSN, 测试环境数据库配置, username:********@tcp(ip:port)/schema (default "tcp/information_schema?timeout=3s&charset=utf8")
178+
* @method null|array|string getOnlineDsn(mixed $default = null) // OnlineDSN, 线上环境数据库配置, username:********@tcp(ip:port)/schema (default "tcp/information_schema?timeout=3s&charset=utf8")
179+
* @method null|bool getAllowOnlineAsTest(mixed $default = null) // AllowOnlineAsTest, 允许线上环境也可以当作测试环境
180+
* @method null|string getBlacklist(mixed $default = null) // 指定 blacklist 配置文件的位置,文件中的 SQL 不会被评审。一行一条SQL,可以是指纹,也可以是正则
181+
* @method null|bool getExplain(mixed $default = null) // Explain, 是否开启Explain执行计划分析 (default true)
182+
* @method null|array|string getIgnoreRules(mixed $default = null) // IgnoreRules, 忽略的优化建议规则 (default "COL.011")
183+
* @method null|int getLogLevel(mixed $default = null) // LogLevel, 日志级别, [0:Emergency, 1:Alert, 2:Critical, 3:Error, 4:Warning, 5:Notice, 6:Informational, 7:Debug] (default 3)
184+
* @method null|string getLogOutput(mixed $default = null) // LogOutput, 日志输出位置 (default "soar.log")
185+
* @method null|string getReportType(mixed $default = null) // ReportType, 优化建议输出格式,目前支持: json, text, markdown, html等 (default "markdown")
186+
* @method null|array|string getAllowCharsets(mixed $default = null) // AllowCharsets (default "utf8,utf8mb4")
187+
* @method null|array|string getAllowCollates(mixed $default = null) // AllowCollates
188+
* @method null|bool getAllowDropIndex(mixed $default = null) // AllowDropIndex, 允许输出删除重复索引的建议
189+
* @method null|array|string getAllowEngines(mixed $default = null) // AllowEngines (default "innodb")
190+
* @method null|bool getCheckConfig(mixed $default = null) // Check configs
191+
* @method null|bool getCleanupTestDatabase(mixed $default = null) // 单次运行清理历史1小时前残余的测试库。
192+
* @method null|array|string getColumnNotAllowType(mixed $default = null) // ColumnNotAllowType (default "boolean")
193+
* @method null|string getDelimiter(mixed $default = null) // Delimiter, SQL分隔符 (default ";")
194+
* @method null|bool getDropTestTemporary(mixed $default = null) // DropTestTemporary, 是否清理测试环境产生的临时库表 (default true)
195+
* @method null|bool getDryRun(mixed $default = null) // 是否在预演环境执行 (default true)
196+
* @method null|string getExplainFormat(mixed $default = null) // ExplainFormat [json, traditional] (default "traditional")
197+
* @method null|float|int getExplainMaxFiltered(mixed $default = null) // ExplainMaxFiltered, filtered大于该配置给出警告 (default 100)
198+
* @method null|int getExplainMaxKeys(mixed $default = null) // ExplainMaxKeyLength, 最大key_len (default 3)
199+
* @method null|int getExplainMaxRows(mixed $default = null) // ExplainMaxRows, 最大扫描行数警告 (default 10000)
200+
* @method null|int getExplainMinKeys(mixed $default = null) // ExplainMinPossibleKeys, 最小possible_keys警告
201+
* @method null|string getExplainSqlReportType(mixed $default = null) // ExplainSQLReportType [pretty, sample, fingerprint] (default "pretty")
202+
* @method null|string getExplainType(mixed $default = null) // ExplainType [extended, partitions, traditional] (default "extended")
203+
* @method null|array|string getExplainWarnAccessType(mixed $default = null) // ExplainWarnAccessType, 哪些access type不建议使用 (default "ALL")
204+
* @method null|array|string getExplainWarnExtra(mixed $default = null) // ExplainWarnExtra, 哪些extra信息会给警告 (default "Using temporary,Using filesort")
205+
* @method null|array|string getExplainWarnScalability(mixed $default = null) // ExplainWarnScalability, 复杂度警告名单, 支持O(n),O(log n),O(1),O(?) (default "O(n)")
206+
* @method null|array|string getExplainWarnSelectType(mixed $default = null) // ExplainWarnSelectType, 哪些select_type不建议使用
207+
* @method null|bool getHelp(mixed $default = null) // Help
208+
* @method null|string getIndexPrefix(mixed $default = null) // IdxPrefix (default "idx_")
209+
* @method null|bool getListHeuristicRules(mixed $default = null) // ListHeuristicRules, 打印支持的评审规则列表
210+
* @method null|bool getListReportTypes(mixed $default = null) // ListReportTypes, 打印支持的报告输出类型
211+
* @method null|bool getListRewriteRules(mixed $default = null) // ListRewriteRules, 打印支持的重写规则列表
212+
* @method null|bool getListTestSqls(mixed $default = null) // ListTestSqls, 打印测试case用于测试
213+
* @method null|bool getLogErrStacks(mixed $default = null) // log stack traces for errors
214+
* @method null|int|string getLogRotateMaxSize(mixed $default = null) // size in bytes at which logs are rotated (glog.MaxSize) (default 1887436800)
215+
* @method null|int getMarkdownExtensions(mixed $default = null) // MarkdownExtensions, markdown 转 html支持的扩展包, 参考blackfriday (default 94)
216+
* @method null|int getMarkdownHtmlFlags(mixed $default = null) // MarkdownHTMLFlags, markdown 转 html 支持的 flag, 参考blackfriday
217+
* @method null|int getMaxColumnCount(mixed $default = null) // MaxColCount, 单表允许的最大列数 (default 40)
218+
* @method null|int getMaxDistinctCount(mixed $default = null) // MaxDistinctCount, 单条 SQL 中 Distinct 的最大数量 (default 5)
219+
* @method null|int getMaxGroupByColsCount(mixed $default = null) // MaxGroupByColsCount, 单条 SQL 中 GroupBy 包含列的最大数量 (default 5)
220+
* @method null|int getMaxInCount(mixed $default = null) // MaxInCount, IN()最大数量 (default 10)
221+
* @method null|int getMaxIndexBytes(mixed $default = null) // MaxIdxBytes, 索引总长度限制 (default 3072)
222+
* @method null|int getMaxIndexBytesPercolumn(mixed $default = null) // MaxIdxBytesPerColumn, 索引中单列最大字节数 (default 767)
223+
* @method null|int getMaxIndexColsCount(mixed $default = null) // MaxIdxColsCount, 复合索引中包含列的最大数量 (default 5)
224+
* @method null|int getMaxIndexCount(mixed $default = null) // MaxIdxCount, 单表最大索引个数 (default 10)
225+
* @method null|int getMaxJoinTableCount(mixed $default = null) // MaxJoinTableCount, 单条 SQL 中 JOIN 表的最大数量 (default 5)
226+
* @method null|int getMaxPrettySqlLength(mixed $default = null) // MaxPrettySQLLength, 超出该长度的SQL会转换成指纹输出 (default 1024)
227+
* @method null|int getMaxQueryCost(mixed $default = null) // MaxQueryCost, last_query_cost 超过该值时将给予警告 (default 9999)
228+
* @method null|int getMaxSubqueryDepth(mixed $default = null) // MaxSubqueryDepth (default 5)
229+
* @method null|int getMaxTextColsCount(mixed $default = null) // MaxTextColsCount, 表中含有的 text/blob 列的最大数量 (default 2)
230+
* @method null|int getMaxTotalRows(mixed $default = null) // MaxTotalRows, 计算散粒度时,当数据行数大于MaxTotalRows即开启数据库保护模式,不计算散粒度 (default 9999999)
231+
* @method null|int getMaxValueCount(mixed $default = null) // MaxValueCount, INSERT/REPLACE 单次批量写入允许的行数 (default 100)
232+
* @method null|int getMaxVarcharLength(mixed $default = null) // MaxVarcharLength (default 1024)
233+
* @method null|float|int getMinCardinality(mixed $default = null) // MinCardinality,索引列散粒度最低阈值,散粒度低于该值的列不添加索引,建议范围0.0 ~ 100.0
234+
* @method null|bool getOnlySyntaxCheck(mixed $default = null) // OnlySyntaxCheck, 只做语法检查不输出优化建议
235+
* @method null|bool getPrintConfig(mixed $default = null) // Print configs
236+
* @method null|bool getProfiling(mixed $default = null) // Profiling, 开启数据采样的情况下在测试环境执行Profile
237+
* @method null|string getQuery(mixed $default = null) // 待评审的 SQL 或 SQL 文件,如 SQL 中包含特殊字符建议使用文件名。
238+
* @method null|string getReportCss(mixed $default = null) // ReportCSS, 当 ReportType 为 html 格式时使用的 css 风格,如不指定会提供一个默认风格。CSS可以是本地文件,也可以是一个URL
239+
* @method null|string getReportJavascript(mixed $default = null) // ReportJavascript, 当 ReportType 为 html 格式时使用的javascript脚本,如不指定默认会加载SQL pretty 使用的 javascript。像CSS一样可以是本地文件,也可以是一个URL
240+
* @method null|string getReportTitle(mixed $default = null) // ReportTitle, 当 ReportType 为 html 格式时,HTML 的 title (default "SQL优化分析报告")
241+
* @method null|array|string getRewriteRules(mixed $default = null) // RewriteRules, 生效的重写规则 (default "delimiter,orderbynull,groupbyconst,dmlorderby,having,star2columns,insertcolumns,distinctstar")
242+
* @method null|bool getSampling(mixed $default = null) // Sampling, 数据采样开关
243+
* @method null|string getSamplingCondition(mixed $default = null) // SamplingCondition, 数据采样条件,如: WHERE xxx LIMIT xxx
244+
* @method null|int getSamplingStatisticTarget(mixed $default = null) // SamplingStatisticTarget, 数据采样因子,对应 PostgreSQL 的 default_statistics_target (default 100)
245+
* @method null|bool getShowLastQueryCost(mixed $default = null) // ShowLastQueryCost
246+
* @method null|bool getShowWarnings(mixed $default = null) // ShowWarnings
247+
* @method null|int getSpaghettiQueryLength(mixed $default = null) // SpaghettiQueryLength, SQL最大长度警告,超过该长度会给警告 (default 2048)
248+
* @method null|bool getTrace(mixed $default = null) // Trace, 开启数据采样的情况下在测试环境执行Trace
249+
* @method null|string getUniqueKeyPrefix(mixed $default = null) // UkPrefix (default "uk_")
250+
* @method null|bool getVerbose(mixed $default = null) // Verbose
251+
* @method null|bool getVersion(mixed $default = null) // Print version info
175252
* @method \Guanguans\SoarPHP\Soar onlyConfig() // Config file path
176253
* @method \Guanguans\SoarPHP\Soar onlyTestDsn() // TestDSN, 测试环境数据库配置, username:********@tcp(ip:port)/schema (default "tcp/information_schema?timeout=3s&charset=utf8")
177254
* @method \Guanguans\SoarPHP\Soar onlyOnlineDsn() // OnlineDSN, 线上环境数据库配置, username:********@tcp(ip:port)/schema (default "tcp/information_schema?timeout=3s&charset=utf8")
@@ -337,7 +414,7 @@ trait HasOptions
337414
*/
338415
public function __call(string $method, array $arguments): mixed
339416
{
340-
foreach (['set', 'with', 'only', 'except'] as $prefix) {
417+
foreach (['set', 'with', 'get', 'only', 'except'] as $prefix) {
341418
if (str_starts_with($method, $prefix)) {
342419
$name = '-'.str_snake(substr($method, \strlen($prefix)), '-');
343420
$actionMethod = $prefix.'Option';
@@ -384,11 +461,6 @@ public function withOptions(array $options): self
384461
return $this;
385462
}
386463

387-
public function getDelimiter(string $default = ';'): string
388-
{
389-
return $this->getOption('-delimiter', $default);
390-
}
391-
392464
public function getOption(string $name, mixed $default = null): mixed
393465
{
394466
return $this->getOptions()[$name] ?? $default;

src/Support/Rectors/AddHasOptionsDocCommentRector.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Guanguans\SoarPHP\Soar;
1818
use Guanguans\SoarPHP\Support\ComposerScripts;
1919
use Illuminate\Support\Str;
20+
use Illuminate\Support\Stringable;
2021
use PhpParser\Node;
2122
use PhpParser\Node\Stmt\Trait_;
2223
use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode;
@@ -100,14 +101,20 @@ public function refactor(Node $node): ?Node
100101
[
101102
'set' => '\Guanguans\SoarPHP\Soar set{method}({type} ${name}) // {description}',
102103
'with' => '\Guanguans\SoarPHP\Soar with{method}({type} ${name}) // {description}',
104+
'get' => '{type} get{method}(mixed $default = null) // {description}',
103105
'only' => '\Guanguans\SoarPHP\Soar only{method}() // {description}',
104106
'except' => '\Guanguans\SoarPHP\Soar except{method}() // {description}',
105-
] as $template
107+
] as $action => $template
106108
) {
107109
foreach ($options as $option) {
108110
$replacer = [
109111
'{method}' => Str::studly($option['name']),
110-
'{type}' => $option['type'],
112+
'{type}' => str($option['type'])
113+
->when(
114+
'get' === $action,
115+
static fn (Stringable $stringable): Stringable => $stringable->start('null|')
116+
)
117+
->toString(),
111118
'{name}' => Str::camel($option['name']),
112119
'{description}' => $option['description'],
113120
];

0 commit comments

Comments
 (0)