173 lines
4.7 KiB
CoffeeScript
173 lines
4.7 KiB
CoffeeScript
|
|
class DBTransaction
|
|
constructor: (@t)->
|
|
|
|
setOperation: (op)->
|
|
that = this
|
|
new Promise (resolve, reject)->
|
|
req = that.t.objectStore("HistoryBuffer").put op
|
|
req.onsuccess = (event)->
|
|
resolve op
|
|
req.onerror = (event)->
|
|
reject "Could not set Operation!"
|
|
|
|
getOperation: (uid)->
|
|
that = this
|
|
new Promise (resolve, reject)->
|
|
req = that.t.objectStore("HistoryBuffer").get uid
|
|
req.onsuccess = (event)->
|
|
resolve req.result
|
|
req.onerror = (event)->
|
|
reject "Could not get Operation!"
|
|
|
|
getOperations: (state_map)->
|
|
flow = Promise.resolve()
|
|
ops = []
|
|
that = this
|
|
hb = that.t.objectStore("HistoryBuffer")
|
|
|
|
that.getStateVector().then (end_state_vector)->
|
|
for end_state of end_state_vector
|
|
# convert to the db-structure
|
|
do (end_state = end_state)->
|
|
start_state =
|
|
user: end_state.name
|
|
state: state_map[end_state] ? 0
|
|
|
|
flow = flow.then ()->
|
|
from = [start_state.user, start_state.number]
|
|
to = [end_state.user, end_state.number]
|
|
range = IDBKeyRange.bound from, to
|
|
defer = Promise.defer()
|
|
|
|
hb.openCursor(range).onsuccess = ()->
|
|
cursor = event.target.result
|
|
if cursor?
|
|
ops.push cursor.value # add Operation
|
|
cursor.continue()
|
|
else
|
|
# got all ops from this user
|
|
defer.resolve ops
|
|
defer.promise
|
|
|
|
setState: (state)->
|
|
that = this
|
|
new Promise (resolve, reject)->
|
|
req = that.t.objectStore("StateVector").put state
|
|
req.onsuccess = (event)->
|
|
resolve state
|
|
req.onerror = (event)->
|
|
reject "Could not set state vector!"
|
|
|
|
getState: (user)->
|
|
defer = Promise.defer()
|
|
req = @t.objectStore("StateVector").get user
|
|
req.onsuccess = (event)->
|
|
defer.resolve req.result
|
|
req.onerror = (event)->
|
|
defer.reject "Could not get state vector!"
|
|
defer.promise
|
|
|
|
getStateVector: ()->
|
|
defer = Promise.defer()
|
|
state_vector = []
|
|
@t.objectStore("StateVector").openCursor().onsuccess = ()->
|
|
cursor = event.target.result
|
|
if cursor?
|
|
state = cursor.value
|
|
state_vector.push state
|
|
cursor.continue()
|
|
else
|
|
# got all ops from this user
|
|
defer.resolve state_vector
|
|
defer.promise
|
|
|
|
|
|
|
|
class Transaction
|
|
constructor: (@t)->
|
|
|
|
updateOperation: (op)->
|
|
@t.setOperation op
|
|
|
|
addOperation: (op)->
|
|
that = this
|
|
@t.getState op.uid[0]
|
|
.then (state)->
|
|
# only add operation if this is an expected operation
|
|
if not state?
|
|
state =
|
|
user: op.uid[0]
|
|
number: 0
|
|
if op.uid[1] is state.number
|
|
state.number++
|
|
that.t.setState state
|
|
else
|
|
return Promise.reject("Unexpected Operation")
|
|
.then that.t.setOperation op
|
|
|
|
getOperation: (uid)->
|
|
@t.getOperation uid
|
|
|
|
getState: (user)->
|
|
@t.getState user
|
|
|
|
getOperations: (state_vector)->
|
|
@t.getOperations state_vector
|
|
|
|
|
|
class window.DB
|
|
constructor: ()->
|
|
@ready = (new Promise (resolve, reject)->
|
|
req = indexedDB.open "Testy", 7
|
|
req.onerror = ()->
|
|
reject "Couldn't open the IndexedDB database!"
|
|
req.onsuccess = (event)->
|
|
resolve event.target.result
|
|
req.onupgradeneeded = (event)->
|
|
db = event.target.result
|
|
objectStore = db.createObjectStore "HistoryBuffer", {keyPath: "uid"}
|
|
objectStore = db.createObjectStore "StateVector", {keyPath: "user"}
|
|
|
|
).catch (message)->
|
|
throw new Error message
|
|
|
|
requestTransaction: ()->
|
|
@ready.then (db)->
|
|
new Promise (resolve, reject)->
|
|
resolve new Transaction( new DBTransaction(db.transaction(["HistoryBuffer", "StateVector"], "readwrite")) )
|
|
|
|
removeDatabase: ()->
|
|
req = indexedDB.deleteDatabase "Testy"
|
|
req.onsuccess = ()->
|
|
console.log("Deleted database successfully");
|
|
req.onblocked = ()->
|
|
console.log("Database is currently being blocked")
|
|
console.dir arguments
|
|
req.onerror = ()->
|
|
console.log("Couldn't delete database")
|
|
console.dir arguments
|
|
null
|
|
|
|
window.db = new DB()
|
|
|
|
window.addDummyDataSet = ()->
|
|
db.requestTransaction().then (t)->
|
|
t.getState("dmonad").then (state)->
|
|
state ?= {number: 0}
|
|
t.addOperation({uid: ["dmonad", state.number]})
|
|
|
|
window.getOp = (num = 3)->
|
|
db.requestTransaction().then (t)->
|
|
t.getOperation(["dmonad", num])
|
|
.then (op)->
|
|
console.log("yay:")
|
|
console.log(op)
|
|
|
|
window.getOps = (state_map = {dmonad: 5})->
|
|
db.requestTransaction().then (t)->
|
|
t.getOperations(state_map)
|
|
.then (op)->
|
|
console.log("yay:")
|
|
console.log(op)
|