-
Notifications
You must be signed in to change notification settings - Fork 20
Treat instances of DateTimeInterface as a value type throughout the API #20
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -45,7 +45,9 @@ public static function hash($value) | |
|
|
||
| case 'o': //object | ||
|
|
||
| return 'o' . spl_object_hash($value); | ||
| return $value instanceof \DateTimeInterface || $value instanceof \DateTime | ||
| ? 'dt:' . get_class($value) . ':' . $value->getTimestamp() | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens for other value types? For instance, we kept rejecting this particular sort of feature throughout doctrine because there is no way to build a "special cases" map. While I agree that it makes developer experience better, it also causes a series of #WTF moments. What if you could simply have the concept of "value objects" and a map of which ones are VOs? Acceptable? Better? Worse?
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Ocramius The |
||
| : 'o' . spl_object_hash($value); | ||
|
|
||
| case 'a': //array | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| <?php | ||
|
|
||
| namespace Pinq\Tests\Helpers; | ||
|
|
||
| /** | ||
| * | ||
| * @author Elliot Levin <[email protected]> | ||
| */ | ||
| class ExtendedDateTime extends \DateTime | ||
| { | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,7 +28,8 @@ public function everything() | |
| 'oneToTenTwice', | ||
| 'assocOneToTen', | ||
| 'tenRandomStrings', | ||
| 'assocMixedValues' | ||
| 'assocMixedValues', | ||
| 'dateTimes' | ||
| ]; | ||
|
|
||
| foreach ($dataProviders as $provider) { | ||
|
|
@@ -106,6 +107,17 @@ public function assocTenRandomStrings() | |
| return $this->getImplementations(array_combine($this->randomStrings(10), $this->randomStrings(10))); | ||
| } | ||
|
|
||
| public function dateTimes() | ||
| { | ||
| return $this->getImplementations(iterator_to_array( | ||
| new \DatePeriod( | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some alignment weirdness here (minor) |
||
| new \DateTime('1-1-2000'), | ||
| new \DateInterval('P4M'), | ||
| new \DateTime('2-3-2004') | ||
| ) | ||
| )); | ||
| } | ||
|
|
||
| private function randomStrings($amount) | ||
| { | ||
| $letters = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890-!@#$%^&*()_'; | ||
|
|
||
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.
As discussed below, I think that building exclusions on a case-by-case basis is a problem. This sort of feature may need some better thought work on the concept of Value Objects, I'd say (and providing a way to extract scalar values/identity from them, eventually)
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.
@Ocramius Hmm.. this is a tough one, perhaps some sort of static registrar defining hasher implementations for a hasher interface for a specific class? The main reason I am considering
DateTimeas a special case is for compatibility with SQL where date times are a value type. For instance:Where
$row['some_date']is a datetime in the database represented as an instance ofDateTimein the query, this will not map well to SQL as it stands as in fact each row containing an instance ofDateTimewill produce a new group. This update fixes that as the behaviour of the API now matches SQL.As you have mentioned, perhaps it is worthwhile implementing way for users to customize this behaviour on a per-class approach. The trouble I have with this idea is again the compatibility with SQL, when mapping entities to rows this is all well and good because what is the instance in PHP corresponds to the primary key in SQL. For value objects, this is more difficult as there is no language level concept in PHP, if we define a way for users to register a special hasher for their classes, it will have to be in some formalized manner that can be interpreted by a query provider. I don't believe it would be a good idea just to provide an interface as such:
There would be no way for any query provider to interpret such an implementation without inspecting the implementation of
getIdentityStringmethod which is just nasty. The reason I bring all this this up is because I have begun implementing a query provide like Pinq.Demo.Sql but a much more thorough implementation using the Doctrine so this is at the forefront of my mind. Will have to think this over some more, thoughts?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.
@TimeToogo the problem is that you are taking an opinionated approach on something that has different opinions all across the interwebz.
We decided to go with a by-ref check to avoid the problem overall until we have a way to solve it.
DBAL types are a semi-working solution (though static and opinionated).
In general, Value Objects would be the way to go, with a way to serialize/unserialize for in-memory and in-sql comparison.
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.
So yeah, serializing would be context-aware :|
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.
@Ocramius Yep makes sense, like above an unopinionated approach would be the
IClassIdentifier(user provides implementations for their classes) that would modify how comparisons are made between classes as the user chooses. The problem is that then the API and how it behaves is a moving target, to the whim of the user. Query providers (other implementations of the API) would most likely am at the largest possible support for the API but this becomes harder as these core behaviours are no longer well-defined.So really it comes down to priorities and the formalization of behaviour. Define a set standards of value of objects such as
DateTime(opinionated) or let the user define such behaviour and instead query providers who implement the API now behave different due to the customizations from the user. As usual both sides have there pros and cons :/