Beispiel #1
0
		/// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception>
		public virtual void TestViewQuery()
		{
			PutDocs(database);
			View view = CreateView(database);
			view.UpdateIndex();
			// Query all rows:
			QueryOptions options = new QueryOptions();
			IList<QueryRow> rows = view.QueryWithOptions(options);
			IList<object> expectedRows = new AList<object>();
			IDictionary<string, object> dict5 = new Dictionary<string, object>();
			dict5.Put("id", "55555");
			dict5.Put("key", "five");
			expectedRows.AddItem(dict5);
			IDictionary<string, object> dict4 = new Dictionary<string, object>();
			dict4.Put("id", "44444");
			dict4.Put("key", "four");
			expectedRows.AddItem(dict4);
			IDictionary<string, object> dict1 = new Dictionary<string, object>();
			dict1.Put("id", "11111");
			dict1.Put("key", "one");
			expectedRows.AddItem(dict1);
			IDictionary<string, object> dict3 = new Dictionary<string, object>();
			dict3.Put("id", "33333");
			dict3.Put("key", "three");
			expectedRows.AddItem(dict3);
			IDictionary<string, object> dict2 = new Dictionary<string, object>();
			dict2.Put("id", "22222");
			dict2.Put("key", "two");
			expectedRows.AddItem(dict2);
			NUnit.Framework.Assert.AreEqual(5, rows.Count);
			NUnit.Framework.Assert.AreEqual(dict5.Get("key"), rows[0].GetKey());
			NUnit.Framework.Assert.AreEqual(dict5.Get("value"), rows[0].GetValue());
			NUnit.Framework.Assert.AreEqual(dict4.Get("key"), rows[1].GetKey());
			NUnit.Framework.Assert.AreEqual(dict4.Get("value"), rows[1].GetValue());
			NUnit.Framework.Assert.AreEqual(dict1.Get("key"), rows[2].GetKey());
			NUnit.Framework.Assert.AreEqual(dict1.Get("value"), rows[2].GetValue());
			NUnit.Framework.Assert.AreEqual(dict3.Get("key"), rows[3].GetKey());
			NUnit.Framework.Assert.AreEqual(dict3.Get("value"), rows[3].GetValue());
			NUnit.Framework.Assert.AreEqual(dict2.Get("key"), rows[4].GetKey());
			NUnit.Framework.Assert.AreEqual(dict2.Get("value"), rows[4].GetValue());
			// Start/end key query:
			options = new QueryOptions();
			options.SetStartKey("a");
			options.SetEndKey("one");
			rows = view.QueryWithOptions(options);
			expectedRows = new AList<object>();
			expectedRows.AddItem(dict5);
			expectedRows.AddItem(dict4);
			expectedRows.AddItem(dict1);
			NUnit.Framework.Assert.AreEqual(3, rows.Count);
			NUnit.Framework.Assert.AreEqual(dict5.Get("key"), rows[0].GetKey());
			NUnit.Framework.Assert.AreEqual(dict5.Get("value"), rows[0].GetValue());
			NUnit.Framework.Assert.AreEqual(dict4.Get("key"), rows[1].GetKey());
			NUnit.Framework.Assert.AreEqual(dict4.Get("value"), rows[1].GetValue());
			NUnit.Framework.Assert.AreEqual(dict1.Get("key"), rows[2].GetKey());
			NUnit.Framework.Assert.AreEqual(dict1.Get("value"), rows[2].GetValue());
			// Start/end query without inclusive end:
			options.SetInclusiveEnd(false);
			rows = view.QueryWithOptions(options);
			expectedRows = new AList<object>();
			expectedRows.AddItem(dict5);
			expectedRows.AddItem(dict4);
			NUnit.Framework.Assert.AreEqual(2, rows.Count);
			NUnit.Framework.Assert.AreEqual(dict5.Get("key"), rows[0].GetKey());
			NUnit.Framework.Assert.AreEqual(dict5.Get("value"), rows[0].GetValue());
			NUnit.Framework.Assert.AreEqual(dict4.Get("key"), rows[1].GetKey());
			NUnit.Framework.Assert.AreEqual(dict4.Get("value"), rows[1].GetValue());
			// Reversed:
			options.SetDescending(true);
			options.SetStartKey("o");
			options.SetEndKey("five");
			options.SetInclusiveEnd(true);
			rows = view.QueryWithOptions(options);
			expectedRows = new AList<object>();
			expectedRows.AddItem(dict4);
			expectedRows.AddItem(dict5);
			NUnit.Framework.Assert.AreEqual(2, rows.Count);
			NUnit.Framework.Assert.AreEqual(dict4.Get("key"), rows[0].GetKey());
			NUnit.Framework.Assert.AreEqual(dict4.Get("value"), rows[0].GetValue());
			NUnit.Framework.Assert.AreEqual(dict5.Get("key"), rows[1].GetKey());
			NUnit.Framework.Assert.AreEqual(dict5.Get("value"), rows[1].GetValue());
			// Reversed, no inclusive end:
			options.SetInclusiveEnd(false);
			rows = view.QueryWithOptions(options);
			expectedRows = new AList<object>();
			expectedRows.AddItem(dict4);
			NUnit.Framework.Assert.AreEqual(1, rows.Count);
			NUnit.Framework.Assert.AreEqual(dict4.Get("key"), rows[0].GetKey());
			NUnit.Framework.Assert.AreEqual(dict4.Get("value"), rows[0].GetValue());
			// Specific keys:
			options = new QueryOptions();
			IList<object> keys = new AList<object>();
			keys.AddItem("two");
			keys.AddItem("four");
			options.SetKeys(keys);
			rows = view.QueryWithOptions(options);
			expectedRows = new AList<object>();
			expectedRows.AddItem(dict4);
			expectedRows.AddItem(dict2);
			NUnit.Framework.Assert.AreEqual(2, rows.Count);
			NUnit.Framework.Assert.AreEqual(dict4.Get("key"), rows[0].GetKey());
			NUnit.Framework.Assert.AreEqual(dict4.Get("value"), rows[0].GetValue());
			NUnit.Framework.Assert.AreEqual(dict2.Get("key"), rows[1].GetKey());
			NUnit.Framework.Assert.AreEqual(dict2.Get("value"), rows[1].GetValue());
		}
Beispiel #2
0
		/// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception>
		public virtual void TestLargerViewQuery()
		{
			PutNDocs(database, 4);
			View view = CreateView(database);
			view.UpdateIndex();
			// Query all rows:
			QueryOptions options = new QueryOptions();
			Status status = new Status();
			IList<QueryRow> rows = view.QueryWithOptions(options);
		}
Beispiel #3
0
		/// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception>
		public virtual void TestViewLinkedDocs()
		{
			PutLinkedDocs(database);
			View view = database.GetView("linked");
			view.SetMapReduce(new _Mapper_1086(), null, "1");
			view.UpdateIndex();
			QueryOptions options = new QueryOptions();
			options.SetIncludeDocs(true);
			// required for linked documents
			IList<QueryRow> rows = view.QueryWithOptions(options);
			NUnit.Framework.Assert.IsNotNull(rows);
			NUnit.Framework.Assert.AreEqual(5, rows.Count);
			object[][] expected = new object[][] { new object[] { "22222", "hello", 0, null, 
				"22222" }, new object[] { "22222", "hello", 1, "11111", "11111" }, new object[] 
				{ "33333", "world", 0, null, "33333" }, new object[] { "33333", "world", 1, "22222"
				, "22222" }, new object[] { "33333", "world", 2, "11111", "11111" } };
			for (int i = 0; i < rows.Count; i++)
			{
				QueryRow row = rows[i];
				IDictionary<string, object> rowAsJson = row.AsJSONDictionary();
				Log.D(Tag, string.Empty + rowAsJson);
				IList<object> key = (IList<object>)rowAsJson.Get("key");
				IDictionary<string, object> doc = (IDictionary<string, object>)rowAsJson.Get("doc"
					);
				string id = (string)rowAsJson.Get("id");
				NUnit.Framework.Assert.AreEqual(expected[i][0], id);
				NUnit.Framework.Assert.AreEqual(2, key.Count);
				NUnit.Framework.Assert.AreEqual(expected[i][1], key[0]);
				NUnit.Framework.Assert.AreEqual(expected[i][2], key[1]);
				if (expected[i][3] == null)
				{
					NUnit.Framework.Assert.IsNull(row.GetValue());
				}
				else
				{
					NUnit.Framework.Assert.AreEqual(expected[i][3], ((IDictionary<string, object>)row
						.GetValue()).Get("_id"));
				}
				NUnit.Framework.Assert.AreEqual(expected[i][4], doc.Get("_id"));
			}
		}
Beispiel #4
0
		public int GetDeletedColumnIndex(QueryOptions options)
		{
			if (options.IsIncludeDocs())
			{
				return 5;
			}
			else
			{
				return 4;
			}
		}
Beispiel #5
0
        /// <summary>Queries the view.</summary>
        /// <remarks>Queries the view. Does NOT first update the index.</remarks>
        /// <param name="options">The options to use.</param>
        /// <returns>An array of QueryRow objects.</returns>
        /// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception>
        internal IEnumerable <QueryRow> QueryWithOptions(QueryOptions options)
        {
            if (options == null)
            {
                options = new QueryOptions();
            }

            Cursor           cursor = null;
            IList <QueryRow> rows   = new List <QueryRow>();

            try
            {
                cursor = ResultSetWithOptions(options);
                int groupLevel  = options.GetGroupLevel();
                var group       = options.IsGroup() || (groupLevel > 0);
                var reduce      = options.IsReduce() || group;
                var reduceBlock = Reduce;

                if (reduce && (reduceBlock == null) && !group)
                {
                    var msg = "Cannot use reduce option in view " + Name + " which has no reduce block defined";
                    Log.W(Database.Tag, msg);
                    throw new CouchbaseLiteException(StatusCode.BadRequest);
                }

                if (reduce || group)
                {
                    // Reduced or grouped query:
                    rows = ReducedQuery(cursor, group, groupLevel);
                }
                else
                {
                    // regular query
                    cursor.MoveToNext();
                    while (!cursor.IsAfterLast())
                    {
                        var lazyKey   = new Lazy <object>(() => FromJSON(cursor.GetBlob(0)));
                        var lazyValue = new Lazy <object>(() => FromJSON(cursor.GetBlob(1)));
                        // TODO: ditto
                        var docId        = cursor.GetString(2);
                        var sequenceLong = cursor.GetLong(3);
                        var sequence     = Convert.ToInt32(sequenceLong);

                        IDictionary <string, object> docContents = null;
                        if (options.IsIncludeDocs())
                        {
                            // http://wiki.apache.org/couchdb/Introduction_to_CouchDB_views#Linked_documents
                            if (lazyValue.Value is IDictionary <string, object> && ((IDictionary <string, object>)lazyValue.Value).ContainsKey("_id"))
                            {
                                var linkedDocId = (string)((IDictionary <string, object>)lazyValue.Value).Get("_id");
                                var linkedDoc   = Database.GetDocumentWithIDAndRev(linkedDocId, null, DocumentContentOptions.None);
                                docContents = linkedDoc.GetProperties();
                            }
                            else
                            {
                                var revId = cursor.GetString(4);
                                docContents = Database.DocumentPropertiesFromJSON(cursor.GetBlob(5), docId, revId, false, sequenceLong, options.GetContentOptions());
                            }
                        }
                        var row = new QueryRow(docId, sequence, lazyKey.Value, lazyValue.Value, docContents);
                        row.Database = Database;
                        rows.AddItem <QueryRow>(row);  // NOTE.ZJG: Change to `yield return row` to convert to a generator.
                        cursor.MoveToNext();
                    }
                }
            }
            catch (SQLException e)
            {
                var errMsg = string.Format("Error querying view: {0}", this);
                Log.E(Database.Tag, errMsg, e);
                throw new CouchbaseLiteException(errMsg, e, new Status(StatusCode.DbError));
            }
            finally
            {
                if (cursor != null)
                {
                    cursor.Close();
                }
            }
            return(rows);
        }
Beispiel #6
0
		/// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception>
		public virtual void TestViewGrouped()
		{
			IDictionary<string, object> docProperties1 = new Dictionary<string, object>();
			docProperties1.Put("_id", "1");
			docProperties1.Put("artist", "Gang Of Four");
			docProperties1.Put("album", "Entertainment!");
			docProperties1.Put("track", "Ether");
			docProperties1.Put("time", 231);
			PutDoc(database, docProperties1);
			IDictionary<string, object> docProperties2 = new Dictionary<string, object>();
			docProperties2.Put("_id", "2");
			docProperties2.Put("artist", "Gang Of Four");
			docProperties2.Put("album", "Songs Of The Free");
			docProperties2.Put("track", "I Love A Man In Uniform");
			docProperties2.Put("time", 248);
			PutDoc(database, docProperties2);
			IDictionary<string, object> docProperties3 = new Dictionary<string, object>();
			docProperties3.Put("_id", "3");
			docProperties3.Put("artist", "Gang Of Four");
			docProperties3.Put("album", "Entertainment!");
			docProperties3.Put("track", "Natural's Not In It");
			docProperties3.Put("time", 187);
			PutDoc(database, docProperties3);
			IDictionary<string, object> docProperties4 = new Dictionary<string, object>();
			docProperties4.Put("_id", "4");
			docProperties4.Put("artist", "PiL");
			docProperties4.Put("album", "Metal Box");
			docProperties4.Put("track", "Memories");
			docProperties4.Put("time", 309);
			PutDoc(database, docProperties4);
			IDictionary<string, object> docProperties5 = new Dictionary<string, object>();
			docProperties5.Put("_id", "5");
			docProperties5.Put("artist", "Gang Of Four");
			docProperties5.Put("album", "Entertainment!");
			docProperties5.Put("track", "Not Great Men");
			docProperties5.Put("time", 187);
			PutDoc(database, docProperties5);
			View view = database.GetView("grouper");
			view.SetMapReduce(new _Mapper_671(), new _Reducer_681(), "1");
			Status status = new Status();
			view.UpdateIndex();
			QueryOptions options = new QueryOptions();
			options.SetReduce(true);
			IList<QueryRow> rows = view.QueryWithOptions(options);
			IList<IDictionary<string, object>> expectedRows = new AList<IDictionary<string, object
				>>();
			IDictionary<string, object> row1 = new Dictionary<string, object>();
			row1.Put("key", null);
			row1.Put("value", 1162.0);
			expectedRows.AddItem(row1);
			NUnit.Framework.Assert.AreEqual(row1.Get("key"), rows[0].GetKey());
			NUnit.Framework.Assert.AreEqual(row1.Get("value"), rows[0].GetValue());
			//now group
			options.SetGroup(true);
			status = new Status();
			rows = view.QueryWithOptions(options);
			expectedRows = new AList<IDictionary<string, object>>();
			row1 = new Dictionary<string, object>();
			IList<string> key1 = new AList<string>();
			key1.AddItem("Gang Of Four");
			key1.AddItem("Entertainment!");
			key1.AddItem("Ether");
			row1.Put("key", key1);
			row1.Put("value", 231.0);
			expectedRows.AddItem(row1);
			IDictionary<string, object> row2 = new Dictionary<string, object>();
			IList<string> key2 = new AList<string>();
			key2.AddItem("Gang Of Four");
			key2.AddItem("Entertainment!");
			key2.AddItem("Natural's Not In It");
			row2.Put("key", key2);
			row2.Put("value", 187.0);
			expectedRows.AddItem(row2);
			IDictionary<string, object> row3 = new Dictionary<string, object>();
			IList<string> key3 = new AList<string>();
			key3.AddItem("Gang Of Four");
			key3.AddItem("Entertainment!");
			key3.AddItem("Not Great Men");
			row3.Put("key", key3);
			row3.Put("value", 187.0);
			expectedRows.AddItem(row3);
			IDictionary<string, object> row4 = new Dictionary<string, object>();
			IList<string> key4 = new AList<string>();
			key4.AddItem("Gang Of Four");
			key4.AddItem("Songs Of The Free");
			key4.AddItem("I Love A Man In Uniform");
			row4.Put("key", key4);
			row4.Put("value", 248.0);
			expectedRows.AddItem(row4);
			IDictionary<string, object> row5 = new Dictionary<string, object>();
			IList<string> key5 = new AList<string>();
			key5.AddItem("PiL");
			key5.AddItem("Metal Box");
			key5.AddItem("Memories");
			row5.Put("key", key5);
			row5.Put("value", 309.0);
			expectedRows.AddItem(row5);
			NUnit.Framework.Assert.AreEqual(row1.Get("key"), rows[0].GetKey());
			NUnit.Framework.Assert.AreEqual(row1.Get("value"), rows[0].GetValue());
			NUnit.Framework.Assert.AreEqual(row2.Get("key"), rows[1].GetKey());
			NUnit.Framework.Assert.AreEqual(row2.Get("value"), rows[1].GetValue());
			NUnit.Framework.Assert.AreEqual(row3.Get("key"), rows[2].GetKey());
			NUnit.Framework.Assert.AreEqual(row3.Get("value"), rows[2].GetValue());
			NUnit.Framework.Assert.AreEqual(row4.Get("key"), rows[3].GetKey());
			NUnit.Framework.Assert.AreEqual(row4.Get("value"), rows[3].GetValue());
			NUnit.Framework.Assert.AreEqual(row5.Get("key"), rows[4].GetKey());
			NUnit.Framework.Assert.AreEqual(row5.Get("value"), rows[4].GetValue());
			//group level 1
			options.SetGroupLevel(1);
			status = new Status();
			rows = view.QueryWithOptions(options);
			expectedRows = new AList<IDictionary<string, object>>();
			row1 = new Dictionary<string, object>();
			key1 = new AList<string>();
			key1.AddItem("Gang Of Four");
			row1.Put("key", key1);
			row1.Put("value", 853.0);
			expectedRows.AddItem(row1);
			row2 = new Dictionary<string, object>();
			key2 = new AList<string>();
			key2.AddItem("PiL");
			row2.Put("key", key2);
			row2.Put("value", 309.0);
			expectedRows.AddItem(row2);
			NUnit.Framework.Assert.AreEqual(row1.Get("key"), rows[0].GetKey());
			NUnit.Framework.Assert.AreEqual(row1.Get("value"), rows[0].GetValue());
			NUnit.Framework.Assert.AreEqual(row2.Get("key"), rows[1].GetKey());
			NUnit.Framework.Assert.AreEqual(row2.Get("value"), rows[1].GetValue());
			//group level 2
			options.SetGroupLevel(2);
			status = new Status();
			rows = view.QueryWithOptions(options);
			expectedRows = new AList<IDictionary<string, object>>();
			row1 = new Dictionary<string, object>();
			key1 = new AList<string>();
			key1.AddItem("Gang Of Four");
			key1.AddItem("Entertainment!");
			row1.Put("key", key1);
			row1.Put("value", 605.0);
			expectedRows.AddItem(row1);
			row2 = new Dictionary<string, object>();
			key2 = new AList<string>();
			key2.AddItem("Gang Of Four");
			key2.AddItem("Songs Of The Free");
			row2.Put("key", key2);
			row2.Put("value", 248.0);
			expectedRows.AddItem(row2);
			row3 = new Dictionary<string, object>();
			key3 = new AList<string>();
			key3.AddItem("PiL");
			key3.AddItem("Metal Box");
			row3.Put("key", key3);
			row3.Put("value", 309.0);
			expectedRows.AddItem(row3);
			NUnit.Framework.Assert.AreEqual(row1.Get("key"), rows[0].GetKey());
			NUnit.Framework.Assert.AreEqual(row1.Get("value"), rows[0].GetValue());
			NUnit.Framework.Assert.AreEqual(row2.Get("key"), rows[1].GetKey());
			NUnit.Framework.Assert.AreEqual(row2.Get("value"), rows[1].GetValue());
			NUnit.Framework.Assert.AreEqual(row3.Get("key"), rows[2].GetKey());
			NUnit.Framework.Assert.AreEqual(row3.Get("value"), rows[2].GetValue());
		}
Beispiel #7
0
		/// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception>
		public virtual void TestViewCollationRaw()
		{
			IList<object> list1 = new AList<object>();
			list1.AddItem("a");
			IList<object> list2 = new AList<object>();
			list2.AddItem("b");
			IList<object> list3 = new AList<object>();
			list3.AddItem("b");
			list3.AddItem("c");
			IList<object> list4 = new AList<object>();
			list4.AddItem("b");
			list4.AddItem("c");
			list4.AddItem("a");
			IList<object> list5 = new AList<object>();
			list5.AddItem("b");
			list5.AddItem("d");
			IList<object> list6 = new AList<object>();
			list6.AddItem("b");
			list6.AddItem("d");
			list6.AddItem("e");
			// Based on CouchDB's "view_collation.js" test
			IList<object> testKeys = new AList<object>();
			testKeys.AddItem(0);
			testKeys.AddItem(2.5);
			testKeys.AddItem(10);
			testKeys.AddItem(false);
			testKeys.AddItem(null);
			testKeys.AddItem(true);
			testKeys.AddItem(list1);
			testKeys.AddItem(list2);
			testKeys.AddItem(list3);
			testKeys.AddItem(list4);
			testKeys.AddItem(list5);
			testKeys.AddItem(list6);
			testKeys.AddItem(" ");
			testKeys.AddItem("A");
			testKeys.AddItem("B");
			testKeys.AddItem("_");
			testKeys.AddItem("a");
			testKeys.AddItem("aa");
			testKeys.AddItem("b");
			testKeys.AddItem("ba");
			testKeys.AddItem("bb");
			testKeys.AddItem("~");
			int i = 0;
			foreach (object key in testKeys)
			{
				IDictionary<string, object> docProperties = new Dictionary<string, object>();
				docProperties.Put("_id", Sharpen.Extensions.ToString(i++));
				docProperties.Put("name", key);
				PutDoc(database, docProperties);
			}
			View view = database.GetView("default/names");
			view.SetMapReduce(new _Mapper_1048(), null, "1.0");
			view.SetCollation(View.TDViewCollation.TDViewCollationRaw);
			QueryOptions options = new QueryOptions();
			IList<QueryRow> rows = view.QueryWithOptions(options);
			i = 0;
			foreach (QueryRow row in rows)
			{
				NUnit.Framework.Assert.AreEqual(testKeys[i++], row.GetKey());
			}
			database.Close();
		}
Beispiel #8
0
        /// <summary>Queries the view.</summary>
        /// <remarks>Queries the view. Does NOT first update the index.</remarks>
        /// <param name="options">The options to use.</param>
        /// <returns>An array of QueryRow objects.</returns>
        /// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception>
        internal IEnumerable<QueryRow> QueryWithOptions(QueryOptions options)
        {
            if (options == null) {
                options = new QueryOptions();
            }

            IEnumerable<QueryRow> iterator = null;
            if (false) {
                //TODO: Full text
            } else if (GroupOrReduce(options)) {
                iterator = Storage.ReducedQuery(options);
            } else {
                iterator = Storage.RegularQuery(options);
            }

            if (iterator != null) {
                Log.D(TAG, "Query {0}: Returning iterator", Name);
            } else {
                Log.D(TAG, "Query {0}: Failed", Name);
            }

            return iterator;
        }
Beispiel #9
0
        private bool GroupOrReduce(QueryOptions options) {
            if (options.Group|| options.GroupLevel> 0) {
                return true;
            }

            if (options.ReduceSpecified) {
                return options.Reduce;
            }

            return Reduce != null;
        }
Beispiel #10
0
		/// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception>
		public virtual void TestViewGrouped()
		{
			IDictionary<string, object> docProperties1 = new Dictionary<string, object>();
			docProperties1["_id"] = "1";
			docProperties1["artist"] = "Gang Of Four";
			docProperties1["album"] = "Entertainment!";
			docProperties1["track"] = "Ether";
			docProperties1["time"] = 231;
			PutDoc(database, docProperties1);
			IDictionary<string, object> docProperties2 = new Dictionary<string, object>();
			docProperties2["_id"] = "2";
			docProperties2["artist"] = "Gang Of Four";
			docProperties2["album"] = "Songs Of The Free";
			docProperties2["track"] = "I Love A Man In Uniform";
			docProperties2["time"] = 248;
			PutDoc(database, docProperties2);
			IDictionary<string, object> docProperties3 = new Dictionary<string, object>();
			docProperties3["_id"] = "3";
			docProperties3["artist"] = "Gang Of Four";
			docProperties3["album"] = "Entertainment!";
			docProperties3["track"] = "Natural's Not In It";
			docProperties3["time"] = 187;
			PutDoc(database, docProperties3);
			IDictionary<string, object> docProperties4 = new Dictionary<string, object>();
			docProperties4["_id"] = "4";
			docProperties4["artist"] = "PiL";
			docProperties4["album"] = "Metal Box";
			docProperties4["track"] = "Memories";
			docProperties4["time"] = 309;
			PutDoc(database, docProperties4);
			IDictionary<string, object> docProperties5 = new Dictionary<string, object>();
			docProperties5["_id"] = "5";
			docProperties5["artist"] = "Gang Of Four";
			docProperties5["album"] = "Entertainment!";
			docProperties5["track"] = "Not Great Men";
			docProperties5["time"] = 187;
			PutDoc(database, docProperties5);
			View view = database.GetView("grouper");
            view.SetMapReduce((IDictionary<string, object> document, EmitDelegate emitter)=>
                {
                    IList<object> key = new AList<object>();
                    key.AddItem(document["artist"]);
                    key.AddItem(document["album"]);
                    key.AddItem(document["track"]);
                    emitter(key, document["time"]);
                }, (IList<object> keys, IList<object> values, bool rereduce)=>
                {
                    return View.TotalValues(values);
                }, "1");
			Status status = new Status();
			view.UpdateIndex();
			QueryOptions options = new QueryOptions();
			options.SetReduce(true);
			IList<QueryRow> rows = view.QueryWithOptions(options);
			IList<IDictionary<string, object>> expectedRows = new AList<IDictionary<string, object
				>>();
			IDictionary<string, object> row1 = new Dictionary<string, object>();
			row1["key"] = null;
			row1["value"] = 1162.0;
			expectedRows.AddItem(row1);
			NUnit.Framework.Assert.AreEqual(row1["key"], rows[0].Key);
			NUnit.Framework.Assert.AreEqual(row1["value"], rows[0].GetValue());
			//now group
			options.SetGroup(true);
			status = new Status();
			rows = view.QueryWithOptions(options);
			expectedRows = new AList<IDictionary<string, object>>();
			row1 = new Dictionary<string, object>();
			IList<string> key1 = new AList<string>();
			key1.AddItem("Gang Of Four");
			key1.AddItem("Entertainment!");
			key1.AddItem("Ether");
			row1["key"] = key1;
			row1["value"] = 231.0;
			expectedRows.AddItem(row1);
			IDictionary<string, object> row2 = new Dictionary<string, object>();
			IList<string> key2 = new AList<string>();
			key2.AddItem("Gang Of Four");
			key2.AddItem("Entertainment!");
			key2.AddItem("Natural's Not In It");
			row2["key"] = key2;
			row2["value"] = 187.0;
			expectedRows.AddItem(row2);
			IDictionary<string, object> row3 = new Dictionary<string, object>();
			IList<string> key3 = new AList<string>();
			key3.AddItem("Gang Of Four");
			key3.AddItem("Entertainment!");
			key3.AddItem("Not Great Men");
			row3["key"] = key3;
			row3["value"] = 187.0;
			expectedRows.AddItem(row3);
			IDictionary<string, object> row4 = new Dictionary<string, object>();
			IList<string> key4 = new AList<string>();
			key4.AddItem("Gang Of Four");
			key4.AddItem("Songs Of The Free");
			key4.AddItem("I Love A Man In Uniform");
			row4["key"] = key4;
			row4["value"] = 248.0;
			expectedRows.AddItem(row4);
			IDictionary<string, object> row5 = new Dictionary<string, object>();
			IList<string> key5 = new AList<string>();
			key5.AddItem("PiL");
			key5.AddItem("Metal Box");
			key5.AddItem("Memories");
			row5["key"] = key5;
			row5["value"] = 309.0;
			expectedRows.AddItem(row5);
			NUnit.Framework.Assert.AreEqual(row1["key"], rows[0].Key);
			NUnit.Framework.Assert.AreEqual(row1["value"], rows[0].GetValue());
			NUnit.Framework.Assert.AreEqual(row2["key"], rows[1].Key);
			NUnit.Framework.Assert.AreEqual(row2["value"], rows[1].GetValue());
			NUnit.Framework.Assert.AreEqual(row3["key"], rows[2].Key);
			NUnit.Framework.Assert.AreEqual(row3["value"], rows[2].GetValue());
			NUnit.Framework.Assert.AreEqual(row4["key"], rows[3].Key);
			NUnit.Framework.Assert.AreEqual(row4["value"], rows[3].GetValue());
			NUnit.Framework.Assert.AreEqual(row5["key"], rows[4].Key);
			NUnit.Framework.Assert.AreEqual(row5["value"], rows[4].GetValue());
			//group level 1
			options.SetGroupLevel(1);
			status = new Status();
			rows = view.QueryWithOptions(options);
			expectedRows = new AList<IDictionary<string, object>>();
			row1 = new Dictionary<string, object>();
			key1 = new AList<string>();
			key1.AddItem("Gang Of Four");
			row1["key"] = key1;
			row1["value"] = 853.0;
			expectedRows.AddItem(row1);
			row2 = new Dictionary<string, object>();
			key2 = new AList<string>();
			key2.AddItem("PiL");
			row2["key"] = key2;
			row2["value"] = 309.0;
			expectedRows.AddItem(row2);
			NUnit.Framework.Assert.AreEqual(row1["key"], rows[0].Key);
			NUnit.Framework.Assert.AreEqual(row1["value"], rows[0].GetValue());
			NUnit.Framework.Assert.AreEqual(row2["key"], rows[1].Key);
			NUnit.Framework.Assert.AreEqual(row2["value"], rows[1].GetValue());
			//group level 2
			options.SetGroupLevel(2);
			status = new Status();
			rows = view.QueryWithOptions(options);
			expectedRows = new AList<IDictionary<string, object>>();
			row1 = new Dictionary<string, object>();
			key1 = new AList<string>();
			key1.AddItem("Gang Of Four");
			key1.AddItem("Entertainment!");
			row1["key"] = key1;
			row1["value"] = 605.0;
			expectedRows.AddItem(row1);
			row2 = new Dictionary<string, object>();
			key2 = new AList<string>();
			key2.AddItem("Gang Of Four");
			key2.AddItem("Songs Of The Free");
			row2["key"] = key2;
			row2["value"] = 248.0;
			expectedRows.AddItem(row2);
			row3 = new Dictionary<string, object>();
			key3 = new AList<string>();
			key3.AddItem("PiL");
			key3.AddItem("Metal Box");
			row3["key"] = key3;
			row3["value"] = 309.0;
			expectedRows.AddItem(row3);
			NUnit.Framework.Assert.AreEqual(row1["key"], rows[0].Key);
			NUnit.Framework.Assert.AreEqual(row1["value"], rows[0].GetValue());
			NUnit.Framework.Assert.AreEqual(row2["key"], rows[1].Key);
			NUnit.Framework.Assert.AreEqual(row2["value"], rows[1].GetValue());
			NUnit.Framework.Assert.AreEqual(row3["key"], rows[2].Key);
			NUnit.Framework.Assert.AreEqual(row3["value"], rows[2].GetValue());
		}
Beispiel #11
0
		/// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception>
		public virtual void TestViewGroupedStrings()
		{
			IDictionary<string, object> docProperties1 = new Dictionary<string, object>();
			docProperties1["name"] = "Alice";
			PutDoc(database, docProperties1);
			IDictionary<string, object> docProperties2 = new Dictionary<string, object>();
			docProperties2["name"] = "Albert";
			PutDoc(database, docProperties2);
			IDictionary<string, object> docProperties3 = new Dictionary<string, object>();
			docProperties3["name"] = "Naomi";
			PutDoc(database, docProperties3);
			IDictionary<string, object> docProperties4 = new Dictionary<string, object>();
			docProperties4["name"] = "Jens";
			PutDoc(database, docProperties4);
			IDictionary<string, object> docProperties5 = new Dictionary<string, object>();
			docProperties5["name"] = "Jed";
			PutDoc(database, docProperties5);
			View view = database.GetView("default/names");
			view.SetMapReduce(new _Mapper_852(), new _Reducer_862(), "1.0");
			view.UpdateIndex();
			QueryOptions options = new QueryOptions();
			options.SetGroupLevel(1);
			IList<QueryRow> rows = view.QueryWithOptions(options);
			IList<IDictionary<string, object>> expectedRows = new AList<IDictionary<string, object
				>>();
			IDictionary<string, object> row1 = new Dictionary<string, object>();
			row1["key"] = "A";
			row1["value"] = 2;
			expectedRows.AddItem(row1);
			IDictionary<string, object> row2 = new Dictionary<string, object>();
			row2["key"] = "J";
			row2["value"] = 2;
			expectedRows.AddItem(row2);
			IDictionary<string, object> row3 = new Dictionary<string, object>();
			row3["key"] = "N";
			row3["value"] = 1;
			expectedRows.AddItem(row3);
			NUnit.Framework.Assert.AreEqual(row1["key"], rows[0].Key);
			NUnit.Framework.Assert.AreEqual(row1["value"], rows[0].GetValue());
			NUnit.Framework.Assert.AreEqual(row2["key"], rows[1].Key);
			NUnit.Framework.Assert.AreEqual(row2["value"], rows[1].GetValue());
			NUnit.Framework.Assert.AreEqual(row3["key"], rows[2].Key);
			NUnit.Framework.Assert.AreEqual(row3["value"], rows[2].GetValue());
		}
Beispiel #12
0
		/// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception>
		public virtual void TestViewReduce()
		{
			IDictionary<string, object> docProperties1 = new Dictionary<string, object>();
			docProperties1["_id"] = "CD";
			docProperties1["cost"] = 8.99;
			PutDoc(database, docProperties1);
			IDictionary<string, object> docProperties2 = new Dictionary<string, object>();
			docProperties2["_id"] = "App";
			docProperties2["cost"] = 1.95;
			PutDoc(database, docProperties2);
			IDictionary<string, object> docProperties3 = new Dictionary<string, object>();
			docProperties3["_id"] = "Dessert";
			docProperties3["cost"] = 6.50;
			PutDoc(database, docProperties3);
			View view = database.GetView("totaler");
            view.SetMapReduce((document, emitter) => {
                NUnit.Framework.Assert.IsNotNull (document.Get ("_id"));
                NUnit.Framework.Assert.IsNotNull (document.Get ("_rev"));
                object cost = document.Get ("cost");
                if (cost != null) {
                    emitter (document.Get ("_id"), cost);
                }
            }, (IList<object> keys, IList<object> values, bool rereduce)=> {
                    return View.TotalValues(values);
                }, "1");
			view.UpdateIndex();
			IList<IDictionary<string, object>> dumpResult = view.Dump();
			Log.V(Tag, "View dump: " + dumpResult);
			NUnit.Framework.Assert.AreEqual(3, dumpResult.Count);
			NUnit.Framework.Assert.AreEqual("\"App\"", dumpResult[0]["key"]);
			NUnit.Framework.Assert.AreEqual("1.95", dumpResult[0]["value"]);
			NUnit.Framework.Assert.AreEqual(2, dumpResult[0]["seq"]);
			NUnit.Framework.Assert.AreEqual("\"CD\"", dumpResult[1]["key"]);
			NUnit.Framework.Assert.AreEqual("8.99", dumpResult[1]["value"]);
			NUnit.Framework.Assert.AreEqual(1, dumpResult[1]["seq"]);
			NUnit.Framework.Assert.AreEqual("\"Dessert\"", dumpResult[2]["key"]);
			NUnit.Framework.Assert.AreEqual("6.5", dumpResult[2]["value"]);
			NUnit.Framework.Assert.AreEqual(3, dumpResult[2]["seq"]);
			QueryOptions options = new QueryOptions();
			options.SetReduce(true);
			IList<QueryRow> reduced = view.QueryWithOptions(options);
			NUnit.Framework.Assert.AreEqual(1, reduced.Count);
			object value = reduced[0].GetValue();
			Number numberValue = (Number)value;
			NUnit.Framework.Assert.IsTrue(Math.Abs(numberValue - 17.44) < 0.001);
		}
 /// <summary>
 /// https://github.com/couchbase/couchbase-lite-android/issues/139
 /// test based on https://github.com/couchbase/couchbase-lite-ios/blob/master/Source/CBL_View_Tests.m#L358
 /// </summary>
 /// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception>
 public virtual void TestViewQueryStartKeyDocID()
 {
     PutDocs(database);
     IList<RevisionInternal> result = new AList<RevisionInternal>();
     IDictionary<string, object> dict = new Dictionary<string, object>();
     dict.Put("_id", "11112");
     dict.Put("key", "one");
     result.AddItem(PutDoc(database, dict));
     View view = CreateView(database);
     view.UpdateIndex();
     QueryOptions options = new QueryOptions();
     options.SetStartKey("one");
     options.SetStartKeyDocId("11112");
     options.SetEndKey("three");
     IList<QueryRow> rows = view.QueryWithOptions(options);
     NUnit.Framework.Assert.AreEqual(2, rows.Count);
     NUnit.Framework.Assert.AreEqual("11112", rows[0].GetDocumentId());
     NUnit.Framework.Assert.AreEqual("one", rows[0].GetKey());
     NUnit.Framework.Assert.AreEqual("33333", rows[1].GetDocumentId());
     NUnit.Framework.Assert.AreEqual("three", rows[1].GetKey());
     options = new QueryOptions();
     options.SetEndKey("one");
     options.SetEndKeyDocId("11111");
     rows = view.QueryWithOptions(options);
     Log.D(Tag, "rows: " + rows);
     NUnit.Framework.Assert.AreEqual(3, rows.Count);
     NUnit.Framework.Assert.AreEqual("55555", rows[0].GetDocumentId());
     NUnit.Framework.Assert.AreEqual("five", rows[0].GetKey());
     NUnit.Framework.Assert.AreEqual("44444", rows[1].GetDocumentId());
     NUnit.Framework.Assert.AreEqual("four", rows[1].GetKey());
     NUnit.Framework.Assert.AreEqual("11111", rows[2].GetDocumentId());
     NUnit.Framework.Assert.AreEqual("one", rows[2].GetKey());
     options.SetStartKey("one");
     options.SetStartKeyDocId("11111");
     rows = view.QueryWithOptions(options);
     NUnit.Framework.Assert.AreEqual(1, rows.Count);
     NUnit.Framework.Assert.AreEqual("11111", rows[0].GetDocumentId());
     NUnit.Framework.Assert.AreEqual("one", rows[0].GetKey());
 }
Beispiel #14
0
        internal Cursor ResultSetWithOptions(QueryOptions options)
        {
            if (options == null)
            {
                options = new QueryOptions();
            }
            // OPT: It would be faster to use separate tables for raw-or ascii-collated views so that
            // they could be indexed with the right Collation, instead of having to specify it here.
            var collationStr = string.Empty;

            if (Collation == ViewCollation.ASCII)
            {
                collationStr += " COLLATE JSON_ASCII";
            }
            else
            {
                if (Collation == ViewCollation.Raw)
                {
                    collationStr += " COLLATE JSON_RAW";
                }
            }
            var sql = "SELECT key, value, docid, revs.sequence";

            if (options.IsIncludeDocs())
            {
                sql = sql + ", revid, json";
            }
            sql = sql + " FROM maps, revs, docs WHERE maps.view_id=?";
            var argsList = new List <string>();

            argsList.AddItem(Sharpen.Extensions.ToString(Id));
            if (options.GetKeys() != null)
            {
                sql += " AND key in (";
                var item = "?";
                foreach (object key in options.GetKeys())
                {
                    sql += item;
                    item = ", ?";
                    argsList.AddItem(ToJSONString(key));
                }
                sql += ")";
            }
            var startKey     = ToJSONString(options.GetStartKey());
            var endKey       = ToJSONString(options.GetEndKey());
            var minKey       = startKey;
            var maxKey       = endKey;
            var minKeyDocId  = options.GetStartKeyDocId();
            var maxKeyDocId  = options.GetEndKeyDocId();
            var inclusiveMin = true;
            var inclusiveMax = options.IsInclusiveEnd();

            if (options.IsDescending())
            {
                var min = minKey;
                minKey       = maxKey;
                maxKey       = min;
                inclusiveMin = inclusiveMax;
                inclusiveMax = true;
                minKeyDocId  = options.GetEndKeyDocId();
                maxKeyDocId  = options.GetStartKeyDocId();
            }
            if (minKey != null)
            {
                sql += inclusiveMin
                    ? " AND key >= ?"
                    : " AND key > ?";
                sql += collationStr;
                argsList.AddItem(minKey);
                if (minKeyDocId != null && inclusiveMin)
                {
                    //OPT: This calls the JSON collator a 2nd time unnecessarily.
                    sql += " AND (key > ? {0} OR docid >= ?)".Fmt(collationStr);
                    argsList.AddItem(minKey);
                    argsList.AddItem(minKeyDocId);
                }
            }
            if (maxKey != null)
            {
                if (inclusiveMax)
                {
                    sql += " AND key <= ?";
                }
                else
                {
                    sql += " AND key < ?";
                }
                sql += collationStr;
                argsList.AddItem(maxKey);
                if (maxKeyDocId != null && inclusiveMax)
                {
                    sql += string.Format(" AND (key < ? {0} OR docid <= ?)", collationStr);
                    argsList.AddItem(maxKey);
                    argsList.AddItem(maxKeyDocId);
                }
            }
            sql  = sql + " AND revs.sequence = maps.sequence AND docs.doc_id = revs.doc_id ORDER BY key";
            sql += collationStr;
            if (options.IsDescending())
            {
                sql = sql + " DESC";
            }
            sql = sql + " LIMIT ? OFFSET ?";
            argsList.AddItem(options.GetLimit().ToString());
            argsList.AddItem(options.GetSkip().ToString());
            Log.V(Database.Tag, "Query {0}:{1}", Name, sql);
            var cursor = Database.StorageEngine.RawQuery(sql, CommandBehavior.SequentialAccess, argsList.ToArray());

            return(cursor);
        }
Beispiel #15
0
		/// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception>
		public virtual void TestAllDocsQuery()
		{
			IList<RevisionInternal> docs = PutDocs(database);
			IList<QueryRow> expectedRow = new AList<QueryRow>();
			foreach (RevisionInternal rev in docs)
			{
				IDictionary<string, object> value = new Dictionary<string, object>();
				value.Put("rev", rev.GetRevId());
				value.Put("_conflicts", new AList<string>());
				QueryRow queryRow = new QueryRow(rev.GetDocId(), 0, rev.GetDocId(), value, null);
				queryRow.SetDatabase(database);
				expectedRow.AddItem(queryRow);
			}
			QueryOptions options = new QueryOptions();
			IDictionary<string, object> allDocs = database.GetAllDocs(options);
			IList<QueryRow> expectedRows = new AList<QueryRow>();
			expectedRows.AddItem(expectedRow[2]);
			expectedRows.AddItem(expectedRow[0]);
			expectedRows.AddItem(expectedRow[3]);
			expectedRows.AddItem(expectedRow[1]);
			expectedRows.AddItem(expectedRow[4]);
			IDictionary<string, object> expectedQueryResult = CreateExpectedQueryResult(expectedRows
				, 0);
			NUnit.Framework.Assert.AreEqual(expectedQueryResult, allDocs);
			// Start/end key query:
			options = new QueryOptions();
			options.SetStartKey("2");
			options.SetEndKey("44444");
			allDocs = database.GetAllDocs(options);
			expectedRows = new AList<QueryRow>();
			expectedRows.AddItem(expectedRow[0]);
			expectedRows.AddItem(expectedRow[3]);
			expectedRows.AddItem(expectedRow[1]);
			expectedQueryResult = CreateExpectedQueryResult(expectedRows, 0);
			NUnit.Framework.Assert.AreEqual(expectedQueryResult, allDocs);
			// Start/end query without inclusive end:
			options.SetInclusiveEnd(false);
			allDocs = database.GetAllDocs(options);
			expectedRows = new AList<QueryRow>();
			expectedRows.AddItem(expectedRow[0]);
			expectedRows.AddItem(expectedRow[3]);
			expectedQueryResult = CreateExpectedQueryResult(expectedRows, 0);
			NUnit.Framework.Assert.AreEqual(expectedQueryResult, allDocs);
			// Get all documents: with default QueryOptions
			options = new QueryOptions();
			allDocs = database.GetAllDocs(options);
			expectedRows = new AList<QueryRow>();
			expectedRows.AddItem(expectedRow[2]);
			expectedRows.AddItem(expectedRow[0]);
			expectedRows.AddItem(expectedRow[3]);
			expectedRows.AddItem(expectedRow[1]);
			expectedRows.AddItem(expectedRow[4]);
			expectedQueryResult = CreateExpectedQueryResult(expectedRows, 0);
			NUnit.Framework.Assert.AreEqual(expectedQueryResult, allDocs);
			// Get specific documents:
			options = new QueryOptions();
			IList<object> docIds = new AList<object>();
			QueryRow expected2 = expectedRow[2];
			docIds.AddItem(expected2.GetDocument().GetId());
			options.SetKeys(docIds);
			allDocs = database.GetAllDocs(options);
			expectedRows = new AList<QueryRow>();
			expectedRows.AddItem(expected2);
			expectedQueryResult = CreateExpectedQueryResult(expectedRows, 0);
			NUnit.Framework.Assert.AreEqual(expectedQueryResult, allDocs);
		}
Beispiel #16
0
		private QueryOptions GetQueryOptions()
		{
			QueryOptions queryOptions = new QueryOptions();
			queryOptions.SetStartKey(GetStartKey());
			queryOptions.SetEndKey(GetEndKey());
			queryOptions.SetStartKey(GetStartKey());
			queryOptions.SetKeys(GetKeys());
			queryOptions.SetSkip(GetSkip());
			queryOptions.SetLimit(GetLimit());
			queryOptions.SetReduce(!IsMapOnly());
			queryOptions.SetReduceSpecified(true);
			queryOptions.SetGroupLevel(GetGroupLevel());
			queryOptions.SetDescending(IsDescending());
			queryOptions.SetIncludeDocs(ShouldPrefetch());
			queryOptions.SetUpdateSeq(true);
			queryOptions.SetInclusiveEnd(true);
			queryOptions.SetStale(GetIndexUpdateMode());
			queryOptions.SetAllDocsMode(GetAllDocsMode());
			return queryOptions;
		}
Beispiel #17
0
		/// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception>
		public virtual void TestViewReduce()
		{
			IDictionary<string, object> docProperties1 = new Dictionary<string, object>();
			docProperties1.Put("_id", "CD");
			docProperties1.Put("cost", 8.99);
			PutDoc(database, docProperties1);
			IDictionary<string, object> docProperties2 = new Dictionary<string, object>();
			docProperties2.Put("_id", "App");
			docProperties2.Put("cost", 1.95);
			PutDoc(database, docProperties2);
			IDictionary<string, object> docProperties3 = new Dictionary<string, object>();
			docProperties3.Put("_id", "Dessert");
			docProperties3.Put("cost", 6.50);
			PutDoc(database, docProperties3);
			View view = database.GetView("totaler");
			view.SetMapReduce(new _Mapper_544(), new _Reducer_555(), "1");
			view.UpdateIndex();
			IList<IDictionary<string, object>> dumpResult = view.Dump();
			Log.V(Tag, "View dump: " + dumpResult);
			NUnit.Framework.Assert.AreEqual(3, dumpResult.Count);
			NUnit.Framework.Assert.AreEqual("\"App\"", dumpResult[0].Get("key"));
			NUnit.Framework.Assert.AreEqual("1.95", dumpResult[0].Get("value"));
			NUnit.Framework.Assert.AreEqual(2, dumpResult[0].Get("seq"));
			NUnit.Framework.Assert.AreEqual("\"CD\"", dumpResult[1].Get("key"));
			NUnit.Framework.Assert.AreEqual("8.99", dumpResult[1].Get("value"));
			NUnit.Framework.Assert.AreEqual(1, dumpResult[1].Get("seq"));
			NUnit.Framework.Assert.AreEqual("\"Dessert\"", dumpResult[2].Get("key"));
			NUnit.Framework.Assert.AreEqual("6.5", dumpResult[2].Get("value"));
			NUnit.Framework.Assert.AreEqual(3, dumpResult[2].Get("seq"));
			QueryOptions options = new QueryOptions();
			options.SetReduce(true);
			IList<QueryRow> reduced = view.QueryWithOptions(options);
			NUnit.Framework.Assert.AreEqual(1, reduced.Count);
			object value = reduced[0].GetValue();
			Number numberValue = (Number)value;
			NUnit.Framework.Assert.IsTrue(Math.Abs(numberValue - 17.44) < 0.001);
		}
Beispiel #18
0
		public Cursor ResultSetWithOptions(QueryOptions options)
		{
			if (options == null)
			{
				options = new QueryOptions();
			}
			// OPT: It would be faster to use separate tables for raw-or ascii-collated views so that
			// they could be indexed with the right collation, instead of having to specify it here.
			string collationStr = string.Empty;
			if (collation == View.TDViewCollation.TDViewCollationASCII)
			{
				collationStr += " COLLATE JSON_ASCII";
			}
			else
			{
				if (collation == View.TDViewCollation.TDViewCollationRaw)
				{
					collationStr += " COLLATE JSON_RAW";
				}
			}
			string sql = "SELECT key, value, docid, revs.sequence";
			if (options.IsIncludeDocs())
			{
				sql = sql + ", revid, json";
			}
			sql = sql + " FROM maps, revs, docs WHERE maps.view_id=?";
			IList<string> argsList = new AList<string>();
			argsList.AddItem(Sharpen.Extensions.ToString(GetViewId()));
			if (options.GetKeys() != null)
			{
				sql += " AND key in (";
				string item = "?";
				foreach (object key in options.GetKeys())
				{
					sql += item;
					item = ", ?";
					argsList.AddItem(ToJSONString(key));
				}
				sql += ")";
			}
			object minKey = options.GetStartKey();
			object maxKey = options.GetEndKey();
			bool inclusiveMin = true;
			bool inclusiveMax = options.IsInclusiveEnd();
			if (options.IsDescending())
			{
				minKey = maxKey;
				maxKey = options.GetStartKey();
				inclusiveMin = inclusiveMax;
				inclusiveMax = true;
			}
			if (minKey != null)
			{
				System.Diagnostics.Debug.Assert((minKey is string));
				if (inclusiveMin)
				{
					sql += " AND key >= ?";
				}
				else
				{
					sql += " AND key > ?";
				}
				sql += collationStr;
				argsList.AddItem(ToJSONString(minKey));
			}
			if (maxKey != null)
			{
				System.Diagnostics.Debug.Assert((maxKey is string));
				if (inclusiveMax)
				{
					sql += " AND key <= ?";
				}
				else
				{
					sql += " AND key < ?";
				}
				sql += collationStr;
				argsList.AddItem(ToJSONString(maxKey));
			}
			sql = sql + " AND revs.sequence = maps.sequence AND docs.doc_id = revs.doc_id ORDER BY key";
			sql += collationStr;
			if (options.IsDescending())
			{
				sql = sql + " DESC";
			}
			sql = sql + " LIMIT ? OFFSET ?";
			argsList.AddItem(Sharpen.Extensions.ToString(options.GetLimit()));
			argsList.AddItem(Sharpen.Extensions.ToString(options.GetSkip()));
			Log.V(Database.Tag, "Query " + name + ": " + sql);
			Cursor cursor = database.GetDatabase().RawQuery(sql, Sharpen.Collections.ToArray(
				argsList, new string[argsList.Count]));
			return cursor;
		}
Beispiel #19
0
		/// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception>
		public virtual void TestViewGroupedStrings()
		{
			IDictionary<string, object> docProperties1 = new Dictionary<string, object>();
			docProperties1.Put("name", "Alice");
			PutDoc(database, docProperties1);
			IDictionary<string, object> docProperties2 = new Dictionary<string, object>();
			docProperties2.Put("name", "Albert");
			PutDoc(database, docProperties2);
			IDictionary<string, object> docProperties3 = new Dictionary<string, object>();
			docProperties3.Put("name", "Naomi");
			PutDoc(database, docProperties3);
			IDictionary<string, object> docProperties4 = new Dictionary<string, object>();
			docProperties4.Put("name", "Jens");
			PutDoc(database, docProperties4);
			IDictionary<string, object> docProperties5 = new Dictionary<string, object>();
			docProperties5.Put("name", "Jed");
			PutDoc(database, docProperties5);
			View view = database.GetView("default/names");
			view.SetMapReduce(new _Mapper_859(), new _Reducer_869(), "1.0");
			view.UpdateIndex();
			QueryOptions options = new QueryOptions();
			options.SetGroupLevel(1);
			IList<QueryRow> rows = view.QueryWithOptions(options);
			IList<IDictionary<string, object>> expectedRows = new AList<IDictionary<string, object
				>>();
			IDictionary<string, object> row1 = new Dictionary<string, object>();
			row1.Put("key", "A");
			row1.Put("value", 2);
			expectedRows.AddItem(row1);
			IDictionary<string, object> row2 = new Dictionary<string, object>();
			row2.Put("key", "J");
			row2.Put("value", 2);
			expectedRows.AddItem(row2);
			IDictionary<string, object> row3 = new Dictionary<string, object>();
			row3.Put("key", "N");
			row3.Put("value", 1);
			expectedRows.AddItem(row3);
			NUnit.Framework.Assert.AreEqual(row1.Get("key"), rows[0].GetKey());
			NUnit.Framework.Assert.AreEqual(row1.Get("value"), rows[0].GetValue());
			NUnit.Framework.Assert.AreEqual(row2.Get("key"), rows[1].GetKey());
			NUnit.Framework.Assert.AreEqual(row2.Get("value"), rows[1].GetValue());
			NUnit.Framework.Assert.AreEqual(row3.Get("key"), rows[2].GetKey());
			NUnit.Framework.Assert.AreEqual(row3.Get("value"), rows[2].GetValue());
		}
Beispiel #20
0
 public Cursor ResultSetWithOptions(QueryOptions options)
 {
     if (options == null)
     {
         options = new QueryOptions();
     }
     // OPT: It would be faster to use separate tables for raw-or ascii-collated views so that
     // they could be indexed with the right collation, instead of having to specify it here.
     string collationStr = string.Empty;
     if (collation == View.TDViewCollation.TDViewCollationASCII)
     {
         collationStr += " COLLATE JSON_ASCII";
     }
     else
     {
         if (collation == View.TDViewCollation.TDViewCollationRaw)
         {
             collationStr += " COLLATE JSON_RAW";
         }
     }
     string sql = "SELECT key, value, docid, revs.sequence";
     if (options.IsIncludeDocs())
     {
         sql = sql + ", revid, json";
     }
     sql = sql + " FROM maps, revs, docs WHERE maps.view_id=?";
     IList<string> argsList = new AList<string>();
     argsList.AddItem(Sharpen.Extensions.ToString(GetViewId()));
     if (options.GetKeys() != null)
     {
         sql += " AND key in (";
         string item = "?";
         foreach (object key in options.GetKeys())
         {
             sql += item;
             item = ", ?";
             argsList.AddItem(ToJSONString(key));
         }
         sql += ")";
     }
     string startKey = ToJSONString(options.GetStartKey());
     string endKey = ToJSONString(options.GetEndKey());
     string minKey = startKey;
     string maxKey = endKey;
     string minKeyDocId = options.GetStartKeyDocId();
     string maxKeyDocId = options.GetEndKeyDocId();
     bool inclusiveMin = true;
     bool inclusiveMax = options.IsInclusiveEnd();
     if (options.IsDescending())
     {
         string min = minKey;
         minKey = maxKey;
         maxKey = min;
         inclusiveMin = inclusiveMax;
         inclusiveMax = true;
         minKeyDocId = options.GetEndKeyDocId();
         maxKeyDocId = options.GetStartKeyDocId();
     }
     if (minKey != null)
     {
         if (inclusiveMin)
         {
             sql += " AND key >= ?";
         }
         else
         {
             sql += " AND key > ?";
         }
         sql += collationStr;
         argsList.AddItem(minKey);
         if (minKeyDocId != null && inclusiveMin)
         {
             //OPT: This calls the JSON collator a 2nd time unnecessarily.
             sql += string.Format(" AND (key > ? %s OR docid >= ?)", collationStr);
             argsList.AddItem(minKey);
             argsList.AddItem(minKeyDocId);
         }
     }
     if (maxKey != null)
     {
         if (inclusiveMax)
         {
             sql += " AND key <= ?";
         }
         else
         {
             sql += " AND key < ?";
         }
         sql += collationStr;
         argsList.AddItem(maxKey);
         if (maxKeyDocId != null && inclusiveMax)
         {
             sql += string.Format(" AND (key < ? %s OR docid <= ?)", collationStr);
             argsList.AddItem(maxKey);
             argsList.AddItem(maxKeyDocId);
         }
     }
     sql = sql + " AND revs.sequence = maps.sequence AND docs.doc_id = revs.doc_id ORDER BY key";
     sql += collationStr;
     if (options.IsDescending())
     {
         sql = sql + " DESC";
     }
     sql = sql + " LIMIT ? OFFSET ?";
     argsList.AddItem(Sharpen.Extensions.ToString(options.GetLimit()));
     argsList.AddItem(Sharpen.Extensions.ToString(options.GetSkip()));
     Log.V(Log.TagView, "Query %s: %s | args: %s", name, sql, argsList);
     Cursor cursor = database.GetDatabase().RawQuery(sql, Sharpen.Collections.ToArray(
         argsList, new string[argsList.Count]));
     return cursor;
 }
Beispiel #21
0
		public IList<QueryRow> QueryViewNamed(string viewName, QueryOptions options, IList
			<long> outLastSequence)
		{
			long before = Runtime.CurrentTimeMillis();
			long lastSequence = 0;
			IList<QueryRow> rows = null;
			if (viewName != null && viewName.Length > 0)
			{
				View view = GetView(viewName);
				if (view == null)
				{
					throw new CouchbaseLiteException(new Status(Status.NotFound));
				}
				lastSequence = view.GetLastSequenceIndexed();
				if (options.GetStale() == Query.IndexUpdateMode.Before || lastSequence <= 0)
				{
					view.UpdateIndex();
					lastSequence = view.GetLastSequenceIndexed();
				}
				else
				{
					if (options.GetStale() == Query.IndexUpdateMode.After && lastSequence < GetLastSequenceNumber
						())
					{
						new Sharpen.Thread(new _Runnable_1847(view)).Start();
					}
				}
				rows = view.QueryWithOptions(options);
			}
			else
			{
				// nil view means query _all_docs
				// note: this is a little kludgy, but we have to pull out the "rows" field from the
				// result dictionary because that's what we want.  should be refactored, but
				// it's a little tricky, so postponing.
				IDictionary<string, object> allDocsResult = GetAllDocs(options);
				rows = (IList<QueryRow>)allDocsResult.Get("rows");
				lastSequence = GetLastSequenceNumber();
			}
			outLastSequence.AddItem(lastSequence);
			long delta = Runtime.CurrentTimeMillis() - before;
			Log.D(Database.Tag, string.Format("Query view %s completed in %d milliseconds", viewName
				, delta));
			return rows;
		}
Beispiel #22
0
 public IList<QueryRow> QueryWithOptions(QueryOptions options)
 {
     if (options == null)
     {
         options = new QueryOptions();
     }
     Cursor cursor = null;
     IList<QueryRow> rows = new AList<QueryRow>();
     try
     {
         cursor = ResultSetWithOptions(options);
         int groupLevel = options.GetGroupLevel();
         bool group = options.IsGroup() || (groupLevel > 0);
         bool reduce = options.IsReduce() || group;
         if (reduce && (reduceBlock == null) && !group)
         {
             Log.W(Log.TagView, "Cannot use reduce option in view %s which has no reduce block defined"
                 , name);
             throw new CouchbaseLiteException(new Status(Status.BadRequest));
         }
         if (reduce || group)
         {
             // Reduced or grouped query:
             rows = ReducedQuery(cursor, group, groupLevel);
         }
         else
         {
             // regular query
             cursor.MoveToNext();
             while (!cursor.IsAfterLast())
             {
                 JsonDocument keyDoc = new JsonDocument(cursor.GetBlob(0));
                 JsonDocument valueDoc = new JsonDocument(cursor.GetBlob(1));
                 string docId = cursor.GetString(2);
                 int sequence = Sharpen.Extensions.ValueOf(cursor.GetString(3));
                 IDictionary<string, object> docContents = null;
                 if (options.IsIncludeDocs())
                 {
                     object valueObject = valueDoc.JsonObject();
                     // http://wiki.apache.org/couchdb/Introduction_to_CouchDB_views#Linked_documents
                     if (valueObject is IDictionary && ((IDictionary)valueObject).ContainsKey("_id"))
                     {
                         string linkedDocId = (string)((IDictionary)valueObject).Get("_id");
                         RevisionInternal linkedDoc = database.GetDocumentWithIDAndRev(linkedDocId, null, 
                             EnumSet.NoneOf<Database.TDContentOptions>());
                         docContents = linkedDoc.GetProperties();
                     }
                     else
                     {
                         docContents = database.DocumentPropertiesFromJSON(cursor.GetBlob(5), docId, cursor
                             .GetString(4), false, cursor.GetLong(3), options.GetContentOptions());
                     }
                 }
                 QueryRow row = new QueryRow(docId, sequence, keyDoc.JsonObject(), valueDoc.JsonObject
                     (), docContents);
                 row.SetDatabase(database);
                 rows.AddItem(row);
                 cursor.MoveToNext();
             }
         }
     }
     catch (SQLException e)
     {
         string errMsg = string.Format("Error querying view: %s", this);
         Log.E(Log.TagView, errMsg, e);
         throw new CouchbaseLiteException(errMsg, e, new Status(Status.DbError));
     }
     finally
     {
         if (cursor != null)
         {
             cursor.Close();
         }
     }
     return rows;
 }
Beispiel #23
0
		public IDictionary<string, object> GetAllDocs(QueryOptions options)
		{
			IDictionary<string, object> result = new Dictionary<string, object>();
			IList<QueryRow> rows = new AList<QueryRow>();
			if (options == null)
			{
				options = new QueryOptions();
			}
			bool includeDeletedDocs = (options.GetAllDocsMode() == Query.AllDocsMode.IncludeDeleted
				);
			long updateSeq = 0;
			if (options.IsUpdateSeq())
			{
				updateSeq = GetLastSequenceNumber();
			}
			// TODO: needs to be atomic with the following SELECT
			StringBuilder sql = new StringBuilder("SELECT revs.doc_id, docid, revid, sequence"
				);
			if (options.IsIncludeDocs())
			{
				sql.Append(", json");
			}
			if (includeDeletedDocs)
			{
				sql.Append(", deleted");
			}
			sql.Append(" FROM revs, docs WHERE");
			if (options.GetKeys() != null)
			{
				if (options.GetKeys().Count == 0)
				{
					return result;
				}
				string commaSeperatedIds = JoinQuotedObjects(options.GetKeys());
				sql.Append(string.Format(" revs.doc_id IN (SELECT doc_id FROM docs WHERE docid IN (%s)) AND"
					, commaSeperatedIds));
			}
			sql.Append(" docs.doc_id = revs.doc_id AND current=1");
			if (!includeDeletedDocs)
			{
				sql.Append(" AND deleted=0");
			}
			IList<string> args = new AList<string>();
			object minKey = options.GetStartKey();
			object maxKey = options.GetEndKey();
			bool inclusiveMin = true;
			bool inclusiveMax = options.IsInclusiveEnd();
			if (options.IsDescending())
			{
				minKey = maxKey;
				maxKey = options.GetStartKey();
				inclusiveMin = inclusiveMax;
				inclusiveMax = true;
			}
			if (minKey != null)
			{
				System.Diagnostics.Debug.Assert((minKey is string));
				sql.Append((inclusiveMin ? " AND docid >= ?" : " AND docid > ?"));
				args.AddItem((string)minKey);
			}
			if (maxKey != null)
			{
				System.Diagnostics.Debug.Assert((maxKey is string));
				sql.Append((inclusiveMax ? " AND docid <= ?" : " AND docid < ?"));
				args.AddItem((string)maxKey);
			}
			sql.Append(string.Format(" ORDER BY docid %s, %s revid DESC LIMIT ? OFFSET ?", (options
				.IsDescending() ? "DESC" : "ASC"), (includeDeletedDocs ? "deleted ASC," : string.Empty
				)));
			args.AddItem(Sharpen.Extensions.ToString(options.GetLimit()));
			args.AddItem(Sharpen.Extensions.ToString(options.GetSkip()));
			Cursor cursor = null;
			IDictionary<string, QueryRow> docs = new Dictionary<string, QueryRow>();
			try
			{
				cursor = database.RawQuery(sql.ToString(), Sharpen.Collections.ToArray(args, new 
					string[args.Count]));
				bool keepGoing = cursor.MoveToNext();
				while (keepGoing)
				{
					long docNumericID = cursor.GetLong(0);
					string docId = cursor.GetString(1);
					string revId = cursor.GetString(2);
					long sequenceNumber = cursor.GetLong(3);
					bool deleted = includeDeletedDocs && cursor.GetInt(GetDeletedColumnIndex(options)
						) > 0;
					IDictionary<string, object> docContents = null;
					if (options.IsIncludeDocs())
					{
						byte[] json = cursor.GetBlob(4);
						docContents = DocumentPropertiesFromJSON(json, docId, revId, deleted, sequenceNumber
							, options.GetContentOptions());
					}
					// Iterate over following rows with the same doc_id -- these are conflicts.
					// Skip them, but collect their revIDs if the 'conflicts' option is set:
					IList<string> conflicts = new AList<string>();
					while (((keepGoing = cursor.MoveToNext()) == true) && cursor.GetLong(0) == docNumericID
						)
					{
						if (options.GetAllDocsMode() == Query.AllDocsMode.ShowConflicts || options.GetAllDocsMode
							() == Query.AllDocsMode.OnlyConflicts)
						{
							if (conflicts.IsEmpty())
							{
								conflicts.AddItem(revId);
							}
							conflicts.AddItem(cursor.GetString(2));
						}
					}
					if (options.GetAllDocsMode() == Query.AllDocsMode.OnlyConflicts && conflicts.IsEmpty
						())
					{
						continue;
					}
					IDictionary<string, object> value = new Dictionary<string, object>();
					value.Put("rev", revId);
					value.Put("_conflicts", conflicts);
					if (includeDeletedDocs)
					{
						value.Put("deleted", (deleted ? true : null));
					}
					QueryRow change = new QueryRow(docId, sequenceNumber, docId, value, docContents);
					change.SetDatabase(this);
					if (options.GetKeys() != null)
					{
						docs.Put(docId, change);
					}
					else
					{
						rows.AddItem(change);
					}
				}
				if (options.GetKeys() != null)
				{
					foreach (object docIdObject in options.GetKeys())
					{
						if (docIdObject is string)
						{
							string docId = (string)docIdObject;
							QueryRow change = docs.Get(docId);
							if (change == null)
							{
								IDictionary<string, object> value = new Dictionary<string, object>();
								long docNumericID = GetDocNumericID(docId);
								if (docNumericID > 0)
								{
									bool deleted;
									IList<bool> outIsDeleted = new AList<bool>();
									IList<bool> outIsConflict = new AList<bool>();
									string revId = WinningRevIDOfDoc(docNumericID, outIsDeleted, outIsConflict);
									if (outIsDeleted.Count > 0)
									{
										deleted = true;
									}
									if (revId != null)
									{
										value.Put("rev", revId);
										value.Put("deleted", true);
									}
								}
								change = new QueryRow((value != null ? docId : null), 0, docId, value, null);
								change.SetDatabase(this);
							}
							rows.AddItem(change);
						}
					}
				}
			}
			catch (SQLException e)
			{
				Log.E(Database.Tag, "Error getting all docs", e);
				throw new CouchbaseLiteException("Error getting all docs", e, new Status(Status.InternalServerError
					));
			}
			finally
			{
				if (cursor != null)
				{
					cursor.Close();
				}
			}
			result.Put("rows", rows);
			result.Put("total_rows", rows.Count);
			result.Put("offset", options.GetSkip());
			if (updateSeq != 0)
			{
				result.Put("update_seq", updateSeq);
			}
			return result;
		}
Beispiel #24
0
        internal Cursor ResultSetWithOptions(QueryOptions options)
        {
            if (options == null)
            {
                options = new QueryOptions();
            }
            // OPT: It would be faster to use separate tables for raw-or ascii-collated views so that
            // they could be indexed with the right Collation, instead of having to specify it here.
            var collationStr = string.Empty;

            if (Collation == ViewCollation.ASCII)
            {
                collationStr += " COLLATE JSON_ASCII";
            }
            else
            {
                if (Collation == ViewCollation.Raw)
                {
                    collationStr += " COLLATE JSON_RAW";
                }
            }
            var sql = "SELECT key, value, docid, revs.sequence";

            if (options.IsIncludeDocs())
            {
                sql = sql + ", revid, json";
            }
            sql = sql + " FROM maps, revs, docs WHERE maps.view_id=@";
            var argsList = new AList <string>();

            argsList.AddItem(Sharpen.Extensions.ToString(Id));
            if (options.GetKeys() != null)
            {
                sql += " AND key in (";
                var item = "@";
                foreach (object key in options.GetKeys())
                {
                    sql += item;
                    item = ", @";
                    argsList.AddItem(ToJSONString(key));
                }
                sql += ")";
            }
            var minKey       = options.GetStartKey();
            var maxKey       = options.GetEndKey();
            var inclusiveMin = true;
            var inclusiveMax = options.IsInclusiveEnd();

            if (options.IsDescending())
            {
                minKey       = maxKey;
                maxKey       = options.GetStartKey();
                inclusiveMin = inclusiveMax;
                inclusiveMax = true;
            }
            if (minKey != null)
            {
                System.Diagnostics.Debug.Assert((minKey is string));
                sql += inclusiveMin ? " AND key >= @" : " AND key > @";
                sql += collationStr;
                argsList.AddItem(ToJSONString(minKey));
            }
            if (maxKey != null)
            {
                System.Diagnostics.Debug.Assert((maxKey is string));
                if (inclusiveMax)
                {
                    sql += " AND key <= @";
                }
                else
                {
                    sql += " AND key < @";
                }
                sql += collationStr;
                argsList.AddItem(ToJSONString(maxKey));
            }
            sql  = sql + " AND revs.sequence = maps.sequence AND docs.doc_id = revs.doc_id ORDER BY key";
            sql += collationStr;
            if (options.IsDescending())
            {
                sql = sql + " DESC";
            }
            sql = sql + " LIMIT @ OFFSET @";
            argsList.AddItem(options.GetLimit().ToString());
            argsList.AddItem(options.GetSkip().ToString());
            Log.V(Database.Tag, "Query " + Name + ": " + sql);
            var cursor = Database.StorageEngine.RawQuery(sql, CommandBehavior.SequentialAccess, argsList.ToArray());

            return(cursor);
        }