Skip to content

Commit ce9c5a7

Browse files
authored
[doc] Mutations (#67)
* renamed query to queries * fix links * added mutations doc * simplify crud * fix pagination * uncommit
1 parent aaef9bd commit ce9c5a7

File tree

10 files changed

+663
-354
lines changed

10 files changed

+663
-354
lines changed

docs/_sidebar.md

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,30 @@
1010
* [Update](crud.md#update)
1111
* [Delete](crud.md#delete)
1212

13-
* [Query Interface](query.md)
14-
15-
* [Retrieving Record](query.md#retrieving-data)
16-
* [Conditions](query.md#conditions)
17-
* [Sorting](query.md#sorting)
18-
* [Selecting Specific Fields](query.md#selecting-specific-fields)
19-
* [Using Specific Table](query.md#using-specific-table)
20-
* [Limit and Offset](query.md#limit-and-offset)
21-
* [Group](query.md#group)
22-
* [Joining Tables](query.md#joining-tables)
23-
* [Pessimistic Locking](query.md#pessimistic-locking)
24-
* [Aggregation](query.md#aggregation)
25-
* [Pagination](query.md#pagination)
26-
* [Batch Iteration](query.md#batch-iteration)
27-
* [Native SQL Query](query.md#native-sql-query)
13+
* [Queries](queries.md)
14+
15+
* [Retrieving Record](queries.md#retrieving-data)
16+
* [Conditions](queries.md#conditions)
17+
* [Sorting](queries.md#sorting)
18+
* [Selecting Specific Fields](queries.md#selecting-specific-fields)
19+
* [Using Specific Table](queries.md#using-specific-table)
20+
* [Limit and Offset](queries.md#limit-and-offset)
21+
* [Group](queries.md#group)
22+
* [Joining Tables](queries.md#joining-tables)
23+
* [Pessimistic Locking](queries.md#pessimistic-locking)
24+
* [Aggregation](queries.md#aggregation)
25+
* [Pagination](queries.md#pagination)
26+
* [Batch Iteration](queries.md#batch-iteration)
27+
* [Native SQL Query](queries.md#native-sql-queries)
28+
29+
* [Mutations](mutations.md)
30+
31+
* [Basic Mutator](mutations.md#basic-mutator)
32+
* [Structset](mutations.md#structset)
33+
* [Changeset](mutations.md#changeset)
34+
* [Map](mutations.md#map)
35+
* [Reloading Updated Struct](mutations.md#reloading-updated-struct)
36+
* [Cascade Operations](mutations.md#cascade-operations)
2837

2938
* [Association](association.md)
3039

docs/crud.go

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -25,35 +25,6 @@ func CrudInsert(ctx context.Context, repo rel.Repository) error {
2525
return err
2626
}
2727

28-
// CrudInsertMap docs example.
29-
func CrudInsertMap(ctx context.Context, repo rel.Repository) error {
30-
/// [insert-map]
31-
var book Book
32-
data := rel.Map{
33-
"title": "Rel for dummies",
34-
"category": "education",
35-
}
36-
37-
// Insert using map.
38-
err := repo.Insert(ctx, &book, data)
39-
/// [insert-map]
40-
41-
return err
42-
}
43-
44-
// CrudInsertSet docs example.
45-
func CrudInsertSet(ctx context.Context, repo rel.Repository) error {
46-
/// [insert-set]
47-
var book Book
48-
err := repo.Insert(ctx, &book,
49-
rel.Set("title", "Rel for dummies"),
50-
rel.Set("category", "education"),
51-
)
52-
/// [insert-set]
53-
54-
return err
55-
}
56-
5728
// CrudInsertAll docs example.
5829
func CrudInsertAll(ctx context.Context, repo rel.Repository) error {
5930
/// [insert-all]
@@ -130,17 +101,6 @@ func CrudUpdate(ctx context.Context, repo rel.Repository) error {
130101
return err
131102
}
132103

133-
// CrudUpdateDec docs example.
134-
func CrudUpdateDec(ctx context.Context, repo rel.Repository) error {
135-
var book Book
136-
137-
/// [update-dec]
138-
err := repo.Update(ctx, &book, rel.Dec("stock"))
139-
/// [update-dec]
140-
141-
return err
142-
}
143-
144104
// CrudDelete docs example.
145105
func CrudDelete(ctx context.Context, repo rel.Repository) error {
146106
var book Book

docs/crud.md

Lines changed: 1 addition & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
A new record can be inserted to database using a struct, map or set function. To insert a new record using a struct, simply pass the pointer to the instance as the only argment. Insertion using struct will update `created_at` and `updated_at` field if any.
66

7-
?> REL will automatically insert all associations if it's non zero, to disable cascade inserts, you can pass `rel.Cascade(false)` mutator.
8-
97
<!-- tabs:start -->
108

119
### **Example**
@@ -34,39 +32,8 @@ Expect insertion to to return an error.
3432

3533
<!-- tabs:end -->
3634

37-
To insert a new record using a map, simply pass a `rel.Map` as the second argument, mutation defined in the map will be applied to the struct passed as the first argument. Insertion using map wont update `created_at` or `updated_at` field.
38-
39-
<!-- tabs:start -->
40-
41-
### **Example**
42-
43-
[crud.go](crud.go ':include :fragment=insert-map')
44-
45-
### **Mock**
46-
47-
?> reltest.Repository will automatically populate record using value provided by map.
48-
49-
[crud_test.go](crud_test.go ':include :fragment=insert-map')
50-
51-
<!-- tabs:end -->
52-
53-
It's also possible to insert a new record manually using `rel.Set`, which is a very basic type of `mutator`.
54-
55-
<!-- tabs:start -->
56-
57-
### **Example**
58-
59-
[crud.go](crud.go ':include :fragment=insert-set')
60-
61-
### **Mock**
62-
63-
[crud_test.go](crud_test.go ':include :fragment=insert-set')
64-
65-
<!-- tabs:end -->
66-
6735
To inserts multiple records at once, use `InsertAll`.
6836

69-
7037
<!-- tabs:start -->
7138

7239
### **Example**
@@ -77,10 +44,8 @@ To inserts multiple records at once, use `InsertAll`.
7744

7845
[crud_test.go](crud_test.go ':include :fragment=insert-all')
7946

80-
8147
<!-- tabs:end -->
8248

83-
8449
## Read
8550

8651
REL provides a powerful API for querying record from database. To query a single record, simply use the Find method, it's accept the returned result as the first argument, and the conditions for the rest arguments.
@@ -148,8 +113,6 @@ Similar to create, updating a record in REL can also be done using struct, map o
148113

149114
An update using struct will cause all fields and association to be saved to database, regardless of whether it's been updated or not. Use `rel.Map`, `rel.Set` or `rel.Changeset` to update only specific fields.
150115

151-
?> REL will automatically update all associations if it's non zero, to disable cascade updates, you can pass `rel.Cascade(false)` mutator.
152-
153116
?> When updating belongs to association, it's recommended to not expose reference key (`[other]_id`) for updates directly from user, since there's no way to validate belongs to association using query.
154117

155118
<!-- tabs:start -->
@@ -164,28 +127,12 @@ An update using struct will cause all fields and association to be saved to data
164127

165128
<!-- tabs:end -->
166129

167-
Besides `rel.Map` and `rel.Set` mutator. There's also increment and decrement mutator to atomically increment/decrement any value in database.
168-
169-
<!-- tabs:start -->
170-
171-
### **Example**
172-
173-
[crud.go](crud.go ':include :fragment=update-dec')
174-
175-
### **Mock**
176-
177-
[crud_test.go](crud_test.go ':include :fragment=update-dec')
178-
179-
<!-- tabs:end -->
180-
181130
## Delete
182131

183132
To delete a record in rel, simply pass the record to be deleted.
184133

185134
?> REL will automatically apply soft-delete if `DeletedAt time.Time` field exists in a struct. To query soft-deleted records, use `rel.Unscoped(true)` when querying.
186135

187-
?> REL will not automatically delete all associations, to enable application level cascade deletes, you can pass `rel.Cascade(true)` mutator.
188-
189136
<!-- tabs:start -->
190137

191138
### **Example**
@@ -214,4 +161,4 @@ Deleting multiple records is possible using `DeleteAll`.
214161
<!-- tabs:end -->
215162

216163

217-
**Next: [Query Interface](query.md)**
164+
**Next: [Queries](queries.md)**

docs/crud_test.go

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -73,40 +73,6 @@ func TestCrudInsert_error(t *testing.T) {
7373
repo.AssertExpectations(t)
7474
}
7575

76-
func TestCrudInsertMap(t *testing.T) {
77-
var (
78-
ctx = context.TODO()
79-
repo = reltest.New()
80-
)
81-
82-
/// [insert-map]
83-
repo.ExpectInsert(rel.Map{
84-
"title": "Rel for dummies",
85-
"category": "education",
86-
}).ForType("main.Book")
87-
/// [insert-map]
88-
89-
assert.Nil(t, CrudInsertMap(ctx, repo))
90-
repo.AssertExpectations(t)
91-
}
92-
93-
func TestCrudInsertSet(t *testing.T) {
94-
var (
95-
ctx = context.TODO()
96-
repo = reltest.New()
97-
)
98-
99-
/// [insert-set]
100-
repo.ExpectInsert(
101-
rel.Set("title", "Rel for dummies"),
102-
rel.Set("category", "education"),
103-
).ForType("main.Book")
104-
/// [insert-set]
105-
106-
assert.Nil(t, CrudInsertSet(ctx, repo))
107-
repo.AssertExpectations(t)
108-
}
109-
11076
func TestCrudInsertAll(t *testing.T) {
11177
var (
11278
ctx = context.TODO()
@@ -214,20 +180,6 @@ func TestCrudUpdate(t *testing.T) {
214180
repo.AssertExpectations(t)
215181
}
216182

217-
func TestCrudUpdateDec(t *testing.T) {
218-
var (
219-
ctx = context.TODO()
220-
repo = reltest.New()
221-
)
222-
223-
/// [update-dec]
224-
repo.ExpectUpdate(rel.Dec("stock")).ForType("main.Book")
225-
/// [update-dec]
226-
227-
assert.Nil(t, CrudUpdateDec(ctx, repo))
228-
repo.AssertExpectations(t)
229-
}
230-
231183
func TestCrudDelete(t *testing.T) {
232184
var (
233185
ctx = context.TODO()

docs/mutations.go

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package main
2+
3+
import (
4+
"context"
5+
6+
"github.com/Fs02/rel"
7+
)
8+
9+
// MutationsBasicSet docs example.
10+
func MutationsBasicSet(ctx context.Context, repo rel.Repository) error {
11+
var book Book
12+
13+
/// [basic-set]
14+
err := repo.Update(ctx, &book,
15+
rel.Set("title", "REL for Dummies"),
16+
rel.Set("category", "technology"),
17+
)
18+
/// [basic-set]
19+
20+
return err
21+
}
22+
23+
// MutationsBasicDec docs example.
24+
func MutationsBasicDec(ctx context.Context, repo rel.Repository) error {
25+
var book Book
26+
27+
/// [basic-dec]
28+
err := repo.Update(ctx, &book, rel.DecBy("stock", 2))
29+
/// [basic-dec]
30+
31+
return err
32+
}
33+
34+
// MutationsBasicFragment docs example.
35+
func MutationsBasicFragment(ctx context.Context, repo rel.Repository) error {
36+
var book Book
37+
38+
/// [basic-fragment]
39+
err := repo.Update(ctx, &book, rel.SetFragment("title=?", "REL for dummies"))
40+
/// [basic-fragment]
41+
42+
return err
43+
}
44+
45+
// MutationsStructset docs example.
46+
func MutationsStructset(ctx context.Context, repo rel.Repository) error {
47+
var book Book
48+
49+
/// [structset]
50+
structset := rel.NewStructset(&book, false)
51+
err := repo.Insert(ctx, &book, structset)
52+
/// [structset]
53+
54+
return err
55+
}
56+
57+
// MutationsChangeset docs example.
58+
func MutationsChangeset(ctx context.Context, repo rel.Repository) error {
59+
var book Book
60+
61+
/// [changeset]
62+
changeset := rel.NewChangeset(&book)
63+
book.Price = 10
64+
if changeset.FieldChanged("price") {
65+
book.Discount = false
66+
}
67+
68+
err := repo.Update(ctx, &book, changeset)
69+
/// [changeset]
70+
71+
return err
72+
}
73+
74+
// MutationsMap docs example.
75+
func MutationsMap(ctx context.Context, repo rel.Repository) error {
76+
var book Book
77+
78+
/// [map]
79+
data := rel.Map{
80+
"title": "Rel for dummies",
81+
"category": "education",
82+
"author": rel.Map{
83+
"name": "CZ2I28 Delta",
84+
},
85+
}
86+
87+
// Insert using map.
88+
err := repo.Insert(ctx, &book, data)
89+
/// [map]
90+
91+
return err
92+
}
93+
94+
// MutationsReload docs example.
95+
func MutationsReload(ctx context.Context, repo rel.Repository) error {
96+
var book Book
97+
98+
/// [reload]
99+
err := repo.Update(ctx, &book,
100+
rel.Set("title", "REL for Dummies"),
101+
rel.Reload(true),
102+
)
103+
/// [reload]
104+
105+
return err
106+
}
107+
108+
// MutationsCascade docs example.
109+
func MutationsCascade(ctx context.Context, repo rel.Repository) error {
110+
var book Book
111+
112+
/// [cascade]
113+
err := repo.Insert(ctx, &book, rel.Cascade(false))
114+
/// [cascade]
115+
116+
return err
117+
}
118+
119+
// MutationsDeleteCascade docs example.
120+
func MutationsDeleteCascade(ctx context.Context, repo rel.Repository) error {
121+
var book Book
122+
123+
/// [delete-cascade]
124+
err := repo.Delete(ctx, &book, rel.Cascade(true))
125+
/// [delete-cascade]
126+
127+
return err
128+
}

0 commit comments

Comments
 (0)