-
Notifications
You must be signed in to change notification settings - Fork 28
Expand file tree
/
Copy pathfetch.go
More file actions
88 lines (76 loc) · 2.78 KB
/
fetch.go
File metadata and controls
88 lines (76 loc) · 2.78 KB
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
// Copyright 2019 Yunion
//
// 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 sqlchemy
import (
"reflect"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/gotypes"
"yunion.io/x/pkg/util/reflectutils"
)
// Fetch method fetches the values of a struct whose primary key values have been set
// input is a pointer to the model to be populated
func (ts *STableSpec) Fetch(dt interface{}) error {
q := ts.Query()
dataValue := reflect.ValueOf(dt).Elem()
fields := reflectutils.FetchStructFieldValueSet(dataValue)
for _, c := range ts.Columns() {
priVal, _ := fields.GetInterface(c.Name())
if c.IsPrimary() && !gotypes.IsNil(priVal) { // skip update primary key
q = q.Equals(c.Name(), priVal)
}
}
return q.First(dt)
}
// FetchAll method fetches the values of an array of structs whose primary key values have been set
// input is a pointer to the array of models to be populated
func (ts *STableSpec) FetchAll(dest interface{}) error {
arrayType := reflect.TypeOf(dest).Elem()
if arrayType.Kind() != reflect.Array && arrayType.Kind() != reflect.Slice {
return errors.Wrap(ErrNeedsArray, "dest is not an array or slice")
}
arrayValue := reflect.ValueOf(dest).Elem()
primaryCols := ts.PrimaryColumns()
if len(primaryCols) != 1 {
return errors.Wrap(ErrNotSupported, "support 1 primary key only")
}
primaryCol := primaryCols[0]
keyValues := make([]interface{}, arrayValue.Len())
for i := 0; i < arrayValue.Len(); i++ {
eleValue := arrayValue.Index(i)
fields := reflectutils.FetchStructFieldValueSet(eleValue)
keyValues[i], _ = fields.GetInterface(primaryCol.Name())
}
q := ts.Query().In(primaryCol.Name(), keyValues)
tmpDestMaps, err := q.AllStringMap()
if err != nil {
return errors.Wrap(err, "q.AllStringMap")
}
tmpDestMapMap := make(map[string]map[string]string)
for i := 0; i < len(tmpDestMaps); i++ {
tmpDestMapMap[tmpDestMaps[i][primaryCol.Name()]] = tmpDestMaps[i]
}
for i := 0; i < arrayValue.Len(); i++ {
keyValueStr := GetStringValue(keyValues[i])
if tmpMap, ok := tmpDestMapMap[keyValueStr]; ok {
err = mapString2Struct(tmpMap, arrayValue.Index(i))
if err != nil {
return errors.Wrapf(err, "mapString2Struct %d:%s", i, keyValueStr)
}
} else {
log.Warningf("element %d:%s not found in fetch result", i, keyValueStr)
}
}
return nil
}