diff --git a/Gopkg.lock b/Gopkg.lock index b7a20c868b..55fc3856b5 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -279,6 +279,7 @@ revision = "d2fe137411c230927e28dd82b1a3bcb618dbb28d" [[projects]] + branch = "master" name = "github.com/yunionio/pkg" packages = [ "gotypes", @@ -312,12 +313,13 @@ "util/workqueue", "utils" ] - revision = "8c5eab6f0b758d3888fd9041419e38a5b1129725" + revision = "607ffde100f37b77f1a90289c06ed6b103325ee8" [[projects]] + branch = "master" name = "github.com/yunionio/sqlchemy" packages = ["."] - revision = "a14641a90b9e5c72868b7a8358d62ea1d83eab53" + revision = "b84d8e2b4313670f24cd50caa5bcc0c5288c16b5" [[projects]] branch = "master" @@ -376,6 +378,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "e90b051392bcbf484678dc55e4b1e44b57442f7b000c6d9956b2979560751ec1" + inputs-digest = "a9c0d04bcafa27a0faa8d0725160249702ccf42913c108c3ac50e1191253f2f1" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 1c5b01e630..92934094e1 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -34,7 +34,7 @@ name = "github.com/yunionio/jsonutils" [[constraint]] - revision = "a14641a90b9e5c72868b7a8358d62ea1d83eab53" + branch = "master" name = "github.com/yunionio/sqlchemy" [[constraint]] @@ -42,7 +42,7 @@ name = "github.com/yunionio/log" [[constraint]] - revision = "8c5eab6f0b758d3888fd9041419e38a5b1129725" + branch = "master" name = "github.com/yunionio/pkg" [[constraint]] diff --git a/Makefile b/Makefile index bb21232025..481827a1ee 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ REPO_PREFIX := github.com/yunionio/onecloud VENDOR_PATH := $(REPO_PREFIX)/vendor VERSION_PKG := $(VENDOR_PATH)/github.com/yunionio/pkg/util/version -ROOT_DIR := $(shell pwd) +ROOT_DIR := $(shell readlink -f `pwd`) BUILD_DIR := $(ROOT_DIR)/_output BIN_DIR := $(BUILD_DIR)/bin BUILD_SCRIPT := $(ROOT_DIR)/build/build.sh @@ -84,6 +84,16 @@ output_dir: @mkdir -p $(BUILD_DIR) +dep: + cd $(ROOT_DIR) && dep ensure -v + +dep_clean: + rm -fr $(GOPATH)/pkg/dep/sources/* + +dep_install: + curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh + + .PHONY: all build prepare_dir clean fmt rpm diff --git a/vendor/github.com/yunionio/pkg/util/reflectutils/reflectutils.go b/vendor/github.com/yunionio/pkg/util/reflectutils/reflectutils.go index 9ab5cde347..58126fec06 100644 --- a/vendor/github.com/yunionio/pkg/util/reflectutils/reflectutils.go +++ b/vendor/github.com/yunionio/pkg/util/reflectutils/reflectutils.go @@ -136,6 +136,22 @@ func FillEmbededStructValue(container reflect.Value, embed reflect.Value) bool { return false } +func SetStructFieldValue(structValue reflect.Value, fieldName string, val reflect.Value) bool { + dataType := structValue.Type() + for i := 0; i < dataType.NumField(); i += 1 { + fieldType := dataType.Field(i) + if gotypes.IsFieldExportable(fieldType.Name) { + fName := GetStructFieldName(&fieldType) + if fName == fieldName { + fieldValue := structValue.Field(i) + fieldValue.Set(val) + return true + } + } + } + return false +} + func ExpandInterface(val interface{}) []interface{} { value := reflect.Indirect(reflect.ValueOf(val)) if value.Kind() == reflect.Slice || value.Kind() == reflect.Array { diff --git a/vendor/github.com/yunionio/pkg/util/secrules/secrules.go b/vendor/github.com/yunionio/pkg/util/secrules/secrules.go index 794564e981..7336b51751 100644 --- a/vendor/github.com/yunionio/pkg/util/secrules/secrules.go +++ b/vendor/github.com/yunionio/pkg/util/secrules/secrules.go @@ -1,21 +1,3 @@ -/* -Copyright 2017 The Kubernetes Authors. - -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. -*/ - -// This file was autogenerated by set-gen. Do not edit it manually! - package secrules import ( diff --git a/vendor/github.com/yunionio/sqlchemy/column.go b/vendor/github.com/yunionio/sqlchemy/column.go index e3146324a3..adae8c47b1 100644 --- a/vendor/github.com/yunionio/sqlchemy/column.go +++ b/vendor/github.com/yunionio/sqlchemy/column.go @@ -18,6 +18,7 @@ type IColumnSpec interface { Name() string ColType() string Default() string + IsSupportDefault() bool IsNullable() bool IsPrimary() bool IsKeyIndex() bool @@ -67,6 +68,10 @@ func (c *SBaseColumn) Default() string { return c.defaultString } +func (c *SBaseColumn) IsSupportDefault() bool { + return true +} + func (c *SBaseColumn) IsNullable() bool { return c.isNullable } @@ -146,7 +151,7 @@ func definitionBuffer(c IColumnSpec) bytes.Buffer { } def := c.Default() - if len(def) > 0 { + if len(def) > 0 && c.IsSupportDefault() { def = c.ConvertFromString(def) buf.WriteString(" DEFAULT ") if c.IsText() { @@ -475,6 +480,16 @@ type STextColumn struct { Charset string } +func (c *STextColumn) IsSupportDefault() bool { + // https://stackoverflow.com/questions/3466872/why-cant-a-text-column-have-a-default-value-in-mysql + // MySQL does not support default for TEXT/BLOB + if c.sqlType == "VARCHAR" { + return true + } else { + return false + } +} + func (c *STextColumn) ColType() string { return fmt.Sprintf("%s CHARACTER SET '%s'", c.SBaseWidthColumn.ColType(), c.Charset) } @@ -588,16 +603,16 @@ func NewDateTimeColumn(name string, tagmap map[string]string) SDateTimeColumn { return dtc } -type CompondColumn struct { +type CompoundColumn struct { STextColumn } -func (c *CompondColumn) DefinitionString() string { +func (c *CompoundColumn) DefinitionString() string { buf := definitionBuffer(c) return buf.String() } -func (c *CompondColumn) IsZero(val interface{}) bool { +func (c *CompoundColumn) IsZero(val interface{}) bool { if val == nil { return true } @@ -606,7 +621,7 @@ func (c *CompondColumn) IsZero(val interface{}) bool { return json.IsZero() } -func (c *CompondColumn) ConvertFromValue(val interface{}) interface{} { +func (c *CompoundColumn) ConvertFromValue(val interface{}) interface{} { bVal, ok := val.(gotypes.ISerializable) if ok && bVal != nil { return bVal.String() @@ -615,8 +630,8 @@ func (c *CompondColumn) ConvertFromValue(val interface{}) interface{} { } } -func NewCompondColumn(name string, tagmap map[string]string) CompondColumn { - dtc := CompondColumn{NewTextColumn(name, tagmap)} +func NewCompoundColumn(name string, tagmap map[string]string) CompoundColumn { + dtc := CompoundColumn{NewTextColumn(name, tagmap)} return dtc } diff --git a/vendor/github.com/yunionio/sqlchemy/conditions.go b/vendor/github.com/yunionio/sqlchemy/conditions.go index 5c6678b853..260d15af9d 100644 --- a/vendor/github.com/yunionio/sqlchemy/conditions.go +++ b/vendor/github.com/yunionio/sqlchemy/conditions.go @@ -12,11 +12,11 @@ type ICondition interface { Variables() []interface{} } -type SCompondConditions struct { +type SCompoundConditions struct { conditions []ICondition } -func compondWhereClause(c *SCompondConditions, op string) string { +func compoundWhereClause(c *SCompoundConditions, op string) string { var buf bytes.Buffer for _, cond := range c.conditions { if buf.Len() > 0 { @@ -31,11 +31,11 @@ func compondWhereClause(c *SCompondConditions, op string) string { return buf.String() } -func (c *SCompondConditions) WhereClause() string { +func (c *SCompoundConditions) WhereClause() string { return "" } -func (c *SCompondConditions) Variables() []interface{} { +func (c *SCompoundConditions) Variables() []interface{} { vars := make([]interface{}, 0) for _, cond := range c.conditions { nvars := cond.Variables() @@ -47,19 +47,19 @@ func (c *SCompondConditions) Variables() []interface{} { } type SAndConditions struct { - SCompondConditions + SCompoundConditions } func (c *SAndConditions) WhereClause() string { - return compondWhereClause(&c.SCompondConditions, SQL_OP_AND) + return compoundWhereClause(&c.SCompoundConditions, SQL_OP_AND) } type SOrConditions struct { - SCompondConditions + SCompoundConditions } func (c *SOrConditions) WhereClause() string { - return compondWhereClause(&c.SCompondConditions, SQL_OP_OR) + return compoundWhereClause(&c.SCompoundConditions, SQL_OP_OR) } func AND(cond ...ICondition) ICondition { @@ -72,7 +72,7 @@ func AND(cond ...ICondition) ICondition { conds = append(conds, c) } } - cc := SAndConditions{SCompondConditions{conditions: conds}} + cc := SAndConditions{SCompoundConditions{conditions: conds}} return &cc } @@ -86,7 +86,7 @@ func OR(cond ...ICondition) ICondition { conds = append(conds, c) } } - cc := SOrConditions{SCompondConditions{conditions: conds}} + cc := SOrConditions{SCompoundConditions{conditions: conds}} return &cc } diff --git a/vendor/github.com/yunionio/sqlchemy/insert.go b/vendor/github.com/yunionio/sqlchemy/insert.go index 53479f7583..942fdabae2 100644 --- a/vendor/github.com/yunionio/sqlchemy/insert.go +++ b/vendor/github.com/yunionio/sqlchemy/insert.go @@ -6,7 +6,6 @@ import ( "strings" "github.com/yunionio/log" - "github.com/yunionio/pkg/gotypes" "github.com/yunionio/pkg/util/reflectutils" ) @@ -25,6 +24,7 @@ func (t *STableSpec) Insert(dt interface{}) error { names := make([]string, 0) format := make([]string, 0) values := make([]interface{}, 0) + fields := reflectutils.FetchStructFieldNameValueInterfaces(dataValue) for _, c := range t.columns { isAutoInc := false @@ -58,15 +58,23 @@ func (t *STableSpec) Insert(dt interface{}) error { } else { return fmt.Errorf("fail to insert for null primary key `%s`", k) } + } else if ! c.IsSupportDefault() && len(c.Default()) > 0 && ov != nil && c.IsZero(ov) { // empty text value + val := c.ConvertFromString(c.Default()) + values = append(values, val) + names = append(names, fmt.Sprintf("`%s`", k)) + format = append(format, "?") } } + insertSql := fmt.Sprintf("INSERT INTO `%s` (%s) VALUES(%s)", t.name, strings.Join(names, ", "), strings.Join(format, ", ")) + if DEBUG_SQLCHEMY { log.Debugf("%s values: %s", insertSql, values) } + results, err := _db.Exec(insertSql, values...) if err != nil { return err @@ -78,6 +86,8 @@ func (t *STableSpec) Insert(dt interface{}) error { if affectCnt != 1 { return fmt.Errorf("Insert affected cnt %d != 1", affectCnt) } + + /* if len(autoIncField) > 0 { lastId, err := results.LastInsertId() if err == nil { @@ -87,5 +97,32 @@ func (t *STableSpec) Insert(dt interface{}) error { } } } + */ + + // query the value, so default value can be feedback into the object + // fields = reflectutils.FetchStructFieldNameValueInterfaces(dataValue) + q := t.Query() + for _, c := range t.columns { + if c.IsPrimary() { + nc, ok := c.(*SIntegerColumn) + if ok && nc.IsAutoIncrement { + lastId, err := results.LastInsertId() + if err != nil { + log.Errorf("Fail to fetch lastInsertId %s", err) + return err + } else { + q = q.Equals(c.Name(), lastId) + } + } else { + q = q.Equals(c.Name(), fields[c.Name()]) + } + } + } + err = q.First(dt) + if err != nil { + log.Errorf("query after insert failed %s", err) + return err + } + return nil } diff --git a/vendor/github.com/yunionio/sqlchemy/parser.go b/vendor/github.com/yunionio/sqlchemy/parser.go index f68ad1fe3d..5c075fd4fe 100644 --- a/vendor/github.com/yunionio/sqlchemy/parser.go +++ b/vendor/github.com/yunionio/sqlchemy/parser.go @@ -86,7 +86,7 @@ func fieldToColumnSpec(field *reflect.StructField) IColumnSpec { return &col*/ default: if gotypes.IsSerializable(field.Type) { - col := NewCompondColumn(fieldname, tagmap) + col := NewCompoundColumn(fieldname, tagmap) return &col } else { log.Fatalf("Unsupported type! %s", field.Type)