github.com/jbking/gohan@v0.0.0-20151217002006-b41ccf1c2a96/extension/otto/gohan_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 otto 17 18 import ( 19 "github.com/dop251/otto" 20 21 "github.com/cloudwan/gohan/db/sql" 22 "github.com/cloudwan/gohan/db/transaction" 23 "github.com/cloudwan/gohan/schema" 24 ) 25 26 func init() { 27 gohanDBInit := func(env *Environment) { 28 vm := env.VM 29 builtins := map[string]interface{}{ 30 "gohan_db_list": func(call otto.FunctionCall) otto.Value { 31 VerifyCallArguments(&call, "gohan_db_list", 3) 32 rawTransaction, _ := call.Argument(0).Export() 33 transaction, ok := rawTransaction.(transaction.Transaction) 34 var err error 35 if !ok { 36 dataStore := env.DataStore 37 transaction, err = dataStore.Begin() 38 if err != nil { 39 ThrowOttoException(&call, noTransactionErrorMessage) 40 } 41 defer transaction.Close() 42 } 43 schemaID := call.Argument(1).String() 44 filterObj, _ := call.Argument(2).Export() 45 var filter map[string]interface{} 46 if filterObj != nil { 47 filter = filterObj.(map[string]interface{}) 48 } 49 manager := schema.GetManager() 50 schema, ok := manager.Schema(schemaID) 51 if !ok { 52 ThrowOttoException(&call, unknownSchemaErrorMesssageFormat, schemaID) 53 } 54 resources, _, err := transaction.List(schema, filter, nil) 55 if err != nil { 56 ThrowOttoException(&call, "Error during gohan_db_list: %s", err.Error()) 57 } 58 resp := []map[string]interface{}{} 59 for _, resource := range resources { 60 resp = append(resp, resource.Data()) 61 } 62 value, _ := vm.ToValue(resp) 63 return value 64 }, 65 "gohan_db_fetch": func(call otto.FunctionCall) otto.Value { 66 VerifyCallArguments(&call, "gohan_db_fetch", 4) 67 rawTransaction, _ := call.Argument(0).Export() 68 transaction, ok := rawTransaction.(transaction.Transaction) 69 var err error 70 if !ok { 71 dataStore := env.DataStore 72 transaction, err = dataStore.Begin() 73 if err != nil { 74 ThrowOttoException(&call, noTransactionErrorMessage) 75 } 76 defer transaction.Close() 77 } 78 schemaID := call.Argument(1).String() 79 ID := call.Argument(2).String() 80 tenantID := call.Argument(3).String() 81 manager := schema.GetManager() 82 schema, ok := manager.Schema(schemaID) 83 if !ok { 84 ThrowOttoException(&call, unknownSchemaErrorMesssageFormat, schemaID) 85 } 86 var tenantFilter []string 87 if tenantID != "" { 88 tenantFilter = []string{tenantID} 89 } 90 resp, err := transaction.Fetch(schema, ID, tenantFilter) 91 if err != nil { 92 ThrowOttoException(&call, "Error during gohan_db_fetch: %s", err.Error()) 93 } 94 if resp == nil { 95 otto.NullValue() 96 } 97 value, _ := vm.ToValue(resp.Data()) 98 return value 99 }, 100 "gohan_db_state_fetch": func(call otto.FunctionCall) otto.Value { 101 VerifyCallArguments(&call, "gohan_db_state_fetch", 4) 102 rawTransaction, _ := call.Argument(0).Export() 103 transaction, ok := rawTransaction.(transaction.Transaction) 104 if !ok { 105 ThrowOttoException(&call, noTransactionErrorMessage) 106 } 107 schemaID := call.Argument(1).String() 108 ID := call.Argument(2).String() 109 tenantID := call.Argument(3).String() 110 manager := schema.GetManager() 111 schema, ok := manager.Schema(schemaID) 112 if !ok { 113 ThrowOttoException(&call, unknownSchemaErrorMesssageFormat, schemaID) 114 } 115 var tenantFilter []string 116 if tenantID != "" { 117 tenantFilter = []string{tenantID} 118 } 119 resp, err := transaction.StateFetch(schema, ID, tenantFilter) 120 if err != nil { 121 ThrowOttoException(&call, "Error during gohan_db_state_fetch: %s", err.Error()) 122 } 123 data := map[string]interface{}{ 124 "config_version": resp.ConfigVersion, 125 "state_version": resp.StateVersion, 126 "error": resp.Error, 127 "state": resp.State, 128 "monitoring": resp.Monitoring, 129 } 130 value, _ := vm.ToValue(data) 131 return value 132 }, 133 "gohan_db_create": func(call otto.FunctionCall) otto.Value { 134 VerifyCallArguments(&call, "gohan_db_create", 3) 135 rawTransaction, _ := call.Argument(0).Export() 136 transaction, ok := rawTransaction.(transaction.Transaction) 137 needCommit := false 138 var err error 139 if !ok { 140 dataStore := env.DataStore 141 transaction, err = dataStore.Begin() 142 needCommit = true 143 if err != nil { 144 ThrowOttoException(&call, noTransactionErrorMessage) 145 } 146 defer transaction.Close() 147 } 148 schemaID := call.Argument(1).String() 149 data := ConvertOttoToGo(call.Argument(2)) 150 dataMap, _ := data.(map[string]interface{}) 151 manager := schema.GetManager() 152 resource, err := manager.LoadResource(schemaID, dataMap) 153 if err != nil { 154 ThrowOttoException(&call, "Error during gohan_db_create: %s", err.Error()) 155 } 156 if err = transaction.Create(resource); err != nil { 157 ThrowOttoException(&call, "Error during gohan_db_create: %s", err.Error()) 158 } 159 if needCommit { 160 err = transaction.Commit() 161 if err != nil { 162 ThrowOttoException(&call, "Error during gohan_db_create: %s", err.Error()) 163 } 164 } 165 value, _ := vm.ToValue(resource.Data()) 166 return value 167 }, 168 "gohan_db_update": func(call otto.FunctionCall) otto.Value { 169 VerifyCallArguments(&call, "gohan_db_update", 3) 170 rawTransaction, _ := call.Argument(0).Export() 171 transaction, ok := rawTransaction.(transaction.Transaction) 172 needCommit := false 173 var err error 174 if !ok { 175 dataStore := env.DataStore 176 transaction, err = dataStore.Begin() 177 needCommit = true 178 if err != nil { 179 ThrowOttoException(&call, noTransactionErrorMessage) 180 } 181 defer transaction.Close() 182 } 183 schemaID := call.Argument(1).String() 184 data := ConvertOttoToGo(call.Argument(2)) 185 dataMap, _ := data.(map[string]interface{}) 186 manager := schema.GetManager() 187 resource, err := manager.LoadResource(schemaID, dataMap) 188 if err != nil { 189 ThrowOttoException(&call, "Error during gohan_db_update: %s", err.Error()) 190 } 191 if err = transaction.Update(resource); err != nil { 192 ThrowOttoException(&call, "Error during gohan_db_update: %s", err.Error()) 193 } 194 if needCommit { 195 err = transaction.Commit() 196 if err != nil { 197 ThrowOttoException(&call, "Error during gohan_db_create: %s", err.Error()) 198 } 199 } 200 value, _ := vm.ToValue(resource.Data()) 201 return value 202 }, 203 "gohan_db_state_update": func(call otto.FunctionCall) otto.Value { 204 VerifyCallArguments(&call, "gohan_db_state_update", 3) 205 rawTransaction, _ := call.Argument(0).Export() 206 transaction, ok := rawTransaction.(transaction.Transaction) 207 needCommit := false 208 var err error 209 if !ok { 210 dataStore := env.DataStore 211 transaction, err = dataStore.Begin() 212 needCommit = true 213 if err != nil { 214 ThrowOttoException(&call, noTransactionErrorMessage) 215 } 216 defer transaction.Close() 217 } 218 schemaID := call.Argument(1).String() 219 data := ConvertOttoToGo(call.Argument(2)) 220 dataMap, _ := data.(map[string]interface{}) 221 manager := schema.GetManager() 222 resource, err := manager.LoadResource(schemaID, dataMap) 223 if err != nil { 224 ThrowOttoException(&call, "Error during gohan_db_state_update: %s", err.Error()) 225 } 226 if err = transaction.StateUpdate(resource, nil); err != nil { 227 ThrowOttoException(&call, "Error during gohan_db_state_update: %s", err.Error()) 228 } 229 if needCommit { 230 err = transaction.Commit() 231 if err != nil { 232 ThrowOttoException(&call, "Error during gohan_db_create: %s", err.Error()) 233 } 234 } 235 value, _ := vm.ToValue(resource.Data()) 236 return value 237 }, 238 "gohan_db_delete": func(call otto.FunctionCall) otto.Value { 239 VerifyCallArguments(&call, "gohan_db_delete", 3) 240 rawTransaction, _ := call.Argument(0).Export() 241 transaction, ok := rawTransaction.(transaction.Transaction) 242 needCommit := false 243 var err error 244 if !ok { 245 dataStore := env.DataStore 246 transaction, err = dataStore.Begin() 247 needCommit = true 248 if err != nil { 249 ThrowOttoException(&call, noTransactionErrorMessage) 250 } 251 defer transaction.Close() 252 } 253 schemaID := call.Argument(1).String() 254 ID := call.Argument(2).String() 255 manager := schema.GetManager() 256 schema, _ := manager.Schema(schemaID) 257 if err := transaction.Delete(schema, ID); err != nil { 258 ThrowOttoException(&call, "Error during gohan_db_delete: %s", err.Error()) 259 } 260 if needCommit { 261 err = transaction.Commit() 262 if err != nil { 263 ThrowOttoException(&call, "Error during gohan_db_create: %s", err.Error()) 264 } 265 } 266 return otto.NullValue() 267 }, 268 "gohan_db_query": func(call otto.FunctionCall) otto.Value { 269 VerifyCallArguments(&call, "gohan_db_query", 4) 270 rawTransaction, _ := call.Argument(0).Export() 271 transaction, ok := rawTransaction.(transaction.Transaction) 272 needCommit := false 273 var err error 274 if !ok { 275 dataStore := env.DataStore 276 transaction, err = dataStore.Begin() 277 needCommit = true 278 if err != nil { 279 ThrowOttoException(&call, noTransactionErrorMessage) 280 } 281 defer transaction.Close() 282 } 283 schemaID := call.Argument(1).String() 284 sqlString := call.Argument(2).String() 285 rawArguments, _ := call.Argument(3).Export() 286 287 manager := schema.GetManager() 288 s, ok := manager.Schema(schemaID) 289 if !ok { 290 ThrowOttoException(&call, unknownSchemaErrorMesssageFormat, schemaID) 291 } 292 293 arguments, ok := rawArguments.([]interface{}) 294 if !ok { 295 ThrowOttoException(&call, "Gievn arguments is not []interface{}") 296 } 297 298 resources, err := transaction.Query(s, sqlString, arguments) 299 if err != nil { 300 ThrowOttoException(&call, "Error during gohan_db_query: %s", err.Error()) 301 } 302 if needCommit { 303 err = transaction.Commit() 304 if err != nil { 305 ThrowOttoException(&call, "Error during gohan_db_create: %s", err.Error()) 306 } 307 } 308 resp := []map[string]interface{}{} 309 for _, resource := range resources { 310 resp = append(resp, resource.Data()) 311 } 312 value, _ := vm.ToValue(resp) 313 return value 314 }, 315 "gohan_db_sql_make_columns": func(call otto.FunctionCall) otto.Value { 316 VerifyCallArguments(&call, "gohan_db_query", 1) 317 schemaID := call.Argument(0).String() 318 manager := schema.GetManager() 319 s, ok := manager.Schema(schemaID) 320 if !ok { 321 ThrowOttoException(&call, unknownSchemaErrorMesssageFormat, schemaID) 322 } 323 results := sql.MakeColumns(s, false) 324 value, _ := vm.ToValue(results) 325 return value 326 }, 327 } 328 329 for name, object := range builtins { 330 vm.Set(name, object) 331 } 332 } 333 RegisterInit(gohanDBInit) 334 }