Changes pushed to qqq-backend-module-rdbms (solo-repo) in 0.2 support

This commit is contained in:
2022-08-04 11:35:17 -05:00
parent a2e267fe40
commit 54103f47ad
3 changed files with 209 additions and 1 deletions

View File

@ -28,6 +28,7 @@ import java.time.Instant;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.kingsrook.qqq.backend.core.actions.QBackendTransaction;
import com.kingsrook.qqq.backend.core.actions.interfaces.InsertInterface; import com.kingsrook.qqq.backend.core.actions.interfaces.InsertInterface;
import com.kingsrook.qqq.backend.core.exceptions.QException; import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput; import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput;
@ -92,7 +93,20 @@ public class RDBMSInsertAction extends AbstractRDBMSAction implements InsertInte
List<QRecord> outputRecords = new ArrayList<>(); List<QRecord> outputRecords = new ArrayList<>();
rs.setRecords(outputRecords); rs.setRecords(outputRecords);
try(Connection connection = getConnection(insertInput)) Connection connection;
boolean needToCloseConnection = false;
if(insertInput.getTransaction() != null && insertInput.getTransaction() instanceof RDBMSTransaction rdbmsTransaction)
{
LOG.debug("Using connection from insertInput [" + rdbmsTransaction.getConnection() + "]");
connection = rdbmsTransaction.getConnection();
}
else
{
connection = getConnection(insertInput);
needToCloseConnection = true;
}
try
{ {
for(List<QRecord> page : CollectionUtils.getPages(insertInput.getRecords(), QueryManager.PAGE_SIZE)) for(List<QRecord> page : CollectionUtils.getPages(insertInput.getRecords(), QueryManager.PAGE_SIZE))
{ {
@ -130,6 +144,13 @@ public class RDBMSInsertAction extends AbstractRDBMSAction implements InsertInte
} }
} }
} }
finally
{
if(needToCloseConnection)
{
connection.close();
}
}
return rs; return rs;
} }
@ -139,4 +160,28 @@ public class RDBMSInsertAction extends AbstractRDBMSAction implements InsertInte
} }
} }
/*******************************************************************************
**
*******************************************************************************/
@Override
public QBackendTransaction openTransaction(InsertInput insertInput) throws QException
{
try
{
LOG.info("Opening transaction");
Connection connection = getConnection(insertInput);
connection.setAutoCommit(false);
System.out.println("Set connection [" + connection + "] to auto-commit false");
return (new RDBMSTransaction(connection));
}
catch(Exception e)
{
throw new QException("Error opening transaction: " + e.getMessage(), e);
}
}
} }

View File

@ -0,0 +1,141 @@
/*
* 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.actions;
import java.io.IOException;
import java.sql.Connection;
import com.kingsrook.qqq.backend.core.actions.QBackendTransaction;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/*******************************************************************************
** RDBMS implementation of backend transaction.
**
** Stores a jdbc connection, which is set to autoCommit(false).
*******************************************************************************/
public class RDBMSTransaction extends QBackendTransaction
{
private static final Logger LOG = LogManager.getLogger(RDBMSTransaction.class);
private Connection connection;
/*******************************************************************************
**
*******************************************************************************/
public RDBMSTransaction(Connection connection)
{
this.connection = connection;
}
/*******************************************************************************
** Getter for connection
**
*******************************************************************************/
public Connection getConnection()
{
return connection;
}
/*******************************************************************************
**
*******************************************************************************/
@Override
public void commit() throws QException
{
try
{
RDBMSTransaction.LOG.info("Committing transaction");
System.out.println("Calling commit on connection [" + connection + "]");
connection.commit();
RDBMSTransaction.LOG.info("Commit complete");
}
catch(Exception e)
{
RDBMSTransaction.LOG.error("Error committing transaction", e);
throw new QException("Error committing transaction: " + e.getMessage(), e);
}
}
/*******************************************************************************
**
*******************************************************************************/
@Override
public void rollback() throws QException
{
try
{
RDBMSTransaction.LOG.info("Rolling back transaction");
connection.rollback();
RDBMSTransaction.LOG.info("Rollback complete");
}
catch(Exception e)
{
RDBMSTransaction.LOG.error("Error rolling back transaction", e);
throw new QException("Error rolling back transaction: " + e.getMessage(), e);
}
}
/*******************************************************************************
* Closes this stream and releases any system resources associated
* with it. If the stream is already closed then invoking this
* method has no effect.
*
* <p> As noted in {@link AutoCloseable#close()}, cases where the
* close may fail require careful attention. It is strongly advised
* to relinquish the underlying resources and to internally
* <em>mark</em> the {@code Closeable} as closed, prior to throwing
* the {@code IOException}.
*
* @throws IOException
* if an I/O error occurs
*******************************************************************************/
@Override
public void close()
{
try
{
if(connection.isClosed())
{
return;
}
connection.close();
}
catch(Exception e)
{
LOG.error("Error closing connection - possible jdbc connection leak", e);
}
}
}

View File

@ -685,6 +685,11 @@ public class QueryManager
bindParam(statement, index, l.intValue()); bindParam(statement, index, l.intValue());
return (1); return (1);
} }
else if(value instanceof Double d)
{
bindParam(statement, index, d.doubleValue());
return (1);
}
else if(value instanceof String s) else if(value instanceof String s)
{ {
bindParam(statement, index, s); bindParam(statement, index, s);
@ -851,6 +856,23 @@ public class QueryManager
/*******************************************************************************
*
*******************************************************************************/
public static void bindParam(PreparedStatement statement, int index, Double value) throws SQLException
{
if(value == null)
{
statement.setNull(index, Types.DOUBLE);
}
else
{
statement.setDouble(index, value);
}
}
/******************************************************************************* /*******************************************************************************
* *
*******************************************************************************/ *******************************************************************************/