OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 142 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 142 Rev 182
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 15... Line 15...
15
 
15
 
16
import org.openconcerto.sql.model.SQLField.Properties;
16
import org.openconcerto.sql.model.SQLField.Properties;
17
import org.openconcerto.sql.model.graph.TablesMap;
17
import org.openconcerto.sql.model.graph.TablesMap;
18
import org.openconcerto.sql.utils.ChangeTable.ClauseType;
18
import org.openconcerto.sql.utils.ChangeTable.ClauseType;
19
import org.openconcerto.sql.utils.SQLUtils;
19
import org.openconcerto.sql.utils.SQLUtils;
-
 
20
import org.openconcerto.utils.CollectionUtils;
20
import org.openconcerto.utils.ListMap;
21
import org.openconcerto.utils.ListMap;
21
import org.openconcerto.utils.NetUtils;
-
 
22
import org.openconcerto.utils.Tuple2;
22
import org.openconcerto.utils.Tuple2;
-
 
23
import org.openconcerto.utils.cc.ITransformer;
-
 
24
import org.openconcerto.utils.cc.Transformer;
-
 
25
import org.openconcerto.xml.XMLCodecUtils;
23
 
26
 
-
 
27
import java.beans.DefaultPersistenceDelegate;
24
import java.io.File;
28
import java.io.File;
25
import java.math.BigDecimal;
29
import java.math.BigDecimal;
26
import java.sql.Blob;
30
import java.sql.Blob;
27
import java.sql.Clob;
31
import java.sql.Clob;
28
import java.sql.SQLException;
32
import java.sql.SQLException;
29
import java.sql.Timestamp;
33
import java.sql.Timestamp;
30
import java.util.ArrayList;
34
import java.util.ArrayList;
-
 
35
import java.util.Arrays;
31
import java.util.IdentityHashMap;
36
import java.util.IdentityHashMap;
32
import java.util.List;
37
import java.util.List;
33
import java.util.Map;
38
import java.util.Map;
34
import java.util.Set;
39
import java.util.Set;
35
 
40
 
36
import org.h2.constant.ErrorCode;
41
import org.h2.constant.ErrorCode;
37
 
42
 
38
class SQLSyntaxH2 extends SQLSyntax {
43
public class SQLSyntaxH2 extends SQLSyntax {
39
 
44
 
40
    static protected final IdentityHashMap<String, String> DATE_SPECS;
45
    static protected final IdentityHashMap<String, String> DATE_SPECS;
41
 
46
 
42
    static {
47
    static {
43
        DATE_SPECS = new IdentityHashMap<String, String>(DateProp.JAVA_DATE_SPECS_PURE);
48
        DATE_SPECS = new IdentityHashMap<String, String>(DateProp.JAVA_DATE_SPECS_PURE);
44
        DATE_SPECS.put(DateProp.MICROSECOND, "SSS000");
49
        DATE_SPECS.put(DateProp.MICROSECOND, "SSS000");
-
 
50
 
-
 
51
        XMLCodecUtils.register(SQLSyntaxH2.class, new DefaultPersistenceDelegate(new String[] {}));
45
    }
52
    }
46
 
53
 
-
 
54
    final static SQLSyntax create(DBSystemRoot sysRoot) {
-
 
55
        boolean standardArray = true;
-
 
56
        if (sysRoot != null) {
47
    SQLSyntaxH2() {
57
            try {
-
 
58
                standardArray = Arrays.equals(new String[] { "foo" }, (Object[]) sysRoot.getDataSource().executeScalar("SELECT ARRAY['foo']"));
-
 
59
            } catch (RuntimeException e) {
-
 
60
                if (SQLUtils.findWithSQLState(e).getErrorCode() == ErrorCode.COLUMN_NOT_FOUND_1)
-
 
61
                    standardArray = false;
-
 
62
                else
-
 
63
                    throw e;
-
 
64
            }
-
 
65
        }
-
 
66
        return new SQLSyntaxH2(standardArray);
-
 
67
    }
-
 
68
 
-
 
69
    private final boolean standardArray;
-
 
70
 
-
 
71
    public SQLSyntaxH2(final boolean standardArray) {
48
        super(SQLSystem.H2, DATE_SPECS);
72
        super(SQLSystem.H2, DATE_SPECS);
-
 
73
        this.standardArray = standardArray;
49
        this.typeNames.addAll(Boolean.class, "boolean", "bool", "bit");
74
        this.typeNames.addAll(Boolean.class, "boolean", "bool", "bit");
50
        this.typeNames.addAll(Integer.class, "integer", "int", "int4", "mediumint");
75
        this.typeNames.addAll(Integer.class, "integer", "int", "int4", "mediumint");
51
        this.typeNames.addAll(Byte.class, "tinyint");
76
        this.typeNames.addAll(Byte.class, "tinyint");
52
        this.typeNames.addAll(Short.class, "smallint", "int2");
77
        this.typeNames.addAll(Short.class, "smallint", "int2");
53
        this.typeNames.addAll(Long.class, "bigint", "int8");
78
        this.typeNames.addAll(Long.class, "bigint", "int8");
Line 187... Line 212...
187
        final String quotedSel = quoteString(SQLSyntaxPG.selectAll(t).asString());
212
        final String quotedSel = quoteString(SQLSyntaxPG.selectAll(t).asString());
188
        t.getBase().getDataSource().execute("CALL CSVWRITE(" + quotedPath + ", " + quotedSel + ", 'UTF8', ',', '\"', '\\', '\\N', '\n');");
213
        t.getBase().getDataSource().execute("CALL CSVWRITE(" + quotedPath + ", " + quotedSel + ", 'UTF8', ',', '\"', '\\', '\\N', '\n');");
189
    }
214
    }
190
 
215
 
191
    @Override
216
    @Override
192
    protected boolean isServerLocalhost(SQLServer s) {
-
 
193
        return s.getName().startsWith("mem") || s.getName().startsWith("file") || NetUtils.isSelfAddr(getAddr(s));
-
 
194
    }
-
 
195
 
-
 
196
    private String getAddr(SQLServer s) {
-
 
197
        if (s.getName().startsWith("tcp") || s.getName().startsWith("ssl")) {
-
 
198
            final int startIndex = "tcp://".length();
-
 
199
            final int endIndex = s.getName().indexOf('/', startIndex);
-
 
200
            return s.getName().substring(startIndex, endIndex < 0 ? s.getName().length() : endIndex);
-
 
201
        } else
-
 
202
            return null;
-
 
203
    }
-
 
204
 
-
 
205
    @Override
-
 
206
    public String getCreateSynonym(SQLTable t, SQLName newName) {
217
    public String getCreateSynonym(SQLTable t, SQLName newName) {
207
        return null;
218
        return null;
208
    }
219
    }
209
 
220
 
210
    @Override
221
    @Override
Line 322... Line 333...
322
        // in MVCC, if two transactions modify the same row the second one will repeatedly throw
333
        // in MVCC, if two transactions modify the same row the second one will repeatedly throw
323
        // CONCURRENT_UPDATE_1 until LockTimeout
334
        // CONCURRENT_UPDATE_1 until LockTimeout
324
        // otherwise, the second one will timeout while waiting for the table lock
335
        // otherwise, the second one will timeout while waiting for the table lock
325
        return stateExn.getErrorCode() == ErrorCode.DEADLOCK_1 || stateExn.getErrorCode() == ErrorCode.LOCK_TIMEOUT_1;
336
        return stateExn.getErrorCode() == ErrorCode.DEADLOCK_1 || stateExn.getErrorCode() == ErrorCode.LOCK_TIMEOUT_1;
326
    }
337
    }
-
 
338
 
-
 
339
    @Override
-
 
340
    public boolean isTableNotFoundException(Exception exn) {
-
 
341
        final SQLException stateExn = SQLUtils.findWithSQLState(exn);
-
 
342
        return stateExn.getErrorCode() == ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1 || stateExn.getErrorCode() == ErrorCode.SCHEMA_NOT_FOUND_1;
-
 
343
    }
-
 
344
 
-
 
345
    @Override
-
 
346
    public String getSessionIDExpression() {
-
 
347
        return "SESSION_ID()";
-
 
348
    }
-
 
349
 
-
 
350
    @Override
-
 
351
    public String getSessionsQuery(final DBSystemRoot sysRoot, final boolean includeSelf) {
-
 
352
        final String allRows = "SELECT \"ID\", \"STATEMENT\" as \"QUERY\", \"USER_NAME\" FROM INFORMATION_SCHEMA.SESSIONS";
-
 
353
        if (includeSelf)
-
 
354
            return allRows;
-
 
355
        return allRows + " WHERE \"ID\" != " + this.getSessionIDExpression();
-
 
356
    }
-
 
357
 
-
 
358
    @Override
-
 
359
    public String getVersionFunction() {
-
 
360
        return "H2VERSION()";
-
 
361
    }
-
 
362
 
-
 
363
    @Override
-
 
364
    public String getAllowConnectionsQuery(String sysRootName, final boolean allow) {
-
 
365
        return "SET EXCLUSIVE " + (allow ? "0" : "1");
-
 
366
    }
-
 
367
 
-
 
368
    @Override
-
 
369
    public boolean isConnectionDisallowedException(SQLException exn) {
-
 
370
        return exn.getErrorCode() == ErrorCode.DATABASE_IS_IN_EXCLUSIVE_MODE;
-
 
371
    }
-
 
372
 
-
 
373
    @Override
-
 
374
    public String getSQLArray(final List<String> sqlExpressions, final String type) {
-
 
375
        // H2 cannot specify type in SQL, so cast each item
-
 
376
        final ITransformer<? super String, ?> tf = type == null ? Transformer.nopTransformer() : (s) -> {
-
 
377
            return this.cast(s, type);
-
 
378
        };
-
 
379
        final String items = CollectionUtils.join(sqlExpressions, ", ", tf);
-
 
380
        if (this.standardArray) {
-
 
381
            return "ARRAY[" + items + ']';
-
 
382
        } else {
-
 
383
            // For the comma, see http://h2database.com/html/grammar.html#array
-
 
384
            return '(' + items + (sqlExpressions.size() == 1 ? ",)" : ")");
-
 
385
        }
-
 
386
    }
-
 
387
 
-
 
388
    @Override
-
 
389
    public String getSQLArrayContains(String arrayExpression, String itemExpression) {
-
 
390
        return "ARRAY_CONTAINS(" + arrayExpression + ", " + itemExpression + ")";
-
 
391
    }
-
 
392
 
-
 
393
    @Override
-
 
394
    public String getSQLArrayLength(final String arrayExpression) {
-
 
395
        return "ARRAY_LENGTH(" + arrayExpression + ")";
-
 
396
    }
-
 
397
 
-
 
398
    @Override
-
 
399
    public String getSQLArrayConcat(final String arrayExpression, final String array2Expression) {
-
 
400
        return "array_cat(" + arrayExpression + ", " + array2Expression + ")";
-
 
401
    }
-
 
402
 
-
 
403
    @Override
-
 
404
    public String getSQLArrayAppend(final String arrayExpression, final String itemExpression) {
-
 
405
        return "array_append(" + arrayExpression + ", " + itemExpression + ")";
-
 
406
    }
-
 
407
 
-
 
408
    @Override
-
 
409
    public String getSQLArraySlice(final String arrayExpression, final String index1Expression, final String index2Expression) {
-
 
410
        return "ARRAY_SLICE(" + arrayExpression + ", " + index1Expression + ", " + index2Expression + ")";
-
 
411
    }
327
}
412
}