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  }