Search in sources :

Example 11 with EntityFieldMetaData

use of com.datastax.driver.mapping.meta.EntityFieldMetaData in project cassandra-driver-mapping by valchkou.

the class SchemaSync method alterTableStatements.

/**
     * Compare TableMetadata against Entity metadata and generate alter statements if necessary.
     * <p>
     * Cannot alter clustered and primary key columns. 
     *
     * @param class the class to generate statements for or indexed
     * @return a new {@code List<RegularStatement>}.
     */
private static <T> List<RegularStatement> alterTableStatements(String keyspace, Session session, EntityTypeMetadata entityMetadata, SyncOptions syncOptions) {
    boolean doNotAddCols = false;
    boolean doDropCols = true;
    if (syncOptions != null) {
        List<SyncOptionTypes> opts = syncOptions.getOptions(entityMetadata.getEntityClass());
        doNotAddCols = opts.contains(SyncOptionTypes.DoNotAddColumns);
        doDropCols = !opts.contains(SyncOptionTypes.DoNotDropColumns);
    }
    List<RegularStatement> statements = new ArrayList<RegularStatement>();
    // get EntityTypeMetadata
    String table = entityMetadata.getTableName();
    // get TableMetadata - requires connection to cassandra
    Cluster cluster = session.getCluster();
    KeyspaceMetadata keyspaceMetadata = cluster.getMetadata().getKeyspace(keyspace);
    TableMetadata tableMetadata = keyspaceMetadata.getTable(table);
    // build statements for a new column or a columns with changed datatype.
    for (EntityFieldMetaData field : entityMetadata.getFields()) {
        String column = field.getColumnName();
        String fieldType = field.getDataType().name();
        ColumnMetadata columnMetadata = tableMetadata.getColumn(column);
        String colIndex = null;
        /*if (columnMetadata!= null && columnMetadata.getIndex() != null) {
    			colIndex = columnMetadata.getIndex().getName();
    		}*/
        String fieldIndex = null;
        if (entityMetadata.getIndex(column) != null) {
            fieldIndex = entityMetadata.getIndex(column);
        }
        if (columnMetadata == null) {
            if (doNotAddCols)
                continue;
            // if column not exists in Cassandra then build add column Statement 
            String colType = fieldType;
            if (field.isGenericType()) {
                colType = field.getGenericDef();
            }
            AlterTable statement = new AlterTable.Builder().addColumn(keyspace, table, column, colType);
            statements.add(statement);
            if (fieldIndex != null) {
                statements.add(new DropIndex(column, fieldIndex));
                statements.add(new CreateIndex(keyspace, table, column, fieldIndex));
            }
        } else if (colIndex != null || fieldIndex != null) {
            if (colIndex == null) {
                statements.add(new CreateIndex(keyspace, table, column, fieldIndex));
            } else if (fieldIndex == null) {
                statements.add(new DropIndex(column, colIndex));
            } else if (!"".equals(fieldIndex) && !fieldIndex.equals(colIndex)) {
                statements.add(new DropIndex(column, colIndex));
                statements.add(new CreateIndex(keyspace, table, column, fieldIndex));
            }
        } else if (!fieldType.equals(columnMetadata.getType().getName().name())) {
            // can't change datatype for clustered columns
            if (tableMetadata.getClusteringColumns().contains(columnMetadata)) {
                continue;
            }
            // can't change datatype for PK  columns
            if (tableMetadata.getPrimaryKey().contains(columnMetadata)) {
                continue;
            }
            // drop index if any
            /*if (columnMetadata.getIndex() != null) {
    				statements.add(new DropIndex(column, columnMetadata.getIndex().getName()));
    			}*/
            // alter column datatype
            statements.add(new AlterTable.Builder().alterColumn(keyspace, table, column, fieldType));
            // create index if any
            if (entityMetadata.getIndex(column) != null) {
                statements.add(new CreateIndex(keyspace, table, column, entityMetadata.getIndex(column)));
            }
        }
    }
    // column is in Cassandra but not in entity anymore
    if (doDropCols) {
        for (ColumnMetadata colmeta : tableMetadata.getColumns()) {
            colmeta.getName();
            boolean exists = false;
            for (EntityFieldMetaData field : entityMetadata.getFields()) {
                if (colmeta.getName().equalsIgnoreCase(field.getColumnName())) {
                    exists = true;
                    break;
                }
            }
            if (!exists) {
                AlterTable statement = new AlterTable.Builder().dropColumn(keyspace, table, colmeta.getName());
                statements.add(statement);
            }
        }
    }
    return statements;
}
Also used : TableMetadata(com.datastax.driver.core.TableMetadata) EntityFieldMetaData(com.datastax.driver.mapping.meta.EntityFieldMetaData) ColumnMetadata(com.datastax.driver.core.ColumnMetadata) ArrayList(java.util.ArrayList) Cluster(com.datastax.driver.core.Cluster) RegularStatement(com.datastax.driver.core.RegularStatement) KeyspaceMetadata(com.datastax.driver.core.KeyspaceMetadata)

Example 12 with EntityFieldMetaData

use of com.datastax.driver.mapping.meta.EntityFieldMetaData in project cassandra-driver-mapping by valchkou.

the class MappingBuilder method prepareRemoveItemsFromSetOrList.

public static BoundStatement prepareRemoveItemsFromSetOrList(Object id, Class<?> clazz, String propertyName, Object item, String keyspace, Session session) {
    EntityTypeMetadata emeta = EntityTypeParser.getEntityMetadata(clazz);
    EntityFieldMetaData fmeta = emeta.getFieldMetadata(propertyName);
    Update update = QueryBuilder.update(keyspace, emeta.getTableName());
    if (item instanceof Set<?> && fmeta.getType() == Set.class) {
        Set<?> set = (Set<?>) item;
        if (set.size() == 0)
            return null;
        update.with(QueryBuilder.removeAll(fmeta.getColumnName(), set));
    } else if (item instanceof List<?> && fmeta.getType() == List.class) {
        List<?> list = (List<?>) item;
        if (list.size() == 0)
            return null;
        update.with(QueryBuilder.discardAll(fmeta.getColumnName(), list));
    } else if (fmeta.getType() == Set.class) {
        update.with(QueryBuilder.remove(fmeta.getColumnName(), item));
    } else if (fmeta.getType() == List.class) {
        update.with(QueryBuilder.discard(fmeta.getColumnName(), item));
    }
    return prepareUpdate(id, emeta, update, session);
}
Also used : EntityFieldMetaData(com.datastax.driver.mapping.meta.EntityFieldMetaData) EntityTypeMetadata(com.datastax.driver.mapping.meta.EntityTypeMetadata)

Example 13 with EntityFieldMetaData

use of com.datastax.driver.mapping.meta.EntityFieldMetaData in project cassandra-driver-mapping by valchkou.

the class MappingBuilder method buildUpdate.

/**
     * Statement to persist an entity in Cassandra
     * 
     * @param entity to be inserted
     * @return com.datastax.driver.core.BoundStatement
     */
public static <E> BuiltStatement buildUpdate(E entity, WriteOptions options, String keyspace) {
    Class<?> clazz = entity.getClass();
    EntityTypeMetadata entityMetadata = EntityTypeParser.getEntityMetadata(clazz);
    String table = entityMetadata.getTableName();
    List<EntityFieldMetaData> fields = entityMetadata.getFields();
    List<String> pkCols = entityMetadata.getPkColumns();
    List<Object> pkVals = entityMetadata.getEntityPKValues(entity);
    String[] columns = new String[fields.size()];
    Object[] values = new Object[fields.size()];
    Update update = QueryBuilder.update(keyspace, table);
    EntityFieldMetaData verField = null;
    Object newVersion = null;
    Object oldVersion = null;
    // increment and set @Version field
    if (entityMetadata.hasVersion()) {
        verField = entityMetadata.getVersionField();
        oldVersion = verField.getValue(entity);
        newVersion = incVersion(oldVersion);
        verField.setValue(entity, newVersion);
        update.onlyIf(eq(verField.getColumnName(), oldVersion));
    }
    for (int i = 0; i < fields.size(); i++) {
        EntityFieldMetaData field = fields.get(i);
        String colName = field.getColumnName();
        Object colVal = null;
        if (pkCols.contains(colName)) {
            int idx = pkCols.indexOf(colName);
            colVal = pkVals.get(idx);
            update.where(eq(colName, colVal));
            continue;
        } else {
            colVal = field.getValue(entity);
        }
        columns[i] = colName;
        if (field.equals(verField)) {
            values[i] = newVersion;
        } else {
            values[i] = colVal;
        }
        update.with(set(colName, colVal));
    }
    applyOptions(options, update, entityMetadata);
    return update;
}
Also used : EntityFieldMetaData(com.datastax.driver.mapping.meta.EntityFieldMetaData) EntityTypeMetadata(com.datastax.driver.mapping.meta.EntityTypeMetadata)

Example 14 with EntityFieldMetaData

use of com.datastax.driver.mapping.meta.EntityFieldMetaData in project cassandra-driver-mapping by valchkou.

the class MappingBuilder method prepareSelect.

/**
     * Prepare BoundStatement to select row by id
     */
public static <T> BoundStatement prepareSelect(Class<T> clazz, Object id, final ReadOptions options, final String keyspace, final Session session) {
    EntityTypeMetadata entityMetadata = EntityTypeParser.getEntityMetadata(clazz);
    final List<EntityFieldMetaData> fields = entityMetadata.getFields();
    final List<String> pkCols = entityMetadata.getPkColumns();
    final String table = entityMetadata.getTableName();
    // get prepared statement
    PreparedStatement ps;
    try {
        ps = statementCache.get(getSelectCacheKey(table, session, fields), new Callable<PreparedStatement>() {

            @Override
            public PreparedStatement call() throws Exception {
                Select stmt = buildSelectAll(table, pkCols, options, keyspace, fields);
                return session.prepare(stmt);
            }
        });
    } catch (ExecutionException e) {
        // if the error caused by prepare the client will get it as is,
        // otherwise process will not blow and statement will not be cached.
        Select stmt = buildSelectAll(table, pkCols, options, keyspace, fields);
        ps = session.prepare(stmt);
    }
    // bind parameters
    Object[] values = entityMetadata.getIdValues(id).toArray(new Object[pkCols.size()]);
    BoundStatement bs = ps.bind(values);
    return bs;
}
Also used : EntityFieldMetaData(com.datastax.driver.mapping.meta.EntityFieldMetaData) EntityTypeMetadata(com.datastax.driver.mapping.meta.EntityTypeMetadata) ExecutionException(java.util.concurrent.ExecutionException) Callable(java.util.concurrent.Callable)

Example 15 with EntityFieldMetaData

use of com.datastax.driver.mapping.meta.EntityFieldMetaData in project cassandra-driver-mapping by valchkou.

the class MappingBuilder method prepareSave.

public static <E> BuiltStatement prepareSave(E entity, WriteOptions options, String keyspace) {
    Class<?> clazz = entity.getClass();
    EntityTypeMetadata entityMetadata = EntityTypeParser.getEntityMetadata(clazz);
    long version = Long.MIN_VALUE;
    if (entityMetadata.hasVersion()) {
        EntityFieldMetaData verField = entityMetadata.getVersionField();
        version = ((Long) verField.getValue(entity)).longValue();
    }
    BuiltStatement stmt = null;
    if (version > 0) {
        stmt = buildUpdate(entity, options, keyspace);
    } else {
        stmt = buildInsert(entity, options, keyspace);
    }
    return stmt;
}
Also used : EntityFieldMetaData(com.datastax.driver.mapping.meta.EntityFieldMetaData) EntityTypeMetadata(com.datastax.driver.mapping.meta.EntityTypeMetadata)

Aggregations

EntityFieldMetaData (com.datastax.driver.mapping.meta.EntityFieldMetaData)18 EntityTypeMetadata (com.datastax.driver.mapping.meta.EntityTypeMetadata)13 PrimaryKeyMetadata (com.datastax.driver.mapping.meta.PrimaryKeyMetadata)2 ExecutionException (java.util.concurrent.ExecutionException)2 Test (org.junit.Test)2 Cluster (com.datastax.driver.core.Cluster)1 ColumnMetadata (com.datastax.driver.core.ColumnMetadata)1 DataType (com.datastax.driver.core.DataType)1 KeyspaceMetadata (com.datastax.driver.core.KeyspaceMetadata)1 RegularStatement (com.datastax.driver.core.RegularStatement)1 TableMetadata (com.datastax.driver.core.TableMetadata)1 Static (com.datastax.driver.mapping.annotation.Static)1 Field (java.lang.reflect.Field)1 Method (java.lang.reflect.Method)1 ArrayList (java.util.ArrayList)1 Callable (java.util.concurrent.Callable)1 EmbeddedId (javax.persistence.EmbeddedId)1 GeneratedValue (javax.persistence.GeneratedValue)1 Transient (javax.persistence.Transient)1 Version (javax.persistence.Version)1