Package org.easycassandra.persistence.cassandra

Source Code of org.easycassandra.persistence.cassandra.FixColumnFamily

/*
* Copyright 2013 Otávio Gonçalves de Santana (otaviojava)
* 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 org.easycassandra.persistence.cassandra;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import org.easycassandra.ClassInformation;
import org.easycassandra.ClassInformations;
import org.easycassandra.FieldInformation;
import org.easycassandra.FieldJavaNotEquivalentCQLException;
import org.easycassandra.KeyProblemsException;
import org.easycassandra.persistence.cassandra.AddColumnUtil.AddColumn;
import org.easycassandra.persistence.cassandra.VerifyRowUtil.VerifyRow;

import com.datastax.driver.core.ColumnDefinitions.Definition;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.exceptions.InvalidQueryException;
import com.datastax.driver.core.querybuilder.QueryBuilder;
import com.datastax.driver.core.querybuilder.Select;

/**
* Class to fix a column family.
* @author otaviojava
*/
class FixColumnFamily {

    private static final String QUERY_PRIMARY_KEY = " PRIMARY KEY (";

    /**
     * verify if exist column family and try to create.
     * @param session - bridge to cassandra data base
     * @param keySpace - the keyspace
     * @param familyColumn - name of family column
     * @param class1 - bean
     * @return - if get it or not
     */
    public boolean verifyColumnFamily(Session session, String keySpace, String familyColumn,
            Class<?> class1) {
        try {
            Select select = QueryBuilder.select().from(keySpace, familyColumn).limit(1);
            ResultSet resultSet = session.execute(select);
            verifyRowType(resultSet, class1, session);
            findIndex(class1, session);
            return true;
        } catch (InvalidQueryException exception) {

            if (exception.getCause().getMessage().contains("unconfigured columnfamily ")) {
                Logger.getLogger(FixColumnFamily.class.getName()).info(
                        "Column family doesn't exist, try to create");
                createColumnFamily(familyColumn, class1, session);
                findIndex(class1, session);
                return true;
            }
        }

        return false;
    }

    /**
     * Column family exists verify.
     * @param resultSet
     */
    private void verifyRowType(ResultSet resultSet, Class<?> class1, Session session) {
        Map<String, String> mapNameType = new HashMap<String, String>();
        for (Definition column : resultSet.getColumnDefinitions()) {
            mapNameType
                    .put(column.getName(), column.getType().getName().name());
        }
        ClassInformation classInformation = ClassInformations.INSTACE.getClass(class1);
        verifyRow(classInformation, session, mapNameType);
    }

    /**
     * verify relationship beteween Java and CQL type.
     * @param class1
     * @param session
     * @param mapNameType
     */
    private void verifyRow(ClassInformation classInformation, Session session,
            Map<String, String> mapNameType) {

        for (FieldInformation fieldInformation : classInformation.getFields()) {

            if (fieldInformation.isKeyCheck()) {
                continue;
            } else if (fieldInformation.isEmbedded() && !fieldInformation.isKeyCheck()) {
                verifyRow(fieldInformation.getSubFields(), session, mapNameType);
                continue;
            }

            String cqlType = mapNameType.get(fieldInformation.getName().toLowerCase());
            if (cqlType == null) {
                executeAlterTableAdd(classInformation, session, fieldInformation);
                continue;
            }

            VerifyRow verifyRow = VerifyRowUtil.INTANCE.factory(fieldInformation);
            List<String> cqlTypes = verifyRow.getTypes(fieldInformation.getField());

            if (!cqlTypes.contains(cqlType.toLowerCase())) {
                createMessageErro(classInformation, fieldInformation, cqlType);
            }

        }
    }

    /**
     * call the command to alter table adding a field.
     * @param class1
     *            - bean within column family
     * @param session
     *            - bridge to cassandra
     * @param field
     *            - field to add in column family
     */
    private void executeAlterTableAdd(ClassInformation classInformation, Session session,
            FieldInformation field) {
        StringBuilder cqlAlterTable = new StringBuilder();
        cqlAlterTable.append("ALTER TABLE ").append(classInformation.getNameSchema());
        cqlAlterTable.append(" ADD ");
        AddColumn addColumn = AddColumnUtil.INSTANCE.factory(field);
        cqlAlterTable.append(addColumn.addRow(field, RelationShipJavaCassandra.INSTANCE));
        cqlAlterTable.deleteCharAt(cqlAlterTable.length() - 1);
        cqlAlterTable.append(";");
        session.execute(cqlAlterTable.toString());
    }

    /**
     * Field Java isn't equivalents with CQL type create error mensage.
     * @param classInformation
     * @param field
     * @param cqlTypes
     */
    private void createMessageErro(ClassInformation classInformation,
            FieldInformation field, String cqlType) {
        StringBuilder erroMensage = new StringBuilder();
        erroMensage.append("In the objetc ").append(classInformation.getClass().getName());
        erroMensage.append(" the field ").append(field.getName());
        erroMensage.append(" of the type ").append(field.getField().getType().getName());
        erroMensage.append(" isn't equivalent with CQL type ").append(cqlType);
        erroMensage.append(" was expected: ").append(
                RelationShipJavaCassandra.INSTANCE.getJavaValue(cqlType
                        .toLowerCase()));
        throw new FieldJavaNotEquivalentCQLException(erroMensage.toString());
    }

    /**
     * Column family doen'snt exist create with this method.
     * @param familyColumn
     *            - name of column family
     * @param class1
     *            - bean
     * @param session
     *            bridge of cassandra data base
     */
    private void createColumnFamily(String familyColumn, Class<?> class1,
            Session session) {
        StringBuilder cqlCreateTable = new StringBuilder();
        cqlCreateTable.append("create table ");

        cqlCreateTable.append(familyColumn).append("( ");
        ClassInformation classInformation = ClassInformations.INSTACE.getClass(class1);
        createQueryCreateTable(classInformation, cqlCreateTable);
        if (classInformation.isComplexKey()) {
            addComlexID(classInformation, cqlCreateTable);
        } else {
            addSimpleId(classInformation, cqlCreateTable);
        }

        session.execute(cqlCreateTable.toString());
    }

    /**
     * add in the query a simple id.
     * @param class1
     * @param cqlCreateTable
     */
    private void addSimpleId(ClassInformation classInformation, StringBuilder cqlCreateTable) {
        FieldInformation keyField = classInformation.getKeyInformation();
        if (keyField == null) {
            createErro(classInformation);
        }
        cqlCreateTable.append(QUERY_PRIMARY_KEY)
                .append(keyField.getName())
                .append(") );");
    }


    /**
     * add in the query a complex key.
     * @param classInformation
     * @param cqlCreateTable
     */
    private void addComlexID(ClassInformation classInformation, StringBuilder cqlCreateTable) {

        FieldInformation keyField = classInformation.getKeyInformation();
        cqlCreateTable.append(QUERY_PRIMARY_KEY);
        boolean firstTime = true;
        if (keyField == null) {
            createErro(classInformation);
        }
        for (FieldInformation subKey : keyField.getSubFields().getFields()) {
            if (firstTime) {
                cqlCreateTable.append(subKey.getName());
                firstTime = false;
            } else {
                cqlCreateTable.append(",").append(subKey.getName());
            }
        }
        cqlCreateTable.append(") );");
    }

    /**
     * @param bean
     */
    private void createErro(ClassInformation bean) {

        StringBuilder erroMensage = new StringBuilder();

        erroMensage.append("the bean ").append(bean.getNameSchema());
        erroMensage
                .append(" hasn't  a field with id annotation, "
                        + "you may to use either javax.persistence.Id");
        erroMensage.append(" to simple id or javax.persistence.EmbeddedId");
        erroMensage
                .append(" to complex id, another object with one "
                        + "or more fields annotated with java.persistence.Column.");
        throw new KeyProblemsException(erroMensage.toString());
    }

    /**
     * create a query to create table and return if exist a complex id or not.
     * @param class1
     * @param cqlCreateTable
     * @param javaCassandra
     * @return
     */
    private void createQueryCreateTable(ClassInformation class1,
            StringBuilder cqlCreateTable) {
        for (FieldInformation field : class1.getFields()) {
            if (field.isEmbedded()) {

                createQueryCreateTable(field.getSubFields(), cqlCreateTable);
                continue;
            }

            AddColumn addColumn = AddColumnUtil.INSTANCE.factory(field);
            cqlCreateTable.append(addColumn.addRow(field,
                    RelationShipJavaCassandra.INSTANCE));
        }
    }

    /**
     * Find if exists.
     * REMARK edited by : Dinusha Nandika;
     */
    private void findIndex(Class<?> familyColumn, Session session) {
        ClassInformation classInformation = ClassInformations.INSTACE.getClass(familyColumn);
        if (classInformation.getIndexFields().size() == 0) {
            return;
        }
        for (FieldInformation index : classInformation.getIndexFields()) {
          createIndex(classInformation, session, index);
    }
    }

    /**
     * method to create index.
     * @param familyColumn
     * @param session
     * @param index
     */
  private void createIndex(ClassInformation familyColumn, Session session,
          FieldInformation index) {
    StringBuilder createIndexQuery;
    createIndexQuery = new StringBuilder();
    createIndexQuery.append("CREATE INDEX ");
    createIndexQuery.append(index.getName()).append(" ON ");
    createIndexQuery.append(familyColumn.getNameSchema());
    createIndexQuery.append(" (").append(index.getName()).append(");");
    try {
      session.execute(createIndexQuery.toString());
    } catch (InvalidQueryException exception) {
      Logger.getLogger(FixColumnFamily.class.getName()).info("Index already exists");
    }
  }
}
TOP

Related Classes of org.easycassandra.persistence.cassandra.FixColumnFamily

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.