6830-6129b.patch
new/src/com/goldencode/p2j/convert/db/ConversionData.java 2023-01-09 10:36:39 +0000 | ||
---|---|---|
15 | 15 |
** CA 20211012 Fixed generated WSDL and reworked SOAP support to rely on namespace, when resolving an |
16 | 16 |
** operation. |
17 | 17 |
** GES 20220502 Match API method name change. |
18 |
** RAA 20230109 Changed inline statement(s) to prepared statement(s). |
|
18 | 19 |
*/ |
19 | 20 | |
20 | 21 |
/* |
... | ... | |
149 | 150 |
{ |
150 | 151 |
// check if the table exists |
151 | 152 |
boolean[] found = { false }; |
153 |
Object[] args = new Object[] {table.toUpperCase() + "__WORK"}; |
|
152 | 154 |
helper.executeQuery("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES " + |
153 |
"WHERE TABLE_SCHEMA = SCHEMA() AND TABLE_NAME LIKE '" + table.toUpperCase() + "__WORK'", (rs) ->
|
|
155 |
"WHERE TABLE_SCHEMA = SCHEMA() AND TABLE_NAME LIKE ?", (rs) ->
|
|
154 | 156 |
{ |
155 | 157 |
found[0] = true; |
156 |
}); |
|
158 |
}, args);
|
|
157 | 159 |
|
158 | 160 |
if (!found[0]) |
159 | 161 |
{ |
new/src/com/goldencode/p2j/persist/AbstractTempTable.java 2023-01-09 10:38:43 +0000 | ||
---|---|---|
57 | 57 |
** delete it instead of handle.delete. |
58 | 58 |
** IAS 20221003 Fixed error message for error 3131 |
59 | 59 |
** IAS 20221111 Added setter for the 'schemaMarshalLevel', fixed one for the 'namespaceURI'. |
60 |
** RAA 20230109 Changed inline statement(s) to prepared statement(s). |
|
60 | 61 |
*/ |
61 | 62 | |
62 | 63 |
/* |
... | ... | |
2575 | 2576 |
sb.append(defBuffer.getTable()); |
2576 | 2577 |
sb.append(" where "); |
2577 | 2578 |
sb.append(TemporaryBuffer.MULTIPLEX_FIELD_NAME); |
2578 |
sb.append(" = "); |
|
2579 |
sb.append(defBuffer.getMultiplexID());
|
|
2579 |
sb.append(" = ?");
|
|
2580 |
Object[] args = new Object[] {defBuffer.getMultiplexID()};
|
|
2580 | 2581 |
try |
2581 | 2582 |
{ |
2582 |
Object res = persistence.getSingleSQLResult(sb.toString(), null);
|
|
2583 |
Object res = persistence.getSingleSQLResult(sb.toString(), args);
|
|
2583 | 2584 |
if (res != null) |
2584 | 2585 |
{ |
2585 | 2586 |
return true; |
new/src/com/goldencode/p2j/persist/BufferImpl.java 2023-01-09 10:40:25 +0000 | ||
---|---|---|
243 | 243 |
** CA 20221121 For a dynamic TEMP-TABLE, if the NAME attribute is changed, then the default-buffer's NAME |
244 | 244 |
** must be changed, too. |
245 | 245 |
** SVL 20230108 Improved performance by replacing some "for-each" loops with indexed "for" loops. |
246 |
** RAA 20230109 Changed inline statement(s) to prepared statement(s). |
|
246 | 247 |
*/ |
247 | 248 | |
248 | 249 |
/* |
... | ... | |
9242 | 9243 |
.append(Buffer.ORIGIN_ROWID_FIELD).append("=NULL, ") |
9243 | 9244 |
.append(Buffer.AFTER_ROWID_FIELD).append("=NULL") |
9244 | 9245 |
.append(" where ") |
9245 |
.append(TemporaryBuffer.MULTIPLEX_FIELD_NAME).append(" = ").append(afterBuf.getMultiplexID());
|
|
9246 |
.append(TemporaryBuffer.MULTIPLEX_FIELD_NAME).append(" = ?");
|
|
9246 | 9247 |
|
9248 |
Object[] args = new Object[] {afterBuf.getMultiplexID()}; |
|
9247 | 9249 |
try |
9248 | 9250 |
{ |
9249 | 9251 |
boolean noUndo = !beforeBuf.isUndoable(); |
9250 |
int cnt = persistence.executeSQL(buf.toString(), null, noUndo);
|
|
9252 |
int cnt = persistence.executeSQL(buf.toString(), args, noUndo);
|
|
9251 | 9253 |
afterBuf.pruneSessionCache(); |
9252 | 9254 |
if (log.isLoggable(Level.FINE)) |
9253 | 9255 |
{ |
new/src/com/goldencode/p2j/persist/FastCopyHelper.java 2023-01-09 10:41:46 +0000 | ||
---|---|---|
22 | 22 |
** ECF 20221006 Minor optimization. |
23 | 23 |
** OM 20220913 Enhanced dialect API for sorting nulls. |
24 | 24 |
** OM 20221012 Fixed regression in previous commit. |
25 |
** RAA 20230109 Changed inline statement(s) to prepared statement(s). |
|
25 | 26 |
*/ |
26 | 27 | |
27 | 28 |
/* |
... | ... | |
813 | 814 |
private static void restartSequence(Persistence persistence, String sequenceName, Long start) |
814 | 815 |
throws PersistenceException |
815 | 816 |
{ |
816 |
persistence.executeSQL("alter sequence " + sequenceName + " restart with " + start); |
|
817 |
Object[] args = new Object[] {start}; |
|
818 |
String stmt = persistence.getDialect().getSequenceSetValString(sequenceName); |
|
819 |
persistence.executeSQL(stmt, args); |
|
817 | 820 |
} |
818 | 821 |
|
819 | 822 |
/** |
new/src/com/goldencode/p2j/persist/TemporaryBuffer.java 2023-01-09 10:46:17 +0000 | ||
---|---|---|
628 | 628 |
** IAS 20221103 Fixed support for a binded table parameter. |
629 | 629 |
** CA 20221206 If a REFERENCE-ONLY table is already bound to the same target table, do not |
630 | 630 |
** re-bind. |
631 |
** RAA 20230109 Changed inline statement(s) to prepared statement(s). |
|
631 | 632 |
*/ |
632 | 633 | |
633 | 634 |
/* |
... | ... | |
4799 | 4800 |
// then update the flag for the after buffer: |
4800 | 4801 |
fql = new FQLExpression("update "); |
4801 | 4802 |
fql.append(getDMOImplementationName()); |
4802 |
fql.append(" set _rowState = ").append(Integer.toString(Buffer.ROW_CREATED)); |
|
4803 |
fql.append(" where ").append(MULTIPLEX_FIELD_NAME).append(" = "); |
|
4804 |
fql.append(Integer.toString(getMultiplexID())); |
|
4803 |
fql.append(" set _rowState = ?"); |
|
4804 |
fql.append(" where ").append(MULTIPLEX_FIELD_NAME).append(" = ?"); |
|
4805 | 4805 |
fql.append(" and (_rowState is null or _rowState = 0)"); |
4806 |
persistence.deleteOrUpdate(fql.toFinalExpression(), null, getEntityName(), !isUndoable()); |
|
4806 |
Object[] args = new Object[] {Integer.toString(Buffer.ROW_CREATED), |
|
4807 |
Integer.toString(getMultiplexID())}; |
|
4808 |
persistence.deleteOrUpdate(fql.toFinalExpression(), args, getEntityName(), !isUndoable()); |
|
4807 | 4809 |
} |
4808 | 4810 |
catch (PersistenceException exc) |
4809 | 4811 |
{ |
... | ... | |
5665 | 5667 |
|
5666 | 5668 |
try |
5667 | 5669 |
{ |
5670 |
Object[] args = new Object[] {getMultiplexID()}; |
|
5668 | 5671 |
String sql = "select count(*) from " + getTable() + |
5669 |
" where " + MULTIPLEX_FIELD_NAME + " = " + getMultiplexID();
|
|
5670 |
Long res = getPersistence().getSingleSQLResult(sql, null);
|
|
5672 |
" where " + MULTIPLEX_FIELD_NAME + " = ?";
|
|
5673 |
Long res = getPersistence().getSingleSQLResult(sql, args);
|
|
5671 | 5674 |
return res.intValue(); |
5672 | 5675 |
|
5673 | 5676 |
} |
... | ... | |
7781 | 7784 |
{ |
7782 | 7785 |
if (!full) |
7783 | 7786 |
{ |
7787 |
Object[] multiplexArgs = new Object[] {multiplexID}; |
|
7784 | 7788 |
// execute a simple query to determine if there is any record in this virtual table |
7785 | 7789 |
String checkStmt = |
7786 | 7790 |
"select tt." + Session.PK + " from " + table + " tt " + |
7787 |
"where tt." + MULTIPLEX_FIELD_NAME + " = " + multiplexID + " limit 1";
|
|
7788 |
Long id = persistence.getSingleSQLResult(checkStmt, null);
|
|
7791 |
"where tt." + MULTIPLEX_FIELD_NAME + " = ?" + " limit 1";
|
|
7792 |
Long id = persistence.getSingleSQLResult(checkStmt, multiplexArgs);
|
|
7789 | 7793 |
full = (id == null); |
7790 | 7794 |
} |
7791 | 7795 |
|
new/src/com/goldencode/p2j/persist/dialect/Dialect.java 2023-01-09 10:52:58 +0000 | ||
---|---|---|
88 | 88 |
** OM 20221018 Added support for MariaDb lenient dialect. |
89 | 89 |
** OM 20221026 Excluded table name from index name by default. It will be added as needed by |
90 | 90 |
** dialects. |
91 |
** RAA 20230109 Added method getSequenceSetValString(). |
|
91 | 92 |
*/ |
92 | 93 | |
93 | 94 |
/* |
... | ... | |
759 | 760 |
public abstract String getSequenceSetValString(String sequenceName, long newVal); |
760 | 761 |
|
761 | 762 |
/** |
763 |
* Generate the appropriate select statement to reset the value of a sequence. |
|
764 |
* |
|
765 |
* @param sequenceName |
|
766 |
* The name of the sequence. |
|
767 |
* |
|
768 |
* @return Dialect-specific string to set the current value of the sequence, or {@code null} |
|
769 |
* if not supported. |
|
770 |
*/ |
|
771 |
public abstract String getSequenceSetValString(String sequenceName); |
|
772 |
|
|
773 |
/** |
|
774 |
* Generate the appropriate select statement to reset the value of a sequence. |
|
775 |
* |
|
776 |
* @return Dialect-specific string to set the current value of the sequence, or {@code null} |
|
777 |
* if not supported. |
|
778 |
*/ |
|
779 |
public abstract String getSequenceSetValString(); |
|
780 |
|
|
781 |
/** |
|
782 |
* |
|
762 | 783 |
* Generate the appropriate select statement to retrieve the next value of a sequence. |
763 | 784 |
* |
764 | 785 |
* @param sequenceName |
... | ... | |
779 | 800 |
public abstract String getSequenceCurrValString(String sequenceName); |
780 | 801 |
|
781 | 802 |
/** |
803 |
* Generate the appropriate select statement to retrieve the current value of a sequence. |
|
804 |
* |
|
805 |
* @return Dialect-specific string to query the sequence, or {@code null} if not supported. |
|
806 |
*/ |
|
807 |
public String getSequenceCurrValString() |
|
808 |
{ |
|
809 |
throw new IllegalStateException( |
|
810 |
"Current value of a sequence cannot be retrieved using prepared statements."); |
|
811 |
} |
|
812 |
|
|
813 |
/** |
|
782 | 814 |
* Returns {@code true} if this dialect fully support the sequences as 4GL language (most important: |
783 | 815 |
* bounded values, cycle). If not fully supported, additional code is needed in P2J sequence class |
784 | 816 |
* implementation to fix this. |
new/src/com/goldencode/p2j/persist/dialect/MariaDbLenientDialect.java 2023-01-09 10:57:04 +0000 | ||
---|---|---|
9 | 9 |
** becomes a subclass and will implement the methods to adhere to MariaDb strict(er) mode. |
10 | 10 |
** OM 20221025 Improve sequence compatibility with 4GL. |
11 | 11 |
** OM 20221026 Excluded table name from index name by default. It will be added as needed by dialects. |
12 |
** RAA 20230109 Overrided method getSequenceSetValString(). |
|
12 | 13 |
*/ |
13 | 14 | |
14 | 15 |
/* |
... | ... | |
1074 | 1075 |
} |
1075 | 1076 |
|
1076 | 1077 |
/** |
1078 |
* Generate the appropriate select statement to reset the value of a sequence. |
|
1079 |
* |
|
1080 |
* @param sequenceName |
|
1081 |
* The name of the sequence. |
|
1082 |
* |
|
1083 |
* @return Dialect-specific string to set the current value of the sequence, or {@code null} |
|
1084 |
* if not supported. |
|
1085 |
* |
|
1086 |
* @see <a href="https://mariadb.com/kb/en/setval/">SETVAL() Function</a> |
|
1087 |
*/ |
|
1088 |
@Override |
|
1089 |
public String getSequenceSetValString(String sequenceName) |
|
1090 |
{ |
|
1091 |
return "select setval(" + sequenceName + ", ?)"; |
|
1092 |
} |
|
1093 |
|
|
1094 |
/** |
|
1095 |
* Generate the appropriate select statement to reset the value of a sequence. |
|
1096 |
* |
|
1097 |
* @return Dialect-specific string to set the current value of the sequence, or {@code null} |
|
1098 |
* if not supported. |
|
1099 |
* |
|
1100 |
* @see <a href="https://mariadb.com/kb/en/setval/">SETVAL() Function</a> |
|
1101 |
*/ |
|
1102 |
@Override |
|
1103 |
public String getSequenceSetValString() |
|
1104 |
{ |
|
1105 |
return "select setval(?, ?)"; |
|
1106 |
} |
|
1107 |
|
|
1108 |
/** |
|
1077 | 1109 |
* Generate the appropriate select statement to retrieve the next value of a sequence. |
1078 | 1110 |
* |
1079 | 1111 |
* @param sequenceName |
new/src/com/goldencode/p2j/persist/dialect/P2JH2Dialect.java 2023-01-09 11:00:20 +0000 | ||
---|---|---|
104 | 104 |
** OM 20221012 Fixed regression (invalid sort criteria) in previous commit. |
105 | 105 |
** OM 20221026 Excluded table name from index name by default. It will be added as needed by |
106 | 106 |
** dialects. |
107 |
** RAA 20230109 Overrided methods getSequenceSetValString() and getSequenceCurrValString(). |
|
107 | 108 |
*/ |
108 | 109 | |
109 | 110 |
/* |
... | ... | |
768 | 769 |
} |
769 | 770 |
|
770 | 771 |
/** |
772 |
* Generate the appropriate select statement to reset the value of a |
|
773 |
* sequence. |
|
774 |
* |
|
775 |
* @param sequenceName |
|
776 |
* The name of the sequence. |
|
777 |
* |
|
778 |
* @return Dialect-specific string to query the sequence, or |
|
779 |
* <code>null</code> if not supported. |
|
780 |
*/ |
|
781 |
@Override |
|
782 |
public String getSequenceSetValString(String sequenceName) |
|
783 |
{ |
|
784 |
return "alter sequence " + sequenceName + " restart with ?"; |
|
785 |
} |
|
786 |
|
|
787 |
/** |
|
788 |
* Generate the appropriate select statement to reset the value of a |
|
789 |
* sequence. |
|
790 |
* |
|
791 |
* @return Dialect-specific string to query the sequence, or |
|
792 |
* <code>null</code> if not supported. |
|
793 |
*/ |
|
794 |
@Override |
|
795 |
public String getSequenceSetValString() |
|
796 |
{ |
|
797 |
throw new IllegalStateException("Can't reset value of a sequence with prepared statement in H2"); |
|
798 |
} |
|
799 |
|
|
800 |
/** |
|
771 | 801 |
* Generate the appropriate select statement to retrieve the current |
772 | 802 |
* value of a sequence. |
773 | 803 |
* |
... | ... | |
784 | 814 |
return "select current_value from information_schema.sequences " + |
785 | 815 |
"where upper(sequence_name) = '" + sequenceName.toUpperCase() + "'"; |
786 | 816 |
} |
817 |
|
|
818 |
/** |
|
819 |
* Generate the appropriate select statement to retrieve the current |
|
820 |
* value of a sequence. |
|
821 |
* |
|
822 |
* @return Dialect-specific string to query the sequence, or |
|
823 |
* <code>null</code> if not supported. |
|
824 |
*/ |
|
825 |
@Override |
|
826 |
public String getSequenceCurrValString() |
|
827 |
{ |
|
828 |
// this feature is not supported by H2 directly, use a workaround |
|
829 |
return "select current_value from information_schema.sequences " + |
|
830 |
"where upper(sequence_name) = ?"; |
|
831 |
} |
|
787 | 832 | |
788 | 833 |
/** |
789 | 834 |
* Returns <code>true</code> if this dialect fully support the sequences as |
new/src/com/goldencode/p2j/persist/dialect/P2JPostgreSQLDialect.java 2023-01-09 11:01:55 +0000 | ||
---|---|---|
122 | 122 |
** IAS 20220921 Dialect-specific UDF schema. |
123 | 123 |
** OM 20221026 Excluded table name from index name by default. It will be added as needed by |
124 | 124 |
** dialects. |
125 |
** RAA 20230109 Overrided method getSequenceSetValString(). |
|
125 | 126 |
*/ |
126 | 127 | |
127 | 128 |
/* |
... | ... | |
1109 | 1110 |
|
1110 | 1111 |
/** |
1111 | 1112 |
* Generate the appropriate select statement to retrieve the next value of a sequence. |
1113 |
* |
|
1114 |
* @param sequenceName |
|
1115 |
* The name of the sequence. |
|
1116 |
* |
|
1117 |
* @return Dialect-specific string to query the sequence, or |
|
1118 |
* <code>null</code> if not supported. |
|
1119 |
*/ |
|
1120 |
@Override |
|
1121 |
public String getSequenceSetValString(String sequenceName) |
|
1122 |
{ |
|
1123 |
return "select setval('" + sequenceName + "', ?)"; |
|
1124 |
} |
|
1125 |
|
|
1126 |
/** |
|
1127 |
* Generate the appropriate select statement to retrieve the next value of a sequence. |
|
1128 |
* |
|
1129 |
* @return Dialect-specific string to query the sequence, or |
|
1130 |
* <code>null</code> if not supported. |
|
1131 |
*/ |
|
1132 |
@Override |
|
1133 |
public String getSequenceSetValString() |
|
1134 |
{ |
|
1135 |
return "select setval(?, ?)"; |
|
1136 |
} |
|
1137 |
|
|
1138 |
/** |
|
1139 |
* Generate the appropriate select statement to retrieve the next value of a sequence. |
|
1112 | 1140 |
* |
1113 | 1141 |
* @param sequenceName |
1114 | 1142 |
* The name of the sequence to be queried. |
new/src/com/goldencode/p2j/persist/dialect/P2JSQLServer2008Dialect.java 2023-01-09 11:03:15 +0000 | ||
---|---|---|
40 | 40 |
** IAS 20220816 Added getScriptRunner() method. |
41 | 41 |
** IAS 20220913 Re-work processing of UDFs errors/warnings. |
42 | 42 |
** OM 20221026 Excluded table name from index name by default. It will be added as needed by dialects. |
43 |
** RAA 20230109 Overrided method getSequenceSetValString(). |
|
43 | 44 |
*/ |
44 | 45 | |
45 | 46 |
/* |
... | ... | |
961 | 962 |
} |
962 | 963 |
|
963 | 964 |
/** |
965 |
* Generate the appropriate select statement to reset the value of a sequence. |
|
966 |
* |
|
967 |
* @param sequenceName |
|
968 |
* The name of the sequence. |
|
969 |
* |
|
970 |
* @return Returning {@code null} since this dialect does not support sequences. |
|
971 |
*/ |
|
972 |
@Override |
|
973 |
public String getSequenceSetValString(String sequenceName) |
|
974 |
{ |
|
975 |
return null; |
|
976 |
} |
|
977 |
|
|
978 |
/** |
|
979 |
* Generate the appropriate select statement to reset the value of a sequence. |
|
980 |
* |
|
981 |
* @return Returning {@code null} since this dialect does not support sequences. |
|
982 |
*/ |
|
983 |
@Override |
|
984 |
public String getSequenceSetValString() |
|
985 |
{ |
|
986 |
return null; |
|
987 |
} |
|
988 |
|
|
989 |
/** |
|
964 | 990 |
* Generate the appropriate select statement to retrieve the next value of a sequence. |
965 | 991 |
* |
966 | 992 |
* @param sequenceName |
new/src/com/goldencode/p2j/persist/dialect/P2JSQLServer2012Dialect.java 2023-01-09 11:04:37 +0000 | ||
---|---|---|
18 | 18 |
** 008 ECF 20200906 New ORM implementation. |
19 | 19 |
** 008 IAS 20201204 Added id() method and support stub for word tables |
20 | 20 |
** IAS 20210315 Refactored for working with word tables for _temp database |
21 |
** RAA 20230109 Overrided method getSequenceCurrValString(). |
|
21 | 22 |
**/ |
22 | 23 | |
23 | 24 |
/* |
... | ... | |
457 | 458 |
} |
458 | 459 |
|
459 | 460 |
/** |
461 |
* Generate the appropriate select statement to retrieve the current value of a sequence. |
|
462 |
* |
|
463 |
* @return Dialect-specific string to query the sequence. |
|
464 |
*/ |
|
465 |
@Override |
|
466 |
public String getSequenceCurrValString() |
|
467 |
{ |
|
468 |
// the cast is needed because the column is of 'variant' datatype. |
|
469 |
// the sql driver does not handle it and reports the following error: |
|
470 |
// 08S01 The "variant" data type is not supported. |
|
471 |
return "select cast(current_value as bigint) " + |
|
472 |
"from sys.sequences where name = ?"; |
|
473 |
} |
|
474 |
|
|
475 |
/** |
|
460 | 476 |
* Generate the appropriate select statement to retrieve the next value of a sequence. |
461 | 477 |
* |
462 | 478 |
* @param sequenceName |
new/src/com/goldencode/p2j/persist/dirty/DefaultDirtyShareManager.java 2023-01-09 11:06:04 +0000 | ||
---|---|---|
75 | 75 |
** 028 ECF 20200906 New ORM implementation. |
76 | 76 |
** 029 EVL 20200621 Adding NPE protection for lockSingle when index name is NULL or empty. |
77 | 77 |
** 030 OM 20201012 Force use locally cached meta information instead of map lookup. |
78 |
** 031 RAA 20230109 Changed inline statement(s) to prepared statement(s). |
|
78 | 79 |
*/ |
79 | 80 | |
80 | 81 |
/* |
... | ... | |
784 | 785 |
} |
785 | 786 |
|
786 | 787 |
String hql = "delete from " + entity + |
787 |
" where " + DatabaseManager.PRIMARY_KEY + " = " + id;
|
|
788 |
" where " + DatabaseManager.PRIMARY_KEY + " = ?";
|
|
788 | 789 |
Session session = null; |
789 | 790 |
boolean inTx = false; |
790 | 791 |
|
... | ... | |
793 | 794 |
session = new Session(dirtyDatabase); |
794 | 795 |
inTx = session.beginTransaction(); |
795 | 796 |
Query query = Session.createQuery(hql); |
797 |
query.setParameter(0, id); |
|
796 | 798 |
query.executeUpdate(session); |
797 | 799 |
session.commit(); |
798 | 800 |
} |
new/src/com/goldencode/p2j/persist/meta/TransactionTableUpdater.java 2023-01-09 11:07:53 +0000 | ||
---|---|---|
13 | 13 |
** OM 20201012 Force use locally cached meta information instead of map lookup. |
14 | 14 |
** ECF 20220630 Fixed MinimalTrans getter/setter names to match conversion of historical names in _Trans |
15 | 15 |
** table. |
16 |
** RAA 20230109 Changed inline statement(s) to prepared statement(s). |
|
16 | 17 |
*/ |
17 | 18 | |
18 | 19 |
/* |
... | ... | |
197 | 198 |
// drop all records that are no more valid |
198 | 199 |
StringBuilder buf = new StringBuilder( |
199 | 200 |
"delete from " + TRANS_TABLE + " where not trans_num in ("); |
201 |
List<Object> args = new ArrayList<>(); |
|
200 | 202 |
Iterator<Integer> it = transactions.values().iterator(); |
201 | 203 |
for (int i = 0; it.hasNext(); i++) |
202 | 204 |
{ |
... | ... | |
205 | 207 |
buf.append(','); |
206 | 208 |
} |
207 | 209 |
|
208 |
buf.append(it.next()); |
|
210 |
args.add(it.next()); |
|
211 |
buf.append('?'); |
|
209 | 212 |
} |
210 | 213 |
buf.append(')'); |
211 |
int delCounter = p.executeSQL(buf.toString()); |
|
214 |
int delCounter = p.executeSQL(buf.toString(), args.toArray());
|
|
212 | 215 |
if (LOG.isLoggable(Level.FINE)) |
213 | 216 |
{ |
214 | 217 |
LOG.log(Level.FINE, "Dropped " + delCounter + " old _trans records from " + dbName); |
new/src/com/goldencode/p2j/persist/sequence/H2SequenceHandler.java 2023-01-09 11:09:28 +0000 | ||
---|---|---|
16 | 16 |
** 007 ECF 20180219 Reduce Hibernate session flushing, if possible. |
17 | 17 |
** 008 OM 20200906 New ORM implementation. |
18 | 18 |
** OM 20220531 Fixed an error message. |
19 |
** RAA 20230109 Changed inline statement(s) to prepared statement(s). |
|
19 | 20 |
*/ |
20 | 21 | |
21 | 22 |
/* |
... | ... | |
141 | 142 |
|
142 | 143 |
Persistence persistence = ConnectionManager.getPersistence(ldbName); |
143 | 144 |
Dialect dialect = persistence.getDialect(); |
144 |
String strQuery = dialect.getSequenceCurrValString(seqName); |
|
145 |
Object[] args = new Object[] {seqName}; |
|
146 |
String strQuery = dialect.getSequenceCurrValString(); |
|
145 | 147 |
int64 ret; |
146 | 148 |
|
147 | 149 |
try |
148 | 150 |
{ |
149 |
ret = getResultValue(persistence.getSingleSQLResult(strQuery, null));
|
|
151 |
ret = getResultValue(persistence.getSingleSQLResult(strQuery, args));
|
|
150 | 152 |
} |
151 | 153 |
catch (PersistenceException pe) |
152 | 154 |
{ |
... | ... | |
366 | 368 |
|
367 | 369 |
Persistence persistence = ConnectionManager.getPersistence(ldbName); |
368 | 370 |
Dialect dialect = persistence.getDialect(); |
369 |
String strQuery = dialect.getSequenceSetValString(seqName, newValFixed); |
|
371 |
Object[] args = new Object[] {newValFixed}; |
|
372 |
String strQuery = dialect.getSequenceSetValString(seqName); |
|
370 | 373 |
|
371 | 374 |
try |
372 | 375 |
{ |
373 |
persistence.executeSQL(strQuery); |
|
376 |
persistence.executeSQL(strQuery, args);
|
|
374 | 377 |
} |
375 | 378 |
catch (PersistenceException pe) |
376 | 379 |
{ |
new/src/com/goldencode/p2j/persist/sequence/PostgreSQLSequenceHandler.java 2023-01-09 11:13:22 +0000 | ||
---|---|---|
19 | 19 |
** OM 20220531 Fixed an error message. |
20 | 20 |
** CA 20221014 Keep a lowercase map of crtSeqList sequence keys, as the change in |
21 | 21 |
** SequenceManager.legacyMap will always load all sequences. |
22 |
** RAA 20230109 Changed inline statement(s) to prepared statement(s). |
|
22 | 23 |
*/ |
23 | 24 | |
24 | 25 |
/* |
... | ... | |
285 | 286 |
|
286 | 287 |
Persistence persistence = ConnectionManager.getPersistence(ldbName); |
287 | 288 |
Dialect dialect = persistence.getDialect(); |
288 |
String setCrtValQuery = dialect.getSequenceSetValString(seqName, newVal); |
|
289 |
Object[] args = new Object[] {seqName, newVal}; |
|
290 |
String setCrtValQuery = dialect.getSequenceSetValString(); |
|
289 | 291 |
|
290 | 292 |
try |
291 | 293 |
{ |
292 |
persistence.getSingleSQLResult(setCrtValQuery, null);
|
|
294 |
persistence.getSingleSQLResult(setCrtValQuery, args);
|
|
293 | 295 |
} |
294 | 296 |
catch (PersistenceException pe) |
295 | 297 |
{ |
new/src/com/goldencode/p2j/report/ReportWorker.java 2023-01-09 11:16:04 +0000 | ||
---|---|---|
174 | 174 |
** the latest version of H2). |
175 | 175 |
** CA 20211214 The AST manager plugin must be context-local, for runtime conversion, as the |
176 | 176 |
** InMemoryRegistryPlugin is not thread-safe. |
177 |
** RAA 20230109 Changed inline statement(s) to prepared statement(s). |
|
177 | 178 |
*/ |
178 | 179 | |
179 | 180 |
/* |
... | ... | |
453 | 454 |
|
454 | 455 |
// read back the id that was autogenerated |
455 | 456 |
ResultSet rs = stmtReportInsert.getGeneratedKeys(); |
457 |
PreparedStatement stmt = null; |
|
456 | 458 |
rs.next(); |
457 | 459 |
rpt.id = rs.getLong(1); |
460 |
List<Object> args = new ArrayList<>(); |
|
458 | 461 |
|
459 | 462 |
if (processTags && rpt.tags != null && !rpt.tags.isEmpty()) |
460 | 463 |
{ |
461 |
StringBuilder buf = new StringBuilder("select id, name from tag where name in('");
|
|
464 |
StringBuilder buf = new StringBuilder("select id, name from tag where name in("); |
|
462 | 465 |
Iterator<String> iter = rpt.tags.iterator(); |
463 | 466 |
for (int i = 0; iter.hasNext(); i++) |
464 | 467 |
{ |
465 | 468 |
if (i > 0) |
466 | 469 |
{ |
467 |
buf.append("', '");
|
|
470 |
buf.append(", ");
|
|
468 | 471 |
} |
469 | 472 |
String tag = iter.next(); |
470 | 473 |
tag.replaceAll("\'", "\\\'"); |
471 |
buf.append(tag); |
|
474 |
buf.append("?"); |
|
475 |
args.add(tag); |
|
472 | 476 |
} |
473 |
buf.append("')");
|
|
477 |
buf.append(")"); |
|
474 | 478 |
String sql = buf.toString(); |
475 | 479 |
|
476 | 480 |
Map<String, Long> tagMap = new HashMap<>(); |
477 |
Statement stmt = connection.createStatement(); |
|
478 |
rs = stmt.executeQuery(sql); |
|
481 |
stmt = connection.prepareStatement(sql); |
|
482 |
for (int i = 0; i < args.size(); i++) |
|
483 |
{ |
|
484 |
stmt.setObject(i + 1, args.get(i)); |
|
485 |
} |
|
486 |
|
|
487 |
rs = stmt.executeQuery(); |
|
479 | 488 |
while (rs.next()) |
480 | 489 |
{ |
481 | 490 |
long tid = rs.getLong(1); |
... | ... | |
509 | 518 |
stmtRptTagInsert.clearParameters(); |
510 | 519 |
} |
511 | 520 |
} |
521 |
|
|
522 |
if (rs != null && !rs.isClosed()) |
|
523 |
{ |
|
524 |
rs.close(); |
|
525 |
} |
|
526 |
|
|
527 |
if (stmt != null && !stmt.isClosed()) |
|
528 |
{ |
|
529 |
stmt.close(); |
|
530 |
} |
|
512 | 531 |
} |
513 | 532 |
|
514 | 533 |
return rpt.id; |
new/src/com/goldencode/p2j/report/server/ReportApi.java 2023-01-09 11:23:14 +0000 | ||
---|---|---|
13 | 13 |
** version of H2). |
14 | 14 |
** OM 20220405 XmlFilePlugin can load either a file or a stream from application's jar. |
15 | 15 |
** DDF 20220823 Replaced .nextvalue with next value for. |
16 |
** RAA 20230109 Changed inline statement(s) to prepared statement(s). |
|
16 | 17 |
*/ |
17 | 18 | |
18 | 19 |
/* |
... | ... | |
745 | 746 |
*/ |
746 | 747 |
private static void applyFileFilter(Connection conn, Long profileId, long sessionId) |
747 | 748 |
{ |
748 |
try (Statement stmt = conn.createStatement()) |
|
749 |
PreparedStatement stmt = null; |
|
750 |
ResultSet rs = null; |
|
751 |
try |
|
749 | 752 |
{ |
750 | 753 |
String sql; |
751 |
ResultSet rs; |
|
752 | 754 |
|
753 | 755 |
if (profileId != null) |
754 | 756 |
{ |
755 | 757 |
// if profileId is null, the active_file was just created and is already empty; |
756 | 758 |
// otherwise, delete all its records in preparation for re-population with the new |
757 | 759 |
// filter profile's data |
758 |
stmt.execute("delete from active_file where sid = " + sessionId); |
|
760 |
stmt = conn.prepareStatement("delete from active_file where sid = ?"); |
|
761 |
stmt.setObject(1, sessionId); |
|
762 |
stmt.executeUpdate(); |
|
759 | 763 |
} |
760 | 764 |
|
761 | 765 |
// Query file specs and types for the provided file filter profile; we will compose a |
... | ... | |
763 | 767 |
// If provided profile id was null, get the default profile. |
764 | 768 |
|
765 | 769 |
int i; |
770 |
int type = 0; |
|
766 | 771 |
|
767 | 772 |
// wildcard path specs first |
768 | 773 |
|
... | ... | |
776 | 781 |
{ |
777 | 782 |
sql = "select f.spec from file_filter f " + |
778 | 783 |
"join filter_profile p on p.id = f.pid " + |
779 |
"where p.id = " + profileId + " and f.wild = true"; |
|
780 |
} |
|
781 |
rs = stmt.executeQuery(sql); |
|
784 |
"where p.id = ?" + " and f.wild = true"; |
|
785 |
type = 1; |
|
786 |
} |
|
787 |
|
|
788 |
if (stmt != null && !stmt.isClosed()) |
|
789 |
{ |
|
790 |
stmt.close(); |
|
791 |
} |
|
792 |
|
|
793 |
stmt = conn.prepareStatement(sql); |
|
794 |
if (type == 1) |
|
795 |
{ |
|
796 |
stmt.setObject(1, profileId); |
|
797 |
} |
|
798 |
|
|
799 |
type = 0; |
|
800 |
rs = stmt.executeQuery(); |
|
801 | ||
802 |
List<Object> args = new ArrayList<>(); |
|
782 | 803 |
|
783 | 804 |
StringBuilder buf = new StringBuilder("insert into active_file (fid, sid) "); |
784 | 805 |
for (i = 0; rs.next(); i++) |
... | ... | |
792 | 813 |
|
793 | 814 |
buf.append("select distinct(f.id), "); |
794 | 815 |
buf.append(sessionId); |
795 |
buf.append(" from file f join ast_map a on a.fid = f.id where f.name like '");
|
|
796 |
buf.append(dbs.escapeLikeRValue(spec));
|
|
797 |
buf.setCharAt(buf.length() - 1, '%');
|
|
798 |
buf.append("'");
|
|
816 |
buf.append(" from file f join ast_map a on a.fid = f.id where f.name like ?");
|
|
817 |
String arg1 = dbs.escapeLikeRValue(spec);
|
|
818 |
arg1 = arg1.substring(0, arg1.length() - 1) + '%';
|
|
819 |
args.add(arg1);
|
|
799 | 820 |
} |
800 | 821 |
|
801 | 822 |
if (profileId == null) |
... | ... | |
808 | 829 |
{ |
809 | 830 |
sql = "select f.spec from file_filter f " + |
810 | 831 |
"join filter_profile p on p.id = f.pid " + |
811 |
"where p.id = " + profileId + " and f.wild = false"; |
|
812 |
} |
|
813 |
rs = stmt.executeQuery(sql); |
|
832 |
"where p.id = ?" + " and f.wild = false"; |
|
833 |
type = 1; |
|
834 |
} |
|
835 |
|
|
836 |
if (rs != null && !rs.isClosed()) |
|
837 |
{ |
|
838 |
rs.close(); |
|
839 |
} |
|
840 |
|
|
841 |
if (stmt != null && !stmt.isClosed()) |
|
842 |
{ |
|
843 |
stmt.close(); |
|
844 |
} |
|
845 |
|
|
846 |
stmt = conn.prepareStatement(sql); |
|
847 |
if (type == 1) |
|
848 |
{ |
|
849 |
stmt.setObject(1, profileId); |
|
850 |
} |
|
851 |
|
|
852 |
type = 0; |
|
853 |
rs = stmt.executeQuery(); |
|
814 | 854 |
|
815 | 855 |
int j = 0; |
816 | 856 |
for (; rs.next(); i++) |
... | ... | |
833 | 873 |
buf.append(", "); |
834 | 874 |
} |
835 | 875 |
|
836 |
buf.append("'"); |
|
837 |
buf.append(spec); |
|
838 |
buf.append("'"); |
|
876 |
args.add(spec); |
|
839 | 877 |
|
840 | 878 |
if (++j == 100) |
841 | 879 |
{ |
... | ... | |
851 | 889 |
|
852 | 890 |
sql = buf.toString(); |
853 | 891 |
|
854 |
stmt.execute(sql); |
|
892 |
if (rs != null && !rs.isClosed()) |
|
893 |
{ |
|
894 |
rs.close(); |
|
895 |
} |
|
896 |
|
|
897 |
if (stmt != null && !stmt.isClosed()) |
|
898 |
{ |
|
899 |
stmt.close(); |
|
900 |
} |
|
901 |
|
|
902 |
stmt = conn.prepareStatement(sql); |
|
903 |
for (int k = 0; k < args.size();k++) |
|
904 |
{ |
|
905 |
stmt.setObject(k + 1, args.get(k)); |
|
906 |
} |
|
907 |
|
|
908 |
stmt.execute(); |
|
855 | 909 |
int uc = stmt.getUpdateCount(); |
856 | 910 |
System.out.println("applyActiveFile update count: " + uc); |
857 | 911 |
|
... | ... | |
873 | 927 |
|
874 | 928 |
throw new RuntimeException(exc); |
875 | 929 |
} |
930 |
finally |
|
931 |
{ |
|
932 |
try |
|
933 |
{ |
|
934 |
if (rs != null && !rs.isClosed()) |
|
935 |
{ |
|
936 |
rs.close(); |
|
937 |
} |
|
938 |
|
|
939 |
if (stmt != null && !stmt.isClosed()) |
|
940 |
{ |
|
941 |
stmt.close(); |
|
942 |
} |
|
943 |
} |
|
944 |
catch (SQLException e) |
|
945 |
{ |
|
946 |
e.printStackTrace(); |
|
947 |
} |
|
948 |
} |
|
876 | 949 |
} |
877 | 950 |
|
878 | 951 |
/** |
... | ... | |
2513 | 2586 |
buf.append("insert into search_history "); |
2514 | 2587 |
buf.append("select * from (select next value for seq_search_history_pk, '"); |
2515 | 2588 |
buf.append(criteria); |
2516 |
buf.append("' ) x where not exists (select 1 from search_history where criteria = '"); |
|
2517 |
buf.append(criteria); |
|
2518 |
buf.append("')"); |
|
2589 |
buf.append("' ) x where not exists (select 1 from search_history where criteria = ?)"); |
|
2590 |
Object histArg = criteria; |
|
2519 | 2591 |
String sqlInsSrchHist = buf.toString(); |
2520 | 2592 |
|
2521 | 2593 |
// compose sql to insert into user_search table, if not already present |
2522 | 2594 |
buf.setLength(0); |
2523 | 2595 |
buf.append("insert into user_search select * from (select "); |
2524 | 2596 |
buf.append(user.getId()); |
2525 |
buf.append(" as u, select id from search_history where criteria = '"); |
|
2526 |
buf.append(criteria); |
|
2527 |
buf.append("' as s) x where exists (select 1 from search_history where criteria = '"); |
|
2528 |
buf.append(criteria); |
|
2529 |
buf.append("') and not exists (select 1 from user_search where uid = x.u and sid = x.s)"); |
|
2597 |
buf.append(" as u, select id from search_history where criteria = ?"); |
|
2598 |
buf.append(" as s) x where exists (select 1 from search_history where criteria = ?"); |
|
2599 |
buf.append(") and not exists (select 1 from user_search where uid = x.u and sid = x.s)"); |
|
2600 |
Object usrArg = criteria; |
|
2530 | 2601 |
String sqlInsUsrSrch = buf.toString(); |
2531 | 2602 |
|
2532 |
try (Statement stmt = conn.createStatement()) |
|
2603 |
//tested with H2 1.4.200 and prepared statements now work with subselects |
|
2604 |
try (PreparedStatement stmt = conn.prepareStatement(sqlInsSrchHist)) |
|
2533 | 2605 |
{ |
2534 |
// we use Statement instead of PreparedStatement here because we need a substitution |
|
2535 |
// parameter in the select clauses of each statement, which H2 does not allow |
|
2536 |
stmt.execute(sqlInsSrchHist); |
|
2537 |
stmt.execute(sqlInsUsrSrch); |
|
2606 |
stmt.setObject(1, histArg); |
|
2607 |
stmt.execute(); |
|
2538 | 2608 |
} |
2609 |
|
|
2610 |
try (PreparedStatement stmt = conn.prepareStatement(sqlInsUsrSrch)) |
|
2611 |
{ |
|
2612 |
stmt.setObject(1, usrArg); |
|
2613 |
stmt.setObject(2, usrArg); |
|
2614 |
stmt.execute(); |
|
2615 |
} |
|
2539 | 2616 |
} |
2540 | 2617 |
|
2541 | 2618 |
/** |