Package info.archinnov.achilles.internal.statement

Source Code of info.archinnov.achilles.internal.statement.StatementGenerator

/*
* Copyright (C) 2012-2014 DuyHai DOAN
*
*  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 info.archinnov.achilles.internal.statement;

import static com.datastax.driver.core.querybuilder.QueryBuilder.timestamp;
import static com.datastax.driver.core.querybuilder.QueryBuilder.ttl;
import static com.datastax.driver.core.querybuilder.QueryBuilder.update;
import static info.archinnov.achilles.type.Options.CASCondition;
import static org.apache.commons.lang3.ArrayUtils.addAll;
import java.util.ArrayList;
import java.util.List;

import info.archinnov.achilles.internal.metadata.holder.EntityMetaConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.datastax.driver.core.querybuilder.Update;
import com.datastax.driver.core.querybuilder.Update.Assignments;
import com.google.common.base.Optional;
import info.archinnov.achilles.exception.AchillesException;
import info.archinnov.achilles.internal.context.facade.PersistentStateHolder;
import info.archinnov.achilles.internal.metadata.holder.EntityMeta;
import info.archinnov.achilles.internal.persistence.operations.CollectionAndMapChangeType;
import info.archinnov.achilles.internal.proxy.dirtycheck.DirtyCheckChangeSet;
import info.archinnov.achilles.type.Pair;

public class StatementGenerator {

    private static final Logger log = LoggerFactory.getLogger(StatementGenerator.class);

    public Pair<Update.Where, Object[]> generateCollectionAndMapUpdateOperation(PersistentStateHolder context, DirtyCheckChangeSet changeSet) {
        log.trace("Generate collection/map update operation for dirty change set {}", changeSet);

        final Object entity = context.getEntity();
        final EntityMeta meta = context.getEntityMeta();
        final EntityMetaConfig metaConfig = meta.config();

        final Optional<Integer> ttlO = context.getTtl();
        final Optional<Long> timestampO = context.getTimestamp();
        final List<CASCondition> CASConditions = context.getCasConditions();

        final Update.Conditions conditions = update(metaConfig.getKeyspaceName(), metaConfig.getTableName()).onlyIf();
        List<Object> casEncodedValues = addAndEncodeCasConditions(meta, CASConditions, conditions);

        Object[] boundValues = new Object[] { };
        if (ttlO.isPresent()) {
            conditions.using(ttl(ttlO.get()));
            boundValues = addAll(boundValues, new Object[] { ttlO.get() });
        }

        if (timestampO.isPresent()) {
            conditions.using(timestamp(timestampO.get()));
            boundValues = addAll(boundValues, new Object[] { timestampO.get() });
        }

        final CollectionAndMapChangeType operationType = changeSet.getChangeType();

        Pair<Assignments, Object[]> updateClauseAndBoundValues;
        switch (operationType) {
            case SET_TO_LIST_AT_INDEX:
                updateClauseAndBoundValues = changeSet.generateUpdateForSetAtIndexElement(conditions);
                break;
            case REMOVE_FROM_LIST_AT_INDEX:
                updateClauseAndBoundValues = changeSet.generateUpdateForRemovedAtIndexElement(conditions);
                break;
            default:
                throw new AchillesException(String.format("Should not generate non-prepared statement for collection/map change of type '%s'", operationType));
        }

        final Pair<Update.Where, Object[]> whereClauseAndBoundValues = meta.getIdMeta().forStatementGeneration().generateWhereClauseForUpdate(entity, changeSet.getPropertyMeta(), updateClauseAndBoundValues.left);
        boundValues = addAll(addAll(boundValues, addAll(updateClauseAndBoundValues.right, whereClauseAndBoundValues.right)), casEncodedValues.toArray());
        return Pair.create(whereClauseAndBoundValues.left, boundValues);
    }

    private List<Object> addAndEncodeCasConditions(EntityMeta entityMeta, List<CASCondition> CASConditions, Update.Conditions conditions) {
        List<Object> casEncodedValues = new ArrayList<>();
        for (CASCondition casCondition : CASConditions) {
            final Object encodedValue = entityMeta.forTranscoding().encodeCasConditionValue(casCondition);
            casEncodedValues.add(encodedValue);
            conditions.and(casCondition.toClause());
        }
        return casEncodedValues;
    }

    public static enum Singleton {
        INSTANCE;

        private final StatementGenerator instance = new StatementGenerator();

        public StatementGenerator get() {
            return instance;
        }
    }
}
TOP

Related Classes of info.archinnov.achilles.internal.statement.StatementGenerator

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.