github.com/adecaro/fabric-ca@v2.0.0-alpha+incompatible/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 "github.com/cloudflare/cfssl/log" 13 "github.com/hyperledger/fabric-ca/lib/server/db" 14 "github.com/hyperledger/fabric-ca/lib/server/db/util" 15 "github.com/hyperledger/fabric-ca/lib/server/user" 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 // Future schema updates should add to the logic below to handle other levels 40 curLevel := m.CurLevels.Identity 41 if curLevel < 1 { 42 log.Debug("Upgrade identity table to level 1") 43 _, err := tx.Exec(funcName, "ALTER TABLE users MODIFY id VARCHAR(255), MODIFY type VARCHAR(256), MODIFY affiliation VARCHAR(1024)") 44 if err != nil { 45 return err 46 } 47 _, err = tx.Exec(funcName, "ALTER TABLE users MODIFY attributes TEXT") 48 if err != nil { 49 return err 50 } 51 _, err = tx.Exec(funcName, "ALTER TABLE users ADD COLUMN level INTEGER DEFAULT 0 AFTER max_enrollments") 52 if err != nil { 53 if !strings.Contains(err.Error(), "1060") { // Already using the latest schema 54 return err 55 } 56 } 57 curLevel++ 58 } 59 if curLevel < 2 { 60 log.Debug("Upgrade identity table to level 2") 61 _, err := tx.Exec(funcName, "ALTER TABLE users ADD COLUMN incorrect_password_attempts INTEGER DEFAULT 0 AFTER level") 62 if err != nil { 63 if !strings.Contains(err.Error(), "1060") { // Already using the latest schema 64 return err 65 } 66 } 67 curLevel++ 68 } 69 70 users, err := user.GetUserLessThanLevel(tx, m.SrvLevels.Identity) 71 if err != nil { 72 return err 73 } 74 75 for _, u := range users { 76 err := u.Migrate(tx) 77 if err != nil { 78 return err 79 } 80 } 81 82 _, err = tx.Exec(funcName, tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'identity.level')"), m.SrvLevels.Identity) 83 if err != nil { 84 return err 85 } 86 return nil 87 } 88 89 // MigrateCertificatesTable is responsible for migrating certificates table 90 func (m *Migrator) MigrateCertificatesTable() error { 91 tx := m.Tx 92 const funcName = "MigrateCertificatesTable" 93 // Future schema updates should add to the logic below to handle other levels 94 if m.CurLevels.Certificate < 1 { 95 log.Debug("Upgrade certificates table to level 1") 96 _, err := tx.Exec(funcName, "ALTER TABLE certificates ADD COLUMN level INTEGER DEFAULT 0 AFTER pem") 97 if err != nil { 98 if !strings.Contains(err.Error(), "1060") { // Already using the latest schema 99 return err 100 } 101 } 102 _, err = tx.Exec(funcName, "ALTER TABLE certificates MODIFY id VARCHAR(255)") 103 if err != nil { 104 return err 105 } 106 } 107 _, err := tx.Exec(funcName, tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'certificate.level')"), m.SrvLevels.Certificate) 108 if err != nil { 109 return err 110 } 111 return nil 112 } 113 114 // MigrateAffiliationsTable is responsible for migrating affiliations table 115 func (m *Migrator) MigrateAffiliationsTable() error { 116 tx := m.Tx 117 const funcName = "MigrateAffiliationsTable" 118 // Future schema updates should add to the logic below to handle other levels 119 if m.CurLevels.Affiliation < 1 { 120 log.Debug("Upgrade affiliations table to level 1") 121 _, err := tx.Exec(funcName, "ALTER TABLE affiliations ADD COLUMN level INTEGER DEFAULT 0 AFTER prekey") 122 if err != nil { 123 if !strings.Contains(err.Error(), "1060") { // Already using the latest schema 124 return err 125 } 126 } 127 _, err = tx.Exec(funcName, "ALTER TABLE affiliations DROP INDEX name;") 128 if err != nil { 129 if !strings.Contains(err.Error(), "Error 1091") { // Indicates that index not found 130 return err 131 } 132 } 133 _, err = tx.Exec(funcName, "ALTER TABLE affiliations ADD COLUMN id INT NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST") 134 if err != nil { 135 if !strings.Contains(err.Error(), "1060") { // Already using the latest schema 136 return err 137 } 138 } 139 _, err = tx.Exec(funcName, "ALTER TABLE affiliations MODIFY name VARCHAR(1024), MODIFY prekey VARCHAR(1024)") 140 if err != nil { 141 return err 142 } 143 _, err = tx.Exec(funcName, "ALTER TABLE affiliations ADD INDEX name_index (name)") 144 if err != nil { 145 if !strings.Contains(err.Error(), "Error 1061") { // Error 1061: Duplicate key name, index already exists 146 return err 147 } 148 } 149 } 150 151 _, err := tx.Exec(funcName, tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'affiliation.level')"), m.SrvLevels.Affiliation) 152 if err != nil { 153 return err 154 } 155 156 return nil 157 } 158 159 // MigrateCredentialsTable is responsible for migrating credentials table 160 func (m *Migrator) MigrateCredentialsTable() error { 161 _, err := m.Tx.Exec("MigrateCredentialsTable", m.Tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'credential.level')"), m.SrvLevels.Credential) 162 return err 163 } 164 165 // MigrateRAInfoTable is responsible for migrating rainfo table 166 func (m *Migrator) MigrateRAInfoTable() error { 167 _, err := m.Tx.Exec("MigrateRAInfoTable", m.Tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'rcinfo.level')"), m.SrvLevels.RAInfo) 168 return err 169 } 170 171 // MigrateNoncesTable is responsible for migrating nonces table 172 func (m *Migrator) MigrateNoncesTable() error { 173 _, err := m.Tx.Exec("MigrateNoncesTable", m.Tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'nonce.level')"), m.SrvLevels.Nonce) 174 return err 175 } 176 177 // Rollback is responsible for rollback transaction if an error is encountered 178 func (m *Migrator) Rollback() error { 179 err := m.Tx.Rollback("Migration") 180 if err != nil { 181 log.Errorf("Error encountered while rolling back database migration changes: %s", err) 182 return err 183 } 184 return nil 185 } 186 187 // Commit is responsible for committing the migration db transcation 188 func (m *Migrator) Commit() error { 189 err := m.Tx.Commit("Migration") 190 if err != nil { 191 return errors.Wrap(err, "Error encountered while committing database migration changes") 192 } 193 return nil 194 }