com.ebuddy.cassandra.cql.dao.CqlStructuredDataSupport Maven / Gradle / Ivy
/*
* Copyright (C) 2013 eBuddy B.V.
*
* 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.ebuddy.cassandra.cql.dao;
import static com.datastax.driver.core.querybuilder.QueryBuilder.batch;
import static com.datastax.driver.core.querybuilder.QueryBuilder.bindMarker;
import static com.datastax.driver.core.querybuilder.QueryBuilder.delete;
import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
import static com.datastax.driver.core.querybuilder.QueryBuilder.gte;
import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
import static com.datastax.driver.core.querybuilder.QueryBuilder.lte;
import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.Validate;
import com.datastax.driver.core.PreparedStatement;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.Row;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.Statement;
import com.datastax.driver.core.querybuilder.Batch;
import com.datastax.driver.core.querybuilder.Delete;
import com.ebuddy.cassandra.BatchContext;
import com.ebuddy.cassandra.Path;
import com.ebuddy.cassandra.StructuredDataSupport;
import com.ebuddy.cassandra.TypeReference;
import com.ebuddy.cassandra.databind.CustomTypeResolverBuilder;
import com.ebuddy.cassandra.structure.Composer;
import com.ebuddy.cassandra.structure.Decomposer;
import com.ebuddy.cassandra.structure.DefaultPath;
import com.ebuddy.cassandra.structure.JacksonTypeReference;
import com.ebuddy.cassandra.structure.StructureConverter;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* Implementation of StructuredDataSupport for CQL.
*
* To use structured data in CQL3, the following data modeling rules apply:
*
* - There must be a designated path column and it must be the first clustering key, i.e. the next element of the
* primary key after the partition key.
* - There must be a designated value column.
* - There can only be one designated path and one designated value column per table.
* - The designated path and value columns must be typed as a textual type.
*
*
* @author Eric Zoerner [email protected]
*/
public class CqlStructuredDataSupport implements StructuredDataSupport {
private static final String DEFAULT_VALUE_COLUMN = "value";
private static final String DEFAULT_PATH_COLUMN = "column1";
private static final String DEFAULT_PARTITION_KEY_COLUMN = "key";
private static final int MAX_CODE_POINT = 0x10FFFF;
private final Session session;
private final String pathColumnName;
private final String valueColumnName;
private final ObjectMapper writeMapper;
private final ObjectMapper readMapper;
private final PreparedStatement readPathQuery;
private final Statement insertStatement;
private final PreparedStatement readForDeleteQuery;
private final String tableName;
private final String partitionKeyColumnName;
/**
* Used for tables that are upgraded from a thrift dynamic column family that still has the default column names.
* @param session a Session configured with the keyspace
*/
public CqlStructuredDataSupport(String tableName, Session session) {
this(tableName, DEFAULT_PARTITION_KEY_COLUMN, DEFAULT_PATH_COLUMN, DEFAULT_VALUE_COLUMN, session);
}
/**
* Construct an instance of CqlStructuredDataSupport with the specified table and column names.
* @param session a Session configured with the keyspace
*/
public CqlStructuredDataSupport(String tableName,
String partitionKeyColumnName,
String pathColumnName,
String valueColumnName,
Session session) {
Validate.notEmpty(tableName);
this.session = session;
this.pathColumnName = pathColumnName;
this.valueColumnName = valueColumnName;
writeMapper = new ObjectMapper();
writeMapper.setDefaultTyping(new CustomTypeResolverBuilder());
readMapper = new ObjectMapper();
this.tableName = tableName;
this.partitionKeyColumnName = partitionKeyColumnName;
readPathQuery = session.prepare(select(pathColumnName, valueColumnName)
.from(tableName)
.where(eq(partitionKeyColumnName, bindMarker()))
.and(gte(pathColumnName, bindMarker()))
.and(lte(pathColumnName, bindMarker()))
.getQueryString());
readForDeleteQuery = session.prepare(select(pathColumnName)
.from(tableName)
.where(eq(partitionKeyColumnName, bindMarker()))
.and(gte(pathColumnName, bindMarker()))
.and(lte(pathColumnName, bindMarker()))
.getQueryString());
insertStatement = insertInto(tableName)
.value(partitionKeyColumnName, bindMarker())
.value(pathColumnName, bindMarker())
.value(valueColumnName, bindMarker());
}
@Override
public BatchContext beginBatch() {
return new CqlBatchContext();
}
@Override
public void applyBatch(BatchContext batchContext) {
Batch batch = validateAndGetBatch(batchContext);
List
© 2015 - 2024 Weber Informatics LLC | Privacy Policy