Skip to content

Instantly share code, notes, and snippets.

@hellertime
Created October 30, 2010 14:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hellertime/655343 to your computer and use it in GitHub Desktop.
Save hellertime/655343 to your computer and use it in GitHub Desktop.
Example generating HaskellDB records for SQLite3 during configuration.
> import Distribution.Simple
This is an example Setup.hs for a haskell program making use of HaskellDB.
> import System.Directory ( removeFile, removeDirectoryRecursive )
HaskellDB needs to have the structure of all database tables laid out as data.
> import Database.HaskellDB
> import Database.HaskellDB.DBSpec
If your database schema is already defined, and is not under your control,
then it is wasted effort to go about defining the table data by hand.
So let's let HaskellDB work for us!
> import Database.HaskellDB.DBSpecToDBDirect
One important feature of the HaskellDB convenience layer is the ability to
intelligently map table and column names to valid haskell names,
this mapping can be customized, but the defaults are OK.
> import Database.HaskellDB.DBSpec.PPHelpers ( mkIdentPreserving )
For this example we will be connecting to a SQLite3 database.
> import Database.HaskellDB.HDBC.SQLite3 ( sqliteConnect )
HDBC-SQLite3 >= 2.3.1 is needed because HaskellDB needs a working 'describeTable'
function.
> main :: IO ()
> main =
Using 'defaultMainWithHooks' allows us to provide the custom handlers which will
'generate' and 'clean' our table records created by HaskellDB.
> defaultMainWithHooks
Extending 'simpleUserHooks' prevents us from doing too much work.
> simpleUserHooks { postConf = generate
> , postClean = clean
> }
The 'generate' function has hardcoded paths to the stub SQLite3 database used to
generate the records, and the Haskell module namespace to create the source
files under. A more complete solution might get these parameters from the environment.
> generate _ _ _ _ = do -- none of the arguments are used in this example
> putStrLn "Generating HaskellDB records..."
> dbInfo <- withDB dbPath (dbToDBSpec False mkIdentPreserving dbPath)
> dbInfoToModuleFiles "src/" dbNS dbInfo
> where
> dbPath = "config/stub.sqlite3"
> dbNS = "Example.DB.Generated"
> withDB = sqliteConnect
The two heavy lifters here are 'dbToDBSpec' and 'dbInfoToModuleFiles'.
Simply, 'dbToDBSpec' makes use of the underlying drivers 'describeTable' function
to gather the table information from the database and convert it to a format
HaskellDB will operate on. Then 'dbInfoToModuleFiles' uses this information to
generate Haskell source files containing the necessary source code needed to work
with this database using HaskellDB.
For completeness, cleaning up these generated files can be automated when the
user calls 'cabal clean'.
> clean _ _ _ _ = do -- none of the arguments are used in this example
> putStrLn "Removing generated HaskellDB records..."
> removeFile "src/Example/DB/Generated.hs"
> removeDirectoryRecursive "src/Example/DB/Generated"
Now go out and code!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment