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 33 34 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 203 204 205 206 207
|
/*
* Copyright (c) 1998, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.platform.database;
import java.io.*;
import java.util.*;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.internal.databaseaccess.FieldTypeDefinition;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.queries.ValueReadQuery;
import org.eclipse.persistence.tools.schemaframework.FieldDefinition;
/**
* <p><b>Purpose</b>: Provides Microsoft Access specific behavior.
*
* @since TOPLink/Java 1.0
*/
public class AccessPlatform extends org.eclipse.persistence.platform.database.DatabasePlatform {
protected Map<String, Class> buildClassTypes() {
Map<String, Class> classTypeMapping = super.buildClassTypes();
// In access LONG means numeric not CLOB like in Oracle
classTypeMapping.put("LONG", Long.class);
classTypeMapping.put("TEXT", String.class);
return classTypeMapping;
}
protected Hashtable buildFieldTypes() {
Hashtable fieldTypeMapping;
fieldTypeMapping = new Hashtable();
fieldTypeMapping.put(Boolean.class, new FieldTypeDefinition("BIT", false));
fieldTypeMapping.put(Integer.class, new FieldTypeDefinition("LONG", false));
fieldTypeMapping.put(Long.class, new FieldTypeDefinition("DOUBLE", false));
fieldTypeMapping.put(Float.class, new FieldTypeDefinition("DOUBLE", false));
fieldTypeMapping.put(Double.class, new FieldTypeDefinition("DOUBLE", false));
fieldTypeMapping.put(Short.class, new FieldTypeDefinition("SHORT", false));
fieldTypeMapping.put(Byte.class, new FieldTypeDefinition("BYTE", false));
fieldTypeMapping.put(java.math.BigInteger.class, new FieldTypeDefinition("DOUBLE", false));
fieldTypeMapping.put(java.math.BigDecimal.class, new FieldTypeDefinition("DOUBLE", false));
fieldTypeMapping.put(Number.class, new FieldTypeDefinition("DOUBLE", false));
fieldTypeMapping.put(String.class, new FieldTypeDefinition("TEXT", DEFAULT_VARCHAR_SIZE));
fieldTypeMapping.put(Character.class, new FieldTypeDefinition("TEXT", 1));
fieldTypeMapping.put(Byte[].class, new FieldTypeDefinition("LONGBINARY", false));
fieldTypeMapping.put(Character[].class, new FieldTypeDefinition("MEMO", false));
fieldTypeMapping.put(byte[].class, new FieldTypeDefinition("LONGBINARY", false));
fieldTypeMapping.put(char[].class, new FieldTypeDefinition("MEMO", false));
fieldTypeMapping.put(java.sql.Blob.class, new FieldTypeDefinition("LONGBINARY", false));
fieldTypeMapping.put(java.sql.Clob.class, new FieldTypeDefinition("MEMO", false));
fieldTypeMapping.put(java.sql.Date.class, new FieldTypeDefinition("DATETIME", false));
fieldTypeMapping.put(java.sql.Time.class, new FieldTypeDefinition("DATETIME", false));
fieldTypeMapping.put(java.sql.Timestamp.class, new FieldTypeDefinition("DATETIME", false));
return fieldTypeMapping;
}
/**
* INTERNAL:
* returns the maximum number of characters that can be used in a field
* name on this platform.
*/
public int getMaxFieldNameSize() {
return 64;
}
/**
* Access do not support millisecond well, truncate the millisecond from the timestamp
*/
public java.sql.Timestamp getTimestampFromServer(AbstractSession session, String sessionName) {
if (getTimestampQuery() == null) {
java.sql.Timestamp currentTime = new java.sql.Timestamp(System.currentTimeMillis());
currentTime.setNanos(0);
return currentTime;
} else {
getTimestampQuery().setSessionName(sessionName);
return (java.sql.Timestamp)session.executeQuery(getTimestampQuery());
}
}
/**
* Initialize any platform-specific operators
*/
protected void initializePlatformOperators() {
super.initializePlatformOperators();
addOperator(ExpressionOperator.simpleFunction(ExpressionOperator.ToUpperCase, "UCASE"));
addOperator(ExpressionOperator.simpleFunction(ExpressionOperator.ToLowerCase, "LCASE"));
}
public boolean isAccess() {
return true;
}
/**
* Builds a table of maximum numeric values keyed on java class. This is used for type testing but
* might also be useful to end users attempting to sanitize values.
* <p><b>NOTE</b>: BigInteger {@literal &} BigDecimal maximums are dependent upon their precision {@literal &} Scale
*/
public Hashtable maximumNumericValues() {
Hashtable values = new Hashtable();
values.put(Integer.class, Integer.valueOf(Integer.MAX_VALUE));
values.put(Long.class, Long.valueOf(Long.MAX_VALUE));
values.put(Double.class, Double.valueOf(Double.MAX_VALUE));
values.put(Short.class, Short.valueOf(Short.MAX_VALUE));
values.put(Byte.class, Byte.valueOf(Byte.MAX_VALUE));
values.put(Float.class, Float.valueOf(123456789));
values.put(java.math.BigInteger.class, new java.math.BigInteger("999999999999999"));
values.put(java.math.BigDecimal.class, new java.math.BigDecimal("99999999999999999999.9999999999999999999"));
return values;
}
/**
* Builds a table of minimum numeric values keyed on java class. This is used for type testing but
* might also be useful to end users attempting to sanitize values.
* <p><b>NOTE</b>: BigInteger {@literal &} BigDecimal minimums are dependent upon their precision {@literal &} Scale
*/
public Hashtable minimumNumericValues() {
Hashtable values = new Hashtable();
values.put(Integer.class, Integer.valueOf(Integer.MIN_VALUE));
values.put(Long.class, Long.valueOf(Long.MIN_VALUE));
values.put(Double.class, Double.valueOf(Double.MIN_VALUE));
values.put(Short.class, Short.valueOf(Short.MIN_VALUE));
values.put(Byte.class, Byte.valueOf(Byte.MIN_VALUE));
values.put(Float.class, Float.valueOf(-123456789));
values.put(java.math.BigInteger.class, new java.math.BigInteger("-999999999999999"));
values.put(java.math.BigDecimal.class, new java.math.BigDecimal("-9999999999999999999.9999999999999999999"));
return values;
}
/**
* This is used as some databases create the primary key constraint differently, i.e. Access.
*/
public boolean requiresNamedPrimaryKeyConstraints() {
return true;
}
/**
* JDBC defines and outer join syntax, many drivers do not support this. So we normally avoid it.
*/
public boolean shouldUseJDBCOuterJoinSyntax() {
return false;
}
/**
* INTERNAL: Build the identity query for native sequencing.
*/
public ValueReadQuery buildSelectQueryForIdentity() {
ValueReadQuery selectQuery = new ValueReadQuery();
StringWriter writer = new StringWriter();
writer.write("SELECT @@IDENTITY");
selectQuery.setSQLString(writer.toString());
return selectQuery;
}
/** Append the receiver's field 'identity' constraint clause to a writer. */
public void printFieldIdentityClause(Writer writer) throws ValidationException {
try {
writer.write(" COUNTER");
} catch (IOException ioException) {
throw ValidationException.fileError(ioException);
}
}
/**
* INTERNAL: Indicates whether the platform supports identity. Sybase does
* through IDENTITY field types. This method is to be used *ONLY* by
* sequencing classes
*/
public boolean supportsIdentity() {
return true;
}
public void printFieldTypeSize(Writer writer, FieldDefinition field,FieldTypeDefinition fieldType, boolean shouldPrintFieldIdentityClause) throws IOException {
if (!shouldPrintFieldIdentityClause) {
super.printFieldTypeSize(writer, field, fieldType,
shouldPrintFieldIdentityClause);
}
}
public void printFieldUnique(Writer writer, boolean shouldPrintFieldIdentityClause) throws IOException {
if (!shouldPrintFieldIdentityClause) {
super.printFieldUnique(writer, shouldPrintFieldIdentityClause);
}
}
}
|