All Downloads are FREE. Search and download functionalities are using the official Maven repository.

info.archinnov.achilles.entity.operations.impl.ThriftPersisterImpl Maven / Gradle / Ivy

package info.archinnov.achilles.entity.operations.impl;

import static info.archinnov.achilles.helper.ThriftLoggerHelper.format;
import static info.archinnov.achilles.serializer.ThriftSerializerUtils.*;
import static me.prettyprint.hector.api.beans.AbstractComposite.ComponentEquality.GREATER_THAN_EQUAL;
import info.archinnov.achilles.composite.ThriftCompositeFactory;
import info.archinnov.achilles.context.ThriftPersistenceContext;
import info.archinnov.achilles.dao.ThriftGenericWideRowDao;
import info.archinnov.achilles.entity.metadata.EntityMeta;
import info.archinnov.achilles.entity.metadata.JoinProperties;
import info.archinnov.achilles.entity.metadata.PropertyMeta;
import info.archinnov.achilles.entity.metadata.PropertyType;
import info.archinnov.achilles.entity.operations.AchillesEntityProxifier;
import info.archinnov.achilles.entity.operations.ThriftEntityPersister;
import info.archinnov.achilles.entity.operations.ThriftEntityProxifier;
import info.archinnov.achilles.exception.AchillesException;
import info.archinnov.achilles.proxy.AchillesMethodInvoker;
import info.archinnov.achilles.type.KeyValue;
import info.archinnov.achilles.validation.Validator;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import me.prettyprint.hector.api.beans.AbstractComposite.ComponentEquality;
import me.prettyprint.hector.api.beans.Composite;
import me.prettyprint.hector.api.mutation.Mutator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * ThriftPersisterImpl
 * 
 * @author DuyHai DOAN
 * 
 */
public class ThriftPersisterImpl
{
	private static final Logger log = LoggerFactory.getLogger(ThriftPersisterImpl.class);

	private AchillesMethodInvoker invoker = new AchillesMethodInvoker();
	private AchillesEntityProxifier proxifier = new ThriftEntityProxifier();

	private ThriftCompositeFactory thriftCompositeFactory = new ThriftCompositeFactory();

	public void batchPersistVersionSerialUID(ThriftPersistenceContext context)
	{
		Composite composite = new Composite();
		composite.setComponent(0, PropertyType.SERIAL_VERSION_UID.flag(), BYTE_SRZ, BYTE_SRZ
				.getComparatorType()
				.getTypeName());
		composite.setComponent(1, PropertyType.SERIAL_VERSION_UID.name(), STRING_SRZ, STRING_SRZ
				.getComparatorType()
				.getTypeName());
		composite.setComponent(2, 0, INT_SRZ, INT_SRZ.getComparatorType().getTypeName());
		Long serialVersionUID = context.getEntityMeta().getSerialVersionUID();

		if (serialVersionUID != null)
		{
			if (log.isTraceEnabled())
			{
				log
						.trace("Batch persisting serial version UID for entity of class {} and primary key {} with column name {}",
								context.getEntityClass().getCanonicalName(),
								context.getPrimaryKey(), format(composite));
			}
			context.getEntityDao().insertColumnBatch(context.getPrimaryKey(), composite,
					serialVersionUID.toString(), context.getEntityMutator(context.getTableName()));
		}
		else
		{
			throw new AchillesException("Cannot find 'serialVersionUID' field for entity class '"
					+ context.getEntityClass().getCanonicalName() + "'");
		}
	}

	public void batchPersistSimpleProperty(ThriftPersistenceContext context,
			PropertyMeta propertyMeta)
	{
		Composite name = thriftCompositeFactory.createForBatchInsertSingleValue(propertyMeta);
		String value = propertyMeta.writeValueToString(invoker.getValueFromField(
				context.getEntity(), propertyMeta.getGetter()));
		if (value != null)
		{
			if (log.isTraceEnabled())
			{
				log
						.trace("Batch persisting simple property {} from entity of class {} and primary key {} with column name {}",
								propertyMeta.getPropertyName(), context
										.getEntityClass()
										.getCanonicalName(), context.getPrimaryKey(), format(name));
			}
			context.getEntityDao().insertColumnBatch(context.getPrimaryKey(), name, value,
					context.getEntityMutator(context.getTableName()));
		}
	}

	public  void batchPersistList(List list, ThriftPersistenceContext context,
			PropertyMeta propertyMeta)
	{
		int count = 0;
		for (V value : list)
		{
			Composite name = thriftCompositeFactory.createForBatchInsertMultiValue(propertyMeta,
					count);

			String stringValue = propertyMeta.writeValueToString(value);
			if (stringValue != null)
			{
				if (log.isTraceEnabled())
				{
					log
							.trace("Batch persisting list property {} from entity of class {} and primary key {} with column name {}",
									propertyMeta.getPropertyName(), context
											.getEntityClass()
											.getCanonicalName(), context.getPrimaryKey(),
									format(name));
				}
				context.getEntityDao().insertColumnBatch(context.getPrimaryKey(), name,
						stringValue, context.getEntityMutator(context.getTableName()));
			}
			count++;
		}
	}

	public  void batchPersistSet(Set set, ThriftPersistenceContext context,
			PropertyMeta propertyMeta)
	{
		for (V value : set)
		{
			Composite name = thriftCompositeFactory.createForBatchInsertMultiValue(propertyMeta,
					value.hashCode());

			String stringValue = propertyMeta.writeValueToString(value);
			if (stringValue != null)
			{
				if (log.isTraceEnabled())
				{
					log
							.trace("Batch persisting set property {} from entity of class {} and primary key {} with column name {}",
									propertyMeta.getPropertyName(), context
											.getEntityClass()
											.getCanonicalName(), context.getPrimaryKey(),
									format(name));
				}
				context.getEntityDao().insertColumnBatch(context.getPrimaryKey(), name,
						stringValue, context.getEntityMutator(context.getTableName()));
			}
		}
	}

	public  void batchPersistMap(Map map, ThriftPersistenceContext context,
			PropertyMeta propertyMeta)
	{
		for (Entry entry : map.entrySet())
		{
			Composite name = thriftCompositeFactory.createForBatchInsertMultiValue(propertyMeta,
					entry.getKey().hashCode());

			String value = propertyMeta.writeValueToString(new KeyValue(entry.getKey(), entry
					.getValue()));

			if (log.isTraceEnabled())
			{
				log
						.trace("Batch persisting map property {} from entity of class {} and primary key {} with column name {}",
								propertyMeta.getPropertyName(), context
										.getEntityClass()
										.getCanonicalName(), context.getPrimaryKey(), format(name));
			}
			context.getEntityDao().insertColumnBatch(context.getPrimaryKey(), name, value,
					context.getEntityMutator(context.getTableName()));
		}
	}

	public  void batchPersistJoinEntity(ThriftPersistenceContext context,
			PropertyMeta propertyMeta, V joinEntity, ThriftEntityPersister persister)
	{
		JoinProperties joinProperties = propertyMeta.getJoinProperties();
		PropertyMeta idMeta = propertyMeta.joinIdMeta();

		Object joinId = invoker.getPrimaryKey(joinEntity, idMeta);
		Validator.validateNotNull(joinId, "Primary key for join entity '" + joinEntity
				+ "' should not be null");
		String joinIdString = idMeta.writeValueToString(joinId);

		Composite joinComposite = thriftCompositeFactory
				.createForBatchInsertSingleValue(propertyMeta);
		context.getEntityDao().insertColumnBatch(context.getPrimaryKey(), joinComposite,
				joinIdString, context.getEntityMutator(context.getTableName()));

		ThriftPersistenceContext joinPersistenceContext = (ThriftPersistenceContext) context
				.newPersistenceContext(propertyMeta.joinMeta(), proxifier.unproxy(joinEntity));

		if (log.isTraceEnabled())
		{
			log
					.trace("Batch persisting join primary key for property {} from entity of class {} and primary key {} with column name {}",
							propertyMeta.getPropertyName(), context
									.getEntityClass()
									.getCanonicalName(), context.getPrimaryKey(),
							format(joinComposite));
		}
		persister.cascadePersistOrEnsureExists(joinPersistenceContext, joinEntity, joinProperties);
	}

	public  void batchPersistJoinCollection(ThriftPersistenceContext context,
			PropertyMeta propertyMeta, Collection joinCollection,
			ThriftEntityPersister persister)
	{
		JoinProperties joinProperties = propertyMeta.getJoinProperties();
		EntityMeta joinEntityMeta = joinProperties.getEntityMeta();
		PropertyMeta joinIdMeta = joinEntityMeta.getIdMeta();
		int count = 0;
		for (V joinEntity : joinCollection)
		{
			Composite name = thriftCompositeFactory.createForBatchInsertMultiValue(propertyMeta,
					count);

			Object joinEntityId = invoker.getValueFromField(joinEntity, joinIdMeta.getGetter());

			String joinEntityIdStringValue = joinIdMeta.writeValueToString(joinEntityId);
			if (joinEntityIdStringValue != null)
			{
				if (log.isTraceEnabled())
				{
					log
							.trace("Batch persisting join primary keys for property {} from entity of class {} and primary key {} with column name {}",
									propertyMeta.getPropertyName(), context
											.getEntityClass()
											.getCanonicalName(), context.getPrimaryKey(),
									format(name));
				}
				context.getEntityDao().insertColumnBatch(context.getPrimaryKey(), name,
						joinEntityIdStringValue, context.getEntityMutator(context.getTableName()));

				ThriftPersistenceContext joinPersistenceContext = (ThriftPersistenceContext) context
						.newPersistenceContext(propertyMeta.joinMeta(),
								proxifier.unproxy(joinEntity));

				persister.cascadePersistOrEnsureExists(joinPersistenceContext, joinEntity,
						joinProperties);
			}
			count++;
		}
	}

	public  void batchPersistJoinMap(ThriftPersistenceContext context,
			PropertyMeta propertyMeta, Map joinMap, ThriftEntityPersister persiter)
	{
		JoinProperties joinProperties = propertyMeta.getJoinProperties();
		EntityMeta joinEntityMeta = joinProperties.getEntityMeta();
		PropertyMeta idMeta = joinEntityMeta.getIdMeta();

		for (Entry entry : joinMap.entrySet())
		{
			Composite name = thriftCompositeFactory.createForBatchInsertMultiValue(propertyMeta,
					entry.getKey().hashCode());

			V joinEntity = entry.getValue();
			Object joinEntityId = invoker.getValueFromField(joinEntity, idMeta.getGetter());
			String joinEntityIdStringValue = idMeta.writeValueToString(joinEntityId);

			String value = propertyMeta.writeValueToString(new KeyValue(entry.getKey(),
					joinEntityIdStringValue));
			context.getEntityDao().insertColumnBatch(context.getPrimaryKey(), name, value,
					context.getEntityMutator(context.getTableName()));

			ThriftPersistenceContext joinPersistenceContext = (ThriftPersistenceContext) context
					.newPersistenceContext(propertyMeta.joinMeta(), proxifier.unproxy(joinEntity));

			if (log.isTraceEnabled())
			{
				log
						.trace("Batch persisting join primary keys for property {} from entity of class {} and primary key {} with column name {}",
								propertyMeta.getPropertyName(), context
										.getEntityClass()
										.getCanonicalName(), context.getPrimaryKey(), format(name));
			}
			persiter.cascadePersistOrEnsureExists(joinPersistenceContext, joinEntity,
					joinProperties);
		}
	}

	public void remove(ThriftPersistenceContext context)
	{
		EntityMeta entityMeta = context.getEntityMeta();
		Object primaryKey = context.getPrimaryKey();

		if (context.isWideRow())
		{
			log.trace("Batch removing wide row of class {} and primary key {}", context
					.getEntityClass()
					.getCanonicalName(), context.getPrimaryKey());
			Mutator wideRowMutator = context.getWideRowMutator(entityMeta.getTableName());
			context.getColumnFamilyDao().removeRowBatch(primaryKey, wideRowMutator);
		}
		else
		{

			log.trace("Batch removing entity of class {} and primary key {}", context
					.getEntityClass()
					.getCanonicalName(), context.getPrimaryKey());

			Mutator entityMutator = context.getEntityMutator(entityMeta.getTableName());
			context.getEntityDao().removeRowBatch(primaryKey, entityMutator);
			for (Entry> entry : entityMeta.getPropertyMetas().entrySet())
			{
				PropertyMeta propertyMeta = entry.getValue();
				if (propertyMeta.isWideMap())
				{

					if (propertyMeta.isCounter())
					{
						removeCounterWideMap(context, propertyMeta);
					}
					else
					{
						removeWideMap(context, primaryKey, propertyMeta);
					}
				}
				if (propertyMeta.isCounter())
				{
					removeSimpleCounter(context, propertyMeta);
				}
			}
		}
	}

	private void removeWideMap(ThriftPersistenceContext context, Object primaryKey,
			PropertyMeta propertyMeta)
	{
		log.trace("Batch removing wideMap property {} of class {} and primary key {}",
				propertyMeta.getPropertyName(), context.getEntityClass().getCanonicalName(),
				context.getPrimaryKey());

		String externalColumnFamilyName = propertyMeta.getExternalCFName();
		ThriftGenericWideRowDao findColumnFamilyDao = context
				.findWideRowDao(externalColumnFamilyName);
		findColumnFamilyDao.removeRowBatch(primaryKey,
				context.getWideRowMutator(externalColumnFamilyName));
	}

	public void removePropertyBatch(ThriftPersistenceContext context,
			PropertyMeta propertyMeta)
	{
		Composite start = thriftCompositeFactory.createBaseForQuery(propertyMeta,
				ComponentEquality.EQUAL);
		Composite end = thriftCompositeFactory.createBaseForQuery(propertyMeta, GREATER_THAN_EQUAL);

		if (log.isTraceEnabled())
		{
			log
					.trace("Batch removing property {} of class {} and primary key {} with column names {}  / {}",
							propertyMeta.getPropertyName(), context
									.getEntityClass()
									.getCanonicalName(), context.getPrimaryKey(), format(start),
							format(end));
		}
		context.getEntityDao().removeColumnRangeBatch(context.getPrimaryKey(), start, end,
				context.getEntityMutator(context.getTableName()));
	}

	private void removeSimpleCounter(ThriftPersistenceContext context,
			PropertyMeta propertyMeta)
	{
		Composite keyComp = thriftCompositeFactory.createKeyForCounter(propertyMeta.fqcn(),
				context.getPrimaryKey(), propertyMeta.counterIdMeta());
		Composite com = thriftCompositeFactory.createForBatchInsertSingleCounter(propertyMeta);

		log.trace("Batch removing counter property {} of class {} and primary key {}",
				propertyMeta.getPropertyName(), context.getEntityClass().getCanonicalName(),
				context.getPrimaryKey());

		context.getCounterDao().removeCounterBatch(keyComp, com, context.getCounterMutator());
	}

	private void removeCounterWideMap(ThriftPersistenceContext context,
			PropertyMeta propertyMeta)
	{

		log.trace("Batch removing counter wideMap property {} of class {} and primary key {}",
				propertyMeta.getPropertyName(), context.getEntityClass().getCanonicalName(),
				context.getPrimaryKey());

		Composite keyComp = thriftCompositeFactory.createKeyForCounter(propertyMeta.fqcn(),
				context.getPrimaryKey(), propertyMeta.counterIdMeta());
		context.getCounterDao().removeCounterRowBatch(keyComp, context.getCounterMutator());
	}
}