-
-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Range and MultiRange parser #307
base: master
Are you sure you want to change the base?
Conversation
PR Summary
|
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## master #307 +/- ##
=============================================
- Coverage 100.00% 99.03% -0.97%
- Complexity 200 272 +72
=============================================
Files 13 15 +2
Lines 596 722 +126
=============================================
+ Hits 596 715 +119
- Misses 0 7 +7
☔ View full report in Codecov by Sentry. |
Good idea to support range types 👍
|
|
Unfortunately |
...
public const TYPE_RANGE = 'range';
...
protected function loadColumnSchema(array $info): ColumnSchemaInterface
{
...
if ($info['type_type'] === 'r') {
$column->type(self::TYPE_RANGE);
}
...
}
... Then you can check |
A while back I suggested adding a custom type mapper. For example, it would be more convenient for me if geometric types were immediately given as an instance of a suitable class from a given library. I think it would be more universal than to have to make a whole package for such a special case For example somewhere in
|
705193b
to
39ec0a4
Compare
39ec0a4
to
5b96d65
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- In
Schema
class... public const TYPE_RANGE = 'range'; ... protected function loadColumnSchema(array $info): ColumnSchemaInterface { ... if ($info['type_type'] === 'r') { $column->type(self::TYPE_RANGE); } ... } ...Then you can check
$column->getType() === Schema::TYPE_RANGE
Suggestion to realize this way.
$schema->setType('point', static fn (?string $value) => $value ? Point::fromText($value) : null );
Something like this will be possible after this PR yiisoft/db#752 in version 2.0.0
This will allow to create PointColumn
class and support type conversation there.
public const TYPE_INT_RANGE = 'int4range'; | ||
public const TYPE_BIGINT_RANGE = 'int8range'; | ||
public const TYPE_NUM_RANGE = 'numrange'; | ||
public const TYPE_TS_RANGE = 'tsrange'; | ||
public const TYPE_TS_TZ_RANGE = 'tstzrange'; | ||
public const TYPE_DATE_RANGE = 'daterange'; | ||
public const TYPE_INT_MULTIRANGE = 'int4multirange'; | ||
public const TYPE_BIGINT_MULTIRANGE = 'int8multirange'; | ||
public const TYPE_NUM_MULTIRANGE = 'nummultirange'; | ||
public const TYPE_TS_MULTIRANGE = 'tsmultirange'; | ||
public const TYPE_TS_TZ_MULTIRANGE = 'tstzmultirange'; | ||
public const TYPE_DATE_MULTIRANGE = 'datemultirange'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Preffered simple abstract types instead of list of all supported range db types.
Suggestion to use one or two abstract types
public const TYPE_INT_RANGE = 'int4range'; | |
public const TYPE_BIGINT_RANGE = 'int8range'; | |
public const TYPE_NUM_RANGE = 'numrange'; | |
public const TYPE_TS_RANGE = 'tsrange'; | |
public const TYPE_TS_TZ_RANGE = 'tstzrange'; | |
public const TYPE_DATE_RANGE = 'daterange'; | |
public const TYPE_INT_MULTIRANGE = 'int4multirange'; | |
public const TYPE_BIGINT_MULTIRANGE = 'int8multirange'; | |
public const TYPE_NUM_MULTIRANGE = 'nummultirange'; | |
public const TYPE_TS_MULTIRANGE = 'tsmultirange'; | |
public const TYPE_TS_TZ_MULTIRANGE = 'tstzmultirange'; | |
public const TYPE_DATE_MULTIRANGE = 'datemultirange'; | |
public const TYPE_RANGE = 'range'; | |
public const TYPE_MULTIRANGE = 'multirange'; |
private const RANGES = [ | ||
Schema::TYPE_INT_RANGE, | ||
Schema::TYPE_BIGINT_RANGE, | ||
Schema::TYPE_NUM_RANGE, | ||
Schema::TYPE_TS_RANGE, | ||
Schema::TYPE_TS_TZ_RANGE, | ||
Schema::TYPE_DATE_RANGE, | ||
]; | ||
|
||
private ?string $type; | ||
|
||
public function __construct(?string $type = null) | ||
{ | ||
$this->type = $type; | ||
} | ||
|
||
public function withType(?string $type): self | ||
{ | ||
$new = clone $this; | ||
$new->type = $type; | ||
|
||
return $new; | ||
} | ||
|
||
public function asInt(): self | ||
{ | ||
return $this->withType(Schema::TYPE_INT_RANGE); | ||
} | ||
|
||
public function asBigInt(): self | ||
{ | ||
return $this->withType(Schema::TYPE_BIGINT_RANGE); | ||
} | ||
|
||
public function asNumeric(): self | ||
{ | ||
return $this->withType(Schema::TYPE_NUM_RANGE); | ||
} | ||
|
||
public function asDate(): self | ||
{ | ||
return $this->withType(Schema::TYPE_DATE_RANGE); | ||
} | ||
|
||
public function asTimestamp(): self | ||
{ | ||
return $this->withType(Schema::TYPE_TS_RANGE); | ||
} | ||
|
||
public function asTimestampTz(): self | ||
{ | ||
return $this->withType(Schema::TYPE_TS_TZ_RANGE); | ||
} | ||
|
||
public function asCustom(): self | ||
{ | ||
return $this->withType(null); | ||
} | ||
|
||
public function parse(?string $value): ?array |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
private const RANGES = [ | |
Schema::TYPE_INT_RANGE, | |
Schema::TYPE_BIGINT_RANGE, | |
Schema::TYPE_NUM_RANGE, | |
Schema::TYPE_TS_RANGE, | |
Schema::TYPE_TS_TZ_RANGE, | |
Schema::TYPE_DATE_RANGE, | |
]; | |
private ?string $type; | |
public function __construct(?string $type = null) | |
{ | |
$this->type = $type; | |
} | |
public function withType(?string $type): self | |
{ | |
$new = clone $this; | |
$new->type = $type; | |
return $new; | |
} | |
public function asInt(): self | |
{ | |
return $this->withType(Schema::TYPE_INT_RANGE); | |
} | |
public function asBigInt(): self | |
{ | |
return $this->withType(Schema::TYPE_BIGINT_RANGE); | |
} | |
public function asNumeric(): self | |
{ | |
return $this->withType(Schema::TYPE_NUM_RANGE); | |
} | |
public function asDate(): self | |
{ | |
return $this->withType(Schema::TYPE_DATE_RANGE); | |
} | |
public function asTimestamp(): self | |
{ | |
return $this->withType(Schema::TYPE_TS_RANGE); | |
} | |
public function asTimestampTz(): self | |
{ | |
return $this->withType(Schema::TYPE_TS_TZ_RANGE); | |
} | |
public function asCustom(): self | |
{ | |
return $this->withType(null); | |
} | |
public function parse(?string $value): ?array | |
public function parse(?string $value, ?string $dbType = null): ?array |
Suggestion to pass $dbType
to parse()
method instead of initiating
$min = $lower ? DateTime::createFromFormat('Y-m-d', $lower) : null; | ||
$max = $upper ? DateTime::createFromFormat('Y-m-d', $upper) : null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to decide this will be DateTime
or better DateTimeImmutable
or just string due to yiisoft/db
do not support DateTime
object.
And DateTimeImmutable
can be added after solving the issue yiisoft/db#725 perhaps in version 2.0.0
if (is_string($value) && $rangeParser = $this->getRangeParser()) { | ||
return $rangeParser->parse($value); | ||
} | ||
|
||
if (is_string($value) && $multiRangeParser = $this->getMultiRangeParser()) { | ||
return $multiRangeParser->parse($value); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (is_string($value) && $rangeParser = $this->getRangeParser()) { | |
return $rangeParser->parse($value); | |
} | |
if (is_string($value) && $multiRangeParser = $this->getMultiRangeParser()) { | |
return $multiRangeParser->parse($value); | |
} |
Please move this to phpTypecastValue()
method in section return match ($this->getType()) {...}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also need to implement dbTypecast(mixed $value)
to cast PHP array of range value to DB. It is better to implement an ExpressionInterface
e.g. RangeExpression
and MultirangeExpression
Range and MultiRange format parser for PgSql