Mutations¶
Basic Mutator¶
REL uses mutator to define inserts and updates operation. Using basic mutator won't update created_at
and updated_at
fields.
Mutator | Description |
---|---|
Dec(field string) | Decrement a field value by 1 |
DecBy(field string, n int) | Decrement a field value by n |
Inc(field string) | Increase a field value by 1 |
IncBy(field string, n int) | Increase a field value by n |
Set(field string, value interface{}) | Set a value to a field |
SetFragment(raw string, args ...interface{}) | Set a value of a field using SQL fragment |
Set title and category values:
err := repo.Update(ctx, &book,
rel.Set("title", "REL for Dummies"),
rel.Set("category", "technology"),
)
repo.ExpectUpdate(
rel.Set("title", "REL for Dummies"),
rel.Set("category", "technology"),
).For(&book)
Decrement stock:
err := repo.Update(ctx, &book, rel.DecBy("stock", 2))
repo.ExpectUpdate(rel.DecBy("stock", 2)).For(&book)
Update title using SQL fragment:
err := repo.Update(ctx, &book, rel.SetFragment("title=?", "REL for dummies"))
repo.ExpectUpdate(rel.SetFragment("title=?", "REL for dummies")).For(&book)
Structset¶
Structset is a mutator that generates list of Set
mutators based on a struct value. Using Structset will result in replacing the intire record in the database using provided struct, It'll always clear a has many association and re-insert it on updates if it's loaded. Changeset can be used to avoid clearing has many association on updates.
Note
Structset
is the default mutator used when none is provided explicitly.
Inserting a struct using structset mutator:
structset := rel.NewStructset(&book, false)
err := repo.Insert(ctx, &book, structset)
repo.ExpectInsert().For(&book)
Changeset¶
Changeset allows you to track and update only updated values and asssociation to database. This is very efficient when dealing with a complex struct that contains a lot of fields and associations.
Update only price and discount field using changeset:
changeset := rel.NewChangeset(&book)
book.Price = 10
if changeset.FieldChanged("price") {
book.Discount = false
}
err := repo.Update(ctx, &book, changeset)
repo.ExpectUpdate().ForType("main.Book")
Map¶
Map allows to define group of Set
mutator, this is intended to be use internally and not to be exposed directly to user. Mutation defined in the map will be applied to the struct passed as the first argument. Insert/Update using map wont update created_at
or updated_at
field.
Insert books and its author using Map
:
data := rel.Map{
"title": "Rel for dummies",
"category": "education",
"author": rel.Map{
"name": "CZ2I28 Delta",
},
}
// Insert using map.
err := repo.Insert(ctx, &book, data)
data := rel.Map{
"title": "Rel for dummies",
"category": "education",
"author": rel.Map{
"name": "CZ2I28 Delta",
},
}
repo.ExpectInsert(data).ForType("main.Book")
Reloading Updated Struct¶
By default, only Inc
, IncBy
, Dec
, DecBy
and SetFragment
will reload struct from database, Reload
mutator can be used to manually trigger reload after inserts/update operations.
Update title and force reload:
err := repo.Update(ctx, &book,
rel.Set("title", "REL for Dummies"),
rel.Reload(true),
)
repo.ExpectUpdate(
rel.Set("title", "REL for Dummies"),
rel.Reload(true),
).For(&book)
Cascade Operations¶
REL supports insert/update/delete record and it's associations.
Disable cascade insert (default enabled):
err := repo.Insert(ctx, &book, rel.Cascade(false))
repo.ExpectInsert(rel.Cascade(false)).For(&book)
Enable cascade delete (default disabled):
err := repo.Delete(ctx, &book, rel.Cascade(true))
repo.ExpectDelete(rel.Cascade(true)).For(&book)