Skip to content

Conversation

@lauzadis
Copy link
Member

Issue #

Description of changes

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@lauzadis lauzadis added the no-changelog Indicates that a changelog entry isn't required for a pull request. Use sparingly. label Sep 10, 2024
@lauzadis lauzadis requested a review from a team as a code owner September 10, 2024 14:36
@lauzadis lauzadis changed the title feat: add DynamoDbIgnore and DynamoDbItemConverter feat: add DynamoDbIgnore and DynamoDbItemConverter annotations Sep 10, 2024
@github-actions
Copy link

A new generated diff is ready to view.

  • No codegen difference in the AWS SDK

@lauzadis lauzadis changed the title feat: add DynamoDbIgnore and DynamoDbItemConverter annotations feat: add @DynamoDbIgnore and @DynamoDbItemConverter annotations Sep 10, 2024
* @param classDeclaration the [KSClassDeclaration] of the class
* @param ctx the [RenderContext] of the renderer
*/
@OptIn(KspExperimental::class)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: What do we need this for? Can we narrow the scope of this opt-in?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's needed for KSP's isAnnotationPresent function, it can be scoped down

Comment on lines 44 to 46
private val properties = classDeclaration.getAllProperties()
.filterNot { it.modifiers.contains(Modifier.PRIVATE) }
.filterNot { it.isAnnotationPresent(DynamoDbIgnore::class) }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style: Fluent call chaining should generally separate each member (e.g., getAllProperties) onto its own line. Additionally, stacking identical collection operations (e.g., filterNot) with different arguments is generally unnecessary and overly verbose.

private val properties = classDeclaration
    .getAllProperties()
    .filterNot { it.modifiers.contains(Modifier.PRIVATE)  || it.isAnnotationPresent(DynamoDbIgnore::class) }

Comment on lines 41 to 46
/**
* Specifies that a custom ItemConverter should be used to convert this class/interface.
* @param qualifiedName The fully qualified name of the item converter.
*/
@Target(AnnotationTarget.CLASS)
public annotation class DynamoDbItemConverter(val qualifiedName: String)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: Does having a separate annotation offer additional benefit over a converter: String? field on DynamoDbItem?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, there's not any specific benefit I was going for with this design choice. I'm open to making it a parameter on DynamoDbItem, I think anything works as long as we document it properly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did this refactor, the only problem was that annotation parameters cannot be nullable (String?) so I made it a String defaulted to the empty string

Comment on lines 62 to 71
private val itemConverter: Type
get() = run {
val qualifiedName = classDeclaration.getAnnotationsByType(DynamoDbItemConverter::class).singleOrNull()?.qualifiedName

return qualifiedName?.let {
val pkg = qualifiedName.substringBeforeLast(".")
val shortName = qualifiedName.removePrefix("$pkg.")
TypeRef(pkg, shortName)
} ?: TypeRef(ctx.pkg, "${className}Converter")
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: Does this need to be calculated on each call? Could it be calculated once instead?

private val itemConverter: Type = run {
    val qualifiedName = classDeclaration.getAnnotationsByType(DynamoDbItemConverter::class).singleOrNull()?.qualifiedName

    return qualifiedName?.let {
        val pkg = qualifiedName.substringBeforeLast(".")
        val shortName = qualifiedName.removePrefix("$pkg.")
        TypeRef(pkg, shortName)
    } ?: TypeRef(ctx.pkg, "${className}Converter")
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it should probably only be calculated once

@github-actions
Copy link

A new generated diff is ready to view.

  • No codegen difference in the AWS SDK

val result = runner.build()
assertContains(setOf(TaskOutcome.SUCCESS, TaskOutcome.UP_TO_DATE), result.task(":build")?.outcome)

// Schema should not exist
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small nit: this comment makes it seem like the assertion below should be false

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, when I was first writing this test I thought the schema file would not be generated because there's no item converter needed, but we still need to render the schema

IntConverter,
),
AttributeDescriptor(
"myCustomFirstName",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: naming here is differs from the data class property i.e. givenName and firstName

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's intentional to show what a custom item converter might do

@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
14.3% Duplication on New Code (required ≤ 3%)

See analysis details on SonarCloud

@github-actions
Copy link

A new generated diff is ready to view.

  • No codegen difference in the AWS SDK

@lauzadis lauzadis merged commit b08e24d into feat-ddb-mapper Sep 12, 2024
@lauzadis lauzadis deleted the feat-more-annotations branch September 12, 2024 19:24
ianbotsf added a commit that referenced this pull request Oct 29, 2024
…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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-changelog Indicates that a changelog entry isn't required for a pull request. Use sparingly.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants