github.com/jbking/gohan@v0.0.0-20151217002006-b41ccf1c2a96/db/db.go (about)

     1  // Copyright (C) 2015 NTT Innovation Institute, 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  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
    12  // implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  
    16  package db
    17  
    18  import (
    19  	"fmt"
    20  	"strings"
    21  
    22  	"github.com/cloudwan/gohan/db/file"
    23  	"github.com/cloudwan/gohan/db/sql"
    24  	"github.com/cloudwan/gohan/db/transaction"
    25  
    26  	"github.com/cloudwan/gohan/schema"
    27  )
    28  
    29  const noSchemasInManagerError = "No schemas in Manager. Did you remember to load them?"
    30  
    31  //DB is a common interface for handing db
    32  type DB interface {
    33  	Connect(string, string) error
    34  	Begin() (transaction.Transaction, error)
    35  	RegisterTable(*schema.Schema, bool) error
    36  	DropTable(*schema.Schema) error
    37  }
    38  
    39  //ConnectDB is builder function of DB
    40  func ConnectDB(dbType, conn string) (DB, error) {
    41  	var db DB
    42  	if dbType == "json" || dbType == "yaml" {
    43  		db = file.NewDB()
    44  	} else {
    45  		db = sql.NewDB()
    46  	}
    47  	err := db.Connect(dbType, conn)
    48  	if err != nil {
    49  		return nil, err
    50  	}
    51  	return db, nil
    52  }
    53  
    54  //CopyDBResources copies resources from input database to output database
    55  func CopyDBResources(input, output DB) error {
    56  	schemaManager := schema.GetManager()
    57  	schemas := schemaManager.OrderedSchemas()
    58  	if len(schemas) == 0 {
    59  		return fmt.Errorf(noSchemasInManagerError)
    60  	}
    61  
    62  	itx, err := input.Begin()
    63  	if err != nil {
    64  		return err
    65  	}
    66  	defer itx.Close()
    67  
    68  	otx, err := output.Begin()
    69  	if err != nil {
    70  		return err
    71  	}
    72  	defer otx.Close()
    73  
    74  	for _, s := range schemas {
    75  		log.Info("Populating resources for schema %s", s.ID)
    76  		resources, _, err := itx.List(s, nil, nil)
    77  		if err != nil {
    78  			return err
    79  		}
    80  
    81  		for _, resource := range resources {
    82  			log.Info("Creating resource %s", resource.ID())
    83  			destResource, _ := otx.Fetch(s, resource.ID(), nil)
    84  			if destResource == nil {
    85  				err := otx.Create(resource)
    86  				if err != nil {
    87  					return err
    88  				}
    89  			} else {
    90  				err := otx.Update(resource)
    91  				if err != nil {
    92  					return err
    93  				}
    94  			}
    95  		}
    96  	}
    97  	err = itx.Commit()
    98  	if err != nil {
    99  		return err
   100  	}
   101  	return otx.Commit()
   102  }
   103  
   104  //InitDBWithSchemas initializes database using schemas stored in Manager
   105  func InitDBWithSchemas(dbType, dbConnection string, dropOnCreate, cascade bool) error {
   106  	aDb, err := ConnectDB(dbType, dbConnection)
   107  	if err != nil {
   108  		return err
   109  	}
   110  	schemaManager := schema.GetManager()
   111  	schemas := schemaManager.OrderedSchemas()
   112  	if len(schemas) == 0 {
   113  		return fmt.Errorf(noSchemasInManagerError)
   114  	}
   115  	if dropOnCreate {
   116  		for i := len(schemas) - 1; i >= 0; i-- {
   117  			s := schemas[i]
   118  			log.Debug("Dropping table '%s'", s.Plural)
   119  			err = aDb.DropTable(s)
   120  			if err != nil {
   121  				log.Fatal("Error during deleting table:", err.Error())
   122  			}
   123  		}
   124  	}
   125  	for _, s := range schemas {
   126  		log.Debug("Registering schema %s", s.ID)
   127  		err = aDb.RegisterTable(s, cascade)
   128  		if err != nil {
   129  			message := "Error during registering table: %s"
   130  			if strings.Contains(err.Error(), "already exists") {
   131  				log.Warning(message, err.Error())
   132  			} else {
   133  				log.Fatal(message, err.Error())
   134  			}
   135  		}
   136  	}
   137  	return nil
   138  }