|
From: Bjorn B. <bri...@cs...> - 2008-01-02 09:37:43
|
On Dec 31, 2007, at 21:25 , Justin Bailey wrote:
Hi Justin,
> All,
>
> As part of my data model, I'd like to say there is a primary
> key/foreign key relationship between two tables/queries. Right now I
> only want to do this to capture some extra-query information that I'm
> using for code generation - I don't intend it to actually affect
> queries generated, though I'd like to go there eventually.
>
> I define a class which says there is a relation:
>
> class HasRelation pk fk
>
> I define a type which holds relation values:
>
> data Relation a pk fk p c =3D Relation { ... }
>
> Relation values can only be constructed by a function with appropriate
> constraints on it:
>
> relation :: (HasRelation pk fk, HasField pk parent, HasField fk
> child) =3D> Attr pk a -> Attr fk a -> Rel parent -> Rel child ->
> Relation a pk fk parent child
> relation primaryKey foreignKey prnt chld =3D Relation ....
>
> As an example, if I have tables Orders and LineItems, both with field
> order_id, I can establish a relationship by first defining an
> instance:
>
> instance HasRelation Orders.Order_id LineItems.Order_id
>
> I can then create a relation value between the two:
>
> orders <- table Orders.orders
> lineItems <- table LineItems.lineItems
> let r1 =3D relation Orders.order_id LineItems.order_id orders =20
> lineitems
>
> Note these types would be defined using DBDirect, so Order_id as a
> type with one constructor, lineItems has type "Table ...", etc. If I
> try to define an incorrect relation (wrong fields, fields in the wrong
> order, etc), then the above will not compile, which is just what I
> want.
>
> If you've read this far, I've not done any type-level programming or
> even played much with classes and instances before so I'd like to know
> if the approach makes sense. I took most of my inspiration from the
> HasField class in the HDBRec module.
>
> 1) Could this be simpler? Any obvious deficiencies?
What's the purpose of the HasRelation class? Wouldn't just the =20
Relation type be enough?
> 2) I had to enable a number of extensions (though all of these are
> also enabled by haskelldb) - FlexibleInstances, FlexibleContexts,
> UndecidableInstances and OverlappingInstances. Should I be worried?
HaskellDB already uses most or all of those, so there's no need to =20
worry.
> 3) It's possible to define relationships among any two types. How
> can I limit that to 1) attributes with 2) the same type? Would I have
> to define an Attr typeclass, parallel to the Attr type?
Getting rid of HasRelation should solve this, AFAICT. But I haven't =20
thought this through in detail.
You may also want to have a look at the CoddFish paper: http://=20
wiki.di.uminho.pt/twiki/bin/view/Research/PURe/CoddFish
They do type-level programming to capture things like this.
/Bj=F6rn
|