doanduyhai / Achilles

An advanced Java Object Mapper/Query DSL generator for Cassandra
http://achilles.archinnov.info
Apache License 2.0
241 stars 92 forks source link

Multiple AbstractCQLCompatibleType & FunctionCall for token function #363

Closed RaAleks closed 5 years ago

RaAleks commented 5 years ago

Hi @doanduyhai Could you please add multiple AbstractCQLCompatibleType & FunctionCall for token function?

If i have table with more than one Parttiotion key, query should be as this for example:

SELECT token(id1,id2) AS table_token FROM keyspace.example_table WHERE token(id1,id2)>-token_value;

No in Achilles i can implement only this way:

SELECT token(id1) AS table_token FROM keyspace.example_table WHERE token(id1,id2)>-token_value;

So, request above throws NPE because i should provide two token keys.

achilles look like this: manager .dsl() .select() .function(SystemFunctions.token(Table_AchillesMeta.COLUMNS.PARTTITION_ONE), "tokens") .fromBaseTable() .where() .tokenValueOf_id1_id2() .Gt(some_long_value) .getTypedMaps();

This what i want to ask you:

manager .dsl() .select() .function(SystemFunctions .token(Table_AchillesMeta.COLUMNS.PARTTITION_ONE, Table_AchillesMeta.COLUMNS.PARTTITION_TWO), "tokens") .fromBaseTable() .where() .tokenValueOf_id1_id2() .Gt(some_long_value) .getTypedMaps()

doanduyhai commented 5 years ago

Humm, thanks for the remark, I'm going to check the source code to see how difficult it is to implement this function

RaAleks commented 5 years ago

Many thanks for quick response!

vrudikov commented 5 years ago

+1

doanduyhai commented 5 years ago

1) I have left the current impl of token() function to avoid breaking change and for backward compatibility

2) I have added a new type-safe token() function which only accept the type PartitionKeys_Type. This generated type has been introduced for the purpose

The usage is

TypedMap typedMap = manager
    .dsl()
    .select()
    .function(SystemFunctions.token(MyEntity_AchillesMeta.COLUMNS.PARTITION_KEYS), "tokens")
    .fromBaseTable()
    ....

Please use the xxx_AchillesMeta.COLUMNS.PARTITION_KEYS that has been introduced for this purpose. If your table has a composite partition key, the generated field PARTITION_KEYS will reference all of them

vrudikov commented 5 years ago

Awesome. Thank you!

On Sat, Jul 6, 2019, 00:28 DuyHai DOAN notifications@github.com wrote:

1.

I have left the current impl of token() function to avoid breaking change and for backward compatibility 2.

I have added a new type-safe token() function which only accept the type PartitionKeys_Type. This generated type has been introduced for the purpose

The usage is

TypedMap typedMap = manager .dsl() .select() .function(SystemFunctions.token(MyEntity_AchillesMeta.COLUMNS.PARTITION_KEYS), "tokens") .fromBaseTable() ....

Please use the xxx_AchillesMeta.COLUMNS.PARTITION_KEYS that has been introduced for this purpose. If your table has a composite partition key, the generated field PARTITION_KEYS will reference all of them

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/doanduyhai/Achilles/issues/363?email_source=notifications&email_token=AADYREVKF6EQUN3IXQSXDYDP564GLA5CNFSM4H46UCJ2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODZKKXXA#issuecomment-508865500, or mute the thread https://github.com/notifications/unsubscribe-auth/AADYREU3GZHSGLDKYKMXEH3P564GLANCNFSM4H46UCJQ .

RaAleks commented 5 years ago

Thank you!

RaAleks commented 5 years ago

@doanduyhai When you expect to release this changes?

doanduyhai commented 5 years ago

I can attempt a minor release tonight. Expect it to be available on Maven Central in 24h max

doanduyhai commented 5 years ago

Just released. Will be available in a few hours on Maven Central (Achilles 6.0.4)

RaAleks commented 5 years ago

Once again, thank you!

RaAleks commented 5 years ago

@doanduyhai I've been update achilles version, and now i have such error : "Invalid argument for 'token' function, it does not accept function call as argument, only simple column"

I think that it is due to Override method isFunctionCall always return true and PartitionKeys_Type implements FunctionCall.

doanduyhai commented 5 years ago

Let me check with a sample project

doanduyhai commented 5 years ago

So I just tested:


@Table(keyspace = KEYSPACE, table = "composite_partitions")
@Immutable
public class CompositePartitionKeyEntity {

    @PartitionKey(1)
    public final Long id;

    @PartitionKey(2)
    public final UUID uuid;

    @Column
    public final String value;

    public CompositePartitionKeyEntity(Long id, UUID uuid, String value) {
        this.id = id;
        this.uuid = uuid;
        this.value = value;
    }
}

    @Rule
    public AchillesTestResource<ManagerFactory> resource = AchillesTestResourceBuilder
            .forJunit()
            .createAndUseKeyspace(KEYSPACE)
            .entityClassesToTruncate(CompositePartitionKeyEntity.class)
            .truncateBeforeAndAfterTest()
            .build((cluster, statementsCache) -> ManagerFactoryBuilder
                    .builder(cluster)
                    .withStatementsCache(statementsCache)
                    .doForceSchemaCreation(true)
                    .withDefaultKeyspaceName(KEYSPACE)
                    .build());

    @Test
    public void should_test() throws Exception {
        //Given
        CompositePartitionKeyEntity_Manager manager = resource.getManagerFactory().forCompositePartitionKeyEntity();
        Long id = RandomUtils.nextLong(0L, Long.MAX_VALUE);
        UUID uuid = UUID.randomUUID();
        String value = RandomStringUtils.randomAlphabetic(10);

        CompositePartitionKeyEntity entity = new CompositePartitionKeyEntity(id, uuid, value);

        manager.crud().insert(entity).execute();

        //When
        TypedMap typedMap = manager
                .dsl()
                .select()
                .value()
                .function(SystemFunctions.token(CompositePartitionKeyEntity_AchillesMeta.COLUMNS.PARTITION_KEYS), "tokens")
                .fromBaseTable()
                .where()
                .id().Eq(id)
                .uuid().Eq(uuid)
                .getTypedMap();

        //Then
        assertThat(typedMap).isNotNull();
        assertThat(typedMap).isNotEmpty();
        assertThat(typedMap.<Long>getTyped("tokens")).isNotNull();
    }

Everything compiles correctly and the test is green

You should probably do a clean compile (mvn clean compile) to remove any left-overs of previously generated code

RaAleks commented 5 years ago

@doanduyhai Can you pls try such request

manager
       .dsl()
       .select()
       .value()
       .function(SystemFunctions.token(CompositePartitionKeyEntity_AchillesMeta.COLUMNS), "tokens")
       .fromBaseTable()
       .where()
       .tokenValueOf_id_uuid()
       .Gt(Long.MIN_VALUE)
       .limit(10)
       .getTypedMaps();
doanduyhai commented 5 years ago

There is a mistake, if should NOT be .function(SystemFunctions.token(CompositePartitionKeyEntity_AchillesMeta.COLUMNS), "tokens") but .function(SystemFunctions.token(CompositePartitionKeyEntity_AchillesMeta.COLUMNS.PARTITION_KEYS), "tokens")

I've pushed a branch TokenFunction on the sample test projet KillrChat. You can checkout the project and execute the integration test NewTest

RaAleks commented 5 years ago

Oh, sorry it seems to my i fixed my comment. I've tried such query Ok, ill check out project and try to reproduce. Thanks!

RaAleks commented 5 years ago

Just tested, and it is ok! Will check what the problem in my project! Thanks.