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.IDatabaseObjectInfo;
026: import net.sourceforge.squirrel_sql.fw.sql.ISQLDatabaseMetaData;
027: import net.sourceforge.squirrel_sql.fw.sql.ITableInfo;
028: import net.sourceforge.squirrel_sql.fw.sql.TableColumnInfo;
029:
030: /**
031: * An extension to the standard Hibernate dialect
032: *
033: * TODO: Progress specification says that the sum of all column lengths of a
034: * table row may not exceed 31960. Need to add an interface method to
035: * the HibernateDialect interface that takes an array of lengths and
036: * and checks the sum of columns for a row. This maximum number may be
037: * different across databases so this check method needs to be
038: * implemented by each dialect.
039: */
040: public class ProgressDialect extends org.hibernate.dialect.Dialect
041: implements HibernateDialect {
042:
043: public ProgressDialect() {
044: super ();
045: registerColumnType(Types.BIGINT, "integer");
046: registerColumnType(Types.BINARY, 2000, "binary($l)");
047: registerColumnType(Types.BINARY, 31982, "varbinary($l)");
048: registerColumnType(Types.BINARY, "lvarbinary($l)");
049: registerColumnType(Types.BIT, "bit");
050: registerColumnType(Types.BLOB, "lvarbinary($l)");
051: registerColumnType(Types.BOOLEAN, "bit");
052: registerColumnType(Types.CHAR, 2000, "char($l)");
053: registerColumnType(Types.CHAR, "char(2000)");
054: //registerColumnType(Types.CLOB, 31982, "varchar($l)");
055: registerColumnType(Types.CLOB, "varchar($l)");
056: registerColumnType(Types.DATE, "date");
057: registerColumnType(Types.DECIMAL, "numeric($p,2)");
058: registerColumnType(Types.DOUBLE, "double precision");
059: registerColumnType(Types.FLOAT, "float($p)");
060: registerColumnType(Types.INTEGER, "integer");
061: registerColumnType(Types.LONGVARBINARY, 999999999,
062: "lvarbinary($l)");
063: registerColumnType(Types.LONGVARBINARY, "lvarbinary(999999999)");
064: //registerColumnType(Types.LONGVARCHAR, 31982, "varchar($l)");
065: registerColumnType(Types.LONGVARCHAR, "varchar($l)");
066: registerColumnType(Types.NUMERIC, "numeric($p,2)");
067: registerColumnType(Types.REAL, "real");
068: registerColumnType(Types.SMALLINT, "smallint");
069: registerColumnType(Types.TIME, "date");
070: registerColumnType(Types.TIMESTAMP, "timestamp");
071: registerColumnType(Types.TINYINT, "tinyint");
072: registerColumnType(Types.VARBINARY, 31982, "varbinary($l)");
073: registerColumnType(Types.VARBINARY, "varbinary(31982)");
074: registerColumnType(Types.VARCHAR, 31982, "varchar($l)");
075: registerColumnType(Types.VARCHAR, "varchar(31982)");
076: }
077:
078: /* (non-Javadoc)
079: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#canPasteTo(net.sourceforge.squirrel_sql.fw.sql.DatabaseObjectType)
080: */
081: public boolean canPasteTo(IDatabaseObjectInfo info) {
082: return true;
083: }
084:
085: /* (non-Javadoc)
086: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#supportsSchemasInTableDefinition()
087: */
088: public boolean supportsSchemasInTableDefinition() {
089: return true;
090: }
091:
092: /* (non-Javadoc)
093: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#getLengthFunction()
094: */
095: public String getLengthFunction(int dataType) {
096: return "length";
097: }
098:
099: /* (non-Javadoc)
100: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#getMaxFunction()
101: */
102: public String getMaxFunction() {
103: return "max";
104: }
105:
106: /* (non-Javadoc)
107: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#getMaxPrecision(int)
108: */
109: public int getMaxPrecision(int dataType) {
110: if (dataType == Types.FLOAT) {
111: return 15;
112: } else {
113: return 32;
114: }
115: }
116:
117: /* (non-Javadoc)
118: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#getMaxScale(int)
119: */
120: public int getMaxScale(int dataType) {
121: return getMaxPrecision(dataType);
122: }
123:
124: /* (non-Javadoc)
125: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#getPrecisionDigits(int, int)
126: */
127: public int getPrecisionDigits(int columnSize, int dataType) {
128: return columnSize;
129: }
130:
131: /* (non-Javadoc)
132: * @see net.sourceforge.squirrel_sql.plugins.dbcopy.dialects.HibernateDialect#getColumnLength(int, int)
133: */
134: public int getColumnLength(int columnSize, int dataType) {
135: return columnSize;
136: }
137:
138: /**
139: * The string which identifies this dialect in the dialect chooser.
140: *
141: * @return a descriptive name that tells the user what database this dialect
142: * is design to work with.
143: */
144: public String getDisplayName() {
145: return "Progress";
146: }
147:
148: /**
149: * Returns boolean value indicating whether or not this dialect supports the
150: * specified database product/version.
151: *
152: * @param databaseProductName the name of the database as reported by
153: * DatabaseMetaData.getDatabaseProductName()
154: * @param databaseProductVersion the version of the database as reported by
155: * DatabaseMetaData.getDatabaseProductVersion()
156: * @return true if this dialect can be used for the specified product name
157: * and version; false otherwise.
158: */
159: public boolean supportsProduct(String databaseProductName,
160: String databaseProductVersion) {
161: if (databaseProductName == null) {
162: return false;
163: }
164: if (databaseProductName.trim().toLowerCase().startsWith(
165: "progress")) {
166: // We don't yet have the need to discriminate by version.
167: return true;
168: }
169: return false;
170: }
171:
172: /**
173: * Returns the SQL statement to use to add a column to the specified table
174: * using the information about the new column specified by info.
175: * @param info information about the new column such as type, name, etc.
176: *
177: * @return
178: * @throws UnsupportedOperationException if the database doesn't support
179: * adding columns after a table has already been created.
180: */
181: public String[] getColumnAddSQL(TableColumnInfo info)
182: throws UnsupportedOperationException {
183: throw new UnsupportedOperationException(
184: "This database dialect doesn't support adding columns to tables");
185: }
186:
187: /**
188: * Returns a boolean value indicating whether or not this dialect supports
189: * adding comments to columns.
190: *
191: * @return true if column comments are supported; false otherwise.
192: */
193: public boolean supportsColumnComment() {
194: return false;
195: }
196:
197: /**
198: * Returns the SQL statement to use to add a comment to the specified
199: * column of the specified table.
200: *
201: * @param tableName the name of the table to create the SQL for.
202: * @param columnName the name of the column to create the SQL for.
203: * @param comment the comment to add.
204: * @return
205: * @throws UnsupportedOperationException if the database doesn't support
206: * annotating columns with a comment.
207: */
208: @SuppressWarnings("unused")
209: public String getColumnCommentAlterSQL(String tableName,
210: String columnName, String comment)
211: throws UnsupportedOperationException {
212: throw new UnsupportedOperationException(
213: "This database dialect doesn't support adding comments to columns");
214: }
215:
216: /**
217: * Returns a boolean value indicating whether or not this database dialect
218: * supports dropping columns from tables.
219: *
220: * @return true if the database supports dropping columns; false otherwise.
221: */
222: public boolean supportsDropColumn() {
223: // TODO: need to verify this
224: return true;
225: }
226:
227: /**
228: * Returns the SQL that forms the command to drop the specified colum in the
229: * specified table.
230: *
231: * @param tableName the name of the table that has the column
232: * @param columnName the name of the column to drop.
233: * @return
234: * @throws UnsupportedOperationException if the database doesn't support
235: * dropping columns.
236: */
237: public String getColumnDropSQL(String tableName, String columnName) {
238: // TODO: Need to verify this
239: return DialectUtils.getColumnDropSQL(tableName, columnName);
240: }
241:
242: /**
243: * Returns the SQL that forms the command to drop the specified table. If
244: * cascade contraints is supported by the dialect and cascadeConstraints is
245: * true, then a drop statement with cascade constraints clause will be
246: * formed.
247: *
248: * @param iTableInfo the table to drop
249: * @param cascadeConstraints whether or not to drop any FKs that may
250: * reference the specified table.
251: * @return the drop SQL command.
252: */
253: public List<String> getTableDropSQL(ITableInfo iTableInfo,
254: boolean cascadeConstraints, boolean isMaterializedView) {
255: // TODO: Need to verify this
256: return DialectUtils.getTableDropSQL(iTableInfo, true,
257: cascadeConstraints, false, DialectUtils.CASCADE_CLAUSE,
258: false);
259: }
260:
261: /**
262: * Returns the SQL that forms the command to add a primary key to the
263: * specified table composed of the given column names.
264: *
265: * @param pkName the name of the constraint
266: * @param columnNames the columns that form the key
267: * @return
268: */
269: public String[] getAddPrimaryKeySQL(String pkName,
270: TableColumnInfo[] columnNames, ITableInfo ti) {
271: // TODO: implement
272: throw new UnsupportedOperationException("Not yet implemented");
273: }
274:
275: /**
276: * Returns the SQL statement to use to add a comment to the specified
277: * column of the specified table.
278: * @param info information about the column such as type, name, etc.
279: * @return
280: * @throws UnsupportedOperationException if the database doesn't support
281: * annotating columns with a comment.
282: */
283: public String getColumnCommentAlterSQL(TableColumnInfo info)
284: throws UnsupportedOperationException {
285: // TODO: implement
286: throw new UnsupportedOperationException("Not yet implemented");
287: }
288:
289: /**
290: * Returns the SQL used to alter the specified column to not allow null
291: * values
292: *
293: * @param info the column to modify
294: * @return the SQL to execute
295: */
296: public String getColumnNullableAlterSQL(TableColumnInfo info) {
297: // TODO: implement
298: throw new UnsupportedOperationException("Not yet implemented");
299: }
300:
301: /**
302: * Returns a boolean value indicating whether or not this database dialect
303: * supports renaming columns.
304: *
305: * @return true if the database supports changing the name of columns;
306: * false otherwise.
307: */
308: public boolean supportsRenameColumn() {
309: // TODO: need to verify this
310: return true;
311: }
312:
313: /**
314: * Returns the SQL that is used to change the column name.
315: *
316: *
317: * @param from the TableColumnInfo as it is
318: * @param to the TableColumnInfo as it wants to be
319: *
320: * @return the SQL to make the change
321: */
322: public String getColumnNameAlterSQL(TableColumnInfo from,
323: TableColumnInfo to) {
324: // TODO: implement
325: throw new UnsupportedOperationException("Not yet implemented");
326: }
327:
328: /**
329: * Returns a boolean value indicating whether or not this dialect supports
330: * modifying a columns type.
331: *
332: * @return true if supported; false otherwise
333: */
334: public boolean supportsAlterColumnType() {
335: // TODO: verify this
336: return true;
337: }
338:
339: /**
340: * Returns the SQL that is used to change the column type.
341: *
342: * @param from the TableColumnInfo as it is
343: * @param to the TableColumnInfo as it wants to be
344: *
345: * @return the SQL to make the change
346: * @throw UnsupportedOperationException if the database doesn't support
347: * modifying column types.
348: */
349: public List<String> getColumnTypeAlterSQL(TableColumnInfo from,
350: TableColumnInfo to) throws UnsupportedOperationException {
351: // TODO: implement
352: throw new UnsupportedOperationException("Not Yet Implemented");
353: }
354:
355: /**
356: * Returns a boolean value indicating whether or not this database dialect
357: * supports changing a column from null to not-null and vice versa.
358: *
359: * @return true if the database supports dropping columns; false otherwise.
360: */
361: public boolean supportsAlterColumnNull() {
362: // TODO Auto-generated method stub
363: return false;
364: }
365:
366: /**
367: * Returns a boolean value indicating whether or not this database dialect
368: * supports changing a column's default value.
369: *
370: * @return true if the database supports modifying column defaults; false
371: * otherwise
372: */
373: public boolean supportsAlterColumnDefault() {
374: // TODO Need to verify this
375: return true;
376: }
377:
378: /**
379: * Returns the SQL command to change the specified column's default value
380: *
381: * @param info the column to modify and it's default value.
382: * @return SQL to make the change
383: */
384: public String getColumnDefaultAlterSQL(TableColumnInfo info) {
385: // TODO need to implement or change the message
386: throw new UnsupportedOperationException("Not yet implemented");
387: }
388:
389: /**
390: * Returns the SQL command to drop the specified table's primary key.
391: *
392: * @param pkName the name of the primary key that should be dropped
393: * @param tableName the name of the table whose primary key should be
394: * dropped
395: * @return
396: */
397: public String getDropPrimaryKeySQL(String pkName, String tableName) {
398: return DialectUtils.getDropPrimaryKeySQL(pkName, tableName,
399: false, false);
400: }
401:
402: /**
403: * Returns the SQL command to drop the specified table's foreign key
404: * constraint.
405: *
406: * @param fkName the name of the foreign key that should be dropped
407: * @param tableName the name of the table whose foreign key should be
408: * dropped
409: * @return
410: */
411: public String getDropForeignKeySQL(String fkName, String tableName) {
412: return DialectUtils.getDropForeignKeySQL(fkName, tableName);
413: }
414:
415: /**
416: * Returns the SQL command to create the specified table.
417: *
418: * @param tables the tables to get create statements for
419: * @param md the metadata from the ISession
420: * @param prefs preferences about how the resultant SQL commands should be
421: * formed.
422: * @param isJdbcOdbc whether or not the connection is via JDBC-ODBC bridge.
423: *
424: * @return the SQL that is used to create the specified table
425: */
426: public List<String> getCreateTableSQL(List<ITableInfo> tables,
427: ISQLDatabaseMetaData md, CreateScriptPreferences prefs,
428: boolean isJdbcOdbc) throws SQLException {
429: return DialectUtils.getCreateTableSQL(tables, md, this, prefs,
430: isJdbcOdbc);
431: }
432:
433: }
|