PageRenderTime 68ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/projects/cayenne-3.0.1/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/postgres/PostgresAdapter.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 271 lines | 167 code | 35 blank | 69 comment | 31 complexity | e5c288cbef01cc40e07ce50875767033 MD5 | raw file
  1. /*****************************************************************
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. ****************************************************************/
  19. package org.apache.cayenne.dba.postgres;
  20. import java.sql.Types;
  21. import java.util.Collection;
  22. import java.util.Collections;
  23. import java.util.Iterator;
  24. import org.apache.cayenne.CayenneRuntimeException;
  25. import org.apache.cayenne.access.DataNode;
  26. import org.apache.cayenne.access.trans.QualifierTranslator;
  27. import org.apache.cayenne.access.trans.QueryAssembler;
  28. import org.apache.cayenne.access.types.CharType;
  29. import org.apache.cayenne.access.types.ExtendedTypeMap;
  30. import org.apache.cayenne.dba.QuotingStrategy;
  31. import org.apache.cayenne.dba.JdbcAdapter;
  32. import org.apache.cayenne.dba.PkGenerator;
  33. import org.apache.cayenne.dba.TypesMapping;
  34. import org.apache.cayenne.map.DbAttribute;
  35. import org.apache.cayenne.map.DbEntity;
  36. import org.apache.cayenne.merge.MergerFactory;
  37. import org.apache.cayenne.query.Query;
  38. import org.apache.cayenne.query.SQLAction;
  39. /**
  40. * DbAdapter implementation for <a href="http://www.postgresql.org">PostgreSQL RDBMS </a>.
  41. * Sample connection settings to use with PostgreSQL are shown below:
  42. *
  43. * <pre>
  44. *
  45. * postgres.cayenne.adapter = org.apache.cayenne.dba.postgres.PostgresAdapter
  46. * postgres.jdbc.username = test
  47. * postgres.jdbc.password = secret
  48. * postgres.jdbc.url = jdbc:postgresql://serverhostname/cayenne
  49. * postgres.jdbc.driver = org.postgresql.Driver
  50. *
  51. * </pre>
  52. *
  53. */
  54. public class PostgresAdapter extends JdbcAdapter {
  55. public PostgresAdapter() {
  56. setSupportsBatchUpdates(true);
  57. }
  58. /**
  59. * Uses PostgresActionBuilder to create the right action.
  60. *
  61. * @since 1.2
  62. */
  63. @Override
  64. public SQLAction getAction(Query query, DataNode node) {
  65. return query.createSQLAction(new PostgresActionBuilder(this, node
  66. .getEntityResolver()));
  67. }
  68. /**
  69. * Installs appropriate ExtendedTypes as converters for passing values between JDBC
  70. * and Java layers.
  71. */
  72. @Override
  73. protected void configureExtendedTypes(ExtendedTypeMap map) {
  74. super.configureExtendedTypes(map);
  75. map.registerType(new CharType(true, false));
  76. map.registerType(new PostgresByteArrayType(true, true));
  77. }
  78. @Override
  79. public DbAttribute buildAttribute(
  80. String name,
  81. String typeName,
  82. int type,
  83. int size,
  84. int scale,
  85. boolean allowNulls) {
  86. // "bytea" maps to pretty much any binary type, so
  87. // it is up to us to select the most sensible default.
  88. // And the winner is LONGVARBINARY
  89. if ("bytea".equalsIgnoreCase(typeName)) {
  90. type = Types.LONGVARBINARY;
  91. }
  92. // oid is returned as INTEGER, need to make it BLOB
  93. else if ("oid".equals(typeName)) {
  94. type = Types.BLOB;
  95. }
  96. // somehow the driver reverse-engineers "text" as VARCHAR, must be CLOB
  97. else if ("text".equalsIgnoreCase(typeName)) {
  98. type = Types.CLOB;
  99. }
  100. return super.buildAttribute(name, typeName, type, size, scale, allowNulls);
  101. }
  102. /**
  103. * Customizes table creating procedure for PostgreSQL. One difference with generic
  104. * implementation is that "bytea" type has no explicit length unlike similar binary
  105. * types in other databases.
  106. *
  107. * @since 1.0.2
  108. */
  109. @Override
  110. public String createTable(DbEntity ent) {
  111. boolean status;
  112. if(ent.getDataMap()!=null && ent.getDataMap().isQuotingSQLIdentifiers()){
  113. status= true;
  114. } else {
  115. status = false;
  116. }
  117. QuotingStrategy context = getQuotingStrategy(status);
  118. StringBuilder buf = new StringBuilder();
  119. buf.append("CREATE TABLE ");
  120. buf.append(context.quoteFullyQualifiedName(ent));
  121. buf.append(" (");
  122. // columns
  123. Iterator<DbAttribute> it = ent.getAttributes().iterator();
  124. boolean first = true;
  125. while (it.hasNext()) {
  126. if (first)
  127. first = false;
  128. else
  129. buf.append(", ");
  130. DbAttribute at = it.next();
  131. // attribute may not be fully valid, do a simple check
  132. if (at.getType() == TypesMapping.NOT_DEFINED) {
  133. throw new CayenneRuntimeException("Undefined type for attribute '"
  134. + ent.getFullyQualifiedName()
  135. + "."
  136. + at.getName()
  137. + "'.");
  138. }
  139. String[] types = externalTypesForJdbcType(at.getType());
  140. if (types == null || types.length == 0) {
  141. throw new CayenneRuntimeException("Undefined type for attribute '"
  142. + ent.getFullyQualifiedName()
  143. + "."
  144. + at.getName()
  145. + "': "
  146. + at.getType());
  147. }
  148. String type = types[0];
  149. buf.append(context.quoteString(at.getName())).append(' ').append(type);
  150. // append size and precision (if applicable)
  151. if (typeSupportsLength(at.getType())) {
  152. int len = at.getMaxLength();
  153. int scale = TypesMapping.isDecimal(at.getType()) ? at.getScale() : -1;
  154. // sanity check
  155. if (scale > len) {
  156. scale = -1;
  157. }
  158. if (len > 0) {
  159. buf.append('(').append(len);
  160. if (scale >= 0) {
  161. buf.append(", ").append(scale);
  162. }
  163. buf.append(')');
  164. }
  165. }
  166. if (at.isMandatory()) {
  167. buf.append(" NOT NULL");
  168. }
  169. else {
  170. buf.append(" NULL");
  171. }
  172. }
  173. // primary key clause
  174. Iterator<DbAttribute> pkit = ent.getPrimaryKeys().iterator();
  175. if (pkit.hasNext()) {
  176. if (first)
  177. first = false;
  178. else
  179. buf.append(", ");
  180. buf.append("PRIMARY KEY (");
  181. boolean firstPk = true;
  182. while (pkit.hasNext()) {
  183. if (firstPk)
  184. firstPk = false;
  185. else
  186. buf.append(", ");
  187. DbAttribute at = pkit.next();
  188. buf.append(context.quoteString(at.getName()));
  189. }
  190. buf.append(')');
  191. }
  192. buf.append(')');
  193. return buf.toString();
  194. }
  195. private boolean typeSupportsLength(int type) {
  196. // "bytea" type does not support length
  197. String[] externalTypes = externalTypesForJdbcType(type);
  198. if (externalTypes != null && externalTypes.length > 0) {
  199. for (String externalType : externalTypes) {
  200. if ("bytea".equalsIgnoreCase(externalType)) {
  201. return false;
  202. }
  203. }
  204. }
  205. return TypesMapping.supportsLength(type);
  206. }
  207. /**
  208. * Adds the CASCADE option to the DROP TABLE clause.
  209. */
  210. @Override
  211. public Collection<String> dropTableStatements(DbEntity table) {
  212. QuotingStrategy context = getQuotingStrategy(table.getDataMap().isQuotingSQLIdentifiers());
  213. StringBuffer buf = new StringBuffer("DROP TABLE ");
  214. buf.append(context.quoteFullyQualifiedName(table));
  215. buf.append(" CASCADE");
  216. return Collections.singleton(buf.toString());
  217. }
  218. /**
  219. * Returns a trimming translator.
  220. */
  221. @Override
  222. public QualifierTranslator getQualifierTranslator(QueryAssembler queryAssembler) {
  223. return new PostgresQualifierTranslator(queryAssembler);
  224. }
  225. /**
  226. * @see JdbcAdapter#createPkGenerator()
  227. */
  228. @Override
  229. protected PkGenerator createPkGenerator() {
  230. return new PostgresPkGenerator(this);
  231. }
  232. @Override
  233. public MergerFactory mergerFactory() {
  234. return new PostgresMergerFactory();
  235. }
  236. }