diff --git a/common/pom.xml b/common/pom.xml
index ae7fc5a..f1635dd 100644
--- a/common/pom.xml
+++ b/common/pom.xml
@@ -8,6 +8,13 @@
common
${project.artifactId}
+
+
+ junit
+ junit
+ test
+
+
${project.artifactId}
diff --git a/common/src/main/java/com/moparisthebest/jdbc/util/InListUtil.java b/common/src/main/java/com/moparisthebest/jdbc/util/InListUtil.java
new file mode 100644
index 0000000..e2eeee8
--- /dev/null
+++ b/common/src/main/java/com/moparisthebest/jdbc/util/InListUtil.java
@@ -0,0 +1,59 @@
+package com.moparisthebest.jdbc.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class InListUtil {
+
+ private static List> split(final List list, final int maxLength) {
+ final int listSize = list.size();
+ final List> ret = new ArrayList>();
+ if (listSize < maxLength)
+ ret.add(list);
+ else
+ for (int fromIndex = 0, toIndex = maxLength; fromIndex < listSize; fromIndex = toIndex, toIndex += maxLength)
+ ret.add(list.subList(fromIndex, toIndex > listSize ? listSize : toIndex));
+ return ret;
+ }
+
+ private static StringBuilder buildCommaSeparatedList(final Iterable list, final StringBuilder sb) {
+ boolean notFirst = false;
+ for (final T obj : list) {
+ if (notFirst) sb.append(',');
+ else notFirst = true;
+ sb.append('?');
+ }
+ return sb;
+ }
+
+ private static StringBuilder buildInList(final Iterable list, final StringBuilder sb, final String fieldName, final String listPrefix) {
+ return buildCommaSeparatedList(list, sb.append(fieldName).append(listPrefix)).append(")");
+ }
+
+ private static String toInList(final String fieldName, final Collection items, final int maxSize, final String listPrefix, final String listCombine) {
+ final StringBuilder sb = new StringBuilder("(");
+
+ // do it quick if it will fit in one in-list
+ if (items.size() < maxSize) // 999 or less
+ return buildInList(items, sb, fieldName, listPrefix).append(")").toString();
+
+ // else we need to split lists
+ boolean notFirst = false;
+ for (final List item : split(items instanceof List ? (List) items : new ArrayList(items), maxSize)) {
+ if (notFirst) sb.append(listCombine);
+ else notFirst = true;
+ buildInList(item, sb, fieldName, listPrefix);
+ }
+
+ return sb.append(")").toString();
+ }
+
+ public static String toInList(final String fieldName, final Collection items, final int maxSize) {
+ return toInList(fieldName, items, maxSize, " IN (", " OR ");
+ }
+
+ public static String toNotInList(final String fieldName, final Collection items, final int maxSize) {
+ return toInList(fieldName, items, maxSize, " NOT IN (", " AND ");
+ }
+}
diff --git a/common/src/test/java/com/moparisthebest/jdbc/util/InListUtilTest.java b/common/src/test/java/com/moparisthebest/jdbc/util/InListUtilTest.java
new file mode 100644
index 0000000..73effd8
--- /dev/null
+++ b/common/src/test/java/com/moparisthebest/jdbc/util/InListUtilTest.java
@@ -0,0 +1,87 @@
+package com.moparisthebest.jdbc.util;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+
+import static com.moparisthebest.jdbc.util.InListUtil.toInList;
+import static com.moparisthebest.jdbc.util.InListUtil.toNotInList;
+import static org.junit.Assert.assertEquals;
+
+public class InListUtilTest {
+
+ private static Collection makeCollection(final int length) {
+ final Collection ret = new ArrayList(length);
+ final int loopLength = length + 1;
+ for(int x = 1; x < loopLength; ++x)
+ ret.add((long) x);
+ return ret;
+ }
+
+ @Test
+ public void testMakeCollection() {
+ assertEquals(new ArrayList(Arrays.asList(1L, 2L, 3L)), makeCollection(3));
+ }
+
+ @Test
+ public void testShortInList() {
+ assertEquals("(column_name IN (?,?,?,?,?))", toInList("column_name", makeCollection(5), 20));
+ }
+
+ @Test
+ public void testShortNotInList() {
+ assertEquals("(column_name NOT IN (?,?,?,?,?))", toNotInList("column_name", makeCollection(5), 20));
+ }
+
+ @Test
+ public void testExactInList() {
+ assertEquals("(column_name IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?))",
+ toInList("column_name", makeCollection(20), 20));
+ }
+
+ @Test
+ public void testExactNotInList() {
+ assertEquals("(column_name NOT IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?))",
+ toNotInList("column_name", makeCollection(20), 20));
+ }
+
+ @Test
+ public void testOneOverInList() {
+ assertEquals("(column_name IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) OR column_name IN (?))",
+ toInList("column_name", makeCollection(21), 20));
+ }
+
+ @Test
+ public void testOneOverNotInList() {
+ assertEquals("(column_name NOT IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) AND column_name NOT IN (?))",
+ toNotInList("column_name", makeCollection(21), 20));
+ }
+
+ @Test
+ public void testOneUnderInList() {
+ assertEquals("(column_name IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?))",
+ toInList("column_name", makeCollection(19), 20));
+ }
+
+ @Test
+ public void testOneUnderNotInList() {
+ assertEquals("(column_name NOT IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?))",
+ toNotInList("column_name", makeCollection(19), 20));
+ }
+
+ @Test
+ public void testOneOver3InList() {
+ assertEquals("(column_name IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) OR column_name IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) " +
+ "OR column_name IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) OR column_name IN (?))",
+ toInList("column_name", makeCollection(61), 20));
+ }
+
+ @Test
+ public void testOneOver3NotInList() {
+ assertEquals("(column_name NOT IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) AND column_name NOT IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) " +
+ "AND column_name NOT IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) AND column_name NOT IN (?))",
+ toNotInList("column_name", makeCollection(61), 20));
+ }
+}
diff --git a/querymapper/src/main/java/com/moparisthebest/jdbc/BindInList.java b/querymapper/src/main/java/com/moparisthebest/jdbc/BindInList.java
index 80f4288..370f2a0 100644
--- a/querymapper/src/main/java/com/moparisthebest/jdbc/BindInList.java
+++ b/querymapper/src/main/java/com/moparisthebest/jdbc/BindInList.java
@@ -3,6 +3,8 @@ package com.moparisthebest.jdbc;
import java.sql.Connection;
import java.util.*;
+import static com.moparisthebest.jdbc.util.InListUtil.toInList;
+
/**
* Created by mopar on 4/29/15.
*/
@@ -26,53 +28,9 @@ public class BindInList implements InList {
this(defaultMaxSize);
}
- private static List> split(final List list, final int maxLength) {
- final int listSize = list.size();
- final List> ret = new ArrayList>();
- if (listSize < maxLength)
- ret.add(list);
- else
- for (int fromIndex = 0, toIndex = maxLength; fromIndex < listSize; fromIndex = toIndex, toIndex += maxLength)
- ret.add(list.subList(fromIndex, toIndex > listSize ? listSize : toIndex));
- return ret;
- }
-
- private String toInList(final String fieldName, final Collection items) {
- final StringBuilder sb = new StringBuilder("(");
-
- // do it quick if it will fit in one in-list
- if (items.size() < maxSize) // 999 or less
- return buildInList(items, sb, fieldName).append(")").toString();
-
- // else we need to split lists
- boolean notFirst = false;
- for (final List item : split(new ArrayList(items), maxSize)) {
- if (notFirst) sb.append(" OR ");
- else notFirst = true;
- buildInList(item, sb, fieldName);
- }
-
- return sb.append(")").toString();
- }
-
- private static StringBuilder buildInList(Iterable list, StringBuilder sb, String fieldName) {
- return oracleCommaSeparatedList(list, sb.append(fieldName).append(" IN (")).append(")");
- }
-
- private static StringBuilder oracleCommaSeparatedList(Iterable list, StringBuilder sb) {
- boolean notFirst = false;
- for (final T obj : list) {
- // DO NOT DO THIS ANYMORE: if (obj == null) continue;
- if (notFirst) sb.append(',');
- else notFirst = true;
- sb.append('?');
- }
- return sb;
- }
-
public InListObject inList(final Connection conn, final String columnName, final Collection values) {
return values == null || values.isEmpty() ? InListObject.empty : new BindInListObject(
- toInList(columnName, values),
+ toInList(columnName, values, this.maxSize),
values.toArray()
);
}