From 65e692b701dc73f185f731400ed9ac3b087f64ac Mon Sep 17 00:00:00 2001 From: Aaron Lindsay Date: Thu, 5 Sep 2013 21:06:15 -0400 Subject: [PATCH] Add support for adding multiple events to the database atomically --- asinkd/database.go | 24 +++++++++++++----------- asinkd/server.go | 15 +++++---------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/asinkd/database.go b/asinkd/database.go index eec76f2..82642e7 100644 --- a/asinkd/database.go +++ b/asinkd/database.go @@ -68,7 +68,7 @@ func GetAndInitDB() (*AsinkDB, error) { return ret, nil } -func (adb *AsinkDB) DatabaseAddEvent(u *User, e *asink.Event) (err error) { +func (adb *AsinkDB) DatabaseAddEvents(u *User, events []*asink.Event) (err error) { adb.lock.Lock() tx, err := adb.db.Begin() if err != nil { @@ -83,21 +83,23 @@ func (adb *AsinkDB) DatabaseAddEvent(u *User, e *asink.Event) (err error) { adb.lock.Unlock() }() - result, err := tx.Exec("INSERT INTO events (userid, type, path, hash, predecessor, timestamp, permissions) VALUES (?,?,?,?,?,?,?);", u.Id, e.Type, e.Path, e.Hash, e.Predecessor, e.Timestamp, e.Permissions) - if err != nil { - return err - } - id, err := result.LastInsertId() - if err != nil { - return err + for _, e := range events { + result, err := tx.Exec("INSERT INTO events (userid, type, path, hash, predecessor, timestamp, permissions) VALUES (?,?,?,?,?,?,?);", u.Id, e.Type, e.Path, e.Hash, e.Predecessor, e.Timestamp, e.Permissions) + if err != nil { + return err + } + id, err := result.LastInsertId() + if err != nil { + return err + } + + e.Id = id } + err = tx.Commit() if err != nil { return err } - - e.Id = id - e.InDB = true return nil } diff --git a/asinkd/server.go b/asinkd/server.go index cb4f7a4..b016a25 100644 --- a/asinkd/server.go +++ b/asinkd/server.go @@ -162,18 +162,13 @@ func putEvents(w http.ResponseWriter, r *http.Request, user *User) { error_message = err.Error() return } - for _, event := range events.Events { - err = adb.DatabaseAddEvent(user, event) - if err != nil { - //TODO should probably do this in a way that the caller knows how many of these have failed and doesn't re-try sending ones that succeeded - //i.e. add this to the return codes or something - //OR put all the DatabaseAddEvent's inside a SQL transaction, and rollback on any failure - error_message = err.Error() - return - } + err = adb.DatabaseAddEvents(user, events.Events) + if err != nil { + error_message = err.Error() + return } - broadcastToPollers(user.Id, events.Events[0]) //TODO support more than one user + broadcastToPollers(user.Id, events.Events[0]) } func eventHandler(w http.ResponseWriter, r *http.Request) {