1
1
#![ allow( dead_code) ]
2
2
use crate :: handler:: { CommandExecutionError , Request } ;
3
- use crate :: utils :: expand_fields ;
4
- use crate :: { commands:: Handler , pg:: SqlParam } ;
3
+ use crate :: parser :: parse_update ;
4
+ use crate :: { commands:: Handler , pg:: SqlParam , pg :: UpdateResult } ;
5
5
use bson:: { doc, Bson , Document } ;
6
6
7
7
pub struct Update { }
8
8
9
- #[ derive( Debug , Clone , PartialEq ) ]
10
- pub enum UpdateOper {
11
- Update ( Vec < UpdateDoc > ) ,
12
- Replace ( Document ) ,
13
- }
14
-
15
- #[ derive( Debug , Clone , PartialEq ) ]
16
- pub enum UpdateDoc {
17
- Inc ( Document ) ,
18
- Set ( Document ) ,
19
- Unset ( Document ) ,
20
- }
21
-
22
- #[ derive( Debug , Clone , PartialEq ) ]
23
- pub struct InvalidUpdateError {
24
- reason : String ,
25
- }
26
-
27
- impl InvalidUpdateError {
28
- pub fn new ( reason : String ) -> Self {
29
- InvalidUpdateError { reason }
30
- }
31
- }
32
-
33
- impl UpdateDoc {
34
- fn validate ( & self ) -> Result < UpdateDoc , InvalidUpdateError > {
35
- match self {
36
- UpdateDoc :: Set ( doc) => match expand_fields ( doc) {
37
- Ok ( u) => Ok ( UpdateDoc :: Set ( u) ) ,
38
- Err ( e) => {
39
- return Err ( InvalidUpdateError :: new ( format ! (
40
- "Cannot update '{}' and '{}' at the same time" ,
41
- e. target, e. source
42
- ) ) ) ;
43
- }
44
- } ,
45
- UpdateDoc :: Unset ( doc) => Ok ( UpdateDoc :: Unset ( doc. clone ( ) ) ) ,
46
- UpdateDoc :: Inc ( u) => Ok ( UpdateDoc :: Inc ( u. clone ( ) ) ) ,
47
- // _ => {
48
- // return Err(InvalidUpdateError::new(format!(
49
- // "Unhandled update operation: {:?}",
50
- // self
51
- // )));
52
- // }
53
- }
54
- }
55
- }
56
-
57
9
impl Handler for Update {
58
10
fn new ( ) -> Self {
59
11
Update { }
@@ -85,9 +37,22 @@ impl Handler for Update {
85
37
return Err ( CommandExecutionError :: new ( format ! ( "{:?}" , update_doc) ) ) ;
86
38
}
87
39
88
- n += client
89
- . update ( & sp, Some ( q) , update_doc. unwrap ( ) , upsert, multi)
40
+ let result = client
41
+ . update (
42
+ & sp,
43
+ Some ( q) ,
44
+ None ,
45
+ update_doc. unwrap ( ) ,
46
+ upsert,
47
+ multi,
48
+ false ,
49
+ )
90
50
. unwrap ( ) ;
51
+
52
+ match result {
53
+ UpdateResult :: Count ( total) => n += total,
54
+ UpdateResult :: Document ( _) => n += 1 ,
55
+ }
91
56
}
92
57
93
58
Ok ( doc ! {
@@ -97,104 +62,3 @@ impl Handler for Update {
97
62
} )
98
63
}
99
64
}
100
-
101
- fn parse_update ( doc : & Document ) -> Result < UpdateOper , InvalidUpdateError > {
102
- let mut res: Vec < UpdateDoc > = vec ! [ ] ;
103
- if !doc. keys ( ) . any ( |k| k. starts_with ( "$" ) ) {
104
- return Ok ( UpdateOper :: Replace ( doc. clone ( ) ) ) ;
105
- }
106
- for ( key, value) in doc. iter ( ) {
107
- match key. as_str ( ) {
108
- "$set" => {
109
- let expanded_doc = match expand_fields ( value. as_document ( ) . unwrap ( ) ) {
110
- Ok ( doc) => doc,
111
- Err ( e) => {
112
- return Err ( InvalidUpdateError :: new ( format ! (
113
- "Cannot update '{}' and '{}' at the same time" ,
114
- e. target, e. source
115
- ) ) ) ;
116
- }
117
- } ;
118
- match UpdateDoc :: Set ( expanded_doc) . validate ( ) {
119
- Ok ( update_doc) => res. push ( update_doc) ,
120
- Err ( e) => {
121
- return Err ( InvalidUpdateError :: new ( format ! ( "{:?}" , e) ) ) ;
122
- }
123
- }
124
- }
125
- "$unset" => {
126
- let expanded_doc = match expand_fields ( value. as_document ( ) . unwrap ( ) ) {
127
- Ok ( doc) => doc,
128
- Err ( e) => {
129
- return Err ( InvalidUpdateError :: new ( format ! (
130
- "Cannot update '{}' and '{}' at the same time" ,
131
- e. target, e. source
132
- ) ) ) ;
133
- }
134
- } ;
135
- match UpdateDoc :: Unset ( expanded_doc) . validate ( ) {
136
- Ok ( update_doc) => res. push ( update_doc) ,
137
- Err ( e) => {
138
- return Err ( InvalidUpdateError :: new ( format ! ( "{:?}" , e) ) ) ;
139
- }
140
- }
141
- }
142
- "$inc" => {
143
- let expanded_doc = match expand_fields ( value. as_document ( ) . unwrap ( ) ) {
144
- Ok ( doc) => doc,
145
- Err ( e) => {
146
- return Err ( InvalidUpdateError :: new ( format ! (
147
- "Cannot update '{}' and '{}' at the same time" ,
148
- e. target, e. source
149
- ) ) ) ;
150
- }
151
- } ;
152
- match UpdateDoc :: Inc ( expanded_doc) . validate ( ) {
153
- Ok ( update_doc) => res. push ( update_doc) ,
154
- Err ( e) => {
155
- return Err ( InvalidUpdateError :: new ( format ! ( "{:?}" , e) ) ) ;
156
- }
157
- }
158
- }
159
- _ => {
160
- if key. starts_with ( "$" ) || res. len ( ) > 0 {
161
- return Err ( InvalidUpdateError :: new ( format ! (
162
- "Unknown modifier: {}" ,
163
- key
164
- ) ) ) ;
165
- }
166
- }
167
- }
168
- }
169
- Ok ( UpdateOper :: Update ( res) )
170
- }
171
-
172
- #[ cfg( test) ]
173
- mod tests {
174
- use super :: * ;
175
-
176
- #[ test]
177
- fn test_parse_update ( ) {
178
- let set_doc = doc ! { "$set" : { "a" : 1 } } ;
179
- let repl_doc = doc ! { "b" : 2 , "c" : 8 , "d" : 9 } ;
180
- let unknown_doc = doc ! { "$xyz" : { "a" : 1 } } ;
181
- let mixed_doc = doc ! { "$set" : { "x" : 1 } , "b" : 2 } ;
182
-
183
- assert_eq ! (
184
- parse_update( & set_doc) . unwrap( ) ,
185
- UpdateOper :: Update ( vec![ UpdateDoc :: Set ( doc! { "a" : 1 } ) ] )
186
- ) ;
187
- assert_eq ! (
188
- parse_update( & repl_doc) . unwrap( ) ,
189
- UpdateOper :: Replace ( repl_doc)
190
- ) ;
191
- assert_eq ! (
192
- parse_update( & unknown_doc) . unwrap_err( ) ,
193
- InvalidUpdateError :: new( "Unknown modifier: $xyz" . to_string( ) )
194
- ) ;
195
- assert_eq ! (
196
- parse_update( & mixed_doc) . unwrap_err( ) ,
197
- InvalidUpdateError :: new( "Unknown modifier: b" . to_string( ) )
198
- ) ;
199
- }
200
- }
0 commit comments