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

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package sqlite
     8  
     9  import (
    10  	"gitee.com/zhaochuninhefei/fabric-ca-gm/lib/server/db"
    11  	"gitee.com/zhaochuninhefei/fabric-ca-gm/lib/server/db/util"
    12  	"gitee.com/zhaochuninhefei/fabric-ca-gm/lib/server/user"
    13  	log "gitee.com/zhaochuninhefei/zcgolog/zclog"
    14  	"github.com/pkg/errors"
    15  )
    16  
    17  // Migrator defines migrator
    18  type Migrator struct {
    19  	Tx        db.FabricCATx
    20  	CurLevels *util.Levels
    21  	SrvLevels *util.Levels
    22  }
    23  
    24  // NewMigrator returns a migrator instance
    25  func NewMigrator(tx db.FabricCATx, curLevels, srvLevels *util.Levels) *Migrator {
    26  	return &Migrator{
    27  		Tx:        tx,
    28  		CurLevels: curLevels,
    29  		SrvLevels: srvLevels,
    30  	}
    31  }
    32  
    33  // MigrateUsersTable is responsible for migrating users table
    34  func (m *Migrator) MigrateUsersTable() error {
    35  	tx := m.Tx
    36  	const funcName = "MigrateUsersTable"
    37  
    38  	// Future schema updates should add to the logic below to handle other levels
    39  	switch m.CurLevels.Identity {
    40  	case 0:
    41  		log.Debug("Upgrade identity table to level 1")
    42  		_, err := tx.Exec(funcName, "ALTER TABLE users RENAME TO users_old")
    43  		if err != nil {
    44  			return err
    45  		}
    46  		err = createIdentityTable(tx)
    47  		if err != nil {
    48  			return err
    49  		}
    50  		// If coming from a table that did not yet have the level column then we can only copy columns that exist in both the tables
    51  		_, err = tx.Exec(funcName, "INSERT INTO users (id, token, type, affiliation, attributes, state, max_enrollments) SELECT id, token, type, affiliation, attributes, state, max_enrollments FROM users_old")
    52  		if err != nil {
    53  			return err
    54  		}
    55  		_, err = tx.Exec(funcName, "DROP TABLE users_old")
    56  		if err != nil {
    57  			return err
    58  		}
    59  		fallthrough
    60  
    61  	case 1:
    62  		log.Debug("Upgrade identity table to level 2")
    63  		_, err := tx.Exec(funcName, "ALTER TABLE users RENAME TO users_old")
    64  		if err != nil {
    65  			return err
    66  		}
    67  		err = createIdentityTable(tx)
    68  		if err != nil {
    69  			return err
    70  		}
    71  		// If coming from a table that did not yet have the level column then we can only copy columns that exist in both the tables
    72  		_, err = tx.Exec(funcName, "INSERT INTO users (id, token, type, affiliation, attributes, state, max_enrollments, level) SELECT id, token, type, affiliation, attributes, state, max_enrollments, level FROM users_old")
    73  		if err != nil {
    74  			return err
    75  		}
    76  		_, err = tx.Exec(funcName, "DROP TABLE users_old")
    77  		if err != nil {
    78  			return err
    79  		}
    80  		fallthrough
    81  
    82  	default:
    83  		users, err := user.GetUserLessThanLevel(tx, m.SrvLevels.Identity)
    84  		if err != nil {
    85  			return err
    86  		}
    87  
    88  		for _, u := range users {
    89  			err := u.Migrate(tx)
    90  			if err != nil {
    91  				return err
    92  			}
    93  		}
    94  
    95  		_, err = tx.Exec(funcName, tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'identity.level')"), m.SrvLevels.Identity)
    96  		if err != nil {
    97  			return err
    98  		}
    99  		return nil
   100  	}
   101  }
   102  
   103  // MigrateCertificatesTable is responsible for migrating certificates table
   104  // SQLite has limited support for altering table columns, to upgrade the schema we
   105  // require renaming the current certificates table to certificates_old and then creating a new certificates
   106  // table using the new schema definition. Next, we proceed to copy the data from the old table to
   107  // new table, and then drop the old table.
   108  func (m *Migrator) MigrateCertificatesTable() error {
   109  	tx := m.Tx
   110  	const funcName = "MigrateCertificatesTable"
   111  
   112  	// Future schema updates should add to the logic below to handle other levels
   113  	switch m.CurLevels.Certificate {
   114  	case 0:
   115  		log.Debug("Upgrade certificates table to level 1")
   116  		_, err := tx.Exec(funcName, "ALTER TABLE certificates RENAME TO certificates_old")
   117  		if err != nil {
   118  			return err
   119  		}
   120  		err = createCertificateTable(tx)
   121  		if err != nil {
   122  			return err
   123  		}
   124  		// If coming from a table that did not yet have the level column then we can only copy columns that exist in both the tables
   125  		_, err = tx.Exec(funcName, "INSERT INTO certificates (id, serial_number, authority_key_identifier, ca_label, status, reason, expiry, revoked_at, pem) SELECT id, serial_number, authority_key_identifier, ca_label, status, reason, expiry, revoked_at, pem FROM certificates_old")
   126  		if err != nil {
   127  			return err
   128  		}
   129  		_, err = tx.Exec(funcName, "DROP TABLE certificates_old")
   130  		if err != nil {
   131  			return err
   132  		}
   133  		fallthrough
   134  
   135  	default:
   136  		_, err := tx.Exec(funcName, tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'certificate.level')"), m.SrvLevels.Certificate)
   137  		if err != nil {
   138  			return err
   139  		}
   140  		return nil
   141  	}
   142  }
   143  
   144  // MigrateAffiliationsTable is responsible for migrating affiliations table
   145  // SQLite has limited support for altering table columns, to upgrade the schema we
   146  // require renaming the current affiliations table to affiliations_old and then creating a new user
   147  // table using the new schema definition. Next, we proceed to copy the data from the old table to
   148  // new table, and then drop the old table.
   149  func (m *Migrator) MigrateAffiliationsTable() error {
   150  	tx := m.Tx
   151  	const funcName = "MigrateAffiliationsTable"
   152  
   153  	// Future schema updates should add to the logic below to handle other levels
   154  	switch m.CurLevels.Affiliation {
   155  	case 0:
   156  		log.Debug("Upgrade affiliations table to level 1")
   157  		_, err := tx.Exec(funcName, "ALTER TABLE affiliations RENAME TO affiliations_old")
   158  		if err != nil {
   159  			return err
   160  		}
   161  		err = createAffiliationTable(tx)
   162  		if err != nil {
   163  			return err
   164  		}
   165  		// If coming from a table that did not yet have the level column then we can only copy columns that exist in both the tables
   166  		_, err = tx.Exec(funcName, "INSERT INTO affiliations (name, prekey) SELECT name, prekey FROM affiliations_old")
   167  		if err != nil {
   168  			return err
   169  		}
   170  		_, err = tx.Exec(funcName, "DROP TABLE affiliations_old")
   171  		if err != nil {
   172  			return err
   173  		}
   174  		fallthrough
   175  
   176  	default:
   177  		_, err := tx.Exec(funcName, tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'affiliation.level')"), m.SrvLevels.Affiliation)
   178  		if err != nil {
   179  			return err
   180  		}
   181  		return nil
   182  	}
   183  }
   184  
   185  // MigrateCredentialsTable is responsible for migrating credentials table
   186  func (m *Migrator) MigrateCredentialsTable() error {
   187  	_, err := m.Tx.Exec("MigrateCredentialsTable", m.Tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'credential.level')"), m.SrvLevels.Credential)
   188  	return err
   189  }
   190  
   191  // MigrateRAInfoTable is responsible for migrating rainfo table
   192  func (m *Migrator) MigrateRAInfoTable() error {
   193  	_, err := m.Tx.Exec("MigrateRAInfoTable", m.Tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'rcinfo.level')"), m.SrvLevels.RAInfo)
   194  	return err
   195  }
   196  
   197  // MigrateNoncesTable is responsible for migrating nonces table
   198  func (m *Migrator) MigrateNoncesTable() error {
   199  	_, err := m.Tx.Exec("MigrateNoncesTable", m.Tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'nonce.level')"), m.SrvLevels.Nonce)
   200  	return err
   201  }
   202  
   203  // Rollback is responsible for rollback transaction if an error is encountered
   204  func (m *Migrator) Rollback() error {
   205  	err := m.Tx.Rollback("Migration")
   206  	if err != nil {
   207  		log.Errorf("Error encountered while rolling back database migration changes: %s", err)
   208  		return err
   209  	}
   210  	return nil
   211  }
   212  
   213  // Commit is responsible for committing the migration db transcation
   214  func (m *Migrator) Commit() error {
   215  	err := m.Tx.Commit("Migration")
   216  	if err != nil {
   217  		return errors.Wrap(err, "Error encountered while committing database migration changes")
   218  	}
   219  	return nil
   220  }