secret
Last active

Mix in action

  • Download Gist
example.sql
SQL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
CREATE TABLE Publisher
(
id text AUTO, -- auto-generated, uuid
stacks set of text REFERENCES Stacks, -- primary key ref
sub_count int, -- Subscription.stack.publisher.id
PRIMARY KEY (id)
);
 
CREATE TABLE Stack
(
id text AUTO,
publisher text NOT NULL REFERENCES Publisher,
subscriptions set of text REFERENCES Subscription,
PRIMARY KEY (id)
);
 
CREATE TABLE Subscription
(
id text AUTO,
user text NOT NULL REFERENCES User,
stack text NOT NULL REFERENCES Stack,
notify_freq text NOT NULL,
language text NOT NULL,
last_notified int,
primary key (id)
);
 
CREATE TABLE NewDocs
(
stack text NOT NULL REFERENCES Stack,
add_date int NOT NULL,
doc_id text NOT NULL,
PRIMARY KEY (stack),
SECONDARY KEY (add_date)
);
 
CREATE TABLE User
(
id text NOT NULL,
subscriptions set of text REFERENCES Subscription,
PRIMARY KEY (id)
);
 
CREATE TABLE UnconfirmedEmails
(
id text AUTO,
email text NOT NULL,
PRIMARY KEY (id)
);
 
 
-- CREATE TRIGGER reminder2
-- ON Sales.Customer
-- AFTER INSERT, UPDATE, DELETE
-- AS
publisher.erl
Erlang
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
-module(publisher).
 
-export([
setup/2,
teardown/0,
describe/0,
create/1,
delete/1,
fetch/1,
store/2,
add_to_stacks/2,
remove_from_stacks/2,
bump_sub_count/2
]).
 
setup(RPS, WPS) ->
ddb:create_table(<<"Publisher">>, RPS, WPS).
 
teardown() ->
ddb:remove_table(<<"Publisher">>).
 
describe() ->
ddb:describe_table(<<"Publisher">>).
 
create(Values) ->
Values1 = mix:auto_gen(Values, [ {<<"id">>, 'string'} ]),
Args = mix:prep_ddb_args(Values1, [
{<<"id">>, 'string'},
{<<"sub_count">>, 'number'},
{<<"stacks">>, 'string_set'}
]),
ddb:put(<<"Publisher">>, Args).
 
delete(Id) ->
ddb:delete(<<"Publisher">>, ddb:key_value(Id, 'string')).
 
fetch(Id) ->
ddb:get(<<"Publisher">>, ddb:key_value(Id, 'string')).
 
store(Id, Values) ->
Args = mix:prep_ddb_args(Values, 'put', [
{<<"sub_count">>, 'number'},
{<<"stacks">>, 'string_set'}
]),
ddb:update(<<"Publisher">>, ddb:key_value(Id, 'string'), Args).
 
add_to_stacks(Id, Values) ->
ddb:update(<<"Publisher">>, ddb:key_value(Id, 'string'), [{<<"stacks">>, Values, 'string_set', 'add'}]).
 
remove_from_stacks(Id, Values) ->
ddb:update(<<"Publisher">>, ddb:key_value(Id, 'string'), [{<<"stacks">>, Values, 'string_set', 'delete'}]).
 
bump_sub_count(Id, Value) ->
ddb:update(<<"Publisher">>, ddb:key_value(Id, 'string'), [{<<"sub_count">>, Value, 'number', 'add'}]).
stack.erl
Erlang
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
-module(stack).
 
-export([
setup/2,
teardown/0,
describe/0,
create/1,
delete/1,
fetch/1,
store/2,
add_to_subscriptions/2,
remove_from_subscriptions/2
]).
 
setup(RPS, WPS) ->
ddb:create_table(<<"Stack">>, RPS, WPS).
 
teardown() ->
ddb:remove_table(<<"Stack">>).
 
describe() ->
ddb:describe_table(<<"Stack">>).
 
create(Values) ->
Values1 = mix:auto_gen(Values, [ {<<"id">>, 'string'} ]),
Args = mix:prep_ddb_args(Values1, [
{<<"id">>, 'string'},
{<<"subscriptions">>, 'string_set'},
{<<"publisher">>, 'string'}
]),
ddb:put(<<"Stack">>, Args),
PrimaryKey = proplists:get_value(<<"id">>, Values1),
publisher:add_to_stacks(Id, [PrimaryKey]).
 
delete(Id) ->
ddb:delete(<<"Stack">>, ddb:key_value(Id, 'string')),
PrimaryKey = proplists:get_value(<<"id">>, Values1),
publisher:remove_from_stacks(Id, [PrimaryKey]).
 
fetch(Id) ->
ddb:get(<<"Stack">>, ddb:key_value(Id, 'string')).
 
store(Id, Values) ->
Args = mix:prep_ddb_args(Values, 'put', [
{<<"subscriptions">>, 'string_set'},
{<<"publisher">>, 'string'}
]),
ddb:update(<<"Stack">>, ddb:key_value(Id, 'string'), Args).
 
add_to_subscriptions(Id, Values) ->
ddb:update(<<"Stack">>, ddb:key_value(Id, 'string'), [{<<"subscriptions">>, Values, 'string_set', 'add'}]).
 
remove_from_subscriptions(Id, Values) ->
ddb:update(<<"Stack">>, ddb:key_value(Id, 'string'), [{<<"subscriptions">>, Values, 'string_set', 'delete'}]).
subscription.erl
Erlang
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
-module(subscription).
 
-export([
setup/2,
teardown/0,
describe/0,
create/1,
delete/1,
fetch/1,
store/2,
bump_last_notified/2
]).
 
setup(RPS, WPS) ->
ddb:create_table(<<"Subscription">>, RPS, WPS).
 
teardown() ->
ddb:remove_table(<<"Subscription">>).
 
describe() ->
ddb:describe_table(<<"Subscription">>).
 
create(Values) ->
Values1 = mix:auto_gen(Values, [ {<<"id">>, 'string'} ]),
Args = mix:prep_ddb_args(Values1, [
{<<"id">>, 'string'},
{<<"last_notified">>, 'number'},
{<<"language">>, 'string'},
{<<"notify_freq">>, 'string'},
{<<"stack">>, 'string'},
{<<"user">>, 'string'}
]),
ddb:put(<<"Subscription">>, Args),
PrimaryKey = proplists:get_value(<<"id">>, Values1),
user:add_to_subscriptions(Id, [PrimaryKey]),
stack:add_to_subscriptions(Id, [PrimaryKey]).
 
delete(Id) ->
ddb:delete(<<"Subscription">>, ddb:key_value(Id, 'string')),
PrimaryKey = proplists:get_value(<<"id">>, Values1),
user:remove_from_subscriptions(Id, [PrimaryKey]),
stack:remove_from_subscriptions(Id, [PrimaryKey]).
 
fetch(Id) ->
ddb:get(<<"Subscription">>, ddb:key_value(Id, 'string')).
 
store(Id, Values) ->
Args = mix:prep_ddb_args(Values, 'put', [
{<<"last_notified">>, 'number'},
{<<"language">>, 'string'},
{<<"notify_freq">>, 'string'},
{<<"stack">>, 'string'},
{<<"user">>, 'string'}
]),
ddb:update(<<"Subscription">>, ddb:key_value(Id, 'string'), Args).
 
bump_last_notified(Id, Value) ->
ddb:update(<<"Subscription">>, ddb:key_value(Id, 'string'), [{<<"last_notified">>, Value, 'number', 'add'}]).

Note that Amazon DynamoDB has no built-in referential integrity so I generate the code for it. For example, the code in subscription:create updates both User and Publisher "tables".

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.