ActiveMemory
1070 | 1071 |A Simple ORM for ETS and Mnesia
1072 |Please note!
1073 | 1074 |This is still a work in progess and feedback is appreciated
1075 |Overview
1076 |A package to help bring the power of in memory storage with ETS and Mnesia to your Elixir application.
1077 |ActiveMemory provides a simple interface and configuration which abstracts the ETS and Mnesia specifics and provides a common interface called a Store
.
Example setup
1079 |-
1080 |
- Define a
Table
with attributes
1081 | - Define a
Store
with configuration settings or accept the defaults (most applications should be fine with defaults).
1082 | - Your app is ready! 1083 |
Example Table: 1085 |
defmodule MyApp.People.Person do
1086 | use ActiveMemory.Table attributes: [
1087 | :uuid,
1088 | :email,
1089 | :first_name,
1090 | :last_name,
1091 | :department,
1092 | :start_date,
1093 | :active,
1094 | :admin?
1095 | ]
1096 | end
1097 |
defmodule MyApp.People.Store do
1100 | use ActiveMemory.Store,
1101 | table: MyApp.People.Person
1102 | end
1103 |
defmodule MyApp.People.Store do
1106 | use ActiveMemory.Store,
1107 | table: MyApp.People.Person,
1108 | type: :ets
1109 | end
1110 |
Add the Store
to your application supervision tree:
1112 |
defmodule MyApp.Application do
1113 | # code..
1114 | def start(_type, _args) do
1115 | children = [
1116 | # other children
1117 | MyApp.People.Store,
1118 | # other children
1119 | ]
1120 | # code..
1121 | end
1122 | end
1123 |
Now you have the default Store
methods available!
Store API
1126 |-
1127 |
Store.all/0
Get all records stored
1128 | Store.delete/1
Delete the record provided
1129 | Store.delete_all/0
Get all records stored
1130 | Store.one/1
Get a record matching either an attributes search ormatch
query
1131 | Store.select/1
Get all records matching either attributes search ormatch
query
1132 | Store.withdraw/1
Get a record matching either an attributes search ormatch
query, delete the record and return it.
1133 | Store.write/1
Write the record into the memmory table
1134 |
Query interface
1136 |There are two different query types availabe to make finding the records in your store.
1137 |The Attribute query syntax
1138 |Attribute matching allows you to provide a map of attributes to search by. 1139 |
Store.one(%{uuid: "a users uuid"})
1140 | Store.select(%{department: "accounting", admin?: false, active: true})
1141 |
The match
query syntax
1143 | Using the match
macro you can strucure a basic query.
1144 |
query = match(:department == "sales" or :department == "marketing" and :start_date > last_month)
1145 | Store.select(query)
1146 |
Seeding
1148 |When starting a Store
there is an option to provide a valid seed file and have the Store
auto load seeds contained in the file.
1149 |
defmodule MyApp.People.Store do
1150 | use ActiveMemory.Store,
1151 | table: MyApp.People.Person,
1152 | seed_file: Path.expand("person_seeds.exs", __DIR__)
1153 | end
1154 |
Before init
1156 | All stores are GenServers
and have init
functions. While those are abstracted you can still specify methods to run during the init
phase of the GenServer startup. Use the before_init
keyword and add the methods as tuples with the arguments.
1157 |
defmodule MyApp.People.Store do
1158 | use ActiveMemory.Store,
1159 | table: MyApp.People.Person,
1160 | before_init: [{:run_me, ["arg1", "arg2"]}, {:run_me_too, []}]
1161 | end
1162 |
Initial State
1164 |All stores are GenServers
and thus have a state. The default state is an array as such:
1165 |
%{started_at: "date time when first started", table_name: MyApp.People.Store}
1166 |
defmodule MyApp.People.Store do
1169 | use ActiveMemory.Store,
1170 | table: MyApp.People.Person,
1171 | before_init: [{:run_me, ["arg1", "arg2"]}, {:run_me_too, []}]
1172 | end
1173 |
Installation
1176 |The package can be installed
1177 | by adding active_memory
to your list of dependencies in mix.exs
:
def deps do
1179 | [
1180 | {:active_memory, "~> 0.1.0"}
1181 | ]
1182 | end
1183 |
Potential Use Cases
1186 |There are many reasons to be leveraging the power of in memory store and the awesome tools of Mnesia and ETS in your Elixir applications.
1187 |Storing config settings and Application secrets
1188 |Instad of having hard coded secrets and application settings crowding your config files store them in an in memory table. Privde your application a small UI to support the secrets and settings and you can update while the application is running in a matter of seconds.
1189 |One Time Use Tokens
1190 |Perfect for short lived tokens such as password reset tokens, 2FA tokens, majic links (passwordless login) etc. Store the tokens and any other needed data into an ActiveMemory.Store
and reduce the burden of your database and provide your users a better experience with faster responses.
API Keys
1192 |If your application has a small set of API Keys (ex: less than a thousand) for clients accessing your API, then store the keys along with any relavent information into an ActiveMemory.Store
and reduce the burden of your database and provide your users a better experience with faster responses.
JWT Encryption Keys
1194 |If your application uses JWT then you can store the keys in an ActiveMemory.Store
and provide fast access for encrypting JWT’s and publishing the public keys on an endpoint so consumers can verify the tokens.
Admin User Management
1196 |Create an ActiveMemory.Store
to manage your admins easily and safely.
and many many many more…