Skip to content

Commit

Permalink
fix(db): add auto increment feature to environments table (#2166)
Browse files Browse the repository at this point in the history
Ref: SRX-JXABF5
  • Loading branch information
AminSlk authored Dec 11, 2024
1 parent 9e76991 commit 1da7225
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 60 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
ALTER TABLE IF EXISTS environments ADD COLUMN IF NOT EXISTS row_version INTEGER;
DO $$
BEGIN
IF EXISTS (SELECT 1
FROM information_schema.columns
WHERE table_name = 'environments'
AND column_name = 'version') THEN
EXECUTE 'WITH ordered_rows AS (
SELECT version, name, ROW_NUMBER() OVER (ORDER BY version) AS row_num
FROM environments
)
UPDATE environments
SET row_version = ordered_rows.row_num
FROM ordered_rows
WHERE environments.version = ordered_rows.version AND environments.name = ordered_rows.name;';
END IF;
END $$;

DROP SEQUENCE IF EXISTS environments_version_seq CASCADE;
CREATE SEQUENCE IF NOT EXISTS environments_version_seq OWNED BY environments.row_version;

SELECT setval('environments_version_seq', coalesce(max(row_version), 0) + 1, false) FROM environments;

ALTER TABLE IF EXISTS environments
ALTER COLUMN row_version SET DEFAULT nextval('environments_version_seq');

ALTER TABLE IF EXISTS environments DROP CONSTRAINT IF EXISTS environments_pkey;

ALTER TABLE IF EXISTS environments ADD PRIMARY KEY (row_version, name);

ALTER TABLE IF EXISTS environments DROP COLUMN IF EXISTS version;
ALTER TABLE IF EXISTS environments RENAME COLUMN row_version TO version;
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
CREATE TABLE IF NOT EXISTS environments_new
(
version INTEGER PRIMARY KEY AUTOINCREMENT,
created TIMESTAMP,
name VARCHAR(255),
json VARCHAR,
deleted bool DEFAULT false NOT NULL,
applications VARCHAR
);

INSERT INTO environments_new (created, name, json, deleted, applications)
SELECT created, name, json, deleted, applications
FROM environments
ORDER BY version;

DROP TABLE IF EXISTS environments;
ALTER TABLE environments_new RENAME TO environments;
34 changes: 10 additions & 24 deletions pkg/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -5316,15 +5316,13 @@ type DBAllEnvironmentsRow struct {

type DBEnvironment struct {
Created time.Time
Version int64
Name string
Config config.EnvironmentConfig
Applications []string
}

type DBEnvironmentRow struct {
Created time.Time
Version int64
Name string
Config string
Applications string
Expand All @@ -5344,7 +5342,6 @@ func EnvironmentFromRow(_ context.Context, row *DBEnvironmentRow) (*DBEnvironmen
}
return &DBEnvironment{
Created: row.Created,
Version: row.Version,
Name: row.Name,
Config: parsedConfig,
Applications: applications,
Expand All @@ -5357,7 +5354,7 @@ func (h *DBHandler) DBSelectEnvironment(ctx context.Context, tx *sql.Tx, environ

selectQuery := h.AdaptQuery(
`
SELECT created, version, name, json, applications
SELECT created, name, json, applications
FROM environments
WHERE name=? AND deleted=false
ORDER BY version DESC
Expand Down Expand Up @@ -5385,7 +5382,7 @@ func (h *DBHandler) DBSelectEnvironmentAtTimestamp(ctx context.Context, tx *sql.

selectQuery := h.AdaptQuery(
`
SELECT created, version, name, json, applications
SELECT created, name, json, applications
FROM environments
WHERE name=? AND deleted=false AND created <= ?
ORDER BY version DESC
Expand Down Expand Up @@ -5418,7 +5415,7 @@ func (h *DBHandler) processEnvironmentRow(ctx context.Context, rows *sql.Rows) (
if rows.Next() {
//exhaustruct:ignore
row := DBEnvironmentRow{}
err := rows.Scan(&row.Created, &row.Version, &row.Name, &row.Config, &row.Applications)
err := rows.Scan(&row.Created, &row.Name, &row.Config, &row.Applications)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, nil
Expand Down Expand Up @@ -5448,7 +5445,6 @@ func (h *DBHandler) DBSelectEnvironmentsBatch(ctx context.Context, tx *sql.Tx, e
`
SELECT
environments.created AS created,
environments.version AS version,
environments.name AS name,
environments.json AS json,
environments.applications AS applications
Expand Down Expand Up @@ -5498,7 +5494,7 @@ LIMIT ?
for rows.Next() {
//exhaustruct:ignore
row := DBEnvironmentRow{}
err := rows.Scan(&row.Created, &row.Version, &row.Name, &row.Config, &row.Applications)
err := rows.Scan(&row.Created, &row.Name, &row.Config, &row.Applications)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, nil
Expand All @@ -5516,7 +5512,7 @@ LIMIT ?

// DBWriteEnvironment writes the env to the db
// if the previousVersion is not supplied, it will do another request to get the environment.
func (h *DBHandler) DBWriteEnvironment(ctx context.Context, tx *sql.Tx, environmentName string, environmentConfig config.EnvironmentConfig, applications []string, previousVersion *int64) error {
func (h *DBHandler) DBWriteEnvironment(ctx context.Context, tx *sql.Tx, environmentName string, environmentConfig config.EnvironmentConfig, applications []string) error {
span, _ := tracer.StartSpanFromContext(ctx, "DBWriteEnvironment")
defer span.Finish()

Expand All @@ -5531,17 +5527,8 @@ func (h *DBHandler) DBWriteEnvironment(ctx context.Context, tx *sql.Tx, environm
if err != nil {
return fmt.Errorf("error while marshalling the environment config %v, error: %w", environmentConfig, err)
}
var existingEnvironmentVersion int64 = 0
if previousVersion == nil {
existingEnvironment, err := h.DBSelectEnvironment(ctx, tx, environmentName)
if err != nil {
return fmt.Errorf("error while selecting environment %s from database, error: %w", environmentName, err)
}
if existingEnvironment != nil {
existingEnvironmentVersion = existingEnvironment.Version
}
} else {
existingEnvironmentVersion = *previousVersion
if err != nil {
return fmt.Errorf("error while selecting environment %s from database, error: %w", environmentName, err)
}

slices.Sort(applications) // we don't really *need* the sorting, it's just for convenience
Expand All @@ -5551,7 +5538,7 @@ func (h *DBHandler) DBWriteEnvironment(ctx context.Context, tx *sql.Tx, environm
}

insertQuery := h.AdaptQuery(
"INSERT Into environments (created, version, name, json, applications, deleted) VALUES (?, ?, ?, ?, ?, ?);",
"INSERT Into environments (created, name, json, applications, deleted) VALUES (?, ?, ?, ?, ?);",
)
now, err := h.DBReadTransactionTimestamp(ctx, tx)
if err != nil {
Expand All @@ -5561,7 +5548,6 @@ func (h *DBHandler) DBWriteEnvironment(ctx context.Context, tx *sql.Tx, environm
_, err = tx.Exec(
insertQuery,
*now,
existingEnvironmentVersion+1,
environmentName,
jsonToInsert,
string(applicationsJson),
Expand Down Expand Up @@ -5759,7 +5745,7 @@ func (h *DBHandler) RunCustomMigrationEnvironments(ctx context.Context, getAllEn
if allEnvsApps[envName] == nil {
allEnvsApps[envName] = make([]string, 0)
}
err = h.DBWriteEnvironment(ctx, transaction, envName, config, allEnvsApps[envName], nil)
err = h.DBWriteEnvironment(ctx, transaction, envName, config, allEnvsApps[envName])
if err != nil {
return fmt.Errorf("unable to write manifest for environment %s to the database, error: %w", envName, err)
}
Expand Down Expand Up @@ -5813,7 +5799,7 @@ func (h *DBHandler) RunCustomMigrationEnvironmentApplications(ctx context.Contex
if allEnvsApps[envName] == nil {
allEnvsApps[envName] = make([]string, 0)
}
err = h.DBWriteEnvironment(ctx, transaction, envName, env.Config, allEnvsApps[envName], &env.Version)
err = h.DBWriteEnvironment(ctx, transaction, envName, env.Config, allEnvsApps[envName])
if err != nil {
return fmt.Errorf("unable to write manifest for environment %s to the database, error: %w", envName, err)
}
Expand Down
26 changes: 8 additions & 18 deletions pkg/db/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2612,7 +2612,6 @@ func TestReadWriteEnvironment(t *testing.T) {
},
EnvToQuery: "development",
ExpectedEntry: &DBEnvironment{
Version: 1,
Name: "development",
Config: testutil.MakeEnvConfigLatest(nil),
Applications: []string{"app1", "app2", "app3"},
Expand All @@ -2629,7 +2628,6 @@ func TestReadWriteEnvironment(t *testing.T) {
},
EnvToQuery: "development",
ExpectedEntry: &DBEnvironment{
Version: 1,
Name: "development",
Config: testutil.MakeEnvConfigLatestWithGroup(nil, conversion.FromString("development-group")),
Applications: []string{"app1"},
Expand All @@ -2649,9 +2647,8 @@ func TestReadWriteEnvironment(t *testing.T) {
},
EnvToQuery: "development",
ExpectedEntry: &DBEnvironment{
Version: 2,
Name: "development",
Config: testutil.MakeEnvConfigLatestWithGroup(nil, conversion.FromString("development-group")),
Name: "development",
Config: testutil.MakeEnvConfigLatestWithGroup(nil, conversion.FromString("development-group")),
},
},
{
Expand All @@ -2672,9 +2669,8 @@ func TestReadWriteEnvironment(t *testing.T) {
},
EnvToQuery: "development",
ExpectedEntry: &DBEnvironment{
Version: 3,
Name: "development",
Config: testutil.MakeEnvConfigLatestWithGroup(nil, conversion.FromString("another-development-group")),
Name: "development",
Config: testutil.MakeEnvConfigLatestWithGroup(nil, conversion.FromString("another-development-group")),
},
},
{
Expand All @@ -2691,9 +2687,8 @@ func TestReadWriteEnvironment(t *testing.T) {
},
EnvToQuery: "staging",
ExpectedEntry: &DBEnvironment{
Version: 1,
Name: "staging",
Config: testutil.MakeEnvConfigUpstream("development", nil),
Name: "staging",
Config: testutil.MakeEnvConfigUpstream("development", nil),
},
},
{
Expand Down Expand Up @@ -2722,7 +2717,6 @@ func TestReadWriteEnvironment(t *testing.T) {
},
EnvToQuery: "development",
ExpectedEntry: &DBEnvironment{
Version: 1,
Name: "development",
Config: testutil.MakeEnvConfigLatest(nil),
Applications: []string{"app1", "capp", "zapp"},
Expand All @@ -2738,7 +2732,7 @@ func TestReadWriteEnvironment(t *testing.T) {

for _, envToWrite := range tc.EnvsToWrite {
err := dbHandler.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
err := dbHandler.DBWriteEnvironment(ctx, transaction, envToWrite.EnvironmentName, envToWrite.EnvironmentConfig, envToWrite.Applications, nil)
err := dbHandler.DBWriteEnvironment(ctx, transaction, envToWrite.EnvironmentName, envToWrite.EnvironmentConfig, envToWrite.Applications)
if err != nil {
return fmt.Errorf("error while writing environment, error: %w", err)
}
Expand Down Expand Up @@ -2802,13 +2796,11 @@ func TestReadEnvironmentBatch(t *testing.T) {
EnvsToQuery: []string{"development", "staging"},
ExpectedEnvs: &[]DBEnvironment{
{
Version: 1,
Name: "development",
Config: testutil.MakeEnvConfigLatest(nil),
Applications: []string{"app1", "app2", "app3"},
},
{
Version: 1,
Name: "staging",
Config: testutil.MakeEnvConfigLatest(nil),
Applications: []string{"app1", "app2", "app3"},
Expand Down Expand Up @@ -2837,13 +2829,11 @@ func TestReadEnvironmentBatch(t *testing.T) {
EnvsToQuery: []string{"development", "staging"},
ExpectedEnvs: &[]DBEnvironment{
{
Version: 2,
Name: "development",
Config: testutil.MakeEnvConfigLatest(nil),
Applications: []string{"app1", "app2"},
},
{
Version: 1,
Name: "staging",
Config: testutil.MakeEnvConfigLatest(nil),
Applications: []string{"app1", "app2", "app3"},
Expand All @@ -2860,7 +2850,7 @@ func TestReadEnvironmentBatch(t *testing.T) {

for _, envToWrite := range tc.EnvsToWrite {
err := dbHandler.WithTransaction(ctx, false, func(ctx context.Context, transaction *sql.Tx) error {
err := dbHandler.DBWriteEnvironment(ctx, transaction, envToWrite.EnvironmentName, envToWrite.EnvironmentConfig, envToWrite.Applications, nil)
err := dbHandler.DBWriteEnvironment(ctx, transaction, envToWrite.EnvironmentName, envToWrite.EnvironmentConfig, envToWrite.Applications)
if err != nil {
return fmt.Errorf("error while writing environment, error: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion services/cd-service/pkg/repository/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -2502,7 +2502,7 @@ func (s *State) DBInsertApplicationWithOverview(ctx context.Context, transaction

func (s *State) DBInsertEnvironmentWithOverview(ctx context.Context, tx *sql.Tx, environmentName string, environmentConfig config.EnvironmentConfig, applications []string) error {
h := s.DBHandler
err := h.DBWriteEnvironment(ctx, tx, environmentName, environmentConfig, applications, nil)
err := h.DBWriteEnvironment(ctx, tx, environmentName, environmentConfig, applications)
if err != nil {
return err
}
Expand Down
12 changes: 3 additions & 9 deletions services/cd-service/pkg/repository/transformer.go
Original file line number Diff line number Diff line change
Expand Up @@ -813,7 +813,7 @@ func (c *CreateApplicationVersion) Transform(
}
}
if envInfo != nil && !found {
err = state.DBHandler.DBWriteEnvironment(ctx, transaction, env, envInfo.Config, append(envInfo.Applications, c.Application), &envInfo.Version)
err = state.DBHandler.DBWriteEnvironment(ctx, transaction, env, envInfo.Config, append(envInfo.Applications, c.Application))
if err != nil {
return "", GetCreateReleaseGeneralFailure(err)
}
Expand Down Expand Up @@ -1701,7 +1701,7 @@ func (u *UndeployApplication) Transform(
}
}
t.AddAppEnv(u.Application, envName, dbApp.Metadata.Team)
err = state.DBHandler.DBWriteEnvironment(ctx, transaction, envName, env.Config, newEnvApps, &env.Version)
err = state.DBHandler.DBWriteEnvironment(ctx, transaction, envName, env.Config, newEnvApps)
if err != nil {
return "", fmt.Errorf("UndeployApplication: could not write environment: %v", err)
}
Expand Down Expand Up @@ -2808,19 +2808,13 @@ func (c *CreateEnvironment) Transform(
}
if state.DBHandler.ShouldUseOtherTables() {
// first read the env to see if it has applications:
existingEnvironment, err := state.DBHandler.DBSelectEnvironment(ctx, transaction, c.Environment)
if err != nil {
return "", fmt.Errorf("could not select environment %s from database, error: %w", c.Environment, err)
}

// write to environments table
environmentApplications := make([]string, 0)
var version *int64
if existingEnvironment != nil {
environmentApplications = existingEnvironment.Applications
version = &existingEnvironment.Version
}
err = state.DBHandler.DBWriteEnvironment(ctx, transaction, c.Environment, c.Config, environmentApplications, version)
err = state.DBHandler.DBWriteEnvironment(ctx, transaction, c.Environment, c.Config, environmentApplications)
if err != nil {
return "", fmt.Errorf("unable to write to the environment table, error: %w", err)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -822,15 +822,15 @@ func TestReleaseTrain(t *testing.T) {
Environment: "staging",
Latest: true,
},
}, []string{appName}, nil)
}, []string{appName})
if err != nil {
return err
}
err = dbHandler.DBWriteEnvironment(ctx, transaction, "production", config.EnvironmentConfig{
Upstream: &config.EnvironmentConfigUpstream{
Environment: "staging",
},
}, []string{appName}, nil)
}, []string{appName})
if err != nil {
return err
}
Expand Down Expand Up @@ -1710,7 +1710,7 @@ func TestCreateUndeployApplicationVersion(t *testing.T) {
ArgoCd: nil,
EnvironmentGroup: nil,
}
err = dbHandler.DBWriteEnvironment(ctx, transaction, envAcceptance, envConfig, []string{}, nil)
err = dbHandler.DBWriteEnvironment(ctx, transaction, envAcceptance, envConfig, []string{})
if err != nil {
return err
}
Expand Down Expand Up @@ -2578,11 +2578,11 @@ func TestCreateUndeployLogic(t *testing.T) {
t.Fatal(err2)
}

err2 = dbHandler.DBWriteEnvironment(ctx, transaction, envAcceptance, envAcceptanceConfig, []string{appName}, nil)
err2 = dbHandler.DBWriteEnvironment(ctx, transaction, envAcceptance, envAcceptanceConfig, []string{appName})
if err2 != nil {
return err2
}
err2 = dbHandler.DBWriteEnvironment(ctx, transaction, envAcceptance2, envAcceptance2Config, []string{appName}, nil)
err2 = dbHandler.DBWriteEnvironment(ctx, transaction, envAcceptance2, envAcceptance2Config, []string{appName})
if err2 != nil {
return err2
}
Expand Down Expand Up @@ -2999,11 +2999,11 @@ func TestUndeployLogic(t *testing.T) {
if err2 != nil {
t.Fatal(err2)
}
err2 = dbHandler.DBWriteEnvironment(ctx, transaction, envAcceptance, environmentConfigAcceptance, []string{appName}, nil)
err2 = dbHandler.DBWriteEnvironment(ctx, transaction, envAcceptance, environmentConfigAcceptance, []string{appName})
if err2 != nil {
return err2
}
err2 = dbHandler.DBWriteEnvironment(ctx, transaction, envAcceptance2, environmentConfigAcceptance2, []string{appName}, nil)
err2 = dbHandler.DBWriteEnvironment(ctx, transaction, envAcceptance2, environmentConfigAcceptance2, []string{appName})
if err2 != nil {
return err2
}
Expand Down
Loading

0 comments on commit 1da7225

Please sign in to comment.