{"id":18519331,"url":"https://github.com/eyedouble/erlstore","last_synced_at":"2026-04-17T11:34:08.714Z","repository":{"id":143749868,"uuid":"123539295","full_name":"eyedouble/erlstore","owner":"eyedouble","description":"Erlstore","archived":false,"fork":false,"pushed_at":"2018-07-17T14:40:31.000Z","size":493,"stargazers_count":4,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-14T16:17:37.816Z","etag":null,"topics":["access-control","authentication","authorization","database","datastore","document-database","documentdb","elixir","erlang","erlang-otp","fast","http-api","persistence","real-time","realtime","rest-api","scalable","websocket"],"latest_commit_sha":null,"homepage":null,"language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eyedouble.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-03-02T06:22:22.000Z","updated_at":"2022-10-28T01:39:42.000Z","dependencies_parsed_at":null,"dependency_job_id":"3ff6d1a5-9349-41df-8e75-e95156c7f087","html_url":"https://github.com/eyedouble/erlstore","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/eyedouble/erlstore","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eyedouble%2Ferlstore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eyedouble%2Ferlstore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eyedouble%2Ferlstore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eyedouble%2Ferlstore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eyedouble","download_url":"https://codeload.github.com/eyedouble/erlstore/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eyedouble%2Ferlstore/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31928050,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-17T10:35:34.458Z","status":"ssl_error","status_checked_at":"2026-04-17T10:35:09.472Z","response_time":62,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["access-control","authentication","authorization","database","datastore","document-database","documentdb","elixir","erlang","erlang-otp","fast","http-api","persistence","real-time","realtime","rest-api","scalable","websocket"],"created_at":"2024-11-06T17:16:06.181Z","updated_at":"2026-04-17T11:34:08.696Z","avatar_url":"https://github.com/eyedouble.png","language":"Erlang","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Erlstore](https://i.imgur.com/pFJWiF4.png)\n# Erlstore\nThe real-time document store build for reliability, \nmagically spreading over both memory and disk storage.\nA modern database with an intuitive REST API and Erlang API.\nWebsockets, access control, filtering and a web based control-panel.\n\n**THIS IS AN ALPHA RELEASE Want to contribute? mail vanwel@eyedouble.nl** \n\n## Document store\nRead section *Tables* if you did not create a table yet.\nAll methods take an optional user map as last argument to enable Access Control filtering.\nFor consiseness these variations of the API are omitted below.\n\n### GetAll\n```erlang \nerlstore_persistence:getAll ( my_table ).\n```\n\n### Get\n```erlang \nerlstore_persistence:get ( my_table, \u003c\u003c\"id\"\u003e\u003e ).\n```\n\n### Create\n*object should not contain an ID erlstore will create an UUID automatically. It will be overwritten*\n```erlang \nerlstore_persistence:create ( my_table, #{ \u003c\u003c\"data\"\u003e\u003e =\u003e \u003c\u003c\"my_data\"\u003e\u003e } ).\n```\n\n### Update\n```erlang \nerlstore_persistence:update ( my_table, Id, #{ \u003c\u003c\"data\"\u003e\u003e =\u003e \u003c\u003c\"my_new_data\"\u003e\u003e } ).\n```\n\n### Delete\n```erlang \nerlstore_persistence:update ( my_table, Id ).\n```\n\n## Filters\nYou can filter by any (nested) property on your document.\nSee the table below for operators.\n\n```erlang\nerlstore_persistence:filter ( Table, Filters, User ).\n```\n\nFilters must be a list of tuples, a filter tuple consists of property, operator, value. \nSee the example below.\n\n```erlang\n% one filter\nerlstore:persistence:filter ( Table, [{ \u003c\u003c\"_system.created\"\u003e\u003e, \u003c\u003c\"\u003e=\"\u003e\u003e, 1519138939 }] ).\n\n% multiple filters\nerlstore:persistence:filter ( Table, [\n    { \u003c\u003c\"_system.created\"\u003e\u003e, \u003c\u003c\"\u003e=\"\u003e\u003e, 1519138939 },\n    { \u003c\u003c\"_system.owner\"\u003e\u003e, \u003c\u003c\"/\"\u003e\u003e, \u003c\u003c\"irsan\"\u003e\u003e\n]).\n\n% filter with AC enabled\nerlstore:persistence:filter ( Table, [{ \u003c\u003c\"_system.created\"\u003e\u003e, \u003c\u003c\"\u003e=\"\u003e\u003e, 1519138939 }], User ).\n\n```\n\nExample object that would match:\n\n```erlang \n#{\n    \"id\" =\u003e \"c6a007de-4b82-4008-9b5c-d009e55782ae\",\n    \"name\" =\u003e \"test\",\n    \"_system\" =\u003e #{\n        \"access\" =\u003e \"superadmin\",\n        \"created\" =\u003e 1519138939,\n        \"last_editor\" =\u003e \"superadmin\",\n        \"owner\" =\u003e \"superadmin\",\n        \"updated\" =\u003e 1519138939\n    }            \n}\n```\n\n### Operators\n| Operator      | Description                                   |\n| ------------- |:---------------------------------------------:| \n| isset         | Is set                                        | \n| isnotset      | Is not set                                    | \n| =             | Exactly equal to                              | \n| /             | Exactly not equal to                          | \n| \u003c             | Lower than                                    | \n| =\u003c            | Equal to or lower than                        | \n| \u003e             | Greater than                                  | \n| \u003e=            | Equal to or greater than                      | \n| str*          | String contains                               | \n| fllen         | Flat list length equals                       | \n| fllen\u003c        | Flat list length lower than                   | \n| fllen=\u003c       | Flat list length equal to or lower than       | \n| fllen         | Flat list length greater than                 | \n| fllen\u003e=       | Flat list length equal to or greater than     | \n| flmem         | Flat list has exactly member                  | \n\n\n\n## Tables\n### Create\n```erlang \nerlstore_persistence:createTable ( my_table ).\n```\n### Delete\n```\nerlang erlstore_persistence:deleteTable ( my_table ).\n```\n\n## Domains\n### Create\nThe domain object must contain a `name` and `groups` property.\nName must be of type string.\nGroups is of type list of strings.\n\nEg.\n\n```erlang \n#{ \u003c\u003c\"name\"\u003e\u003e =\u003e \u003c\u003c\"Example domain\"\u003e\u003e, \u003c\u003c\"groups\"\u003e\u003e =\u003e [ \u003c\u003c\"admin\"\u003e\u003e, \u003c\u003c\"guests\"\u003e\u003e ] }\n```\n\n### Delete\nNot available yet due to AC logic.\n\n## Users\n### Create\nThe user object must contain an `id` and `domain` property.\nId must be of type string and is both the id as well as the username for that user.\nDomain is a combination of the `domain` id and `domain group list position` seperated by a `:`. This property is used for Access Control.\n\nEg.\n\n```erlang \n\u003c\u003c\"6a3e55d2-5344-4226-a136-a6cf18d3bccc:0\"\u003e\u003e\n```\n\n\n### Delete\nNot available yet due to AC logic.\n\n\n\n## Access Control\nAccess control in Erlstore is done on a per document basis.\n\n\n### Using AC, or not\nAll functions of the API have a AC variant and one without.\n\nEg. With and without AC respectively.\n\n```erlang \nerlstore_persistence:get ( movies, \u003c\u003c\"abf18cca-fe78-48b7-a465-b00ae8d9fc44\"\u003e\u003e, User )\n```\n\n```erlang \nerlstore_persistence:get ( movies, \u003c\u003c\"abf18cca-fe78-48b7-a465-b00ae8d9fc44\"\u003e\u003e )\n```\n\n\n\n\u003e ## Don't drink too much of the cool-aid\n\u003e\n\u003e If you use create or update functions without AC these documents are created or updated with\n\u003e SuperAdmin permissions. Hence 'normal' users cannot access them.\n\u003e \n\u003e Using non AC variant of the API is like typing `sudo` in your terminal.\n\u003e It's not bad, but it comes with extra responsibility!\n\u003e\n\n\n## Change feeds\nChange feeds allow one to receive events from a particular table by subscribing to it.\n\n### Events\n- Create\n- Update\n- Delete\n\nYou will receive messages if something in that table changes.\nIn case of create and update events one will receive the latest document.\nIn case of a delete event the last version of the deleted document is passed along.\n\n### Filtering\nAll filters as described in the section filters above may be used.\n\n\n### Subscribe\n```erlang \nerlstore_persistence:subscribe ( Pid, Table, Filters).\n```\n\nAs `Pid` is the process that will receive messages and `Table` is the table to subscribe to.\nMessages are standard Erlang messages.\n\n#### Structure\n```erlang \n{ ChangeType, Table, Data, [OldData] }\n```\n\n#### Create\n```erlang \n{2101, {create, my_table, #{ \u003c\u003cid\u003e\u003e =\u003e \u003c\u003c\"my_new_document\"\u003e\u003e, \u003c\u003c\"tests\"\u003e\u003e =\u003e 3 } } }\n```\n\n#### Update\n```erlang \n{2102, {update, my_table, #{ \u003c\u003cid\u003e\u003e =\u003e \u003c\u003c\"my_new_document\"\u003e\u003e, \u003c\u003c\"tests\"\u003e\u003e =\u003e 9 }, #{ \u003c\u003cid\u003e\u003e =\u003e \u003c\u003c\"my_new_document\"\u003e\u003e, \u003c\u003c\"tests\"\u003e\u003e =\u003e 3 } } }\n```\n\n#### Delete\n```erlang \n{2102, {delete, my_table, \u003c\u003c\"my_new_document\"\u003e\u003e } }\n```\n\n## Data dumping\nErlstore can dumping data to a binary file. This is ideal for backup and export/import purposes.\n\n#### dump_export/1\n```erlang \nerlstore_persistence:dump_export ( \"data/dump.erlstore\" ).\n```\n\n#### dump_import/1\n```erlang \nerlstore_persistence:dump_import ( \"data/dump.erlstore\" ).\n```\n\n**Erlstore's binary dump files are implementation specific. Erlstore uses Erlang Mnesia to store data. Mnesia and thuss Erlstore data is node specific for distribution purposes. This means a data dump made on one node must be altered to be used on another. Erlstore handles this automatically for you. The if such alteration is performed the file will be renamed to `{filename}._nc.{extension}`. Once Erlstore has completed importing a data file it will rename the dat file to `{filename}._imported.{extension}`**\n\n*Please note the functions `dump/2` have been deprecated and removed from the api.*\n\n\n## Erlstore status codes\n\n| Code          | Type                      | Message                            |\n| ------------- |:-------------------------:| :---------------------------------:|\n| 2000          | Ok                        | General success status |\n| 2100          | Changefeeds - create      | General success status |\n| 2101          | Changefeeds - update      | General success status |\n| 2102          | Changefeeds - delete      | General success status |\n| 4000          | Error         | General error status |\n| 4001          | Error         | Resource does not excist |\n| 4002          | Error         | Cannot create duplicate |\n| 4003          | Error         | Cannot update resource without ID |\n| 4010          | Error - Table | Cannot create on reserved table name |\n| 4020          | Error - Domain| Create domain: object does not meet requirements |\n| 4030          | Error - User  | Create user: object does not meet requirements |\n| 4031          | Error - User  | Create user: domain does not excist |\n| 5000          | Authorisation | General authorisation status |\n| 5001          | Authorisation | User not authorised to perform action |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feyedouble%2Ferlstore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feyedouble%2Ferlstore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feyedouble%2Ferlstore/lists"}