Architecture The ORM

alsonkemp edited this page Sep 13, 2010 · 12 revisions

ORM = Object-Relational Mapper, though for Haskell it’s really more of a Type-Relational Mapper.

Assuming that you have a databaseConnection set up in Config/App.hs and that you have a database, the ORM can be run by:

runghc scripts/GenerateModels.hs

After the script runs, you should have a number of files in App/Models. Assuming that you have Page and Comment tables:


In general you can ignore the /Bases/* files. To add additional functionality to the Page model, add functions to App/Models/Page.hs (do not add them to any /Bases/* files because the ORM will overwrite the changes). To use a Page, import App.Models.Page, though you’ll probably want to qualify the import to avoid naming conflicts:

import qualified App.Models.Page as Page
import qualified App.Models.Comment as Comment

dummy = do p <- Page.find “some page”
Comment.deleteWhere “pageId = ?” [toSql $ _id p]

Tables and Columns to Types

Database tables and columns are directly converted as Types and functions, so the ORM will automatically capitalize table names so that they are valid type names and will automatically lowercase column names so that they are valid as functions. As an example, these tables and columns will be mapped to types as follows:

Database —> Haskell Types And Functions
page [table] Page [type]
text text
author_id author_id
Comment [table] Comment [type]
pageID pageID
Text text

Bits to notice:

  1. The “page” table was capitalized in order to become a valid type name.
  2. The “Comment” table was fine the way it was.
  3. The “ID” column was lowercased in order to become a valid function name (but the changed name “iD” is odd).
  4. The “Text” column (in Comment) was lowercased in order to become a valid function name.
  5. Unlike in Ruby on Rails, “author_id” is not converted to AuthorId.

The “id” Column

In Ruby On Rails, it’s standard to have a column named “id” as the primary key on tables. It’s a nice convention, but “id” is already a function name in Haskell. So the convention in Turbinado is to name the “id” column “_id”.


Following are conventions for Turbinado databases:

  1. Table names are singular.
  2. Column names do not include the table name as a prefix (e.g. “text” is preferred to “pageText”).
  3. Partial camel case is preferred to underscores for column names (e.g. “firstName” rather than “first_name”).
  4. Tables should usually include an “_id” column as the primary key.
  5. Foreign keys should be named for the target table and column (e.g. “page_id” refers to Page : _id).