com.wizarius.orm.database.actions.builders.WizWhereQueryBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of wizarius-orm Show documentation
Show all versions of wizarius-orm Show documentation
Java orm for Postgres or Mysql with migration system and connection pool
The newest version!
package com.wizarius.orm.database.actions.builders;
import com.wizarius.orm.database.DBException;
import com.wizarius.orm.database.DBRuntimeException;
import com.wizarius.orm.database.data.*;
import com.wizarius.orm.database.data.fieldfinder.FieldFinder;
import com.wizarius.orm.database.data.fieldfinder.FieldFinderResult;
import com.wizarius.orm.database.entityreader.DBSupportedTypes;
import com.wizarius.orm.database.entityreader.WizEntityManager;
import com.wizarius.orm.database.handlers.WritableHandler;
import com.wizarius.orm.database.handlers.WritableHandlers;
import lombok.Setter;
import java.lang.reflect.Array;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author Vladyslav Shyshkin
* Date: 2019-10-17
* Time: 23:23
*/
public class WizWhereQueryBuilder {
/**
* List of where queries
*/
private final List where = new ArrayList<>();
/**
* Group stack
*/
private final Deque groupStack = new ArrayDeque<>();
/**
* Field finder
*/
private final FieldFinder fieldFinder;
/**
* DB where type
*/
@Setter
private DBWhereType whereType = DBWhereType.AND;
/**
* Writable handlers
*/
private final WritableHandlers writableHandlers;
public WizWhereQueryBuilder(WritableHandlers writableHandlers, FieldFinder fieldsFinder) {
this.writableHandlers = writableHandlers;
this.fieldFinder = fieldsFinder;
}
/**
* Setup where filed
*
* @param field filed name
* @param value field value
*/
public void where(String field, Object value) {
if (value == null) {
throw new DBRuntimeException("Value can't be null");
}
addCondition(new WhereBaseCondition<>(whereType, field, value, DBSignType.EQUALS));
}
/**
* Setup where filed
*
* @param field filed name
* @param value field value
* @param signType sign type
*/
public void where(String field, Object value, DBSignType signType) {
if (value == null) {
throw new DBRuntimeException("Value can't be null");
}
if (signType == DBSignType.IN || signType == DBSignType.NOT_IN) {
whereIN(field, value, signType);
} else {
addCondition(new WhereBaseCondition<>(whereType, field, value, signType));
}
}
/**
* Setup where filed
*
* @param key database field name
* @param value database field value
* @param clazz instance of object
* @throws DBException on unable to build where condition
*/
public void where(String key, Object value, Class> clazz) throws DBException {
if (value == null) {
throw new DBRuntimeException("Value can't be null");
}
where(key, value, DBSignType.EQUALS, clazz);
}
/**
* Start group
*/
public void startWhereGroup() {
WhereGroupCondition groupCondition = new WhereGroupCondition(whereType);
addCondition(groupCondition);
groupStack.push(groupCondition);
}
/**
* Ends the current group of conditions.
*
* @throws DBRuntimeException if no group has been started or the last condition is not a group
*/
public void endWhereGroup() {
if (groupStack.isEmpty()) {
throw new DBRuntimeException("Cannot end group: No group has been started. Please call startGroup() before endGroup().");
}
groupStack.pop();
}
/**
* Build where clause
*
* @param key database field name
* @param value database field value
* @param signType where sign type
* @param clazz instance of object
* @throws DBException on unable to build where condition
*/
public void where(String key,
Object value,
DBSignType signType,
Class> clazz) throws DBException {
if (value == null) {
throw new DBRuntimeException("Value can't be null");
}
FieldFinderResult dbField;
if (clazz == null) {
dbField = fieldFinder.findDBField(key);
} else {
dbField = fieldFinder.findDBField(key, clazz);
}
if (dbField == null) {
throw new DBRuntimeException("Unable to find field where name = " + key);
}
addCondition(new WhereBaseCondition<>(whereType, dbField.getFindField().getDbFieldName(), value, signType));
}
/**
* Setup where query
*
* @param query custom query
*/
public void where(String query) {
addCondition(new WhereQueryCondition(whereType, query));
}
/**
* Setup where field in array
*
* @param field field name
* @param values values array
*/
public void whereIN(String field, Object values) {
whereIN(field, values, DBSignType.IN);
}
/**
* Setup where NOT IN array
*
* @param field db field name
* @param values values array
*/
public void whereNotIN(String field, Object values) {
whereIN(field, values, DBSignType.NOT_IN);
}
/**
* Setup where IN or NOT IN query
*
* @param values values array
* @param field database field name
* @param sign sign type IN or NOT IN
*/
private void whereIN(String field, Object values, DBSignType sign) {
if (values == null) {
throw new DBRuntimeException("Array must be present in where condition");
}
if (!values.getClass().isArray()) {
throw new DBRuntimeException("Class is not array");
}
Object[] array = buildArray(values);
if (array.length == 0) {
throw new DBRuntimeException("Array can't be empty for condition");
}
addCondition(new WhereInCondition<>(whereType, field, array, sign));
}
/**
* Setup where field is null
*
* @param field database field name
*/
public void whereNull(String field) {
addCondition(new WhereNullCondition(whereType, field, true));
}
/**
* Setup where field is not null
*
* @param field database field name
*/
public void whereIsNotNull(String field) {
addCondition(new WhereNullCondition(whereType, field, false));
}
/**
* Setup where field between values
*
* @param field field name
* @param value1 value1
* @param value2 value2
*/
public void whereBetween(String field, Object value1, Object value2) {
if (value1 == null || value2 == null) {
throw new DBRuntimeException("Array must be present in where condition");
}
addCondition(new WhereBetweenCondition(whereType, field, value1, value2));
}
/**
* Setup prepared query where values
*
* @param index index in prepared statement
* @param statement prepared query
* @throws DBException on unable to set up where values
*/
public void setupWhereValues(AtomicInteger index, PreparedStatement statement) throws DBException {
setupWhereValues(where, index, statement);
}
/**
* Recursive setup query where values
*
* @param conditions conditions
* @param index index
* @param statement statement
* @throws DBException on unable to set value in query
*/
private void setupWhereValues(List conditions, AtomicInteger index, PreparedStatement statement) throws DBException {
for (WhereCondition condition : conditions) {
if (condition instanceof WhereBaseCondition>) {
WhereBaseCondition> item = (WhereBaseCondition>) condition;
Object value = item.getValue();
setupIndexValue(index, statement, value);
} else if (condition instanceof WhereInCondition) {
WhereInCondition> item = (WhereInCondition>) condition;
for (Object value : item.getValues()) {
setupIndexValue(index, statement, value);
}
} else if (condition instanceof WhereBetweenCondition) {
WhereBetweenCondition item = (WhereBetweenCondition) condition;
setupIndexValue(index, statement, item.getValue1());
setupIndexValue(index, statement, item.getValue2());
} else if (condition instanceof WhereGroupCondition) {
WhereGroupCondition item = (WhereGroupCondition) condition;
setupWhereValues(item.getConditions(), index, statement);
}
}
}
/**
* Setup value for index
*
* @param index index
* @param statement statement
* @param value value
* @throws DBException on unable to setup value
*/
@SuppressWarnings({"rawtypes", "unchecked"})
private void setupIndexValue(AtomicInteger index, PreparedStatement statement, Object value) throws DBException {
DBSupportedTypes supportedType = WizEntityManager.javaTypeToDBType(value.getClass());
WritableHandler handlerByType = writableHandlers.getHandlerByType(supportedType);
try {
handlerByType.set(value, index.getAndIncrement(), statement);
} catch (SQLException e) {
throw new DBException("Unable to setup value to prepared statement", e);
}
}
/**
* Recursive build conditions
*
* @param conditions list of conditions
* @param sb StringBuilder to build sql
*/
private void buildConditions(List conditions, StringBuilder sb, boolean isGroup) {
boolean first = true;
for (WhereCondition condition : conditions) {
if (!first) {
String space = isGroup ? " " : "\n";
sb.append(space).append(condition.getType()).append(space);
}
if (condition instanceof WhereBaseCondition>) {
WhereBaseCondition> item = (WhereBaseCondition>) condition;
sb.append(item.getDbFieldName()).append(" ")
.append(item.getSignType().getSign())
.append(" ?");
} else if (condition instanceof WhereInCondition) {
WhereInCondition> item = (WhereInCondition>) condition;
sb.append(item.getDbFieldName())
.append(" ")
.append(item.getSignType().getSign())
.append(" (")
.append(buildQuestionsCount(item.getValues().length))
.append(")");
} else if (condition instanceof WhereNullCondition) {
WhereNullCondition item = (WhereNullCondition) condition;
sb.append(item.getDbFieldName()).append(" ").append(item.isNull() ? "IS NULL" : "IS NOT NULL");
} else if (condition instanceof WhereBetweenCondition) {
WhereBetweenCondition item = (WhereBetweenCondition) condition;
sb.append(item.getDbFieldName()).append(" ").append("BETWEEN ? AND ?");
} else if (condition instanceof WhereQueryCondition) {
WhereQueryCondition item = (WhereQueryCondition) condition;
sb.append(item.getQuery());
} else if (condition instanceof WhereGroupCondition) {
WhereGroupCondition groupCondition = (WhereGroupCondition) condition;
sb.append("(");
buildConditions(groupCondition.getConditions(), sb, true);
sb.append(")");
}
first = false;
}
}
/**
* Build where clause
*
* @return where prepared string
*/
public String getWhereQuery() {
if (where.isEmpty()) {
return "";
}
if (!groupStack.isEmpty()) {
throw new DBRuntimeException("Not all condition groups have been closed. Please ensure that for every call to startGroup(), there is a corresponding endGroup().");
}
StringBuilder sb = new StringBuilder("WHERE\n");
buildConditions(where, sb, false);
return sb.toString();
}
/**
* Returns a string with the given number of question characters
*
* @param length questions count
* @return string like ?,?,?
*/
private String buildQuestionsCount(int length) {
if (length == 1) {
return "?";
}
StringBuilder sb = new StringBuilder();
for (int i = length; i > 0; i--) {
sb.append("?").append(",");
}
sb.setLength(sb.length() - 1);
return sb.toString();
}
/**
* Convert values array
*
* @param values value object
* @return object array for value
*/
private Object[] buildArray(Object values) {
if (values instanceof Object[]) {
return (Object[]) values;
}
int length = Array.getLength(values);
Object[] result = new Object[length];
for (int i = 0; i < length; ++i) {
result[i] = Array.get(values, i);
}
return result;
}
/**
* Add condition in build current query
*
* @param condition condition
*/
private void addCondition(WhereCondition condition) {
if (!groupStack.isEmpty()) {
groupStack.peek().getConditions().add(condition);
} else {
where.add(condition);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy