diff --git a/go.mod b/go.mod index 2aec6f584d..5151d63304 100644 --- a/go.mod +++ b/go.mod @@ -155,7 +155,7 @@ require ( yunion.io/x/ovsdb v0.0.0-20200526071744-27bf0940cbc7 yunion.io/x/pkg v0.0.0-20220227083757-28690b33ce38 yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e - yunion.io/x/sqlchemy v0.0.0-20220312043902-049823163880 + yunion.io/x/sqlchemy v0.0.0-20220405074102-7b815a97eb67 yunion.io/x/structarg v0.0.0-20220312084958-9c6c79c7d1c6 ) diff --git a/go.sum b/go.sum index 65ef80c523..4497695f7e 100644 --- a/go.sum +++ b/go.sum @@ -998,7 +998,7 @@ yunion.io/x/pkg v0.0.0-20220227083757-28690b33ce38 h1:QV3gVskJfi1J0e5kTs4oTx8D+M yunion.io/x/pkg v0.0.0-20220227083757-28690b33ce38/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E= yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e h1:v+EzIadodSwkdZ/7bremd7J8J50Cise/HCylsOJngmo= yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e/go.mod h1:0iFKpOs1y4lbCxeOmq3Xx/0AcQoewVPwj62eRluioEo= -yunion.io/x/sqlchemy v0.0.0-20220312043902-049823163880 h1:qkNHJaiwNS/UwOj2sLdnURytvAaHkILhK5ze6ofck+M= -yunion.io/x/sqlchemy v0.0.0-20220312043902-049823163880/go.mod h1:FTdwPdGhMgh4E+UFXc9klI1Ok34fMuybTT+jLhOaIjI= +yunion.io/x/sqlchemy v0.0.0-20220405074102-7b815a97eb67 h1:vZiiB5oc6wqEvr1UNmJPFCX3FmLznZbvoUZ90ONgAcE= +yunion.io/x/sqlchemy v0.0.0-20220405074102-7b815a97eb67/go.mod h1:FTdwPdGhMgh4E+UFXc9klI1Ok34fMuybTT+jLhOaIjI= yunion.io/x/structarg v0.0.0-20220312084958-9c6c79c7d1c6 h1:WuWXhY3DvhdRTzWCJ/kwt3Ss6KIq7+KqJwb+esvNGwU= yunion.io/x/structarg v0.0.0-20220312084958-9c6c79c7d1c6/go.mod h1:EP6NSv2C0zzqBDTKumv8hPWLb3XvgMZDHQRfyuOrQng= diff --git a/vendor/modules.txt b/vendor/modules.txt index 53d0c14e95..2bd884fafe 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1265,7 +1265,7 @@ yunion.io/x/pkg/util/workqueue yunion.io/x/pkg/utils # yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e yunion.io/x/s3cli -# yunion.io/x/sqlchemy v0.0.0-20220312043902-049823163880 +# yunion.io/x/sqlchemy v0.0.0-20220405074102-7b815a97eb67 yunion.io/x/sqlchemy yunion.io/x/sqlchemy/backends yunion.io/x/sqlchemy/backends/clickhouse diff --git a/vendor/yunion.io/x/sqlchemy/field_update.go b/vendor/yunion.io/x/sqlchemy/field_update.go index 3ec63f2773..0492084793 100644 --- a/vendor/yunion.io/x/sqlchemy/field_update.go +++ b/vendor/yunion.io/x/sqlchemy/field_update.go @@ -19,12 +19,11 @@ import ( "fmt" "reflect" - "yunion.io/x/pkg/util/timeutils" - "yunion.io/x/log" "yunion.io/x/pkg/errors" "yunion.io/x/pkg/gotypes" "yunion.io/x/pkg/util/reflectutils" + "yunion.io/x/pkg/util/timeutils" ) // UpdateFields update a record with the values provided by fields stringmap @@ -49,7 +48,7 @@ func (ts *STableSpec) updateFieldSql(dt interface{}, fields map[string]interface fullFields := reflectutils.FetchStructFieldValueSet(dataValue) versionFields := make([]string, 0) updatedFields := make([]string, 0) - primaryCols := make(map[string]interface{}, 0) + primaryCols := make([]sPrimaryKeyValue, 0) for _, col := range ts.Columns() { name := col.Name() colValue, ok := fullFields.GetInterface(name) @@ -58,9 +57,15 @@ func (ts *STableSpec) updateFieldSql(dt interface{}, fields map[string]interface } if col.IsPrimary() { if !gotypes.IsNil(colValue) && !col.IsZero(colValue) { - primaryCols[name] = colValue + primaryCols = append(primaryCols, sPrimaryKeyValue{ + key: name, + value: colValue, + }) } else if col.IsText() { - primaryCols[name] = "" + primaryCols = append(primaryCols, sPrimaryKeyValue{ + key: name, + value: "", + }) } else { return nil, ErrEmptyPrimaryKey } @@ -103,15 +108,12 @@ func (ts *STableSpec) updateFieldSql(dt interface{}, fields map[string]interface vars = append(vars, now) } buf.WriteString(" WHERE ") - first := true - for k, v := range primaryCols { - if first { - first = false - } else { + for i, pkv := range primaryCols { + if i > 0 { buf.WriteString(" AND ") } - buf.WriteString(fmt.Sprintf("`%s` = ?", k)) - vars = append(vars, v) + buf.WriteString(fmt.Sprintf("`%s` = ?", pkv.key)) + vars = append(vars, pkv.value) } if DEBUG_SQLCHEMY || debug { diff --git a/vendor/yunion.io/x/sqlchemy/inc.go b/vendor/yunion.io/x/sqlchemy/inc.go index 30acb8da9b..d22e863c87 100644 --- a/vendor/yunion.io/x/sqlchemy/inc.go +++ b/vendor/yunion.io/x/sqlchemy/inc.go @@ -46,12 +46,6 @@ func (t *STableSpec) Decrement(diff interface{}, target interface{}) error { return t.incrementInternal(diff, "-", target) } -type incrementSqlResult struct { - sql string - vars []interface{} - primaries map[string]interface{} -} - func (t *STableSpec) incrementInternalSql(diff interface{}, opcode string, target interface{}) (*sUpdateSQLResult, error) { dataValue := reflect.Indirect(reflect.ValueOf(diff)) fields := reflectutils.FetchStructFieldValueSet(dataValue) @@ -63,7 +57,7 @@ func (t *STableSpec) incrementInternalSql(diff interface{}, opcode string, targe now := timeutils.UtcNow() - primaries := make(map[string]interface{}) + primaries := make([]sPrimaryKeyValue, 0) vars := make([]interface{}, 0) versionFields := make([]string, 0) updatedFields := make([]string, 0) @@ -77,9 +71,15 @@ func (t *STableSpec) incrementInternalSql(diff interface{}, opcode string, targe v, _ = targetFields.GetInterface(k) } if !gotypes.IsNil(v) && !c.IsZero(v) { - primaries[k] = v + primaries = append(primaries, sPrimaryKeyValue{ + key: k, + value: v, + }) } else if c.IsText() { - primaries[k] = "" + primaries = append(primaries, sPrimaryKeyValue{ + key: k, + value: "", + }) } else { return nil, ErrEmptyPrimaryKey } @@ -127,15 +127,12 @@ func (t *STableSpec) incrementInternalSql(diff interface{}, opcode string, targe } buf.WriteString(" WHERE ") - first = true - for k, v := range primaries { - if first { - first = false - } else { + for i, pkv := range primaries { + if i > 0 { buf.WriteString(" AND ") } - buf.WriteString(fmt.Sprintf("`%s` = ?", k)) - vars = append(vars, v) + buf.WriteString(fmt.Sprintf("`%s` = ?", pkv.key)) + vars = append(vars, pkv.value) } if DEBUG_SQLCHEMY { diff --git a/vendor/yunion.io/x/sqlchemy/parser.go b/vendor/yunion.io/x/sqlchemy/parser.go index d021274ca1..f27518247a 100644 --- a/vendor/yunion.io/x/sqlchemy/parser.go +++ b/vendor/yunion.io/x/sqlchemy/parser.go @@ -48,6 +48,7 @@ func (table *STableSpec) structField2ColumnSpec(field *reflectutils.SStructField func (table *STableSpec) struct2TableSpec(sv reflect.Value) { fields := reflectutils.FetchStructFieldValueSet(sv) autoIncCnt := 0 + tmpCols := make([]IColumnSpec, 0) for i := 0; i < len(fields); i++ { column := table.structField2ColumnSpec(&fields[i]) if column != nil { @@ -60,7 +61,9 @@ func (table *STableSpec) struct2TableSpec(sv reflect.Value) { if column.IsIndex() { table.AddIndex(column.IsUnique(), column.Name()) } - table._columns = append(table._columns, column) + tmpCols = append(tmpCols, column) } } + // make column assignment atomic + table._columns = tmpCols } diff --git a/vendor/yunion.io/x/sqlchemy/update.go b/vendor/yunion.io/x/sqlchemy/update.go index 5ad3254232..59bdd407af 100644 --- a/vendor/yunion.io/x/sqlchemy/update.go +++ b/vendor/yunion.io/x/sqlchemy/update.go @@ -20,13 +20,12 @@ import ( "reflect" "strings" - "yunion.io/x/pkg/util/timeutils" - "yunion.io/x/jsonutils" "yunion.io/x/log" "yunion.io/x/pkg/errors" "yunion.io/x/pkg/gotypes" "yunion.io/x/pkg/util/reflectutils" + "yunion.io/x/pkg/util/timeutils" "yunion.io/x/pkg/utils" ) @@ -92,17 +91,30 @@ type UpdateDiffs map[string]SUpdateDiff // String of UpdateDiffs returns the string representation of UpdateDiffs func (uds UpdateDiffs) String() string { obj := jsonutils.NewDict() - for k := range uds { - obj.Set(k, uds[k].jsonObj()) + for i := range uds { + obj.Set(uds[i].col.Name(), uds[i].jsonObj()) } return obj.String() } +func updateDiffList2Map(diffs []SUpdateDiff) UpdateDiffs { + ret := make(map[string]SUpdateDiff) + for i := range diffs { + ret[diffs[i].col.Name()] = diffs[i] + } + return ret +} + +type sPrimaryKeyValue struct { + key string + value interface{} +} + type sUpdateSQLResult struct { sql string vars []interface{} - setters UpdateDiffs - primaries map[string]interface{} + setters []SUpdateDiff + primaries []sPrimaryKeyValue } func (us *SUpdateSession) saveUpdateSql(dt interface{}) (*sUpdateSQLResult, error) { @@ -120,8 +132,8 @@ func (us *SUpdateSession) saveUpdateSql(dt interface{}) (*sUpdateSQLResult, erro versionFields := make([]string, 0) updatedFields := make([]string, 0) - primaries := make(map[string]interface{}) - setters := UpdateDiffs{} + primaries := make([]sPrimaryKeyValue, 0) + setters := make([]SUpdateDiff, 0) for _, c := range us.tableSpec.Columns() { k := c.Name() of, _ := ofields.GetInterface(k) @@ -132,12 +144,18 @@ func (us *SUpdateSession) saveUpdateSql(dt interface{}) (*sUpdateSQLResult, erro ov, _ := of.(string) nv, _ := nf.(string) if ov != nv && strings.EqualFold(ov, nv) { - setters[k] = SUpdateDiff{old: of, new: nf, col: c} + setters = append(setters, SUpdateDiff{old: of, new: nf, col: c}) } } - primaries[k] = c.ConvertFromValue(of) + primaries = append(primaries, sPrimaryKeyValue{ + key: k, + value: c.ConvertFromValue(of), + }) } else if c.IsText() { - primaries[k] = "" + primaries = append(primaries, sPrimaryKeyValue{ + key: k, + value: "", + }) } else { return nil, ErrEmptyPrimaryKey } @@ -157,7 +175,7 @@ func (us *SUpdateSession) saveUpdateSql(dt interface{}) (*sUpdateSQLResult, erro if c.IsZero(nf) && c.IsText() { nf = nil } - setters[k] = SUpdateDiff{old: of, new: nf, col: c} + setters = append(setters, SUpdateDiff{old: of, new: nf, col: c}) } if len(setters) == 0 { @@ -171,18 +189,15 @@ func (us *SUpdateSession) saveUpdateSql(dt interface{}) (*sUpdateSQLResult, erro vars := make([]interface{}, 0) var buf bytes.Buffer buf.WriteString(fmt.Sprintf("UPDATE `%s` SET ", us.tableSpec.name)) - first := true - for k, v := range setters { - if first { - first = false - } else { + for i, udif := range setters { + if i > 0 { buf.WriteString(", ") } - if gotypes.IsNil(v.new) { - buf.WriteString(fmt.Sprintf("`%s` = NULL", k)) + if gotypes.IsNil(udif.new) { + buf.WriteString(fmt.Sprintf("`%s` = NULL", udif.col.Name())) } else { - buf.WriteString(fmt.Sprintf("`%s` = ?", k)) - vars = append(vars, v.col.ConvertFromValue(v.new)) + buf.WriteString(fmt.Sprintf("`%s` = ?", udif.col.Name())) + vars = append(vars, udif.col.ConvertFromValue(udif.new)) } } for _, versionField := range versionFields { @@ -193,15 +208,12 @@ func (us *SUpdateSession) saveUpdateSql(dt interface{}) (*sUpdateSQLResult, erro vars = append(vars, now) } buf.WriteString(" WHERE ") - first = true - for k, v := range primaries { - if first { - first = false - } else { + for i, pkv := range primaries { + if i > 0 { buf.WriteString(" AND ") } - buf.WriteString(fmt.Sprintf("`%s` = ?", k)) - vars = append(vars, v) + buf.WriteString(fmt.Sprintf("`%s` = ?", pkv.key)) + vars = append(vars, pkv.value) } if DEBUG_SQLCHEMY { @@ -227,7 +239,7 @@ func (us *SUpdateSession) saveUpdate(dt interface{}) (UpdateDiffs, error) { return nil, errors.Wrap(err, "execUpdateSql") } - return sqlResult.setters, nil + return updateDiffList2Map(sqlResult.setters), nil } func (ts *STableSpec) execUpdateSql(dt interface{}, result *sUpdateSQLResult) error { @@ -246,8 +258,8 @@ func (ts *STableSpec) execUpdateSql(dt interface{}, result *sUpdateSQLResult) er } } q := ts.Query() - for k, v := range result.primaries { - q = q.Equals(k, v) + for _, pkv := range result.primaries { + q = q.Equals(pkv.key, pkv.value) } err = q.First(dt) if err != nil {