code: func (st *Store) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error {
  	s, _ := context.Get(r, contextKey(session.Name())).(*gormSession)
  
  	// delete if max age is < 0
  	if session.Options.MaxAge < 0 {
  		if s != nil {
  			if err := st.db.Delete(s).Error; err != nil {
  				return err
  			}
  		}
  		http.SetCookie(w, sessions.NewCookie(session.Name(), "", session.Options))
  		return nil
  	}
  
  	data, err := securecookie.EncodeMulti(session.Name(), session.Values, st.Codecs...)
  	if err != nil {
  		return err
  	}
  	now := time.Now()
  	expire := now.Add(time.Second * time.Duration(session.Options.MaxAge))
  
  	if s == nil {
  		// generate random session ID key suitable for storage in the db
  		session.ID = strings.TrimRight(
  			base32.StdEncoding.EncodeToString(
  				securecookie.GenerateRandomKey(sessionIDLen)), "=")
  		s = &gormSession{
  			ID:        session.ID,
  			Data:      data,
  			CreatedAt: now,
  			UpdatedAt: now,
  			ExpiresAt: expire,
  			tableName: st.opts.TableName,
  		}
  		if err := st.db.Create(s).Error; err != nil {
  			return err
  		}
  		context.Set(r, contextKey(session.Name()), s)
  	} else {
  		s.Data = data
  		s.UpdatedAt = now
  		s.ExpiresAt = expire
  		if err := st.db.Save(s).Error; err != nil {
  			return err
  		}
  	}
  
  	// set session id cookie
  	id, err := securecookie.EncodeMulti(session.Name(), session.ID, st.Codecs...)
  	if err != nil {
  		return err
  	}
  	http.SetCookie(w, sessions.NewCookie(session.Name(), id, session.Options))
  
  	return nil
  }
docs: // Save session and set cookie header