示例#1
0
        /// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception>
        internal IList<QueryRow> ReducedQuery(Cursor cursor, Boolean group, Int32 groupLevel)
        {
            IList<object> keysToReduce = null;
            IList<object> valuesToReduce = null;
            object lastKey = null;

            var reduce = Reduce;
            // FIXME: If reduce is null, then so are keysToReduce and ValuesToReduce, which can throw an NRE below.
            if (reduce != null)
            {
                keysToReduce = new AList<Object>(ReduceBatchSize);
                valuesToReduce = new AList<Object>(ReduceBatchSize);
            }

            var rows = new AList<QueryRow>();
            cursor.MoveToNext();

            while (!cursor.IsAfterLast())
            {
                var keyData = FromJSON(cursor.GetBlob(0));
                var value = FromJSON(cursor.GetBlob(1));
                System.Diagnostics.Debug.Assert((keyData != null));
                if (group && !GroupTogether(keyData, lastKey, groupLevel))
                {
                    if (lastKey != null)
                    {
                        // This pair starts a new group, so reduce & record the last one:
                        var reduced = (reduce != null) ? reduce(keysToReduce, valuesToReduce, false) : null;

                        var key = GroupKey(lastKey, groupLevel);
                        var row = new QueryRow(null, 0, key, reduced, null);
                        row.Database = Database;
                        rows.AddItem(row); // NOTE.ZJG: Change to `yield return row` to convert to a generator.

                        keysToReduce.Clear();
                        valuesToReduce.Clear();
                    }
                    lastKey = keyData;
                }
                keysToReduce.AddItem(keyData);
                valuesToReduce.AddItem(value);
                cursor.MoveToNext();
            }
            // NOTE.ZJG: Need to handle grouping differently if switching this to a generator.
            if (keysToReduce.Count > 0)
            {
                // Finish the last group (or the entire list, if no grouping):
                var key = group ? GroupKey(lastKey, groupLevel) : null;
                var reduced = (reduce != null) ? reduce(keysToReduce, valuesToReduce, false) : null;
                var row = new QueryRow(null, 0, key, reduced, null);
                row.Database = Database;
                rows.AddItem(row);
            }
            return rows;
        }
        /// <summary>
        /// Executes only read-only SQL.
        /// </summary>
        /// <returns>The query.</returns>
        /// <param name="sql">Sql.</param>
        /// <param name="paramArgs">Parameter arguments.</param>
        public Cursor IntransactionRawQuery(String sql, params Object[] paramArgs)
        {
            if (!IsOpen)
            {
                Open(Path);
            }

            if (transactionCount == 0) 
            {
                return RawQuery(sql, paramArgs);
            }

            var t = Factory.StartNew(() =>
            {
                Cursor cursor = null;
                sqlite3_stmt command = null;
                try 
                {
                    Log.V(TAG, "RawQuery sql: {0} ({1})", sql, String.Join(", ", paramArgs.ToStringArray()));
                    command = BuildCommand (_writeConnection, sql, paramArgs);
                    cursor = new Cursor(command);
                }
                catch (Exception e) 
                {
                    if (command != null) 
                    {
                        command.Dispose();
                    }
                    Log.E(TAG, "Error executing raw query '{0}'".Fmt(sql), e);
                    LastErrorCode = raw.sqlite3_errcode(_writeConnection);
                    throw;
                }
                return cursor;
            });

            return t.Result;
        }
        /// <summary>
        /// Executes only read-only SQL.
        /// </summary>
        /// <returns>The query.</returns>
        /// <param name="sql">Sql.</param>
        /// <param name="paramArgs">Parameter arguments.</param>
        public Cursor RawQuery(String sql, params Object[] paramArgs)
        {
            if (!IsOpen)
            {
                Open(Path);
            }

            Cursor cursor = null;
            sqlite3_stmt command = null;

            var t = Factory.StartNew (() => 
            {
                try {
                    Log.V (TAG, "RawQuery sql: {0} ({1})", sql, String.Join (", ", paramArgs.ToStringArray ()));
                    command = BuildCommand (_readConnection, sql, paramArgs);
                    cursor = new Cursor (command);
                } catch (Exception e) {
                    if (command != null) {
                        command.Dispose ();
                    }
                    var args = paramArgs == null 
                    ? String.Empty 
                    : String.Join (",", paramArgs.ToStringArray ());
                    Log.E (TAG, "Error executing raw query '{0}' is values '{1}' {2}".Fmt (sql, args, _readConnection.errmsg ()), e);
                    LastErrorCode = raw.sqlite3_errcode(_readConnection);
                    throw;
                }
                return cursor;
            });

            return t.Result;
        }
示例#4
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;
 }