package account import ( "arimelody-web/model" "strings" "github.com/jmoiron/sqlx" _ "github.com/lib/pq" ) type ( AccountRepositoryPostgres struct { db *sqlx.DB } ) var _ AccountRepository = new(AccountRepositoryPostgres) func NewAccountRepositoryPostgres(db *sqlx.DB) *AccountRepositoryPostgres { return &AccountRepositoryPostgres{ db: db } } func (repo *AccountRepositoryPostgres) GetAll() ([]model.Account, error) { var accounts = []model.Account{} err := repo.db.Select(&accounts, "SELECT * FROM account ORDER BY created_at ASC") if err != nil { return nil, err } return accounts, nil } func (repo *AccountRepositoryPostgres) GetCount() (int, error) { accountsCount := 0 err := repo.db.Get(&accountsCount, "SELECT count(*) FROM account") return accountsCount, err } func (repo *AccountRepositoryPostgres) GetByID(id string) (*model.Account, error) { var account = model.Account{} err := repo.db.Get(&account, "SELECT * FROM account WHERE id=$1", id) if err != nil { if strings.Contains(err.Error(), "no rows") { return nil, nil } return nil, err } return &account, nil } func (repo *AccountRepositoryPostgres) GetByUsername(username string) (*model.Account, error) { var account = model.Account{} err := repo.db.Get(&account, "SELECT * FROM account WHERE username=$1", username) if err != nil { if strings.Contains(err.Error(), "no rows") { return nil, nil } return nil, err } return &account, nil } func (repo *AccountRepositoryPostgres) GetByEmail(email string) (*model.Account, error) { var account = model.Account{} err := repo.db.Get(&account, "SELECT * FROM account WHERE email=$1", email) if err != nil { if strings.Contains(err.Error(), "no rows") { return nil, nil } return nil, err } return &account, nil } func (repo *AccountRepositoryPostgres) GetBySession(sessionToken string) (*model.Account, error) { if sessionToken == "" { return nil, nil } account := model.Account{} err := repo.db.Get(&account, "SELECT account.* FROM account JOIN token ON id=account WHERE token=$1", sessionToken) if err != nil { if strings.Contains(err.Error(), "no rows") { return nil, nil } return nil, err } return &account, nil } func (repo *AccountRepositoryPostgres) Create( username string, password string, email *string, avatarURL *string, ) (string, error) { var id string err := repo.db.Get( &id, "INSERT INTO account (username, password, email, avatar_url) " + "VALUES ($1, $2, $3, $4) " + "RETURNING id", username, password, email, avatarURL, ) return id, err } func (repo *AccountRepositoryPostgres) Update( id string, username string, password string, email *string, avatarURL *string, ) error { _, err := repo.db.Exec( "UPDATE account " + "SET username=$2,password=$3,email=$4,avatar_url=$5 " + "WHERE id=$1", id, username, password, email, avatarURL, ) return err } func (repo *AccountRepositoryPostgres) ChangeUsername(id string, username string) error { _, err := repo.db.Exec( "UPDATE account SET username=$2 WHERE id=$1", id, username, ) return err } func (repo *AccountRepositoryPostgres) ChangePassword(id string, password string) error { _, err := repo.db.Exec( "UPDATE account SET password=$2 WHERE id=$1", id, password, ) return err } func (repo *AccountRepositoryPostgres) ChangeEmail(id string, email string) error { _, err := repo.db.Exec( "UPDATE account SET email=$2 WHERE id=$1", id, email, ) return err } func (repo *AccountRepositoryPostgres) RemoveEmail(id string) error { _, err := repo.db.Exec("UPDATE account SET email=NULL WHERE id=$1", id) return err } func (repo *AccountRepositoryPostgres) ChangeAvatarURL(id string, avatarURL string) error { _, err := repo.db.Exec( "UPDATE account SET avatar_url=$2 WHERE id=$1", id, avatarURL, ) return err } func (repo *AccountRepositoryPostgres) RemoveAvatar(id string) error { _, err := repo.db.Exec("UPDATE account SET avatar_url=NULL WHERE id=$1", id) return err } func (repo *AccountRepositoryPostgres) Delete(accountID string) error { _, err := repo.db.Exec("DELETE FROM account WHERE id=$1", accountID) return err } // Increment the number of account login failure attempts, // returning the current fail count. func (repo *AccountRepositoryPostgres) IncrementFails(accountID string) (int, error) { failAttempts := 0 err := repo.db.Get(&failAttempts, "UPDATE account SET fail_attempts = fail_attempts + 1 WHERE id=$1 RETURNING fail_attempts", accountID) return failAttempts, err } func (repo *AccountRepositoryPostgres) Lock(accountID string) error { _, err := repo.db.Exec("UPDATE account SET locked = true WHERE id=$1", accountID) return err } func (repo *AccountRepositoryPostgres) Unlock(accountID string) error { _, err := repo.db.Exec("UPDATE account SET locked = false, fail_attempts = 0 WHERE id=$1", accountID) return err }