-
Notifications
You must be signed in to change notification settings - Fork 5
Basic concepts
How to represent queries in code?
Of course, as functions. Query parameters should be reflected as function parameters, their results as function results.
E.g. the query:
select id, name, title, description, owner, createdAt, modifiedAt, modifiedBy
from Blog
where id = @id
could be implemented as a function of type:
int -> IDbConnection-> Blog
SqlFun alows to generate such a function:
let getBlog: int -> IDbConnection-> Blog =
sql "select id, name, title, description, owner, createdAt, modifiedAt, modifiedBy
from Blog
where id = @id"
where sql
is a function responsible for building query functions using runtime code generation.
It generates:
- mappings between function parameters and query parameters
- mappings between function result and query result
- all needed type conversions
- command execution
But it doesn't cache generated function.
A side-effect of code generation is a validation of sql commands and all necessary type checking (i.e. if function parameter types match query parameter types and if function and query results are compatible).
Couple of functions can be grouped in a module:
module Blogging =
let getBlog: int -> IDbConnection-> Blog = ...
let getPosts: int -> IDbConnection-> Post list = ...
let getComments: int -> IDbConnection-> Comment list = ...
We don't need any cache. Assigning to variables is perfectly enough. And, since all module variables are evaluated during the first access to its contents, we obtain some level of type safety for free.