diff --git a/src/database/DB.java b/src/database/DB.java
index aa2e5449..39d118ac 100644
--- a/src/database/DB.java
+++ b/src/database/DB.java
@@ -3,7 +3,6 @@ package database;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@@ -168,65 +167,6 @@ public class DB {
return result;
}
- /**
- * Format table and column names into an INSERT INTO ... SQL statement.
- *
- * Full form is:
- *
- * INSERT INTO table (column, ...) VALUES (?, ...) ON DUPLICATE KEY UPDATE column=?, ...
- *
- * Note that HSQLDB needs to put into mySQL compatibility mode first via "SET DATABASE SQL SYNTAX MYS TRUE".
- *
- * @param table
- * @param columns
- * @return String
- */
- public static String formatInsertWithPlaceholders(String table, String... columns) {
- String[] placeholders = new String[columns.length];
- Arrays.setAll(placeholders, (int i) -> "?");
-
- StringBuilder output = new StringBuilder();
- output.append("INSERT INTO ");
- output.append(table);
- output.append(" (");
- output.append(String.join(", ", columns));
- output.append(") VALUES (");
- output.append(String.join(", ", placeholders));
- output.append(") ON DUPLICATE KEY UPDATE ");
- output.append(String.join("=?, ", columns));
- output.append("=?");
- return output.toString();
- }
-
- /**
- * Binds Objects to PreparedStatement based on INSERT INTO ... ON DUPLICATE KEY UPDATE ...
- *
- * Note that each object is bound to two place-holders based on this SQL syntax:
- *
- * INSERT INTO table (column, ...) VALUES (?, ...) ON DUPLICATE KEY UPDATE column=?, ...
- *
- * Requires that mySQL SQL syntax support is enabled during connection.
- *
- * @param preparedStatement
- * @param objects
- * @throws SQLException
- */
- public static void bindInsertPlaceholders(PreparedStatement preparedStatement, Object... objects) throws SQLException {
- for (int i = 0; i < objects.length; ++i) {
- Object object = objects[i];
-
- // Special treatment for BigDecimals so that they retain their "scale",
- // which would otherwise be assumed as 0.
- if (object instanceof BigDecimal) {
- preparedStatement.setBigDecimal(i + 1, (BigDecimal) object);
- preparedStatement.setBigDecimal(i + objects.length + 1, (BigDecimal) object);
- } else {
- preparedStatement.setObject(i + 1, object);
- preparedStatement.setObject(i + objects.length + 1, object);
- }
- }
- }
-
/**
* Execute SQL using byte[] as 1st placeholder.
*
diff --git a/src/database/SaveHelper.java b/src/database/SaveHelper.java
new file mode 100644
index 00000000..bb159a71
--- /dev/null
+++ b/src/database/SaveHelper.java
@@ -0,0 +1,132 @@
+package database;
+
+import java.math.BigDecimal;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Database helper for building, and executing, INSERT INTO ... ON DUPLICATE KEY UPDATE ... statements.
+ *
+ * Columns, and corresponding values, are bound via close-coupled pairs in a chain thus:
+ *
+ * {@code SaveHelper helper = new SaveHelper(connection, "TableName"); }
+ * {@code helper.bind("column_name", someColumnValue).bind("column2", columnValue2); }
+ * {@code helper.execute(); }
+ *
+ */
+public class SaveHelper {
+
+ private Connection connection;
+ private String table;
+
+ private List columns = new ArrayList();
+ private List