/// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception>
        internal IDictionary<String, Object> GetAllDocs(QueryOptions options)
        {
            var result = new Dictionary<String, Object>();
            var rows = new AList<QueryRow>();
            if (options == null)
                options = new QueryOptions();

            var includeDeletedDocs = (options.GetAllDocsMode() == AllDocsMode.IncludeDeleted);
            var updateSeq = 0L;
            if (options.IsUpdateSeq())
            {
                updateSeq = GetLastSequenceNumber();
            }

            // TODO: needs to be atomic with the following SELECT
            var 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;
                }
                var commaSeperatedIds = JoinQuotedObjects(options.GetKeys());
                sql.Append(String.Format(" revs.doc_id IN (SELECT doc_id FROM docs WHERE docid IN ({0})) AND", commaSeperatedIds));
            }
            sql.Append(" docs.doc_id = revs.doc_id AND current=1");

            if (!includeDeletedDocs)
            {
                sql.Append(" AND deleted=0");
            }

            var args = new AList<String>();
            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)
            {
                Debug.Assert((minKey is String));
                sql.Append((inclusiveMin ? " AND docid >= ?" : " AND docid > ?"));
                args.AddItem((string)minKey);
            }
            if (maxKey != null)
            {
                Debug.Assert((maxKey is string));
                sql.Append((inclusiveMax ? " AND docid <= ?" : " AND docid < ?"));
                args.AddItem((string)maxKey);
            }
            sql.Append(
                String.Format(" ORDER BY docid {0}, {1} revid DESC LIMIT ? OFFSET ?", 
                    options.IsDescending() ? "DESC" : "ASC", 
                    includeDeletedDocs ? "deleted ASC," : String.Empty
                )
            );
            args.AddItem(options.GetLimit().ToString());
            args.AddItem(options.GetSkip().ToString());

            Cursor cursor = null;
            var docs = new Dictionary<String, QueryRow>();
            try
            {
                cursor = StorageEngine.RawQuery(
                    sql.ToString(),
                    CommandBehavior.SequentialAccess,
                    args.ToArray()
                );

//                cursor.MoveToNext();

                var keepGoing = cursor.MoveToNext();
                while (keepGoing)
                {
                    var docNumericID = cursor.GetLong(0);

                    var includeDocs = options.IsIncludeDocs();

                    var docId = cursor.GetString(1);
                    var revId = cursor.GetString(2);
                    var sequenceNumber = cursor.GetLong(3);
                    byte[] json = null;
                    if (includeDocs)
                    {
                        json = cursor.GetBlob(4);
                    }
                    var deleted = includeDeletedDocs && cursor.GetInt(GetDeletedColumnIndex(options)) > 0;

                    IDictionary<String, Object> docContents = null;

                    if (includeDocs)
                    {
                        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:
                    var conflicts = new List<string>();
                    while (((keepGoing = cursor.MoveToNext())) && cursor.GetLong(0) == docNumericID)
                    {
                       if (options.GetAllDocsMode() == AllDocsMode.ShowConflicts || options.GetAllDocsMode() == AllDocsMode.OnlyConflicts)
                       {
                           if (conflicts.IsEmpty())
                           {
                               conflicts.AddItem(revId);
                           }
                           conflicts.AddItem(cursor.GetString(2));
                       }
                    }
                    if (options.GetAllDocsMode() == AllDocsMode.OnlyConflicts && conflicts.IsEmpty())
                    {
                       continue;
                    }
                    var value = new Dictionary<string, object>();
                    value["rev"] = revId;
                    value["_conflicts"] = conflicts;
                    if (includeDeletedDocs)
                    {
                        value["deleted"] = deleted;
                    }
                    var change = new QueryRow(docId, sequenceNumber, docId, value, docContents);
                    change.Database = this;

                    if (options.GetKeys() != null)
                    {
                        docs[docId] = change;
                    }
                    else
                    {
                        rows.AddItem(change);
                    }
                }
                if (options.GetKeys() != null)
                {
                    foreach (var docIdObject in options.GetKeys())
                    {
                        if (docIdObject is string)
                        {
                            var docId = (string)docIdObject;
                            var change = docs.Get(docId);
                            if (change == null)
                            {
                                var value = new Dictionary<string, object>();
                                var docNumericID = GetDocNumericID(docId);
                                if (docNumericID > 0)
                                {
                                    bool deleted;
                                    var outIsDeleted = new AList<bool>();
                                    var outIsConflict = new AList<bool>();
                                    var revId = WinningRevIDOfDoc(docNumericID, outIsDeleted, outIsConflict);
                                    if (outIsDeleted.Count > 0)
                                    {
                                        deleted = true;
                                    }
                                    if (revId != null)
                                    {
                                        value["rev"] = revId;
                                        value["deleted"] = true; // FIXME: SHould this be set the value of `deleted`?
                                    }
                                }
                                change = new QueryRow((value != null ? docId : null), 0, docId, value, null);
                                change.Database = this;
                            }
                            rows.AddItem(change);
                        }
                    }
                }
            }
            catch (SQLException e)
            {
                Log.E(Tag, "Error getting all docs", e);
                throw new CouchbaseLiteException("Error getting all docs", e, new Status(StatusCode.InternalServerError));
            }
            finally
            {
                if (cursor != null)
                    cursor.Close();
            }
            result["rows"] = rows;
            result["total_rows"] = rows.Count;
            result.Put("offset", options.GetSkip());
            if (updateSeq != 0)
            {
                result["update_seq"] = updateSeq;
            }
            return result;
        }
        internal int PruneRevsToMaxDepth(int maxDepth)
        {
            int outPruned = 0;
            bool shouldCommit = false;
            IDictionary<long, int> toPrune = new Dictionary<long, int>();
            if (maxDepth == 0)
            {
                maxDepth = MaxRevTreeDepth;
            }

            // First find which docs need pruning, and by how much:
            Cursor cursor = null;
            var sql = "SELECT doc_id, MIN(revid), MAX(revid) FROM revs GROUP BY doc_id";
            long docNumericID = -1;
            var minGen = 0;
            var maxGen = 0;
            try
            {
                cursor = StorageEngine.RawQuery(sql);
                while (cursor.MoveToNext())
                {
                    docNumericID = cursor.GetLong(0);
                    var minGenRevId = cursor.GetString(1);
                    var maxGenRevId = cursor.GetString(2);
                    minGen = RevisionInternal.GenerationFromRevID(minGenRevId);
                    maxGen = RevisionInternal.GenerationFromRevID(maxGenRevId);
                    if ((maxGen - minGen + 1) > maxDepth)
                    {
                        toPrune.Put(docNumericID, (maxGen - minGen));
                    }
                }

                BeginTransaction();

                if (toPrune.Count == 0)
                {
                    return 0;
                }

                foreach (long id in toPrune.Keys)
                {
                    string minIDToKeep = String.Format("{0}-", (toPrune.Get(id) + 1));
                    string[] deleteArgs = new string[] { System.Convert.ToString(docNumericID), minIDToKeep };
                    int rowsDeleted = StorageEngine.Delete("revs", "doc_id=? AND revid < ? AND current=0", deleteArgs);
                    outPruned += rowsDeleted;
                }
                shouldCommit = true;
            }
            catch (Exception e)
            {
                throw new CouchbaseLiteException(e, StatusCode.InternalServerError);
            }
            finally
            {
                EndTransaction(shouldCommit);
                if (cursor != null)
                {
                    cursor.Close();
                }
            }
            return outPruned;
        }
        public void throws_invalidcastexception_when_type_is_not_supported()
        {
            var dictionary = new Dictionary<string, string> { { "length", "1:10:10" } };

            Expect(() => dictionary.Get<TimeSpan>("length"), Throws.TypeOf<InvalidCastException>());
        }
Example #4
0
 static void CopyProxyPrefs(Dictionary proxy, ref Dictionary prefs) {
     var TKEY = "network.proxy.type";
     switch ((string)proxy.Get("proxyType", null)) {
         case "direct": prefs[TKEY] = 0; break;
         case "manual": prefs[TKEY] = 1; break;
         case "pac": prefs[TKEY] = 2; break;
         case "autodetect": prefs[TKEY] = 4; break;
         case "system": prefs[TKEY] = 5; break;
     }
     if (proxy.ContainsKey("proxyAutoconfigUrl"))
         prefs["network.proxy.autoconfig_url"] = proxy["proxyAutoconfigUrl"];
     SetProxyCapability(proxy, "ftpProxy", prefs, "network.proxy.ftp", "network.proxy.ftp_port");
     SetProxyCapability(proxy, "httpProxy", prefs, "network.proxy.http", "network.proxy.http_port");
     SetProxyCapability(proxy, "sslProxy", prefs, "network.proxy.ssl", "network.proxy.ssl_port");
     SetProxyCapability(proxy, "socksProxy", prefs, "network.proxy.socks", "network.proxy.socks_port");
 }
        public void throws_formatexception_when_value_cannot_be_parsed()
        {
            var dictionary = new Dictionary<string, string> { { "ID", "abc123" } };

            Expect(() => dictionary.Get<int>("ID"), Throws.TypeOf<FormatException>());
        }
Example #6
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;
		}
Example #7
0
 int IEntityOperator.UpdateValues(SchemaModel.Column keyColumn, SchemaModel.Table table, Dictionary<string, object> values)
 {
     var keyValue = values.Get(keyColumn.Name);
     if (keyValue == null)
     {
         throw new InvalidOperationException("字典未传入主键");
     }
     var updateSql = "UPDATE {0} SET {1} WHERE {2}";
     var tableName = _sqlBuilder.GetTableName(table);
     var sqlParameters = new Dictionary<string, object>();
     var setts = new List<string>();
     var alias = string.Empty;
     foreach (var key in values.Keys)
     {
         if (key == keyColumn.Name)
         {
             continue;
         }
         alias = ParserUtils.GenerateAlias(key);
         var set = string.Format("[{0}] = @{1}", key, alias);
         sqlParameters.Add(alias, values.Get(key));
         setts.Add(set);
     }
     alias = ParserUtils.GenerateAlias(keyColumn.Name);
     var condition = string.Format("[{0}] = @{1}", keyColumn.Name, alias);
     sqlParameters.Add(alias, keyValue);
     updateSql = string.Format(updateSql, tableName, string.Join(",", setts), condition);
     return _sqlExecutor.ExecuteNonQuery(updateSql, sqlParameters);
 }
Example #8
0
		private static Block[] BuildBlocks(Node[] statementNodes)
		{
			// a mapping from each target node to the block it begins
			IDictionary<Node, Block.FatBlock> theTargetBlocks = new Dictionary<Node, Block.FatBlock>();
			ObjArray theBlocks = new ObjArray();
			// there's a block that starts at index 0
			int beginNodeIndex = 0;
			for (int i = 0; i < statementNodes.Length; i++)
			{
				switch (statementNodes[i].GetType())
				{
					case Token.TARGET:
					{
						if (i != beginNodeIndex)
						{
							Block.FatBlock fb = NewFatBlock(beginNodeIndex, i - 1);
							if (statementNodes[beginNodeIndex].GetType() == Token.TARGET)
							{
								theTargetBlocks.Put(statementNodes[beginNodeIndex], fb);
							}
							theBlocks.Add(fb);
							// start the next block at this node
							beginNodeIndex = i;
						}
						break;
					}

					case Token.IFNE:
					case Token.IFEQ:
					case Token.GOTO:
					{
						Block.FatBlock fb = NewFatBlock(beginNodeIndex, i);
						if (statementNodes[beginNodeIndex].GetType() == Token.TARGET)
						{
							theTargetBlocks.Put(statementNodes[beginNodeIndex], fb);
						}
						theBlocks.Add(fb);
						// start the next block at the next node
						beginNodeIndex = i + 1;
						break;
					}
				}
			}
			if (beginNodeIndex != statementNodes.Length)
			{
				Block.FatBlock fb = NewFatBlock(beginNodeIndex, statementNodes.Length - 1);
				if (statementNodes[beginNodeIndex].GetType() == Token.TARGET)
				{
					theTargetBlocks.Put(statementNodes[beginNodeIndex], fb);
				}
				theBlocks.Add(fb);
			}
			// build successor and predecessor links
			for (int i_1 = 0; i_1 < theBlocks.Size(); i_1++)
			{
				Block.FatBlock fb = (Block.FatBlock)(theBlocks.Get(i_1));
				Node blockEndNode = statementNodes[fb.realBlock.itsEndNodeIndex];
				int blockEndNodeType = blockEndNode.GetType();
				if ((blockEndNodeType != Token.GOTO) && (i_1 < (theBlocks.Size() - 1)))
				{
					Block.FatBlock fallThruTarget = (Block.FatBlock)(theBlocks.Get(i_1 + 1));
					fb.AddSuccessor(fallThruTarget);
					fallThruTarget.AddPredecessor(fb);
				}
				if ((blockEndNodeType == Token.IFNE) || (blockEndNodeType == Token.IFEQ) || (blockEndNodeType == Token.GOTO))
				{
					Node target = ((Jump)blockEndNode).target;
					Block.FatBlock branchTargetBlock = theTargetBlocks.Get(target);
					target.PutProp(Node.TARGETBLOCK_PROP, branchTargetBlock.realBlock);
					fb.AddSuccessor(branchTargetBlock);
					branchTargetBlock.AddPredecessor(fb);
				}
			}
			Block[] result = new Block[theBlocks.Size()];
			for (int i_2 = 0; i_2 < theBlocks.Size(); i_2++)
			{
				Block.FatBlock fb = (Block.FatBlock)(theBlocks.Get(i_2));
				Block b = fb.realBlock;
				b.itsSuccessors = fb.GetSuccessors();
				b.itsPredecessors = fb.GetPredecessors();
				b.itsBlockID = i_2;
				result[i_2] = b;
			}
			return result;
		}
 protected internal override void ProcessInbox(RevisionList changes)
 {
     // Generate a set of doc/rev IDs in the JSON format that _revs_diff wants:
     // <http://wiki.apache.org/couchdb/HttpPostRevsDiff>
     IDictionary<string, IList<string>> diffs = new Dictionary<string, IList<string>>(
         );
     foreach (RevisionInternal rev in changes)
     {
         string docID = rev.GetDocId();
         IList<string> revs = diffs.Get(docID);
         if (revs == null)
         {
             revs = new AList<string>();
             diffs.Put(docID, revs);
         }
         revs.AddItem(rev.GetRevId());
         AddPending(rev);
     }
     // Call _revs_diff on the target db:
     Log.V(Log.TagSync, "%s: posting to /_revs_diff", this);
     Log.V(Log.TagSync, "%s | %s: processInbox() calling asyncTaskStarted()", this, Sharpen.Thread
         .CurrentThread());
     AsyncTaskStarted();
     SendAsyncRequest("POST", "/_revs_diff", diffs, new _RemoteRequestCompletionBlock_280
         (this, changes));
 }