gitee.com/zhaochuninhefei/fabric-ca-gm@v0.0.2/lib/server/db/postgres/migrator.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package postgres 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 ALTER COLUMN id TYPE VARCHAR(255), ALTER COLUMN type TYPE VARCHAR(256), ALTER COLUMN affiliation TYPE VARCHAR(1024)") 45 if err != nil { 46 return err 47 } 48 _, err = tx.Exec(funcName, "ALTER TABLE users ALTER COLUMN attributes TYPE TEXT") 49 if err != nil { 50 return err 51 } 52 var res []string 53 query := "SELECT column_name FROM information_schema.columns WHERE table_name='users' and column_name='level'" 54 err = tx.Select(funcName, &res, tx.Rebind(query)) 55 if err != nil { 56 return err 57 } 58 if len(res) == 0 { 59 _, err = tx.Exec(funcName, "ALTER TABLE users ADD COLUMN level INTEGER DEFAULT 0") 60 if err != nil && !strings.Contains(err.Error(), "already exists") { 61 return err 62 } 63 } 64 fallthrough 65 66 case 1: 67 log.Debug("Upgrade identity table to level 2") 68 var res []string 69 query := "SELECT column_name FROM information_schema.columns WHERE table_name='users' and column_name='incorrect_password_attempts'" 70 err := tx.Select(funcName, &res, tx.Rebind(query)) 71 if err != nil { 72 return err 73 } 74 if len(res) == 0 { 75 _, err = tx.Exec(funcName, "ALTER TABLE users ADD COLUMN incorrect_password_attempts INTEGER DEFAULT 0") 76 if err != nil { 77 if !strings.Contains(err.Error(), "already exists") { 78 return err 79 } 80 } 81 } 82 fallthrough 83 84 default: 85 users, err := user.GetUserLessThanLevel(tx, m.SrvLevels.Identity) 86 if err != nil { 87 return err 88 } 89 90 for _, u := range users { 91 err := u.Migrate(tx) 92 if err != nil { 93 return err 94 } 95 } 96 97 _, err = tx.Exec(funcName, tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'identity.level')"), m.SrvLevels.Identity) 98 if err != nil { 99 return err 100 } 101 102 return nil 103 } 104 } 105 106 // MigrateCertificatesTable is responsible for migrating certificates table 107 func (m *Migrator) MigrateCertificatesTable() error { 108 tx := m.Tx 109 const funcName = "MigrateCertificatesTable" 110 111 // Future schema updates should add to the logic below to handle other levels 112 switch m.CurLevels.Certificate { 113 case 0: 114 log.Debug("Upgrade certificates table to level 1") 115 var res []string 116 query := "SELECT column_name FROM information_schema.columns WHERE table_name='certificates' and column_name='level'" 117 err := tx.Select(funcName, &res, tx.Rebind(query)) 118 if err != nil { 119 return err 120 } 121 if len(res) == 0 { 122 _, err := tx.Exec(funcName, "ALTER TABLE certificates ADD COLUMN level INTEGER DEFAULT 0") 123 if err != nil && !strings.Contains(err.Error(), "already exists") { 124 return err 125 } 126 } 127 _, err = tx.Exec(funcName, "ALTER TABLE certificates ALTER COLUMN id TYPE VARCHAR(255)") 128 if err != nil { 129 return err 130 } 131 fallthrough 132 133 default: 134 _, err := tx.Exec(funcName, tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'certificate.level')"), m.SrvLevels.Certificate) 135 if err != nil { 136 return err 137 } 138 139 return nil 140 } 141 } 142 143 // MigrateAffiliationsTable is responsible for migrating affiliations table 144 func (m *Migrator) MigrateAffiliationsTable() error { 145 tx := m.Tx 146 const funcName = "MigrateAffiliationsTable" 147 148 // Future schema updates should add to the logic below to handle other levels 149 switch m.CurLevels.Affiliation { 150 case 0: 151 log.Debug("Upgrade affiliations table to level 1") 152 var res []string 153 query := "SELECT column_name FROM information_schema.columns WHERE table_name='affiliations' and column_name='level'" 154 err := tx.Select(funcName, &res, tx.Rebind(query)) 155 if err != nil { 156 return err 157 } 158 if len(res) == 0 { 159 _, err := tx.Exec(funcName, "ALTER TABLE affiliations ADD COLUMN level INTEGER DEFAULT 0") 160 if err != nil && !strings.Contains(err.Error(), "already exists") { 161 return err 162 } 163 } 164 _, err = tx.Exec(funcName, "ALTER TABLE affiliations ALTER COLUMN name TYPE VARCHAR(1024), ALTER COLUMN prekey TYPE VARCHAR(1024)") 165 if err != nil { 166 return err 167 } 168 fallthrough 169 170 default: 171 _, err := tx.Exec(funcName, tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'affiliation.level')"), m.SrvLevels.Affiliation) 172 if err != nil { 173 return err 174 } 175 return nil 176 } 177 } 178 179 // MigrateCredentialsTable is responsible for migrating credentials table 180 func (m *Migrator) MigrateCredentialsTable() error { 181 _, err := m.Tx.Exec("MigrateCredentialsTable", m.Tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'credential.level')"), m.SrvLevels.Credential) 182 return err 183 } 184 185 // MigrateRAInfoTable is responsible for migrating rainfo table 186 func (m *Migrator) MigrateRAInfoTable() error { 187 _, err := m.Tx.Exec("MigrateRAInfoTable", m.Tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'rcinfo.level')"), m.SrvLevels.RAInfo) 188 return err 189 } 190 191 // MigrateNoncesTable is responsible for migrating nonces table 192 func (m *Migrator) MigrateNoncesTable() error { 193 _, err := m.Tx.Exec("MigrateNoncesTable", m.Tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'nonce.level')"), m.SrvLevels.Nonce) 194 return err 195 } 196 197 // Rollback is responsible for rollback transaction if an error is encountered 198 func (m *Migrator) Rollback() error { 199 err := m.Tx.Rollback("Migration") 200 if err != nil { 201 log.Errorf("Error encountered while rolling back database migration changes: %s", err) 202 return err 203 } 204 return nil 205 } 206 207 // Commit is responsible for committing the migration db transcation 208 func (m *Migrator) Commit() error { 209 err := m.Tx.Commit("Migration") 210 if err != nil { 211 return errors.Wrap(err, "Error encountered while committing database migration changes") 212 } 213 return nil 214 }