harness-drone/store/user/user.go
2019-02-19 15:56:41 -08:00

258 lines
5.7 KiB
Go

// Copyright 2019 Drone.IO Inc. All rights reserved.
// Use of this source code is governed by the Drone Non-Commercial License
// that can be found in the LICENSE file.
package user
import (
"context"
"github.com/drone/drone/store/shared/db"
"github.com/drone/drone/core"
)
// New returns a new UserStore.
func New(db *db.DB) core.UserStore {
return &userStore{db}
}
type userStore struct {
db *db.DB
}
// Find returns a user from the datastore.
func (s *userStore) Find(ctx context.Context, id int64) (*core.User, error) {
out := &core.User{ID: id}
err := s.db.View(func(queryer db.Queryer, binder db.Binder) error {
params := toParams(out)
query, args, err := binder.BindNamed(queryKey, params)
if err != nil {
return err
}
row := queryer.QueryRow(query, args...)
return scanRow(row, out)
})
return out, err
}
// FindLogin returns a user from the datastore by username.
func (s *userStore) FindLogin(ctx context.Context, login string) (*core.User, error) {
out := &core.User{Login: login}
err := s.db.View(func(queryer db.Queryer, binder db.Binder) error {
params := toParams(out)
query, args, err := binder.BindNamed(queryLogin, params)
if err != nil {
return err
}
row := queryer.QueryRow(query, args...)
return scanRow(row, out)
})
return out, err
}
// FindToken returns a user from the datastore by token.
func (s *userStore) FindToken(ctx context.Context, token string) (*core.User, error) {
out := &core.User{Hash: token}
err := s.db.View(func(queryer db.Queryer, binder db.Binder) error {
params := toParams(out)
query, args, err := binder.BindNamed(queryToken, params)
if err != nil {
return err
}
row := queryer.QueryRow(query, args...)
return scanRow(row, out)
})
return out, err
}
// List returns a list of users from the datastore.
func (s *userStore) List(ctx context.Context) ([]*core.User, error) {
var out []*core.User
err := s.db.View(func(queryer db.Queryer, binder db.Binder) error {
rows, err := queryer.Query(queryAll)
if err != nil {
return err
}
out, err = scanRows(rows)
return err
})
return out, err
}
// Create persists a new user to the datastore.
func (s *userStore) Create(ctx context.Context, user *core.User) error {
if s.db.Driver() == db.Postgres {
return s.createPostgres(ctx, user)
}
return s.create(ctx, user)
}
func (s *userStore) create(ctx context.Context, user *core.User) error {
return s.db.Lock(func(execer db.Execer, binder db.Binder) error {
params := toParams(user)
stmt, args, err := binder.BindNamed(stmtInsert, params)
if err != nil {
return err
}
res, err := execer.Exec(stmt, args...)
if err != nil {
return err
}
user.ID, err = res.LastInsertId()
return err
})
}
func (s *userStore) createPostgres(ctx context.Context, user *core.User) error {
return s.db.Lock(func(execer db.Execer, binder db.Binder) error {
params := toParams(user)
stmt, args, err := binder.BindNamed(stmtInsertPg, params)
if err != nil {
return err
}
return execer.QueryRow(stmt, args...).Scan(&user.ID)
})
}
// Update persists an updated user to the datastore.
func (s *userStore) Update(ctx context.Context, user *core.User) error {
return s.db.Lock(func(execer db.Execer, binder db.Binder) error {
params := toParams(user)
stmt, args, err := binder.BindNamed(stmtUpdate, params)
if err != nil {
return err
}
_, err = execer.Exec(stmt, args...)
return err
})
}
// Delete deletes a user from the datastore.
func (s *userStore) Delete(ctx context.Context, user *core.User) error {
return s.db.Lock(func(execer db.Execer, binder db.Binder) error {
params := toParams(user)
stmt, args, err := binder.BindNamed(stmtDelete, params)
if err != nil {
return err
}
_, err = execer.Exec(stmt, args...)
return err
})
}
// Count returns a count of active users.
func (s *userStore) Count(ctx context.Context) (int64, error) {
var out int64
err := s.db.View(func(queryer db.Queryer, binder db.Binder) error {
return queryer.QueryRow(queryCount).Scan(&out)
})
return out, err
}
const queryCount = `
SELECT COUNT(*)
FROM users
`
const queryBase = `
SELECT
user_id
,user_login
,user_email
,user_admin
,user_machine
,user_active
,user_avatar
,user_syncing
,user_synced
,user_created
,user_updated
,user_last_login
,user_oauth_token
,user_oauth_refresh
,user_oauth_expiry
,user_hash
`
const queryKey = queryBase + `
FROM users
WHERE user_id = :user_id
`
const queryLogin = queryBase + `
FROM users
WHERE user_login = :user_login
`
const queryToken = queryBase + `
FROM users
WHERE user_hash = :user_hash
`
const queryAll = queryBase + `
FROM users
ORDER BY user_login
`
const stmtUpdate = `
UPDATE users
SET
user_email = :user_email
,user_admin = :user_admin
,user_active = :user_active
,user_avatar = :user_avatar
,user_syncing = :user_syncing
,user_synced = :user_synced
,user_created = :user_created
,user_updated = :user_updated
,user_last_login = :user_last_login
,user_oauth_token = :user_oauth_token
,user_oauth_refresh = :user_oauth_refresh
,user_oauth_expiry = :user_oauth_expiry
,user_hash = :user_hash
WHERE user_id = :user_id
`
const stmtDelete = `
DELETE FROM users WHERE user_id = :user_id
`
const stmtInsert = `
INSERT INTO users (
user_login
,user_email
,user_admin
,user_machine
,user_active
,user_avatar
,user_syncing
,user_synced
,user_created
,user_updated
,user_last_login
,user_oauth_token
,user_oauth_refresh
,user_oauth_expiry
,user_hash
) VALUES (
:user_login
,:user_email
,:user_admin
,:user_machine
,:user_active
,:user_avatar
,:user_syncing
,:user_synced
,:user_created
,:user_updated
,:user_last_login
,:user_oauth_token
,:user_oauth_refresh
,:user_oauth_expiry
,:user_hash
)
`
const stmtInsertPg = stmtInsert + `
RETURNING user_id
`