選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

SQLDialectDefault.java 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*
  2. * Copyright 2004-2011 H2 Group.
  3. * Copyright 2011 James Moger.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package com.iciql;
  18. import java.sql.DatabaseMetaData;
  19. import java.sql.SQLException;
  20. import com.iciql.TableDefinition.FieldDefinition;
  21. import com.iciql.TableDefinition.IndexDefinition;
  22. import com.iciql.util.StatementBuilder;
  23. import com.iciql.util.StringUtils;
  24. /**
  25. * Default implementation of an SQL dialect. Does not support merge nor index
  26. * creation.
  27. */
  28. public class SQLDialectDefault implements SQLDialect {
  29. float databaseVersion;
  30. String databaseName;
  31. String productVersion;
  32. @Override
  33. public String toString() {
  34. return getClass().getName() + ": " + databaseName + " " + productVersion;
  35. }
  36. @Override
  37. public void configureDialect(String databaseName, DatabaseMetaData data) {
  38. this.databaseName = databaseName;
  39. try {
  40. databaseVersion = Float.parseFloat(data.getDatabaseMajorVersion() + "."
  41. + data.getDatabaseMinorVersion());
  42. productVersion = data.getDatabaseProductVersion();
  43. } catch (SQLException e) {
  44. throw new IciqlException(e);
  45. }
  46. }
  47. /**
  48. * Allows subclasses to change the type of a column for a CREATE statement.
  49. *
  50. * @param sqlType
  51. * @return the SQL type or a preferred alternative
  52. */
  53. protected String convertSqlType(String sqlType) {
  54. return sqlType;
  55. }
  56. @Override
  57. public Class<? extends java.util.Date> getDateTimeClass() {
  58. return java.util.Date.class;
  59. }
  60. @Override
  61. public boolean supportsMemoryTables() {
  62. return false;
  63. }
  64. @Override
  65. public boolean supportsIfNotExists() {
  66. return true;
  67. }
  68. @Override
  69. public boolean supportsLimitOffset() {
  70. return true;
  71. }
  72. @Override
  73. public String prepareTableName(String schemaName, String tableName) {
  74. if (StringUtils.isNullOrEmpty(schemaName)) {
  75. return tableName;
  76. }
  77. return schemaName + "." + tableName;
  78. }
  79. @Override
  80. public String prepareColumnName(String name) {
  81. return name;
  82. }
  83. @Override
  84. public <T> void prepareCreateTable(SQLStatement stat, TableDefinition<T> def) {
  85. StatementBuilder buff;
  86. if (def.memoryTable && supportsMemoryTables()) {
  87. buff = new StatementBuilder("CREATE MEMORY TABLE ");
  88. } else {
  89. buff = new StatementBuilder("CREATE TABLE ");
  90. }
  91. if (supportsIfNotExists()) {
  92. buff.append("IF NOT EXISTS ");
  93. }
  94. buff.append(prepareTableName(def.schemaName, def.tableName)).append('(');
  95. boolean hasIdentityColumn = false;
  96. for (FieldDefinition field : def.fields) {
  97. buff.appendExceptFirst(", ");
  98. buff.append(prepareColumnName(field.columnName)).append(' ');
  99. String dataType = field.dataType;
  100. if (dataType.equals("VARCHAR")) {
  101. // check to see if we should use VARCHAR or CLOB
  102. if (field.length <= 0) {
  103. dataType = "CLOB";
  104. }
  105. buff.append(convertSqlType(dataType));
  106. if (field.length > 0) {
  107. buff.append('(').append(field.length).append(')');
  108. }
  109. } else if (dataType.equals("DECIMAL")) {
  110. // DECIMAL(precision,scale)
  111. buff.append(convertSqlType(dataType));
  112. if (field.length > 0) {
  113. buff.append('(').append(field.length);
  114. if (field.scale > 0) {
  115. buff.append(',').append(field.scale);
  116. }
  117. buff.append(')');
  118. }
  119. } else {
  120. // other
  121. buff.append(convertSqlType(dataType));
  122. }
  123. hasIdentityColumn |= prepareColumnDefinition(buff, field.isAutoIncrement, field.isPrimaryKey);
  124. if (!field.nullable) {
  125. buff.append(" NOT NULL");
  126. }
  127. // default values
  128. if (!field.isAutoIncrement && !field.isPrimaryKey) {
  129. String dv = field.defaultValue;
  130. if (!StringUtils.isNullOrEmpty(dv)) {
  131. if (ModelUtils.isProperlyFormattedDefaultValue(dv)
  132. && ModelUtils.isValidDefaultValue(field.field.getType(), dv)) {
  133. buff.append(" DEFAULT " + dv);
  134. }
  135. }
  136. }
  137. }
  138. // if table does not have identity column then specify primary key
  139. if (!hasIdentityColumn) {
  140. if (def.primaryKeyColumnNames != null && def.primaryKeyColumnNames.size() > 0) {
  141. buff.append(", PRIMARY KEY(");
  142. buff.resetCount();
  143. for (String n : def.primaryKeyColumnNames) {
  144. buff.appendExceptFirst(", ");
  145. buff.append(prepareColumnName(n));
  146. }
  147. buff.append(')');
  148. }
  149. }
  150. buff.append(')');
  151. stat.setSQL(buff.toString());
  152. }
  153. protected boolean prepareColumnDefinition(StatementBuilder buff, boolean isAutoIncrement,
  154. boolean isPrimaryKey) {
  155. boolean isIdentity = false;
  156. if (isAutoIncrement && isPrimaryKey) {
  157. buff.append(" IDENTITY");
  158. isIdentity = true;
  159. } else if (isAutoIncrement) {
  160. buff.append(" AUTO_INCREMENT");
  161. }
  162. return isIdentity;
  163. }
  164. @Override
  165. public void prepareCreateIndex(SQLStatement stat, String schemaName, String tableName,
  166. IndexDefinition index) {
  167. throw new IciqlException("{0} does not support index creation!", getClass().getSimpleName());
  168. }
  169. @Override
  170. public <T> void prepareMerge(SQLStatement stat, String schemaName, String tableName,
  171. TableDefinition<T> def, Object obj) {
  172. throw new IciqlException("{0} does not support merge statements!", getClass().getSimpleName());
  173. }
  174. @Override
  175. public void appendLimitOffset(SQLStatement stat, long limit, long offset) {
  176. if (limit > 0) {
  177. stat.appendSQL(" LIMIT " + limit);
  178. }
  179. if (offset > 0) {
  180. stat.appendSQL(" OFFSET " + offset);
  181. }
  182. }
  183. }