Idiomatic haskell for database abstraction

In OOP languages, I can write a database shell that encapsulates a database connection, manages a schema, and provides several basic operations, such as exec , query , prepare_and_execute . I could even have a separate database helper class that handles the database schema, leaving the database abstraction to handle connections only. This will then be used by model shells / factories that use the database abstraction class to instantiate model classes. Something along the line like this UML diagram:

What would be the preferred way to create such a system in an idiomatic haskell?

+7
source share
2 answers

The most used database abstraction library in Haskell HDBC . This means that queries are simply represented as String with placeholders. Fewer people use HaskellDB , which provides a secure type of query building. Nothing prohibits the use of custom data types to represent common queries and custom functions to create them.

The values ​​in Haskell are immutable, which means that it is not practical to have a mutable object corresponding to a record in the database. Instead, I believe that the types and functions of user data that march and push / transfer the values ​​of these types to / from the database are most often defined.

Whenever database updates are needed, they are likely to run in some kind of monopoly monad in IO . This will keep the connection open, for example, or do something between requests.

Finally, the functions are first-class, so you can build all the functions on the fly. Thus, the function itself can encapsulate any necessary information.

So, I think the normal Haskell approach consists of

  • algebraic data types for representing actual data (as constant values)
  • the rest of the application to convert these values
  • which generate requests (encapsulate schema details, marshal data to / from Haskell data types)
  • (optional) a monad with a state to run queries (hide database access information)
  • functions that run queries (hide database access information)
+4
source

The most idiomatic way to use Haskell for databases and the most efficient IMHO method is to cache records in memory and use STM in memory transactions so that you use the database for storage. You can then use transactional variables (TVar) to manage your record. But you have to define your own query language, and you need a mechanism for caching / emancipation and synchronization. That's all java EJB3 and Hybernate do.

The TCache package defines DBRefs, which are constant STM variables with the semantics of TVar . They can be part of a post and point to another post and be light, so you can develop your own abstraction over it. It also has an SQL query language, including field search, concatenation, and full-text search. It has default constancy in files. You just need to define the key for your Haskell entry, and you have the persistence of the file. To save the database, there is an IResource class in which you define the read, write, and delete operations for your records. Each entry may have its own constancy. Thus, all interaction with the database is in one place in the source code, and transactions in memory are an order of magnitude faster. TCache writes a coherent state every time it writes asynchronously to the database. He can also write synchronously.

0
source

All Articles