func GetTokenByKey(conn *gorm.DB, key string) (*models.Token, error) {
	tk := &models.Token{}
	q := conn.Where(&models.Token{Key: key}).First(tk)
	if q.Error != nil {
		return nil, q.Error
	}
	return tk, nil
}
TOKEN


GetTokenByKey retrieves a token by the given key.
package query
import (
	"fmt"
	"html/template"
	sysLog "log"
	"time"
	"github.com/jinzhu/gorm"
	"github.com/zedio/zedlist/modules/forms"
	"github.com/zedio/zedlist/modules/settings"
	"github.com/drhodes/golorem"
	"github.com/oxtoacart/bpool"
	"github.com/zedio/zedlist/models"
	"golang.org/x/crypto/bcrypt"
)
func CreateJob(conn *gorm.DB, j *models.Job) error {
	return Create(conn, j)
}
func GetJobByID(conn *gorm.DB, id int64) (*models.Job, error) {
	jb := &models.Job{}
	q := conn.First(jb, id)
	if q.Error != nil {
		return nil, q.Error
	}
	return jb, nil
}
func NotFound(err error) bool {
	return err.Error() == gorm.ErrRecordNotFound.Error()
}
func GetALLJobs(conn *gorm.DB) ([]*models.Job, error) {
	jbs := []*models.Job{}
	q := conn.Order("created_at desc").Find(&jbs)
	if q.Error != nil {
		return nil, q.Error
	}
	return jbs, nil
}
func GetLatestJobs(conn *gorm.DB) ([]*models.Job, error) {
	jobs := []*models.Job{}
	q := conn.Order("created_at desc,id").Limit(settings.MaxListLimit).Find(&jobs)
	if q.Error != nil {
		return nil, q.Error
	}
	return jobs, nil
}
var bufPool = bpool.NewBufferPool(2)
func composeJob() *models.Job {
	j := &models.Job{}
	j.Title = lorem.Sentence(5, 10)
	buf := bufPool.Get()
	defer bufPool.Put(buf)
	for _ = range make([]struct{}, 2) {
		buf.WriteString(lorem.Paragraph(4, 5))
		buf.WriteString("\n")
	}
	j.Description = buf.String()
	return j
}
func PopulateDB(conn *gorm.DB) {
	sysLog.Print("Populating database...")
	var migrationData = []struct {
		name, short string
	}{
		{"mwanza", "mza"},
		{"dar es salaam", "dar"},
	}
	deadline := time.Now().Add(time.Hour)
	q := conn.First(&models.Region{})
	qj := conn.First(&models.Job{})
	qu := conn.First(&models.User{})
	if q.Error != nil && qj.Error != nil && qu.Error != nil {
		usr, err := SampleUser(conn)
		if err != nil {
			sysLog.Println(err)
		}
		for _, v := range migrationData {
			conn.FirstOrCreate(&models.Region{}, models.Region{Name: v.name, Short: v.short})
		}
		regs := []models.Region{}
		conn.Find(&regs)
		for _ = range make([]struct{}, 40) {
			for _, v := range regs {
				j := composeJob()
				j.Deadline = deadline
				j.PersonID = usr.Person.ID
				j.Region = v
				conn.Create(j)
			}
		}
	}
	sysLog.Printf("Done. \n")
}
func MigrateSession(conn *gorm.DB) {
	conn.AutoMigrate(&models.Session{})
}
func DropSession(conn *gorm.DB) {
	conn.DropTableIfExists(&models.Session{})
}
func SampleUser(conn *gorm.DB) (*models.User, error) {
	regForm := forms.Register{
		UserName:        "sneakyjeff",
		Email:           "root@home.com",
		Password:        "pass",
		ConfirmPassword: "pass",
	}
	return CreateNewUser(conn, regForm)
}
func GetUserByID(conn *gorm.DB, id int64) (*models.User, error) {
	usr := &models.User{}
	q := conn.First(usr, id)
	if q.Error != nil {
		return nil, q.Error
	}
	return usr, nil
}
func GetUserByEmail(conn *gorm.DB, email string) (*models.User, error) {
	usr := &models.User{}
	q := conn.Where(&models.User{Email: email}).First(usr)
	if q.Error != nil {
		return nil, q.Error
	}
	return usr, nil
}
func GetUserByName(conn *gorm.DB, name string) (*models.User, error) {
	usr := &models.User{}
	q := conn.Where(&models.User{Name: name}).First(usr)
	if q.Error != nil {
		return nil, q.Error
	}
	return usr, nil
}
func CreateNewUser(conn *gorm.DB, reg forms.Register) (*models.User, error) {
	_, err := GetUserByEmail(conn, reg.Email)
	if err == nil {
		return nil, fmt.Errorf("email %s already taken", reg.Email)
	}
	hashedPass, err := hashPassword(reg.Password)
	if err != nil {
		return nil, err
	}
	usr := &models.User{
		Email:    reg.Email,
		Password: hashedPass,
		Name:     reg.UserName,
		Status:   models.StatusActive,
		Person: models.Person{
			Email:      reg.Email,
			ObjectType: models.ObjPerson,
			PersonName: models.PersonName{
				Name: reg.UserName,
			},
		},
	}
	err = Create(conn, usr)
	if err != nil {
		return nil, err
	}
	return usr, nil
}
func AuthenticateUserByEmail(conn *gorm.DB, loginForm forms.Login) (*models.User, error) {
	usr, err := GetUserByEmail(conn, loginForm.Name)
	if err != nil {
		return nil, err
	}
	err = verifyPass(usr.Password, loginForm.Password)
	if err != nil {
		return nil, err
	}
	return usr, nil
}
func AuthenticateUserByName(conn *gorm.DB, loginForm forms.Login) (*models.User, error) {
	usr, err := GetUserByName(conn, loginForm.Name)
	if err != nil {
		return nil, err
	}
	err = verifyPass(usr.Password, loginForm.Password)
	if err != nil {
		return nil, err
	}
	return usr, nil
}
func verifyPass(hash, pass string) error {
	return bcrypt.CompareHashAndPassword([]byte(hash), []byte(pass))
}
func hashPassword(pass string) (string, error) {
	np, err := bcrypt.GenerateFromPassword([]byte(pass), bcrypt.DefaultCost)
	return string(np), err
}
func GetPersonByUserID(conn *gorm.DB, userID int64) (*models.Person, error) {
	p := &models.Person{}
	usr := &models.User{}
	qu := conn.First(usr, userID)
	if qu.Error != nil {
		return nil, qu.Error
	}
	q := conn.Preload("PersonName").First(p, usr.PersonID)
	if q.Error != nil {
		return nil, q.Error
	}
	return p, nil
}
func GetPersonByID(conn *gorm.DB, id int64) (*models.Person, error) {
	p := &models.Person{}
	qu := conn.Preload("PersonName").First(p, id)
	if qu.Error != nil {
		return nil, qu.Error
	}
	return p, nil
}
func PersonCreateJob(conn *gorm.DB, p *models.Person, j forms.JobForm) (*models.Job, error) {
	job := &models.Job{
		Title:       j.Title,
		Description: j.Description,
		PersonID:    p.ID,
	}
	if q := conn.Create(job); q.Error != nil {
		return nil, q.Error
	}
	return job, nil
}
func PersonDeleteJob(conn *gorm.DB, p *models.Person, jobID int) error {
	job := &models.Job{}
	q := conn.First(job, jobID)
	if q.Error != nil {
		return q.Error
	}
	return conn.Delete(job).Error
}
func GetAllRegions(conn *gorm.DB) ([]*models.Region, error) {
	regs := []*models.Region{}
	q := conn.Model(&models.Region{}).Find(&regs)
	if q.Error != nil {
		return nil, q.Error
	}
	return regs, nil
}
func GetJobByRegionShort(conn *gorm.DB, short string) ([]*models.Job, int64, error) {
	reg := &models.Region{}
	q := conn.Where(&models.Region{Short: short}).First(reg)
	if q.Error != nil {
		return nil, 0, q.Error
	}
	var count int64
	jobs := []*models.Job{}
	qerr := conn.Model(&models.Job{}).Where(&models.Job{RegionID: reg.ID}).Count(&count).
		Order("created_at desc,id").Limit(settings.MaxListLimit).Find(&jobs)
	if qerr.Error != nil {
		return nil, 0, qerr.Error
	}
	return jobs, count, nil
}
func GetJobByRegionPaginate(conn *gorm.DB, short string, offset, limit int) ([]*models.Job, error) {
	reg := &models.Region{}
	q := conn.Where(&models.Region{Short: short}).First(reg)
	if q.Error != nil {
		return nil, q.Error
	}
	jobs := []*models.Job{}
	qerr := conn.Model(&models.Job{}).Where(&models.Job{RegionID: reg.ID}).
		Order("created_at desc,id").Offset(offset).Limit(limit).Find(&jobs)
	if qerr.Error != nil {
		return nil, qerr.Error
	}
	return jobs, nil
}
func GetSessionByKey(conn *gorm.DB, key string) (*models.Session, error) {
	sess := &models.Session{}
	querry := conn.Where(&models.Session{Key: key}).First(sess)
	if querry.Error != nil {
		return nil, querry.Error
	}
	return sess, nil
}
func UpdateSession(conn *gorm.DB, sess *models.Session) error {
	ss, err := GetSessionByKey(conn, sess.Key)
	if err != nil {
		return err
	}
	ss.Data = sess.Data
	return Update(conn, ss)
}
func DeleteSession(conn *gorm.DB, key string) error {
	s, err := GetSessionByKey(conn, key)
	if err != nil {
		return err
	}
	return conn.Delete(s).Error
}
func Create(conn *gorm.DB, v interface{}) error {
	q := conn.Create(v)
	return q.Error
}
func Update(conn *gorm.DB, v interface{}) error {
	s := conn.Save(v)
	return s.Error
}
func Delete(conn *gorm.DB, v interface{}) error {
	d := conn.Delete(v)
	return d.Error
}