1
1
extern crate couchbase_lite;
2
2
extern crate regex;
3
3
4
- use couchbase_lite:: index:: ValueIndexConfiguration ;
4
+ use couchbase_lite:: index:: { ValueIndexConfiguration , ArrayIndexConfiguration } ;
5
5
use regex:: Regex ;
6
6
7
7
use self :: couchbase_lite:: * ;
@@ -65,6 +65,90 @@ fn query() {
65
65
} ) ;
66
66
}
67
67
68
+ #[ test]
69
+ fn parameters ( ) {
70
+ utils:: with_db ( |db| {
71
+ let mut doc = Document :: new_with_id ( "id1" ) ;
72
+ let mut props = doc. mutable_properties ( ) ;
73
+ props. at ( "bool" ) . put_bool ( true ) ;
74
+ props. at ( "f64" ) . put_f64 ( 3.1 ) ;
75
+ props. at ( "i64" ) . put_i64 ( 3 ) ;
76
+ props. at ( "string" ) . put_string ( "allo" ) ;
77
+ db. save_document_with_concurency_control ( & mut doc, ConcurrencyControl :: FailOnConflict )
78
+ . expect ( "save" ) ;
79
+
80
+ let query = Query :: new (
81
+ db,
82
+ QueryLanguage :: N1QL ,
83
+ "SELECT _.* FROM _ \
84
+ WHERE _.bool=$bool \
85
+ AND _.f64=$f64 \
86
+ AND _.i64=$i64 \
87
+ AND _.string=$string",
88
+ )
89
+ . expect ( "create query" ) ;
90
+
91
+ let mut params = MutableDict :: new ( ) ;
92
+ params. at ( "bool" ) . put_bool ( true ) ;
93
+ params. at ( "f64" ) . put_f64 ( 3.1 ) ;
94
+ params. at ( "i64" ) . put_i64 ( 3 ) ;
95
+ params. at ( "string" ) . put_string ( "allo" ) ;
96
+ query. set_parameters ( & params) ;
97
+
98
+ let params = query. parameters ( ) ;
99
+ assert_eq ! ( params. get( "bool" ) . as_bool( ) , Some ( true ) ) ;
100
+ assert_eq ! ( params. get( "f64" ) . as_f64( ) , Some ( 3.1 ) ) ;
101
+ assert_eq ! ( params. get( "i64" ) . as_i64( ) , Some ( 3 ) ) ;
102
+ assert_eq ! ( params. get( "string" ) . as_string( ) , Some ( "allo" ) ) ;
103
+
104
+ assert_eq ! ( query. execute( ) . unwrap( ) . count( ) , 1 ) ;
105
+ } ) ;
106
+ }
107
+
108
+ #[ test]
109
+ fn get_index ( ) {
110
+ utils:: with_db ( |db| {
111
+ // Default collection
112
+ let default_collection = db. default_collection ( ) . unwrap ( ) . unwrap ( ) ;
113
+ assert ! ( default_collection
114
+ . create_index(
115
+ "new_index1" ,
116
+ & ValueIndexConfiguration :: new( QueryLanguage :: JSON , r#"[[".someField"]]"# ) ,
117
+ )
118
+ . unwrap( ) ) ;
119
+
120
+ let index1 = default_collection. get_index ( "new_index1" ) . unwrap ( ) ;
121
+ assert_eq ! ( index1. name( ) , "new_index1" ) ;
122
+ assert_eq ! (
123
+ index1. collection( ) . full_name( ) ,
124
+ default_collection. full_name( )
125
+ ) ;
126
+
127
+ // New collection
128
+ let new_coll = db
129
+ . create_collection ( String :: from ( "coll" ) , String :: from ( "scop" ) )
130
+ . unwrap ( ) ;
131
+
132
+ assert ! ( new_coll
133
+ . create_index(
134
+ "new_index2" ,
135
+ & ValueIndexConfiguration :: new( QueryLanguage :: JSON , r#"[[".someField2"]]"# ) ,
136
+ )
137
+ . unwrap( ) ) ;
138
+
139
+ let index2 = new_coll. get_index ( "new_index2" ) . unwrap ( ) ;
140
+ assert_eq ! ( index2. name( ) , "new_index2" ) ;
141
+ assert_eq ! ( index2. collection( ) . full_name( ) , new_coll. full_name( ) ) ;
142
+ } )
143
+ }
144
+
145
+ fn get_index_name_from_explain ( explain : & str ) -> Option < String > {
146
+ Regex :: new ( r"USING INDEX (\w+) " )
147
+ . unwrap ( )
148
+ . captures ( explain)
149
+ . map ( |c| c. get ( 1 ) . unwrap ( ) . as_str ( ) . to_string ( ) )
150
+ }
151
+
68
152
#[ test]
69
153
fn full_index ( ) {
70
154
utils:: with_db ( |db| {
@@ -88,12 +172,7 @@ fn full_index() {
88
172
)
89
173
. expect ( "create query" ) ;
90
174
91
- let index = Regex :: new ( r"USING INDEX (\w+) " )
92
- . unwrap ( )
93
- . captures ( & query. explain ( ) . unwrap ( ) )
94
- . map ( |c| c. get ( 1 ) . unwrap ( ) . as_str ( ) . to_string ( ) )
95
- . unwrap ( ) ;
96
-
175
+ let index = get_index_name_from_explain ( & query. explain ( ) . unwrap ( ) ) . unwrap ( ) ;
97
176
assert_eq ! ( index, "new_index" ) ;
98
177
99
178
// Check index not used
@@ -148,12 +227,7 @@ fn partial_index() {
148
227
)
149
228
. expect ( "create query" ) ;
150
229
151
- let index = Regex :: new ( r"USING INDEX (\w+) " )
152
- . unwrap ( )
153
- . captures ( & query. explain ( ) . unwrap ( ) )
154
- . map ( |c| c. get ( 1 ) . unwrap ( ) . as_str ( ) . to_string ( ) )
155
- . unwrap ( ) ;
156
-
230
+ let index = get_index_name_from_explain ( & query. explain ( ) . unwrap ( ) ) . unwrap ( ) ;
157
231
assert_eq ! ( index, "new_index" ) ;
158
232
159
233
// Check index not used
@@ -174,41 +248,95 @@ fn partial_index() {
174
248
}
175
249
176
250
#[ test]
177
- fn parameters ( ) {
251
+ fn array_index ( ) {
178
252
utils:: with_db ( |db| {
179
- let mut doc = Document :: new_with_id ( "id1" ) ;
180
- let mut props = doc. mutable_properties ( ) ;
181
- props. at ( "bool" ) . put_bool ( true ) ;
182
- props. at ( "f64" ) . put_f64 ( 3.1 ) ;
183
- props. at ( "i64" ) . put_i64 ( 3 ) ;
184
- props. at ( "string" ) . put_string ( "allo" ) ;
185
- db. save_document_with_concurency_control ( & mut doc, ConcurrencyControl :: FailOnConflict )
186
- . expect ( "save" ) ;
253
+ let mut default_collection = db. default_collection ( ) . unwrap ( ) . unwrap ( ) ;
254
+
255
+ // Add one document
256
+ let mut doc = Document :: new ( ) ;
257
+ doc. set_properties_as_json (
258
+ r#"{
259
+ "name":"Sam",
260
+ "contacts":[
261
+ {
262
+ "type":"primary",
263
+ "address":{"street":"1 St","city":"San Pedro","state":"CA"},
264
+ "phones":[
265
+ {"type":"home","number":"310-123-4567"},
266
+ {"type":"mobile","number":"310-123-6789"}
267
+ ]
268
+ },
269
+ {
270
+ "type":"secondary",
271
+ "address":{"street":"5 St","city":"Seattle","state":"WA"},
272
+ "phones":[
273
+ {"type":"home","number":"206-123-4567"},
274
+ {"type":"mobile","number":"206-123-6789"}
275
+ ]
276
+ }
277
+ ],
278
+ "likes":["soccer","travel"]
279
+ }"# ,
280
+ )
281
+ . unwrap ( ) ;
282
+ default_collection. save_document ( & mut doc) . unwrap ( ) ;
283
+
284
+ // Index with one level of unnest
285
+ let index_configuration = ArrayIndexConfiguration :: new ( QueryLanguage :: N1QL , "likes" , "" ) ;
286
+
287
+ assert ! ( default_collection
288
+ . create_array_index( "one_level" , & index_configuration, )
289
+ . unwrap( ) ) ;
187
290
188
291
let query = Query :: new (
189
292
db,
190
293
QueryLanguage :: N1QL ,
191
- "SELECT _.* FROM _ \
192
- WHERE _.bool=$bool \
193
- AND _.f64=$f64 \
194
- AND _.i64=$i64 \
195
- AND _.string=$string",
294
+ "SELECT _.name, _like FROM _ UNNEST _.likes as _like WHERE _like = 'travel'" ,
196
295
)
197
- . expect ( "create query" ) ;
296
+ . unwrap ( ) ;
198
297
199
- let mut params = MutableDict :: new ( ) ;
200
- params. at ( "bool" ) . put_bool ( true ) ;
201
- params. at ( "f64" ) . put_f64 ( 3.1 ) ;
202
- params. at ( "i64" ) . put_i64 ( 3 ) ;
203
- params. at ( "string" ) . put_string ( "allo" ) ;
204
- query. set_parameters ( & params) ;
298
+ let index = get_index_name_from_explain ( & query. explain ( ) . unwrap ( ) ) . unwrap ( ) ;
299
+ assert_eq ! ( index, "one_level" ) ;
205
300
206
- let params = query. parameters ( ) ;
207
- assert_eq ! ( params. get( "bool" ) . as_bool( ) , Some ( true ) ) ;
208
- assert_eq ! ( params. get( "f64" ) . as_f64( ) , Some ( 3.1 ) ) ;
209
- assert_eq ! ( params. get( "i64" ) . as_i64( ) , Some ( 3 ) ) ;
210
- assert_eq ! ( params. get( "string" ) . as_string( ) , Some ( "allo" ) ) ;
301
+ let mut result = query. execute ( ) . unwrap ( ) ;
302
+ let row = result. next ( ) . unwrap ( ) ;
303
+ assert_eq ! ( row. as_array( ) . to_json( ) , r#"["Sam","travel"]"# ) ;
211
304
212
- assert_eq ! ( query. execute( ) . unwrap( ) . count( ) , 1 ) ;
213
- } ) ;
305
+ assert ! ( result. next( ) . is_none( ) ) ;
306
+
307
+ // Index with two levels of unnest
308
+ /*let index_configuration = ArrayIndexConfiguration::new(
309
+ QueryLanguage::N1QL,
310
+ "contacts[].phones",
311
+ "",//"type",
312
+ );
313
+
314
+ assert!(default_collection
315
+ .create_array_index(
316
+ "myindex",
317
+ &index_configuration,
318
+ ).unwrap()
319
+ );
320
+
321
+ let query = Query::new(
322
+ db,
323
+ QueryLanguage::N1QL,
324
+ r#"SELECT _.name, contact.type, phone.number
325
+ FROM _
326
+ UNNEST _.contacts as contact
327
+ UNNEST contact.phones as phone
328
+ WHERE phone.type = 'mobile'"#
329
+ ).unwrap();
330
+
331
+ println!("Explain: {}", query.explain().unwrap());
332
+
333
+ let index = get_index_name_from_explain(&query.explain().unwrap()).unwrap();
334
+ assert_eq!(index, "two_levels");
335
+
336
+ let mut result = query.execute().unwrap();
337
+ let row = result.next().unwrap();
338
+ assert_eq!(row.as_array().to_json(), r#"["Sam","travel"]"#);
339
+
340
+ assert!(result.next().is_none());*/
341
+ } )
214
342
}
0 commit comments