11extern crate couchbase_lite;
22extern crate regex;
33
4- use couchbase_lite:: index:: ValueIndexConfiguration ;
4+ use couchbase_lite:: index:: { ValueIndexConfiguration , ArrayIndexConfiguration } ;
55use regex:: Regex ;
66
77use self :: couchbase_lite:: * ;
@@ -65,6 +65,90 @@ fn query() {
6565 } ) ;
6666}
6767
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+
68152#[ test]
69153fn full_index ( ) {
70154 utils:: with_db ( |db| {
@@ -88,12 +172,7 @@ fn full_index() {
88172 )
89173 . expect ( "create query" ) ;
90174
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 ( ) ;
97176 assert_eq ! ( index, "new_index" ) ;
98177
99178 // Check index not used
@@ -148,12 +227,7 @@ fn partial_index() {
148227 )
149228 . expect ( "create query" ) ;
150229
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 ( ) ;
157231 assert_eq ! ( index, "new_index" ) ;
158232
159233 // Check index not used
@@ -174,41 +248,95 @@ fn partial_index() {
174248}
175249
176250#[ test]
177- fn parameters ( ) {
251+ fn array_index ( ) {
178252 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( ) ) ;
187290
188291 let query = Query :: new (
189292 db,
190293 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'" ,
196295 )
197- . expect ( "create query" ) ;
296+ . unwrap ( ) ;
198297
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" ) ;
205300
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"]"# ) ;
211304
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+ } )
214342}
0 commit comments