I adopt a idea (not remember the original library where I say it) where ALL the sql strings are in a single .sql file.
Exactly as with sql upgrade scripts.
It look like this:
--name: post-event
SELECT post_log(@theId, @ENTITY, @ACTION, @CHANGEBY, @DATA, @VERSION)
GO
--name: get-location
SELECT * FROM "Location"
WHERE
id = @id
GO
--name: list-location
SELECT * FROM "Location"
ORDER BY country, state, city;
GO
Then I just parse this file (note the names with --) once and use this alike (in F#):
module Location =
let ENTITY = "Location"
let SQL_LIST = SQL_CMDS.["list-location"]
type LocationRecord = {id:int64 option; address:string; country:string; state:string; city:string; version:int64}
type LocationQuery =
| All
| ById of int64
let query q =
use con = openConn()
let toRec = Db.toRecord<LocationRecord>
match q with
| All ->
Db.select con SQL_LIST []
|> Seq.map toRec
| ById(theId) ->
let id = [P("@id", theId)]
Db.select con SQL_BYID id
|> Seq.map toRec
And plug a micro-orm (mainly just a very thin layer over ADO.NET in .NET. I do similar over swift and python).
This take me like a few hours. Let me test easily the sql. I can build the sql exactly as I want.
The only cons is the repetition on the scripts - because SQL is a terrible language that not allow composability, like similar to CSS - . Probably I will later use a template parser (like mustache or similar) but I think this is the closest to the holy grail ;)