From: Justin B. <jgb...@gm...> - 2009-07-23 15:53:31
|
I don't think the code below can compile. One important aspect of HaskellDB is that the "shape" of the query is shown in the *type* of the query. Looking at your example: >> q val = do >> s <- table stock >> restrict (fromNull (constant "") (s!company_name) >> `like` constant ("%"++val++"%")) >> r <- project (company_name << s!company_name # >> ticker << s!ticker) >> return r The type of q would be based on the columns projected. Assuming company_name and ticker are both strings, you would get q :: Query (Rel (RecCons (CompanyName (Expr String)) (RecCons (Ticker (Expr String)) RecNil) That is, a type-level tuple which indicates that the query has two columns, CompanyName and Ticker, both with type String. Simplying your next example a little bit, I can show that it won't type check: >> flds cond2 s = let a = (vendor_name << s!vendor_name) # fld >> b = if cond2 >> then (customer_id << s!customer_id) # a >> else a >> in b >> where >> fld = company_name << s!company_name # ticker << s!ticker What is the type of b? We have to look at the query created. When cond2 is true, then b is: (customer_id << s!customer_id) # (vendor_name << s!vendor_name) # company_name << s!company_name # ticker << s!ticker However, if cond2 is false then b is: (vendor_name << s!vendor_name) # company_name << s!company_name # ticker << s!ticker If cond2 is true, then the type of b can determined by the query shape: b :: RecCons (CustomerId (Expr Int)) (RecCons (VendorName (Expr String)) (RecCons (CompanyName (Expr String) (...)) However, if cond2 is false then the type is b :: RecCons (VendorName (Expr String)) (RecCons (CompanyName (Expr String) (...)) Since the type of the "then" and "else" arms need to agree, this won't compile. Its like writing b = if True then "a" else 1 On Thu, Jul 23, 2009 at 1:37 AM, Artyom Shalkhakov<art...@gm...> wrote: > Hi, > > 2009/7/22 Keren Lenz <ker...@gm...>: >> Here is an example (in imperative psudo code of what I mean by dynamic >> query: >> Query generate(bool cond1, bool cond2) { >> Colums c = null; >> if(cond1) >> c.add(col1); >> if(cond3) >> c.add(col2); >> Query q = SELECT + c + FROM table_name; >> return q; >> } > > > >> That is, the selected columns are chosen based on runtime conditions. >> Is that possible with HaskellDB? > > I would like to stress how HaskellDB works. You are given atomic building > blocks (relations, tuples and fields) and some combinators ("glue" that helps > you combine your building blocks: relational and query operations). What you > are really doing with HaskellDB is manipulating an abstract syntax tree of a DSL > embedded in Haskell. > > A simple example would be something along these lines [1]: > >> q val = do >> s <- table stock >> restrict (fromNull (constant "") (s!company_name) >> `like` constant ("%"++val++"%")) >> r <- project (company_name << s!company_name # >> ticker << s!ticker) >> return r > > It is already somewhat "dynamic". Can we do anything to make it more "dynamic"? > Yes, we can: > >> q flds val = do >> s <- table stock >> restrict (fromNull (constant "") (s!company_name) >> `like` constant ("%"++val++"%")) >> r <- project (flds s) >> return r > > where flds is simply > >> flds s = company_name << s!company_name # ticker << s!ticker) > > So now you can do: > >> flds cond1 cond2 s = let a = if cond1 >> then (vendor_name << s!vendor_name) # fld >> else fld >> b = if cond2 >> then (customer_id << s!customer_id) # a >> else a >> in b >> where >> fld = company_name << s!company_name # ticker << s!ticker > > (don't forget to change the definition of q!) > > As the number of conditions grows, this style becomes very inconvenient to > program in, so you'd need a writer monad over a monoid or something I suppose. > > Also, I would like to note that I haven't tested the code given above, > so I don't > know if there are any bugs or not. But feel free to ask if there are, > anyway. :-) > > Cheers, > Artyom Shalkhakov. > > [1] http://pseudofish.com/blog/2008/05/11/haskelldb-basics/ > > ------------------------------------------------------------------------------ > _______________________________________________ > Haskelldb-users mailing list > Has...@li... > https://lists.sourceforge.net/lists/listinfo/haskelldb-users > |