H2Dictionary.java.txt 7.0 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
package org.apache.openjpa.jdbc.sql;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Arrays;
import java.util.Locale;

import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.jdbc.kernel.exps.FilterValue;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.PrimaryKey;
import org.apache.openjpa.jdbc.schema.Table;
import org.apache.openjpa.jdbc.schema.Unique;
import org.apache.openjpa.meta.JavaTypes;

public class H2Dictionary extends DBDictionary {

    public H2Dictionary() {
        platform = "H2";
        validationSQL = "CALL 1";
        closePoolSQL = "SHUTDOWN";

        supportsAutoAssign = true;
        lastGeneratedKeyQuery = "CALL IDENTITY()";
        autoAssignClause = "IDENTITY";
        autoAssignTypeName = "INTEGER";
        nextSequenceQuery = "CALL NEXT VALUE FOR {0}";

33 34
        crossJoinClause = "CROSS JOIN";
        requiresConditionForCrossJoin = false;
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
        stringLengthFunction = "LENGTH({0})";
        trimLeadingFunction = "LTRIM({0})";
        trimTrailingFunction = "RTRIM({0})";
        trimBothFunction = "TRIM({0})";

        useSchemaName = true;
        supportsSelectForUpdate = true;
        supportsSelectStartIndex = true;
        supportsSelectEndIndex = true;
        rangePosition = RANGE_POST_LOCK;
        supportsDeferredConstraints = false;

        blobTypeName = "BLOB";
        doubleTypeName = "DOUBLE";

        supportsNullTableForGetPrimaryKeys = true;
        supportsNullTableForGetIndexInfo = true;

        requiresCastForMathFunctions = false;
        requiresCastForComparisons = false;

        reservedWordSet.addAll(Arrays.asList(new String[] { "CURRENT_TIMESTAMP", "CURRENT_TIME", "CURRENT_DATE", "CROSS", "DISTINCT", "EXCEPT", "EXISTS", "FROM", "FOR", "FALSE",
                "FULL", "GROUP", "HAVING", "INNER", "INTERSECT", "IS", "JOIN", "LIKE", "MINUS", "NATURAL", "NOT", "NULL", "ON", "ORDER", "PRIMARY", "ROWNUM", "SELECT", "SYSDATE",
                "SYSTIME", "SYSTIMESTAMP", "TODAY", "TRUE", "UNION", "WHERE" }));
    }

    public int getJDBCType(int metaTypeCode, boolean lob) {
        int type = super.getJDBCType(metaTypeCode, lob);
        switch (type) {
        case Types.BIGINT:
            if (metaTypeCode == JavaTypes.BIGINTEGER)
                return Types.NUMERIC;
            break;
        }
        return type;
    }

    public int getPreferredType(int type) {
        return super.getPreferredType(type);
    }

    public String[] getAddPrimaryKeySQL(PrimaryKey pk) {
        return new String[0];
    }

    public String[] getDropPrimaryKeySQL(PrimaryKey pk) {
        return new String[0];
    }

    public String[] getAddColumnSQL(Column column) {
        return new String[] { "ALTER TABLE " + getFullName(column.getTable(), false) + " ADD COLUMN " + getDeclareColumnSQL(column, true) };
    }

    public String[] getCreateTableSQL(Table table) {
        StringBuffer buf = new StringBuffer();
        buf.append("CREATE TABLE ").append(getFullName(table, false)).append(" (");

        Column[] cols = table.getColumns();
        for (int i = 0; i < cols.length; i++) {
            if (i > 0)
                buf.append(", ");
            buf.append(getDeclareColumnSQL(cols[i], false));
        }

        PrimaryKey pk = table.getPrimaryKey();
        String pkStr;
        if (pk != null) {
            pkStr = getPrimaryKeyConstraintSQL(pk);
            if (!StringUtils.isEmpty(pkStr))
                buf.append(", ").append(pkStr);
        }

        Unique[] uniques = table.getUniques();
        String uniqueStr;
        for (int i = 0; i < uniques.length; i++) {
            uniqueStr = getUniqueConstraintSQL(uniques[i]);
            if (uniqueStr != null)
                buf.append(", ").append(uniqueStr);
        }

        buf.append(")");
        return new String[] { buf.toString() };
    }

    protected String getPrimaryKeyConstraintSQL(PrimaryKey pk) {
        Column[] cols = pk.getColumns();
        if (cols.length == 1 && cols[0].isAutoAssigned())
            return null;
        return super.getPrimaryKeyConstraintSQL(pk);
    }

    public boolean isSystemIndex(String name, Table table) {
        return name.toUpperCase(Locale.ENGLISH).startsWith("SYSTEM_");
    }

    protected String getSequencesSQL(String schemaName, String sequenceName) {
        StringBuffer buf = new StringBuffer();
        buf.append("SELECT SEQUENCE_SCHEMA, SEQUENCE_NAME FROM ").append("INFORMATION_SCHEMA.SEQUENCES");
        if (schemaName != null || sequenceName != null)
            buf.append(" WHERE ");
        if (schemaName != null) {
            buf.append("SEQUENCE_SCHEMA = ?");
            if (sequenceName != null)
                buf.append(" AND ");
        }
        if (sequenceName != null)
            buf.append("SEQUENCE_NAME = ?");
        return buf.toString();
    }

    protected SQLBuffer toOperation(String op, SQLBuffer selects, SQLBuffer from, SQLBuffer where, SQLBuffer group, SQLBuffer having, SQLBuffer order, boolean distinct,
            boolean forUpdate, long start, long end) {
        return super.toOperation(op, selects, from, where, group, having, order, distinct, forUpdate, start, end);
    }

    public Column[] getColumns(DatabaseMetaData meta, String catalog, String schemaName, String tableName, String columnName, Connection conn) throws SQLException {
        Column[] cols = super.getColumns(meta, catalog, schemaName, tableName, columnName, conn);
        return cols;
    }

    public void setDouble(PreparedStatement stat, int idx, double val, Column col) throws SQLException {
        super.setDouble(stat, idx, val, col);
    }

    public void setBigDecimal(PreparedStatement stat, int idx, BigDecimal val, Column col) throws SQLException {
        super.setBigDecimal(stat, idx, val, col);
    }

    protected void appendSelectRange(SQLBuffer buf, long start, long end) {
        if (end != Long.MAX_VALUE)
            buf.append(" LIMIT ").appendValue(end - start);
        if (start != 0)
            buf.append(" OFFSET ").appendValue(start);
    }

    public void substring(SQLBuffer buf, FilterValue str, FilterValue start, FilterValue end) {
        buf.append("SUBSTR(");
        str.appendTo(buf);
        buf.append(", (");
        start.appendTo(buf);
        buf.append(" + 1)");
        if (end != null) {
            buf.append(", (");
            end.appendTo(buf);
            buf.append(" - ");
            start.appendTo(buf);
            buf.append(")");
        }
        buf.append(")");
    }

    public void indexOf(SQLBuffer buf, FilterValue str, FilterValue find, FilterValue start) {
        buf.append("(POSITION(");
        find.appendTo(buf);
        buf.append(" IN ");
        if (start != null)
            substring(buf, str, start, null);
        else
            str.appendTo(buf);
        buf.append(") - 1");
        if (start != null) {
            buf.append(" + ");
            start.appendTo(buf);
        }
        buf.append(")");
    }

}