forked from cloudwan/gohan
-
Notifications
You must be signed in to change notification settings - Fork 0
/
db.go
153 lines (139 loc) · 3.68 KB
/
db.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// Copyright (C) 2015 NTT Innovation Institute, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package db
import (
"fmt"
"strings"
"github.com/cloudwan/gohan/db/file"
"github.com/cloudwan/gohan/db/sql"
"github.com/cloudwan/gohan/db/transaction"
"github.com/cloudwan/gohan/schema"
)
//DefaultMaxOpenConn will applied for db object
const DefaultMaxOpenConn = 100
const noSchemasInManagerError = "No schemas in Manager. Did you remember to load them?"
//DB is a common interface for handing db
type DB interface {
Connect(string, string, int) error
Close()
Begin() (transaction.Transaction, error)
RegisterTable(*schema.Schema, bool) error
DropTable(*schema.Schema) error
}
//ConnectDB is builder function of DB
func ConnectDB(dbType, conn string, maxOpenConn int) (DB, error) {
var db DB
if dbType == "json" || dbType == "yaml" {
db = file.NewDB()
} else {
db = sql.NewDB()
}
err := db.Connect(dbType, conn, maxOpenConn)
if err != nil {
return nil, err
}
return db, nil
}
//CopyDBResources copies resources from input database to output database
func CopyDBResources(input, output DB, overrideExisting bool) error {
schemaManager := schema.GetManager()
schemas := schemaManager.OrderedSchemas()
if len(schemas) == 0 {
return fmt.Errorf(noSchemasInManagerError)
}
itx, err := input.Begin()
if err != nil {
return err
}
defer itx.Close()
otx, err := output.Begin()
if err != nil {
return err
}
defer otx.Close()
for _, s := range schemas {
if s.IsAbstract() {
continue
}
log.Info("Populating resources for schema %s", s.ID)
resources, _, err := itx.List(s, nil, nil)
if err != nil {
return err
}
for _, resource := range resources {
log.Info("Creating resource %s", resource.ID())
destResource, _ := otx.Fetch(s, transaction.IDFilter(resource.ID()))
if destResource == nil {
resource.PopulateDefaults()
err := otx.Create(resource)
if err != nil {
return err
}
} else if overrideExisting {
err := otx.Update(resource)
if err != nil {
return err
}
}
}
}
err = itx.Commit()
if err != nil {
return err
}
return otx.Commit()
}
//InitDBWithSchemas initializes database using schemas stored in Manager
func InitDBWithSchemas(dbType, dbConnection string, dropOnCreate, cascade bool) error {
aDb, err := ConnectDB(dbType, dbConnection, DefaultMaxOpenConn)
if err != nil {
return err
}
schemaManager := schema.GetManager()
schemas := schemaManager.OrderedSchemas()
if len(schemas) == 0 {
return fmt.Errorf(noSchemasInManagerError)
}
if dropOnCreate {
for i := len(schemas) - 1; i >= 0; i-- {
s := schemas[i]
if s.IsAbstract() {
continue
}
log.Debug("Dropping table '%s'", s.Plural)
err = aDb.DropTable(s)
if err != nil {
log.Fatal("Error during deleting table:", err.Error())
}
}
}
for _, s := range schemas {
if s.IsAbstract() {
continue
}
log.Debug("Registering schema %s", s.ID)
err = aDb.RegisterTable(s, cascade)
if err != nil {
message := "Error during registering table: %s"
if strings.Contains(err.Error(), "already exists") {
log.Warning(message, err.Error())
} else {
log.Fatal(message, err.Error())
}
}
}
aDb.Close()
return nil
}