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

com.droidlogix.dbflare.datahandler.EntityRepository Maven / Gradle / Ivy

package com.droidlogix.dbflare.datahandler;

import com.droidlogix.dbflare.datahandler.models.*;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.persistence.*;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.sql.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author John Pili
 * @since 2016-10-13
 */
public class EntityRepository implements IEntityRepository
{
	private static final Logger logger = LoggerFactory.getLogger(EntityRepository.class);

	EntityManager entityManager;
	ITotalCountGenerator totalCountGenerator;

	private long lapToLogExecution(long delta1, String queryString)
	{
		long delta2 = System.currentTimeMillis();
		long result = delta2 - delta1;
		return result;
	}

	public EntityRepository(EntityManager entityManager)
	{
		this.entityManager = entityManager;
	}

	public EntityRepository setTotalCountGenerator(ITotalCountGenerator totalCountGenerator)
	{
		this.totalCountGenerator = totalCountGenerator;
		return this;
	}

	@Override
	public  long create(List entities) throws Exception
	{
		long c = 0;
		try
		{
			for (T item : entities)
			{
				entityManager.persist(item);
				++c;
			}
			entityManager.flush();
		}
		catch (Exception exception)
		{
			throw new Exception(exception.getMessage());
		}
		return c;
	}

	@Override
	@SuppressWarnings("unchecked")
	public  void update(T entity, String findQuery, Map parameters) throws Exception
	{
		T r = null;
		try
		{
			Query query = entityManager.createQuery(findQuery.replace("\n", " "));
			feedParameters(query, parameters);
			r = (T) query.getSingleResult();
			if (r != null)
			{
				entityManager.merge(entity);
				entityManager.flush();
			}
		}
		catch (NoResultException nre)
		{
			throw new NoResultException();
		}
		catch (Exception exception)
		{
			throw new Exception(exception.getMessage());
		}
		finally
		{
			if (entityManager != null && entityManager.isOpen())
			{
				entityManager.close();
			}
		}
	}

	@Override
	@SuppressWarnings("unchecked")
	public  long update(List entities, String fieldName) throws Exception
	{
		long c = 0;
		try
		{
			if (entities != null && !entities.isEmpty())
			{
				for (T item : entities)
				{
					if (item != null)
					{
						Field field = item.getClass().getDeclaredField(fieldName);
						field.setAccessible(true);
						Object fieldValue = field.get(item);
						if(fieldValue == null)
						{
							throw new Exception("Field name (_key) is null or invalid");
						}

						T r = (T) entityManager.find(item.getClass(), field.get(item));
						if (r != null)
						{
							entityManager.merge(item);
							++c;
						}
					}
				}
				entityManager.flush();
			}
			return c;
		}
		catch (Exception exception)
		{
			throw new Exception(exception.getMessage());
		}
	}

	@Override
	@SuppressWarnings("unchecked")
	public  List delete(String findQuery, Map parameters) throws Exception
	{
		try
		{
			Query query = entityManager.createQuery(findQuery.replace("\n", " "));
			feedParameters(query, parameters);
			List tmpList = query.getResultList();
			if (tmpList != null && !tmpList.isEmpty())
			{
				for (T item : tmpList)
				{
					entityManager.remove(item);
				}
				entityManager.flush();
			}
			return tmpList;
		}
		catch (Exception exception)
		{
			throw new Exception(exception.getMessage());
		}
		finally
		{
			if (entityManager != null && entityManager.isOpen())
			{
				entityManager.close();
			}
		}
	}

	@Override
	@SuppressWarnings("unchecked")
	public  List delete(String findQuery, Map parameters, Type typeOf) throws Exception
	{
		return delete(findQuery, parameters);
	}

	@Override
	public List extractMetadata(String nativeSqlQuery) throws SQLException
	{
		try
		{
			Connection connection = entityManager.unwrap(Connection.class);
			connection.setAutoCommit(false);
			Statement stmt = connection.createStatement();
			stmt.setFetchSize(1);
			stmt.setMaxRows(1);
			ResultSet resultSet = stmt.executeQuery(nativeSqlQuery);
			List metadataResults = new ArrayList<>();
			ResultSetMetaData md = resultSet.getMetaData();
			for (int i = 1; i <= md.getColumnCount(); ++i)
			{
				MetadataResult tmp = new MetadataResult();
				tmp.setPosition(i);
				tmp.setCatalogName(md.getCatalogName(i));
				tmp.setColumnName(md.getColumnName(i));
				tmp.setColumnLabel(md.getColumnLabel(i));
				tmp.setColumnType(md.getColumnType(i));
				tmp.setColumnTypeName(md.getColumnTypeName(i));
				tmp.setColumnDisplaySize(md.getColumnDisplaySize(i));
				metadataResults.add(tmp);
			}
			return metadataResults;
		}
		finally
		{
			if (entityManager != null && entityManager.isOpen())
			{
				entityManager.close();
			}
		}
	}

	@Override
	public Object getSingle(String queryString, Map parameters,
	                        QUERY_STRING_TYPE queryStringType, IResultInfo resultInfo)
	{
		long delta1 = System.currentTimeMillis();
		try
		{
			Query query = null;
			if (queryStringType == QUERY_STRING_TYPE.JPQL_QUERY)
			{
				resultInfo.setTotal(getResultInfo(queryStringType, queryString, parameters).getTotal());

				query = entityManager.createQuery(queryString.replace("\n", " "));
				feedParameters(query, parameters);
				return query.getSingleResult();
			}
			else if (queryStringType == QUERY_STRING_TYPE.NATIVE_QUERY)
			{
				resultInfo.setTotal(getResultInfo(queryStringType, queryString, parameters).getTotal());

				query = entityManager.createNativeQuery(queryString.replace("\n", " "));
				feedParameters(query, parameters);
				return query.getSingleResult();
			}
			else if (queryStringType == QUERY_STRING_TYPE.NAMED_QUERY)
			{
				resultInfo.setTotal(getResultInfo(queryStringType, queryString, parameters).getTotal());

				query = entityManager.createNamedQuery(queryString.replace("\n", " "));
				feedParameters(query, parameters);
				return query.getSingleResult();
			}
		}
		catch (NoResultException noResultException)
		{
			//noResultException.printStackTrace();
		}
		catch (Exception exception)
		{
			throw exception;
		}
		finally
		{
			resultInfo.setDbExecutionTime(lapToLogExecution(delta1, queryString));
			if (entityManager != null && entityManager.isOpen())
			{
				entityManager.close();
			}
		}
		return null;
	}

	@Override
	public  List getList(String queryString, Map parameters, QUERY_STRING_TYPE queryStringType, IResultInfo resultInfo)
	{
		return processGetList(queryString, parameters, queryStringType, resultInfo);
	}

	@Override
	public  List getList(String queryString, Map parameters, QUERY_STRING_TYPE queryStringType, IResultInfo resultInfo, IPagingParameter pagingParameter)
	{
		return processGetList(queryString, parameters, queryStringType, resultInfo, pagingParameter);
	}

	/**
	 * This is a method that will execute the JPQL or Native SQL query getList.
	 * @param queryString
	 * @param parameters
	 * @param queryStringType
	 * @param resultInfo
	 * @param 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private  List processGetList(String queryString, Map parameters, QUERY_STRING_TYPE queryStringType, IResultInfo resultInfo)
	{
		long delta1 = System.currentTimeMillis();
		List tmpList = new ArrayList<>();
		try
		{
			if (queryStringType == QUERY_STRING_TYPE.JPQL_QUERY)
			{
				resultInfo.setTotal(getResultInfo(queryStringType, queryString, parameters).getTotal());

				Query query = entityManager.createQuery(queryString.replace("\n", " "));
				feedParameters(query, parameters);
				tmpList = query.getResultList();
			}
			else if (queryStringType == QUERY_STRING_TYPE.NATIVE_QUERY)
			{
				resultInfo.setTotal(getResultInfo(queryStringType, queryString, parameters).getTotal());

				Query query = entityManager.createNativeQuery(queryString.replace("\n", " "));
				feedParameters(query, parameters);
				tmpList = query.getResultList();
			}
			else if (queryStringType == QUERY_STRING_TYPE.NAMED_QUERY)
			{
				resultInfo.setTotal(getResultInfo(queryStringType, queryString, parameters).getTotal());

				Query query = entityManager.createNamedQuery(queryString.replace("\n", " "));
				feedParameters(query, parameters);
				tmpList = query.getResultList();
			}
		}
		catch (NoResultException noResultException)
		{
			return tmpList;
		}
		catch (Exception exception)
		{
			throw exception;
		}
		finally
		{
			resultInfo.setDbExecutionTime(lapToLogExecution(delta1, queryString));
			if (entityManager != null && entityManager.isOpen())
			{
				entityManager.close();
			}
		}
		return tmpList;
	}

	/**
	 * This is a method that will execute the JPQL or Native SQL query getList with pagination
	 * @param queryString
	 * @param parameters
	 * @param queryStringType
	 * @param resultInfo
	 * @param pagingParameter
	 * @param 
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	private  List processGetList(String queryString, Map parameters, QUERY_STRING_TYPE queryStringType, IResultInfo resultInfo, IPagingParameter pagingParameter)
	{
		long delta1 = System.currentTimeMillis();
		List tmpList = new ArrayList<>();
		try
		{
			if (queryStringType == QUERY_STRING_TYPE.JPQL_QUERY)
			{
				resultInfo.setTotal(getResultInfo(queryStringType, queryString, parameters).getTotal());

				Query query = entityManager.createQuery(queryString.replace("\n", " "));
				query.setFirstResult(pagingParameter.getSkip());
				query.setMaxResults(pagingParameter.getPageSize());

				feedParameters(query, parameters);
				tmpList = query.getResultList();
			}
			else if (queryStringType == QUERY_STRING_TYPE.NATIVE_QUERY)
			{
				resultInfo.setTotal(getResultInfo(queryStringType, queryString, parameters).getTotal());

				Query query = entityManager.createNativeQuery(queryString.replace("\n", " "));
				query.setFirstResult(pagingParameter.getSkip());
				query.setMaxResults(pagingParameter.getPageSize());

				feedParameters(query, parameters);
				tmpList = query.getResultList();
			}
			else if (queryStringType == QUERY_STRING_TYPE.NAMED_QUERY)
			{
				resultInfo.setTotal(getResultInfo(queryStringType, queryString, parameters).getTotal());

				Query query = entityManager.createNamedQuery(queryString.replace("\n", " "));
				query.setFirstResult(pagingParameter.getSkip());
				query.setMaxResults(pagingParameter.getPageSize());

				feedParameters(query, parameters);
				tmpList = query.getResultList();
			}
		}
		catch (NoResultException noResultException)
		{
			return tmpList;
		}
		catch (Exception exception)
		{
			throw exception;
		}
		finally
		{
			resultInfo.setDbExecutionTime(lapToLogExecution(delta1, queryString));
			if (entityManager != null && entityManager.isOpen())
			{
				entityManager.close();
			}
		}
		return tmpList;
	}

	@Override
	public List> nativeQuery(String queryString, Map parameters, IResultParser resultParser) throws Exception
	{
		try
		{
			Query query = entityManager.createNativeQuery(queryString.replace("\n", " "));
			feedParameters(query, parameters);
			return resultParser.parse(query.getResultList());
		}
		catch(Exception exception)
		{
			throw new Exception(exception.getMessage());
		}
	}

	/**
	 * This method handles the injection of parameters into the query
	 * @param query
	 * @param parameters
	 */
	private void feedParameters(Query query, Map parameters)
	{
		if (query != null)
		{
			if (parameters != null)
			{
				for (Map.Entry entry : parameters.entrySet())
				{
					if (entry.getKey().getClass() == String.class) // Named Parameters
					{
						//region CODE HANDLES THE BASIC NAMED PARAMETERS
						if (entry.getValue().getClass() == TemporalTypeParameter.class)
						{
							TemporalTypeParameter temporalTypeParameter = (TemporalTypeParameter) entry.getValue();
							query.setParameter((String) entry.getKey(), temporalTypeParameter.getTemporalTypeValue(), temporalTypeParameter.getTemporalType());
						}
						else if (entry.getValue().getClass() == DateTime.class)
						{
							query.setParameter((String) entry.getKey(), ((DateTime) entry.getValue()).toDate(), TemporalType.TIMESTAMP);
						}
						else if (entry.getValue().getClass() == Date.class)
						{
							query.setParameter((String) entry.getKey(), (Date) entry.getValue(), TemporalType.TIMESTAMP);
						}
						else
						{
							query.setParameter((String) entry.getKey(), entry.getValue()); // This assumes that value already formatted accordingly. Should be String, Integer or Double
						}
						//endregion
					}
					else if (entry.getKey().getClass() == Integer.class || entry.getKey().getClass() == Long.class) // Positional Parameters
					{
						if (entry.getValue().getClass() == TemporalTypeParameter.class)
						{
							TemporalTypeParameter temporalTypeParameter = (TemporalTypeParameter) entry.getValue();
							query.setParameter((Integer) entry.getKey(), temporalTypeParameter.getTemporalTypeValue(), temporalTypeParameter.getTemporalType());
						}
						else if (entry.getValue().getClass() == DateTime.class)
						{
							query.setParameter((Integer) entry.getKey(), ((DateTime) entry.getValue()).toDate(), TemporalType.TIMESTAMP);
						}
						else if (entry.getValue().getClass() == Date.class)
						{
							query.setParameter((Integer) entry.getKey(), (Date) entry.getValue(), TemporalType.TIMESTAMP);
						}
						else
						{
							query.setParameter((Integer) entry.getKey(), entry.getValue());
						}
					}
				}
			}
		}
	}

	/**
	 * This is a helper method in generating resultInfo with total row count
	 * @param queryStringType
	 * @param queryString
	 * @param parameters
	 * @return
	 */
	private IResultInfo getResultInfo(QUERY_STRING_TYPE queryStringType, String queryString, Map parameters)
	{
		IResultInfo resultInfo = new ResultInfo();
		try
		{
			if(this.totalCountGenerator == null)
			{
				resultInfo.setTotal(0);
			}

			switch (queryStringType)
			{
				case JPQL_QUERY:
				{
					Query plainQuery = entityManager.createQuery(this.totalCountGenerator.generateTotalCountQuery(queryStringType, queryString));
					feedParameters(plainQuery, parameters);
					resultInfo.setTotal((long) plainQuery.getSingleResult());
					return resultInfo;
				}
				case NATIVE_QUERY:
				{
					Query plainQuery = entityManager.createNativeQuery(this.totalCountGenerator.generateTotalCountQuery(queryStringType, queryString));
					feedParameters(plainQuery, parameters);
					resultInfo.setTotal((long) plainQuery.getSingleResult());
					return resultInfo;
				}
				case NAMED_QUERY:
				{
					Query plainQuery = entityManager.createNamedQuery(this.totalCountGenerator.generateTotalCountQuery(queryStringType, queryString));
					feedParameters(plainQuery, parameters);
					resultInfo.setTotal((long) plainQuery.getSingleResult());
					return resultInfo;
				}
				default:
				{
					resultInfo.setTotal(0);
				}
			}
		}
		catch (Exception exception)
		{
			resultInfo.setTotal(0);
		}
		return resultInfo;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy