KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > platform > database > InformixPlatform


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21 // Copyright (c) 1998, 2006, Oracle. All rights reserved.
22
package oracle.toplink.essentials.platform.database;
23
24 import java.io.*;
25 import java.util.*;
26 import oracle.toplink.essentials.exceptions.*;
27 import oracle.toplink.essentials.internal.helper.*;
28 import oracle.toplink.essentials.internal.databaseaccess.*;
29 import oracle.toplink.essentials.queryframework.*;
30
31 /**
32  * <p><b>Purpose</b>: Provides Informix specific behaviour.
33  * <p><b>Responsibilities</b>:<ul>
34  * <li> Types for schema creation.
35  * <li> Native sequencing using @@SERIAL.
36  * </ul>
37  *
38  * @since TOPLink/Java 1.0.1
39  */

40 public class InformixPlatform extends oracle.toplink.essentials.platform.database.DatabasePlatform {
41
42     /**
43      * INTERNAL:
44      * Answer a platform correct string representation of a Date, suitable for SQL generation.
45      * Native format: 'yyyy-mm-dd
46      */

47     protected void appendDate(java.sql.Date JavaDoc date, Writer writer) throws IOException {
48         if (usesNativeSQL()) {
49             writer.write("'");
50             writer.write(Helper.printDate(date));
51             writer.write("'");
52         } else {
53             super.appendDate(date, writer);
54         }
55     }
56
57     /**
58      * INTERNAL:
59      * Write a timestamp in Informix specific format (yyyy-mm-dd hh:mm:ss.fff).
60      */

61     protected void appendInformixTimestamp(java.sql.Timestamp JavaDoc timestamp, Writer writer) throws IOException {
62         writer.write("'");
63         writer.write(Helper.printTimestampWithoutNanos(timestamp));
64         writer.write('.');
65
66         // Must truncate the nanos to three decimal places,
67
// it is actually a complex algorithm...
68
String JavaDoc nanoString = Integer.toString(timestamp.getNanos());
69         int numberOfZeros = 0;
70         for (int num = Math.min(9 - nanoString.length(), 3); num > 0; num--) {
71             writer.write('0');
72             numberOfZeros++;
73         }
74         if ((nanoString.length() + numberOfZeros) > 3) {
75             nanoString = nanoString.substring(0, (3 - numberOfZeros));
76         }
77         writer.write(nanoString);
78         writer.write("'");
79     }
80
81     /**
82      * INTERNAL:
83      * Answer a platform correct string representation of a Calendar, suitable for SQL generation.
84      * The date is printed in the ODBC platform independent format {d'YYYY-MM-DD'}.
85      */

86     protected void appendCalendar(Calendar calendar, Writer writer) throws IOException {
87         if (usesNativeSQL()) {
88             appendInformixCalendar(calendar, writer);
89         } else {
90             super.appendCalendar(calendar, writer);
91         }
92     }
93
94     /**
95      * INTERNAL:
96      * Write a timestamp in Informix specific format ( yyyy-mm-dd hh:mm:ss.fff)
97      */

98     protected void appendInformixCalendar(Calendar calendar, Writer writer) throws IOException {
99         writer.write("'");
100         writer.write(Helper.printCalendar(calendar));
101         writer.write("'");
102     }
103
104     /**
105      * INTERNAL:
106      * Answer a platform correct string representation of a Time, suitable for SQL generation.
107      * The time is printed in the ODBC platform independent format {t'hh:mm:ss'}.
108      */

109     protected void appendTime(java.sql.Time JavaDoc time, Writer writer) throws IOException {
110         if (usesNativeSQL()) {
111             writer.write("'");
112             writer.write(Helper.printTime(time));
113             writer.write("'");
114         } else {
115             super.appendTime(time, writer);
116         }
117     }
118
119     /**
120      * INTERNAL:
121      * Answer a platform correct string representation of a Timestamp, suitable for SQL generation.
122      * The date is printed in the ODBC platform independent format {d'YYYY-MM-DD'}.
123      */

124     protected void appendTimestamp(java.sql.Timestamp JavaDoc timestamp, Writer writer) throws IOException {
125         if (usesNativeSQL()) {
126             appendInformixTimestamp(timestamp, writer);
127         } else {
128             super.appendTimestamp(timestamp, writer);
129         }
130     }
131
132     protected Hashtable buildFieldTypes() {
133         Hashtable fieldTypeMapping;
134
135         fieldTypeMapping = new Hashtable();
136         fieldTypeMapping.put(Boolean JavaDoc.class, new FieldTypeDefinition("SMALLINT default 0", false));
137
138         fieldTypeMapping.put(Integer JavaDoc.class, new FieldTypeDefinition("INTEGER", false));
139         fieldTypeMapping.put(Long JavaDoc.class, new FieldTypeDefinition("NUMERIC", 19));
140         fieldTypeMapping.put(Float JavaDoc.class, new FieldTypeDefinition("FLOAT(16)", false));
141         fieldTypeMapping.put(Double JavaDoc.class, new FieldTypeDefinition("FLOAT(32)", false));
142         fieldTypeMapping.put(Short JavaDoc.class, new FieldTypeDefinition("SMALLINT", false));
143         fieldTypeMapping.put(Byte JavaDoc.class, new FieldTypeDefinition("SMALLINT", false));
144         fieldTypeMapping.put(java.math.BigInteger JavaDoc.class, new FieldTypeDefinition("DECIMAL", 32));
145         fieldTypeMapping.put(java.math.BigDecimal JavaDoc.class, new FieldTypeDefinition("DECIMAL", 32).setLimits(32, -19, 19));
146         fieldTypeMapping.put(Number JavaDoc.class, new FieldTypeDefinition("DECIMAL", 32).setLimits(32, -19, 19));
147
148         fieldTypeMapping.put(String JavaDoc.class, new FieldTypeDefinition("VARCHAR", 255));
149         fieldTypeMapping.put(Character JavaDoc.class, new FieldTypeDefinition("CHAR", 1));
150         
151         fieldTypeMapping.put(Byte JavaDoc[].class, new FieldTypeDefinition("BYTE", false));
152         fieldTypeMapping.put(Character JavaDoc[].class, new FieldTypeDefinition("TEXT", false));
153         fieldTypeMapping.put(byte[].class, new FieldTypeDefinition("BYTE", false));
154         fieldTypeMapping.put(char[].class, new FieldTypeDefinition("TEXT", false));
155         fieldTypeMapping.put(java.sql.Blob JavaDoc.class, new FieldTypeDefinition("BYTE", false));
156         fieldTypeMapping.put(java.sql.Clob JavaDoc.class, new FieldTypeDefinition("TEXT", false));
157
158         fieldTypeMapping.put(java.sql.Date JavaDoc.class, new FieldTypeDefinition("DATE", false));
159         fieldTypeMapping.put(java.sql.Time JavaDoc.class, new FieldTypeDefinition("DATETIME HOUR TO SECOND", false));
160         fieldTypeMapping.put(java.sql.Timestamp JavaDoc.class, new FieldTypeDefinition("DATETIME YEAR TO FRACTION(5)", false));
161
162         return fieldTypeMapping;
163     }
164
165     /**
166      * INTERNAL:
167      * Build the identity query for native sequencing.
168      */

169     public ValueReadQuery buildSelectQueryForNativeSequence() {
170         ValueReadQuery selectQuery = new ValueReadQuery();
171         StringWriter writer = new StringWriter();
172         writer.write("SELECT DISTINCT(DBINFO('sqlca.sqlerrd1')) FROM systables");
173         selectQuery.setSQLString(writer.toString());
174         return selectQuery;
175     }
176
177     /**
178      * INTERNAL:
179      * returns the maximum number of characters that can be used in a field
180      * name on this platform.
181      */

182     public int getMaxFieldNameSize() {
183         return 18;
184     }
185
186     /**
187      * INTERNAL:
188      * Informix seems to like this syntax instead of the OF * syntax.
189      */

190     public String JavaDoc getSelectForUpdateString() {
191         return " FOR UPDATE";
192     }
193
194     public boolean isInformix() {
195         return true;
196     }
197
198     /**
199      * INTERNAL:
200      * Some database require outer joins to be given in the where clause, others require it in the from clause.
201      * Informix requires it in the from clause with no ON expression.
202      */

203     public boolean isInformixOuterJoin() {
204         return true;
205     }
206
207     /**
208      * INTERNAL:
209      * Builds a table of maximum numeric values keyed on java class. This is used for type testing but
210      * might also be useful to end users attempting to sanitize values.
211      * <p><b>NOTE</b>: BigInteger & BigDecimal maximums are dependent upon their precision & Scale
212      */

213     public Hashtable maximumNumericValues() {
214         Hashtable values = new Hashtable();
215
216         values.put(Integer JavaDoc.class, new Integer JavaDoc(Integer.MAX_VALUE));
217         values.put(Long JavaDoc.class, new Long JavaDoc(Long.MAX_VALUE));
218         values.put(Double JavaDoc.class, new Double JavaDoc((double)Float.MAX_VALUE));
219         values.put(Short JavaDoc.class, new Short JavaDoc(Short.MAX_VALUE));
220         values.put(Byte JavaDoc.class, new Byte JavaDoc(Byte.MAX_VALUE));
221         values.put(Float JavaDoc.class, new Float JavaDoc(Float.MAX_VALUE));
222         values.put(java.math.BigInteger JavaDoc.class, new java.math.BigInteger JavaDoc("99999999999999999999999999999999999999"));
223         values.put(java.math.BigDecimal JavaDoc.class, new java.math.BigDecimal JavaDoc("9999999999999999999.9999999999999999999"));
224         return values;
225     }
226
227     /**
228      * INTERNAL:
229      * Builds a table of minimum numeric values keyed on java class. This is used for type testing but
230      * might also be useful to end users attempting to sanitize values.
231      * <p><b>NOTE</b>: BigInteger & BigDecimal minimums are dependent upon their precision & Scale
232      */

233     public Hashtable minimumNumericValues() {
234         Hashtable values = new Hashtable();
235
236         values.put(Integer JavaDoc.class, new Integer JavaDoc(Integer.MIN_VALUE));
237         values.put(Long JavaDoc.class, new Long JavaDoc(Long.MIN_VALUE));
238         values.put(Double JavaDoc.class, new Double JavaDoc((double)1.4012984643247149E-44));// The double values are weird. They lose precision at E-45
239
values.put(Short JavaDoc.class, new Short JavaDoc(Short.MIN_VALUE));
240         values.put(Byte JavaDoc.class, new Byte JavaDoc(Byte.MIN_VALUE));
241         values.put(Float JavaDoc.class, new Float JavaDoc(Float.MIN_VALUE));
242         values.put(java.math.BigInteger JavaDoc.class, new java.math.BigInteger JavaDoc("-99999999999999999999999999999999999999"));
243         values.put(java.math.BigDecimal JavaDoc.class, new java.math.BigDecimal JavaDoc("-9999999999999999999.9999999999999999999"));
244         return values;
245     }
246
247     /**
248      * INTERNAL:
249      * Append the receiver's field serial constraint clause to a writer.
250      */

251     public void printFieldIdentityClause(Writer writer) throws ValidationException {
252         try {
253             writer.write(" SERIAL");
254         } catch (IOException ioException) {
255             throw ValidationException.fileError(ioException);
256         }
257     }
258
259     /**
260      * INTERNAL:
261      * USed for sp calls.
262      */

263     public boolean requiresProcedureCallBrackets() {
264         return false;
265     }
266
267     /**
268      * INTERNAL:
269      * If native sequencing is being used on Informix then the values must be
270      * retrieved after the insert.
271      * This method is to be used *ONLY* by sequencing classes
272      */

273     public boolean shouldNativeSequenceAcquireValueAfterInsert() {
274         return true;
275     }
276
277     /**
278      * INTERNAL:
279      * Some Platforms want the constraint name after the constraint definition.
280      */

281     public boolean shouldPrintConstraintNameAfter() {
282         return true;
283     }
284
285     /**
286      * INTERNAL:
287      * Some database require outer joins to be given in the where clause, others require it in the from clause.
288      */

289     public boolean shouldPrintOuterJoinInWhereClause() {
290         return false;
291     }
292
293     /**
294      * INTERNAL:
295      * Return true if the receiver uses host sequence numbers, generated on the database.
296      * Informix does this through SERIAL field types.
297      */

298     public boolean supportsNativeSequenceNumbers() {
299         return true;
300     }
301 }
302
Popular Tags