001: /*
002: * Copyright (C) 2006 Rob Manning
003: * manningr@users.sourceforge.net
004: *
005: * This program is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU General Public License
007: * as published by the Free Software Foundation; either version 2
008: * of the License, or any later version.
009: *
010: * This program is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013: * GNU General Public License for more details.
014: *
015: * You should have received a copy of the GNU General Public License
016: * along with this program; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
018: */
019: package net.sourceforge.squirrel_sql.fw.dialects;
020:
021: import java.sql.SQLException;
022: import java.sql.Types;
023: import java.util.List;
024:
025: import net.sourceforge.squirrel_sql.fw.sql.DatabaseObjectType;
026: import net.sourceforge.squirrel_sql.fw.sql.IDatabaseObjectInfo;
027: import net.sourceforge.squirrel_sql.fw.sql.ISQLDatabaseMetaData;
028: import net.sourceforge.squirrel_sql.fw.sql.ITableInfo;
029: import net.sourceforge.squirrel_sql.fw.sql.TableColumnInfo;
030:
031: /**
032: * An extension to the standard Hibernate Informix dialect
033: *
034: */
035: public class InformixDialect extends
036: org.hibernate.dialect.InformixDialect implements
037: HibernateDialect {
038:
039: public InformixDialect() {
040: super ();
041: registerColumnType(Types.BIGINT, "integer");
042: registerColumnType(Types.BINARY, "byte");
043: registerColumnType(Types.BIT, "smallint");
044: registerColumnType(Types.BLOB, "byte");
045: registerColumnType(Types.BOOLEAN, "smallint");
046: registerColumnType(Types.CHAR, 32511, "char($l)");
047: registerColumnType(Types.CHAR, "char(32511)");
048: registerColumnType(Types.CLOB, "text");
049: registerColumnType(Types.DATE, "date");
050: registerColumnType(Types.DECIMAL, "decimal($p,$s)");
051: registerColumnType(Types.DOUBLE, 15, "float($l)");
052: registerColumnType(Types.DOUBLE, "float(15)");
053: registerColumnType(Types.FLOAT, 15, "float($l)");
054: registerColumnType(Types.FLOAT, "float(15)");
055: registerColumnType(Types.INTEGER, "integer");
056: registerColumnType(Types.LONGVARBINARY, "byte");
057: registerColumnType(Types.LONGVARCHAR, "text");
058: registerColumnType(Types.NUMERIC, "numeric($p,$s)");
059: registerColumnType(Types.REAL, "real");
060: registerColumnType(Types.SMALLINT, "smallint");
061: registerColumnType(Types.TIME, "datetime hour to second");
062: registerColumnType(Types.TIMESTAMP, "datetime year to fraction");
063: registerColumnType(Types.TINYINT, "smallint");
064: registerColumnType(Types.VARBINARY, "byte");
065: registerColumnType(Types.VARCHAR, 255, "varchar($l)");
066: registerColumnType(Types.VARCHAR, "text");
067: }
068:
069: /*
070: * (non-Javadoc)
071: *
072: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#canPasteTo(net.sourceforge.squirrel_sql.fw.sql.DatabaseObjectType)
073: */
074: public boolean canPasteTo(IDatabaseObjectInfo info) {
075: if (info.getDatabaseObjectType() == DatabaseObjectType.SCHEMA) {
076: return true;
077: } else {
078: return false;
079: }
080: }
081:
082: /*
083: * (non-Javadoc)
084: *
085: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#supportsSchemasInTableDefinition()
086: */
087: public boolean supportsSchemasInTableDefinition() {
088: return true;
089: }
090:
091: /*
092: * (non-Javadoc)
093: *
094: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#getLengthFunction()
095: */
096: public String getLengthFunction(int dataType) {
097: return "length";
098: }
099:
100: /*
101: * (non-Javadoc)
102: *
103: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#getMaxFunction()
104: */
105: public String getMaxFunction() {
106: return "max";
107: }
108:
109: /*
110: * (non-Javadoc)
111: *
112: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#getMaxPrecision(int)
113: */
114: public int getMaxPrecision(int dataType) {
115: if (dataType == Types.DECIMAL || dataType == Types.NUMERIC) {
116: return 32;
117: }
118: if (dataType == Types.DOUBLE || dataType == Types.DOUBLE) {
119: return 16;
120: }
121: return 32;
122: }
123:
124: /*
125: * (non-Javadoc)
126: *
127: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#getMaxScale(int)
128: */
129: public int getMaxScale(int dataType) {
130: return getMaxPrecision(dataType);
131: }
132:
133: /*
134: * (non-Javadoc)
135: *
136: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#getPrecisionDigits(int,
137: * int)
138: */
139: public int getPrecisionDigits(int columnSize, int dataType) {
140: return columnSize;
141: }
142:
143: /*
144: * (non-Javadoc)
145: *
146: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#getColumnLength(int,
147: * int)
148: */
149: public int getColumnLength(int columnSize, int dataType) {
150: return columnSize;
151: }
152:
153: /**
154: * The string which identifies this dialect in the dialect chooser.
155: *
156: * @return a descriptive name that tells the user what database this dialect
157: * is design to work with.
158: */
159: public String getDisplayName() {
160: return "Informix";
161: }
162:
163: /**
164: * Returns boolean value indicating whether or not this dialect supports the
165: * specified database product/version.
166: *
167: * @param databaseProductName
168: * the name of the database as reported by
169: * DatabaseMetaData.getDatabaseProductName()
170: * @param databaseProductVersion
171: * the version of the database as reported by
172: * DatabaseMetaData.getDatabaseProductVersion()
173: * @return true if this dialect can be used for the specified product name
174: * and version; false otherwise.
175: */
176: public boolean supportsProduct(String databaseProductName,
177: String databaseProductVersion) {
178: if (databaseProductName == null) {
179: return false;
180: }
181: if (databaseProductName.toLowerCase().contains("informix")) {
182: // We don't yet have the need to discriminate by version.
183: return true;
184: }
185: return false;
186: }
187:
188: /**
189: * Returns the SQL statement to use to add a column to the specified table
190: * using the information about the new column specified by info.
191: *
192: * @param info
193: * information about the new column such as type, name, etc.
194: *
195: * @return
196: * @throws UnsupportedOperationException
197: * if the database doesn't support adding columns after a table
198: * has already been created.
199: */
200: public String[] getColumnAddSQL(TableColumnInfo info)
201: throws UnsupportedOperationException {
202: return new String[] { DialectUtils.getColumnAddSQL(info, this ,
203: true, false, true) };
204: }
205:
206: /**
207: * Returns a boolean value indicating whether or not this database dialect
208: * supports dropping columns from tables.
209: *
210: * @return true if the database supports dropping columns; false otherwise.
211: */
212: public boolean supportsDropColumn() {
213: return true;
214: }
215:
216: /**
217: * Returns the SQL that forms the command to drop the specified colum in the
218: * specified table.
219: *
220: * @param tableName
221: * the name of the table that has the column
222: * @param columnName
223: * the name of the column to drop.
224: * @return
225: * @throws UnsupportedOperationException
226: * if the database doesn't support dropping columns.
227: */
228: public String getColumnDropSQL(String tableName, String columnName) {
229: return DialectUtils.getColumnDropSQL(tableName, columnName);
230: }
231:
232: /**
233: * Returns the SQL that forms the command to drop the specified table. If
234: * cascade contraints is supported by the dialect and cascadeConstraints is
235: * true, then a drop statement with cascade constraints clause will be
236: * formed.
237: *
238: * @param iTableInfo
239: * the table to drop
240: * @param cascadeConstraints
241: * whether or not to drop any FKs that may reference the
242: * specified table.
243: * @return the drop SQL command.
244: */
245: public List<String> getTableDropSQL(ITableInfo iTableInfo,
246: boolean cascadeConstraints, boolean isMaterializedView) {
247: return DialectUtils.getTableDropSQL(iTableInfo, true,
248: cascadeConstraints, false, DialectUtils.CASCADE_CLAUSE,
249: false);
250: }
251:
252: /**
253: * Returns the SQL that forms the command to add a primary key to the
254: * specified table composed of the given column names.
255: *
256: * CREATE UNIQUE INDEX test_index ON test_table (test_field);
257: *
258: * ALTER TABLE test_table ADD CONSTRAINT PRIMARY KEY (test_field) CONSTRAINT
259: * test_constraint;
260: *
261: * alter table table_name add constraint primary key (column_names)
262: * constraint pkName
263: *
264: * @param pkName
265: * the name of the constraint
266: * @param columnNames
267: * the columns that form the key
268: * @return
269: */
270: public String[] getAddPrimaryKeySQL(String pkName,
271: TableColumnInfo[] columns, ITableInfo ti) {
272: // TODO: should also make sure that each of the columns is made "NOT NULL"
273:
274: return new String[] {
275: DialectUtils.getAddIndexSQL(pkName, true, columns),
276: DialectUtils.getAddPrimaryKeySQL(ti, pkName, columns,
277: true) };
278: }
279:
280: /**
281: * Returns a boolean value indicating whether or not this dialect supports
282: * adding comments to columns.
283: *
284: * @return true if column comments are supported; false otherwise.
285: */
286: public boolean supportsColumnComment() {
287: return false;
288: }
289:
290: /**
291: * Returns the SQL statement to use to add a comment to the specified column
292: * of the specified table.
293: *
294: * @param info
295: * information about the column such as type, name, etc.
296: * @return
297: * @throws UnsupportedOperationException
298: * if the database doesn't support annotating columns with a
299: * comment.
300: */
301: public String getColumnCommentAlterSQL(TableColumnInfo info)
302: throws UnsupportedOperationException {
303: int featureId = DialectUtils.COLUMN_COMMENT_ALTER_TYPE;
304: String msg = DialectUtils
305: .getUnsupportedMessage(this , featureId);
306: throw new UnsupportedOperationException(msg);
307: }
308:
309: /**
310: * Returns a boolean value indicating whether or not this database dialect
311: * supports changing a column from null to not-null and vice versa.
312: *
313: * @return true if the database supports dropping columns; false otherwise.
314: */
315: public boolean supportsAlterColumnNull() {
316: return true;
317: }
318:
319: /**
320: * Returns the SQL used to alter the specified column to not allow null
321: * values
322: *
323: * @param info
324: * the column to modify
325: * @return the SQL to execute
326: */
327: public String getColumnNullableAlterSQL(TableColumnInfo info) {
328: String alterClause = DialectUtils.MODIFY_CLAUSE;
329: return DialectUtils.getColumnNullableAlterSQL(info, this ,
330: alterClause, true);
331: }
332:
333: /**
334: * Returns a boolean value indicating whether or not this database dialect
335: * supports renaming columns.
336: *
337: * @return true if the database supports changing the name of columns; false
338: * otherwise.
339: */
340: public boolean supportsRenameColumn() {
341: return true;
342: }
343:
344: /**
345: * Returns the SQL that is used to change the column name.
346: *
347: *
348: * @param from
349: * the TableColumnInfo as it is
350: * @param to
351: * the TableColumnInfo as it wants to be
352: *
353: * @return the SQL to make the change
354: */
355: public String getColumnNameAlterSQL(TableColumnInfo from,
356: TableColumnInfo to) {
357: return DialectUtils.getColumnRenameSQL(from, to);
358: }
359:
360: /**
361: * Returns a boolean value indicating whether or not this dialect supports
362: * modifying a columns type.
363: *
364: * @return true if supported; false otherwise
365: */
366: public boolean supportsAlterColumnType() {
367: return true;
368: }
369:
370: /**
371: * Returns the SQL that is used to change the column type.
372: *
373: * alter table table_name modify column_name datatype
374: *
375: * @param from
376: * the TableColumnInfo as it is
377: * @param to
378: * the TableColumnInfo as it wants to be
379: *
380: * @return the SQL to make the change
381: * @throw UnsupportedOperationException if the database doesn't support
382: * modifying column types.
383: */
384: public List<String> getColumnTypeAlterSQL(TableColumnInfo from,
385: TableColumnInfo to) throws UnsupportedOperationException {
386: String alterClause = DialectUtils.MODIFY_CLAUSE;
387: String setClause = null;
388: return DialectUtils.getColumnTypeAlterSQL(this , alterClause,
389: setClause, false, from, to);
390: }
391:
392: /**
393: * Returns a boolean value indicating whether or not this database dialect
394: * supports changing a column's default value.
395: *
396: * @return true if the database supports modifying column defaults; false
397: * otherwise
398: */
399: public boolean supportsAlterColumnDefault() {
400: return true;
401: }
402:
403: /**
404: * Returns the SQL command to change the specified column's default value
405: *
406: * @param info
407: * the column to modify and it's default value.
408: * @return SQL to make the change
409: */
410: public String getColumnDefaultAlterSQL(TableColumnInfo info) {
411: String alterClause = DialectUtils.MODIFY_CLAUSE;
412: String defaultClause = DialectUtils.DEFAULT_CLAUSE;
413: return DialectUtils.getColumnDefaultAlterSQL(this , info,
414: alterClause, true, defaultClause);
415: }
416:
417: /**
418: * Returns the SQL command to drop the specified table's primary key.
419: *
420: * @param pkName
421: * the name of the primary key that should be dropped
422: * @param tableName
423: * the name of the table whose primary key should be dropped
424: * @return
425: */
426: public String getDropPrimaryKeySQL(String pkName, String tableName) {
427: return DialectUtils.getDropPrimaryKeySQL(pkName, tableName,
428: true, false);
429: }
430:
431: /**
432: * Returns the SQL command to drop the specified table's foreign key
433: * constraint.
434: *
435: * @param fkName the name of the foreign key that should be dropped
436: * @param tableName the name of the table whose foreign key should be
437: * dropped
438: * @return
439: */
440: public String getDropForeignKeySQL(String fkName, String tableName) {
441: return DialectUtils.getDropForeignKeySQL(fkName, tableName);
442: }
443:
444: /**
445: * Returns the SQL command to create the specified table.
446: *
447: * @param tables the tables to get create statements for
448: * @param md the metadata from the ISession
449: * @param prefs preferences about how the resultant SQL commands should be
450: * formed.
451: * @param isJdbcOdbc whether or not the connection is via JDBC-ODBC bridge.
452: *
453: * @return the SQL that is used to create the specified table
454: */
455: public List<String> getCreateTableSQL(List<ITableInfo> tables,
456: ISQLDatabaseMetaData md, CreateScriptPreferences prefs,
457: boolean isJdbcOdbc) throws SQLException {
458: return DialectUtils.getCreateTableSQL(tables, md, this, prefs,
459: isJdbcOdbc);
460: }
461:
462: }
|