From a143ca61ecf8dbf96387b4d43330c61927592998 Mon Sep 17 00:00:00 2001 From: gwen-soleil <gwenaelle.abeille@gmail.com> Date: Wed, 4 Jan 2023 09:11:46 +0100 Subject: [PATCH] Avoid Oracle DB error ORA-01795: maximum number of expressions in a list is 1000 (Jira SOLEIL TANGOARCH-744) --- .../archiving/snap/api/DataBaseAPI.java | 188 ++++++++++-------- 1 file changed, 101 insertions(+), 87 deletions(-) diff --git a/src/main/java/fr/soleil/archiving/snap/api/DataBaseAPI.java b/src/main/java/fr/soleil/archiving/snap/api/DataBaseAPI.java index badafc8..0ca8314 100644 --- a/src/main/java/fr/soleil/archiving/snap/api/DataBaseAPI.java +++ b/src/main/java/fr/soleil/archiving/snap/api/DataBaseAPI.java @@ -172,6 +172,7 @@ //-====================================================================== package fr.soleil.archiving.snap.api; +import com.google.common.collect.Lists; import fr.esrf.Tango.AttrDataFormat; import fr.esrf.Tango.AttrWriteType; import fr.esrf.Tango.ErrSeverity; @@ -227,6 +228,7 @@ import java.util.stream.Collectors; public class DataBaseAPI { private static final String ERROR_EXTRACTING_SNAPSHOT_DATA = "error extracting snapshot data"; + public static final int MAX_SELECT_SIZE = 1000; public static boolean useLog4JDBC = System.getProperty("log4jdbc.active") == null ? false : System.getProperty( "log4jdbc.active").equalsIgnoreCase("true"); private final Logger logger = LoggerFactory.getLogger(DataBaseAPI.class); @@ -278,15 +280,6 @@ public class DataBaseAPI { return params.getName(); } - /** - * <b>Description : </b> Gets the database's schema name - * - * @return The database name - */ - public String getDbSchema() { - return params.getSchema(); - } - /** * <b>Description : </b> Returns the connected database host identifier. * @@ -346,7 +339,6 @@ public class DataBaseAPI { return arrayCount; } - /** * ************************************************************************ * <b>Description : </b> Closes the connection with the database @@ -358,6 +350,22 @@ public class DataBaseAPI { closeConnection(conn); } + private void closeConnection(final Connection conn) { + if (conn == null) { + return; + } + + try { + conn.close(); + } catch (final SQLException e) { + e.printStackTrace(); + + logger.error("ERROR !! " + "\r\n" + "\t Origin : \t " + "DataBaseAPI.closeConnection" + "\r\n" + + "\t Reason : \t " + getDbSchema().toUpperCase().trim() + "_FAILURE" + "\r\n" + + "\t Description : \t " + e.getMessage()); + } + } + /***************************************************************************** * @@ -366,6 +374,33 @@ public class DataBaseAPI { * ****************************************************************************/ + /** + * <b>Description : </b> Gets the database's schema name + * + * @return The database name + */ + public String getDbSchema() { + return params.getSchema(); + } + + /** + * <b>Description : </b> Checks if the attribute of the given name, is + * already registered in <I>SnapDb</I> (and more particularly in the table + * of the definitions). + * + * @param att_name The name of the attribute to check. + * @return boolean + * @throws SnapshotingException + */ + public boolean isRegistered(final String att_name) throws SnapshotingException { + final int id = getAttID(att_name.trim()); + if (id != 0) { + return true; + } else { + return false; + } + } + /** * ************************************************************************ * <b>Description : </b> Gets for a specified attribute its ID as defined in @@ -420,21 +455,35 @@ public class DataBaseAPI { return attributesID; } - /** - * <b>Description : </b> Checks if the attribute of the given name, is - * already registered in <I>SnapDb</I> (and more particularly in the table - * of the definitions). - * - * @param att_name The name of the attribute to check. - * @return boolean - * @throws SnapshotingException - */ - public boolean isRegistered(final String att_name) throws SnapshotingException { - final int id = getAttID(att_name.trim()); - if (id != 0) { - return true; - } else { - return false; + public void closeResultSet(final ResultSet resultSet) { + if (resultSet == null) { + return; + } + + try { + resultSet.close(); + } catch (final SQLException e) { + e.printStackTrace(); + + logger.error("ERROR !! " + "\r\n" + "\t Origin : \t " + "DataBaseAPI.closeResultSet" + "\r\n" + + "\t Reason : \t " + getDbSchema().toUpperCase().trim() + "_FAILURE" + "\r\n" + + "\t Description : \t " + e.getMessage()); + } + } + + public void closeStatement(final Statement preparedStatement) { + if (preparedStatement == null) { + return; + } + + try { + preparedStatement.close(); + } catch (final SQLException e) { + e.printStackTrace(); + + logger.error("ERROR !! " + "\r\n" + "\t Origin : \t " + "DataBaseAPI.closeStatement" + "\r\n" + + "\t Reason : \t " + getDbSchema().toUpperCase().trim() + "_FAILURE" + "\r\n" + + "\t Description : \t " + e.getMessage()); } } @@ -483,7 +532,6 @@ public class DataBaseAPI { return res; } - /** * This method retrives from the the database, the list of all registered * contexts (or 'snap-patterns) which subscribe to the clause and/or have @@ -554,7 +602,6 @@ public class DataBaseAPI { } - /** * Retrieves the context identifier to wich the given snapshot identifier is * associated. @@ -632,7 +679,6 @@ public class DataBaseAPI { } } - private void selectRO(final List<SnapAttributeExtract> attributes, int snapID, final String tableName) throws SnapshotingException, SQLException { @@ -685,7 +731,7 @@ public class DataBaseAPI { // t_sp_2val WHERE id_snap = ? List<String> scpectrumRWAttId = attributes.stream().filter(s -> s.getDataFormat() == AttrDataFormat._SPECTRUM - && (s.getWritable() == AttrWriteType._READ_WITH_WRITE || s.getWritable() == AttrWriteType._READ_WRITE)) + && (s.getWritable() == AttrWriteType._READ_WITH_WRITE || s.getWritable() == AttrWriteType._READ_WRITE)) .map(s -> String.valueOf(s.getAttId())).collect(Collectors.toList()); if (scpectrumRWAttId.isEmpty()) { return; @@ -781,7 +827,6 @@ public class DataBaseAPI { throws SnapshotingException { // one sql request per table - List<SnapAttributeExtract> numericScalarRO = attributes.stream() .filter(s -> s.getDataFormat() == AttrDataFormat._SCALAR && s.getDataType() != TangoConst.Tango_DEV_STRING @@ -808,94 +853,64 @@ public class DataBaseAPI { try { // --- Get scalar numeric read only values - selectScalarRO(numericScalarRO, snapID, SnapConst.T_SC_NUM_1VAL); + + // Avoid Oracle DB error ORA-01795: maximum number of expressions in a list is 1000 + final List<List<SnapAttributeExtract>> chunks = Lists.partition(numericScalarRO, MAX_SELECT_SIZE); + for (List<SnapAttributeExtract> chunk : chunks) { + selectScalarRO(chunk, snapID, SnapConst.T_SC_NUM_1VAL); + } } catch (SQLException | SnapshotingException e) { logger.error(ERROR_EXTRACTING_SNAPSHOT_DATA, e); } try { // --- Get scalar numeric read write values - selectScalarRW(numericScalarRW, snapID, SnapConst.T_SC_NUM_2VAL); + final List<List<SnapAttributeExtract>> chunks = Lists.partition(numericScalarRW, MAX_SELECT_SIZE); + for (List<SnapAttributeExtract> chunk : chunks) { + selectScalarRW(chunk, snapID, SnapConst.T_SC_NUM_2VAL); + } } catch (SQLException | SnapshotingException e) { logger.error(ERROR_EXTRACTING_SNAPSHOT_DATA, e); } try { // --- Get scalar string read only values - selectScalarRO(stringScalarRO, snapID, SnapConst.T_SC_STR_1VAL); + final List<List<SnapAttributeExtract>> chunks = Lists.partition(stringScalarRO, MAX_SELECT_SIZE); + for (List<SnapAttributeExtract> chunk : chunks) { + selectScalarRO(chunk, snapID, SnapConst.T_SC_STR_1VAL); + } } catch (SQLException | SnapshotingException e) { logger.error(ERROR_EXTRACTING_SNAPSHOT_DATA, e); } try { // --- Get scalar numeric read write values - selectScalarRW(stringScalarRW, snapID, SnapConst.T_SC_STR_2VAL); + final List<List<SnapAttributeExtract>> chunks = Lists.partition(stringScalarRW, MAX_SELECT_SIZE); + for (List<SnapAttributeExtract> chunk : chunks) { + selectScalarRW(chunk, snapID, SnapConst.T_SC_STR_2VAL); + } } catch (SQLException | SnapshotingException e) { logger.error(ERROR_EXTRACTING_SNAPSHOT_DATA, e); } try { // --- Get spectrum read values - selectRO(attributes, snapID, SnapConst.T_SP_1VAL); + final List<List<SnapAttributeExtract>> chunks = Lists.partition(attributes, MAX_SELECT_SIZE); + for (List<SnapAttributeExtract> chunk : chunks) { + selectRO(chunk, snapID, SnapConst.T_SP_1VAL); + } } catch (SQLException | SnapshotingException e) { logger.error(ERROR_EXTRACTING_SNAPSHOT_DATA, e); } try { // --- Get spectrum read write values - selectRW(attributes, snapID, SnapConst.T_SP_2VAL); + final List<List<SnapAttributeExtract>> chunks = Lists.partition(attributes, MAX_SELECT_SIZE); + for (List<SnapAttributeExtract> chunk : chunks) { + selectRW(chunk, snapID, SnapConst.T_SP_2VAL); + } } catch (SQLException | SnapshotingException e) { logger.error(ERROR_EXTRACTING_SNAPSHOT_DATA, e); } } - - public void closeResultSet(final ResultSet resultSet) { - if (resultSet == null) { - return; - } - - try { - resultSet.close(); - } catch (final SQLException e) { - e.printStackTrace(); - - logger.error("ERROR !! " + "\r\n" + "\t Origin : \t " + "DataBaseAPI.closeResultSet" + "\r\n" - + "\t Reason : \t " + getDbSchema().toUpperCase().trim() + "_FAILURE" + "\r\n" - + "\t Description : \t " + e.getMessage()); - } - } - - public void closeStatement(final Statement preparedStatement) { - if (preparedStatement == null) { - return; - } - - try { - preparedStatement.close(); - } catch (final SQLException e) { - e.printStackTrace(); - - logger.error("ERROR !! " + "\r\n" + "\t Origin : \t " + "DataBaseAPI.closeStatement" + "\r\n" - + "\t Reason : \t " + getDbSchema().toUpperCase().trim() + "_FAILURE" + "\r\n" - + "\t Description : \t " + e.getMessage()); - } - } - - private void closeConnection(final Connection conn) { - if (conn == null) { - return; - } - - try { - conn.close(); - } catch (final SQLException e) { - e.printStackTrace(); - - logger.error("ERROR !! " + "\r\n" + "\t Origin : \t " + "DataBaseAPI.closeConnection" + "\r\n" - + "\t Reason : \t " + getDbSchema().toUpperCase().trim() + "_FAILURE" + "\r\n" - + "\t Description : \t " + e.getMessage()); - } - } - - private NullableData<?> getSpectrumValue(final String readStr, final String writeStr, final int dataType, final boolean returnAsReadWrite) { int readSize = 0, writeSize = 0; @@ -1367,7 +1382,6 @@ public class DataBaseAPI { * @param id_context The given context's identifier * @return The list of attributes associated to the given context * @throws SnapshotingException - * @see SnapAttributeLight */ public List<SnapAttributeExtract> getContextAssociatedAttributes(final int id_context) throws SnapshotingException { final List<SnapAttributeExtract> attibutesList = new ArrayList<SnapAttributeExtract>(); -- GitLab