github.com/mmatczuk/gohan@v0.0.0-20170206152520-30e45d9bdb69/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  //DefaultMaxOpenConn will applied for db object
    30  const DefaultMaxOpenConn = 100
    31  
    32  const noSchemasInManagerError = "No schemas in Manager. Did you remember to load them?"
    33  
    34  //DB is a common interface for handing db
    35  type DB interface {
    36  	Connect(string, string, int) error
    37  	Close()
    38  	Begin() (transaction.Transaction, error)
    39  	RegisterTable(*schema.Schema, bool) error
    40  	DropTable(*schema.Schema) error
    41  }
    42  
    43  //ConnectDB is builder function of DB
    44  func ConnectDB(dbType, conn string, maxOpenConn int) (DB, error) {
    45  	var db DB
    46  	if dbType == "json" || dbType == "yaml" {
    47  		db = file.NewDB()
    48  	} else {
    49  		db = sql.NewDB()
    50  	}
    51  	err := db.Connect(dbType, conn, maxOpenConn)
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  	return db, nil
    56  }
    57  
    58  //CopyDBResources copies resources from input database to output database
    59  func CopyDBResources(input, output DB, overrideExisting bool) error {
    60  	schemaManager := schema.GetManager()
    61  	schemas := schemaManager.OrderedSchemas()
    62  	if len(schemas) == 0 {
    63  		return fmt.Errorf(noSchemasInManagerError)
    64  	}
    65  
    66  	itx, err := input.Begin()
    67  	if err != nil {
    68  		return err
    69  	}
    70  	defer itx.Close()
    71  
    72  	otx, err := output.Begin()
    73  	if err != nil {
    74  		return err
    75  	}
    76  	defer otx.Close()
    77  
    78  	for _, s := range schemas {
    79  		if s.IsAbstract() {
    80  			continue
    81  		}
    82  		log.Info("Populating resources for schema %s", s.ID)
    83  		resources, _, err := itx.List(s, nil, nil)
    84  		if err != nil {
    85  			return err
    86  		}
    87  
    88  		for _, resource := range resources {
    89  			log.Info("Creating resource %s", resource.ID())
    90  			destResource, _ := otx.Fetch(s, transaction.IDFilter(resource.ID()))
    91  			if destResource == nil {
    92  				resource.PopulateDefaults()
    93  				err := otx.Create(resource)
    94  				if err != nil {
    95  					return err
    96  				}
    97  			} else if overrideExisting {
    98  				err := otx.Update(resource)
    99  				if err != nil {
   100  					return err
   101  				}
   102  			}
   103  		}
   104  	}
   105  	err = itx.Commit()
   106  	if err != nil {
   107  		return err
   108  	}
   109  	return otx.Commit()
   110  }
   111  
   112  //InitDBWithSchemas initializes database using schemas stored in Manager
   113  func InitDBWithSchemas(dbType, dbConnection string, dropOnCreate, cascade bool) error {
   114  	aDb, err := ConnectDB(dbType, dbConnection, DefaultMaxOpenConn)
   115  	if err != nil {
   116  		return err
   117  	}
   118  	schemaManager := schema.GetManager()
   119  	schemas := schemaManager.OrderedSchemas()
   120  	if len(schemas) == 0 {
   121  		return fmt.Errorf(noSchemasInManagerError)
   122  	}
   123  	if dropOnCreate {
   124  		for i := len(schemas) - 1; i >= 0; i-- {
   125  			s := schemas[i]
   126  			if s.IsAbstract() {
   127  				continue
   128  			}
   129  			log.Debug("Dropping table '%s'", s.Plural)
   130  			err = aDb.DropTable(s)
   131  			if err != nil {
   132  				log.Fatal("Error during deleting table:", err.Error())
   133  			}
   134  		}
   135  	}
   136  	for _, s := range schemas {
   137  		if s.IsAbstract() {
   138  			continue
   139  		}
   140  		log.Debug("Registering schema %s", s.ID)
   141  		err = aDb.RegisterTable(s, cascade)
   142  		if err != nil {
   143  			message := "Error during registering table: %s"
   144  			if strings.Contains(err.Error(), "already exists") {
   145  				log.Warning(message, err.Error())
   146  			} else {
   147  				log.Fatal(message, err.Error())
   148  			}
   149  		}
   150  	}
   151  	aDb.Close()
   152  	return nil
   153  }