add casser entity type to differ table and user type entities

This commit is contained in:
Albert Shift 2015-03-25 19:24:03 -07:00
parent 9eeee7d119
commit f8bbcd1cd3
20 changed files with 265 additions and 133 deletions

View file

@ -42,7 +42,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<cassandra-unit.version>2.0.2.2</cassandra-unit.version>
<cassandra-driver-core.version>2.1.4</cassandra-driver-core.version>
<cassandra-driver-core.version>2.1.5</cassandra-driver-core.version>
<cassandra>2.1.2</cassandra>
<guava.version>16.0.1</guava.version>

View file

@ -26,6 +26,7 @@ import com.datastax.driver.core.RegularStatement;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.ResultSetFuture;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.Statement;
import com.datastax.driver.core.querybuilder.BuiltStatement;
public abstract class AbstractSessionOperations {
@ -40,27 +41,13 @@ public abstract class AbstractSessionOperations {
abstract public Executor getExecutor();
public ResultSet execute(String cql) {
public ResultSet execute(Statement statement) {
try {
if (logger.isInfoEnabled()) {
logger.info("Execute query " + cql);
}
if (isShowCql() && cql != null) {
System.out.println(cql);
}
return currentSession().execute(cql);
}
catch(RuntimeException e) {
throw translateException(e);
}
return executeAsync(statement).getUninterruptibly();
}
public ResultSetFuture executeAsync(BuiltStatement statement) {
public ResultSetFuture executeAsync(Statement statement) {
try {
@ -70,20 +57,30 @@ public abstract class AbstractSessionOperations {
if (isShowCql()) {
RegularStatement regular = statement.setForceNoValues(true);
String cql = regular.getQueryString();
System.out.println(cql);
return currentSession().executeAsync(regular);
}
else {
if (statement instanceof BuiltStatement) {
BuiltStatement builtStatement = (BuiltStatement) statement;
return currentSession().executeAsync(statement);
RegularStatement regularStatement = builtStatement.setForceNoValues(true);
System.out.println(regularStatement.getQueryString());
}
else if (statement instanceof RegularStatement) {
RegularStatement regularStatement = (RegularStatement) statement;
System.out.println(regularStatement.getQueryString());
}
else {
System.out.println(statement.toString());
}
}
return currentSession().executeAsync(statement);
}
catch(RuntimeException e) {
throw translateException(e);

View file

@ -270,10 +270,8 @@ public class CasserSession extends AbstractSessionOperations implements Closeabl
}
private void dropEntity(CasserMappingEntity<?> entity) {
String cql = SchemaUtil.dropTableCql(entity);
execute(cql);
execute(SchemaUtil.dropTable(entity));
}

View file

@ -21,6 +21,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import casser.mapping.CasserEntityType;
import casser.mapping.CasserMappingEntity;
import casser.mapping.CasserMappingProperty;
import casser.mapping.CqlUtil;
@ -29,29 +30,49 @@ import casser.support.CasserMappingException;
import com.datastax.driver.core.ColumnMetadata;
import com.datastax.driver.core.DataType;
import com.datastax.driver.core.RegularStatement;
import com.datastax.driver.core.SimpleStatement;
import com.datastax.driver.core.TableMetadata;
import com.datastax.driver.core.schemabuilder.Alter;
import com.datastax.driver.core.schemabuilder.Create;
import com.datastax.driver.core.schemabuilder.Create.Options;
import com.datastax.driver.core.schemabuilder.CreateType;
import com.datastax.driver.core.schemabuilder.SchemaBuilder;
import com.datastax.driver.core.schemabuilder.SchemaStatement;
public final class SchemaUtil {
private SchemaUtil() {
}
public static String useCql(String keyspace, boolean forceQuote) {
public static RegularStatement use(String keyspace, boolean forceQuote) {
if (forceQuote) {
return "USE " + keyspace;
return new SimpleStatement("USE" + CqlUtil.forceQuote(keyspace));
}
else {
return "USE" + CqlUtil.forceQuote(keyspace);
return new SimpleStatement("USE " + keyspace);
}
}
public static SchemaStatement createUserType(CasserMappingEntity<?> entity) {
public static String createTableCql(CasserMappingEntity<?> entity) {
if (entity.getType() != CasserEntityType.USER_DEFINED_TYPE) {
throw new CasserMappingException("expected user defined type entity " + entity);
}
CreateType create = SchemaBuilder.createType(entity.getName());
Create create = SchemaBuilder.createTable(entity.getTableName());
return create;
}
public static SchemaStatement createTable(CasserMappingEntity<?> entity) {
if (entity.getType() != CasserEntityType.TABLE) {
throw new CasserMappingException("expected table entity " + entity);
}
Create create = SchemaBuilder.createTable(entity.getName());
List<CasserMappingProperty<?>> partitionKeys = new ArrayList<CasserMappingProperty<?>>();
List<CasserMappingProperty<?>> clusteringColumns = new ArrayList<CasserMappingProperty<?>>();
@ -102,16 +123,20 @@ public final class SchemaUtil {
}
return create.buildInternal();
return create;
}
public static String alterTableCql(TableMetadata tmd,
public static List<SchemaStatement> alterTable(TableMetadata tmd,
CasserMappingEntity<?> entity, boolean dropRemovedColumns) {
boolean altered = false;
if (entity.getType() != CasserEntityType.TABLE) {
throw new CasserMappingException("expected table entity " + entity);
}
List<SchemaStatement> result = new ArrayList<SchemaStatement>();
Alter alter = SchemaBuilder.alterTable(entity.getTableName());
Alter alter = SchemaBuilder.alterTable(entity.getName());
final Set<String> visitedColumns = dropRemovedColumns ? new HashSet<String>()
: Collections.<String> emptySet();
@ -138,32 +163,40 @@ public final class SchemaUtil {
throw new CasserMappingException(
"unable to alter column that is a part of primary key '"
+ columnName + "' for entity "
+ entity.getName());
+ entity);
}
if (columnMetadata == null) {
alter.addColumn(columnName).type(columnDataType);
altered = true;
result.add(alter.addColumn(columnName).type(columnDataType));
} else {
alter.alterColumn(columnName).type(columnDataType);
altered = true;
result.add(alter.alterColumn(columnName).type(columnDataType));
}
}
if (altered) {
return alter.buildInternal();
if (dropRemovedColumns) {
for (ColumnMetadata cm : tmd.getColumns()) {
if (!visitedColumns.contains(cm.getName())) {
result.add(alter.dropColumn(cm.getName()));
}
}
}
return null;
return result;
}
public static String dropTableCql(CasserMappingEntity<?> entity) {
public static SchemaStatement dropTable(CasserMappingEntity<?> entity) {
return SchemaBuilder.dropTable(entity.getTableName()).buildInternal();
if (entity.getType() != CasserEntityType.TABLE) {
throw new CasserMappingException("expected table entity " + entity);
}
return SchemaBuilder.dropTable(entity.getName());
}

View file

@ -140,13 +140,13 @@ public class SessionInitializer extends AbstractSessionOperations {
}
public SessionInitializer use(String keyspace) {
session.execute(SchemaUtil.useCql(keyspace, false));
session.execute(SchemaUtil.use(keyspace, false));
this.usingKeyspace = keyspace;
return this;
}
public SessionInitializer use(String keyspace, boolean forceQuote) {
session.execute(SchemaUtil.useCql(keyspace, forceQuote));
session.execute(SchemaUtil.use(keyspace, forceQuote));
this.usingKeyspace = keyspace;
return this;
}
@ -236,7 +236,7 @@ public class SessionInitializer extends AbstractSessionOperations {
}
private TableMetadata getTableMetadata(CasserMappingEntity<?> entity) {
String tableName = entity.getTableName();
String tableName = entity.getName();
return getKeyspaceMetadata().getTable(tableName.toLowerCase());
}

View file

@ -15,10 +15,16 @@
*/
package casser.core;
import java.util.List;
import casser.mapping.CasserMappingEntity;
import casser.support.CasserException;
import com.datastax.driver.core.RegularStatement;
import com.datastax.driver.core.TableMetadata;
import com.datastax.driver.core.querybuilder.Batch;
import com.datastax.driver.core.querybuilder.QueryBuilder;
import com.datastax.driver.core.schemabuilder.SchemaStatement;
public final class TableOperations {
@ -31,23 +37,19 @@ public final class TableOperations {
}
public void createTable(CasserMappingEntity<?> entity) {
String cql = SchemaUtil.createTableCql(entity);
sessionOps.execute(cql);
sessionOps.execute(SchemaUtil.createTable(entity));
}
public void validateTable(TableMetadata tmd, CasserMappingEntity<?> entity) {
if (tmd == null) {
throw new CasserException("table not exists " + entity.getTableName() + "for entity " + entity.getMappingInterface());
throw new CasserException("table not exists " + entity.getName() + "for entity " + entity.getMappingInterface());
}
String cql = SchemaUtil.alterTableCql(tmd, entity, dropRemovedColumns);
List<SchemaStatement> list = SchemaUtil.alterTable(tmd, entity, dropRemovedColumns);
if (cql != null) {
throw new CasserException("schema changed for entity " + entity.getMappingInterface() + ", apply this command: " + cql);
if (!list.isEmpty()) {
throw new CasserException("schema changed for entity " + entity.getMappingInterface() + ", apply this command: " + list);
}
}
@ -57,10 +59,11 @@ public final class TableOperations {
createTable(entity);
}
String cql = SchemaUtil.alterTableCql(tmd, entity, dropRemovedColumns);
List<SchemaStatement> list = SchemaUtil.alterTable(tmd, entity, dropRemovedColumns);
if (cql != null) {
sessionOps.execute(cql);
if (!list.isEmpty()) {
Batch b = QueryBuilder.batch(list.toArray(new RegularStatement[list.size()]));
sessionOps.execute(b);
}
}

View file

@ -15,7 +15,7 @@
*/
package casser.core;
import casser.mapping.CasserMappingUserType;
import casser.mapping.CasserMappingEntity;
import com.datastax.driver.core.UserType;
@ -27,16 +27,18 @@ public final class UserTypeOperations {
this.sessionOps = sessionOps;
}
public void createUserType(String name, CasserMappingUserType<?> type) {
public void createUserType(String name, CasserMappingEntity<?> entity) {
}
public void validateUserType(String name, UserType userType, CasserMappingUserType<?> type) {
public void validateUserType(String name, UserType userType, CasserMappingEntity<?> entity) {
}
public void updateUserType(String name, UserType userType, CasserMappingUserType<?> type) {
public void updateUserType(String name, UserType userType, CasserMappingEntity<?> entity) {
}

View file

@ -38,7 +38,7 @@ public final class CountOperation extends AbstractFilterOperation<Long, CountOpe
@Override
public BuiltStatement buildStatement() {
Select select = QueryBuilder.select().countAll().from(entity.getTableName());
Select select = QueryBuilder.select().countAll().from(entity.getName());
if (filters != null && !filters.isEmpty()) {

View file

@ -41,7 +41,7 @@ public final class DeleteOperation extends AbstractFilterOperation<ResultSet, De
if (filters != null && !filters.isEmpty()) {
Delete delete = QueryBuilder.delete().from(entity.getTableName());
Delete delete = QueryBuilder.delete().from(entity.getName());
Where where = delete.where();
@ -53,7 +53,7 @@ public final class DeleteOperation extends AbstractFilterOperation<ResultSet, De
}
else {
return QueryBuilder.truncate(entity.getTableName());
return QueryBuilder.truncate(entity.getName());
}
}

View file

@ -135,7 +135,7 @@ public final class SelectOperation<E> extends AbstractFilterStreamOperation<E, S
throw new CasserMappingException("no entity or table to select data");
}
Select select = selection.from(entity.getTableName());
Select select = selection.from(entity.getName());
if (ordering != null && !ordering.isEmpty()) {
select.orderBy(ordering.toArray(new Ordering[ordering.size()]));

View file

@ -85,7 +85,7 @@ public final class UpdateOperation extends AbstractFilterOperation<ResultSet, Up
}
Update update = QueryBuilder.update(entity.getTableName());
Update update = QueryBuilder.update(entity.getName());
for (int i = 0; i != props.length; ++i) {

View file

@ -35,7 +35,7 @@ public final class UpsertOperation extends AbstractObjectOperation<ResultSet, Up
public UpsertOperation(AbstractSessionOperations sessionOperations, CasserMappingEntity<?> entity, Object pojo) {
super(sessionOperations);
this.insert = QueryBuilder.insertInto(entity.getTableName());
this.insert = QueryBuilder.insertInto(entity.getName());
for (CasserMappingProperty<?> prop : entity.getMappingProperties()) {

View file

@ -19,9 +19,9 @@ import java.util.Collection;
public interface CasserEntity<E> {
String getName();
CasserEntityType getType();
String getTableName();
String getName();
Collection<CasserProperty<E>> getProperties();

View file

@ -15,15 +15,6 @@
*/
package casser.mapping;
public class CasserMappingUserType<E> implements CasserUserType<E> {
public CasserMappingUserType(Class<E> clazz) {
}
@Override
public String getName() {
return null;
}
public enum CasserEntityType {
TABLE, USER_DEFINED_TYPE;
}

View file

@ -72,12 +72,17 @@ public class CasserMappingEntity<E> implements CasserEntity<E> {
}
@Override
public CasserEntityType getType() {
return CasserEntityType.TABLE;
}
public Class<E> getMappingInterface() {
return iface;
}
@Override
public String getName() {
public String toString() {
return iface.toString();
}
@ -91,7 +96,7 @@ public class CasserMappingEntity<E> implements CasserEntity<E> {
}
@Override
public String getTableName() {
public String getName() {
if (tableName == null) {

View file

@ -27,7 +27,7 @@ public class CasserMappingRepository {
private final Map<Class<?>, CasserMappingEntity<?>> entityMap = new HashMap<Class<?>, CasserMappingEntity<?>>();
private final Map<String, CasserMappingUserType<?>> udtMap = new HashMap<String, CasserMappingUserType<?>>();
private final Map<String, CasserMappingEntity<?>> udtMap = new HashMap<String, CasserMappingEntity<?>>();
private boolean readOnly = false;
@ -42,15 +42,15 @@ public class CasserMappingRepository {
throw new CasserException("read-only mode");
}
udtMap.putIfAbsent(name, new CasserMappingUserType(userTypeClass));
udtMap.putIfAbsent(name, new CasserMappingEntity(userTypeClass));
}
public Map<String, CasserMappingUserType<?>> knownUserTypes() {
public Map<String, CasserMappingEntity<?>> knownUserTypes() {
return Collections.unmodifiableMap(udtMap);
}
public CasserMappingUserType<?> findUserType(Class<?> userTypeClass) {
public CasserMappingEntity<?> findUserType(Class<?> userTypeClass) {
return udtMap.get(userTypeClass);
}

View file

@ -15,8 +15,12 @@
*/
package casser.mapping;
import java.util.Collection;
public interface CasserUserType<E> {
public String getName();
String getName();
Collection<CasserProperty<E>> getProperties();
}

View file

@ -1,3 +1,18 @@
/*
* Copyright (C) 2015 Noorq, 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 casser.test.integration.core.usertype;
import casser.mapping.PartitionKey;

View file

@ -1,50 +1,41 @@
/*
* Copyright (C) 2015 Noorq, 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 casser.test.integration.core.usertype;
import casser.mapping.Field;
import casser.mapping.UserDefinedType;
@UserDefinedType("address")
public class Address {
public interface Address {
@Field("line_1")
private String street;
String getStreet();
private String city;
void setStreet(String street);
private int zip;
String getCity();
private String country;
void setCity(String city);
public String getStreet() {
return street;
}
int getZip();
public void setStreet(String street) {
this.street = street;
}
void setZip(int zip);
public String getCity() {
return city;
}
String getCountry();
public void setCity(String city) {
this.city = city;
}
public int getZip() {
return zip;
}
public void setZip(int zip) {
this.zip = zip;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
void setCountry(String country);
}

View file

@ -1,5 +1,22 @@
/*
* Copyright (C) 2015 Noorq, 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 casser.test.integration.core.usertype;
import java.util.regex.Pattern;
import org.junit.Before;
import org.junit.Test;
@ -7,24 +24,100 @@ import casser.core.Casser;
import casser.core.CasserSession;
import casser.test.integration.build.AbstractEmbeddedCassandraTest;
import com.datastax.driver.core.DataType;
import com.datastax.driver.core.KeyspaceMetadata;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.UserType;
import com.datastax.driver.core.querybuilder.QueryBuilder;
import com.datastax.driver.core.querybuilder.Select;
import com.datastax.driver.core.schemabuilder.Create;
import com.datastax.driver.core.schemabuilder.CreateType;
import com.datastax.driver.core.schemabuilder.SchemaBuilder;
public class UserDefinedTypeTest extends AbstractEmbeddedCassandraTest {
Account account;
CasserSession session;
CasserSession csession;
@Before
public void beforeTest() {
account = Casser.dsl(Account.class);
//session = Casser.init(getSession()).showCql().add(Account.class).autoCreateDrop().get();
//csession = Casser.init(getSession()).showCql().add(Account.class).autoCreateDrop().get();
Session session = getSession();
CreateType ct = SchemaBuilder.createType("address");
ct.addColumn("street", DataType.text());
ct.addColumn("city", DataType.text());
ct.addColumn("zip_code", DataType.cint());
ct.addColumn("phones", DataType.set(DataType.text()));
String cql = ct.build();
System.out.println(cql);
//session.execute("CREATE TYPE address (street text, city text, zip_code int, phones set<text>)");
session.execute(cql);
ct = SchemaBuilder.createType("fullname");
ct.addColumn("firstname", DataType.text());
ct.addColumn("lastname", DataType.text());
cql = ct.build();
System.out.println(cql);
session.execute(cql);
//session.execute("CREATE TYPE fullname (firstname text,lastname text)");
System.out.println("keyspace = " + session.getLoggedKeyspace());
KeyspaceMetadata km = session.getCluster().getMetadata().getKeyspace(session.getLoggedKeyspace());
UserType address = km.getUserType("address");
UserType fullname = km.getUserType("fullname");
Create create = SchemaBuilder.createTable("users");
create.addPartitionKey("id", DataType.uuid());
create.addUDTColumn("name", SchemaBuilder.frozen("fullname"));
create.addUDTMapColumn("addresses", DataType.ascii(), SchemaBuilder.frozen("address"));
cql = create.buildInternal();
System.out.println(cql);
session.execute(create);
//session.execute("CREATE TABLE users (id uuid PRIMARY KEY, name fullname, "
// + "addresses map<string, address>)");
}
@Test
public void testUDT() {
System.out.println("test it");
Session session = getSession();
Select select = QueryBuilder.select().column("\"name\".\"lastname\"").from("users");
System.out.println(select);
ResultSet resultSet = session.execute("SELECT \"name\".\"lastname\" FROM users;");
System.out.println("resultSet = " + resultSet);
//csession.select(account.getAddress()::getStreet).sync();
}
}