func (kind *Kind) updateIDField(ent interface{}, idvalue string) string { entValue := reflect.Indirect(reflect.ValueOf(ent)) idfield := entValue.FieldByName(kind.IDFieldName) keystr := idfield.String() idfieldType := idfield.Type() if keystr != "" { // already have an ID value return keystr } // if idvalue is not specified, use UUID. if idvalue == "" { idvalue = string(wcg.NewUUID()) } if idfieldType == _UUIDType && wcg.IsUUID(idvalue) { idfield.Set(reflect.ValueOf(wcg.UUID(idvalue))) } else { idfield.Set(reflect.ValueOf(idvalue)) } return idvalue }
// SessionSupportWithConfig returns two middleware functions for session support, which need to be registered // on route.Before and route.After. // // Example: // // sprepare, scomplete := SessionSupport() // // route.Before(sprepare) // route.After(scomplete) // func SessionSupportWithConfig(cfg *SessionConfig) (wcg.Handler, wcg.Handler) { if cfg.StoreFactory == nil { memorystore := wcg.NewMemorySessionStore() cfg.StoreFactory = func(req *wcg.Request) wcg.SessionStore { req.Logger.Warnf("Memory SessionStore is used so that the session data would lost suddenly.") req.Logger.Warnf("If you are in GAE environment (including devserver), you must use GAESessionStoreFactory") return memorystore } } // load handler loads the session data from backend storage. load := func(res *wcg.Response, req *wcg.Request) { if res.IsClosed() { return } var sess *wcg.Session var err error store := cfg.StoreFactory(req) c, err := req.SignedCookie(cfg.CookieName, cfg.Key) if err != nil { req.Logger.Debugf("Could not decode the signed cookie on %s: %v", cfg.Key, err) } if c != nil { if wcg.IsUUID(c.Value) { sess, err = store.Load(wcg.UUID(c.Value)) } if err != nil { req.Logger.Warnf( "Could not load the session (id: %q) from the store (%v), use a new session.", err, c.Value) sess = nil c = nil } else { if sess == nil { req.Logger.Debugf("Session data for %q was not found on backend.", c.Value) } else { req.Logger.Debugf("Session data for %q found.", c.Value) expiredAt := sess.Timestamp.Add(time.Duration(cfg.MaxAge) * time.Second) if expiredAt.Before(time.Now()) { // expired req.Logger.Infof("Session data for %q is found but expired.", c.Value) if _, err := store.Delete(sess.ID); err != nil { req.Logger.Errorf("An error occurred while deleting the expired session (%q): %v", sess.ID, err) } sess = nil } } } } if c == nil { // no cookie found c = &http.Cookie{} c.Name = cfg.CookieName c.HttpOnly = cfg.HTTPOnly c.MaxAge = cfg.MaxAge if cfg.Domain != "" { c.Domain = cfg.Domain } } c.Path = cfg.Path // No session found if sess == nil { sess = wcg.NewSession(req) sess.Timestamp = time.Now() req.Logger.Debugf("Creating the new session.") store := cfg.StoreFactory(req) err := store.Save(sess) if err != nil { res.RenderInternalError("New Session could not be created: %v", err) return } } else { // Update the timestamp. sess.Timestamp = time.Now() } // Set the cookie data c.Value = string(sess.ID) c.Expires = sess.Timestamp.Add(time.Duration(cfg.MaxAge) * time.Second) c.MaxAge = cfg.MaxAge req.Session = sess encoded, _ := sess.Encode() req.SetLocal("__session_support", encoded) res.SetSignedCookie(c, cfg.Key) } // save handler store the cookie data into backend storage. save := func(res *wcg.Response, req *wcg.Request) { if encoded, ok := req.Local("__session_support").(string); ok { nencoded, _ := req.Session.Encode() // Store session if it is changed. if encoded != nencoded { store := cfg.StoreFactory(req) err := store.Save(req.Session) if err != nil { // TODO: log session error req.Logger.Errorf("Could not save the session data on backend: %v", err) } else { req.Logger.Debugf("Successfully stored the session data on backend.") } } else { req.Logger.Debugf("Session is not changed, skipped to be stored.") } } } return wcg.NewNamedHandler("Session.Load", load), wcg.NewNamedHandler("Session.Save", save) }
func (kind *Kind) DeleteMulti() *DeleteMulti { base := &methodBase{} base.kind = kind return &DeleteMulti{ base: base, } } // DeleteQuery returns *DeleteQuery operation helper func (kind *Kind) DeleteQuery() *DeleteQuery { return &DeleteQuery{ query: kind.Query(), } } var _UUIDType = reflect.TypeOf(wcg.UUID("")) func (kind *Kind) updateIDField(ent interface{}, idvalue string) string { entValue := reflect.Indirect(reflect.ValueOf(ent)) idfield := entValue.FieldByName(kind.IDFieldName) keystr := idfield.String() idfieldType := idfield.Type() if keystr != "" { // already have an ID value return keystr } // if idvalue is not specified, use UUID. if idvalue == "" { idvalue = string(wcg.NewUUID()) } if idfieldType == _UUIDType && wcg.IsUUID(idvalue) {