gitee.com/zhaochuninhefei/fabric-ca-gm@v0.0.2/lib/server/db/mysql/migrator.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package mysql
     8  
     9  import (
    10  	"strings"
    11  
    12  	"gitee.com/zhaochuninhefei/fabric-ca-gm/lib/server/db"
    13  	"gitee.com/zhaochuninhefei/fabric-ca-gm/lib/server/db/util"
    14  	"gitee.com/zhaochuninhefei/fabric-ca-gm/lib/server/user"
    15  	log "gitee.com/zhaochuninhefei/zcgolog/zclog"
    16  	"github.com/pkg/errors"
    17  )
    18  
    19  // Migrator defines migrator
    20  type Migrator struct {
    21  	Tx        db.FabricCATx
    22  	CurLevels *util.Levels
    23  	SrvLevels *util.Levels
    24  }
    25  
    26  // NewMigrator returns a migrator instance
    27  func NewMigrator(tx db.FabricCATx, curLevels, srvLevels *util.Levels) *Migrator {
    28  	return &Migrator{
    29  		Tx:        tx,
    30  		CurLevels: curLevels,
    31  		SrvLevels: srvLevels,
    32  	}
    33  }
    34  
    35  // MigrateUsersTable is responsible for migrating users table
    36  func (m *Migrator) MigrateUsersTable() error {
    37  	tx := m.Tx
    38  	const funcName = "MigrateUsersTable"
    39  
    40  	// Future schema updates should add to the logic below to handle other levels
    41  	switch m.CurLevels.Identity {
    42  	case 0:
    43  		log.Debug("Upgrade identity table to level 1")
    44  		_, err := tx.Exec(funcName, "ALTER TABLE users MODIFY id VARCHAR(255), MODIFY type VARCHAR(256), MODIFY affiliation VARCHAR(1024)")
    45  		if err != nil {
    46  			return err
    47  		}
    48  		_, err = tx.Exec(funcName, "ALTER TABLE users MODIFY attributes TEXT")
    49  		if err != nil {
    50  			return err
    51  		}
    52  		_, err = tx.Exec(funcName, "ALTER TABLE users ADD COLUMN level INTEGER DEFAULT 0 AFTER max_enrollments")
    53  		if err != nil && !strings.Contains(err.Error(), "1060") { // Already using the latest schema
    54  			return err
    55  		}
    56  		fallthrough
    57  
    58  	case 1:
    59  		log.Debug("Upgrade identity table to level 2")
    60  		_, err := tx.Exec(funcName, "ALTER TABLE users ADD COLUMN incorrect_password_attempts INTEGER DEFAULT 0 AFTER level")
    61  		if err != nil && !strings.Contains(err.Error(), "1060") { // Already using the latest schema
    62  			return err
    63  		}
    64  		fallthrough
    65  
    66  	default:
    67  		users, err := user.GetUserLessThanLevel(tx, m.SrvLevels.Identity)
    68  		if err != nil {
    69  			return err
    70  		}
    71  
    72  		for _, u := range users {
    73  			err := u.Migrate(tx)
    74  			if err != nil {
    75  				return err
    76  			}
    77  		}
    78  
    79  		_, err = tx.Exec(funcName, tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'identity.level')"), m.SrvLevels.Identity)
    80  		if err != nil {
    81  			return err
    82  		}
    83  
    84  		return nil
    85  	}
    86  }
    87  
    88  // MigrateCertificatesTable is responsible for migrating certificates table
    89  func (m *Migrator) MigrateCertificatesTable() error {
    90  	tx := m.Tx
    91  	const funcName = "MigrateCertificatesTable"
    92  
    93  	// Future schema updates should add to the logic below to handle other levels
    94  	switch m.CurLevels.Certificate {
    95  	case 0:
    96  		log.Debug("Upgrade certificates table to level 1")
    97  		_, err := tx.Exec(funcName, "ALTER TABLE certificates ADD COLUMN level INTEGER DEFAULT 0 AFTER pem")
    98  		if err != nil {
    99  			if !strings.Contains(err.Error(), "1060") { // Already using the latest schema
   100  				return err
   101  			}
   102  		}
   103  		_, err = tx.Exec(funcName, "ALTER TABLE certificates MODIFY id VARCHAR(255)")
   104  		if err != nil {
   105  			return err
   106  		}
   107  		fallthrough
   108  
   109  	case 1:
   110  		log.Debug("Upgrade certificates table to level 2")
   111  		_, err := tx.Exec(funcName, "ALTER TABLE certificates MODIFY pem varbinary(8192)")
   112  		if err != nil {
   113  			return err
   114  		}
   115  		fallthrough
   116  
   117  	default:
   118  		_, err := tx.Exec(funcName, tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'certificate.level')"), m.SrvLevels.Certificate)
   119  		if err != nil {
   120  			return err
   121  		}
   122  		return nil
   123  	}
   124  }
   125  
   126  // MigrateAffiliationsTable is responsible for migrating affiliations table
   127  func (m *Migrator) MigrateAffiliationsTable() error {
   128  	tx := m.Tx
   129  	const funcName = "MigrateAffiliationsTable"
   130  
   131  	// Future schema updates should add to the logic below to handle other levels
   132  	switch m.CurLevels.Affiliation {
   133  	case 0:
   134  		log.Debug("Upgrade affiliations table to level 1")
   135  		_, err := tx.Exec(funcName, "ALTER TABLE affiliations ADD COLUMN level INTEGER DEFAULT 0 AFTER prekey")
   136  		if err != nil && !strings.Contains(err.Error(), "1060") { // Already using the latest schema
   137  			return err
   138  		}
   139  		_, err = tx.Exec(funcName, "ALTER TABLE affiliations DROP INDEX name;")
   140  		if err != nil && !strings.Contains(err.Error(), "Error 1091") { // Indicates that index not found
   141  			return err
   142  		}
   143  		_, err = tx.Exec(funcName, "ALTER TABLE affiliations ADD COLUMN id INT NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST")
   144  		if err != nil && !strings.Contains(err.Error(), "1060") { // Already using the latest schema
   145  			return err
   146  		}
   147  		_, err = tx.Exec(funcName, "ALTER TABLE affiliations MODIFY name VARCHAR(1024), MODIFY prekey VARCHAR(1024)")
   148  		if err != nil {
   149  			return err
   150  		}
   151  		_, err = tx.Exec(funcName, "ALTER TABLE affiliations ADD INDEX name_index (name)")
   152  		if err != nil && !strings.Contains(err.Error(), "Error 1061") { // Error 1061: Duplicate key name, index already exists
   153  			return err
   154  		}
   155  		fallthrough
   156  
   157  	default:
   158  		_, err := tx.Exec(funcName, tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'affiliation.level')"), m.SrvLevels.Affiliation)
   159  		if err != nil {
   160  			return err
   161  		}
   162  
   163  		return nil
   164  	}
   165  }
   166  
   167  // MigrateCredentialsTable is responsible for migrating credentials table
   168  func (m *Migrator) MigrateCredentialsTable() error {
   169  	_, err := m.Tx.Exec("MigrateCredentialsTable", m.Tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'credential.level')"), m.SrvLevels.Credential)
   170  	return err
   171  }
   172  
   173  // MigrateRAInfoTable is responsible for migrating rainfo table
   174  func (m *Migrator) MigrateRAInfoTable() error {
   175  	_, err := m.Tx.Exec("MigrateRAInfoTable", m.Tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'rcinfo.level')"), m.SrvLevels.RAInfo)
   176  	return err
   177  }
   178  
   179  // MigrateNoncesTable is responsible for migrating nonces table
   180  func (m *Migrator) MigrateNoncesTable() error {
   181  	_, err := m.Tx.Exec("MigrateNoncesTable", m.Tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'nonce.level')"), m.SrvLevels.Nonce)
   182  	return err
   183  }
   184  
   185  // Rollback is responsible for rollback transaction if an error is encountered
   186  func (m *Migrator) Rollback() error {
   187  	err := m.Tx.Rollback("Migration")
   188  	if err != nil {
   189  		log.Errorf("Error encountered while rolling back database migration changes: %s", err)
   190  		return err
   191  	}
   192  	return nil
   193  }
   194  
   195  // Commit is responsible for committing the migration db transcation
   196  func (m *Migrator) Commit() error {
   197  	err := m.Tx.Commit("Migration")
   198  	if err != nil {
   199  		return errors.Wrap(err, "Error encountered while committing database migration changes")
   200  	}
   201  	return nil
   202  }