SQLBuilder { public void addCriteria(String criteria, Object argument) { if (criteria == null || criteria.trim().isEmpty()) { throw new IllegalArgumentException("criteria cannot be null"); } String trimmedCriteria = criteria.trim(); if (trimmedCriteria.isEmpty()) { throw new IllegalArgumentException("criteria cannot be null"); } if (trimmedCriteria.contains("?")) { throw new IllegalArgumentException( "criteria cannot contain a '?' (that is automatically added at the end): " + trimmedCriteria); } int columnOperatorIndex = trimmedCriteria.indexOf(' '); if (columnOperatorIndex == -1) { throw new IllegalArgumentException("criteria missing operator: " + trimmedCriteria); } String columnName = trimmedCriteria.substring(0, columnOperatorIndex).trim().toLowerCase(Locale.ROOT); if (!ATOZ.matcher(columnName).matches()) { throw new IllegalArgumentException( "criteria column name must match [a-zA-Z_][a-zA-Z0-9_-]*\\.)?[a-zA-Z_-][a-zA-Z0-9_-]* : " + trimmedCriteria); } String operator = trimmedCriteria.substring(columnOperatorIndex).trim(); if (operator.indexOf(' ') > -1) { throw new IllegalArgumentException( "criteria cannot contain more than 1 space (between column name and operator): " + trimmedCriteria); } if (!operator.equals("=") && !operator.equals("<") && !operator.equals(">") && !operator.equals("<=") && !operator.equals(">=") && !operator.equals("<>") && !operator.equals("LIKE") && !operator.equals("like") && !operator.toLowerCase().equals("is")) { throw new IllegalArgumentException("criteria must end with valid SQL operator for WHERE: " + trimmedCriteria); } if (sb.length() > 0) { sb.append(" AND "); } sb.append(trimmedCriteria); sb.append(" ?"); crts.add(trimmedCriteria); args.add(argument); }  void addCriteria(String criteria, Object argument); void addNonNullCriteria(String criteria, Object argument); String getSQLTemplate(); Object[] getArguments(); @Override String toString();  }
@Test public void testLowerAndUpperCaseOperators() { SQLBuilder sqlBuilder = new SQLBuilder(); sqlBuilder.addCriteria("hobby LIKE ", "Mifos/Apache Fineract"); sqlBuilder.addCriteria("hobby like ", "Mifos/Apache Fineract"); }
@Test public void testAddIllegalArguments() throws Exception { assertThrows(IllegalArgumentException.class, () -> { new SQLBuilder().addCriteria("age<", 123); }, "space between column and operator"); assertThrows(IllegalArgumentException.class, () -> { new SQLBuilder().addCriteria(null, "argument"); }, "null Criteria Fragment"); assertThrows(IllegalArgumentException.class, () -> { new SQLBuilder().addCriteria("", "argument"); }, "empty Criteria Fragment"); assertThrows(IllegalArgumentException.class, () -> { new SQLBuilder().addCriteria(" ", "argument"); }, "space only Criteria Fragment"); assertThrows(IllegalArgumentException.class, () -> { new SQLBuilder().addCriteria("age = ?", 123); }, "Criteria Fragment with ?"); assertThrows(IllegalArgumentException.class, () -> { new SQLBuilder().addCriteria("age", 123); }, "Criteria Fragment missing operator"); assertThrows(IllegalArgumentException.class, () -> { new SQLBuilder().addCriteria("and age = ?", 123); }, "Criteria starts with AND"); assertThrows(IllegalArgumentException.class, () -> { new SQLBuilder().addCriteria("age = ? and", 123); }, "Criteria ends with AND"); assertThrows(IllegalArgumentException.class, () -> { new SQLBuilder().addCriteria("or age =", 123); }, "Criteria starts with OR"); assertThrows(IllegalArgumentException.class, () -> { new SQLBuilder().addCriteria("age = ? or", 123); }, "Criteria ends with OR"); assertThrows(IllegalArgumentException.class, () -> { new SQLBuilder().addCriteria("(age =", 123); }, "Criteria contains opening parentheis"); assertThrows(IllegalArgumentException.class, () -> { new SQLBuilder().addCriteria("age = ?)", 123); }, "Criteria contains closing parentheis"); assertThrows(IllegalArgumentException.class, () -> { new SQLBuilder().addCriteria("age< = ?)", 123); }, "Offset corner case"); }