KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cayenne > dba > frontbase > FrontBaseAdapter


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
20 package org.apache.cayenne.dba.frontbase;
21
22 import java.sql.Types JavaDoc;
23 import java.util.Iterator JavaDoc;
24
25 import org.apache.cayenne.CayenneRuntimeException;
26 import org.apache.cayenne.access.DataNode;
27 import org.apache.cayenne.access.types.ExtendedTypeMap;
28 import org.apache.cayenne.dba.JdbcAdapter;
29 import org.apache.cayenne.dba.PkGenerator;
30 import org.apache.cayenne.dba.TypesMapping;
31 import org.apache.cayenne.map.DbAttribute;
32 import org.apache.cayenne.map.DbEntity;
33 import org.apache.cayenne.map.DerivedDbEntity;
34 import org.apache.cayenne.query.Query;
35 import org.apache.cayenne.query.SQLAction;
36
37 /**
38  * DbAdapter implementation for <a HREF="http://www.frontbase.com/">FrontBase RDBMS</a>.
39  * Sample <a target="_top"
40  * HREF="../../../../../../../developerguide/unit-tests.html">connection settings</a> to
41  * use with FrontBase are shown below:
42  *
43  * <pre>
44  * fb.cayenne.adapter = org.apache.cayenne.dba.frontbase.FrontBaseAdapter
45  * fb.jdbc.username = _system
46  * fb.jdbc.password = secret
47  * fb.jdbc.url = jdbc:FrontBase://localhost/cayenne/
48  * fb.jdbc.driver = jdbc.FrontBase.FBJDriver
49  * </pre>
50  *
51  * @since 1.2
52  * @author Andrus Adamchik
53  */

54 // TODO, Andrus 11/8/2005:
55
// Limitations (also see FrontBaseStackAdapter in unit tests):
56
//
57
// 1. Case insensitive ordering (i.e. UPPER in the ORDER BY clause) is supported by
58
// FrontBase, however aliases don't work ( ORDER BY UPPER(t0.ARTIST_NAME)) ... not sure
59
// what to do about it.
60
public class FrontBaseAdapter extends JdbcAdapter {
61
62     public FrontBaseAdapter() {
63         setSupportsBatchUpdates(true);
64     }
65
66     /**
67      * Uses special action builder to create the right action.
68      */

69     public SQLAction getAction(Query query, DataNode node) {
70         return query.createSQLAction(new FrontBaseActionBuilder(this, node
71                 .getEntityResolver()));
72     }
73
74     public String JavaDoc tableTypeForTable() {
75         return "BASE TABLE";
76     }
77
78     protected void configureExtendedTypes(ExtendedTypeMap map) {
79         super.configureExtendedTypes(map);
80
81         map.registerType(new FrontBaseByteArrayType());
82         map.registerType(new FrontBaseBooleanType());
83         map.registerType(new FrontBaseCharType());
84     }
85
86     /**
87      * Customizes table creating procedure for FrontBase.
88      */

89     public String JavaDoc createTable(DbEntity ent) {
90
91         // later we may support view creation
92
// for derived DbEntities
93
if (ent instanceof DerivedDbEntity) {
94             throw new CayenneRuntimeException("Can't create table for derived DbEntity '"
95                     + ent.getName()
96                     + "'.");
97         }
98
99         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
100         buf.append("CREATE TABLE ").append(ent.getFullyQualifiedName()).append(" (");
101
102         // columns
103
Iterator JavaDoc it = ent.getAttributes().iterator();
104         boolean first = true;
105         while (it.hasNext()) {
106             if (first) {
107                 first = false;
108             }
109             else {
110                 buf.append(", ");
111             }
112
113             DbAttribute at = (DbAttribute) it.next();
114
115             // attribute may not be fully valid, do a simple check
116
if (at.getType() == TypesMapping.NOT_DEFINED) {
117                 throw new CayenneRuntimeException("Undefined type for attribute '"
118                         + ent.getFullyQualifiedName()
119                         + "."
120                         + at.getName()
121                         + "'.");
122             }
123
124             String JavaDoc[] types = externalTypesForJdbcType(at.getType());
125             if (types == null || types.length == 0) {
126                 throw new CayenneRuntimeException("Undefined type for attribute '"
127                         + ent.getFullyQualifiedName()
128                         + "."
129                         + at.getName()
130                         + "': "
131                         + at.getType());
132             }
133
134             String JavaDoc type = types[0];
135             buf.append(at.getName()).append(' ').append(type);
136
137             // Mapping LONGVARCHAR without length creates a column with lenght "1" which
138
// is defintely not what we want...so just use something very large (1Gb seems
139
// to be the limit for FB)
140
if (at.getType() == Types.LONGVARCHAR) {
141
142                 int len = at.getMaxLength() > 0 ? at.getMaxLength() : 1073741824;
143                 buf.append("(" + len + ")");
144             }
145             else if (at.getType() == Types.VARBINARY || at.getType() == Types.BINARY) {
146
147                 // use a BIT column with size * 8
148
int len = at.getMaxLength() > 0 ? at.getMaxLength() : 1073741824;
149                 len *= 8;
150                 buf.append("(" + len + ")");
151             }
152             else if (TypesMapping.supportsLength(at.getType())) {
153                 int len = at.getMaxLength();
154                 int scale = TypesMapping.isDecimal(at.getType()) ? at.getScale() : -1;
155
156                 // sanity check
157
if (scale > len) {
158                     scale = -1;
159                 }
160
161                 if (len > 0) {
162                     buf.append('(').append(len);
163
164                     if (scale >= 0) {
165                         buf.append(", ").append(scale);
166                     }
167
168                     buf.append(')');
169                 }
170             }
171
172             if (at.isMandatory()) {
173                 buf.append(" NOT NULL");
174             }
175             // else: don't appen NULL for FrontBase:
176
}
177
178         // primary key clause
179
Iterator JavaDoc pkit = ent.getPrimaryKey().iterator();
180         if (pkit.hasNext()) {
181             if (first)
182                 first = false;
183             else
184                 buf.append(", ");
185
186             buf.append("PRIMARY KEY (");
187             boolean firstPk = true;
188             while (pkit.hasNext()) {
189                 if (firstPk)
190                     firstPk = false;
191                 else
192                     buf.append(", ");
193
194                 DbAttribute at = (DbAttribute) pkit.next();
195                 buf.append(at.getName());
196             }
197             buf.append(')');
198         }
199         buf.append(')');
200         return buf.toString();
201     }
202
203     /**
204      * Adds the CASCADE option to the DROP TABLE clause.
205      */

206     public String JavaDoc dropTable(DbEntity ent) {
207         return super.dropTable(ent) + " CASCADE";
208     }
209
210     protected PkGenerator createPkGenerator() {
211         return new FrontBasePkGenerator();
212     }
213 }
214
Popular Tags