Skip to content

Instantly share code, notes, and snippets.

@retroryan
Last active July 13, 2018 07:09
Show Gist options
  • Save retroryan/7448032411c415330cc5fd81ff549b3b to your computer and use it in GitHub Desktop.
Save retroryan/7448032411c415330cc5fd81ff549b3b to your computer and use it in GitHub Desktop.
Event-Sourcing with FaunaDB
#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