package io.shockah.skylark.db; import java.lang.reflect.Field; import java.sql.SQLException; import java.util.regex.Pattern; import com.j256.ormlite.field.DatabaseField; import com.j256.ormlite.field.SqlType; import com.j256.ormlite.stmt.SelectArg; import com.j256.ormlite.stmt.Where; import io.shockah.skylark.UnexpectedException; public final class WhereBuilder { public static enum Operator { AND, OR; } public final Where<?, ?> where; public final Operator operator; private boolean first = true; public WhereBuilder(Where<?, ?> where) { this(where, Operator.AND); } public WhereBuilder(Where<?, ?> where, Operator operator) { this.where = where; this.operator = operator; } private void checkFirst() { if (first) { first = false; } else { switch (operator) { case AND: where.and(); break; case OR: where.or(); break; } } } private String getColumnName(Field field) { DatabaseField dbField = field.getAnnotation(DatabaseField.class); if (dbField == null) throw new IllegalArgumentException(); if (dbField.columnName() == null) return field.getName(); return dbField.columnName(); } public WhereBuilder equals(Field field, Object value) { return equals(getColumnName(field), value); } public WhereBuilder equals(String columnName, Object value) { try { checkFirst(); if (value == null) where.isNull(columnName); else where.eq(columnName, value); } catch (SQLException e) { throw new UnexpectedException(e); } return this; } public WhereBuilder notEquals(Field field, Object value) { return notEquals(getColumnName(field), value); } public WhereBuilder notEquals(String columnName, Object value) { try { checkFirst(); if (value == null) where.isNotNull(columnName); else where.ne(columnName, value); } catch (SQLException e) { throw new UnexpectedException(e); } return this; } public WhereBuilder greater(Field field, Object value) { return greater(getColumnName(field), value); } public WhereBuilder greater(String columnName, Object value) { try { checkFirst(); where.gt(columnName, value); } catch (SQLException e) { throw new UnexpectedException(e); } return this; } public WhereBuilder greaterOrEqual(Field field, Object value) { return greaterOrEqual(getColumnName(field), value); } public WhereBuilder greaterOrEqual(String columnName, Object value) { try { checkFirst(); where.ge(columnName, value); } catch (SQLException e) { throw new UnexpectedException(e); } return this; } public WhereBuilder less(Field field, Object value) { return less(getColumnName(field), value); } public WhereBuilder less(String columnName, Object value) { try { checkFirst(); where.lt(columnName, value); } catch (SQLException e) { throw new UnexpectedException(e); } return this; } public WhereBuilder lessOrEqual(Field field, Object value) { return lessOrEqual(getColumnName(field), value); } public WhereBuilder lessOrEqual(String columnName, Object value) { try { checkFirst(); where.le(columnName, value); } catch (SQLException e) { throw new UnexpectedException(e); } return this; } public WhereBuilder between(Field field, Object low, Object high) { return between(getColumnName(field), low, high); } public WhereBuilder between(String columnName, Object low, Object high) { try { checkFirst(); where.between(columnName, low, high); } catch (SQLException e) { throw new UnexpectedException(e); } return this; } public WhereBuilder regexp(Field field, String pattern) { return regexp(getColumnName(field), pattern); } public WhereBuilder regexp(String columnName, String pattern) { try { checkFirst(); where.rawComparison(columnName, "REGEXP", pattern); } catch (SQLException e) { throw new UnexpectedException(e); } return this; } public WhereBuilder regexp(Field field, Pattern pattern) { return regexp(getColumnName(field), pattern.pattern()); } public WhereBuilder regexp(String columnName, Pattern pattern) { try { checkFirst(); where.rawComparison(columnName, "REGEXP", pattern.pattern()); } catch (SQLException e) { throw new UnexpectedException(e); } return this; } public WhereBuilder reverseRegexp(Field field, String value) { return reverseRegexp(getColumnName(field), value); } public WhereBuilder reverseRegexp(String columnName, String value) { checkFirst(); where.raw(String.format("? REGEXP %s", columnName), new SelectArg(SqlType.STRING, value)); return this; } }