Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ondrap/dynamodb-simple
Type-safe Haskell framework for AWS DynamoDB
https://github.com/ondrap/dynamodb-simple
aws-dynamodb dynamodb haskell
Last synced: 2 months ago
JSON representation
Type-safe Haskell framework for AWS DynamoDB
- Host: GitHub
- URL: https://github.com/ondrap/dynamodb-simple
- Owner: ondrap
- License: bsd-3-clause
- Created: 2016-11-27T11:26:51.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2022-05-14T08:26:01.000Z (over 2 years ago)
- Last Synced: 2024-04-14T09:07:31.020Z (10 months ago)
- Topics: aws-dynamodb, dynamodb, haskell
- Language: Haskell
- Homepage:
- Size: 249 KB
- Stars: 18
- Watchers: 5
- Forks: 5
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: changelog.md
- License: LICENSE
Awesome Lists containing this project
README
# DynamoDB layer for Haskell
[![Build Status](https://travis-ci.org/ondrap/dynamodb-simple.svg?branch=master)](https://travis-ci.org/ondrap/dynamodb-simple) [![Hackage](https://img.shields.io/hackage/v/dynamodb-simple.svg)](https://hackage.haskell.org/package/dynamodb-simple)
This library intends to simplify working with DynamoDB AWS database.
It uses Generics code ([generics-sop](https://hackage.haskell.org/package/generics-sop)) on top of your structures
and just by adding a few instances allows you to easily generate AWS
commands.````haskell
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 the `Maybe` 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 supporting
`Show/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 become `Nothing` 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 become `Nothing` on empty set
* Don't try to use inequality comparisons (`>.`, `<.`) on empty strings.
* If you use `maybeCol' == Nothing`, it gets internally replaced
by `attr_missing(maybeCol)`, so it will behave as expected. The same with
empty `String` or `Set`. Keep that in mind when traversing nested structures.
* In case of schema change, `Maybe` columns are considered `Nothing`.
* 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.