mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 13:10:44 +00:00
QQQ-21 change Update action to use batch, and single-query w/ IN list for same-updates
This commit is contained in:
@ -42,7 +42,7 @@ jobs:
|
|||||||
executor: java17
|
executor: java17
|
||||||
steps:
|
steps:
|
||||||
- run_maven:
|
- run_maven:
|
||||||
maven_subcommand: test
|
maven_subcommand: verify
|
||||||
- slack/notify:
|
- slack/notify:
|
||||||
event: fail
|
event: fail
|
||||||
|
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -27,3 +27,4 @@ target/
|
|||||||
|
|
||||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||||
hs_err_pid*
|
hs_err_pid*
|
||||||
|
.DS_Store
|
||||||
|
@ -181,8 +181,8 @@
|
|||||||
</module>
|
</module>
|
||||||
-->
|
-->
|
||||||
<module name="OverloadMethodsDeclarationOrder"/>
|
<module name="OverloadMethodsDeclarationOrder"/>
|
||||||
<module name="VariableDeclarationUsageDistance"/>
|
|
||||||
<!--
|
<!--
|
||||||
|
<module name="VariableDeclarationUsageDistance"/>
|
||||||
<module name="CustomImportOrder">
|
<module name="CustomImportOrder">
|
||||||
<property name="sortImportsInGroupAlphabetically" value="true"/>
|
<property name="sortImportsInGroupAlphabetically" value="true"/>
|
||||||
<property name="separateLineBetweenGroups" value="true"/>
|
<property name="separateLineBetweenGroups" value="true"/>
|
||||||
|
@ -97,7 +97,7 @@ public abstract class AbstractRDBMSAction
|
|||||||
** Handle obvious problems with values - like empty string for integer should be null.
|
** Handle obvious problems with values - like empty string for integer should be null.
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
protected Serializable scrubValue(QFieldMetaData field, Serializable value)
|
protected Serializable scrubValue(QFieldMetaData field, Serializable value, boolean isInsert)
|
||||||
{
|
{
|
||||||
if("".equals(value))
|
if("".equals(value))
|
||||||
{
|
{
|
||||||
@ -111,10 +111,13 @@ public abstract class AbstractRDBMSAction
|
|||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
// todo - let this come from something in the field //
|
// todo - let this come from something in the field //
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
if(value == null && (field.getName().equals("createDate") || field.getName().equals("modifyDate")))
|
if(value == null)
|
||||||
|
{
|
||||||
|
if((isInsert && field.getName().equals("createDate")) || field.getName().equals("modifyDate"))
|
||||||
{
|
{
|
||||||
value = OffsetDateTime.now();
|
value = OffsetDateTime.now();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (value);
|
return (value);
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ public class RDBMSInsertAction extends AbstractRDBMSAction implements InsertInte
|
|||||||
for(QFieldMetaData field : insertableFields)
|
for(QFieldMetaData field : insertableFields)
|
||||||
{
|
{
|
||||||
Serializable value = record.getValue(field.getName());
|
Serializable value = record.getValue(field.getName());
|
||||||
value = scrubValue(field, value);
|
value = scrubValue(field, value, true);
|
||||||
|
|
||||||
params.add(value);
|
params.add(value);
|
||||||
}
|
}
|
||||||
|
@ -24,8 +24,11 @@ package com.kingsrook.qqq.backend.module.rdbms.actions;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.update.UpdateRequest;
|
import com.kingsrook.qqq.backend.core.model.actions.update.UpdateRequest;
|
||||||
@ -34,11 +37,19 @@ import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
|||||||
import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.modules.interfaces.UpdateInterface;
|
import com.kingsrook.qqq.backend.core.modules.interfaces.UpdateInterface;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.ListingHash;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||||
import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager;
|
import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager;
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
** Only the fields which exist in the record's values map will be updated.
|
||||||
|
** Note the difference between a field being in the value map, with a null value,
|
||||||
|
** vs. not being in the map. If the field (its key) is in the value map, with a
|
||||||
|
** null value, then the field will be updated to NULL. But if it's not in the
|
||||||
|
** map, then it'll be ignored. This would be to do a PATCH type operation, vs a
|
||||||
|
** PUT. See https://rapidapi.com/blog/put-vs-patch/
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public class RDBMSUpdateAction extends AbstractRDBMSAction implements UpdateInterface
|
public class RDBMSUpdateAction extends AbstractRDBMSAction implements UpdateInterface
|
||||||
{
|
{
|
||||||
@ -48,52 +59,59 @@ public class RDBMSUpdateAction extends AbstractRDBMSAction implements UpdateInte
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public UpdateResult execute(UpdateRequest updateRequest) throws QException
|
public UpdateResult execute(UpdateRequest updateRequest) throws QException
|
||||||
{
|
{
|
||||||
try
|
if(CollectionUtils.nullSafeIsEmpty(updateRequest.getRecords()))
|
||||||
{
|
{
|
||||||
|
throw (new QException("Request to update 0 records."));
|
||||||
|
}
|
||||||
|
|
||||||
UpdateResult rs = new UpdateResult();
|
UpdateResult rs = new UpdateResult();
|
||||||
QTableMetaData table = updateRequest.getTable();
|
QTableMetaData table = updateRequest.getTable();
|
||||||
|
|
||||||
List<QRecord> outputRecords = new ArrayList<>();
|
List<QRecord> outputRecords = new ArrayList<>();
|
||||||
rs.setRecords(outputRecords);
|
rs.setRecords(outputRecords);
|
||||||
|
|
||||||
// todo - sql batch for performance
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// todo - if setting a bunch of records to have the same value, a single update where id IN?
|
// we want to do batch updates. But, since we only update the columns columns that //
|
||||||
Connection connection = getConnection(updateRequest);
|
// are present in each record, it means we may have different update SQL for each //
|
||||||
int recordIndex = 0;
|
// record. So, we will first "hash" up the records by their list of fields being updated. //
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
ListingHash<List<String>, QRecord> recordsByFieldBeingUpdated = new ListingHash<>();
|
||||||
for(QRecord record : updateRequest.getRecords())
|
for(QRecord record : updateRequest.getRecords())
|
||||||
{
|
{
|
||||||
List<QFieldMetaData> updateableFields = table.getFields().values().stream()
|
List<String> updatableFields = table.getFields().values().stream()
|
||||||
.filter(field -> !field.getName().equals("id")) // todo - intent here is to avoid non-updateable fields.
|
.map(QFieldMetaData::getName)
|
||||||
.filter(field -> record.getValues().containsKey(field.getName()))
|
// todo - intent here is to avoid non-updateable fields - but this
|
||||||
|
// should be like based on field.isUpdatable once that attribute exists
|
||||||
|
.filter(name -> !name.equals("id"))
|
||||||
|
.filter(name -> record.getValues().containsKey(name))
|
||||||
.toList();
|
.toList();
|
||||||
|
recordsByFieldBeingUpdated.add(updatableFields, record);
|
||||||
|
|
||||||
String columns = updateableFields.stream()
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
.map(f -> this.getColumnName(f) + " = ?")
|
// go ahead and put the record into the output list at this point in time, //
|
||||||
.collect(Collectors.joining(", "));
|
// so that the output list's order matches the input list order //
|
||||||
|
// note that if we want to capture updated values (like modify dates), then //
|
||||||
String tableName = getTableName(table);
|
// we may want a map of primary key to output record, for easy updating. //
|
||||||
StringBuilder sql = new StringBuilder("UPDATE ").append(tableName)
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
.append(" SET ").append(columns)
|
|
||||||
.append(" WHERE ").append(getColumnName(table.getField(table.getPrimaryKeyField()))).append(" = ?");
|
|
||||||
|
|
||||||
// todo sql customization - can edit sql and/or param list
|
|
||||||
|
|
||||||
QRecord outputRecord = new QRecord(record);
|
QRecord outputRecord = new QRecord(record);
|
||||||
outputRecords.add(outputRecord);
|
outputRecords.add(outputRecord);
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
List<Object> params = new ArrayList<>();
|
|
||||||
for(QFieldMetaData field : updateableFields)
|
|
||||||
{
|
|
||||||
Serializable value = record.getValue(field.getName());
|
|
||||||
value = scrubValue(field, value);
|
|
||||||
params.add(value);
|
|
||||||
}
|
}
|
||||||
params.add(record.getValue(table.getPrimaryKeyField()));
|
|
||||||
|
|
||||||
QueryManager.executeUpdate(connection, sql.toString(), params);
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// todo - auto-updated values, e.g., modifyDate... maybe need to re-select?
|
// todo - further optimization: if setting a bunch of records to have the same value, a single update where id IN ? //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
try(Connection connection = getConnection(updateRequest))
|
||||||
|
{
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// process each distinct list of fields being updated (e.g., each different SQL statement) //
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
for(List<String> fieldsBeingUpdated : recordsByFieldBeingUpdated.keySet())
|
||||||
|
{
|
||||||
|
updateRecordsWithMatchingListOfFields(connection, table, recordsByFieldBeingUpdated.get(fieldsBeingUpdated), fieldsBeingUpdated);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rs;
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
@ -102,12 +120,133 @@ public class RDBMSUpdateAction extends AbstractRDBMSAction implements UpdateInte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rs;
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private void updateRecordsWithMatchingListOfFields(Connection connection, QTableMetaData table, List<QRecord> recordList, List<String> fieldsBeingUpdated) throws SQLException
|
||||||
{
|
{
|
||||||
throw new QException("Error executing update: " + e.getMessage(), e);
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// check for an optimization - if all of the records have the same values for //
|
||||||
|
// all fields being updated, just do 1 update, with an IN list on the ids. //
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
if(areAllValuesBeingUpdatedTheSame(recordList, fieldsBeingUpdated))
|
||||||
|
{
|
||||||
|
updateRecordsWithMatchingValuesAndFields(connection, table, recordList, fieldsBeingUpdated);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String sql = writeUpdateSQLPrefix(table, fieldsBeingUpdated) + " = ?";
|
||||||
|
|
||||||
|
// todo sql customization? - let each table have custom sql and/or param list
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
// build the list of list of values, from the records //
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
List<List<Serializable>> values = new ArrayList<>();
|
||||||
|
for(QRecord record : recordList)
|
||||||
|
{
|
||||||
|
List<Serializable> rowValues = new ArrayList<>();
|
||||||
|
values.add(rowValues);
|
||||||
|
|
||||||
|
for(String fieldName : fieldsBeingUpdated)
|
||||||
|
{
|
||||||
|
Serializable value = record.getValue(fieldName);
|
||||||
|
value = scrubValue(table.getField(fieldName), value, false);
|
||||||
|
rowValues.add(value);
|
||||||
|
}
|
||||||
|
rowValues.add(record.getValue(table.getPrimaryKeyField()));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// let query manager do the batch updates - note that it will internally page //
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
QueryManager.executeBatchUpdate(connection, sql, values);
|
||||||
|
|
||||||
|
// todo - auto-updated values, e.g., modifyDate... maybe need to re-select?
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private String writeUpdateSQLPrefix(QTableMetaData table, List<String> fieldsBeingUpdated)
|
||||||
|
{
|
||||||
|
String columns = fieldsBeingUpdated.stream()
|
||||||
|
.map(f -> this.getColumnName(table.getField(f)) + " = ?")
|
||||||
|
.collect(Collectors.joining(", "));
|
||||||
|
|
||||||
|
String tableName = getTableName(table);
|
||||||
|
return ("UPDATE " + tableName
|
||||||
|
+ " SET " + columns
|
||||||
|
+ " WHERE " + getColumnName(table.getField(table.getPrimaryKeyField())) + " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private void updateRecordsWithMatchingValuesAndFields(Connection connection, QTableMetaData table, List<QRecord> recordList, List<String> fieldsBeingUpdated) throws SQLException
|
||||||
|
{
|
||||||
|
String sql = writeUpdateSQLPrefix(table, fieldsBeingUpdated) + " IN (" + StringUtils.join(",", Collections.nCopies(recordList.size(), "?")) + ")";
|
||||||
|
|
||||||
|
// todo sql customization? - let each table have custom sql and/or param list
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
// values in the update clause can come from the first record //
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
QRecord record0 = recordList.get(0);
|
||||||
|
List<Object> params = new ArrayList<>();
|
||||||
|
for(String fieldName : fieldsBeingUpdated)
|
||||||
|
{
|
||||||
|
Serializable value = record0.getValue(fieldName);
|
||||||
|
value = scrubValue(table.getField(fieldName), value, false);
|
||||||
|
params.add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// values in the where clause (in list) are the id from each record //
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
for(QRecord record : recordList)
|
||||||
|
{
|
||||||
|
params.add(record.getValue(table.getPrimaryKeyField()));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// let query manager do the batch updates - note that it will internally page //
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
QueryManager.executeUpdate(connection, sql, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private boolean areAllValuesBeingUpdatedTheSame(List<QRecord> recordList, List<String> fieldsBeingUpdated)
|
||||||
|
{
|
||||||
|
if(recordList.size() == 1)
|
||||||
|
{
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
QRecord record0 = recordList.get(0);
|
||||||
|
for(int i = 1; i < recordList.size(); i++)
|
||||||
|
{
|
||||||
|
QRecord record = recordList.get(i);
|
||||||
|
for(String fieldName : fieldsBeingUpdated)
|
||||||
|
{
|
||||||
|
if(!Objects.equals(record0.getValue(fieldName), record.getValue(fieldName)))
|
||||||
|
{
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ public class ConnectionManager
|
|||||||
}
|
}
|
||||||
case "h2":
|
case "h2":
|
||||||
{
|
{
|
||||||
jdbcURL = "jdbc:h2:" + backend.getHostName() + ":" + backend.getDatabaseName() + ";MODE=MySQL";
|
jdbcURL = "jdbc:h2:" + backend.getHostName() + ":" + backend.getDatabaseName() + ";MODE=MySQL;DB_CLOSE_DELAY=-1";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -22,13 +22,12 @@
|
|||||||
package com.kingsrook.qqq.backend.module.rdbms.jdbc;
|
package com.kingsrook.qqq.backend.module.rdbms.jdbc;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.Date;
|
import java.sql.Date;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.ResultSetMetaData;
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
@ -43,13 +42,10 @@ import java.time.temporal.ChronoUnit;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
import org.apache.commons.lang.NotImplementedException;
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -114,6 +110,8 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static void executeStatementForeachResult(Connection connection, String sql, ResultSetProcessor processor, Object... params) throws SQLException
|
public static void executeStatementForeachResult(Connection connection, String sql, ResultSetProcessor processor, Object... params) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
PreparedStatement statement = null;
|
PreparedStatement statement = null;
|
||||||
ResultSet resultSet = null;
|
ResultSet resultSet = null;
|
||||||
|
|
||||||
@ -145,6 +143,7 @@ public class QueryManager
|
|||||||
resultSet.close();
|
resultSet.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -155,6 +154,8 @@ public class QueryManager
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T> T executeStatementForSingleValue(Connection connection, Class<T> returnClass, String sql, Object... params) throws SQLException
|
public static <T> T executeStatementForSingleValue(Connection connection, Class<T> returnClass, String sql, Object... params) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
PreparedStatement statement = prepareStatementAndBindParams(connection, sql, params);
|
PreparedStatement statement = prepareStatementAndBindParams(connection, sql, params);
|
||||||
statement.execute();
|
statement.execute();
|
||||||
ResultSet resultSet = statement.getResultSet();
|
ResultSet resultSet = statement.getResultSet();
|
||||||
@ -203,6 +204,7 @@ public class QueryManager
|
|||||||
{
|
{
|
||||||
return (null);
|
return (null);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -212,6 +214,8 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static Map<String, Object> executeStatementForSingleRow(Connection connection, String sql, Object... params) throws SQLException
|
public static Map<String, Object> executeStatementForSingleRow(Connection connection, String sql, Object... params) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
PreparedStatement statement = prepareStatementAndBindParams(connection, sql, params);
|
PreparedStatement statement = prepareStatementAndBindParams(connection, sql, params);
|
||||||
statement.execute();
|
statement.execute();
|
||||||
ResultSet resultSet = statement.getResultSet();
|
ResultSet resultSet = statement.getResultSet();
|
||||||
@ -231,6 +235,7 @@ public class QueryManager
|
|||||||
{
|
{
|
||||||
return (null);
|
return (null);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -240,6 +245,8 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static SimpleEntity executeStatementForSimpleEntity(Connection connection, String sql, Object... params) throws SQLException
|
public static SimpleEntity executeStatementForSimpleEntity(Connection connection, String sql, Object... params) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
PreparedStatement statement = prepareStatementAndBindParams(connection, sql, params);
|
PreparedStatement statement = prepareStatementAndBindParams(connection, sql, params);
|
||||||
statement.execute();
|
statement.execute();
|
||||||
ResultSet resultSet = statement.getResultSet();
|
ResultSet resultSet = statement.getResultSet();
|
||||||
@ -251,6 +258,7 @@ public class QueryManager
|
|||||||
{
|
{
|
||||||
return (null);
|
return (null);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -260,6 +268,8 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static List<Map<String, Object>> executeStatementForRows(Connection connection, String sql, Object... params) throws SQLException
|
public static List<Map<String, Object>> executeStatementForRows(Connection connection, String sql, Object... params) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
List<Map<String, Object>> rs = new ArrayList<>();
|
List<Map<String, Object>> rs = new ArrayList<>();
|
||||||
|
|
||||||
PreparedStatement statement = prepareStatementAndBindParams(connection, sql, params);
|
PreparedStatement statement = prepareStatementAndBindParams(connection, sql, params);
|
||||||
@ -278,6 +288,7 @@ public class QueryManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (rs);
|
return (rs);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -287,6 +298,8 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static List<SimpleEntity> executeStatementForSimpleEntityList(Connection connection, String sql, Object... params) throws SQLException
|
public static List<SimpleEntity> executeStatementForSimpleEntityList(Connection connection, String sql, Object... params) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
List<SimpleEntity> rs = new ArrayList<>();
|
List<SimpleEntity> rs = new ArrayList<>();
|
||||||
|
|
||||||
PreparedStatement statement = prepareStatementAndBindParams(connection, sql, params);
|
PreparedStatement statement = prepareStatementAndBindParams(connection, sql, params);
|
||||||
@ -300,6 +313,7 @@ public class QueryManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (rs);
|
return (rs);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -309,6 +323,8 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static SimpleEntity buildSimpleEntity(ResultSet resultSet) throws SQLException
|
public static SimpleEntity buildSimpleEntity(ResultSet resultSet) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
SimpleEntity row = new SimpleEntity();
|
SimpleEntity row = new SimpleEntity();
|
||||||
|
|
||||||
ResultSetMetaData metaData = resultSet.getMetaData();
|
ResultSetMetaData metaData = resultSet.getMetaData();
|
||||||
@ -317,6 +333,7 @@ public class QueryManager
|
|||||||
row.put(metaData.getColumnName(i), getObject(resultSet, i));
|
row.put(metaData.getColumnName(i), getObject(resultSet, i));
|
||||||
}
|
}
|
||||||
return row;
|
return row;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -350,10 +367,13 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static void executeUpdateVoid(Connection connection, String sql, Object... params) throws SQLException
|
public static void executeUpdateVoid(Connection connection, String sql, Object... params) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
try(PreparedStatement statement = prepareStatementAndBindParams(connection, sql, params))
|
try(PreparedStatement statement = prepareStatementAndBindParams(connection, sql, params))
|
||||||
{
|
{
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -363,10 +383,13 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static void executeUpdateVoid(Connection connection, String sql, List<Object> params) throws SQLException
|
public static void executeUpdateVoid(Connection connection, String sql, List<Object> params) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
try(PreparedStatement statement = prepareStatementAndBindParams(connection, sql, params))
|
try(PreparedStatement statement = prepareStatementAndBindParams(connection, sql, params))
|
||||||
{
|
{
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -390,11 +413,14 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static Integer executeUpdateForRowCount(Connection connection, String sql, List<Object> params) throws SQLException
|
public static Integer executeUpdateForRowCount(Connection connection, String sql, List<Object> params) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
try(PreparedStatement statement = prepareStatementAndBindParams(connection, sql, params))
|
try(PreparedStatement statement = prepareStatementAndBindParams(connection, sql, params))
|
||||||
{
|
{
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
return (statement.getUpdateCount());
|
return (statement.getUpdateCount());
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -404,6 +430,8 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static Integer executeInsertForGeneratedId(Connection connection, String sql, Object... params) throws SQLException
|
public static Integer executeInsertForGeneratedId(Connection connection, String sql, Object... params) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
try(PreparedStatement statement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS))
|
try(PreparedStatement statement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS))
|
||||||
{
|
{
|
||||||
bindParams(params, statement);
|
bindParams(params, statement);
|
||||||
@ -418,12 +446,13 @@ public class QueryManager
|
|||||||
return (null);
|
return (null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** todo - needs unit test
|
** todo - needs (specific) unit test
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static List<Integer> executeInsertForGeneratedIds(Connection connection, String sql, List<Object> params) throws SQLException
|
public static List<Integer> executeInsertForGeneratedIds(Connection connection, String sql, List<Object> params) throws SQLException
|
||||||
{
|
{
|
||||||
@ -448,6 +477,8 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static void executeInsertForList(Connection connection, List<SimpleEntity> entityList) throws SQLException
|
public static void executeInsertForList(Connection connection, List<SimpleEntity> entityList) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
List<List<SimpleEntity>> pages = CollectionUtils.getPages(entityList, PAGE_SIZE);
|
List<List<SimpleEntity>> pages = CollectionUtils.getPages(entityList, PAGE_SIZE);
|
||||||
for(List<SimpleEntity> page : pages)
|
for(List<SimpleEntity> page : pages)
|
||||||
{
|
{
|
||||||
@ -474,6 +505,7 @@ public class QueryManager
|
|||||||
page.clear();
|
page.clear();
|
||||||
}
|
}
|
||||||
pages.clear();
|
pages.clear();
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -483,6 +515,8 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static Integer executeInsert(Connection connection, SimpleEntity entity) throws SQLException
|
public static Integer executeInsert(Connection connection, SimpleEntity entity) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
ArrayList<String> columns = new ArrayList<>(entity.keySet());
|
ArrayList<String> columns = new ArrayList<>(entity.keySet());
|
||||||
String sql = "INSERT INTO " + entity.getTableName() + "(" + StringUtils.join(",", columns) + ") VALUES (" + columns.stream().map(s -> "?").collect(Collectors.joining(",")) + ")";
|
String sql = "INSERT INTO " + entity.getTableName() + "(" + StringUtils.join(",", columns) + ") VALUES (" + columns.stream().map(s -> "?").collect(Collectors.joining(",")) + ")";
|
||||||
|
|
||||||
@ -493,6 +527,32 @@ public class QueryManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (executeInsertForGeneratedId(connection, sql, params));
|
return (executeInsertForGeneratedId(connection, sql, params));
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public static void executeBatchUpdate(Connection connection, String updateSQL, List<List<Serializable>> values) throws SQLException
|
||||||
|
{
|
||||||
|
for(List<List<Serializable>> page : CollectionUtils.getPages(values, PAGE_SIZE))
|
||||||
|
{
|
||||||
|
PreparedStatement updatePS = connection.prepareStatement(updateSQL);
|
||||||
|
for(List<Serializable> row : page)
|
||||||
|
{
|
||||||
|
Object[] params = new Object[row.size()];
|
||||||
|
for(int i = 0; i < row.size(); i++)
|
||||||
|
{
|
||||||
|
params[i] = row.get(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
bindParams(updatePS, params);
|
||||||
|
updatePS.addBatch();
|
||||||
|
}
|
||||||
|
updatePS.executeBatch();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -570,12 +630,13 @@ public class QueryManager
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static int bindParamObject(PreparedStatement statement, int index, Object value) throws SQLException
|
public static int bindParamObject(PreparedStatement statement, int index, Object value) throws SQLException
|
||||||
{
|
{
|
||||||
if(value instanceof TypeValuePair)
|
/* if(value instanceof TypeValuePair)
|
||||||
{
|
{
|
||||||
bindParamTypeValuePair(statement, index, (TypeValuePair<Object>) value);
|
bindParamTypeValuePair(statement, index, (TypeValuePair<Object>) value);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
else if(value instanceof Integer)
|
else*/
|
||||||
|
if(value instanceof Integer)
|
||||||
{
|
{
|
||||||
bindParam(statement, index, (Integer) value);
|
bindParam(statement, index, (Integer) value);
|
||||||
return (1);
|
return (1);
|
||||||
@ -675,16 +736,19 @@ public class QueryManager
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
/*
|
||||||
public static <T> TypeValuePair<T> param(Class<T> c, T v)
|
public static <T> TypeValuePair<T> param(Class<T> c, T v)
|
||||||
{
|
{
|
||||||
return (new TypeValuePair<>(c, v));
|
return (new TypeValuePair<>(c, v));
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
/*
|
||||||
private static void bindParamTypeValuePair(PreparedStatement statement, int index, TypeValuePair<Object> value) throws SQLException
|
private static void bindParamTypeValuePair(PreparedStatement statement, int index, TypeValuePair<Object> value) throws SQLException
|
||||||
{
|
{
|
||||||
Object v = value.getValue();
|
Object v = value.getValue();
|
||||||
@ -731,6 +795,7 @@ public class QueryManager
|
|||||||
throw (new SQLException("Unexpected value type [" + t.getSimpleName() + "] in bindParamTypeValuePair."));
|
throw (new SQLException("Unexpected value type [" + t.getSimpleName() + "] in bindParamTypeValuePair."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1044,12 +1109,15 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static BigDecimal getBigDecimal(ResultSet resultSet, String column) throws SQLException
|
public static BigDecimal getBigDecimal(ResultSet resultSet, String column) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
BigDecimal value = resultSet.getBigDecimal(column);
|
BigDecimal value = resultSet.getBigDecimal(column);
|
||||||
if(resultSet.wasNull())
|
if(resultSet.wasNull())
|
||||||
{
|
{
|
||||||
return (null);
|
return (null);
|
||||||
}
|
}
|
||||||
return (value);
|
return (value);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1074,12 +1142,15 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static Date getDate(ResultSet resultSet, String column) throws SQLException
|
public static Date getDate(ResultSet resultSet, String column) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
Date value = resultSet.getDate(column);
|
Date value = resultSet.getDate(column);
|
||||||
if(resultSet.wasNull())
|
if(resultSet.wasNull())
|
||||||
{
|
{
|
||||||
return (null);
|
return (null);
|
||||||
}
|
}
|
||||||
return (value);
|
return (value);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1104,6 +1175,8 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static Calendar getCalendar(ResultSet resultSet, String column) throws SQLException
|
public static Calendar getCalendar(ResultSet resultSet, String column) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
Timestamp value = resultSet.getTimestamp(column);
|
Timestamp value = resultSet.getTimestamp(column);
|
||||||
if(resultSet.wasNull())
|
if(resultSet.wasNull())
|
||||||
{
|
{
|
||||||
@ -1112,6 +1185,7 @@ public class QueryManager
|
|||||||
Calendar rs = Calendar.getInstance();
|
Calendar rs = Calendar.getInstance();
|
||||||
rs.setTimeInMillis(value.getTime());
|
rs.setTimeInMillis(value.getTime());
|
||||||
return (rs);
|
return (rs);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1121,6 +1195,8 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static Calendar getCalendar(ResultSet resultSet, int column) throws SQLException
|
public static Calendar getCalendar(ResultSet resultSet, int column) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
Timestamp value = resultSet.getTimestamp(column);
|
Timestamp value = resultSet.getTimestamp(column);
|
||||||
if(resultSet.wasNull())
|
if(resultSet.wasNull())
|
||||||
{
|
{
|
||||||
@ -1129,6 +1205,7 @@ public class QueryManager
|
|||||||
Calendar rs = Calendar.getInstance();
|
Calendar rs = Calendar.getInstance();
|
||||||
rs.setTimeInMillis(value.getTime());
|
rs.setTimeInMillis(value.getTime());
|
||||||
return (rs);
|
return (rs);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1139,6 +1216,8 @@ public class QueryManager
|
|||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public static LocalDate getLocalDate(ResultSet resultSet, String column) throws SQLException
|
public static LocalDate getLocalDate(ResultSet resultSet, String column) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
Timestamp value = resultSet.getTimestamp(column);
|
Timestamp value = resultSet.getTimestamp(column);
|
||||||
if(resultSet.wasNull())
|
if(resultSet.wasNull())
|
||||||
{
|
{
|
||||||
@ -1147,6 +1226,7 @@ public class QueryManager
|
|||||||
|
|
||||||
LocalDate date = LocalDate.of(value.getYear() + NINETEEN_HUNDRED, value.getMonth() + 1, value.getDate());
|
LocalDate date = LocalDate.of(value.getYear() + NINETEEN_HUNDRED, value.getMonth() + 1, value.getDate());
|
||||||
return (date);
|
return (date);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1157,6 +1237,8 @@ public class QueryManager
|
|||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public static LocalDateTime getLocalDateTime(ResultSet resultSet, String column) throws SQLException
|
public static LocalDateTime getLocalDateTime(ResultSet resultSet, String column) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
Timestamp value = resultSet.getTimestamp(column);
|
Timestamp value = resultSet.getTimestamp(column);
|
||||||
if(resultSet.wasNull())
|
if(resultSet.wasNull())
|
||||||
{
|
{
|
||||||
@ -1165,6 +1247,7 @@ public class QueryManager
|
|||||||
|
|
||||||
LocalDateTime dateTime = LocalDateTime.of(value.getYear() + NINETEEN_HUNDRED, value.getMonth() + 1, value.getDate(), value.getHours(), value.getMinutes(), value.getSeconds(), 0);
|
LocalDateTime dateTime = LocalDateTime.of(value.getYear() + NINETEEN_HUNDRED, value.getMonth() + 1, value.getDate(), value.getHours(), value.getMinutes(), value.getSeconds(), 0);
|
||||||
return (dateTime);
|
return (dateTime);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1193,6 +1276,8 @@ public class QueryManager
|
|||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public static OffsetDateTime getOffsetDateTime(ResultSet resultSet, String column) throws SQLException
|
public static OffsetDateTime getOffsetDateTime(ResultSet resultSet, String column) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
Timestamp value = resultSet.getTimestamp(column);
|
Timestamp value = resultSet.getTimestamp(column);
|
||||||
if(resultSet.wasNull())
|
if(resultSet.wasNull())
|
||||||
{
|
{
|
||||||
@ -1201,6 +1286,7 @@ public class QueryManager
|
|||||||
|
|
||||||
OffsetDateTime dateTime = OffsetDateTime.of(value.getYear() + NINETEEN_HUNDRED, value.getMonth() + 1, value.getDate(), value.getHours(), value.getMinutes(), value.getSeconds(), 0, OffsetDateTime.now().getOffset());
|
OffsetDateTime dateTime = OffsetDateTime.of(value.getYear() + NINETEEN_HUNDRED, value.getMonth() + 1, value.getDate(), value.getHours(), value.getMinutes(), value.getSeconds(), 0, OffsetDateTime.now().getOffset());
|
||||||
return (dateTime);
|
return (dateTime);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1210,12 +1296,15 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static Boolean getBoolean(ResultSet resultSet, String column) throws SQLException
|
public static Boolean getBoolean(ResultSet resultSet, String column) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
Boolean value = resultSet.getBoolean(column);
|
Boolean value = resultSet.getBoolean(column);
|
||||||
if(resultSet.wasNull())
|
if(resultSet.wasNull())
|
||||||
{
|
{
|
||||||
return (null);
|
return (null);
|
||||||
}
|
}
|
||||||
return (value);
|
return (value);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1225,12 +1314,15 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static Boolean getBoolean(ResultSet resultSet, int column) throws SQLException
|
public static Boolean getBoolean(ResultSet resultSet, int column) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
Boolean value = resultSet.getBoolean(column);
|
Boolean value = resultSet.getBoolean(column);
|
||||||
if(resultSet.wasNull())
|
if(resultSet.wasNull())
|
||||||
{
|
{
|
||||||
return (null);
|
return (null);
|
||||||
}
|
}
|
||||||
return (value);
|
return (value);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1240,12 +1332,15 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static Long getLong(ResultSet resultSet, int column) throws SQLException
|
public static Long getLong(ResultSet resultSet, int column) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
long value = resultSet.getLong(column);
|
long value = resultSet.getLong(column);
|
||||||
if(resultSet.wasNull())
|
if(resultSet.wasNull())
|
||||||
{
|
{
|
||||||
return (null);
|
return (null);
|
||||||
}
|
}
|
||||||
return (value);
|
return (value);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1255,12 +1350,15 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static Long getLong(ResultSet resultSet, String column) throws SQLException
|
public static Long getLong(ResultSet resultSet, String column) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
long value = resultSet.getLong(column);
|
long value = resultSet.getLong(column);
|
||||||
if(resultSet.wasNull())
|
if(resultSet.wasNull())
|
||||||
{
|
{
|
||||||
return (null);
|
return (null);
|
||||||
}
|
}
|
||||||
return (value);
|
return (value);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1270,12 +1368,15 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static Timestamp getTimestamp(ResultSet resultSet, int column) throws SQLException
|
public static Timestamp getTimestamp(ResultSet resultSet, int column) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
Timestamp value = resultSet.getTimestamp(column);
|
Timestamp value = resultSet.getTimestamp(column);
|
||||||
if(resultSet.wasNull())
|
if(resultSet.wasNull())
|
||||||
{
|
{
|
||||||
return (null);
|
return (null);
|
||||||
}
|
}
|
||||||
return (value);
|
return (value);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1285,12 +1386,15 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static Timestamp getTimestamp(ResultSet resultSet, String column) throws SQLException
|
public static Timestamp getTimestamp(ResultSet resultSet, String column) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
Timestamp value = resultSet.getTimestamp(column);
|
Timestamp value = resultSet.getTimestamp(column);
|
||||||
if(resultSet.wasNull())
|
if(resultSet.wasNull())
|
||||||
{
|
{
|
||||||
return (null);
|
return (null);
|
||||||
}
|
}
|
||||||
return (value);
|
return (value);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1304,7 +1408,10 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static Integer findIdForDaysAgo(Connection connection, String tableName, String dateFieldName, int goalDaysAgo) throws SQLException
|
public static Integer findIdForDaysAgo(Connection connection, String tableName, String dateFieldName, int goalDaysAgo) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
return (findIdForTimeUnitAgo(connection, tableName, dateFieldName, goalDaysAgo, ChronoUnit.DAYS));
|
return (findIdForTimeUnitAgo(connection, tableName, dateFieldName, goalDaysAgo, ChronoUnit.DAYS));
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1314,8 +1421,11 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static Integer findIdForTimestamp(Connection connection, String tableName, String dateFieldName, LocalDateTime timestamp) throws SQLException
|
public static Integer findIdForTimestamp(Connection connection, String tableName, String dateFieldName, LocalDateTime timestamp) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
long between = ChronoUnit.SECONDS.between(timestamp, LocalDateTime.now());
|
long between = ChronoUnit.SECONDS.between(timestamp, LocalDateTime.now());
|
||||||
return (findIdForTimeUnitAgo(connection, tableName, dateFieldName, (int) between, ChronoUnit.SECONDS));
|
return (findIdForTimeUnitAgo(connection, tableName, dateFieldName, (int) between, ChronoUnit.SECONDS));
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1325,6 +1435,8 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static Integer findIdForTimeUnitAgo(Connection connection, String tableName, String dateFieldName, int goalUnitsAgo, ChronoUnit unit) throws SQLException
|
public static Integer findIdForTimeUnitAgo(Connection connection, String tableName, String dateFieldName, int goalUnitsAgo, ChronoUnit unit) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
Integer maxId = executeStatementForSingleValue(connection, Integer.class, "SELECT MAX(id) FROM " + tableName);
|
Integer maxId = executeStatementForSingleValue(connection, Integer.class, "SELECT MAX(id) FROM " + tableName);
|
||||||
Integer minId = executeStatementForSingleValue(connection, Integer.class, "SELECT MIN(id) FROM " + tableName);
|
Integer minId = executeStatementForSingleValue(connection, Integer.class, "SELECT MIN(id) FROM " + tableName);
|
||||||
|
|
||||||
@ -1340,6 +1452,7 @@ public class QueryManager
|
|||||||
// Logger.logDebug("For [" + tableName + "], using min id [" + idForGoal + "], which is from [" + foundUnitsAgo + "] Units[" + unit + "] ago.");
|
// Logger.logDebug("For [" + tableName + "], using min id [" + idForGoal + "], which is from [" + foundUnitsAgo + "] Units[" + unit + "] ago.");
|
||||||
|
|
||||||
return (idForGoal);
|
return (idForGoal);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1349,6 +1462,8 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
private static Integer findIdForTimeUnitAgo(Connection connection, String tableName, String dateFieldName, int goalUnitsAgo, Integer minId, Integer maxId, ChronoUnit unit) throws SQLException
|
private static Integer findIdForTimeUnitAgo(Connection connection, String tableName, String dateFieldName, int goalUnitsAgo, Integer minId, Integer maxId, ChronoUnit unit) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
Integer midId = minId + ((maxId - minId) / 2);
|
Integer midId = minId + ((maxId - minId) / 2);
|
||||||
if(midId.equals(minId) || midId.equals(maxId))
|
if(midId.equals(minId) || midId.equals(maxId))
|
||||||
{
|
{
|
||||||
@ -1368,6 +1483,7 @@ public class QueryManager
|
|||||||
{
|
{
|
||||||
return (findIdForTimeUnitAgo(connection, tableName, dateFieldName, goalUnitsAgo, minId, midId, unit));
|
return (findIdForTimeUnitAgo(connection, tableName, dateFieldName, goalUnitsAgo, minId, midId, unit));
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1377,6 +1493,8 @@ public class QueryManager
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
private static long getTimeUnitAgo(Connection connection, String tableName, String dateFieldName, Integer id, ChronoUnit unit) throws SQLException
|
private static long getTimeUnitAgo(Connection connection, String tableName, String dateFieldName, Integer id, ChronoUnit unit) throws SQLException
|
||||||
{
|
{
|
||||||
|
throw (new NotImplementedException());
|
||||||
|
/*
|
||||||
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -1395,61 +1513,52 @@ public class QueryManager
|
|||||||
// System.out.println("Unit[" + unit + "]'s ago: " + diff);
|
// System.out.println("Unit[" + unit + "]'s ago: " + diff);
|
||||||
return diff;
|
return diff;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static class TypeValuePair<T>
|
// public static class TypeValuePair<T>
|
||||||
{
|
// {
|
||||||
private Class<T> type;
|
// private Class<T> type;
|
||||||
private T value;
|
// private T value;
|
||||||
|
|
||||||
|
// /*******************************************************************************
|
||||||
|
// **
|
||||||
|
// *******************************************************************************/
|
||||||
|
// @SuppressWarnings("unchecked")
|
||||||
|
// public TypeValuePair(T value)
|
||||||
|
// {
|
||||||
|
// this.value = value;
|
||||||
|
// this.type = (Class<T>) value.getClass();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /*******************************************************************************
|
||||||
|
// **
|
||||||
|
// *******************************************************************************/
|
||||||
|
// public TypeValuePair(Class<T> type, T value)
|
||||||
|
// {
|
||||||
|
// this.type = type;
|
||||||
|
// this.value = value;
|
||||||
|
// }
|
||||||
|
|
||||||
/*******************************************************************************
|
// /*******************************************************************************
|
||||||
**
|
// **
|
||||||
*******************************************************************************/
|
// *******************************************************************************/
|
||||||
@SuppressWarnings("unchecked")
|
// public T getValue()
|
||||||
public TypeValuePair(T value)
|
// {
|
||||||
{
|
// return (value);
|
||||||
this.value = value;
|
// }
|
||||||
this.type = (Class<T>) value.getClass();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// /*******************************************************************************
|
||||||
|
// **
|
||||||
|
// *******************************************************************************/
|
||||||
|
// public Class<T> getType()
|
||||||
|
// {
|
||||||
|
// return (type);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
/*******************************************************************************
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public TypeValuePair(Class<T> type, T value)
|
|
||||||
{
|
|
||||||
this.type = type;
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public T getValue()
|
|
||||||
{
|
|
||||||
return (value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
**
|
|
||||||
*******************************************************************************/
|
|
||||||
public Class<T> getType()
|
|
||||||
{
|
|
||||||
return (type);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,8 @@ public class RDBMSActionTest
|
|||||||
protected void primeTestDatabase() throws Exception
|
protected void primeTestDatabase() throws Exception
|
||||||
{
|
{
|
||||||
ConnectionManager connectionManager = new ConnectionManager();
|
ConnectionManager connectionManager = new ConnectionManager();
|
||||||
Connection connection = connectionManager.getConnection(TestUtils.defineBackend());
|
try(Connection connection = connectionManager.getConnection(TestUtils.defineBackend()))
|
||||||
|
{
|
||||||
InputStream primeTestDatabaseSqlStream = RDBMSActionTest.class.getResourceAsStream("/prime-test-database.sql");
|
InputStream primeTestDatabaseSqlStream = RDBMSActionTest.class.getResourceAsStream("/prime-test-database.sql");
|
||||||
assertNotNull(primeTestDatabaseSqlStream);
|
assertNotNull(primeTestDatabaseSqlStream);
|
||||||
List<String> lines = (List<String>) IOUtils.readLines(primeTestDatabaseSqlStream);
|
List<String> lines = (List<String>) IOUtils.readLines(primeTestDatabaseSqlStream);
|
||||||
@ -57,6 +58,7 @@ public class RDBMSActionTest
|
|||||||
QueryManager.executeUpdate(connection, sql);
|
QueryManager.executeUpdate(connection, sql);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,7 +22,10 @@
|
|||||||
package com.kingsrook.qqq.backend.module.rdbms.actions;
|
package com.kingsrook.qqq.backend.module.rdbms.actions;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.update.UpdateRequest;
|
import com.kingsrook.qqq.backend.core.model.actions.update.UpdateRequest;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.update.UpdateResult;
|
import com.kingsrook.qqq.backend.core.model.actions.update.UpdateResult;
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||||
@ -31,6 +34,7 @@ import org.junit.jupiter.api.BeforeEach;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
|
||||||
|
|
||||||
@ -51,6 +55,38 @@ public class RDBMSUpdateActionTest extends RDBMSActionTest
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
public void testUpdateNullList()
|
||||||
|
{
|
||||||
|
UpdateRequest updateRequest = initUpdateRequest();
|
||||||
|
updateRequest.setRecords(null);
|
||||||
|
assertThrows(QException.class, () ->
|
||||||
|
{
|
||||||
|
new RDBMSUpdateAction().execute(updateRequest);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
public void testUpdateEmptyList()
|
||||||
|
{
|
||||||
|
UpdateRequest updateRequest = initUpdateRequest();
|
||||||
|
updateRequest.setRecords(Collections.emptyList());
|
||||||
|
assertThrows(QException.class, () ->
|
||||||
|
{
|
||||||
|
new RDBMSUpdateAction().execute(updateRequest);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -94,7 +130,7 @@ public class RDBMSUpdateActionTest extends RDBMSActionTest
|
|||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateMany() throws Exception
|
public void testUpdateManyWithDifferentColumnsAndValues() throws Exception
|
||||||
{
|
{
|
||||||
UpdateRequest updateRequest = initUpdateRequest();
|
UpdateRequest updateRequest = initUpdateRequest();
|
||||||
QRecord record1 = new QRecord().withTableName("person")
|
QRecord record1 = new QRecord().withTableName("person")
|
||||||
@ -108,11 +144,17 @@ public class RDBMSUpdateActionTest extends RDBMSActionTest
|
|||||||
.withValue("firstName", "Wilt")
|
.withValue("firstName", "Wilt")
|
||||||
.withValue("birthDate", null);
|
.withValue("birthDate", null);
|
||||||
|
|
||||||
updateRequest.setRecords(List.of(record1, record2));
|
QRecord record3 = new QRecord().withTableName("person")
|
||||||
|
.withValue("id", 5)
|
||||||
|
.withValue("firstName", "Richard")
|
||||||
|
.withValue("birthDate", null);
|
||||||
|
|
||||||
|
updateRequest.setRecords(List.of(record1, record2, record3));
|
||||||
UpdateResult updateResult = new RDBMSUpdateAction().execute(updateRequest);
|
UpdateResult updateResult = new RDBMSUpdateAction().execute(updateRequest);
|
||||||
assertEquals(2, updateResult.getRecords().size(), "Should return 2 rows");
|
assertEquals(3, updateResult.getRecords().size(), "Should return 3 rows");
|
||||||
assertEquals(1, updateResult.getRecords().get(0).getValue("id"), "Should have expected ids in the row");
|
assertEquals(1, updateResult.getRecords().get(0).getValue("id"), "Should have expected ids in the row");
|
||||||
assertEquals(3, updateResult.getRecords().get(1).getValue("id"), "Should have expected ids in the row");
|
assertEquals(3, updateResult.getRecords().get(1).getValue("id"), "Should have expected ids in the row");
|
||||||
|
assertEquals(5, updateResult.getRecords().get(2).getValue("id"), "Should have expected ids in the row");
|
||||||
// todo - add errors to QRecord? assertTrue(updateResult.getRecords().stream().noneMatch(qrs -> CollectionUtils.nullSafeHasContents(qrs.getErrors())), "There should be no errors");
|
// todo - add errors to QRecord? assertTrue(updateResult.getRecords().stream().noneMatch(qrs -> CollectionUtils.nullSafeHasContents(qrs.getErrors())), "There should be no errors");
|
||||||
runTestSql("SELECT * FROM person WHERE last_name = 'From Bewitched'", (rs -> {
|
runTestSql("SELECT * FROM person WHERE last_name = 'From Bewitched'", (rs -> {
|
||||||
int rowsFound = 0;
|
int rowsFound = 0;
|
||||||
@ -137,6 +179,100 @@ public class RDBMSUpdateActionTest extends RDBMSActionTest
|
|||||||
}
|
}
|
||||||
assertEquals(1, rowsFound);
|
assertEquals(1, rowsFound);
|
||||||
}));
|
}));
|
||||||
|
runTestSql("SELECT * FROM person WHERE last_name = 'Richardson'", (rs -> {
|
||||||
|
int rowsFound = 0;
|
||||||
|
while(rs.next())
|
||||||
|
{
|
||||||
|
rowsFound++;
|
||||||
|
assertEquals(5, rs.getInt("id"));
|
||||||
|
assertEquals("Richard", rs.getString("first_name"));
|
||||||
|
assertNull(rs.getString("birth_date"));
|
||||||
|
}
|
||||||
|
assertEquals(1, rowsFound);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
public void testUpdateManyWithSameColumnsDifferentValues() throws Exception
|
||||||
|
{
|
||||||
|
UpdateRequest updateRequest = initUpdateRequest();
|
||||||
|
QRecord record1 = new QRecord().withTableName("person")
|
||||||
|
.withValue("id", 1)
|
||||||
|
.withValue("firstName", "Darren")
|
||||||
|
.withValue("lastName", "From Bewitched")
|
||||||
|
.withValue("birthDate", "1900-01-01");
|
||||||
|
|
||||||
|
QRecord record2 = new QRecord().withTableName("person")
|
||||||
|
.withValue("id", 3)
|
||||||
|
.withValue("firstName", "Wilt")
|
||||||
|
.withValue("lastName", "Tim's Uncle")
|
||||||
|
.withValue("birthDate", null);
|
||||||
|
|
||||||
|
updateRequest.setRecords(List.of(record1, record2));
|
||||||
|
UpdateResult updateResult = new RDBMSUpdateAction().execute(updateRequest);
|
||||||
|
assertEquals(2, updateResult.getRecords().size(), "Should return 2 rows");
|
||||||
|
assertEquals(1, updateResult.getRecords().get(0).getValue("id"), "Should have expected ids in the row");
|
||||||
|
assertEquals(3, updateResult.getRecords().get(1).getValue("id"), "Should have expected ids in the row");
|
||||||
|
// todo - add errors to QRecord? assertTrue(updateResult.getRecords().stream().noneMatch(qrs -> CollectionUtils.nullSafeHasContents(qrs.getErrors())), "There should be no errors");
|
||||||
|
runTestSql("SELECT * FROM person WHERE last_name = 'From Bewitched'", (rs -> {
|
||||||
|
int rowsFound = 0;
|
||||||
|
while(rs.next())
|
||||||
|
{
|
||||||
|
rowsFound++;
|
||||||
|
assertEquals(1, rs.getInt("id"));
|
||||||
|
assertEquals("Darren", rs.getString("first_name"));
|
||||||
|
assertEquals("From Bewitched", rs.getString("last_name"));
|
||||||
|
assertEquals("1900-01-01", rs.getString("birth_date"));
|
||||||
|
}
|
||||||
|
assertEquals(1, rowsFound);
|
||||||
|
}));
|
||||||
|
runTestSql("SELECT * FROM person WHERE last_name = 'Tim''s Uncle'", (rs -> {
|
||||||
|
int rowsFound = 0;
|
||||||
|
while(rs.next())
|
||||||
|
{
|
||||||
|
rowsFound++;
|
||||||
|
assertEquals(3, rs.getInt("id"));
|
||||||
|
assertEquals("Wilt", rs.getString("first_name"));
|
||||||
|
assertEquals("Tim's Uncle", rs.getString("last_name"));
|
||||||
|
assertNull(rs.getString("birth_date"));
|
||||||
|
}
|
||||||
|
assertEquals(1, rowsFound);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
public void testUpdateManyWithSameColumnsSameValues() throws Exception
|
||||||
|
{
|
||||||
|
UpdateRequest updateRequest = initUpdateRequest();
|
||||||
|
List<QRecord> records = new ArrayList<>();
|
||||||
|
for(int i = 1; i <= 5; i++)
|
||||||
|
{
|
||||||
|
records.add(new QRecord().withTableName("person").withValue("id", i).withValue("birthDate", "1999-09-09"));
|
||||||
|
}
|
||||||
|
|
||||||
|
updateRequest.setRecords(records);
|
||||||
|
UpdateResult updateResult = new RDBMSUpdateAction().execute(updateRequest);
|
||||||
|
assertEquals(5, updateResult.getRecords().size(), "Should return 5 rows");
|
||||||
|
// todo - add errors to QRecord? assertTrue(updateResult.getRecords().stream().noneMatch(qrs -> CollectionUtils.nullSafeHasContents(qrs.getErrors())), "There should be no errors");
|
||||||
|
runTestSql("SELECT * FROM person WHERE id <= 5", (rs -> {
|
||||||
|
int rowsFound = 0;
|
||||||
|
while(rs.next())
|
||||||
|
{
|
||||||
|
rowsFound++;
|
||||||
|
assertEquals("1999-09-09", rs.getString("birth_date"));
|
||||||
|
}
|
||||||
|
assertEquals(5, rowsFound);
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2022. Kingsrook, LLC
|
||||||
|
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||||
|
* contact@kingsrook.com
|
||||||
|
* https://github.com/Kingsrook/
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.module.rdbms.jdbc;
|
||||||
|
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
class QueryManagerTest
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user