-
Notifications
You must be signed in to change notification settings - Fork 49
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
DDB Mapper filter expressions (runtime components) #1401
DDB Mapper filter expressions (runtime components) #1401
Conversation
A new generated diff is ready to view.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Captured some notes from a live code review with the team today. More comments/reviews to follow.
/** | ||
* Creates an equality expression for verifying two expressions are equal to each other | ||
* @param value The other value in the comparison | ||
*/ | ||
public infix fun Expression.eq(value: Boolean?): BooleanExpr = eq(LiteralExpr(value)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
live review: Can we collapse KDocs for multiple methods into a single shared instance?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Turns out we can but it only affects Dokka-generated documentation. IntelliJ will only find KDocs directly attached to each overload. I'm going to leave the documentation on overloads for the time being.
/** | ||
* Creates a range expression for verifying this expression is in the given range | ||
* @param range The range to check | ||
*/ | ||
@Suppress("INAPPLICABLE_JVM_NAME") | ||
@JvmName("isInRangeNumber") | ||
public infix fun <N> AttributePath.isIn(range: ClosedRange<N>): BooleanExpr where N : Number, N : Comparable<N> = | ||
isBetween(LiteralExpr(range.start), LiteralExpr(range.endInclusive)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
live review: Should we support open ranges now or in the future? Investigate and/or leave a TODO
* Several additional filter expressions are possible via the following methods/properties: | ||
* | ||
* * [contains] — checks if a string/list attribute value contains the given value | ||
* * [exists] — checks if _any value_ (including `null`) exists for an attribute | ||
* * [notExists] — checks if no value is present for an attribute (i.e., the attribute is "undefined" for an item) | ||
* * [isOfType] — checks if an attribute value is of the given type | ||
* * [size] — gets the size of an attribute (e.g., number of elements in list/map/set, the length of a string, etc.) | ||
* * [startsWith] — checks if a string attribute value starts with the given value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
live review: Here and elsewhere when referring to Kotlin-ized names of DDB primitives, mention the underlying primitive to help users get up to speed, transition from another mapper, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also add a few examples here.
settings.gradle.kts
Outdated
include(":hll:dynamodb-mapper:tests:dynamodb-mapper-schema-generator-plugin-test") | ||
// include(":hll:dynamodb-mapper:tests:dynamodb-mapper-schema-generator-plugin-test") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
live review: accidental inclusion, remove
/** | ||
* Represents any kind of expression. This is an abstract top-level interface and describes no details about an | ||
* expression on its own. Expressions may be of various specific types (e.g., [AttributePath], [ComparisonExpr], | ||
* [AndExpr], etc.) each of which have specific data detailing the expression. | ||
* | ||
* [Expression] and its derivatives support the [visitor design pattern](https://en.wikipedia.org/wiki/Visitor_pattern) | ||
* by way of an [accept] method. | ||
*/ | ||
public sealed interface Expression { | ||
/** | ||
* Accepts a visitor that is traversing an expression tree by dispatching to a subtype implementation. Subtype | ||
* implementations MUST call the [ExpressionVisitor.visit] overload for their concrete type (effectively forming a | ||
* [double dispatch](https://en.wikipedia.org/wiki/Double_dispatch)) and MUST return the resulting value. | ||
* @param visitor The [ExpressionVisitor] that is traversing an expression | ||
*/ | ||
public fun <T> accept(visitor: ExpressionVisitor<T>): T | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
live review: split out hierarchy into different smaller files
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No strong comments / suggestions outside of what we covered in the live review!
String("S"), | ||
|
||
/** | ||
* String set data type, denoted in DynamoDB as `S` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: SS
* * The value of attribute `bar` is less than the value of `baz` **–and–** the value of `baz` is greater/equal to `42` | ||
* * The value of attribute `qux` is not one of `"ready"`, `"steady"`, or `"go"` | ||
* | ||
* This is roughly equivalent to the Kotlin syntax: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
roughly equivalent -> logically equivalent?
GREATER_THAN(">"), | ||
|
||
/** | ||
* A greater-than-or-equal-to comparison, equivalent to `>=` in Kotlin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: "in Kotlin and DynamoDB"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
opinion: I feel like the implementations don't need to repeat the KDocs of what they are implementing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you clarify what you mean? This ScalarFunc
enum doesn't implement a particular interface...it identifies a particular low-level function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is referring to the entire ExpressionImpls.kt
file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh jeez, I can't read. 🤦♂️
Yeah, I can remove the KDocs for the internal
implementations. Still calibrating when it's helpful to leave KDocs on non-public
stuff vs when it's just noise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I was thinking in this case they are repeated on the public interfaces, so the internal implementations don't need them
…heir own files, revert accidental settings.gradle.kts change, clean up various KDocs
Quality Gate passedIssues Measures |
A new generated diff is ready to view.
|
…lin (#1451) * initial poc commit of DynamoDB Mapper (#1232) * add support for Mapper initialization (#1237) * implement mapper pipeline (#1266) * initial implementation of codegen for low-level operations/types (#1357) * initial implementation of secondary index support (#1375) * Create new codegen module and refactor annotation processor to use it (#1382) * feat: add Schema generator Gradle plugin (#1385) * Fix plugin test package * add attribute converters for "standard" values (#1381) * fix: schema generator plugin test module (#1394) * feat: annotation processor codegen configuration (#1392) * feat: add `@DynamoDbIgnore` annotation (#1402) * DDB Mapper filter expressions (runtime components) (#1401) * feat: basic annotation processing (#1399) * add DSL overloads, paginators, and better builder integration for DDB Mapper ops codegen (#1409) * chore: split dynamodb-mapper-codegen into two modules (#1414) * emit DDB_MAPPER business metric (#1426) * feat: setup DynamoDbMapper publication (#1419) * DDB Mapper filter expressions (codegen components) (#1424) * correct docs * mark every HLL/DDBM API experimental (#1428) * fix accidental inclusion of expression attribute members in high-level DynamoDB Mapper requests (#1432) * Upgrade to latest build plugin version * fix: various issues found during testing (#1450) * chore: update Athena changelog notes for 1.3.57 (2024-10-18) release (#1449) * feat: update AWS API models * feat: update AWS service endpoints metadata * chore: release 1.3.60 * chore: bump snapshot version to 1.3.61-SNAPSHOT * feat: initial release of Developer Preview of DynamoDB Mapper for Kotlin * Fix Kotlin gradle-plugin version * fix: ddb mapper tests (#1453) * Bump build plugin version --------- Co-authored-by: Matas <lauzmata@amazon.com> Co-authored-by: aws-sdk-kotlin-ci <aws-kotlin-sdk-automation@amazon.com>
Issue #
Related to #76
Description of changes
This change adds low-level filter expressions support to the runtime, although nothing uses them yet. The filter DSL is defined in the
Filter
interface and will eventually (in the next PR) be part of a Lambda signature in a codegenned member for operation requests.Something like this:
Callers will then use this when building their query structures to specify their filter expression (if desired):
In addition to the normal things, I could especially use feedback on the DSL—names, conventions, types, etc. If it's incomprehensible to you then it'll probably be even worse for users!
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.