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 }