github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/ddl/schema.go (about) 1 // Copyright 2015 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package ddl 15 16 import ( 17 "github.com/insionng/yougam/libraries/juju/errors" 18 "github.com/insionng/yougam/libraries/pingcap/tidb/infoschema" 19 "github.com/insionng/yougam/libraries/pingcap/tidb/meta" 20 "github.com/insionng/yougam/libraries/pingcap/tidb/meta/autoid" 21 "github.com/insionng/yougam/libraries/pingcap/tidb/model" 22 "github.com/insionng/yougam/libraries/pingcap/tidb/table" 23 "github.com/insionng/yougam/libraries/pingcap/tidb/terror" 24 ) 25 26 func (d *ddl) onCreateSchema(t *meta.Meta, job *model.Job) error { 27 schemaID := job.SchemaID 28 dbInfo := &model.DBInfo{} 29 if err := job.DecodeArgs(dbInfo); err != nil { 30 // arg error, cancel this job. 31 job.State = model.JobCancelled 32 return errors.Trace(err) 33 } 34 35 dbInfo.ID = schemaID 36 dbInfo.State = model.StateNone 37 38 dbs, err := t.ListDatabases() 39 if err != nil { 40 return errors.Trace(err) 41 } 42 43 for _, db := range dbs { 44 if db.Name.L == dbInfo.Name.L { 45 if db.ID != schemaID { 46 // database exists, can't create, we should cancel this job now. 47 job.State = model.JobCancelled 48 return errors.Trace(infoschema.ErrDatabaseExists) 49 } 50 dbInfo = db 51 } 52 } 53 54 _, err = t.GenSchemaVersion() 55 if err != nil { 56 return errors.Trace(err) 57 } 58 59 switch dbInfo.State { 60 case model.StateNone: 61 // none -> public 62 job.SchemaState = model.StatePublic 63 dbInfo.State = model.StatePublic 64 err = t.CreateDatabase(dbInfo) 65 if err != nil { 66 return errors.Trace(err) 67 } 68 // finish this job 69 job.State = model.JobDone 70 return nil 71 default: 72 // we can't enter here. 73 return errors.Errorf("invalid db state %v", dbInfo.State) 74 } 75 } 76 77 func (d *ddl) delReorgSchema(t *meta.Meta, job *model.Job) error { 78 dbInfo := &model.DBInfo{} 79 if err := job.DecodeArgs(dbInfo); err != nil { 80 // arg error, cancel this job. 81 job.State = model.JobCancelled 82 return errors.Trace(err) 83 } 84 85 tables, err := t.ListTables(dbInfo.ID) 86 if terror.ErrorEqual(meta.ErrDBNotExists, err) { 87 job.State = model.JobDone 88 return nil 89 } 90 if err != nil { 91 return errors.Trace(err) 92 } 93 94 if err = d.dropSchemaData(dbInfo, tables); err != nil { 95 return errors.Trace(err) 96 } 97 98 // finish this background job 99 job.SchemaState = model.StateNone 100 job.State = model.JobDone 101 102 return nil 103 } 104 105 func (d *ddl) onDropSchema(t *meta.Meta, job *model.Job) error { 106 dbInfo, err := t.GetDatabase(job.SchemaID) 107 if err != nil { 108 return errors.Trace(err) 109 } 110 if dbInfo == nil { 111 job.State = model.JobCancelled 112 return errors.Trace(infoschema.ErrDatabaseNotExists) 113 } 114 115 _, err = t.GenSchemaVersion() 116 if err != nil { 117 return errors.Trace(err) 118 } 119 120 switch dbInfo.State { 121 case model.StatePublic: 122 // public -> write only 123 job.SchemaState = model.StateWriteOnly 124 dbInfo.State = model.StateWriteOnly 125 err = t.UpdateDatabase(dbInfo) 126 case model.StateWriteOnly: 127 // write only -> delete only 128 job.SchemaState = model.StateDeleteOnly 129 dbInfo.State = model.StateDeleteOnly 130 err = t.UpdateDatabase(dbInfo) 131 case model.StateDeleteOnly: 132 dbInfo.State = model.StateDeleteReorganization 133 err = t.UpdateDatabase(dbInfo) 134 if err = t.DropDatabase(dbInfo.ID); err != nil { 135 break 136 } 137 // finish this job 138 job.Args = []interface{}{dbInfo} 139 job.State = model.JobDone 140 job.SchemaState = model.StateNone 141 default: 142 // we can't enter here. 143 err = errors.Errorf("invalid db state %v", dbInfo.State) 144 } 145 146 return errors.Trace(err) 147 } 148 149 func (d *ddl) dropSchemaData(dbInfo *model.DBInfo, tables []*model.TableInfo) error { 150 for _, tblInfo := range tables { 151 alloc := autoid.NewAllocator(d.store, dbInfo.ID) 152 t, err := table.TableFromMeta(alloc, tblInfo) 153 if err != nil { 154 return errors.Trace(err) 155 } 156 157 err = d.dropTableData(t) 158 if err != nil { 159 return errors.Trace(err) 160 } 161 } 162 return nil 163 }