haskell - Reconciling lens usage with database access -


i've been playing around lenses recently, , finding them pleasant intended usage - digging complex data structures. 1 of areas i'd appreciate them in database access (specifically sqlite, think question generalizes dbs), , yet can't see way write lenses don't heavily sacrifice either performance or granularity.

if write lens (or think prism, in light of nullable fields?) db table, table row, , row column, each step of incurs db access, meaning ought 1 access @ minimum 4.

on other hand, if aim map db access 1:1 uses of lens/prism, big do-everything lenses can't broken smaller pieces when do want see columns in table, , on.

does make sense @ use lenses db, , if missing obvious way avoid having duplicate work avoid unnecessary db access?

it sound me want use lens in way similar linq iqueryable in c#.

eg if have types:

data project = project {   _projectid :: int   , _projectpriority :: int   , _projectname :: string   , _projecttasks :: [task]    } deriving (show)  data task = task {   _taskid :: int   , _taskname :: string   , _taskestimate :: int   } deriving (show)   makelenses ''project makelenses ''task 

and database:

create table projects ( id, name, priority); create table tasks (id, name, estimate, projectid);  insert projects values (1, 'proj', 1), (2, 'another proj', 2);  insert tasks values (1, 'task1', 30, 1), (2, 'another', 40, 1),                         (3, 'task3', 20, 2), (4, 'more', 80, 2); 

if wanted list of task names projects priority greater 1, nice if use:

highprioritytasks :: io [string] highprioritytasks = db ^.. projects . filtered (\p -> p ^. projectpriority > 1 )                     . projecttasks . traverse . taskname 

and have query database using query:

select t.name projects p  inner join tasks t on t.projectid = p.id  p.priority > 1; 

unfortunately, isn't possible library. basically, efficient database wise, (normally) have everthing in 1 query. wouldn't acceptable this:

select * projects priority > 1; each project:    select name tasks projectid = <project>.id     

unfortunately, isn't possible decompose functions know built them up. apart type, can't find out function without running it. there no way extract data out of filtered function build query. nor possible extract sub lens out of full expression. isn't possible using lens library.

the best can @ moment query database using 1 set of functions, , query resulting data using lens. see blog post yesod example of this.


a related question if possible @ all. so, need create sublanguage numeric , string operators, , composition tracks done. possible. example, can build num type records done it:

data trackednum = trackednum :-: trackednum                 | trackednum :+: trackednum                 | trackednum :*: trackednum                 | abs trackednum                 | signum trackednum                 | value integer   deriving (show)  instance num trackednum   + b = :+: b   * b = :*: b   - b = :-: b   abs = abs   signum = signum   frominteger = value  t :: trackednum t = 3 + 4 * 2 - abs (-34)  > t  (value 3 :+: (value 4 :*: value 2)) :-: abs (value 0 :-: value 34) 

repeat process boolean operators (you need new type class this), list operators, , function composition (ie category class), , should able make "white-box" function, used create efficient sql query. isn't trivial undertaking though!


Comments

Popular posts from this blog

javascript - RequestAnimationFrame not working when exiting fullscreen switching space on Safari -

jsf - How to ajax update an item in the footer of a PrimeFaces dataTable? -

django - CSRF verification failed. Request aborted. CSRF cookie not set -