drone/app/store/database/gitspace_config.go
Patrick Wolf d789e5775e feat: [CODE-2402] : Update all occurences of 'gitness' to 'harness' within comments and markdown. Updated the logo reference (did not delete the Gitness logo directory yet). No active code changes except display strings. (#2684)
* Apply suggestion from code review
* updating images for signin and register page.
* fix: lint
* fix: logo update
* revert golangci
* Adding more strings and updated the logo. Still need to update the signin page images
* Apply suggestion from code review

Updating harness logo to use Open Source logo
* Update all occurences of 'gitness' to 'harness' within comments and markdown. Updated the logo reference (did not delete the Gitness logo directory yet).  No active code changes except display strings.
2024-09-25 00:13:28 +00:00

366 lines
12 KiB
Go

// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package database
import (
"context"
"fmt"
"strings"
"github.com/harness/gitness/app/store"
"github.com/harness/gitness/store/database"
"github.com/harness/gitness/store/database/dbtx"
"github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
"github.com/Masterminds/squirrel"
"github.com/guregu/null"
"github.com/jmoiron/sqlx"
"github.com/pkg/errors"
)
const (
gitspaceConfigInsertColumns = `
gconf_uid,
gconf_display_name,
gconf_ide,
gconf_infra_provider_resource_id,
gconf_code_auth_type,
gconf_code_auth_id,
gconf_code_repo_type,
gconf_code_repo_is_private,
gconf_code_repo_url,
gconf_devcontainer_path,
gconf_branch,
gconf_user_uid,
gconf_space_id,
gconf_created,
gconf_updated,
gconf_is_deleted,
gconf_code_repo_ref,
gconf_ssh_token_identifier,
gconf_created_by
`
gitspaceConfigsTable = `gitspace_configs`
ReturningClause = "RETURNING "
gitspaceConfigSelectColumns = "gconf_id," + gitspaceConfigInsertColumns
)
type gitspaceConfig struct {
ID int64 `db:"gconf_id"`
Identifier string `db:"gconf_uid"`
Name string `db:"gconf_display_name"`
IDE enum.IDEType `db:"gconf_ide"`
InfraProviderResourceID int64 `db:"gconf_infra_provider_resource_id"`
CodeAuthType string `db:"gconf_code_auth_type"`
CodeRepoRef null.String `db:"gconf_code_repo_ref"`
CodeAuthID string `db:"gconf_code_auth_id"`
CodeRepoType enum.GitspaceCodeRepoType `db:"gconf_code_repo_type"`
CodeRepoIsPrivate bool `db:"gconf_code_repo_is_private"`
CodeRepoURL string `db:"gconf_code_repo_url"`
DevcontainerPath null.String `db:"gconf_devcontainer_path"`
Branch string `db:"gconf_branch"`
// TODO: migrate to principal int64 id to use principal cache and consistent with Harness code.
UserUID string `db:"gconf_user_uid"`
SpaceID int64 `db:"gconf_space_id"`
Created int64 `db:"gconf_created"`
Updated int64 `db:"gconf_updated"`
IsDeleted bool `db:"gconf_is_deleted"`
SSHTokenIdentifier string `db:"gconf_ssh_token_identifier"`
CreatedBy null.Int `db:"gconf_created_by"`
}
var _ store.GitspaceConfigStore = (*gitspaceConfigStore)(nil)
// NewGitspaceConfigStore returns a new GitspaceConfigStore.
func NewGitspaceConfigStore(
db *sqlx.DB,
pCache store.PrincipalInfoCache,
rCache store.InfraProviderResourceCache,
) store.GitspaceConfigStore {
return &gitspaceConfigStore{
db: db,
pCache: pCache,
rCache: rCache,
}
}
type gitspaceConfigStore struct {
db *sqlx.DB
pCache store.PrincipalInfoCache
rCache store.InfraProviderResourceCache
}
func (s gitspaceConfigStore) Count(ctx context.Context, filter *types.GitspaceFilter) (int64, error) {
db := dbtx.GetAccessor(ctx, s.db)
countStmt := database.Builder.
Select("COUNT(*)").
From(gitspaceConfigsTable)
if !filter.IncludeDeleted {
countStmt = countStmt.Where(squirrel.Eq{"gconf_is_deleted": false})
}
if filter.UserID != "" {
countStmt = countStmt.Where(squirrel.Eq{"gconf_user_uid": filter.UserID})
}
if filter.SpaceIDs != nil {
countStmt = countStmt.Where(squirrel.Eq{"gconf_space_id": filter.SpaceIDs})
}
sql, args, err := countStmt.ToSql()
if err != nil {
return 0, errors.Wrap(err, "Failed to convert squirrel builder to sql")
}
var count int64
err = db.QueryRowContext(ctx, sql, args...).Scan(&count)
if err != nil {
return 0, database.ProcessSQLErrorf(ctx, err, "Failed executing custom count query")
}
return count, nil
}
func (s gitspaceConfigStore) Find(ctx context.Context, id int64) (*types.GitspaceConfig, error) {
stmt := database.Builder.
Select(gitspaceConfigSelectColumns).
From(gitspaceConfigsTable).
Where("gconf_id = ?", id). //nolint:goconst
Where("gconf_is_deleted = ?", false)
dst := new(gitspaceConfig)
sql, args, err := stmt.ToSql()
if err != nil {
return nil, errors.Wrap(err, "Failed to convert squirrel builder to sql")
}
db := dbtx.GetAccessor(ctx, s.db)
if err := db.GetContext(ctx, dst, sql, args...); err != nil {
return nil, database.ProcessSQLErrorf(ctx, err, "Failed to find gitspace config for %d", id)
}
return s.mapToGitspaceConfig(ctx, dst)
}
func (s gitspaceConfigStore) FindByIdentifier(
ctx context.Context,
spaceID int64,
identifier string,
) (*types.GitspaceConfig, error) {
stmt := database.Builder.
Select(gitspaceConfigSelectColumns).
From(gitspaceConfigsTable).
Where("LOWER(gconf_uid) = $1", strings.ToLower(identifier)).
Where("gconf_space_id = $2", spaceID).
Where("gconf_is_deleted = $3", false)
sql, args, err := stmt.ToSql()
if err != nil {
return nil, errors.Wrap(err, "Failed to convert squirrel builder to sql")
}
dst := new(gitspaceConfig)
db := dbtx.GetAccessor(ctx, s.db)
if err := db.GetContext(ctx, dst, sql, args...); err != nil {
return nil, database.ProcessSQLErrorf(ctx, err, "Failed to find gitspace config for %s", identifier)
}
return s.mapToGitspaceConfig(ctx, dst)
}
func (s gitspaceConfigStore) Create(ctx context.Context, gitspaceConfig *types.GitspaceConfig) error {
stmt := database.Builder.
Insert(gitspaceConfigsTable).
Columns(gitspaceConfigInsertColumns).
Values(
gitspaceConfig.Identifier,
gitspaceConfig.Name,
gitspaceConfig.IDE,
gitspaceConfig.InfraProviderResource.ID,
gitspaceConfig.CodeRepo.AuthType,
gitspaceConfig.CodeRepo.AuthID,
gitspaceConfig.CodeRepo.Type,
gitspaceConfig.CodeRepo.IsPrivate,
gitspaceConfig.CodeRepo.URL,
gitspaceConfig.DevcontainerPath,
gitspaceConfig.Branch,
gitspaceConfig.GitspaceUser.Identifier,
gitspaceConfig.SpaceID,
gitspaceConfig.Created,
gitspaceConfig.Updated,
gitspaceConfig.IsDeleted,
gitspaceConfig.CodeRepo.Ref,
gitspaceConfig.SSHTokenIdentifier,
gitspaceConfig.GitspaceUser.ID,
).
Suffix(ReturningClause + "gconf_id")
sql, args, err := stmt.ToSql()
if err != nil {
return errors.Wrap(err, "Failed to convert squirrel builder to sql")
}
db := dbtx.GetAccessor(ctx, s.db)
if err = db.QueryRowContext(ctx, sql, args...).Scan(&gitspaceConfig.ID); err != nil {
return database.ProcessSQLErrorf(
ctx, err, "gitspace config create query failed for %s", gitspaceConfig.Identifier)
}
return nil
}
func (s gitspaceConfigStore) Update(ctx context.Context,
gitspaceConfig *types.GitspaceConfig) error {
dbGitspaceConfig := mapToInternalGitspaceConfig(gitspaceConfig)
stmt := database.Builder.
Update(gitspaceConfigsTable).
Set("gconf_display_name", dbGitspaceConfig.Name).
Set("gconf_ide", dbGitspaceConfig.IDE).
Set("gconf_updated", dbGitspaceConfig.Updated).
Set("gconf_infra_provider_resource_id", dbGitspaceConfig.InfraProviderResourceID).
Set("gconf_is_deleted", dbGitspaceConfig.IsDeleted).
Where("gconf_id = ?", gitspaceConfig.ID)
sql, args, err := stmt.ToSql()
if err != nil {
return errors.Wrap(err, "Failed to convert squirrel builder to sql")
}
db := dbtx.GetAccessor(ctx, s.db)
if _, err := db.ExecContext(ctx, sql, args...); err != nil {
return database.ProcessSQLErrorf(
ctx, err, "Failed to update gitspace config for %s", gitspaceConfig.Identifier)
}
return nil
}
func mapToInternalGitspaceConfig(config *types.GitspaceConfig) *gitspaceConfig {
return &gitspaceConfig{
ID: config.ID,
Identifier: config.Identifier,
Name: config.Name,
IDE: config.IDE,
InfraProviderResourceID: config.InfraProviderResource.ID,
CodeAuthType: config.CodeRepo.AuthType,
CodeAuthID: config.CodeRepo.AuthID,
CodeRepoIsPrivate: config.CodeRepo.IsPrivate,
CodeRepoType: config.CodeRepo.Type,
CodeRepoRef: null.StringFromPtr(config.CodeRepo.Ref),
CodeRepoURL: config.CodeRepo.URL,
DevcontainerPath: null.StringFromPtr(config.DevcontainerPath),
Branch: config.Branch,
UserUID: config.GitspaceUser.Identifier,
SpaceID: config.SpaceID,
IsDeleted: config.IsDeleted,
Created: config.Created,
Updated: config.Updated,
SSHTokenIdentifier: config.SSHTokenIdentifier,
CreatedBy: null.IntFromPtr(config.GitspaceUser.ID),
}
}
func (s gitspaceConfigStore) List(ctx context.Context, filter *types.GitspaceFilter) ([]*types.GitspaceConfig, error) {
stmt := database.Builder.
Select(gitspaceConfigSelectColumns).
From(gitspaceConfigsTable).
Where(squirrel.Eq{"gconf_is_deleted": false}).
Where(squirrel.Eq{"gconf_user_uid": filter.UserID}).
Where(squirrel.Eq{"gconf_space_id": filter.SpaceIDs})
queryFilter := filter.QueryFilter
stmt = stmt.Limit(database.Limit(queryFilter.Size))
stmt = stmt.Offset(database.Offset(queryFilter.Page, queryFilter.Size))
sql, args, err := stmt.ToSql()
if err != nil {
return nil, errors.Wrap(err, "Failed to convert squirrel builder to sql")
}
db := dbtx.GetAccessor(ctx, s.db)
var dst []*gitspaceConfig
if err = db.SelectContext(ctx, &dst, sql, args...); err != nil {
return nil, database.ProcessSQLErrorf(ctx, err, "Failed executing gitspace config list space query")
}
return s.mapToGitspaceConfigs(ctx, dst)
}
func (s gitspaceConfigStore) ListAll(
ctx context.Context,
userUID string,
) ([]*types.GitspaceConfig, error) {
stmt := database.Builder.
Select(gitspaceConfigSelectColumns).
From(gitspaceConfigsTable).
Where(squirrel.Eq{"gconf_is_deleted": false}).
Where(squirrel.Eq{"gconf_user_uid": userUID})
sql, args, err := stmt.ToSql()
if err != nil {
return nil, errors.Wrap(err, "Failed to convert squirrel builder to sql")
}
db := dbtx.GetAccessor(ctx, s.db)
var dst []*gitspaceConfig
if err = db.SelectContext(ctx, &dst, sql, args...); err != nil {
return nil, database.ProcessSQLErrorf(ctx, err, "Failed executing gitspace config list all query")
}
return s.mapToGitspaceConfigs(ctx, dst)
}
func (s *gitspaceConfigStore) mapToGitspaceConfig(
ctx context.Context,
in *gitspaceConfig,
) (*types.GitspaceConfig, error) {
codeRepo := types.CodeRepo{
URL: in.CodeRepoURL,
Ref: in.CodeRepoRef.Ptr(),
Type: in.CodeRepoType,
Branch: in.Branch,
DevcontainerPath: in.DevcontainerPath.Ptr(),
IsPrivate: in.CodeRepoIsPrivate,
AuthType: in.CodeAuthType,
AuthID: in.CodeAuthID,
}
var res = &types.GitspaceConfig{
ID: in.ID,
Identifier: in.Identifier,
Name: in.Name,
IDE: in.IDE,
SpaceID: in.SpaceID,
Created: in.Created,
Updated: in.Updated,
SSHTokenIdentifier: in.SSHTokenIdentifier,
CodeRepo: codeRepo,
GitspaceUser: types.GitspaceUser{
ID: in.CreatedBy.Ptr(),
Identifier: in.UserUID},
}
if res.GitspaceUser.ID != nil {
author, _ := s.pCache.Get(ctx, *res.GitspaceUser.ID)
if author != nil {
res.GitspaceUser.DisplayName = author.DisplayName
res.GitspaceUser.Email = author.Email
}
}
if resource, err := s.rCache.Get(ctx, in.InfraProviderResourceID); err == nil {
res.InfraProviderResource = *resource
} else {
return nil, fmt.Errorf("couldn't set resource to the config in DB: %s", in.Identifier)
}
return res, nil
}
func (s *gitspaceConfigStore) mapToGitspaceConfigs(
ctx context.Context,
configs []*gitspaceConfig,
) ([]*types.GitspaceConfig, error) {
var err error
res := make([]*types.GitspaceConfig, len(configs))
for i := range configs {
res[i], err = s.mapToGitspaceConfig(ctx, configs[i])
if err != nil {
return nil, err
}
}
return res, nil
}