Skip to content

Expressions #1032

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
Jan 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
7be39ba
Implement boolean expressions (#1025)
katcharov Nov 2, 2022
2f33777
Implement filter, map, reduce (#1031)
katcharov Nov 9, 2022
6acb798
Implement eq, ne, gt, gte, lt, lte (#1033)
katcharov Nov 10, 2022
2d7c03c
Implement string expressions (#1036)
katcharov Nov 15, 2022
6768db0
Implement arithmetic expressions (#1037)
katcharov Nov 29, 2022
7ac3ccd
Implement array expressions (#1043)
katcharov Nov 29, 2022
8b69f18
Implement date expressions (#1045)
katcharov Nov 29, 2022
47efc90
Implement conversion/type expressions (#1050)
katcharov Dec 13, 2022
3dcd2ff
Implement document expressions (#1052)
katcharov Dec 13, 2022
1ce4912
Replace reduce with individual reductions (#1053)
katcharov Jan 18, 2023
0bfce8e
Implement map expressions (#1054)
katcharov Jan 19, 2023
a5245b0
Implement switch expression (#1055)
katcharov Jan 19, 2023
6436f96
Test expressions in context (#1057)
katcharov Jan 19, 2023
25553d1
Add javadoc for boolean, date, number, integer, and expression (#1059)
katcharov Nov 30, 2022
1d9964b
Update and add documentation (#1059)
katcharov Dec 5, 2022
347ab45
Add `@MqlUnchecked` and a few usage examples (#1059)
stIncMale Jan 18, 2023
7ce9cb5
Add has to document, add tests (#1070)
katcharov Jan 20, 2023
75cb0b7
Add javadocs for remaining classes (#1070)
katcharov Jan 20, 2023
8de3396
5.2 annotations (#1070)
katcharov Jan 23, 2023
5680102
5.0 annotations (#1070)
katcharov Jan 23, 2023
b80bfcd
4.4 annotations (#1070)
katcharov Jan 23, 2023
6f24bea
4.2 annotations (#1070)
katcharov Jan 23, 2023
b1ae65d
4.0 annotations (#1070)
katcharov Jan 23, 2023
678cef8
Update and add documentation, add tests, fix minor issues (#1070)
katcharov Jan 23, 2023
441bc53
Rename to Mql (automated) (#1073)
katcharov Jan 27, 2023
6bbb231
Rename methods (automated) (#1073)
katcharov Jan 27, 2023
6588406
Update naming, terms, and missing checks and annotations (#1073)
katcharov Jan 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions config/checkstyle/suppressions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,6 @@
<suppress checks="ParameterName" files=".*org[\\/]bson[\\/]codecs[\\/]pojo[\\/]bench[\\/].*"/>
<suppress checks="Regexp" files=".*org[\\/]bson[\\/]codecs[\\/]pojo[\\/]bench[\\/].*"/>

<!-- Complicated expressions for demo purposes -->
<suppress checks="SimplifyBooleanExpressionCheck" files="ExpressionsFunctionalTest"/>
</suppressions>
3 changes: 3 additions & 0 deletions driver-core/src/main/com/mongodb/MongoClientSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.mongodb.annotations.Immutable;
import com.mongodb.annotations.NotThreadSafe;
import com.mongodb.client.gridfs.codecs.GridFSFileCodecProvider;
import com.mongodb.client.model.mql.ExpressionCodecProvider;
import com.mongodb.client.model.geojson.codecs.GeoJsonCodecProvider;
import com.mongodb.connection.ClusterSettings;
import com.mongodb.connection.ConnectionPoolSettings;
Expand Down Expand Up @@ -76,6 +77,7 @@ public final class MongoClientSettings {
new JsonObjectCodecProvider(),
new BsonCodecProvider(),
new EnumCodecProvider(),
new ExpressionCodecProvider(),
new Jep395RecordCodecProvider()));

private final ReadPreference readPreference;
Expand Down Expand Up @@ -123,6 +125,7 @@ public final class MongoClientSettings {
* <li>{@link org.bson.codecs.JsonObjectCodecProvider}</li>
* <li>{@link org.bson.codecs.BsonCodecProvider}</li>
* <li>{@link org.bson.codecs.EnumCodecProvider}</li>
* <li>{@link ExpressionCodecProvider}</li>
* <li>{@link com.mongodb.Jep395RecordCodecProvider}</li>
* </ul>
*
Expand Down
42 changes: 42 additions & 0 deletions driver-core/src/main/com/mongodb/annotations/Sealed.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright 2008-present MongoDB, Inc.
* Copyright 2010 The Guava Authors
* Copyright 2011 The Guava Authors
*
* 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.
*/

package com.mongodb.annotations;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Signifies that the annotated class or interface should be treated as sealed:
* it must not be extended or implemented.
*
* <p>Using such classes and interfaces is no different from using ordinary
* unannotated classes and interfaces.
*
* <p>This annotation does not imply that the API is experimental or
* {@link Beta}, or that the quality or performance of the API is inferior.
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
@Documented
@Sealed
public @interface Sealed {
}
268 changes: 268 additions & 0 deletions driver-core/src/main/com/mongodb/client/model/mql/Branches.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
/*
* Copyright 2008-present MongoDB, Inc.
*
* 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.
*/

package com.mongodb.client.model.mql;

import com.mongodb.annotations.Beta;
import com.mongodb.assertions.Assertions;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

import static com.mongodb.client.model.mql.MqlUnchecked.Unchecked.TYPE_ARGUMENT;

/**
* Branches are used in {@linkplain MqlValue#switchOn}, and
* define a sequence of checks that will be performed. The first check
* to succeed will produce the value that it specifies. If no check succeeds,
* then the operation
* {@linkplain BranchesIntermediary#defaults(Function) defaults} to a default
* value, or if none is specified, the operation will cause an error.
*
* @param <T> the type of the values that may be checked.
* @since 4.9.0
*/
@Beta(Beta.Reason.CLIENT)
public final class Branches<T extends MqlValue> {

Branches() {
}

private static <T extends MqlValue, R extends MqlValue> BranchesIntermediary<T, R> with(final Function<T, SwitchCase<R>> switchCase) {
List<Function<T, SwitchCase<R>>> v = new ArrayList<>();
v.add(switchCase);
return new BranchesIntermediary<>(v);
}

private static <T extends MqlValue> MqlExpression<?> mqlEx(final T value) {
return (MqlExpression<?>) value;
}

// is fn

/**
* A successful check for the specified {@code predicate}
* produces a value specified by the {@code mapping}.
*
* @param predicate the predicate.
* @param mapping the mapping.
* @param <R> the type of the produced value.
* @return the appended sequence of checks.
*/
public <R extends MqlValue> BranchesIntermediary<T, R> is(final Function<? super T, MqlBoolean> predicate, final Function<? super T, ? extends R> mapping) {
Assertions.notNull("predicate", predicate);
Assertions.notNull("mapping", mapping);
return with(value -> new SwitchCase<>(predicate.apply(value), mapping.apply(value)));
}

// eq lt lte

/**
* A successful check for {@linkplain MqlValue#eq equality}
* produces a value specified by the {@code mapping}.
*
* @param v the value to check against.
* @param mapping the mapping.
* @param <R> the type of the produced value.
* @return the appended sequence of checks.
*/
public <R extends MqlValue> BranchesIntermediary<T, R> eq(final T v, final Function<? super T, ? extends R> mapping) {
Assertions.notNull("v", v);
Assertions.notNull("mapping", mapping);
return is(value -> value.eq(v), mapping);
}

/**
* A successful check for being
* {@linkplain MqlValue#lt less than}
* the provided value {@code v}
* produces a value specified by the {@code mapping}.
*
* @param v the value to check against.
* @param mapping the mapping.
* @param <R> the type of the produced value.
* @return the appended sequence of checks.
*/
public <R extends MqlValue> BranchesIntermediary<T, R> lt(final T v, final Function<? super T, ? extends R> mapping) {
Assertions.notNull("v", v);
Assertions.notNull("mapping", mapping);
return is(value -> value.lt(v), mapping);
}

/**
* A successful check for being
* {@linkplain MqlValue#lte less than or equal to}
* the provided value {@code v}
* produces a value specified by the {@code mapping}.
*
* @param v the value to check against.
* @param mapping the mapping.
* @param <R> the type of the produced value.
* @return the appended sequence of checks.
*/
public <R extends MqlValue> BranchesIntermediary<T, R> lte(final T v, final Function<? super T, ? extends R> mapping) {
Assertions.notNull("v", v);
Assertions.notNull("mapping", mapping);
return is(value -> value.lte(v), mapping);
}

// is type

/**
* A successful check for
* {@linkplain MqlValue#isBooleanOr(MqlBoolean) being a boolean}
* produces a value specified by the {@code mapping}.
*
* @param mapping the mapping.
* @return the appended sequence of checks.
* @param <R> the type of the produced value.
*/
public <R extends MqlValue> BranchesIntermediary<T, R> isBoolean(final Function<? super MqlBoolean, ? extends R> mapping) {
Assertions.notNull("mapping", mapping);
return is(v -> mqlEx(v).isBoolean(), v -> mapping.apply((MqlBoolean) v));
}

/**
* A successful check for
* {@linkplain MqlValue#isNumberOr(MqlNumber) being a number}
* produces a value specified by the {@code mapping}.
*
* @mongodb.server.release 4.4
* @param mapping the mapping.
* @return the appended sequence of checks.
* @param <R> the type of the produced value.
*/
public <R extends MqlValue> BranchesIntermediary<T, R> isNumber(final Function<? super MqlNumber, ? extends R> mapping) {
Assertions.notNull("mapping", mapping);
return is(v -> mqlEx(v).isNumber(), v -> mapping.apply((MqlNumber) v));
}

/**
* A successful check for
* {@linkplain MqlValue#isIntegerOr(MqlInteger) being an integer}
* produces a value specified by the {@code mapping}.
*
* @mongodb.server.release 4.4
* @param mapping the mapping.
* @return the appended sequence of checks.
* @param <R> the type of the produced value.
*/
public <R extends MqlValue> BranchesIntermediary<T, R> isInteger(final Function<? super MqlInteger, ? extends R> mapping) {
Assertions.notNull("mapping", mapping);
return is(v -> mqlEx(v).isInteger(), v -> mapping.apply((MqlInteger) v));
}

/**
* A successful check for
* {@linkplain MqlValue#isStringOr(MqlString) being a string}
* produces a value specified by the {@code mapping}.
*
* @param mapping the mapping.
* @return the appended sequence of checks.
* @param <R> the type of the produced value.
*/
public <R extends MqlValue> BranchesIntermediary<T, R> isString(final Function<? super MqlString, ? extends R> mapping) {
Assertions.notNull("mapping", mapping);
return is(v -> mqlEx(v).isString(), v -> mapping.apply((MqlString) v));
}

/**
* A successful check for
* {@linkplain MqlValue#isDateOr(MqlDate) being a date}
* produces a value specified by the {@code mapping}.
*
* @param mapping the mapping.
* @return the appended sequence of checks.
* @param <R> the type of the produced value.
*/
public <R extends MqlValue> BranchesIntermediary<T, R> isDate(final Function<? super MqlDate, ? extends R> mapping) {
Assertions.notNull("mapping", mapping);
return is(v -> mqlEx(v).isDate(), v -> mapping.apply((MqlDate) v));
}

/**
* A successful check for
* {@linkplain MqlValue#isArrayOr(MqlArray) being an array}
* produces a value specified by the {@code mapping}.
*
* <p>Warning: The type argument of the array is not
* enforced by the API. The use of this method is an
* unchecked assertion that the type argument is correct.
*
* @param mapping the mapping.
* @return the appended sequence of checks.
* @param <R> the type of the produced value.
* @param <Q> the type of the array.
*/
@SuppressWarnings("unchecked")
public <R extends MqlValue, Q extends MqlValue> BranchesIntermediary<T, R> isArray(final Function<? super MqlArray<@MqlUnchecked(TYPE_ARGUMENT) Q>, ? extends R> mapping) {
Assertions.notNull("mapping", mapping);
return is(v -> mqlEx(v).isArray(), v -> mapping.apply((MqlArray<Q>) v));
}

/**
* A successful check for
* {@linkplain MqlValue#isDocumentOr(MqlDocument) being a document}
* (or document-like value, see
* {@link MqlMap} and {@link MqlEntry})
* produces a value specified by the {@code mapping}.
*
* @param mapping the mapping.
* @return the appended sequence of checks.
* @param <R> the type of the produced value.
*/
public <R extends MqlValue> BranchesIntermediary<T, R> isDocument(final Function<? super MqlDocument, ? extends R> mapping) {
Assertions.notNull("mapping", mapping);
return is(v -> mqlEx(v).isDocumentOrMap(), v -> mapping.apply((MqlDocument) v));
}

/**
* A successful check for
* {@linkplain MqlValue#isMapOr(MqlMap) being a map}
* (or map-like value, see
* {@link MqlDocument} and {@link MqlEntry})
* produces a value specified by the {@code mapping}.
*
* <p>Warning: The type argument of the map is not
* enforced by the API. The use of this method is an
* unchecked assertion that the type argument is correct.
*
* @param mapping the mapping.
* @return the appended sequence of checks.
* @param <R> the type of the produced value.
* @param <Q> the type of the array.
*/
@SuppressWarnings("unchecked")
public <R extends MqlValue, Q extends MqlValue> BranchesIntermediary<T, R> isMap(final Function<? super MqlMap<@MqlUnchecked(TYPE_ARGUMENT) Q>, ? extends R> mapping) {
Assertions.notNull("mapping", mapping);
return is(v -> mqlEx(v).isDocumentOrMap(), v -> mapping.apply((MqlMap<Q>) v));
}

/**
* A successful check for
* {@linkplain MqlValues#ofNull()} being the null value}
* produces a value specified by the {@code mapping}.
*
* @param mapping the mapping.
* @return the appended sequence of checks.
* @param <R> the type of the produced value.
*/
public <R extends MqlValue> BranchesIntermediary<T, R> isNull(final Function<? super MqlValue, ? extends R> mapping) {
Assertions.notNull("mapping", mapping);
return is(v -> mqlEx(v).isNull(), v -> mapping.apply(v));
}
}
Loading