Esempio n. 1
0
        internal IList <QueryRow> ReducedQuery(Cursor cursor, bool group, int groupLevel)
        {
            IList <object> keysToReduce   = null;
            IList <object> valuesToReduce = null;
            object         lastKey        = null;

            if (GetReduce() != null)
            {
                keysToReduce   = new AList <object>(ReduceBatchSize);
                valuesToReduce = new AList <object>(ReduceBatchSize);
            }
            IList <QueryRow> rows = new AList <QueryRow>();

            cursor.MoveToNext();
            while (!cursor.IsAfterLast())
            {
                JsonDocument keyDoc   = new JsonDocument(cursor.GetBlob(0));
                JsonDocument valueDoc = new JsonDocument(cursor.GetBlob(1));
                System.Diagnostics.Debug.Assert((keyDoc != null));
                object keyObject = keyDoc.JsonObject();
                if (group && !GroupTogether(keyObject, lastKey, groupLevel))
                {
                    if (lastKey != null)
                    {
                        // This pair starts a new group, so reduce & record the last one:
                        object reduced = (reduceBlock != null) ? reduceBlock.Reduce(keysToReduce, valuesToReduce
                                                                                    , false) : null;
                        object   key = GroupKey(lastKey, groupLevel);
                        QueryRow row = new QueryRow(null, 0, key, reduced, null);
                        row.SetDatabase(database);
                        rows.AddItem(row);
                        keysToReduce.Clear();
                        valuesToReduce.Clear();
                    }
                    lastKey = keyObject;
                }
                keysToReduce.AddItem(keyObject);
                valuesToReduce.AddItem(valueDoc.JsonObject());
                cursor.MoveToNext();
            }
            if (keysToReduce.Count > 0)
            {
                // Finish the last group (or the entire list, if no grouping):
                object key     = group ? GroupKey(lastKey, groupLevel) : null;
                object reduced = (reduceBlock != null) ? reduceBlock.Reduce(keysToReduce, valuesToReduce
                                                                            , false) : null;
                QueryRow row = new QueryRow(null, 0, key, reduced, null);
                row.SetDatabase(database);
                rows.AddItem(row);
            }
            return(rows);
        }
Esempio n. 2
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;
		}
Esempio n. 3
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);
        }
Esempio n. 4
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);
		}
Esempio n. 5
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.StartKey = "2";
            options.EndKey   = "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.Document.Id);
            options.SetKeys(docIds);
            allDocs      = database.GetAllDocs(options);
            expectedRows = new AList <QueryRow>();
            expectedRows.AddItem(expected2);
            expectedQueryResult = CreateExpectedQueryResult(expectedRows, 0);
            NUnit.Framework.Assert.AreEqual(expectedQueryResult, allDocs);
        }
Esempio n. 6
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;
 }
Esempio n. 7
0
 internal IList<QueryRow> ReducedQuery(Cursor cursor, bool group, int groupLevel)
 {
     IList<object> keysToReduce = null;
     IList<object> valuesToReduce = null;
     object lastKey = null;
     if (GetReduce() != null)
     {
         keysToReduce = new AList<object>(ReduceBatchSize);
         valuesToReduce = new AList<object>(ReduceBatchSize);
     }
     IList<QueryRow> rows = new AList<QueryRow>();
     cursor.MoveToNext();
     while (!cursor.IsAfterLast())
     {
         JsonDocument keyDoc = new JsonDocument(cursor.GetBlob(0));
         JsonDocument valueDoc = new JsonDocument(cursor.GetBlob(1));
         System.Diagnostics.Debug.Assert((keyDoc != null));
         object keyObject = keyDoc.JsonObject();
         if (group && !GroupTogether(keyObject, lastKey, groupLevel))
         {
             if (lastKey != null)
             {
                 // This pair starts a new group, so reduce & record the last one:
                 object reduced = (reduceBlock != null) ? reduceBlock.Reduce(keysToReduce, valuesToReduce
                     , false) : null;
                 object key = GroupKey(lastKey, groupLevel);
                 QueryRow row = new QueryRow(null, 0, key, reduced, null);
                 row.SetDatabase(database);
                 rows.AddItem(row);
                 keysToReduce.Clear();
                 valuesToReduce.Clear();
             }
             lastKey = keyObject;
         }
         keysToReduce.AddItem(keyObject);
         valuesToReduce.AddItem(valueDoc.JsonObject());
         cursor.MoveToNext();
     }
     if (keysToReduce.Count > 0)
     {
         // Finish the last group (or the entire list, if no grouping):
         object key = group ? GroupKey(lastKey, groupLevel) : null;
         object reduced = (reduceBlock != null) ? reduceBlock.Reduce(keysToReduce, valuesToReduce
             , false) : null;
         QueryRow row = new QueryRow(null, 0, key, reduced, null);
         row.SetDatabase(database);
         rows.AddItem(row);
     }
     return rows;
 }