diff --git a/src/Couchbase.Lite.Tests.Shared/QueryTest.cs b/src/Couchbase.Lite.Tests.Shared/QueryTest.cs index ebfb46457..aebfffcd2 100644 --- a/src/Couchbase.Lite.Tests.Shared/QueryTest.cs +++ b/src/Couchbase.Lite.Tests.Shared/QueryTest.cs @@ -659,6 +659,68 @@ public void TestGroupBy() } } + [Fact] + public void TestParameters() + { + LoadNumbers(10); + + var NUMBER1 = Expression.Property("number1"); + var PARAM_N1 = Expression.Parameter("num1"); + var PARAM_N2 = Expression.Parameter("num2"); + + using (var q = Query.Select(SelectResult.Expression(NUMBER1)) + .From(DataSource.Database(Db)) + .Where(NUMBER1.Between(PARAM_N1, PARAM_N2)) + .OrderBy(Ordering.Expression(NUMBER1))) { + q.Parameters.Set("num1", 2); + q.Parameters.Set("num2", 5); + + var expectedNumbers = new[] {2, 3, 4, 5}; + var numRows = VerifyQuery(q, (n, row) => + { + var number = row.GetInt(0); + number.Should().Be(expectedNumbers[n - 1]); + }); + + numRows.Should().Be(4); + } + } + + [Fact] + public void TestMeta() + { + LoadNumbers(5); + + var DOC_ID = Expression.Meta().DocumentID; + var DOC_SEQ = Expression.Meta().Sequence; + var NUMBER1 = Expression.Property("number1"); + + var RES_DOC_ID = SelectResult.Expression(DOC_ID); + var RES_DOC_SEQ = SelectResult.Expression(DOC_SEQ); + var RES_NUMBER1 = SelectResult.Expression(NUMBER1); + + using (var q = Query.Select(RES_DOC_ID, RES_DOC_SEQ, RES_NUMBER1) + .From(DataSource.Database(Db)) + .OrderBy(Ordering.Expression(DOC_SEQ))) { + var expectedDocIDs = new[] {"doc1", "doc2", "doc3", "doc4", "doc5"}; + var expectedSeqs = new[] {1, 2, 3, 4, 5}; + var expectedNumbers = expectedSeqs; + + var numRows = VerifyQuery(q, (n, row) => + { + var docID = row.GetString(0); + var seq = row.GetInt(1); + var number = row.GetInt(2); + + docID.Should().Be(expectedDocIDs[n - 1]); + seq.Should().Be(expectedSeqs[n - 1]); + number.Should().Be(expectedNumbers[n - 1]); + }); + + numRows.Should().Be(5); + } + } + private bool TestWhereCompareValidator(IDictionary properties, object context) { var ctx = (Func)context; diff --git a/src/Couchbase.Lite/API/Query/Expression.cs b/src/Couchbase.Lite/API/Query/Expression.cs index 6e4d0c657..4af657286 100644 --- a/src/Couchbase.Lite/API/Query/Expression.cs +++ b/src/Couchbase.Lite/API/Query/Expression.cs @@ -41,9 +41,15 @@ internal static IExpression Group(params IExpression[] expressions) throw new NotImplementedException(); } - internal static IMeta Meta() + /// + /// Creates an object that can generate expressions for retrieving metadata about + /// a result + /// + /// An object that can generate expressions for retrieving metadata about + /// a result + public static IMeta Meta() { - throw new NotImplementedException(); + return new QueryMeta(); } /// @@ -93,7 +99,7 @@ public static IExpression Parameter(string name) /// /// The name of the property to fetch /// An expression representing the value of a named property - public static IPropertySource Property(string property) + public static IPropertyExpression Property(string property) { return new QueryTypeExpression(property, ExpressionType.KeyPath); } diff --git a/src/Couchbase.Lite/API/Query/IMeta.cs b/src/Couchbase.Lite/API/Query/IMeta.cs index d4244ef4f..b95a93612 100644 --- a/src/Couchbase.Lite/API/Query/IMeta.cs +++ b/src/Couchbase.Lite/API/Query/IMeta.cs @@ -21,22 +21,24 @@ namespace Couchbase.Lite.Query { - internal interface IMeta + /// + /// An interface representing an object that can generate expressions + /// for retrieving metadata information during an + /// + public interface IMeta { #region Properties - IMetaSource DocumentID { get; } + /// + /// Gets an expression for retrieving the unique ID of a document + /// + IMetaExpression DocumentID { get; } - IMetaSource Sequence { get; } - - #endregion - } - - internal interface IMetaSource : IExpression - { - #region Public Methods - - IExpression From(string alias); + /// + /// Gets an expression for retrieving the sequence of a document + /// (i.e. the auto-incrementing entry in the database) + /// + IMetaExpression Sequence { get; } #endregion } diff --git a/src/Couchbase.Lite/API/Query/IMetaExpression.cs b/src/Couchbase.Lite/API/Query/IMetaExpression.cs new file mode 100644 index 000000000..e952b886d --- /dev/null +++ b/src/Couchbase.Lite/API/Query/IMetaExpression.cs @@ -0,0 +1,41 @@ +// +// IMetaExpression.cs +// +// Author: +// Jim Borden +// +// Copyright (c) 2017 Couchbase, Inc All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +namespace Couchbase.Lite.Query +{ + /// + /// Represents an expression that is meant to retrieve metadata information + /// inside of an + /// + public interface IMetaExpression : IExpression + { + #region Public Methods + + /// + /// Specifies the source to retrieve the information from + /// if multiple sources are used in a query + /// + /// The name of the data source + /// The expression with the alias added + IExpression From(string alias); + + #endregion + } +} \ No newline at end of file diff --git a/src/Couchbase.Lite/API/Query/IPropertySource.cs b/src/Couchbase.Lite/API/Query/IPropertyExpression.cs similarity index 94% rename from src/Couchbase.Lite/API/Query/IPropertySource.cs rename to src/Couchbase.Lite/API/Query/IPropertyExpression.cs index de1185ecb..e68ae6b0f 100644 --- a/src/Couchbase.Lite/API/Query/IPropertySource.cs +++ b/src/Couchbase.Lite/API/Query/IPropertyExpression.cs @@ -1,5 +1,5 @@ // -// IPropertySource.cs +// IPropertyExpression.cs // // Author: // Jim Borden @@ -21,19 +21,19 @@ namespace Couchbase.Lite.Query { - /// + /// /// An interface for an expression that will retrieve a property - /// from a keypath + /// from a keypath /// - public interface IPropertySource : IExpression + public interface IPropertyExpression : IExpression { #region Public Methods - /// + /// /// Specifies where to retrieve the property from (necessary - /// in instances where the query is coming from multiple sources) - /// - /// The alias of the source to retrieve from + /// in instances where the query is coming from multiple sources) + /// + /// The alias of the source to retrieve from /// The expression, for further processing IExpression From(string alias); diff --git a/src/Couchbase.Lite/Query/QueryMeta.cs b/src/Couchbase.Lite/Query/QueryMeta.cs new file mode 100644 index 000000000..22e3dff0c --- /dev/null +++ b/src/Couchbase.Lite/Query/QueryMeta.cs @@ -0,0 +1,35 @@ +// +// QueryMeta.cs +// +// Author: +// Jim Borden +// +// Copyright (c) 2017 Couchbase, Inc All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +using Couchbase.Lite.Query; + +namespace Couchbase.Lite.Internal.Query +{ + internal sealed class QueryMeta : IMeta + { + #region Properties + + public IMetaExpression DocumentID => new QueryTypeExpression("_id", ExpressionType.KeyPath); + + public IMetaExpression Sequence => new QueryTypeExpression("_sequence", ExpressionType.KeyPath); + + #endregion + } +} \ No newline at end of file diff --git a/src/Couchbase.Lite/Query/QueryTypeExpression.cs b/src/Couchbase.Lite/Query/QueryTypeExpression.cs index b38c5e9c6..4c88b77a3 100644 --- a/src/Couchbase.Lite/Query/QueryTypeExpression.cs +++ b/src/Couchbase.Lite/Query/QueryTypeExpression.cs @@ -35,7 +35,7 @@ internal enum ExpressionType Aggregate, } - internal sealed class QueryTypeExpression : QueryExpression, IPropertySource + internal sealed class QueryTypeExpression : QueryExpression, IPropertyExpression, IMetaExpression { #region Variables