github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/ddl/foreign_key.go (about) 1 // Copyright 2016 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/model" 21 ) 22 23 func (d *ddl) onCreateForeignKey(t *meta.Meta, job *model.Job) error { 24 schemaID := job.SchemaID 25 tblInfo, err := d.getTableInfo(t, job) 26 if err != nil { 27 return errors.Trace(err) 28 } 29 30 var fkInfo model.FKInfo 31 err = job.DecodeArgs(&fkInfo) 32 if err != nil { 33 job.State = model.JobCancelled 34 return errors.Trace(err) 35 } 36 tblInfo.ForeignKeys = append(tblInfo.ForeignKeys, &fkInfo) 37 38 _, err = t.GenSchemaVersion() 39 if err != nil { 40 return errors.Trace(err) 41 } 42 43 switch fkInfo.State { 44 case model.StateNone: 45 // We just support record the foreign key, so we just make it public. 46 // none -> public 47 job.SchemaState = model.StatePublic 48 fkInfo.State = model.StatePublic 49 err = t.UpdateTable(schemaID, tblInfo) 50 if err != nil { 51 return errors.Trace(err) 52 } 53 // finish this job 54 job.State = model.JobDone 55 return nil 56 default: 57 return ErrInvalidForeignKeyState.Gen("invalid fk state %v", fkInfo.State) 58 } 59 } 60 61 func (d *ddl) onDropForeignKey(t *meta.Meta, job *model.Job) error { 62 schemaID := job.SchemaID 63 tblInfo, err := d.getTableInfo(t, job) 64 if err != nil { 65 return errors.Trace(err) 66 } 67 68 var ( 69 fkName model.CIStr 70 found bool 71 fkInfo model.FKInfo 72 ) 73 err = job.DecodeArgs(&fkName) 74 if err != nil { 75 job.State = model.JobCancelled 76 return errors.Trace(err) 77 } 78 79 for _, fk := range tblInfo.ForeignKeys { 80 if fk.Name.L == fkName.L { 81 found = true 82 fkInfo = *fk 83 } 84 } 85 86 if !found { 87 return infoschema.ErrForeignKeyNotExists.Gen("foreign key doesn't exist", fkName) 88 } 89 90 nfks := tblInfo.ForeignKeys[:0] 91 for _, fk := range tblInfo.ForeignKeys { 92 if fk.Name.L != fkName.L { 93 nfks = append(nfks, fk) 94 } 95 } 96 tblInfo.ForeignKeys = nfks 97 98 _, err = t.GenSchemaVersion() 99 if err != nil { 100 return errors.Trace(err) 101 } 102 103 switch fkInfo.State { 104 case model.StatePublic: 105 // We just support record the foreign key, so we just make it none. 106 // public -> none 107 job.SchemaState = model.StateNone 108 fkInfo.State = model.StateNone 109 err = t.UpdateTable(schemaID, tblInfo) 110 if err != nil { 111 return errors.Trace(err) 112 } 113 // finish this job 114 job.State = model.JobDone 115 return nil 116 default: 117 return ErrInvalidForeignKeyState.Gen("invalid fk state %v", fkInfo.State) 118 } 119 120 }