@@ -7,11 +7,15 @@ use diesel::pg::Pg;
7
7
use diesel:: prelude:: * ;
8
8
use juniper:: { ExecutionResult , Executor , GraphQLInputObject , Selection , Value } ;
9
9
use wundergraph:: prelude:: * ;
10
- use wundergraph:: query_builder:: mutations:: { HandleBatchInsert , HandleInsert } ;
10
+ use wundergraph:: query_builder:: mutations:: { HandleBatchInsert , HandleInsert , HandleUpdate } ;
11
11
use wundergraph:: query_builder:: selection:: LoadingHandler ;
12
12
use wundergraph:: scalar:: WundergraphScalarValue ;
13
13
14
- #[ derive( WundergraphEntity , Identifiable , Debug ) ]
14
+ mod post_at_version;
15
+
16
+ use self :: post_at_version:: * ;
17
+
18
+ #[ derive( WundergraphEntity , Identifiable , Debug , Clone ) ]
15
19
#[ table_name = "users" ]
16
20
pub struct User {
17
21
id : i32 ,
@@ -21,7 +25,7 @@ pub struct User {
21
25
comments : HasMany < Comment , comments:: author > ,
22
26
}
23
27
24
- #[ derive( WundergraphEntity , Identifiable , Debug ) ]
28
+ #[ derive( WundergraphEntity , Identifiable , Debug , Clone ) ]
25
29
#[ table_name = "posts" ]
26
30
pub struct Post {
27
31
id : i32 ,
@@ -33,21 +37,24 @@ pub struct Post {
33
37
post_state : PostState ,
34
38
}
35
39
36
- #[ derive( WundergraphEntity , Identifiable , Debug ) ]
40
+ #[ derive( WundergraphEntity , Identifiable , Debug , Clone ) ]
37
41
#[ table_name = "comments" ]
38
42
pub struct Comment {
39
43
id : i32 ,
40
44
comment : String ,
41
45
published_at : DateTime < Utc > ,
42
46
author : HasOne < i32 , User > ,
43
47
post : HasOne < i32 , Post > ,
48
+ #[ column_name = "post" ]
49
+ posts_at_version : HasOne < i32 , PostAtVersion > ,
44
50
}
45
51
46
52
wundergraph:: query_object! {
47
53
Query {
48
54
User ,
49
55
Post ,
50
56
Comment ,
57
+ PostAtVersion ( version: Option <i32 >) ,
51
58
}
52
59
}
53
60
@@ -58,7 +65,7 @@ pub struct UserChangeset {
58
65
name : String ,
59
66
}
60
67
61
- #[ derive( GraphQLInputObject , Identifiable , AsChangeset ) ]
68
+ #[ derive( GraphQLInputObject , Identifiable ) ]
62
69
#[ table_name = "posts" ]
63
70
pub struct PostChangeset {
64
71
id : i32 ,
@@ -100,6 +107,8 @@ impl HandleInsert<Post, NewPost, Pg, PgConnection> for posts::table {
100
107
posts:: content. eq ( insertable. content ) ,
101
108
posts:: author. eq ( insertable. author ) ,
102
109
posts:: post_state. eq ( PostState :: Draft ) ,
110
+ posts:: version_start. eq ( 0 ) ,
111
+ posts:: version_end. eq ( Option :: < i32 > :: None ) ,
103
112
) )
104
113
. returning ( posts:: id)
105
114
. get_result :: < i32 > ( conn) ?;
@@ -133,6 +142,8 @@ impl HandleBatchInsert<Post, NewPost, Pg, PgConnection> for posts::table {
133
142
posts:: content. eq ( content) ,
134
143
posts:: author. eq ( author) ,
135
144
posts:: post_state. eq ( PostState :: Draft ) ,
145
+ posts:: version_start. eq ( 0 ) ,
146
+ posts:: version_end. eq ( Option :: < i32 > :: None ) ,
136
147
)
137
148
} ,
138
149
)
@@ -152,6 +163,54 @@ impl HandleBatchInsert<Post, NewPost, Pg, PgConnection> for posts::table {
152
163
}
153
164
}
154
165
166
+ impl HandleUpdate < Post , PostChangeset , Pg , PgConnection > for posts:: table {
167
+ fn handle_update (
168
+ selection : Option < & ' _ [ Selection < ' _ , WundergraphScalarValue > ] > ,
169
+ executor : & Executor < PgConnection , WundergraphScalarValue > ,
170
+ update : & PostChangeset ,
171
+ ) -> ExecutionResult < WundergraphScalarValue > {
172
+ let ctx = executor. context ( ) ;
173
+ let conn = ctx. get_connection ( ) ;
174
+ conn. transaction ( || {
175
+ let current_version = posts:: table
176
+ . select ( diesel:: dsl:: max ( posts:: version_start) )
177
+ . filter ( posts:: id. eq ( update. id ) )
178
+ . get_result :: < Option < i32 > > ( conn) ?
179
+ . unwrap_or ( 0 ) ;
180
+
181
+ diesel:: update (
182
+ posts:: table. filter (
183
+ posts:: id
184
+ . eq ( update. id )
185
+ . and ( posts:: version_start. eq ( current_version) ) ,
186
+ ) ,
187
+ )
188
+ . set ( posts:: version_end. eq ( Some ( current_version + 1 ) ) )
189
+ . execute ( conn) ?;
190
+
191
+ let inserted = diesel:: insert_into ( posts:: table)
192
+ . values ( (
193
+ posts:: id. eq ( update. id ) ,
194
+ posts:: title. eq ( & update. title ) ,
195
+ posts:: content. eq ( & update. content ) ,
196
+ posts:: author. eq ( update. author ) ,
197
+ posts:: post_state. eq ( update. post_state ) ,
198
+ posts:: version_start. eq ( current_version + 1 ) ,
199
+ posts:: version_end. eq ( Option :: < i32 > :: None ) ,
200
+ ) )
201
+ . returning ( posts:: id)
202
+ . get_result :: < i32 > ( conn) ?;
203
+
204
+ let look_ahead = executor. look_ahead ( ) ;
205
+
206
+ let query = <Post as LoadingHandler < _ , PgConnection > >:: build_query ( & [ ] , & look_ahead) ?
207
+ . filter ( posts:: id. eq ( inserted) ) ;
208
+ let items = Post :: load ( & look_ahead, selection, executor, query) ?;
209
+ Ok ( items. into_iter ( ) . next ( ) . unwrap_or ( Value :: Null ) )
210
+ } )
211
+ }
212
+ }
213
+
155
214
wundergraph:: mutation_object! {
156
215
Mutation {
157
216
User ( insert = NewUser , update = UserChangeset , delete = true ) ,
0 commit comments