mirror of https://github.com/go-gorm/gorm.git
Add CHANGELOG
This commit is contained in:
parent
c89b896778
commit
899996fec9
|
@ -0,0 +1,54 @@
|
||||||
|
# Change Log
|
||||||
|
|
||||||
|
## v1.0 (unreleased)
|
||||||
|
|
||||||
|
#### Breaking Changes
|
||||||
|
|
||||||
|
* **`gorm.Open` return type `*gorm.DB` instead of `gorm.DB`**
|
||||||
|
|
||||||
|
* **Updating will only update changed fields**
|
||||||
|
|
||||||
|
Most applications won't be affected, only when you are changing updating values in callbacks like `BeforeSave`, `BeforeUpdate`, you should use `scope.SetColumn` then, for example:
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (user *User) BeforeUpdate(scope *gorm.Scope) {
|
||||||
|
if pw, err := bcrypt.GenerateFromPassword(user.Password, 0); err == nil {
|
||||||
|
scope.SetColumn("EncryptedPassword", pw)
|
||||||
|
// user.EncryptedPassword = pw // doesn't work, won't including EncryptedPassword field when updating
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* **Soft delete's default querying scope will only check `deleted_at IS NULL`**
|
||||||
|
|
||||||
|
Before `db.Find(&user)` will generate querying SQL if user has `DeletedAt` field
|
||||||
|
|
||||||
|
`SELECT * FROM users WHERE deleted_at IS NULL OR deleted_at <= '0001-01-02'`
|
||||||
|
|
||||||
|
Now won't include blank time check `<= '0001-01-02` anymore, will generat SQL like:
|
||||||
|
|
||||||
|
`SELECT * FROM users WHERE deleted_at IS NULL`
|
||||||
|
|
||||||
|
So your application's `DeletedAt` field should not use `time.Time` as data type, need to use pointer `*time.Time` or something like `NullTime`.
|
||||||
|
If you are using `gorm.Model`, then you are good, nothing need to be change, just make sure all records using blank time for `deleted_at` has been set to NULL, sample migration script:
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"github.com/jinzhu/now"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var models = []interface{}{&User{}, &Image{}}
|
||||||
|
for _, model := range models {
|
||||||
|
db.Unscoped().Model(model).Where("deleted_at < ?", now.MustParse("0001-01-02")).Update("deleted_at", gorm.Expr("NULL"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* **New ToDBName logic**
|
||||||
|
|
||||||
|
Before when GORM convert Struct, Field's name to db name, only some common initialisms from [golint](https://github.com/golang/lint/blob/master/lint.go#L702) like `HTTP`, `URI` are special handled.
|
||||||
|
|
||||||
|
So field `HTTP`'s db name will be `http` not `h_t_t_p`, but other initialisms like `SKU` not in golint, it's db name will be `s_k_u`, this release fixed this, any upper case initialisms should be converted correctly.
|
||||||
|
|
||||||
|
If you applications using some upper case initialisms which doesn't exist in [golint](https://github.com/golang/lint/blob/master/lint.go#L702), you could set the column name with tag, like `sql:"column:s_k_u"`, or alert your database's column name in your database
|
|
@ -653,7 +653,7 @@ db.Where("age = ?", 20).Delete(&User{})
|
||||||
|
|
||||||
// Soft deleted records will be ignored when query them
|
// Soft deleted records will be ignored when query them
|
||||||
db.Where("age = 20").Find(&user)
|
db.Where("age = 20").Find(&user)
|
||||||
//// SELECT * FROM users WHERE age = 20 AND (deleted_at IS NULL OR deleted_at <= '0001-01-02');
|
//// SELECT * FROM users WHERE age = 20 AND deleted_at IS NULL;
|
||||||
|
|
||||||
// Find soft deleted records with Unscoped
|
// Find soft deleted records with Unscoped
|
||||||
db.Unscoped().Where("age = 20").Find(&users)
|
db.Unscoped().Where("age = 20").Find(&users)
|
||||||
|
|
7
utils.go
7
utils.go
|
@ -76,7 +76,9 @@ func ToDBName(name string) string {
|
||||||
if lastCase == upper && nextCase == upper {
|
if lastCase == upper && nextCase == upper {
|
||||||
buf.WriteRune(v)
|
buf.WriteRune(v)
|
||||||
} else {
|
} else {
|
||||||
buf.WriteRune('_')
|
if value[i-1] != '_' && value[i+1] != '_' {
|
||||||
|
buf.WriteRune('_')
|
||||||
|
}
|
||||||
buf.WriteRune(v)
|
buf.WriteRune(v)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -92,8 +94,7 @@ func ToDBName(name string) string {
|
||||||
|
|
||||||
buf.WriteByte(value[len(value)-1])
|
buf.WriteByte(value[len(value)-1])
|
||||||
|
|
||||||
s := strings.Replace(strings.ToLower(buf.String()), "__", "_", -1)
|
s := strings.ToLower(buf.String())
|
||||||
|
|
||||||
smap.Set(name, s)
|
smap.Set(name, s)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ func TestToDBNameGenerateFriendlyName(t *testing.T) {
|
||||||
"PFAndESI": "pf_and_esi",
|
"PFAndESI": "pf_and_esi",
|
||||||
"AbcAndJkl": "abc_and_jkl",
|
"AbcAndJkl": "abc_and_jkl",
|
||||||
"EmployeeID": "employee_id",
|
"EmployeeID": "employee_id",
|
||||||
|
"SKU_ID": "sku_id",
|
||||||
"HTTPAndSMTP": "http_and_smtp",
|
"HTTPAndSMTP": "http_and_smtp",
|
||||||
"HTTPServerHandlerForURLID": "http_server_handler_for_url_id",
|
"HTTPServerHandlerForURLID": "http_server_handler_for_url_id",
|
||||||
"UUID": "uuid",
|
"UUID": "uuid",
|
||||||
|
|
Loading…
Reference in New Issue