001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.openjpa.jdbc.meta.strats;
020:
021: import java.sql.SQLException;
022:
023: import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
024: import org.apache.openjpa.jdbc.kernel.JDBCStore;
025: import org.apache.openjpa.jdbc.meta.Embeddable;
026: import org.apache.openjpa.jdbc.meta.FieldMapping;
027: import org.apache.openjpa.jdbc.meta.Joinable;
028: import org.apache.openjpa.jdbc.meta.ValueMappingInfo;
029: import org.apache.openjpa.jdbc.schema.Column;
030: import org.apache.openjpa.jdbc.schema.ColumnIO;
031: import org.apache.openjpa.jdbc.schema.ForeignKey;
032: import org.apache.openjpa.jdbc.schema.PrimaryKey;
033: import org.apache.openjpa.jdbc.sql.Joins;
034: import org.apache.openjpa.jdbc.sql.Result;
035: import org.apache.openjpa.jdbc.sql.Row;
036: import org.apache.openjpa.jdbc.sql.RowManager;
037: import org.apache.openjpa.jdbc.sql.SQLBuffer;
038: import org.apache.openjpa.jdbc.sql.Select;
039: import org.apache.openjpa.kernel.OpenJPAStateManager;
040: import org.apache.openjpa.lib.util.Localizer;
041: import org.apache.openjpa.meta.JavaTypes;
042: import org.apache.openjpa.meta.ValueStrategies;
043: import org.apache.openjpa.util.MetaDataException;
044:
045: /**
046: * Direct mapping from a string value to a column.
047: *
048: * @author Abe White
049: * @since 0.4.0
050: */
051: public class StringFieldStrategy extends AbstractFieldStrategy
052: implements Joinable, Embeddable {
053:
054: private static final Localizer _loc = Localizer
055: .forPackage(StringFieldStrategy.class);
056:
057: public void map(boolean adapt) {
058: if (field.getTypeCode() != JavaTypes.STRING)
059: throw new MetaDataException(_loc.get("not-string", field));
060: assertNotMappedBy();
061:
062: // map join key, if any
063: field.mapJoin(adapt, false);
064: field.getKeyMapping().getValueInfo().assertNoSchemaComponents(
065: field.getKey(), !adapt);
066: field.getElementMapping().getValueInfo()
067: .assertNoSchemaComponents(field.getElement(), !adapt);
068:
069: ValueMappingInfo vinfo = field.getValueInfo();
070: vinfo.assertNoJoin(field, true);
071: vinfo.assertNoForeignKey(field, !adapt);
072:
073: // get value columns
074: Column tmpCol = new Column();
075: tmpCol.setName(field.getName());
076: tmpCol.setJavaType(field.getTypeCode());
077:
078: Column[] cols = vinfo.getColumns(field, field.getName(),
079: new Column[] { tmpCol }, field.getTable(), adapt);
080: if (field.getValueStrategy() == ValueStrategies.AUTOASSIGN)
081: cols[0].setAutoAssigned(true);
082:
083: field.setColumns(cols);
084: field.setColumnIO(vinfo.getColumnIO());
085: field.mapConstraints(field.getName(), adapt);
086:
087: // add primary key columns to table pk if logical
088: field.mapPrimaryKey(adapt);
089: PrimaryKey pk = field.getTable().getPrimaryKey();
090: if (field.isPrimaryKey() && pk != null
091: && (adapt || pk.isLogical()))
092: pk.addColumn(cols[0]);
093:
094: // set joinable
095: field.getDefiningMapping().setJoinable(field.getColumns()[0],
096: this );
097: }
098:
099: public void insert(OpenJPAStateManager sm, JDBCStore store,
100: RowManager rm) throws SQLException {
101: String str = (String) toDataStoreValue(sm.fetchString(field
102: .getIndex()), store);
103: if (field.getColumnIO().isInsertable(0, str == null)) {
104: Row row = field.getRow(sm, store, rm, Row.ACTION_INSERT);
105: if (row != null)
106: row.setString(field.getColumns()[0], str);
107: }
108: }
109:
110: public void update(OpenJPAStateManager sm, JDBCStore store,
111: RowManager rm) throws SQLException {
112: String str = (String) toDataStoreValue(sm.fetchString(field
113: .getIndex()), store);
114: if (field.getColumnIO().isUpdatable(0, str == null)) {
115: Row row = field.getRow(sm, store, rm, Row.ACTION_UPDATE);
116: if (row != null)
117: row.setString(field.getColumns()[0], str);
118: }
119: }
120:
121: public void delete(OpenJPAStateManager sm, JDBCStore store,
122: RowManager rm) throws SQLException {
123: field.deleteRow(sm, store, rm);
124: }
125:
126: public Object toDataStoreValue(Object val, JDBCStore store) {
127: if (val != null)
128: return val;
129:
130: if (field.getNullValue() != FieldMapping.NULL_DEFAULT)
131: return null;
132: if (field.getColumns()[0].getDefaultString() != null)
133: return null;
134: // honor the user's null-value=default
135: return "";
136: }
137:
138: public int supportsSelect(Select sel, int type,
139: OpenJPAStateManager sm, JDBCStore store,
140: JDBCFetchConfiguration fetch) {
141: if (type == Select.TYPE_JOINLESS
142: && sel.isSelected(field.getTable()))
143: return 1;
144: return 0;
145: }
146:
147: public int select(Select sel, OpenJPAStateManager sm,
148: JDBCStore store, JDBCFetchConfiguration fetch, int eagerMode) {
149: sel.select(field.getColumns()[0], field.join(sel));
150: return 1;
151: }
152:
153: public void load(OpenJPAStateManager sm, JDBCStore store,
154: JDBCFetchConfiguration fetch, Result res)
155: throws SQLException {
156: Column col = field.getColumns()[0];
157: if (res.contains(col))
158: sm.storeString(field.getIndex(), res.getString(col));
159: }
160:
161: public void appendIsNull(SQLBuffer sql, Select sel, Joins joins) {
162: joins = join(joins, false);
163: sql.append(sel.getColumnAlias(field.getColumns()[0], joins))
164: .append(" IS ")
165: .appendValue(null, field.getColumns()[0]);
166: }
167:
168: public void appendIsNotNull(SQLBuffer sql, Select sel, Joins joins) {
169: joins = join(joins, false);
170: sql.append(sel.getColumnAlias(field.getColumns()[0], joins))
171: .append(" IS NOT ").appendValue(null,
172: field.getColumns()[0]);
173: }
174:
175: public Joins join(Joins joins, boolean forceOuter) {
176: return field.join(joins, forceOuter, false);
177: }
178:
179: public Object loadProjection(JDBCStore store,
180: JDBCFetchConfiguration fetch, Result res, Joins joins)
181: throws SQLException {
182: return res.getString(field.getColumns()[0], joins);
183: }
184:
185: public boolean isVersionable() {
186: return true;
187: }
188:
189: public void where(OpenJPAStateManager sm, JDBCStore store,
190: RowManager rm, Object prevValue) throws SQLException {
191: Row row = field.getRow(sm, store, rm, Row.ACTION_UPDATE);
192: if (row == null)
193: return;
194:
195: Column col = field.getColumns()[0];
196: if (prevValue == null)
197: row.whereNull(col);
198: else
199: row.whereString(col, prevValue.toString());
200: }
201:
202: ///////////////////////////
203: // Joinable implementation
204: ///////////////////////////
205:
206: public int getFieldIndex() {
207: return field.getIndex();
208: }
209:
210: public Object getPrimaryKeyValue(Result res, Column[] cols,
211: ForeignKey fk, JDBCStore store, Joins joins)
212: throws SQLException {
213: Column col = cols[0];
214: if (fk != null)
215: col = fk.getColumn(col);
216: return res.getString(col, joins);
217: }
218:
219: public Column[] getColumns() {
220: return field.getColumns();
221: }
222:
223: public Object getJoinValue(Object fieldVal, Column col,
224: JDBCStore store) {
225: return fieldVal;
226: }
227:
228: public Object getJoinValue(OpenJPAStateManager sm, Column col,
229: JDBCStore store) {
230: return sm.fetch(field.getIndex());
231: }
232:
233: public void setAutoAssignedValue(OpenJPAStateManager sm,
234: JDBCStore store, Column col, Object autoInc) {
235: String str = (autoInc == null) ? null : autoInc.toString();
236: sm.storeString(field.getIndex(), str);
237: }
238:
239: /////////////////////////////
240: // Embeddable implementation
241: /////////////////////////////
242:
243: public ColumnIO getColumnIO() {
244: return field.getColumnIO();
245: }
246:
247: public Object[] getResultArguments() {
248: return null;
249: }
250:
251: public Object toEmbeddedDataStoreValue(Object val, JDBCStore store) {
252: return toDataStoreValue(val, store);
253: }
254:
255: public Object toEmbeddedObjectValue(Object val) {
256: return val;
257: }
258:
259: public void loadEmbedded(OpenJPAStateManager sm, JDBCStore store,
260: JDBCFetchConfiguration fetch, Object val)
261: throws SQLException {
262: sm.storeString(field.getIndex(), (String) val);
263: }
264: }
|