mirror of
https://github.com/harness/drone.git
synced 2025-05-06 17:00:54 +08:00
Removed sync store for token/service/user/service-acc (#139)
This commit is contained in:
parent
e4ae2b269b
commit
ae6e864f57
@ -6,10 +6,10 @@ package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"github.com/harness/gitness/internal/store"
|
||||
"github.com/harness/gitness/internal/store/database/dbtx"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
|
||||
@ -43,10 +43,13 @@ type ServiceStore struct {
|
||||
|
||||
// Find finds the service by id.
|
||||
func (s *ServiceStore) Find(ctx context.Context, id int64) (*types.Service, error) {
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
dst := new(service)
|
||||
if err := s.db.GetContext(ctx, dst, serviceSelectID, id); err != nil {
|
||||
if err := db.GetContext(ctx, dst, serviceSelectID, id); err != nil {
|
||||
return nil, processSQLErrorf(err, "Select by id query failed")
|
||||
}
|
||||
|
||||
return s.mapDBService(dst), nil
|
||||
}
|
||||
|
||||
@ -60,10 +63,13 @@ func (s *ServiceStore) FindUID(ctx context.Context, uid string) (*types.Service,
|
||||
return nil, store.ErrResourceNotFound
|
||||
}
|
||||
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
dst := new(service)
|
||||
if err = s.db.GetContext(ctx, dst, serviceSelectUIDUnique, uidUnique); err != nil {
|
||||
if err = db.GetContext(ctx, dst, serviceSelectUIDUnique, uidUnique); err != nil {
|
||||
return nil, processSQLErrorf(err, "Select by uid query failed")
|
||||
}
|
||||
|
||||
return s.mapDBService(dst), nil
|
||||
}
|
||||
|
||||
@ -74,12 +80,14 @@ func (s *ServiceStore) Create(ctx context.Context, svc *types.Service) error {
|
||||
return fmt.Errorf("failed to map db service: %w", err)
|
||||
}
|
||||
|
||||
query, arg, err := s.db.BindNamed(serviceInsert, dbSVC)
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
query, arg, err := db.BindNamed(serviceInsert, dbSVC)
|
||||
if err != nil {
|
||||
return processSQLErrorf(err, "Failed to bind service object")
|
||||
}
|
||||
|
||||
if err = s.db.QueryRowContext(ctx, query, arg...).Scan(&svc.ID); err != nil {
|
||||
if err = db.QueryRowContext(ctx, query, arg...).Scan(&svc.ID); err != nil {
|
||||
return processSQLErrorf(err, "Insert query failed")
|
||||
}
|
||||
|
||||
@ -93,12 +101,14 @@ func (s *ServiceStore) Update(ctx context.Context, svc *types.Service) error {
|
||||
return fmt.Errorf("failed to map db service: %w", err)
|
||||
}
|
||||
|
||||
query, arg, err := s.db.BindNamed(serviceUpdate, dbSVC)
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
query, arg, err := db.BindNamed(serviceUpdate, dbSVC)
|
||||
if err != nil {
|
||||
return processSQLErrorf(err, "Failed to bind service object")
|
||||
}
|
||||
|
||||
if _, err = s.db.ExecContext(ctx, query, arg...); err != nil {
|
||||
if _, err = db.ExecContext(ctx, query, arg...); err != nil {
|
||||
return processSQLErrorf(err, "Update query failed")
|
||||
}
|
||||
|
||||
@ -107,38 +117,40 @@ func (s *ServiceStore) Update(ctx context.Context, svc *types.Service) error {
|
||||
|
||||
// Delete deletes the service.
|
||||
func (s *ServiceStore) Delete(ctx context.Context, id int64) error {
|
||||
tx, err := s.db.BeginTx(ctx, nil)
|
||||
if err != nil {
|
||||
return processSQLErrorf(err, "Failed to start a new transaction")
|
||||
}
|
||||
defer func(tx *sql.Tx) {
|
||||
_ = tx.Rollback()
|
||||
}(tx)
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
// delete the service
|
||||
if _, err = tx.ExecContext(ctx, serviceDelete, id); err != nil {
|
||||
if _, err := db.ExecContext(ctx, serviceDelete, id); err != nil {
|
||||
return processSQLErrorf(err, "The delete query failed")
|
||||
}
|
||||
return tx.Commit()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// List returns a list of service for a specific parent.
|
||||
func (s *ServiceStore) List(ctx context.Context) ([]*types.Service, error) {
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
dst := []*service{}
|
||||
|
||||
err := s.db.SelectContext(ctx, &dst, serviceSelect)
|
||||
err := db.SelectContext(ctx, &dst, serviceSelect)
|
||||
if err != nil {
|
||||
return nil, processSQLErrorf(err, "Failed executing default list query")
|
||||
}
|
||||
|
||||
return s.mapDBServices(dst), nil
|
||||
}
|
||||
|
||||
// Count returns a count of service for a specific parent.
|
||||
func (s *ServiceStore) Count(ctx context.Context) (int64, error) {
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
var count int64
|
||||
err := s.db.QueryRowContext(ctx, serviceCount).Scan(&count)
|
||||
err := db.QueryRowContext(ctx, serviceCount).Scan(&count)
|
||||
if err != nil {
|
||||
return 0, processSQLErrorf(err, "Failed executing count query")
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
|
@ -6,10 +6,10 @@ package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"github.com/harness/gitness/internal/store"
|
||||
"github.com/harness/gitness/internal/store/database/dbtx"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
|
||||
@ -43,8 +43,10 @@ type ServiceAccountStore struct {
|
||||
|
||||
// Find finds the service account by id.
|
||||
func (s *ServiceAccountStore) Find(ctx context.Context, id int64) (*types.ServiceAccount, error) {
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
dst := new(serviceAccount)
|
||||
if err := s.db.GetContext(ctx, dst, serviceAccountSelectID, id); err != nil {
|
||||
if err := db.GetContext(ctx, dst, serviceAccountSelectID, id); err != nil {
|
||||
return nil, processSQLErrorf(err, "Select by id query failed")
|
||||
}
|
||||
return s.mapDBServiceAccount(dst), nil
|
||||
@ -60,10 +62,13 @@ func (s *ServiceAccountStore) FindUID(ctx context.Context, uid string) (*types.S
|
||||
return nil, store.ErrResourceNotFound
|
||||
}
|
||||
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
dst := new(serviceAccount)
|
||||
if err = s.db.GetContext(ctx, dst, serviceAccountSelectUIDUnique, uidUnique); err != nil {
|
||||
if err = db.GetContext(ctx, dst, serviceAccountSelectUIDUnique, uidUnique); err != nil {
|
||||
return nil, processSQLErrorf(err, "Select by uid query failed")
|
||||
}
|
||||
|
||||
return s.mapDBServiceAccount(dst), nil
|
||||
}
|
||||
|
||||
@ -74,12 +79,14 @@ func (s *ServiceAccountStore) Create(ctx context.Context, sa *types.ServiceAccou
|
||||
return fmt.Errorf("failed to map db service account: %w", err)
|
||||
}
|
||||
|
||||
query, arg, err := s.db.BindNamed(serviceAccountInsert, dbSA)
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
query, arg, err := db.BindNamed(serviceAccountInsert, dbSA)
|
||||
if err != nil {
|
||||
return processSQLErrorf(err, "Failed to bind service account object")
|
||||
}
|
||||
|
||||
if err = s.db.QueryRowContext(ctx, query, arg...).Scan(&sa.ID); err != nil {
|
||||
if err = db.QueryRowContext(ctx, query, arg...).Scan(&sa.ID); err != nil {
|
||||
return processSQLErrorf(err, "Insert query failed")
|
||||
}
|
||||
|
||||
@ -93,12 +100,14 @@ func (s *ServiceAccountStore) Update(ctx context.Context, sa *types.ServiceAccou
|
||||
return fmt.Errorf("failed to map db service account: %w", err)
|
||||
}
|
||||
|
||||
query, arg, err := s.db.BindNamed(serviceAccountUpdate, dbSA)
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
query, arg, err := db.BindNamed(serviceAccountUpdate, dbSA)
|
||||
if err != nil {
|
||||
return processSQLErrorf(err, "Failed to bind service account object")
|
||||
}
|
||||
|
||||
if _, err = s.db.ExecContext(ctx, query, arg...); err != nil {
|
||||
if _, err = db.ExecContext(ctx, query, arg...); err != nil {
|
||||
return processSQLErrorf(err, "Update query failed")
|
||||
}
|
||||
|
||||
@ -107,40 +116,40 @@ func (s *ServiceAccountStore) Update(ctx context.Context, sa *types.ServiceAccou
|
||||
|
||||
// Delete deletes the service account.
|
||||
func (s *ServiceAccountStore) Delete(ctx context.Context, id int64) error {
|
||||
tx, err := s.db.BeginTx(ctx, nil)
|
||||
if err != nil {
|
||||
return processSQLErrorf(err, "Failed to start a new transaction")
|
||||
}
|
||||
defer func(tx *sql.Tx) {
|
||||
_ = tx.Rollback()
|
||||
}(tx)
|
||||
// delete the service account
|
||||
if _, err = tx.ExecContext(ctx, serviceAccountDelete, id); err != nil {
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
if _, err := db.ExecContext(ctx, serviceAccountDelete, id); err != nil {
|
||||
return processSQLErrorf(err, "The delete query failed")
|
||||
}
|
||||
return tx.Commit()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// List returns a list of service accounts for a specific parent.
|
||||
func (s *ServiceAccountStore) List(ctx context.Context, parentType enum.ParentResourceType,
|
||||
parentID int64) ([]*types.ServiceAccount, error) {
|
||||
dst := []*serviceAccount{}
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
err := s.db.SelectContext(ctx, &dst, serviceAccountSelectByParentTypeAndID, parentType, parentID)
|
||||
dst := []*serviceAccount{}
|
||||
err := db.SelectContext(ctx, &dst, serviceAccountSelectByParentTypeAndID, parentType, parentID)
|
||||
if err != nil {
|
||||
return nil, processSQLErrorf(err, "Failed executing default list query")
|
||||
}
|
||||
|
||||
return s.mapDBServiceAccounts(dst), nil
|
||||
}
|
||||
|
||||
// Count returns a count of service accounts for a specific parent.
|
||||
func (s *ServiceAccountStore) Count(ctx context.Context,
|
||||
parentType enum.ParentResourceType, parentID int64) (int64, error) {
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
var count int64
|
||||
err := s.db.QueryRowContext(ctx, serviceAccountCountByParentTypeAndID, parentType, parentID).Scan(&count)
|
||||
err := db.QueryRowContext(ctx, serviceAccountCountByParentTypeAndID, parentType, parentID).Scan(&count)
|
||||
if err != nil {
|
||||
return 0, processSQLErrorf(err, "Failed executing count query")
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
|
@ -1,79 +0,0 @@
|
||||
// Copyright 2022 Harness Inc. All rights reserved.
|
||||
// Use of this source code is governed by the Polyform Free Trial License
|
||||
// that can be found in the LICENSE.md file for this repository.
|
||||
|
||||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/harness/gitness/internal/store"
|
||||
"github.com/harness/gitness/internal/store/database/mutex"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
)
|
||||
|
||||
var _ store.ServiceAccountStore = (*ServiceAccountStoreSync)(nil)
|
||||
|
||||
// NewServiceAccountStoreSync returns a new ServiceAccountStoreSync.
|
||||
func NewServiceAccountStoreSync(base *ServiceAccountStore) *ServiceAccountStoreSync {
|
||||
return &ServiceAccountStoreSync{base}
|
||||
}
|
||||
|
||||
// ServiceAccountStoreSync synchronizes read and write access to the
|
||||
// service account store. This prevents race conditions when the database
|
||||
// type is sqlite3.
|
||||
type ServiceAccountStoreSync struct {
|
||||
base *ServiceAccountStore
|
||||
}
|
||||
|
||||
// Find finds the service account by id.
|
||||
func (s *ServiceAccountStoreSync) Find(ctx context.Context, id int64) (*types.ServiceAccount, error) {
|
||||
mutex.RLock()
|
||||
defer mutex.RUnlock()
|
||||
return s.base.Find(ctx, id)
|
||||
}
|
||||
|
||||
// FindUID finds the service account by uid.
|
||||
func (s *ServiceAccountStoreSync) FindUID(ctx context.Context, uid string) (*types.ServiceAccount, error) {
|
||||
mutex.RLock()
|
||||
defer mutex.RUnlock()
|
||||
return s.base.FindUID(ctx, uid)
|
||||
}
|
||||
|
||||
// Create saves the service account.
|
||||
func (s *ServiceAccountStoreSync) Create(ctx context.Context, sa *types.ServiceAccount) error {
|
||||
mutex.RLock()
|
||||
defer mutex.RUnlock()
|
||||
return s.base.Create(ctx, sa)
|
||||
}
|
||||
|
||||
// Update updates the service account details.
|
||||
func (s *ServiceAccountStoreSync) Update(ctx context.Context, sa *types.ServiceAccount) error {
|
||||
mutex.RLock()
|
||||
defer mutex.RUnlock()
|
||||
return s.base.Update(ctx, sa)
|
||||
}
|
||||
|
||||
// Delete deletes the service account.
|
||||
func (s *ServiceAccountStoreSync) Delete(ctx context.Context, id int64) error {
|
||||
mutex.RLock()
|
||||
defer mutex.RUnlock()
|
||||
return s.base.Delete(ctx, id)
|
||||
}
|
||||
|
||||
// List returns a list of service accounts for a specific parent.
|
||||
func (s *ServiceAccountStoreSync) List(ctx context.Context, parentType enum.ParentResourceType,
|
||||
parentID int64) ([]*types.ServiceAccount, error) {
|
||||
mutex.RLock()
|
||||
defer mutex.RUnlock()
|
||||
return s.base.List(ctx, parentType, parentID)
|
||||
}
|
||||
|
||||
// Count returns a count of service accounts for a specific parent.
|
||||
func (s *ServiceAccountStoreSync) Count(ctx context.Context, parentType enum.ParentResourceType,
|
||||
parentID int64) (int64, error) {
|
||||
mutex.RLock()
|
||||
defer mutex.RUnlock()
|
||||
return s.base.Count(ctx, parentType, parentID)
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
// Copyright 2022 Harness Inc. All rights reserved.
|
||||
// Use of this source code is governed by the Polyform Free Trial License
|
||||
// that can be found in the LICENSE.md file for this repository.
|
||||
|
||||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/harness/gitness/internal/store"
|
||||
"github.com/harness/gitness/internal/store/database/mutex"
|
||||
"github.com/harness/gitness/types"
|
||||
)
|
||||
|
||||
var _ store.ServiceStore = (*ServiceStoreSync)(nil)
|
||||
|
||||
// NewServiceStoreSync returns a new ServiceStoreSync.
|
||||
func NewServiceStoreSync(base *ServiceStore) *ServiceStoreSync {
|
||||
return &ServiceStoreSync{base}
|
||||
}
|
||||
|
||||
// ServiceStoreSync synchronizes read and write access to the
|
||||
// service store. This prevents race conditions when the database
|
||||
// type is sqlite3.
|
||||
type ServiceStoreSync struct {
|
||||
base *ServiceStore
|
||||
}
|
||||
|
||||
// Find finds the service by id.
|
||||
func (s *ServiceStoreSync) Find(ctx context.Context, id int64) (*types.Service, error) {
|
||||
mutex.RLock()
|
||||
defer mutex.RUnlock()
|
||||
return s.base.Find(ctx, id)
|
||||
}
|
||||
|
||||
// FindUID finds the service by uid.
|
||||
func (s *ServiceStoreSync) FindUID(ctx context.Context, uid string) (*types.Service, error) {
|
||||
mutex.RLock()
|
||||
defer mutex.RUnlock()
|
||||
return s.base.FindUID(ctx, uid)
|
||||
}
|
||||
|
||||
// Create saves the service.
|
||||
func (s *ServiceStoreSync) Create(ctx context.Context, sa *types.Service) error {
|
||||
mutex.RLock()
|
||||
defer mutex.RUnlock()
|
||||
return s.base.Create(ctx, sa)
|
||||
}
|
||||
|
||||
// Update updates the service.
|
||||
func (s *ServiceStoreSync) Update(ctx context.Context, sa *types.Service) error {
|
||||
mutex.RLock()
|
||||
defer mutex.RUnlock()
|
||||
return s.base.Update(ctx, sa)
|
||||
}
|
||||
|
||||
// Delete deletes the service.
|
||||
func (s *ServiceStoreSync) Delete(ctx context.Context, id int64) error {
|
||||
mutex.RLock()
|
||||
defer mutex.RUnlock()
|
||||
return s.base.Delete(ctx, id)
|
||||
}
|
||||
|
||||
// List returns a list of service for a specific parent.
|
||||
func (s *ServiceStoreSync) List(ctx context.Context) ([]*types.Service, error) {
|
||||
mutex.RLock()
|
||||
defer mutex.RUnlock()
|
||||
return s.base.List(ctx)
|
||||
}
|
||||
|
||||
// Count returns a count of service for a specific parent.
|
||||
func (s *ServiceStoreSync) Count(ctx context.Context) (int64, error) {
|
||||
mutex.RLock()
|
||||
defer mutex.RUnlock()
|
||||
return s.base.Count(ctx)
|
||||
}
|
@ -30,6 +30,7 @@ func connect() (*sqlx.DB, error) {
|
||||
|
||||
// seed seed the database state.
|
||||
func seed(db *sqlx.DB) error {
|
||||
/*
|
||||
_, err := db.Exec("DELETE FROM executions")
|
||||
if err != nil {
|
||||
return err
|
||||
@ -52,6 +53,8 @@ func seed(db *sqlx.DB) error {
|
||||
}
|
||||
_, err = db.Exec("ALTER SEQUENCE executions_execution_id_seq RESTART WITH 1")
|
||||
return err
|
||||
*/
|
||||
return nil
|
||||
}
|
||||
|
||||
// unmarshal a testdata file.
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/harness/gitness/internal/store"
|
||||
"github.com/harness/gitness/internal/store/database/dbtx"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
|
||||
@ -28,30 +29,38 @@ type TokenStore struct {
|
||||
|
||||
// Find finds the token by id.
|
||||
func (s *TokenStore) Find(ctx context.Context, id int64) (*types.Token, error) {
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
dst := new(types.Token)
|
||||
if err := s.db.GetContext(ctx, dst, TokenSelectByID, id); err != nil {
|
||||
if err := db.GetContext(ctx, dst, TokenSelectByID, id); err != nil {
|
||||
return nil, processSQLErrorf(err, "Select query failed")
|
||||
}
|
||||
|
||||
return dst, nil
|
||||
}
|
||||
|
||||
// Find finds the token by principalId and tokenUID.
|
||||
func (s *TokenStore) FindByUID(ctx context.Context, principalID int64, tokenUID string) (*types.Token, error) {
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
dst := new(types.Token)
|
||||
if err := s.db.GetContext(ctx, dst, TokenSelectByPrincipalIDAndUID, principalID, tokenUID); err != nil {
|
||||
if err := db.GetContext(ctx, dst, TokenSelectByPrincipalIDAndUID, principalID, tokenUID); err != nil {
|
||||
return nil, processSQLErrorf(err, "Select query failed")
|
||||
}
|
||||
|
||||
return dst, nil
|
||||
}
|
||||
|
||||
// Create saves the token details.
|
||||
func (s *TokenStore) Create(ctx context.Context, token *types.Token) error {
|
||||
query, arg, err := s.db.BindNamed(tokenInsert, token)
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
query, arg, err := db.BindNamed(tokenInsert, token)
|
||||
if err != nil {
|
||||
return processSQLErrorf(err, "Failed to bind token object")
|
||||
}
|
||||
|
||||
if err = s.db.QueryRowContext(ctx, query, arg...).Scan(&token.ID); err != nil {
|
||||
if err = db.QueryRowContext(ctx, query, arg...).Scan(&token.ID); err != nil {
|
||||
return processSQLErrorf(err, "Insert query failed")
|
||||
}
|
||||
|
||||
@ -60,7 +69,9 @@ func (s *TokenStore) Create(ctx context.Context, token *types.Token) error {
|
||||
|
||||
// Delete deletes the token with the given id.
|
||||
func (s *TokenStore) Delete(ctx context.Context, id int64) error {
|
||||
if _, err := s.db.ExecContext(ctx, tokenDelete, id); err != nil {
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
if _, err := db.ExecContext(ctx, tokenDelete, id); err != nil {
|
||||
return processSQLErrorf(err, "The delete query failed")
|
||||
}
|
||||
|
||||
@ -69,7 +80,9 @@ func (s *TokenStore) Delete(ctx context.Context, id int64) error {
|
||||
|
||||
// DeleteForPrincipal deletes all tokens for a specific principal.
|
||||
func (s *TokenStore) DeleteForPrincipal(ctx context.Context, principalID int64) error {
|
||||
if _, err := s.db.ExecContext(ctx, tokenDeleteForPrincipal, principalID); err != nil {
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
if _, err := db.ExecContext(ctx, tokenDeleteForPrincipal, principalID); err != nil {
|
||||
return processSQLErrorf(err, "The delete query failed")
|
||||
}
|
||||
|
||||
@ -79,22 +92,27 @@ func (s *TokenStore) DeleteForPrincipal(ctx context.Context, principalID int64)
|
||||
// Count returns a count of tokens of a specifc type for a specific principal.
|
||||
func (s *TokenStore) Count(ctx context.Context,
|
||||
principalID int64, tokenType enum.TokenType) (int64, error) {
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
var count int64
|
||||
err := s.db.QueryRowContext(ctx, tokenCountForPrincipalIDOfType, principalID, tokenType).Scan(&count)
|
||||
err := db.QueryRowContext(ctx, tokenCountForPrincipalIDOfType, principalID, tokenType).Scan(&count)
|
||||
if err != nil {
|
||||
return 0, processSQLErrorf(err, "Failed executing count query")
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// List returns a list of tokens of a specific type for a specific principal.
|
||||
func (s *TokenStore) List(ctx context.Context,
|
||||
principalID int64, tokenType enum.TokenType) ([]*types.Token, error) {
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
dst := []*types.Token{}
|
||||
|
||||
// TODO: custom filters / sorting for tokens.
|
||||
|
||||
err := s.db.SelectContext(ctx, &dst, tokenSelectForPrincipalIDOfType, principalID, tokenType)
|
||||
err := db.SelectContext(ctx, &dst, tokenSelectForPrincipalIDOfType, principalID, tokenType)
|
||||
if err != nil {
|
||||
return nil, processSQLErrorf(err, "Failed executing token list query")
|
||||
}
|
||||
|
@ -1,77 +0,0 @@
|
||||
// Copyright 2022 Harness Inc. All rights reserved.
|
||||
// Use of this source code is governed by the Polyform Free Trial License
|
||||
// that can be found in the LICENSE.md file for this repository.
|
||||
|
||||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/harness/gitness/internal/store"
|
||||
"github.com/harness/gitness/internal/store/database/mutex"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
)
|
||||
|
||||
var _ store.TokenStore = (*TokenStoreSync)(nil)
|
||||
|
||||
// NewTokenStoreSync returns a new TokenStoreSync.
|
||||
func NewTokenStoreSync(store *TokenStore) *TokenStoreSync {
|
||||
return &TokenStoreSync{base: store}
|
||||
}
|
||||
|
||||
// TokenStoreSync synronizes read and write access to the
|
||||
// token store. This prevents race conditions when the database
|
||||
// type is sqlite3.
|
||||
type TokenStoreSync struct{ base *TokenStore }
|
||||
|
||||
// Find finds the token by id.
|
||||
func (s *TokenStoreSync) Find(ctx context.Context, id int64) (*types.Token, error) {
|
||||
mutex.RLock()
|
||||
defer mutex.RUnlock()
|
||||
return s.base.Find(ctx, id)
|
||||
}
|
||||
|
||||
// Find finds the token by principalId and tokenUID.
|
||||
func (s *TokenStoreSync) FindByUID(ctx context.Context, principalID int64, tokenUID string) (*types.Token, error) {
|
||||
mutex.RLock()
|
||||
defer mutex.RUnlock()
|
||||
return s.base.FindByUID(ctx, principalID, tokenUID)
|
||||
}
|
||||
|
||||
// Create saves the token details.
|
||||
func (s *TokenStoreSync) Create(ctx context.Context, token *types.Token) error {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
return s.base.Create(ctx, token)
|
||||
}
|
||||
|
||||
// Delete deletes the token with the given id.
|
||||
func (s *TokenStoreSync) Delete(ctx context.Context, id int64) error {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
return s.base.Delete(ctx, id)
|
||||
}
|
||||
|
||||
// DeleteForPrincipal deletes all tokens for a specific principal.
|
||||
func (s *TokenStoreSync) DeleteForPrincipal(ctx context.Context, principalID int64) error {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
return s.base.DeleteForPrincipal(ctx, principalID)
|
||||
}
|
||||
|
||||
// Count returns a count of tokens of a specifc type for a specific principal.
|
||||
func (s *TokenStoreSync) Count(ctx context.Context, principalID int64,
|
||||
tokenType enum.TokenType) (int64, error) {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
return s.base.Count(ctx, principalID, tokenType)
|
||||
}
|
||||
|
||||
// List returns a list of tokens of a specific type for a specific principal.
|
||||
func (s *TokenStoreSync) List(ctx context.Context, principalID int64,
|
||||
tokenType enum.TokenType) ([]*types.Token, error) {
|
||||
mutex.RLock()
|
||||
defer mutex.RUnlock()
|
||||
return s.base.List(ctx, principalID, tokenType)
|
||||
}
|
@ -6,10 +6,10 @@ package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"github.com/harness/gitness/internal/store"
|
||||
"github.com/harness/gitness/internal/store/database/dbtx"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
|
||||
@ -35,8 +35,7 @@ func NewUserStore(db *sqlx.DB, uidTransformation store.PrincipalUIDTransformatio
|
||||
}
|
||||
}
|
||||
|
||||
// UserStore implements a UserStore backed by a relational
|
||||
// database.
|
||||
// UserStore implements a UserStore backed by a relational database.
|
||||
type UserStore struct {
|
||||
db *sqlx.DB
|
||||
uidTransformation store.PrincipalUIDTransformation
|
||||
@ -44,10 +43,13 @@ type UserStore struct {
|
||||
|
||||
// Find finds the user by id.
|
||||
func (s *UserStore) Find(ctx context.Context, id int64) (*types.User, error) {
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
dst := new(user)
|
||||
if err := s.db.GetContext(ctx, dst, userSelectID, id); err != nil {
|
||||
if err := db.GetContext(ctx, dst, userSelectID, id); err != nil {
|
||||
return nil, processSQLErrorf(err, "Select by id query failed")
|
||||
}
|
||||
|
||||
return s.mapDBUser(dst), nil
|
||||
}
|
||||
|
||||
@ -61,19 +63,25 @@ func (s *UserStore) FindUID(ctx context.Context, uid string) (*types.User, error
|
||||
return nil, store.ErrResourceNotFound
|
||||
}
|
||||
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
dst := new(user)
|
||||
if err = s.db.GetContext(ctx, dst, userSelectUIDUnique, uidUnique); err != nil {
|
||||
if err = db.GetContext(ctx, dst, userSelectUIDUnique, uidUnique); err != nil {
|
||||
return nil, processSQLErrorf(err, "Select by uid query failed")
|
||||
}
|
||||
|
||||
return s.mapDBUser(dst), nil
|
||||
}
|
||||
|
||||
// FindEmail finds the user by email.
|
||||
func (s *UserStore) FindEmail(ctx context.Context, email string) (*types.User, error) {
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
dst := new(user)
|
||||
if err := s.db.GetContext(ctx, dst, userSelectEmail, email); err != nil {
|
||||
if err := db.GetContext(ctx, dst, userSelectEmail, email); err != nil {
|
||||
return nil, processSQLErrorf(err, "Select by email query failed")
|
||||
}
|
||||
|
||||
return s.mapDBUser(dst), nil
|
||||
}
|
||||
|
||||
@ -84,12 +92,14 @@ func (s *UserStore) Create(ctx context.Context, user *types.User) error {
|
||||
return fmt.Errorf("failed to map db user: %w", err)
|
||||
}
|
||||
|
||||
query, arg, err := s.db.BindNamed(userInsert, dbUser)
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
query, arg, err := db.BindNamed(userInsert, dbUser)
|
||||
if err != nil {
|
||||
return processSQLErrorf(err, "Failed to bind user object")
|
||||
}
|
||||
|
||||
if err = s.db.QueryRowContext(ctx, query, arg...).Scan(&user.ID); err != nil {
|
||||
if err = db.QueryRowContext(ctx, query, arg...).Scan(&user.ID); err != nil {
|
||||
return processSQLErrorf(err, "Insert query failed")
|
||||
}
|
||||
|
||||
@ -103,12 +113,14 @@ func (s *UserStore) Update(ctx context.Context, user *types.User) error {
|
||||
return fmt.Errorf("failed to map db user: %w", err)
|
||||
}
|
||||
|
||||
query, arg, err := s.db.BindNamed(userUpdate, dbUser)
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
query, arg, err := db.BindNamed(userUpdate, dbUser)
|
||||
if err != nil {
|
||||
return processSQLErrorf(err, "Failed to bind user object")
|
||||
}
|
||||
|
||||
if _, err = s.db.ExecContext(ctx, query, arg...); err != nil {
|
||||
if _, err = db.ExecContext(ctx, query, arg...); err != nil {
|
||||
return processSQLErrorf(err, "Update query failed")
|
||||
}
|
||||
|
||||
@ -117,28 +129,25 @@ func (s *UserStore) Update(ctx context.Context, user *types.User) error {
|
||||
|
||||
// Delete deletes the user.
|
||||
func (s *UserStore) Delete(ctx context.Context, id int64) error {
|
||||
tx, err := s.db.BeginTx(ctx, nil)
|
||||
if err != nil {
|
||||
return processSQLErrorf(err, "Failed to start a new transaction")
|
||||
}
|
||||
defer func(tx *sql.Tx) {
|
||||
_ = tx.Rollback()
|
||||
}(tx)
|
||||
// delete the user
|
||||
if _, err = tx.ExecContext(ctx, userDelete, id); err != nil {
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
if _, err := db.ExecContext(ctx, userDelete, id); err != nil {
|
||||
return processSQLErrorf(err, "The delete query failed")
|
||||
}
|
||||
return tx.Commit()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// List returns a list of users.
|
||||
func (s *UserStore) List(ctx context.Context, opts *types.UserFilter) ([]*types.User, error) {
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
dst := []*user{}
|
||||
|
||||
// if the user does not provide any customer filter
|
||||
// or sorting we use the default select statement.
|
||||
if opts.Sort == enum.UserAttrNone {
|
||||
err := s.db.SelectContext(ctx, &dst, userSelect, limit(opts.Size), offset(opts.Page, opts.Size))
|
||||
err := db.SelectContext(ctx, &dst, userSelect, limit(opts.Size), offset(opts.Page, opts.Size))
|
||||
if err != nil {
|
||||
return nil, processSQLErrorf(err, "Failed executing default list query")
|
||||
}
|
||||
@ -173,7 +182,7 @@ func (s *UserStore) List(ctx context.Context, opts *types.UserFilter) ([]*types.
|
||||
return nil, errors.Wrap(err, "Failed to convert query to sql")
|
||||
}
|
||||
|
||||
if err = s.db.SelectContext(ctx, &dst, sql); err != nil {
|
||||
if err = db.SelectContext(ctx, &dst, sql); err != nil {
|
||||
return nil, processSQLErrorf(err, "Failed executing custom list query")
|
||||
}
|
||||
|
||||
@ -182,11 +191,14 @@ func (s *UserStore) List(ctx context.Context, opts *types.UserFilter) ([]*types.
|
||||
|
||||
// Count returns a count of users.
|
||||
func (s *UserStore) Count(ctx context.Context) (int64, error) {
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
var count int64
|
||||
err := s.db.QueryRowContext(ctx, userCount).Scan(&count)
|
||||
err := db.QueryRowContext(ctx, userCount).Scan(&count)
|
||||
if err != nil {
|
||||
return 0, processSQLErrorf(err, "Failed executing count query")
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
|
@ -1,81 +0,0 @@
|
||||
// Copyright 2022 Harness Inc. All rights reserved.
|
||||
// Use of this source code is governed by the Polyform Free Trial License
|
||||
// that can be found in the LICENSE.md file for this repository.
|
||||
|
||||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/harness/gitness/internal/store"
|
||||
"github.com/harness/gitness/internal/store/database/mutex"
|
||||
"github.com/harness/gitness/types"
|
||||
)
|
||||
|
||||
var _ store.UserStore = (*UserStoreSync)(nil)
|
||||
|
||||
// NewUserStoreSync returns a new UserStoreSync.
|
||||
func NewUserStoreSync(store *UserStore) *UserStoreSync {
|
||||
return &UserStoreSync{base: store}
|
||||
}
|
||||
|
||||
// UserStoreSync synronizes read and write access to the
|
||||
// user store. This prevents race conditions when the database
|
||||
// type is sqlite3.
|
||||
type UserStoreSync struct{ base *UserStore }
|
||||
|
||||
// Find finds the user by id.
|
||||
func (s *UserStoreSync) Find(ctx context.Context, id int64) (*types.User, error) {
|
||||
mutex.RLock()
|
||||
defer mutex.RUnlock()
|
||||
return s.base.Find(ctx, id)
|
||||
}
|
||||
|
||||
// FindUID finds the user by uid.
|
||||
func (s *UserStoreSync) FindUID(ctx context.Context, uid string) (*types.User, error) {
|
||||
mutex.RLock()
|
||||
defer mutex.RUnlock()
|
||||
return s.base.FindUID(ctx, uid)
|
||||
}
|
||||
|
||||
// FindEmail finds the user by email.
|
||||
func (s *UserStoreSync) FindEmail(ctx context.Context, email string) (*types.User, error) {
|
||||
mutex.RLock()
|
||||
defer mutex.RUnlock()
|
||||
return s.base.FindEmail(ctx, email)
|
||||
}
|
||||
|
||||
// List returns a list of users.
|
||||
func (s *UserStoreSync) List(ctx context.Context, opts *types.UserFilter) ([]*types.User, error) {
|
||||
mutex.RLock()
|
||||
defer mutex.RUnlock()
|
||||
return s.base.List(ctx, opts)
|
||||
}
|
||||
|
||||
// Create saves the user details.
|
||||
func (s *UserStoreSync) Create(ctx context.Context, user *types.User) error {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
return s.base.Create(ctx, user)
|
||||
}
|
||||
|
||||
// Update updates the user details.
|
||||
func (s *UserStoreSync) Update(ctx context.Context, user *types.User) error {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
return s.base.Update(ctx, user)
|
||||
}
|
||||
|
||||
// Delete deletes the user.
|
||||
func (s *UserStoreSync) Delete(ctx context.Context, id int64) error {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
return s.base.Delete(ctx, id)
|
||||
}
|
||||
|
||||
// Count returns a count of users.
|
||||
func (s *UserStoreSync) Count(ctx context.Context) (int64, error) {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
return s.base.Count(ctx)
|
||||
}
|
@ -38,7 +38,7 @@ func TestUser(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
userStoreSync := NewUserStoreSync(NewUserStore(db, store.ToLowerPrincipalUIDTransformation))
|
||||
userStoreSync := NewUserStore(db, store.ToLowerPrincipalUIDTransformation)
|
||||
t.Run("create", testUserCreate(userStoreSync))
|
||||
t.Run("duplicate", testUserDuplicate(userStoreSync))
|
||||
t.Run("count", testUserCount(userStoreSync))
|
||||
@ -244,8 +244,8 @@ func testUserDelete(s store.UserStore) func(t *testing.T) {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if _, err = s.Find(ctx, 1); errors.Is(err, store.ErrResourceNotFound) {
|
||||
t.Errorf("Expected sql.ErrNoRows got %s", err)
|
||||
if _, err = s.Find(ctx, 1); !errors.Is(err, store.ErrResourceNotFound) {
|
||||
t.Errorf("Expected store.ErrResourceNotFound got %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,39 +44,18 @@ func ProvideDatabase(ctx context.Context, config *types.Config) (*sqlx.DB, error
|
||||
|
||||
// ProvideUserStore provides a user store.
|
||||
func ProvideUserStore(db *sqlx.DB, uidTransformation store.PrincipalUIDTransformation) store.UserStore {
|
||||
switch db.DriverName() {
|
||||
case postgres:
|
||||
return NewUserStore(db, uidTransformation)
|
||||
default:
|
||||
return NewUserStoreSync(
|
||||
NewUserStore(db, uidTransformation),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// ProvideServiceAccountStore provides a service account store.
|
||||
func ProvideServiceAccountStore(db *sqlx.DB,
|
||||
uidTransformation store.PrincipalUIDTransformation) store.ServiceAccountStore {
|
||||
switch db.DriverName() {
|
||||
case postgres:
|
||||
return NewServiceAccountStore(db, uidTransformation)
|
||||
default:
|
||||
return NewServiceAccountStoreSync(
|
||||
NewServiceAccountStore(db, uidTransformation),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// ProvideServiceStore provides a service store.
|
||||
func ProvideServiceStore(db *sqlx.DB, uidTransformation store.PrincipalUIDTransformation) store.ServiceStore {
|
||||
switch db.DriverName() {
|
||||
case postgres:
|
||||
return NewServiceStore(db, uidTransformation)
|
||||
default:
|
||||
return NewServiceStoreSync(
|
||||
NewServiceStore(db, uidTransformation),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// ProvideSpaceStore provides a space store.
|
||||
@ -105,14 +84,7 @@ func ProvideRepoStore(db *sqlx.DB, pathTransformation store.PathTransformation)
|
||||
|
||||
// ProvideTokenStore provides a token store.
|
||||
func ProvideTokenStore(db *sqlx.DB) store.TokenStore {
|
||||
switch db.DriverName() {
|
||||
case postgres:
|
||||
return NewTokenStore(db)
|
||||
default:
|
||||
return NewTokenStoreSync(
|
||||
NewTokenStore(db),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// ProvidePullReqStore provides a pull request store.
|
||||
|
Loading…
Reference in New Issue
Block a user