| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- // 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
- }
|