Add support for adding multiple events to the database atomically

This commit is contained in:
Aaron Lindsay 2013-09-05 21:06:15 -04:00
parent fcf61701cc
commit 65e692b701
2 changed files with 18 additions and 21 deletions

View File

@ -68,7 +68,7 @@ func GetAndInitDB() (*AsinkDB, error) {
return ret, nil 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() adb.lock.Lock()
tx, err := adb.db.Begin() tx, err := adb.db.Begin()
if err != nil { if err != nil {
@ -83,21 +83,23 @@ func (adb *AsinkDB) DatabaseAddEvent(u *User, e *asink.Event) (err error) {
adb.lock.Unlock() 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) for _, e := range events {
if err != nil { 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)
return err if err != nil {
} return err
id, err := result.LastInsertId() }
if err != nil { id, err := result.LastInsertId()
return err if err != nil {
return err
}
e.Id = id
} }
err = tx.Commit() err = tx.Commit()
if err != nil { if err != nil {
return err return err
} }
e.Id = id
e.InDB = true
return nil return nil
} }

View File

@ -162,18 +162,13 @@ func putEvents(w http.ResponseWriter, r *http.Request, user *User) {
error_message = err.Error() error_message = err.Error()
return return
} }
for _, event := range events.Events { err = adb.DatabaseAddEvents(user, events.Events)
err = adb.DatabaseAddEvent(user, event) if err != nil {
if err != nil { error_message = err.Error()
//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 return
//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
}
} }
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) { func eventHandler(w http.ResponseWriter, r *http.Request) {