/* * Copyright (C) 2012-2015 DataStax Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.datastax.driver.mapping; import com.datastax.driver.core.*; import com.datastax.driver.core.exceptions.CodecNotFoundException; import com.datastax.driver.core.utils.CassandraVersion; import com.datastax.driver.mapping.annotations.*; import org.testng.SkipException; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import static com.datastax.driver.core.Assertions.assertThat; import static com.datastax.driver.core.ProtocolVersion.V1; /** * Tests to ensure validity of {@link com.datastax.driver.mapping.annotations.Computed} * annotation to map computed fields. */ @SuppressWarnings("unused") public class MapperComputedFieldsTest extends CCMTestsSupport { @Override public void onTestContextInitialized() { execute( "CREATE TABLE user (login text primary key, name text)", "INSERT INTO user (login, name) VALUES ('testlogin', 'test name')"); } ProtocolVersion protocolVersion; MappingManager mappingManager; Mapper<User> userMapper; @BeforeMethod(groups = "short") void setup() { mappingManager = new MappingManager(session()); protocolVersion = cluster().getConfiguration().getProtocolOptions().getProtocolVersion(); if (protocolVersion.compareTo(V1) > 0) userMapper = mappingManager.mapper(User.class); } @Test(groups = "short", expectedExceptions = UnsupportedOperationException.class) void should_get_unsupported_operation_exception_on_v1() { if (protocolVersion.compareTo(V1) > 0) throw new SkipException("Skipped when protocol version > V1"); userMapper = mappingManager.mapper(User.class); } @Test(groups = "short") @CassandraVersion("2.0.0") void should_save_and_get_entity_with_computed_fields() { long writeTime = System.currentTimeMillis() * 1000; User newUser = new User("testlogin2", "blah"); newUser.setWriteTime(1); // will be ignored userMapper.save(newUser); User fetched = userMapper.get("testlogin2"); assertThat(fetched.getLogin()).isEqualTo("testlogin2"); assertThat(fetched.getName()).isEqualTo("blah"); // write time should be within 30 seconds. assertThat(fetched.getWriteTime()).isGreaterThanOrEqualTo(writeTime).isLessThan(writeTime + 30000000L); assertThat(fetched.getTtl()).isNull(); // TTL should be null since it was not set. // Overwrite with TTL session().execute("insert into user (login, name) values ('testlogin2', 'blah') using TTL 600"); fetched = userMapper.get("testlogin2"); assertThat(fetched.getWriteTime()).isGreaterThanOrEqualTo(writeTime).isLessThan(writeTime + 30000000L); assertThat(fetched.getTtl()).isBetween(570, 600); // TTL should be within 30 secs. // cleanup userMapper.delete(newUser); } @Test(groups = "short") @CassandraVersion("2.0.0") void should_add_aliases_for_fields_in_select_queries() { BoundStatement bs = (BoundStatement) userMapper.getQuery("test"); assertThat(bs.preparedStatement().getQueryString()) .contains("SELECT", "login AS col", "name AS col", "writetime(\"name\") AS col"); } @Test(groups = "short") @CassandraVersion("2.0.0") public void should_map_aliased_resultset_to_objects() { Statement getQuery = userMapper.getQuery("testlogin"); getQuery.setConsistencyLevel(ConsistencyLevel.QUORUM); ResultSet rs = session().execute(getQuery); Result<User> result = userMapper.map(rs); User user = result.one(); assertThat(user.getLogin()).isEqualTo("testlogin"); } @Test(groups = "short") @CassandraVersion("2.0.0") void should_map_unaliased_resultset_to_objects() { UserAccessor userAccessor = mappingManager.createAccessor(UserAccessor.class); ResultSet rs = userAccessor.all(); Result<User> result = userMapper.map(rs); User user = result.one(); assertThat(user.getLogin()).isEqualTo("testlogin"); assertThat(user.getWriteTime()).isEqualTo(0); } @Test(groups = "short", expectedExceptions = CodecNotFoundException.class) @CassandraVersion("2.0.0") void should_fail_if_computed_field_is_not_right_type() { Mapper<User_WrongComputedType> mapper = mappingManager.mapper(User_WrongComputedType.class); User_WrongComputedType user = mapper.get("testlogin"); } @Test(groups = "short", expectedExceptions = IllegalArgumentException.class) @CassandraVersion("2.0.0") void should_fail_if_computed_field_marked_with_column_annotation() { mappingManager.mapper(User_WrongAnnotationForComputed.class); } @Table(name = "user") public static class User { @PartitionKey private String login; private String name; public User() { } public User(String login, String name) { this.login = login; this.name = name; } // quotes in the column name inserted on purpose // to test the alias generation mechanism @Computed(value = "writetime(\"name\")") long writeTime; @Computed("ttl(name)") Integer ttl; public String getLogin() { return login; } public void setLogin(String login) { this.login = login; } public String getName() { return name; } public void setName(String name) { this.name = name; } public long getWriteTime() { return writeTime; } public void setWriteTime(long writeTime) { this.writeTime = writeTime; } public Integer getTtl() { return ttl; } public void setTtl(Integer ttl) { this.ttl = ttl; } } @Accessor interface UserAccessor { @Query("select * from user") ResultSet all(); } @Table(name = "user") public static class User_WrongComputedType { @PartitionKey private String login; private String name; @Computed(value = "writetime(name)") String writeTime; public String getLogin() { return login; } public void setLogin(String login) { this.login = login; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getWriteTime() { return writeTime; } public void setWriteTime(String writeTime) { this.writeTime = writeTime; } } @Table(name = "user") public static class User_WrongAnnotationForComputed { @PartitionKey private String login; private String name; @Column(name = "writetime(v)") long writeTime; public User_WrongAnnotationForComputed() { } public User_WrongAnnotationForComputed(String login, String name) { this.login = login; this.name = name; } public String getLogin() { return login; } public void setLogin(String login) { this.login = login; } public String getName() { return name; } public void setName(String name) { this.name = name; } public long getWriteTime() { return writeTime; } public void setWriteTime(long writeTime) { this.writeTime = writeTime; } } }