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  }