Description
Typesafe library for working with DynamoDB database.
Description
Framework for accessing DynamoDB database. The majority of AWS API is available to the user in a convenient, simple and typesafe manner.
README.md
DynamoDB layer for Haskell
This library intends to simplify working with DynamoDB AWS database. It uses Generics code (generics-sop) on top of your structures and just by adding a few instances allows you to easily generate AWS commands.
data Test = Test {
category :: T.Text
, user :: T.Text
, subject :: T.Text
, replies :: Int
} deriving (Show)
-- Generate instances and category', user' etc. variables for queries/updates
mkTableDefs "migrate" (tableConfig "" (''Test, WithRange) [] [])
test :: IO ()
test = do
lgr <- newLogger Info stdout
setEnv "AWS_ACCESS_KEY_ID" "XXXXXXXXXXXXXX"
setEnv "AWS_SECRET_ACCESS_KEY" "XXXXXXXXXXXXXXfdjdsfjdsfjdskldfs+kl"
env <- newEnv Discover
let dynamo = setEndpoint False "localhost" 8000 dynamoDB
let newenv = env & configure dynamo & set envLogger lgr
runResourceT $ runAWS newenv $ do
migrate mempty Nothing -- Create tables, indices etc.
--
putItem (Test "news" "john" "test" 20)
--
item <- getItem Eventually tTest ("news", "john")
liftIO $ print item
--
items <- scanCond tTest (replies' >. 15) 10
liftIO $ print items
Features
- Global secondary indexes.
- Local secondary indexes.
- Tables with only hash keys as well as tables with combined hash and sort key.
- Sparse indexes (define the column as
Maybe
in a table, omit theMaybe
in index definition). - Automatically generate polymorphic lenses to access fields in main table and index records.
- Standard datatypes including
Tagged
and basic default instances for data types supportingShow/Read
. - New types can be added easily.
- High-level, easy-to-use API - hides intricacies of both DynamoDB and amazonka library.
- Type-safe conditions, including nested structures.
- Type-safe update actions.
- Template-haskell macro to easily create all relevant instances.
- 'Schema migration' - upon startup checks if the database schema matches the definition and, if possible, adjusts the database. If it is impossible, it fails.
- Automatic handling of invalid values (empty strings, empty sets). Automatic rewriting of queries when searching for these empty values.
- Compatible with GHC8
DuplicateRecordFields
- Customizable table and index names. Custom translation of field names to attribute names.
- AWS Dynamo streaming settings.
- Utilities to help with simulated joins or retriving original data from index.
- Both conduit and page-based API.
What is planned
- Support for automatic versioning of fields.
Limitations
- Projections are not supported. Using some generic programming on tuples it should be possible.
- You cannot compare attributes between themselves (i.e.
currentAccount' >=. averageAccount'
). I'm not sure this would be currently technically possible. Does anybody need it?
Handling of NULLs
DynamoDB does not accept empty strings/sets. It accepts NULL
, but that is not acceptable in fields that are used for sparse indexing.
Empty string and empty set are represented by omitting the value.
Just Nothing :: Maybe (Maybe a)
will becomeNothing
on retrieval.[Just 1, Nothing, Just 3]
will become[Just 1, Just 3]
on retrieval.HashMap Text (Maybe a)
is not a good idea; missing values will disappear.Maybe (Set a)
will becomeNothing
on empty set- Don't try to use inequality comparisons (
>.
,<.
) on empty strings. - If you use
maybeCol' == Nothing
, it gets internally replaced byattr_missing(maybeCol)
, so it will behave as expected. The same with emptyString
orSet
. Keep that in mind when traversing nested structures. - In case of schema change,
Maybe
columns are consideredNothing
. - In case of schema change,
String
columns are decoded as empty strings,Set
columns as empty sets,[a]
columns as empty lists. - Condition for
== ""
,== []
etc. is automatically enhanced to account for non-existent attributes (i.e. after schema change). - Empty list/empty hashmap is represented as empty list/hashmap; however it is allowed to be decoded even when the attribute is missing in order to allow better schema migrations.