Merge branch 'master' into feature/go-modules

This commit is contained in:
Satoshi Inoue 2019-02-07 13:51:16 +09:00 committed by GitHub
commit 917edfbc32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 55 additions and 46 deletions

View File

@ -75,7 +75,7 @@ func updateCallback(scope *Scope) {
} else {
for _, field := range scope.Fields() {
if scope.changeableField(field) {
if !field.IsPrimaryKey && field.IsNormal {
if !field.IsPrimaryKey && field.IsNormal && (field.Name != "CreatedAt" || !field.IsBlank) {
if !field.IsForeignKey || !field.IsBlank || !field.HasDefaultValue {
sqls = append(sqls, fmt.Sprintf("%v = %v", scope.Quote(field.DBName), scope.AddToVars(field.Field.Interface())))
}

View File

@ -6,11 +6,11 @@ import (
)
var (
// ErrRecordNotFound record not found error, happens when only haven't find any matched data when looking up with a struct, finding a slice won't return this error
// ErrRecordNotFound returns a "record not found error". Occurs only when attempting to query the database with a struct; querying with a slice won't return this error
ErrRecordNotFound = errors.New("record not found")
// ErrInvalidSQL invalid SQL error, happens when you passed invalid SQL
// ErrInvalidSQL occurs when you attempt a query with invalid SQL
ErrInvalidSQL = errors.New("invalid SQL")
// ErrInvalidTransaction invalid transaction when you are trying to `Commit` or `Rollback`
// ErrInvalidTransaction occurs when you are trying to `Commit` or `Rollback`
ErrInvalidTransaction = errors.New("no valid transaction")
// ErrCantStartTransaction can't start transaction when you are trying to start one with `Begin`
ErrCantStartTransaction = errors.New("can't start transaction")
@ -21,7 +21,7 @@ var (
// Errors contains all happened errors
type Errors []error
// IsRecordNotFoundError returns current error has record not found error or not
// IsRecordNotFoundError returns true if error contains a RecordNotFound error
func IsRecordNotFoundError(err error) bool {
if errs, ok := err.(Errors); ok {
for _, err := range errs {
@ -33,12 +33,12 @@ func IsRecordNotFoundError(err error) bool {
return err == ErrRecordNotFound
}
// GetErrors gets all happened errors
// GetErrors gets all errors that have occurred and returns a slice of errors (Error type)
func (errs Errors) GetErrors() []error {
return errs
}
// Add adds an error
// Add adds an error to a given slice of errors
func (errs Errors) Add(newErrors ...error) Errors {
for _, err := range newErrors {
if err == nil {
@ -62,7 +62,7 @@ func (errs Errors) Add(newErrors ...error) Errors {
return errs
}
// Error format happened errors
// Error takes a slice of all errors that have occurred and returns it as a formatted string
func (errs Errors) Error() string {
var errors = []string{}
for _, e := range errs {

View File

@ -178,7 +178,7 @@ func (s *DB) SingularTable(enable bool) {
func (s *DB) NewScope(value interface{}) *Scope {
dbClone := s.clone()
dbClone.Value = value
return &Scope{db: dbClone, Search: dbClone.search.clone(), Value: value}
return &Scope{db: dbClone, Search: dbClone.search, Value: value}
}
// QueryExpr returns the query as expr object

View File

@ -40,7 +40,7 @@ func (s *ModelStruct) TableName(db *DB) string {
s.defaultTableName = tabler.TableName()
} else {
tableName := ToTableName(s.ModelType.Name())
if db == nil || !db.parent.singularTable {
if db == nil || (db.parent != nil && !db.parent.singularTable) {
tableName = inflection.Plural(tableName)
}
s.defaultTableName = tableName
@ -70,52 +70,52 @@ type StructField struct {
}
// TagSettingsSet Sets a tag in the tag settings map
func (s *StructField) TagSettingsSet(key, val string) {
s.tagSettingsLock.Lock()
defer s.tagSettingsLock.Unlock()
s.TagSettings[key] = val
func (sf *StructField) TagSettingsSet(key, val string) {
sf.tagSettingsLock.Lock()
defer sf.tagSettingsLock.Unlock()
sf.TagSettings[key] = val
}
// TagSettingsGet returns a tag from the tag settings
func (s *StructField) TagSettingsGet(key string) (string, bool) {
s.tagSettingsLock.RLock()
defer s.tagSettingsLock.RUnlock()
val, ok := s.TagSettings[key]
func (sf *StructField) TagSettingsGet(key string) (string, bool) {
sf.tagSettingsLock.RLock()
defer sf.tagSettingsLock.RUnlock()
val, ok := sf.TagSettings[key]
return val, ok
}
// TagSettingsDelete deletes a tag
func (s *StructField) TagSettingsDelete(key string) {
s.tagSettingsLock.Lock()
defer s.tagSettingsLock.Unlock()
delete(s.TagSettings, key)
func (sf *StructField) TagSettingsDelete(key string) {
sf.tagSettingsLock.Lock()
defer sf.tagSettingsLock.Unlock()
delete(sf.TagSettings, key)
}
func (structField *StructField) clone() *StructField {
func (sf *StructField) clone() *StructField {
clone := &StructField{
DBName: structField.DBName,
Name: structField.Name,
Names: structField.Names,
IsPrimaryKey: structField.IsPrimaryKey,
IsNormal: structField.IsNormal,
IsIgnored: structField.IsIgnored,
IsScanner: structField.IsScanner,
HasDefaultValue: structField.HasDefaultValue,
Tag: structField.Tag,
DBName: sf.DBName,
Name: sf.Name,
Names: sf.Names,
IsPrimaryKey: sf.IsPrimaryKey,
IsNormal: sf.IsNormal,
IsIgnored: sf.IsIgnored,
IsScanner: sf.IsScanner,
HasDefaultValue: sf.HasDefaultValue,
Tag: sf.Tag,
TagSettings: map[string]string{},
Struct: structField.Struct,
IsForeignKey: structField.IsForeignKey,
Struct: sf.Struct,
IsForeignKey: sf.IsForeignKey,
}
if structField.Relationship != nil {
relationship := *structField.Relationship
if sf.Relationship != nil {
relationship := *sf.Relationship
clone.Relationship = &relationship
}
// copy the struct field tagSettings, they should be read-locked while they are copied
structField.tagSettingsLock.Lock()
defer structField.tagSettingsLock.Unlock()
for key, value := range structField.TagSettings {
sf.tagSettingsLock.Lock()
defer sf.tagSettingsLock.Unlock()
for key, value := range sf.TagSettings {
clone.TagSettings[key] = value
}

View File

@ -1309,6 +1309,7 @@ func (scope *Scope) autoIndex() *Scope {
}
func (scope *Scope) getColumnAsArray(columns []string, values ...interface{}) (results [][]interface{}) {
resultMap := make(map[string][]interface{})
for _, value := range values {
indirectValue := indirect(reflect.ValueOf(value))
@ -1327,7 +1328,10 @@ func (scope *Scope) getColumnAsArray(columns []string, values ...interface{}) (r
}
if hasValue {
results = append(results, result)
h := fmt.Sprint(result...)
if _, exist := resultMap[h]; !exist {
resultMap[h] = result
}
}
}
case reflect.Struct:
@ -1342,11 +1346,16 @@ func (scope *Scope) getColumnAsArray(columns []string, values ...interface{}) (r
}
if hasValue {
results = append(results, result)
h := fmt.Sprint(result...)
if _, exist := resultMap[h]; !exist {
resultMap[h] = result
}
}
}
}
for _, v := range resultMap {
results = append(results, v)
}
return
}