Last active
July 13, 2018 07:09
-
-
Save retroryan/7448032411c415330cc5fd81ff549b3b to your computer and use it in GitHub Desktop.
Event-Sourcing with FaunaDB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#create class | |
CreateClass({ name: "ledger" }) | |
#create index | |
CreateIndex( | |
{ | |
name: "UNIQUE_ENTRY_CONSTRAINT", | |
source: Class("ledger"), | |
terms: [{ field: ["data", "clientId"] }], | |
values: [{ field: ["data", "counter"] }], | |
unique: true | |
}) | |
#create index | |
CreateIndex( | |
{ | |
name: "ledger_client_id", | |
source: Class("ledger"), | |
terms: [{ field: ["data", "clientId"] }], | |
values: [{ field: ["data", "counter"], reverse:true }, { field: ["ref"] }], | |
unique: false, | |
serialized: true | |
}) | |
#read the index back out | |
Get(Index("ledger_client_id")) | |
#create class instance | |
Create(Class("ledger"), | |
{ data: {"clientId":50,"counter":0,"type":"DEPOSIT","description":"NEW DEPOSIT", "amount":28.19} }) | |
#This will fail with Error: instance not unique | |
Create(Class("ledger"), | |
{ data: {"clientId":50,"counter":0,"type":"DEPOSIT","description":"NEW DEPOSIT", "amount":28.19} }) | |
#Select out the counter of the saved ledger class instance | |
Select(["data", "counter"], Create(Class("ledger"),{ data: {"clientId":50,"counter":5,"type":"DEPOSIT","description":"NEW DEPOSIT", "amount":28.19} })) | |
#Paginate through the index | |
Paginate(Match(Index("ledger_client_id"), 50)) | |
#Select out the latest counter of the ledger client 100 - should not exist so it will return default of 0 | |
Select([0,0], | |
Paginate(Match(Index("ledger_client_id"), 100)), 0 | |
) | |
#Setting the variable latest to the last counter in the ledger (or 0 if not found) and then adding 1 to it to get the next counter for this client | |
Let( | |
{latest: Add( | |
Select([0,0], | |
Paginate(Match(Index("ledger_client_id"), 100)),0 | |
),1) | |
}, | |
Var("latest") | |
) | |
#Example If query | |
If(Equals(20, 20), | |
["saved", 7], | |
["not_saved",9] | |
) | |
#Example of conditionaly creating a class instance | |
If( | |
Equals(7, 7), | |
["saved", | |
Select(["data", "counter"], Create(Class("ledger"), | |
{ data: {"clientId":50,"counter":7,"type":"DEPOSIT", "description":"NEW DEPOSIT", "amount":28.19} })) | |
], | |
["not_saved",6] | |
) | |
#Putting that all together in a complete query | |
#If the counter passed into the query (simulated as 1 in this case) is equal to the latest expected counter then save this class instance | |
#This returns an array with 2 elements. String with the status of whether the instance was saved and the counter that was saved or expected. | |
#To test run this once with the counter set to 1 and it should return ["saved",1] | |
#Run it again, still with the counter equal to 1 and now it should return ["not_saved",2] - 2 being the expected counter value | |
#Finally update counter to 2 and should then return ["saved",2] | |
Let( | |
{latest: Add( | |
Select([0,0], | |
Paginate(Match(Index("ledger_client_id"), 100)),0 | |
),1), | |
counter: 3 | |
}, | |
If(Equals(Var("counter"), Var("latest")), | |
["saved", | |
Select(["data", "counter"], Create(Class("ledger"), | |
{ data: {"clientId":100,"counter":Var("counter"),"type":"DEPOSIT","description":"NEW DEPOSIT", "amount":28.19} })) | |
], | |
["not_saved",Var("latest")] | |
) | |
) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment