Source code: org/objectstyle/cayenne/dba/db2/DB2Adapter.java
1 /* ====================================================================
2 *
3 * The ObjectStyle Group Software License, Version 1.0
4 *
5 * Copyright (c) 2002-2003 The ObjectStyle Group
6 * and individual authors of the software. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. The end-user documentation included with the redistribution, if
21 * any, must include the following acknowlegement:
22 * "This product includes software developed by the
23 * ObjectStyle Group (http://objectstyle.org/)."
24 * Alternately, this acknowlegement may appear in the software itself,
25 * if and wherever such third-party acknowlegements normally appear.
26 *
27 * 4. The names "ObjectStyle Group" and "Cayenne"
28 * must not be used to endorse or promote products derived
29 * from this software without prior written permission. For written
30 * permission, please contact andrus@objectstyle.org.
31 *
32 * 5. Products derived from this software may not be called "ObjectStyle"
33 * nor may "ObjectStyle" appear in their names without prior written
34 * permission of the ObjectStyle Group.
35 *
36 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39 * DISCLAIMED. IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This software consists of voluntary contributions made by many
51 * individuals on behalf of the ObjectStyle Group. For more
52 * information on the ObjectStyle Group, please see
53 * <http://objectstyle.org/>.
54 *
55 */
56
57 package org.objectstyle.cayenne.dba.db2;
58
59 import java.util.Iterator;
60
61 import org.objectstyle.cayenne.CayenneRuntimeException;
62 import org.objectstyle.cayenne.access.trans.QualifierTranslator;
63 import org.objectstyle.cayenne.access.trans.QueryAssembler;
64 import org.objectstyle.cayenne.access.types.CharType;
65 import org.objectstyle.cayenne.access.types.ExtendedTypeMap;
66 import org.objectstyle.cayenne.dba.JdbcAdapter;
67 import org.objectstyle.cayenne.dba.PkGenerator;
68 import org.objectstyle.cayenne.dba.TypesMapping;
69 import org.objectstyle.cayenne.map.DbAttribute;
70 import org.objectstyle.cayenne.map.DbEntity;
71 import org.objectstyle.cayenne.map.DerivedDbEntity;
72
73 /**
74 * DbAdapter implementation for the <a href="http://www.ibm.com/db2/"> DB2 RDBMS</a>.
75 * Sample <a target="_top" href="../../../../../../../developerguide/unit-tests.html">connection
76 * settings</a> to use with DB2 are shown below:
77 *
78 <pre>
79 test-db2.cayenne.adapter = org.objectstyle.cayenne.dba.db2.DB2Adapter
80 test-db2.jdbc.username = test
81 test-db2.jdbc.password = secret
82 test-db2.jdbc.url = jdbc:db2://servername:50000/databasename
83 test-db2.jdbc.driver = com.ibm.db2.jcc.DB2Driver
84 </pre>
85 *
86 * @author Holger Hoffstaette
87 */
88 public class DB2Adapter extends JdbcAdapter {
89
90 /**
91 * Creates a DB2 specific PK Generator.
92 */
93 protected PkGenerator createPkGenerator() {
94 return new DB2PkGenerator();
95 }
96
97 protected void configureExtendedTypes(ExtendedTypeMap map) {
98 super.configureExtendedTypes(map);
99
100 // create specially configured CharType handler
101 map.registerType(new CharType(true, true));
102 }
103
104 /**
105 * Returns a SQL string that can be used to create database table
106 * corresponding to <code>ent</code> parameter.
107 */
108 public String createTable(DbEntity ent) {
109 // later we may support view creation
110 // for derived DbEntities
111 if (ent instanceof DerivedDbEntity) {
112 throw new CayenneRuntimeException(
113 "Can't create table for derived DbEntity '"
114 + ent.getName()
115 + "'.");
116 }
117
118 StringBuffer buf = new StringBuffer();
119 buf.append("CREATE TABLE ").append(ent.getFullyQualifiedName()).append(
120 " (");
121
122 // columns
123 Iterator it = ent.getAttributes().iterator();
124 boolean first = true;
125 while (it.hasNext()) {
126 if (first) {
127 first = false;
128 } else {
129 buf.append(", ");
130 }
131
132 DbAttribute at = (DbAttribute) it.next();
133
134 // attribute may not be fully valid, do a simple check
135 if (at.getType() == TypesMapping.NOT_DEFINED) {
136 throw new CayenneRuntimeException(
137 "Undefined type for attribute '"
138 + ent.getFullyQualifiedName()
139 + "."
140 + at.getName()
141 + "'.");
142 }
143
144 String[] types = externalTypesForJdbcType(at.getType());
145 if (types == null || types.length == 0) {
146 throw new CayenneRuntimeException(
147 "Undefined type for attribute '"
148 + ent.getFullyQualifiedName()
149 + "."
150 + at.getName()
151 + "': "
152 + at.getType());
153 }
154
155 String type = types[0];
156 buf.append(at.getName()).append(' ').append(type);
157
158 // append size and precision (if applicable)
159 if (TypesMapping.supportsLength(at.getType())) {
160 int len = at.getMaxLength();
161 int prec =
162 TypesMapping.isDecimal(at.getType())
163 ? at.getPrecision()
164 : -1;
165
166 // sanity check
167 if (prec > len) {
168 prec = -1;
169 }
170
171 if (len > 0) {
172 buf.append('(').append(len);
173
174 if (prec >= 0) {
175 buf.append(", ").append(prec);
176 }
177
178 buf.append(')');
179 }
180 }
181
182 if (at.isMandatory()) {
183 buf.append(" NOT NULL");
184 }
185 }
186
187 // primary key clause
188 Iterator pkit = ent.getPrimaryKey().iterator();
189 if (pkit.hasNext()) {
190 if (first)
191 first = false;
192 else
193 buf.append(", ");
194
195 buf.append("PRIMARY KEY (");
196 boolean firstPk = true;
197 while (pkit.hasNext()) {
198 if (firstPk)
199 firstPk = false;
200 else
201 buf.append(", ");
202
203 DbAttribute at = (DbAttribute) pkit.next();
204 buf.append(at.getName());
205 }
206 buf.append(')');
207 }
208 buf.append(')');
209 return buf.toString();
210 }
211
212 /**
213 * Returns a trimming translator.
214 */
215 public QualifierTranslator getQualifierTranslator(QueryAssembler queryAssembler) {
216 return new DB2QualifierTranslator(queryAssembler, "RTRIM");
217 }
218
219 }