Skip to content

Conversation

@armiol
Copy link
Contributor

@armiol armiol commented Sep 27, 2023

This PR is a port of #186 to master.

Here is its full description, for convenience.

This PR reproduces and addresses core-java#1536.

Previously, it was not possible to clear columns of some Proto types, since it was not possible to distinguish between meaningful "default values" set to columns on purpose, and those "default values" which in fact signalized of "no value set".

Changing the API of DsColumnMapping

This is a breaking change.

Previously, SPI users could only extend DsColumnMapping's behavior by overriding this method:

protected void setupCustomMapping(
            ImmutableMap.Builder<Class<?>, ColumnTypeMapping<?, ? extends Value<?>>> builder);

It was good enough if one wanted to append their mapping rules. But such an approach did not allow to re-define the existing (framework-default) mapping — since a builder of ImmutableMap was passed, preventing from having duplicate keys.

Now, the API for SPI users implies overriding another method:

@SPI
protected ImmutableMap<Class<?>, ColumnTypeMapping<?, ? extends Value<?>>> customMapping()

This one allows to return an immutable map of mappings, combining them into the final result, giving priority to those values which were provided by SPI users.

Please see the documentation for DsColumnMapping for more details.

How to use it

Referring to the original issue, end-users may configure how Timestamp.getDefaultValue() is stored for some column. In the example below, a Datastore-specific null is written for such values to the corresponding property of respective Datastore Entity:

/**
 * A mapping similar to the default one,
 * but telling to store {@link Timestamp}s as {@code null}s.
 */
public final class CustomMapping extends DsColumnMapping {

    @Override
    protected ImmutableMap<Class<?>, ColumnTypeMapping<?, ? extends Value<?>>> customMapping() {
        return ImmutableMap.of(Timestamp.class, ofNullableTimestamp());
    }

    @SuppressWarnings("UnnecessaryLambda" /* For brevity */)
    private static ColumnTypeMapping<Timestamp, Value<?>> ofNullableTimestamp() {
        return timestamp -> {
            if (timestamp.equals(Timestamp.getDefaultInstance())) {
                return NullValue.of();
            }
            return TimestampValue.of(
                    ofTimeSecondsAndNanos(timestamp.getSeconds(), timestamp.getNanos())
            );
        };
    }
}

Updates to TestDatastoreStorageFactory

Additionally, this changeset updates the API of TestDatastoreStorageFactory utility to allow access to two features:

  1. Creation of a test-only storage factory with some custom mapping.
  2. Accessing "raw" DatastoreWrapper via public API, which is useful to verify the actual content of Datastore entities written.

See TestDatastoreStorageFactory for detail, and have a look at the usage example in DsEntityColumnsTest.

The library version is set to 2.0.0-SNAPSHOT.158.

@armiol armiol self-assigned this Sep 27, 2023
@codecov
Copy link

codecov bot commented Sep 27, 2023

Codecov Report

Merging #187 (041129f) into master (2907499) will increase coverage by 0.10%.
Report is 2 commits behind head on master.
The diff coverage is 100.00%.

Additional details and impacted files
@@             Coverage Diff              @@
##             master     #187      +/-   ##
============================================
+ Coverage     87.09%   87.20%   +0.10%     
- Complexity      472      476       +4     
============================================
  Files            75       75              
  Lines          1798     1813      +15     
  Branches         90       90              
============================================
+ Hits           1566     1581      +15     
  Misses          200      200              
  Partials         32       32              

@armiol armiol merged commit 2563913 into master Sep 27, 2023
@armiol armiol deleted the customizable-column-mapping branch September 27, 2023 16:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant