package main import ( "database/sql" "log" _ "github.com/lib/pq" ) type Session struct { Id string UserId int64 } type User struct { Id int64 Name string Password []byte } type Store interface { GetSession(id string) (*Session, bool) NewSession(userId int64) *Session GetUser(name string) (*User, bool) } type PgStore struct { *sql.DB sessionCache map[string]*Session } func NewPgStore(database string) *PgStore { db, err := sql.Open("postgres", database) if err != nil { log.Panic(err) } return &PgStore{db, make(map[string]*Session)} } func (store *PgStore) GetSession(id string) (*Session, bool) { s, ok := store.sessionCache[id] if ok { return s, true } s = new(Session) row := store.QueryRow("SELECT id, user_id FROM sessions WHERE id = $1", id) if err := row.Scan(&s.Id, &s.UserId); err != nil { return nil, false } store.sessionCache[s.Id] = s return s, true } func (store *PgStore) NewSession(userId int64) *Session { var id string store.QueryRow("INSERT INTO sessions(user_id) VALUES ($1) RETURNING id", userId).Scan(&id) s := &Session{id, userId} store.sessionCache[s.Id] = s return s } func (store *PgStore) GetUser(name string) (*User, bool) { u := &User{Name: name} row := store.QueryRow("SELECT id, password FROM users WHERE name = $1", name) if err := row.Scan(&u.Id, &u.Password); err != nil { return nil, false } return u, true }