/// <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; }
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; }