[web-devel] (Yesod) PersistEntity Key types

Rick Richardson rick.richardson at gmail.com
Sun Apr 3 18:52:32 CEST 2011

On Sun, Apr 3, 2011 at 12:17 PM, Greg Weber <greg at gregweber.info> wrote:

> On Sun, Apr 3, 2011 at 7:44 AM, Rick Richardson <rick.richardson at gmail.com
> > wrote:
>> On Sun, Apr 3, 2011 at 10:35 AM, Michael Snoyman <michael at snoyman.com>wrote:
>>> As a short term solution, I think you're right. However, I think we might
>>> want to consider a slightly more sophisticated approach... I say consider
>>> specifically, because I'm really not certain that what I'm saying is a good
>>> idea.
>>> I think there's basically three problems with the approach of using a
>>> PersistValue inside a PersistKey:
>>> 1) It will probably hurt performance, since we'll need to do more
>>> checking.
>>> 2) The code becomes a bit more fragile. By adding this sum type to the
>>> mix, we're adding necessity for a number of checks that can fail.
>>> 3) There's nothing stopping you from inserting a value into one database
>>> (say, SQLite), getting a key, and then looking up in MongoDB. (Not that this
>>> is a flaw in the current approach as well.)
>> I agree on the first two points. I think the principle behind 3 is
>> actually a feature.
>>> So here's the idea: each database backend will have an associated type
>>> for its key datatype. Then, instead of having:
>>>     data Key entity = Int64
>>> we'll have
>>>     data Key entity backend = BackendKey backend
>>> (ignoring all the newtype wrappers). I think this should solve both the
>>> issue you raise about MongoDB, and the three points I mention above.
>>> However, I'm still concerned that it might lead to difficult-to-follow code.
>>> There's really only one way to find out, but I just wanted to bounce the
>>> idea around before diving in.

Regarding the key type. I would like to be able to set it as part of the
PersistEntity via TH,  since I think keys should be allowed to be set on a
per PersistEntity basis.
Though this means that anything dealing with keys has to reference (Key val)
which makes such things as fromPersistKey nonsensical.  I also think that we
could define some generic key-> datatype functions that are also set by TH,
but they can't be part of the PersistEntity class, it would enable the
backends to build such functions as selectKeys.

>> I am going to negate my previous email. After thinking on this a bit. I
>> think that setting they key type at the PersistEntity is the correct
>> approach.
>> This would be the only way to handle keys as strings or composite keys (if
>> we want to support either)
> There are 2 use cases- relying on MongoDB to auto-generate a key, or
> providing one's own key. Now technically the key provided could be almost
> any PersistValue. But I think in practice it is likely to be an integer or
> an ObjectId. And I think even those use cases are likely to be the
> exception, not the rule. For now, to get this working, I think it is
> reasonable to assume that no id value will be provided by the user- that
> mongoDB will always be auto-generating it. So we should be able to
> just accommodate the key the same way as a normal db, except that it is 12
> bit number. And then it should be easy to go from there to support the user
> supplying their own ObjectId (which is the 12 bit number that MongoDB
> auto-generates). And supporting inserting an integer with the overhead of
> assuming it is 12bits would be easy also.
I was just assuming that we would let mongo generate the values, since we
didn't really want to force our customer to generate their own unique values
for each insert.

At the moment, I have gone the PersistValue route.  I have altered the TH,
PersistEntity and PersistBackend classes to support a PersistValue key.
Getting it to build GenericSql required adding (PersistField (Key val)) =>
 to most of the PersistBackend  functions. I also had to muck with the
selectKeys implementation.

My current approach is to add a  keyType=  attribute for Entities in TH. If
none is provided, it defaults to PersistInt64.

I am not sure I like this solution, but I pretty much have everything
working.  I have to take off for a while. I was hoping to get this working
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/web-devel/attachments/20110403/3c3efdd7/attachment.htm>

More information about the web-devel mailing list