From 0b73a5a43baab931a5837ac6a2bb6e69c70a02bc Mon Sep 17 00:00:00 2001 From: Daisuke Maki Date: Sun, 10 Jul 2016 18:18:39 +0900 Subject: [PATCH 1/6] include speaker ID in error --- octav/service/session.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/octav/service/session.go b/octav/service/session.go index 905712d..0f1d313 100644 --- a/octav/service/session.go +++ b/octav/service/session.go @@ -208,7 +208,7 @@ func (v *Session) Decorate(tx *db.Tx, session *model.Session) error { speaker := model.User{} if err := speaker.Load(tx, session.SpeakerID); err != nil { - return errors.Wrap(err, "failed to load speaker") + return errors.Wrapf(err, "failed to load speaker '%s'", session.SpeakerID) } session.Speaker = &speaker From f32723b50749c03e772a361fb2f83ba373b5e3dc Mon Sep 17 00:00:00 2001 From: Daisuke Maki Date: Sun, 10 Jul 2016 18:24:54 +0900 Subject: [PATCH 2/6] use LoadByEID --- octav/service/session.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/octav/service/session.go b/octav/service/session.go index 0f1d313..28bfd15 100644 --- a/octav/service/session.go +++ b/octav/service/session.go @@ -192,7 +192,7 @@ func (v *Session) LoadByConference(tx *db.Tx, vdbl *db.SessionList, cid string, func (v *Session) Decorate(tx *db.Tx, session *model.Session) error { // session must be associated with a conference conf := model.Conference{} - if err := conf.Load(tx, session.ConferenceID); err != nil { + if err := conf.LoadByEID(tx, session.ConferenceID); err != nil { return errors.Wrap(err, "failed to load conference") } session.Conference = &conf @@ -200,14 +200,14 @@ func (v *Session) Decorate(tx *db.Tx, session *model.Session) error { // ... but not necessarily with a room if session.RoomID != "" { room := model.Room{} - if err := conf.Load(tx, session.RoomID); err != nil { + if err := conf.LoadByEID(tx, session.RoomID); err != nil { return errors.Wrap(err, "failed to load room") } session.Room = &room } speaker := model.User{} - if err := speaker.Load(tx, session.SpeakerID); err != nil { + if err := speaker.LoadByEID(tx, session.SpeakerID); err != nil { return errors.Wrapf(err, "failed to load speaker '%s'", session.SpeakerID) } session.Speaker = &speaker From 54ec931e4b9b4634d2e0cf7fb250f8dc95e8989a Mon Sep 17 00:00:00 2001 From: Daisuke Maki Date: Sun, 10 Jul 2016 19:16:48 +0900 Subject: [PATCH 3/6] Make all conference/room/speaker optional in the backend This can happen if we delete conferences, speakers, or rooms. However, we do NOT want to lose session information because this is the most important piece of information we have --- octav/handlers.go | 9 +++++++-- octav/service/session.go | 25 +++++++++++++++++-------- octav/sql/octav.sql | 6 ++++-- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/octav/handlers.go b/octav/handlers.go index f262575..e872367 100644 --- a/octav/handlers.go +++ b/octav/handlers.go @@ -534,7 +534,7 @@ func doCreateSession(ctx context.Context, w http.ResponseWriter, r *http.Request } if err := s.Decorate(tx, &v); err != nil { - httpError(w, `LookupSession`, http.StatusInternalServerError, err) + httpError(w, `CreateSession`, http.StatusInternalServerError, errors.Wrap(err) return } @@ -1106,6 +1106,11 @@ func doListVenue(ctx context.Context, w http.ResponseWriter, r *http.Request, pa } func doLookupSession(ctx context.Context, w http.ResponseWriter, r *http.Request, payload model.LookupSessionRequest) { + if pdebug.Enabled { + g := pdebug.Marker("doLookupSession") + defer g.End() + } + tx, err := db.Begin() if err != nil { httpError(w, `LookupSession`, http.StatusInternalServerError, err) @@ -1120,7 +1125,7 @@ func doLookupSession(ctx context.Context, w http.ResponseWriter, r *http.Request } s := service.Session{} - if err := s.Decorate(tx, &v); err != nil { + if err := errors.Wrap(s.Decorate(tx, &v), "failed to decorate session with associated data"); err != nil { httpError(w, `LookupSession`, http.StatusInternalServerError, err) return } diff --git a/octav/service/session.go b/octav/service/session.go index 28bfd15..77b5498 100644 --- a/octav/service/session.go +++ b/octav/service/session.go @@ -4,6 +4,7 @@ import ( "github.com/builderscon/octav/octav/db" "github.com/builderscon/octav/octav/model" "github.com/builderscon/octav/octav/tools" + "github.com/lestrrat/go-pdebug" "github.com/pkg/errors" ) @@ -190,12 +191,18 @@ func (v *Session) LoadByConference(tx *db.Tx, vdbl *db.SessionList, cid string, } func (v *Session) Decorate(tx *db.Tx, session *model.Session) error { + if pdebug.Enabled { + g := pdebug.Marker("service.Session.Decorate") + defer g.End() + } // session must be associated with a conference - conf := model.Conference{} - if err := conf.LoadByEID(tx, session.ConferenceID); err != nil { - return errors.Wrap(err, "failed to load conference") + if session.ConferenceID != "" { + conf := model.Conference{} + if err := conf.LoadByEID(tx, session.ConferenceID); err != nil { + return errors.Wrap(err, "failed to load conference") + } + session.Conference = &conf } - session.Conference = &conf // ... but not necessarily with a room if session.RoomID != "" { @@ -206,11 +213,13 @@ func (v *Session) Decorate(tx *db.Tx, session *model.Session) error { session.Room = &room } - speaker := model.User{} - if err := speaker.LoadByEID(tx, session.SpeakerID); err != nil { - return errors.Wrapf(err, "failed to load speaker '%s'", session.SpeakerID) + if session.SpeakerID != "" { + speaker := model.User{} + if err := speaker.LoadByEID(tx, session.SpeakerID); err != nil { + return errors.Wrapf(err, "failed to load speaker '%s'", session.SpeakerID) + } + session.Speaker = &speaker } - session.Speaker = &speaker return nil } diff --git a/octav/sql/octav.sql b/octav/sql/octav.sql index 351f4df..c0a3d8b 100644 --- a/octav/sql/octav.sql +++ b/octav/sql/octav.sql @@ -100,9 +100,9 @@ CREATE TABLE conference_venues ( CREATE TABLE sessions ( oid INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, eid CHAR(64) CHARACTER SET latin1 NOT NULL, - conference_id CHAR(64) CHARACTER SET latin1 NOT NULL, + conference_id CHAR(64) CHARACTER SET latin1, room_id CHAR(64) CHARACTER SET latin1, - speaker_id CHAR(64) NOT NULL, + speaker_id CHAR(64) CHARACTER SET latin1, title TEXT NOT NULL, abstract TEXT, memo TEXT, @@ -124,6 +124,8 @@ CREATE TABLE sessions ( confirmed TINYINT(1) NOT NULL DEFAULT 0, created_on DATETIME NOT NULL, modified_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + FOREIGN KEY (speaker_id) REFERENCES users(eid) ON DELETE SET NULL, + FOREIGN KEY (conference_id) REFERENCES conferences(eid) ON DELETE SET NULL, UNIQUE KEY (eid), KEY(eid, conference_id, room_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; From 422885534625a42c2f53d8b6ee19b94d45d7a83a Mon Sep 17 00:00:00 2001 From: Daisuke Maki Date: Sun, 10 Jul 2016 19:28:13 +0900 Subject: [PATCH 4/6] fix errors --- octav/service/session.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/octav/service/session.go b/octav/service/session.go index 77b5498..c2b4a3c 100644 --- a/octav/service/session.go +++ b/octav/service/session.go @@ -198,7 +198,7 @@ func (v *Session) Decorate(tx *db.Tx, session *model.Session) error { // session must be associated with a conference if session.ConferenceID != "" { conf := model.Conference{} - if err := conf.LoadByEID(tx, session.ConferenceID); err != nil { + if err := conf.Load(tx, session.ConferenceID); err != nil { return errors.Wrap(err, "failed to load conference") } session.Conference = &conf @@ -207,7 +207,7 @@ func (v *Session) Decorate(tx *db.Tx, session *model.Session) error { // ... but not necessarily with a room if session.RoomID != "" { room := model.Room{} - if err := conf.LoadByEID(tx, session.RoomID); err != nil { + if err := room.Load(tx, session.RoomID); err != nil { return errors.Wrap(err, "failed to load room") } session.Room = &room @@ -215,7 +215,7 @@ func (v *Session) Decorate(tx *db.Tx, session *model.Session) error { if session.SpeakerID != "" { speaker := model.User{} - if err := speaker.LoadByEID(tx, session.SpeakerID); err != nil { + if err := speaker.Load(tx, session.SpeakerID); err != nil { return errors.Wrapf(err, "failed to load speaker '%s'", session.SpeakerID) } session.Speaker = &speaker From 8b481e371de969a7257bddaaee398ea321419e59 Mon Sep 17 00:00:00 2001 From: Daisuke Maki Date: Sun, 10 Jul 2016 19:33:05 +0900 Subject: [PATCH 5/6] fix import errors --- octav/handlers.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/octav/handlers.go b/octav/handlers.go index e872367..cc74bc6 100644 --- a/octav/handlers.go +++ b/octav/handlers.go @@ -11,6 +11,7 @@ import ( "github.com/lestrrat/go-apache-logformat" "github.com/lestrrat/go-jsval" "github.com/lestrrat/go-pdebug" + "github.com/pkg/errors" "golang.org/x/net/context" ) @@ -534,7 +535,7 @@ func doCreateSession(ctx context.Context, w http.ResponseWriter, r *http.Request } if err := s.Decorate(tx, &v); err != nil { - httpError(w, `CreateSession`, http.StatusInternalServerError, errors.Wrap(err) + httpError(w, `CreateSession`, http.StatusInternalServerError, errors.Wrap(err)) return } From 7ba56356f3f5075e4f81b279705bc90802f33e95 Mon Sep 17 00:00:00 2001 From: Daisuke Maki Date: Sun, 10 Jul 2016 19:36:24 +0900 Subject: [PATCH 6/6] oops, wrap here --- octav/handlers.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/octav/handlers.go b/octav/handlers.go index cc74bc6..575ece1 100644 --- a/octav/handlers.go +++ b/octav/handlers.go @@ -534,8 +534,8 @@ func doCreateSession(ctx context.Context, w http.ResponseWriter, r *http.Request return } - if err := s.Decorate(tx, &v); err != nil { - httpError(w, `CreateSession`, http.StatusInternalServerError, errors.Wrap(err)) + if err := errors.Wrap(s.Decorate(tx, &v), "failed to decorate session with associated data"); err != nil { + httpError(w, `CreateSession`, http.StatusInternalServerError, err) return }