Skip to content

Custom byte array and number conversion logic #24

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

Closed
nvamelichev opened this issue Feb 9, 2024 · 7 comments
Closed

Custom byte array and number conversion logic #24

nvamelichev opened this issue Feb 9, 2024 · 7 comments
Assignees
Labels
feature New feature or request

Comments

@nvamelichev
Copy link
Collaborator

nvamelichev commented Feb 9, 2024

Add converter logic & annotations to make your custom types convertible to a basic repertoire of YOJ types hard-coded in FieldValueType.

Note that at this time there is no attempt to make such types fully workable for complex scenarios, e.g. in-memory listing with filtering.

nvamelichev added a commit that referenced this issue Feb 9, 2024
…re tests!!!]

#24: EXPERIMENTAL: Custom converters to bridge between YOJ-supported field value types and totally custom user types
nvamelichev added a commit that referenced this issue Feb 12, 2024
…ld value types and custom user types

See the `@CustomValueType` annotation and the `ValueConverter` interface for more information.
nvamelichev added a commit that referenced this issue Feb 12, 2024
…ld value types and custom user types

See the `@CustomValueType` annotation and the `ValueConverter` interface for more information.
nvamelichev added a commit that referenced this issue Feb 12, 2024
…ld value types and custom user types

See the `@CustomValueType` annotation and the `ValueConverter` interface for more information.
@nvamelichev
Copy link
Collaborator Author

Prototyping in #22

@nvamelichev
Copy link
Collaborator Author

#22 merged, now we can use this experimental feature and improve it in future versions :-)

@nvamelichev nvamelichev added the feature New feature or request label Mar 6, 2024
@nvamelichev nvamelichev self-assigned this Mar 6, 2024
@nvamelichev
Copy link
Collaborator Author

nvamelichev commented Mar 14, 2024

Bug: FieldValue.ofObj() does recognize the custom value type but does not call the preconvert()/postconvert() anywhere. This leads to ClassCastException at query-building time (db.myTable().query().where("customValueTypedField").eq(...)).

This was not detected because my test custom-value type implemented Number and/or was String-like and implemented a sane toString().

Failing test:

@Test
public void failingTest() {
    var ve = new VersionedEntity(new VersionedEntity.Id("heyhey"), new Version(100_500L));
    db.tx(() -> db.versionedEntities().insert(ve));

    // Throws ClassCastException on eq() call
    assertThat(db.tx(() -> db.versionedEntities().query()
            .where("version").eq(ve.version())
            .findOne()
    )).isEqualTo(ve);
}

Entity and cvt:

public record VersionedEntity(
        Id id,
        Version version
) implements RecordEntity<VersionedEntity> {
    public record Id(String value) implements Entity.Id<VersionedEntity> {
    }
}

@CustomValueType(
        columnValueType = FieldValueType.INTEGER,
        columnClass = Long.class,
        converter = Version.Converter.class
)
public record Version(long value) {
    public static final class Converter implements ValueConverter<Version, Long> {
        @Override
        public @NonNull Long toColumn(@NonNull JavaField field, Version v) {
            return v.value();
        }

        @Override
        public @NonNull Version toJava(@NonNull JavaField field, @NonNull Long value) {
            return new Version(value);
        }
    }
}

nvamelichev added a commit that referenced this issue Mar 14, 2024
- Add `@Deprecated(forRemoval=true)` and "will be removed in YOJ 3.0.0" warnings
to `FieldValueType` pitfalls (`BINARY`, `isSortable()` etc.)
- Remove `@CustomValueType.columnValueType` because it can always be deduced from
`@CustomValueType.columnClass` instead.
- Disallow *recursive* custom value types (that is, types whose converter in turn produce
custom value types).
- Allow preconverted values to be of a subclass of the column class. This is valuable if
columnClass is a enum class, because Java makes anonymous inner classes of enums.
Remove fast-path for postconverted values because it is never used by any real code
(preconvert fast-path is used by `FieldValue`).
- Add "map enum by ordinal" custom value type converter as a demonstration.
Custom value types might become a viable alternatives for `@Column(dbQualifier="...")`.
@nvamelichev
Copy link
Collaborator Author

Now we have meta-annotation support for @Column and @CustomValueType annotations (#50).
You can e.g. write @StringColumn UUID myColumn in an entity and this is equivalent to @Column(customValueType=@CustomValueType(columnClass=String.class, converter=StringValueConverter.class)) UUID myColumn. Same is possible for annotating types with predefined @CustomValueType annotation, see e.g. @StringValueType.

@nvamelichev nvamelichev changed the title EXPERIMENTAL: Custom byte array and number conversion logic Custom byte array and number conversion logic Mar 27, 2024
nvamelichev added a commit that referenced this issue Apr 10, 2024
- Cache custom value types in `Schema.JavaField`
- Remove legacy string value type conversion logic, only use `StringValueConverter` "under the hood"
- Log attempts to use deprecated methods in `FieldValueType`
- Improve documentation and add `@ObjectColumn` annotation to express `@Column(flatten=false)` more clearly
@nvamelichev
Copy link
Collaborator Author

🎉 As of YOJ 2.2.10, custom value conversion logic is considered fairly well-tested and is OK performance wise, but API changes are still likely.

@nvamelichev
Copy link
Collaborator Author

🎉 As of YOJ 2.5.x, the custom value conversion logic has stabilized; further API changes are unlikely.

Custom conversion APIs will (most likely) stop being @ExperimentalApi in YOJ 3.0.0.

@nvamelichev
Copy link
Collaborator Author

Value conversion logic is essentially feature-complete; no API changes are anticipated, closing this ticket. As promised in the previous comment, custom conversion APIs will stop being experimental in YOJ 3.0.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant