Line 1... |
Line 1... |
1 |
/*
|
1 |
/*
|
2 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
|
2 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
|
3 |
*
|
3 |
*
|
4 |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
|
4 |
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
|
5 |
*
|
5 |
*
|
6 |
* The contents of this file are subject to the terms of the GNU General Public License Version 3
|
6 |
* The contents of this file are subject to the terms of the GNU General Public License Version 3
|
7 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
|
7 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
|
8 |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
|
8 |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
|
9 |
* language governing permissions and limitations under the License.
|
9 |
* language governing permissions and limitations under the License.
|
Line 24... |
Line 24... |
24 |
import org.openconcerto.utils.FileUtils;
|
24 |
import org.openconcerto.utils.FileUtils;
|
25 |
import org.openconcerto.utils.ListMap;
|
25 |
import org.openconcerto.utils.ListMap;
|
26 |
import org.openconcerto.utils.StringUtils;
|
26 |
import org.openconcerto.utils.StringUtils;
|
27 |
import org.openconcerto.utils.Tuple2;
|
27 |
import org.openconcerto.utils.Tuple2;
|
28 |
import org.openconcerto.utils.cc.ITransformer;
|
28 |
import org.openconcerto.utils.cc.ITransformer;
|
- |
|
29 |
import org.openconcerto.xml.XMLCodecUtils;
|
29 |
|
30 |
|
- |
|
31 |
import java.beans.DefaultPersistenceDelegate;
|
30 |
import java.io.File;
|
32 |
import java.io.File;
|
31 |
import java.io.FileInputStream;
|
33 |
import java.io.FileInputStream;
|
32 |
import java.io.FileOutputStream;
|
34 |
import java.io.FileOutputStream;
|
33 |
import java.io.IOException;
|
35 |
import java.io.IOException;
|
34 |
import java.math.BigDecimal;
|
36 |
import java.math.BigDecimal;
|
Line 65... |
Line 67... |
65 |
* (already set up on Ubuntu).
|
67 |
* (already set up on Ubuntu).
|
66 |
* <p>
|
68 |
* <p>
|
67 |
*
|
69 |
*
|
68 |
* @author Sylvain CUAZ
|
70 |
* @author Sylvain CUAZ
|
69 |
*/
|
71 |
*/
|
70 |
class SQLSyntaxPG extends SQLSyntax {
|
72 |
public class SQLSyntaxPG extends SQLSyntax {
|
71 |
|
73 |
|
72 |
// From http://www.postgresql.org/docs/9.0/interactive/multibyte.html
|
74 |
// From http://www.postgresql.org/docs/9.0/interactive/multibyte.html
|
73 |
static final short MAX_BYTES_PER_CHAR = 4;
|
75 |
static final short MAX_BYTES_PER_CHAR = 4;
|
74 |
// http://www.postgresql.org/docs/9.0/interactive/datatype-character.html
|
76 |
// http://www.postgresql.org/docs/9.0/interactive/datatype-character.html
|
75 |
private static final short MAX_LENGTH_BYTES = 4;
|
77 |
private static final short MAX_LENGTH_BYTES = 4;
|
Line 89... |
Line 91... |
89 |
DATE_SPECS.put(DateProp.DAY_NAME_IN_WEEK, "TMday");
|
91 |
DATE_SPECS.put(DateProp.DAY_NAME_IN_WEEK, "TMday");
|
90 |
DATE_SPECS.put(DateProp.HOUR, "HH24");
|
92 |
DATE_SPECS.put(DateProp.HOUR, "HH24");
|
91 |
DATE_SPECS.put(DateProp.MINUTE, "MI");
|
93 |
DATE_SPECS.put(DateProp.MINUTE, "MI");
|
92 |
DATE_SPECS.put(DateProp.SECOND, "SS");
|
94 |
DATE_SPECS.put(DateProp.SECOND, "SS");
|
93 |
DATE_SPECS.put(DateProp.MICROSECOND, "US");
|
95 |
DATE_SPECS.put(DateProp.MICROSECOND, "US");
|
- |
|
96 |
|
- |
|
97 |
XMLCodecUtils.register(SQLSyntaxPG.class, new DefaultPersistenceDelegate(new String[] {}));
|
94 |
}
|
98 |
}
|
95 |
|
99 |
|
96 |
SQLSyntaxPG() {
|
100 |
public SQLSyntaxPG() {
|
97 |
super(SQLSystem.POSTGRESQL, DATE_SPECS);
|
101 |
super(SQLSystem.POSTGRESQL, DATE_SPECS);
|
98 |
this.typeNames.addAll(Boolean.class, "boolean", "bool", "bit");
|
102 |
this.typeNames.addAll(Boolean.class, "boolean", "bool", "bit");
|
99 |
this.typeNames.addAll(Short.class, "smallint", "int2");
|
103 |
this.typeNames.addAll(Short.class, "smallint", "int2");
|
100 |
this.typeNames.addAll(Integer.class, "integer", "int", "int4");
|
104 |
this.typeNames.addAll(Integer.class, "integer", "int", "int4");
|
101 |
this.typeNames.addAll(Long.class, "bigint", "int8");
|
105 |
this.typeNames.addAll(Long.class, "bigint", "int8");
|
Line 293... |
Line 297... |
293 |
@Override
|
297 |
@Override
|
294 |
public boolean isDeadLockException(SQLException exn) {
|
298 |
public boolean isDeadLockException(SQLException exn) {
|
295 |
return SQLUtils.findWithSQLState(exn).getSQLState().equals("40P01");
|
299 |
return SQLUtils.findWithSQLState(exn).getSQLState().equals("40P01");
|
296 |
}
|
300 |
}
|
297 |
|
301 |
|
- |
|
302 |
@Override
|
- |
|
303 |
public boolean isTableNotFoundException(Exception exn) {
|
- |
|
304 |
return SQLUtils.findWithSQLState(exn).getSQLState().equals("42P01");
|
- |
|
305 |
}
|
- |
|
306 |
|
- |
|
307 |
@Override
|
- |
|
308 |
public String getSetLockTimeoutQuery(int millis) {
|
- |
|
309 |
return "SET lock_timeout to " + millis;
|
- |
|
310 |
}
|
- |
|
311 |
|
- |
|
312 |
@Override
|
- |
|
313 |
public String getShowLockTimeoutQuery() {
|
- |
|
314 |
final String interval = cast("setting||unit", "INTERVAL");
|
- |
|
315 |
return "select CAST( EXTRACT(milliseconds from " + interval + ") as int) from pg_settings where \"name\" = 'lock_timeout'";
|
- |
|
316 |
}
|
- |
|
317 |
|
298 |
private static final Pattern NOW_PTRN = Pattern.compile("\\(?'now'::text\\)?(::timestamp)");
|
318 |
private static final Pattern NOW_PTRN = Pattern.compile("\\(?'now'::text\\)?(::timestamp)");
|
299 |
|
319 |
|
300 |
@Override
|
320 |
@Override
|
301 |
public String transfDefaultJDBC2SQL(SQLField f) {
|
321 |
public String transfDefaultJDBC2SQL(SQLField f) {
|
302 |
if (f.getDefaultValue() != null && Date.class.isAssignableFrom(f.getType().getJavaType())) {
|
322 |
if (f.getDefaultValue() != null && Date.class.isAssignableFrom(f.getType().getJavaType())) {
|
Line 562... |
Line 582... |
562 |
|
582 |
|
563 |
@Override
|
583 |
@Override
|
564 |
public String getDropTrigger(Trigger t) {
|
584 |
public String getDropTrigger(Trigger t) {
|
565 |
return "DROP TRIGGER " + SQLBase.quoteIdentifier(t.getName()) + " on " + t.getTable().getSQLName().quote();
|
585 |
return "DROP TRIGGER " + SQLBase.quoteIdentifier(t.getName()) + " on " + t.getTable().getSQLName().quote();
|
566 |
}
|
586 |
}
|
- |
|
587 |
|
- |
|
588 |
@Override
|
- |
|
589 |
public String getSessionIDExpression() {
|
- |
|
590 |
return "pg_backend_pid()";
|
- |
|
591 |
}
|
- |
|
592 |
|
- |
|
593 |
@Override
|
- |
|
594 |
public String getSessionsQuery(final DBSystemRoot sysRoot, final boolean includeSelf) {
|
- |
|
595 |
final String allRows = "SELECT pid as \"ID\", query as \"QUERY\", usename as \"USER_NAME\" FROM pg_stat_activity WHERE datname=" + quoteString(sysRoot.getName());
|
- |
|
596 |
if (includeSelf)
|
- |
|
597 |
return allRows;
|
- |
|
598 |
return allRows + " and pid != " + this.getSessionIDExpression();
|
- |
|
599 |
}
|
- |
|
600 |
|
- |
|
601 |
@Override
|
- |
|
602 |
public String getVersionFunction() {
|
- |
|
603 |
// shorter than version() : "PostgreSQL 9.6.9 on x86_64-pc-linux-gnu (Ubuntu
|
- |
|
604 |
// 9.6.9-2.pgdg16.04+1), compiled by gcc (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609,
|
- |
|
605 |
// 64-bit"
|
- |
|
606 |
return "current_setting('server_version')";
|
- |
|
607 |
}
|
- |
|
608 |
|
- |
|
609 |
@Override
|
- |
|
610 |
public String getAllowConnectionsQuery(String sysRootName, boolean allow) {
|
- |
|
611 |
// REVOKE CONNECT ON DATABASE "ControleKD" TO public : superusers can still connect
|
- |
|
612 |
|
- |
|
613 |
// to recover if all DB (even postgres and templates) run postgres --single
|
- |
|
614 |
// (single user / standalone mode ignores datallowconn)
|
- |
|
615 |
return "UPDATE pg_database SET datallowconn=" + SQLType.getBoolean(this).toString(allow) + " WHERE datname=" + quoteString(sysRootName);
|
- |
|
616 |
// "ALTER DATABASE WITH ALLOW_CONNECTIONS" isn't allowed on our own base
|
- |
|
617 |
}
|
- |
|
618 |
|
- |
|
619 |
@Override
|
- |
|
620 |
public boolean isConnectionDisallowedException(SQLException exn) {
|
- |
|
621 |
return "55000".equals(exn.getSQLState());
|
- |
|
622 |
}
|
- |
|
623 |
|
- |
|
624 |
@Override
|
- |
|
625 |
public String getSQLArray(final List<String> sqlExpressions, final String type) {
|
- |
|
626 |
if (type == null)
|
- |
|
627 |
return "ARRAY[" + CollectionUtils.join(sqlExpressions, ", ") + ']';
|
- |
|
628 |
else
|
- |
|
629 |
return this.quoteString('{' + CollectionUtils.join(sqlExpressions, ", ") + '}') + "::" + type + "[]";
|
- |
|
630 |
}
|
- |
|
631 |
|
- |
|
632 |
@Override
|
- |
|
633 |
public String getSQLArrayContains(String arrayExpression, String itemExpression) {
|
- |
|
634 |
return itemExpression + " = ANY(" + arrayExpression + ")";
|
- |
|
635 |
}
|
- |
|
636 |
|
- |
|
637 |
@Override
|
- |
|
638 |
public String getSQLArrayLength(final String arrayExpression) {
|
- |
|
639 |
return "ARRAY_LENGTH(" + arrayExpression + ", 1)";
|
- |
|
640 |
}
|
- |
|
641 |
|
- |
|
642 |
@Override
|
- |
|
643 |
public String getSQLArrayConcat(final String arrayExpression, final String array2Expression) {
|
- |
|
644 |
return "array_cat(" + arrayExpression + ", " + array2Expression + ")";
|
- |
|
645 |
}
|
- |
|
646 |
|
- |
|
647 |
@Override
|
- |
|
648 |
public String getSQLArrayAppend(final String arrayExpression, final String itemExpression) {
|
- |
|
649 |
// don't use || as it doesn't handle varchar literal
|
- |
|
650 |
return "array_append(" + arrayExpression + ", " + itemExpression + ")";
|
- |
|
651 |
}
|
- |
|
652 |
|
- |
|
653 |
@Override
|
- |
|
654 |
public String getSQLArraySlice(final String arrayExpression, final String index1Expression, final String index2Expression) {
|
- |
|
655 |
return '(' + arrayExpression + ")[" + index1Expression + ":" + index2Expression + "]";
|
- |
|
656 |
}
|
567 |
}
|
657 |
}
|