diff --git a/src/main/java/net/ucanaccess/commands/InsertCommand.java b/src/main/java/net/ucanaccess/commands/InsertCommand.java index 401b8e1e..bf46aa72 100644 --- a/src/main/java/net/ucanaccess/commands/InsertCommand.java +++ b/src/main/java/net/ucanaccess/commands/InsertCommand.java @@ -165,9 +165,8 @@ public IFeedbackAction persist() throws SQLException { BlobAction ba = new BlobAction(table, newRow); ba.doAction(this); return ana; - } catch (IOException e) { - e.printStackTrace(); - throw new UcanaccessSQLException(e); + } catch (IOException _ex) { + throw new UcanaccessSQLException(_ex); } } diff --git a/src/main/java/net/ucanaccess/console/Main.java b/src/main/java/net/ucanaccess/console/Main.java index 4b31aaf3..6ad83708 100644 --- a/src/main/java/net/ucanaccess/console/Main.java +++ b/src/main/java/net/ucanaccess/console/Main.java @@ -135,9 +135,9 @@ public static void main(String[] args) throws Exception { System.out.println(sqlw.getMessage()); sqlw = sqlw.getNextWarning(); } - } catch (Exception e) { - e.printStackTrace(); - System.out.println(e.getMessage()); + } catch (Exception _ex) { + _ex.printStackTrace(); + System.out.println(_ex.getMessage()); System.exit(1); } Main main = new Main(conn, input); diff --git a/src/main/java/net/ucanaccess/converters/LoadJet.java b/src/main/java/net/ucanaccess/converters/LoadJet.java index d2a16b6b..5416c992 100644 --- a/src/main/java/net/ucanaccess/converters/LoadJet.java +++ b/src/main/java/net/ucanaccess/converters/LoadJet.java @@ -32,68 +32,77 @@ import java.util.Date; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; public class LoadJet { private static int namingCounter = 0; private final class FunctionsLoader { - private Set functionsDefinition = new HashSet<>(); - private void addAggregates() { - functionsDefinition.add(getAggregate("LONGVARCHAR", "last")); - functionsDefinition.add(getAggregate("DECIMAL(100,10)", "last")); - functionsDefinition.add(getAggregate("BOOLEAN", "last")); - functionsDefinition.add(getAggregate("LONGVARCHAR", "first")); - functionsDefinition.add(getAggregate("DECIMAL(100,10)", "first")); - functionsDefinition.add(getAggregate("BOOLEAN", "first")); - functionsDefinition.add(getLastTimestamp()); - functionsDefinition.add(getFirstTimestamp()); + private final Set functionDefinitions = new LinkedHashSet<>(); + private void addAggregates() { + Stream.of(getAggregate("last", "LONGVARCHAR"), + getAggregate("last", "DECIMAL(100,10)"), + getAggregate("last", "BOOLEAN"), + getAggregate("first", "LONGVARCHAR"), + getAggregate("first", "DECIMAL(100,10)"), + getAggregate("first", "BOOLEAN"), + getLastTimestamp(), + getFirstTimestamp() + ).forEach(functionDefinitions::add); } private String getLastTimestamp() { return "CREATE AGGREGATE FUNCTION last(IN val TIMESTAMP, IN flag boolean, INOUT ts TIMESTAMP, INOUT counter INT) " - + "RETURNS TIMESTAMP " + "CONTAINS SQL " + "BEGIN ATOMIC " + "IF flag THEN " + "RETURN ts; " - + "ELSE " + "IF counter IS NULL THEN SET counter = 0; END IF; " + "SET counter = counter + 1; " - + "SET ts = val;" + "RETURN NULL; " + "END IF; " + "END "; + + "RETURNS TIMESTAMP CONTAINS SQL BEGIN ATOMIC IF flag THEN RETURN ts; " + + "ELSE IF counter IS NULL THEN SET counter = 0; END IF; SET counter = counter + 1; " + + "SET ts = val; RETURN NULL; END IF; END"; } private String getFirstTimestamp() { return "CREATE AGGREGATE FUNCTION First(IN val TIMESTAMP, IN flag boolean, INOUT ts TIMESTAMP , INOUT counter INT) " - + "RETURNS TIMESTAMP " + "CONTAINS SQL " + "BEGIN ATOMIC " + "IF flag THEN " + "RETURN ts; " - + "ELSE " + "IF counter IS NULL THEN SET counter = 0; END IF; " + "SET counter = counter + 1; " - + " IF counter = 1 THEN " + " SET ts = val; END IF; " + "RETURN NULL; " + "END IF; " + "END "; + + "RETURNS TIMESTAMP CONTAINS SQL BEGIN ATOMIC IF flag THEN RETURN ts; " + + "ELSE IF counter IS NULL THEN SET counter = 0; END IF; SET counter = counter + 1; " + + " IF counter = 1 THEN SET ts = val; END IF; RETURN NULL; END IF; END "; } - private void addFunction(String functionName, String methodName, String returnType, String... parTypes) { - StringBuilder funDef = new StringBuilder(); + private void addFunction(String _functionName, String _javaMethodName, String _returnType, String... _paramTypes) { if (DBReference.is2xx()) { - funDef.append("CREATE FUNCTION ").append(functionName).append("("); - String comma = ""; - for (int i = 0; i < parTypes.length; i++) { - funDef.append(comma).append("par").append(i).append(" ").append(parTypes[i]); - comma = ","; - } - funDef.append(")"); - funDef.append(" RETURNS "); - funDef.append(returnType); - funDef.append(" LANGUAGE JAVA DETERMINISTIC NO SQL EXTERNAL NAME 'CLASSPATH:"); - funDef.append(methodName).append("'"); + functionDefinitions.add(new StringBuilder() + .append("CREATE FUNCTION ") + .append(_functionName) + .append("(") + .append(IntStream.range(0, _paramTypes.length).mapToObj(i -> "par" + i + " " + _paramTypes[i]).collect(Collectors.joining(", "))) + .append(")") + .append(" RETURNS ") + .append(_returnType) + .append(" LANGUAGE JAVA DETERMINISTIC NO SQL EXTERNAL NAME 'CLASSPATH:") + .append(_javaMethodName) + .append("'") + .toString()); } else { - funDef.append("CREATE ALIAS ").append(functionName).append(" FOR \"").append(methodName).append("\""); + functionDefinitions.add(new StringBuilder() + .append("CREATE ALIAS ") + .append(_functionName) + .append(" FOR \"") + .append(_javaMethodName) + .append("\"") + .toString()); } - functionsDefinition.add(funDef.toString()); } - private void addFunctions(Class clazz, boolean cswitch) throws SQLException { - Method[] mths = clazz.getDeclaredMethods(); + private void addFunctions(Class _clazz, boolean _cswitch) throws SQLException { + Method[] mths = _clazz.getDeclaredMethods(); Map tmap = TypesMap.getAccess2HsqlTypesMap(); for (Method mth : mths) { Annotation[] ants = mth.getAnnotations(); for (Annotation ant : ants) { if (ant.annotationType().equals(FunctionType.class)) { FunctionType ft = (FunctionType) ant; - String methodName = clazz.getName() + "." + mth.getName(); + String methodName = _clazz.getName() + "." + mth.getName(); String functionName = ft.functionName(); if (functionName == null) { functionName = methodName; @@ -122,7 +131,7 @@ private void addFunctions(Class clazz, boolean cswitch) throws SQLException { } } createFunctions(); - if (cswitch) { + if (_cswitch) { createSwitch(); } } @@ -148,17 +157,16 @@ private void resetDefault() { } private void createFunctions() { - for (String functionDef : functionsDefinition) { + for (String functionDef : functionDefinitions) { try { exec(functionDef, true); - } catch (SQLException e) { - e.printStackTrace(); - Logger.logWarning(LoggerMessageEnum.FUNCTION_ALREADY_ADDED, functionDef); + } catch (SQLException _ex) { + Logger.logWarning(LoggerMessageEnum.FAILED_TO_CREATE_FUNCTION, functionDef, _ex.toString()); } } - functionsDefinition.clear(); + functionDefinitions.clear(); } private void createSwitch() { @@ -184,18 +192,18 @@ private void createSwitch() { header.append(") RETURNS").append(type).append(" RETURN").append(body); try { exec(header.toString(), true); - } catch (SQLException e) { - Logger.logWarning(LoggerMessageEnum.FUNCTION_ALREADY_ADDED, header.toString()); + } catch (SQLException _ex) { + Logger.logWarning(LoggerMessageEnum.FAILED_TO_CREATE_FUNCTION, header.toString(), _ex.toString()); } } } } - private String getAggregate(String type, String fun) { - return "CREATE AGGREGATE FUNCTION " + fun + "(IN val " + type + ", IN flag BOOLEAN, INOUT register " - + type + ", INOUT counter INT) " + " RETURNS " + type + " NO SQL LANGUAGE JAVA " - + " EXTERNAL NAME 'CLASSPATH:net.ucanaccess.converters.FunctionsAggregate." + fun + "'"; + private String getAggregate(String _functionName, String _type) { + return "CREATE AGGREGATE FUNCTION " + _functionName + "(IN val " + _type + ", IN flag BOOLEAN, INOUT register " + + _type + ", INOUT counter INT) RETURNS " + _type + " NO SQL LANGUAGE JAVA " + + "EXTERNAL NAME 'CLASSPATH:net.ucanaccess.converters.FunctionsAggregate." + _functionName + "'"; } private void loadMappedFunctions() throws SQLException { @@ -235,8 +243,8 @@ private final class TablesLoader { private final List unresolvedTables = new ArrayList<>(); private final List calculatedFieldsTriggers = new ArrayList<>(); private final List loadingOrder = new LinkedList<>(); - private final Set alreadyIndexed = new HashSet<>(); - private final Set readOnlyTables = new HashSet<>(); + private final Set alreadyIndexed = new LinkedHashSet<>(); + private final Set readOnlyTables = new LinkedHashSet<>(); private String commaSeparated(List columns, boolean escape) throws SQLException { String comma = ""; @@ -322,13 +330,13 @@ private String getCalculatedFieldTrigger(String ntn, Column cl, boolean isCreate return isCreate ? "CREATE TRIGGER expr%d before insert ON " + ntn + " REFERENCING NEW AS newrow FOR EACH ROW " - + " BEGIN ATOMIC " + " SET newrow." + ecl + " = " + call + "; END " + + " BEGIN ATOMIC SET newrow." + ecl + " = " + call + "; END " : "CREATE TRIGGER expr%d before update ON " + ntn - + " REFERENCING NEW AS newrow OLD AS OLDROW FOR EACH ROW " + " BEGIN ATOMIC IF %s THEN " + + " REFERENCING NEW AS newrow OLD AS OLDROW FOR EACH ROW BEGIN ATOMIC IF %s THEN " + " SET newrow." + ecl + " = " + call + "; ELSEIF newrow." + ecl + " <> oldrow." + ecl + " THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '" + Logger.getMessage(LoggerMessageEnum.TRIGGER_UPDATE_CF_ERR) + cl.getName().replace("%", "%%") - + "'" + "; END IF ; END "; + + "'; END IF ; END "; } private boolean isNumeric(DataType dt) { @@ -1464,20 +1472,19 @@ private static boolean hasAutoNumberColumn(Table t) { return false; } - public void addFunctions(Class clazz) throws SQLException { - functionsLoader.addFunctions(clazz, false); + public void addFunctions(Class _clazz) throws SQLException { + functionsLoader.addFunctions(_clazz, false); } - private void exec(String expression, boolean logging) throws SQLException { + private void exec(String _expression, boolean _logging) throws SQLException { try (Statement st = conn.createStatement()) { - - st.executeUpdate(expression); - } catch (SQLException e) { - if (logging && e.getErrorCode() != TablesLoader.HSQL_FK_ALREADY_EXISTS) { - Logger.log("Cannot execute:" + expression + " " + e.getMessage()); + st.executeUpdate(_expression); + } catch (SQLException _ex) { + if (_logging && _ex.getErrorCode() != TablesLoader.HSQL_FK_ALREADY_EXISTS) { + Logger.log("Cannot execute:" + _expression + " " + _ex.getMessage()); } - throw e; + throw _ex; } } diff --git a/src/main/java/net/ucanaccess/jdbc/DBReference.java b/src/main/java/net/ucanaccess/jdbc/DBReference.java index 24914d36..0f11eb51 100644 --- a/src/main/java/net/ucanaccess/jdbc/DBReference.java +++ b/src/main/java/net/ucanaccess/jdbc/DBReference.java @@ -287,8 +287,8 @@ private void setIgnoreCase(Connection conn) { } } - private void initHSQLDB(Connection conn) { - try (Statement st = conn.createStatement()) { + private void initHSQLDB(Connection _conn) { + try (Statement st = _conn.createStatement()) { st.execute("SET DATABASE SQL SYNTAX ora TRUE"); st.execute("SET DATABASE SQL CONCAT NULLS " + concatNulls); if (lobScale == null && inMemory) { @@ -297,8 +297,8 @@ private void initHSQLDB(Connection conn) { st.execute("SET FILES LOB SCALE " + lobScale); } - } catch (Exception w) { - w.printStackTrace(); + } catch (Exception _ex) { + _ex.printStackTrace(); } } @@ -381,8 +381,8 @@ private String getHsqlUrl(final Session session) throws SQLException { } else { finalizeHsqlDb(session); } - } catch (Exception e) { - e.printStackTrace(); + } catch (Exception _ex) { + _ex.printStackTrace(); } })); } diff --git a/src/main/java/net/ucanaccess/jdbc/UcanaccessConnection.java b/src/main/java/net/ucanaccess/jdbc/UcanaccessConnection.java index 61947312..cfa1dba9 100644 --- a/src/main/java/net/ucanaccess/jdbc/UcanaccessConnection.java +++ b/src/main/java/net/ucanaccess/jdbc/UcanaccessConnection.java @@ -284,8 +284,8 @@ private void flushIO() throws SQLException { if (testRollback) { throw new RuntimeException("PhysicalRollbackTest"); } - } catch (Throwable t) { - t.printStackTrace(); + } catch (Throwable _t) { + _t.printStackTrace(); hsqlDBConnection.rollback(); ibal.clear(); Iterator it = executed.descendingIterator(); @@ -304,10 +304,10 @@ private void flushIO() throws SQLException { try { ref.getDbIO().flush(); unloadDB(); - } catch (IOException e) { - e.printStackTrace(); + } catch (IOException _ex) { + _ex.printStackTrace(); } - throw new UcanaccessSQLException(t); + throw new UcanaccessSQLException(_t); } try { ref.getDbIO().flush(); diff --git a/src/main/java/net/ucanaccess/log/LoggerMessageEnum.java b/src/main/java/net/ucanaccess/log/LoggerMessageEnum.java index ee3d7f60..80e029f4 100644 --- a/src/main/java/net/ucanaccess/log/LoggerMessageEnum.java +++ b/src/main/java/net/ucanaccess/log/LoggerMessageEnum.java @@ -13,6 +13,6 @@ public enum LoggerMessageEnum implements LoggerResourceMessage { STATEMENT_DDL, CONSTRAINT, LOBSCALE, - FUNCTION_ALREADY_ADDED, + FAILED_TO_CREATE_FUNCTION, NO_SELECT } diff --git a/src/main/resources/net/ucanaccess/log/logger_messages.properties b/src/main/resources/net/ucanaccess/log/logger_messages.properties index baf684a4..f515054c 100644 --- a/src/main/resources/net/ucanaccess/log/logger_messages.properties +++ b/src/main/resources/net/ucanaccess/log/logger_messages.properties @@ -7,7 +7,7 @@ CONCURRENT_PROCESS_ACCESS=File marked as read only. Notice that only one process NOT_A_VALID_PASSWORD=Password authentication failed. INVALID_MONTH_NUMBER=Invalid Month Number UNPARSABLE_DATE=Unparsable Date. -TABLE_DOES_NOT_EXIST=Table %s does not exist . +TABLE_DOES_NOT_EXIST=Table %s does not exist. INVALID_JACKCESS_OPENER=Jackess Opener class must implement net.ucanaccess.jdbc.JackcessOpener ONLY_IN_MEMORY_ALLOWED=If you specify a custom JackcessOpener only the in memory mode is allowed COMPLEX_TYPE_UNSUPPORTED=Complex Type not supported yet @@ -27,6 +27,6 @@ CONSTRAINT=Detected %s constraint breach, table %s, record %s: making the table LOBSCALE=Lobscale value must equal at least one of the following values:1,2,4,8,16,32. Skipping. ACCESS_97=Access 97 is supported in read-only. PARAMETER_NULL=Parameter %s mustn't be null. -FUNCTION_ALREADY_ADDED=Function already added: %s +FAILED_TO_CREATE_FUNCTION=Failed to create function '%s': %s NO_SELECT=Please, don't use executeQuery method to execute INSERT, DELETE or UPDATE SQL statement(it isn't correct). Use execute or executeUpdate methods instead DEFAULT_NEEDED=When adding a new column not null(%s), you must specify a default because the table %s already contains one or more records(%d records) diff --git a/src/test/java/net/ucanaccess/test/integration/DropTableTest.java b/src/test/java/net/ucanaccess/test/integration/DropTableTest.java index 2de3187c..9d876abe 100644 --- a/src/test/java/net/ucanaccess/test/integration/DropTableTest.java +++ b/src/test/java/net/ucanaccess/test/integration/DropTableTest.java @@ -14,21 +14,21 @@ class DropTableTest extends UcanaccessBaseTest { @Override protected void init(AccessVersion _accessVersion) throws SQLException { super.init(_accessVersion); - executeStatements("CREATE TABLE AAAn ( baaaa TEXT(3) PRIMARY KEY,A INTEGER , C TEXT(4)) ", - "CREATE TABLE [AAA n] ( baaaa TEXT(3) PRIMARY KEY,A INTEGER , C TEXT(4)) "); + executeStatements("CREATE TABLE AAAn (baaaa TEXT(3) PRIMARY KEY, A INTEGER, C TEXT(4))", + "CREATE TABLE [AAA n] (baaaa TEXT(3) PRIMARY KEY, A INTEGER, C TEXT(4))"); } - void createSimple(String _tableName, String a, Object[][] ver) throws SQLException, IOException { + void createSimple(String _tableName, String a, Object[][] ver) throws SQLException { try (Statement st = ucanaccess.createStatement()) { - st.execute("INSERT INTO " + _tableName + " VALUES ('33A',11,'" + a + "' )"); - st.execute("INSERT INTO " + _tableName + " VALUES ('33B',111,'" + a + "' )"); + st.execute("INSERT INTO " + _tableName + " VALUES ('33A', 11,'" + a + "')"); + st.execute("INSERT INTO " + _tableName + " VALUES ('33B',111,'" + a + "')"); checkQuery("SELECT * FROM " + _tableName + " ORDER BY c", ver); } } @ParameterizedTest(name = "[{index}] {0}") @EnumSource(value = AccessVersion.class) - void testDrop(AccessVersion _accessVersion) throws SQLException, IOException { + void testDrop(AccessVersion _accessVersion) throws SQLException { init(_accessVersion); // ucanaccess.setAutoCommit(false); @@ -36,7 +36,7 @@ void testDrop(AccessVersion _accessVersion) throws SQLException, IOException { try (Statement st = ucanaccess.createStatement()) { st.executeUpdate("DROP TABLE AAAn"); // ucanaccess.commit(); - st.execute("CREATE TABLE AAAn ( baaaa TEXT(3) PRIMARY KEY,A INTEGER , C TEXT(4)) "); + st.execute("CREATE TABLE AAAn (baaaa TEXT(3) PRIMARY KEY, A INTEGER, C TEXT(4))"); createSimple("AAAn", "b", new Object[][] {{"33A", 11, "b"}, {"33B", 111, "b"}}); dumpQueryResult("SELECT * FROM AAAn"); ucanaccess.commit(); @@ -53,7 +53,7 @@ void testDropBlank(AccessVersion _accessVersion) throws SQLException, IOExceptio try (Statement st = ucanaccess.createStatement()) { st.executeUpdate("DROP TABLE [AAA n]"); // ucanaccess.commit(); - st.execute("CREATE TABLE [AAA n] ( baaaa TEXT(3) PRIMARY KEY,A INTEGER , C TEXT(4)) "); + st.execute("CREATE TABLE [AAA n] (baaaa TEXT(3) PRIMARY KEY, A INTEGER, C TEXT(4))"); createSimple("[AAA n]", "b", new Object[][] {{"33A", 11, "b"}, {"33B", 111, "b"}}); dumpQueryResult("SELECT * FROM [AAA n]"); ucanaccess.commit(); diff --git a/src/test/java/net/ucanaccess/test/integration/MultiThreadAccessTest.java b/src/test/java/net/ucanaccess/test/integration/MultiThreadAccessTest.java index d53e9fc3..aeb2c699 100644 --- a/src/test/java/net/ucanaccess/test/integration/MultiThreadAccessTest.java +++ b/src/test/java/net/ucanaccess/test/integration/MultiThreadAccessTest.java @@ -79,8 +79,8 @@ void testMultiThread(AccessVersion _accessVersion) throws SQLException, IOExcept crud(); crudPS(); crudUpdatableRS(); - } catch (SQLException e) { - e.printStackTrace(); + } catch (SQLException _ex) { + fail(_ex); } }); threads[i].start(); @@ -88,8 +88,8 @@ void testMultiThread(AccessVersion _accessVersion) throws SQLException, IOExcept for (Thread t : threads) { try { t.join(); - } catch (InterruptedException e) { - e.printStackTrace(); + } catch (InterruptedException _ex) { + continue; } } ucanaccess = getUcanaccessConnection(dbPath); diff --git a/src/test/java/net/ucanaccess/test/integration/RomanCharacterTest.java b/src/test/java/net/ucanaccess/test/integration/RomanCharacterTest.java index f96f03d7..62755d09 100644 --- a/src/test/java/net/ucanaccess/test/integration/RomanCharacterTest.java +++ b/src/test/java/net/ucanaccess/test/integration/RomanCharacterTest.java @@ -21,10 +21,10 @@ void testNoRomanCharactersInColumnName(AccessVersion _accessVersion) throws Exce dumpQueryResult("SELECT * FROM NOROMAN"); getLogger().info("q3¹²³¼½¾ß€Ð×ÝÞðýþäüöß"); try (Statement st = ucanaccess.createStatement()) { - st.execute("INSERT INTO NOROMAN ([end],[q3¹²³¼½¾ß€Ð×ÝÞðýþäüöß]) VALUES( 'the end','yeeep')"); + st.execute("INSERT INTO NOROMAN ([end],[q3¹²³¼½¾ß€Ð×ÝÞðýþäüöß]) VALUES('the end', 'yeeep')"); st.execute("UPDATE NOROMAN SET [q3¹²³¼½¾ß€Ð×ÝÞðýþäüöß]='NOOOp' WHERE [end]='the end' "); - checkQuery("SELECT * FROM NOROMAN"); } + checkQuery("SELECT * FROM NOROMAN"); } }