Files
upstream-corteza/server/store/adapters/rdbms/upgrade.go
upstream-mirror 7e385fc126
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
snapshot of https://github.com/cortezaproject/corteza.git (2024.9.x, 2026-09-18; blobs > 131072B omitted)
2026-09-18 01:22:23 +05:00

210 lines
5.2 KiB
Go

package rdbms
import (
"context"
"fmt"
automationModels "github.com/cortezaproject/corteza/server/automation/model"
composeModels "github.com/cortezaproject/corteza/server/compose/model"
federationModels "github.com/cortezaproject/corteza/server/federation/model"
"github.com/cortezaproject/corteza/server/pkg/dal"
"github.com/cortezaproject/corteza/server/pkg/errors"
"github.com/cortezaproject/corteza/server/store/adapters/rdbms/ddl"
systemModels "github.com/cortezaproject/corteza/server/system/model"
"go.uber.org/zap"
)
func (s *Store) Upgrade(ctx context.Context) (err error) {
for _, fix := range fixesPre {
if err = fix(ctx, s); err != nil {
return
}
}
err = createTablesFromModels(
ctx,
s.log(ctx),
s.DataDefiner,
systemModels.Models(),
composeModels.Models(),
automationModels.Models(),
federationModels.Models(),
)
if err != nil {
return err
}
for _, fix := range fixesPost {
if err = fix(ctx, s); err != nil {
return
}
}
return
}
func createTablesFromModels(ctx context.Context, log *zap.Logger, dd ddl.DataDefiner, sets ...dal.ModelSet) (err error) {
var (
tbl *ddl.Table
)
for _, mm := range sets {
for _, m := range mm {
log.Debug("verifying primary store table", zap.String("table", m.Ident))
if tbl, err = dd.ConvertModel(m); err != nil {
return fmt.Errorf("can not convert model %q to table: %w", m.Ident, err)
}
_, err = dd.TableLookup(ctx, m.Ident)
if err != nil {
if !errors.IsNotFound(err) {
return fmt.Errorf("can not do a table lookup: %w", err)
}
if err = dd.TableCreate(ctx, tbl); err != nil {
return fmt.Errorf("can not create table from model %q: %w", m.Ident, err)
}
}
for _, idx := range tbl.Indexes {
if idx.Ident == ddl.PRIMARY_KEY {
// @todo move this decision to drivers!
continue
}
_, err = dd.IndexLookup(ctx, idx.Ident, idx.TableIdent)
if err != nil && !errors.IsNotFound(err) {
return
} else if errors.IsNotFound(err) {
if err = dd.IndexCreate(ctx, tbl.Ident, idx); err != nil {
return fmt.Errorf("can not create index %q on table %q: %w", idx.Ident, tbl.Ident, err)
}
}
}
}
}
return nil
}
func dropTable(ctx context.Context, s *Store, table string) error {
_, err := s.DataDefiner.TableLookup(ctx, table)
if err != nil {
if errors.IsNotFound(err) {
return nil
}
return err
}
return s.DataDefiner.TableDrop(ctx, table)
}
// addColumn adds column on a table but only if table exists!
//
// If table does not exist adding column can be skipped
// We can assume that 2nd step of the upgrade process will include the column
func addColumn(ctx context.Context, s *Store, table string, attr *dal.Attribute) error {
err, _ := addColumnExists(ctx, s, table, attr)
return err
}
func addColumnExists(ctx context.Context, s *Store, table string, attr *dal.Attribute) (err error, exists bool) {
tbl, err := s.DataDefiner.TableLookup(ctx, table)
if err != nil {
if errors.IsNotFound(err) {
return nil, false
}
return err, false
}
if tbl.ColumnByIdent(attr.StoreIdent()) != nil {
return nil, true
}
s.log(ctx).Info(fmt.Sprintf("extending %q table with %q column", table, attr.StoreIdent()))
col, err := s.DataDefiner.ConvertAttribute(attr)
if err != nil {
return err, false
}
return s.DataDefiner.ColumnAdd(ctx, table, col), false
}
// dropColumns removes columns from a table but only if table exists!
//
// If table does not exist column removing can be skipped
// We can assume that 2nd step of the upgrade process will omit the column
func dropColumns(ctx context.Context, s *Store, table string, cc ...string) error {
tbl, err := s.DataDefiner.TableLookup(ctx, table)
if err != nil {
if errors.IsNotFound(err) {
return nil
}
return err
}
for _, c := range cc {
if tbl.ColumnByIdent(c) == nil {
// column does not exist, nothing to do
continue
}
s.log(ctx).Info(fmt.Sprintf("dropping %q column from %q", c, table))
if err := s.DataDefiner.ColumnDrop(ctx, table, c); err != nil {
return err
}
}
return nil
}
// renameColumn renames columns from a table but only if table exists!
//
// If table does not exist column renaming can be skipped
// We can assume that 2nd step of the upgrade process will have columns properly nameed
func renameColumn(ctx context.Context, s *Store, table string, from, to string) error {
tbl, err := s.DataDefiner.TableLookup(ctx, table)
if err != nil {
if errors.IsNotFound(err) {
return nil
}
return err
}
if tbl.ColumnByIdent(from) == nil {
// from column does not exist, nothing to do
return nil
}
if tbl.ColumnByIdent(to) != nil {
// to column already exists, nothing to do
return nil
}
s.log(ctx).Info(fmt.Sprintf("renaming %q column on table %q to %q", from, table, to))
if err := s.DataDefiner.ColumnRename(ctx, table, from, to); err != nil {
return err
}
return nil
}
// tableNames returns table names that Corteza creates
func tableNames() (tnames []string) {
cortezaModels := append(systemModels.Models(), composeModels.Models()...)
cortezaModels = append(cortezaModels, automationModels.Models()...)
cortezaModels = append(cortezaModels, federationModels.Models()...)
for _, m := range cortezaModels {
tnames = append(tnames, m.Ident)
}
return tnames
}