You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pc...@apache.org on 2006/07/19 23:35:07 UTC
svn commit: r423615 [21/44] - in /incubator/openjpa/trunk: ./
openjpa-jdbc-5/ openjpa-jdbc-5/src/ openjpa-jdbc-5/src/main/
openjpa-jdbc-5/src/main/java/ openjpa-jdbc-5/src/main/java/org/
openjpa-jdbc-5/src/main/java/org/apache/ openjpa-jdbc-5/src/main/...
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerHandlerMapTableFieldStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerHandlerMapTableFieldStrategy.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerHandlerMapTableFieldStrategy.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerHandlerMapTableFieldStrategy.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.openjpa.jdbc.kernel.JDBCFetchState;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.ValueHandler;
+import org.apache.openjpa.jdbc.meta.ValueMapping;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.ColumnIO;
+import org.apache.openjpa.jdbc.sql.Joins;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.jdbc.sql.Row;
+import org.apache.openjpa.jdbc.sql.RowManager;
+import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.ChangeTracker;
+import org.apache.openjpa.util.MetaDataException;
+import org.apache.openjpa.util.Proxies;
+import org.apache.openjpa.util.Proxy;
+
+/**
+ * Mapping for a map of keys and values both controlled by
+ * {@link ValueHandler}s.
+ *
+ * @author Abe White
+ * @since 4.0
+ */
+public class HandlerHandlerMapTableFieldStrategy
+ extends MapTableFieldStrategy {
+
+ private static final Localizer _loc = Localizer.forPackage
+ (HandlerHandlerMapTableFieldStrategy.class);
+
+ private Column[] _kcols = null;
+ private ColumnIO _kio = null;
+ private boolean _kload = false;
+ private Column[] _vcols = null;
+ private ColumnIO _vio = null;
+ private boolean _vload = false;
+
+ public Column[] getKeyColumns(ClassMapping cls) {
+ return _kcols;
+ }
+
+ public Column[] getValueColumns(ClassMapping cls) {
+ return _vcols;
+ }
+
+ public void selectKey(Select sel, ClassMapping cls, OpenJPAStateManager sm,
+ JDBCStore store, JDBCFetchState fetchState, Joins joins) {
+ sel.select(_kcols, joins);
+ }
+
+ public void selectValue(Select sel, ClassMapping cls,
+ OpenJPAStateManager sm,
+ JDBCStore store, JDBCFetchState fetchState, Joins joins) {
+ sel.select(_vcols, joins);
+ }
+
+ public Result[] getResults(OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState, int eagerMode, Joins[] joins, boolean lrs)
+ throws SQLException {
+ Select sel = store.getSQLFactory().newSelect();
+ sel.setLRS(lrs);
+ sel.select(_kcols);
+ sel.select(_vcols);
+ sel.whereForeignKey(field.getJoinForeignKey(), sm.getObjectId(),
+ field.getDefiningMapping(), store);
+ Result res = sel.execute(store,
+ fetchState.getJDBCFetchConfiguration());
+ return new Result[]{ res, res };
+ }
+
+ public Object loadKey(OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState, Result res, Joins joins)
+ throws SQLException {
+ return HandlerStrategies.loadObject(field.getKeyMapping(),
+ sm, store, fetchState, res, joins, _kcols, _kload);
+ }
+
+ public Object loadValue(OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState, Result res, Joins joins)
+ throws SQLException {
+ return HandlerStrategies.loadObject(field.getElementMapping(),
+ sm, store, fetchState, res, joins, _vcols, _vload);
+ }
+
+ public void map(boolean adapt) {
+ super.map(adapt);
+
+ ValueMapping key = field.getKeyMapping();
+ if (key.getHandler() == null)
+ throw new MetaDataException(_loc.get("no-handler", key));
+ ValueMapping val = field.getElementMapping();
+ if (val.getHandler() == null)
+ throw new MetaDataException(_loc.get("no-handler", val));
+ assertNotMappedBy();
+
+ field.mapJoin(adapt, true);
+ _kio = new ColumnIO();
+ _kcols = HandlerStrategies.map(key, "key", _kio, adapt);
+ _vio = new ColumnIO();
+ _vcols = HandlerStrategies.map(val, "value", _vio, adapt);
+ field.mapPrimaryKey(adapt);
+ }
+
+ public void initialize() {
+ _kload = field.getKeyMapping().getHandler().
+ objectValueRequiresLoad(field.getKeyMapping());
+ _vload = field.getElementMapping().getHandler().
+ objectValueRequiresLoad(field.getElementMapping());
+ }
+
+ public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+ throws SQLException {
+ insert(sm, store, rm, (Map) sm.fetchObject(field.getIndex()));
+ }
+
+ private void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm,
+ Map map)
+ throws SQLException {
+ if (map == null || map.isEmpty())
+ return;
+
+ Row row = rm.getSecondaryRow(field.getTable(), Row.ACTION_INSERT);
+ row.setForeignKey(field.getJoinForeignKey(), field.getJoinColumnIO(),
+ sm);
+
+ ValueMapping key = field.getKeyMapping();
+ ValueMapping val = field.getElementMapping();
+ Map.Entry entry;
+ for (Iterator itr = map.entrySet().iterator(); itr.hasNext();) {
+ entry = (Map.Entry) itr.next();
+ HandlerStrategies.set(key, entry.getKey(), store, row, _kcols,
+ _kio, true);
+ HandlerStrategies.set(val, entry.getValue(), store, row, _vcols,
+ _vio, true);
+ rm.flushSecondaryRow(row);
+ }
+ }
+
+ public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+ throws SQLException {
+ Map map = (Map) sm.fetchObject(field.getIndex());
+ ChangeTracker ct = null;
+ if (map instanceof Proxy) {
+ Proxy proxy = (Proxy) map;
+ if (Proxies.isOwner(proxy, sm, field.getIndex()))
+ ct = proxy.getChangeTracker();
+ }
+
+ // if no fine-grained change tracking then just delete and reinsert
+ if (ct == null || !ct.isTracking()) {
+ delete(sm, store, rm);
+ insert(sm, store, rm, map);
+ return;
+ }
+
+ // delete the removes
+ ValueMapping key = field.getKeyMapping();
+ Collection rem = ct.getRemoved();
+ if (!rem.isEmpty()) {
+ Row delRow = rm.getSecondaryRow(field.getTable(),
+ Row.ACTION_DELETE);
+ delRow.setForeignKey(field.getJoinForeignKey(),
+ field.getJoinColumnIO(), sm);
+ for (Iterator itr = rem.iterator(); itr.hasNext();) {
+ HandlerStrategies.where(key, itr.next(), store, delRow,
+ _kcols);
+ rm.flushSecondaryRow(delRow);
+ }
+ }
+
+ // insert the adds
+ ValueMapping val = field.getElementMapping();
+ Collection add = ct.getAdded();
+ Object mkey;
+ if (!add.isEmpty()) {
+ Row addRow = rm.getSecondaryRow(field.getTable(),
+ Row.ACTION_INSERT);
+ addRow.setForeignKey(field.getJoinForeignKey(),
+ field.getJoinColumnIO(), sm);
+
+ for (Iterator itr = add.iterator(); itr.hasNext();) {
+ mkey = itr.next();
+ HandlerStrategies.set(key, mkey, store, addRow, _kcols,
+ _kio, true);
+ HandlerStrategies.set(val, map.get(mkey), store, addRow,
+ _vcols, _vio, true);
+ rm.flushSecondaryRow(addRow);
+ }
+ }
+
+ // update the changes
+ Collection change = ct.getChanged();
+ if (!change.isEmpty()) {
+ Row changeRow = rm.getSecondaryRow(field.getTable(),
+ Row.ACTION_UPDATE);
+ changeRow.whereForeignKey(field.getJoinForeignKey(), sm);
+
+ for (Iterator itr = change.iterator(); itr.hasNext();) {
+ mkey = itr.next();
+ HandlerStrategies.where(key, mkey, store, changeRow, _kcols);
+ HandlerStrategies.set(val, map.get(mkey), store, changeRow,
+ _vcols, _vio, true);
+ rm.flushSecondaryRow(changeRow);
+ }
+ }
+ }
+
+ public Object toDataStoreValue(Object val, JDBCStore store) {
+ return HandlerStrategies.toDataStoreValue(field.getElementMapping(),
+ val, _vcols, store);
+ }
+
+ public Object toKeyDataStoreValue(Object val, JDBCStore store) {
+ return HandlerStrategies.toDataStoreValue(field.getKeyMapping(), val,
+ _kcols, store);
+ }
+
+ public Joins joinRelation(Joins joins, boolean forceOuter,
+ boolean traverse) {
+ if (traverse)
+ HandlerStrategies.assertJoinable(field.getElementMapping());
+ return joins;
+ }
+
+ public Joins joinKeyRelation(Joins joins, boolean forceOuter,
+ boolean traverse) {
+ if (traverse)
+ HandlerStrategies.assertJoinable(field.getKeyMapping());
+ return joins;
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerHandlerMapTableFieldStrategy.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerStrategies.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerStrategies.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerStrategies.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerStrategies.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,258 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.sql.SQLException;
+
+import org.apache.openjpa.jdbc.kernel.JDBCFetchState;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.RelationId;
+import org.apache.openjpa.jdbc.meta.ValueHandler;
+import org.apache.openjpa.jdbc.meta.ValueMapping;
+import org.apache.openjpa.jdbc.meta.ValueMappingInfo;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.ColumnIO;
+import org.apache.openjpa.jdbc.sql.Joins;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.jdbc.sql.Row;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.InvalidStateException;
+
+/**
+ * Utility methods for strategies using value handlers.
+ *
+ * @author Abe White
+ * @since 4.0
+ */
+public class HandlerStrategies {
+
+ private static final Localizer _loc = Localizer.forPackage
+ (HandlerStrategies.class);
+
+ /**
+ * Map the given value.
+ */
+ public static Column[] map(ValueMapping vm, String name, ColumnIO io,
+ boolean adapt) {
+ ValueMappingInfo vinfo = vm.getValueInfo();
+ vinfo.assertNoJoin(vm, true);
+ vinfo.assertNoForeignKey(vm, !adapt);
+
+ Column[] cols = vm.getHandler().map(vm, name, io, adapt);
+ if (cols.length > 0 && cols[0].getTable() == null) {
+ cols = vinfo.getColumns(vm, name, cols,
+ vm.getFieldMapping().getTable(), adapt);
+ ColumnIO mappedIO = vinfo.getColumnIO();
+ vm.setColumns(cols);
+ vm.setColumnIO(mappedIO);
+ if (mappedIO != null) {
+ for (int i = 0; i < cols.length; i++) {
+ io.setInsertable(i, mappedIO.isInsertable(i, false));
+ io.setNullInsertable(i, mappedIO.isInsertable(i, true));
+ io.setUpdatable(i, mappedIO.isUpdatable(i, false));
+ io.setNullUpdatable(i, mappedIO.isUpdatable(i, true));
+ }
+ }
+ }
+ vm.mapConstraints(name, adapt);
+ return cols;
+ }
+
+ /**
+ * Set the given value into the given row.
+ */
+ public static void set(ValueMapping vm, Object val, JDBCStore store,
+ Row row, Column[] cols, ColumnIO io, boolean nullNone)
+ throws SQLException {
+ if (!canSetAny(row, io, cols))
+ return;
+
+ ValueHandler handler = vm.getHandler();
+ val = handler.toDataStoreValue(vm, val, store);
+ if (val == null) {
+ for (int i = 0; i < cols.length; i++)
+ if (canSet(row, io, i, true))
+ set(row, cols[i], null, handler, nullNone);
+ } else if (cols.length == 1) {
+ if (canSet(row, io, 0, val == null))
+ set(row, cols[0], val, handler, nullNone);
+ } else {
+ Object[] vals = (Object[]) val;
+ for (int i = 0; i < vals.length; i++)
+ if (canSet(row, io, i, vals[i] == null))
+ set(row, cols[i], vals[i], handler, nullNone);
+ }
+ }
+
+ /**
+ * Return true if the given column index is settable.
+ */
+ private static boolean canSet(Row row, ColumnIO io, int i,
+ boolean nullValue) {
+ if (row.getAction() == Row.ACTION_INSERT)
+ return io.isInsertable(i, nullValue);
+ if (row.getAction() == Row.ACTION_UPDATE)
+ return io.isUpdatable(i, nullValue);
+ return true;
+ }
+
+ /**
+ * Return true if the any column up to the given index is settable.
+ */
+ private static boolean canSetAny(Row row, ColumnIO io, Column[] cols) {
+ if (row.getAction() == Row.ACTION_INSERT)
+ return io.isAnyInsertable(cols, false);
+ if (row.getAction() == Row.ACTION_UPDATE)
+ return io.isAnyUpdatable(cols, false);
+ return true;
+ }
+
+ /**
+ * Set a value into a row, taking care not to override column defualts
+ * with nulls unless the user wants us to.
+ */
+ private static void set(Row row, Column col, Object val,
+ ValueHandler handler, boolean nullNone)
+ throws SQLException {
+ if (val == null)
+ row.setNull(col, nullNone);
+ else if (col.isRelationId() && handler instanceof RelationId)
+ row.setRelationId(col, (OpenJPAStateManager) val,
+ (RelationId) handler);
+ else
+ row.setObject(col, val);
+ }
+
+ /**
+ * Add where conditions to the given row.
+ */
+ public static void where(ValueMapping vm, Object val, JDBCStore store,
+ Row row, Column[] cols)
+ throws SQLException {
+ if (cols.length == 0)
+ return;
+
+ val = toDataStoreValue(vm, val, cols, store);
+ if (val == null)
+ for (int i = 0; i < cols.length; i++)
+ row.whereNull(cols[i]);
+ else if (cols.length == 1)
+ where(row, cols[0], val);
+ else {
+ Object[] vals = (Object[]) val;
+ for (int i = 0; i < vals.length; i++)
+ where(row, cols[i], vals[i]);
+ }
+ }
+
+ /**
+ * Set a where condition on the given row.
+ */
+ private static void where(Row row, Column col, Object val)
+ throws SQLException {
+ if (val == null)
+ row.whereNull(col);
+ else
+ row.whereObject(col, val);
+ }
+
+ /**
+ * Load the Object value from the given result.
+ */
+ public static Object loadObject(ValueMapping vm, OpenJPAStateManager sm,
+ JDBCStore store, JDBCFetchState fetchState, Result res,
+ Joins joins, Column[] cols, boolean objectValueRequiresLoad)
+ throws SQLException {
+ if (cols.length == 0)
+ throw new InvalidStateException(_loc.get("cant-project-owned",
+ vm));
+
+ Object val = loadDataStore(vm, res, joins, cols);
+ if (objectValueRequiresLoad)
+ return vm.getHandler().toObjectValue(vm, val, sm, store,
+ fetchState);
+ return vm.getHandler().toObjectValue(vm, val);
+ }
+
+ /**
+ * Load the datastore value from the given result. This method does
+ * <b>not</b> process the loaded value through
+ * {@link ValueHandler#toObjectValue}.
+ */
+ public static Object loadDataStore(ValueMapping vm, Result res,
+ Joins joins, Column[] cols)
+ throws SQLException {
+ if (cols.length == 0)
+ return null;
+ if (cols.length == 1)
+ return res.getObject(cols[0], vm.getHandler().
+ getResultArgument(vm), joins);
+
+ Object[] vals = new Object[cols.length];
+ Object[] args = (Object[]) vm.getHandler().getResultArgument(vm);
+ for (int i = 0; i < cols.length; i++)
+ vals[i] = res.getObject(cols[i], (args == null) ? null : args[i],
+ joins);
+ return vals;
+ }
+
+ /**
+ * Convert the given object to its datastore value(s). Relation ids are
+ * converted to their final values immediately.
+ */
+ public static Object toDataStoreValue(ValueMapping vm, Object val,
+ Column[] cols, JDBCStore store) {
+ ValueHandler handler = vm.getHandler();
+ val = handler.toDataStoreValue(vm, val, store);
+ if (val == null) {
+ if (cols.length > 1)
+ return new Object[cols.length];
+ return null;
+ }
+
+ // relation ids are returned as state managers; resolve the final
+ // datastore value immediately
+ Object[] vals;
+ for (int i = 0; i < cols.length; i++) {
+ if (!cols[i].isRelationId())
+ continue;
+ if (!(handler instanceof RelationId))
+ break;
+ if (cols.length == 1) {
+ val = ((RelationId) handler).toRelationDataStoreValue
+ ((OpenJPAStateManager) val, cols[i]);
+ } else {
+ vals = (Object[]) val;
+ vals[i] = ((RelationId) handler).toRelationDataStoreValue
+ ((OpenJPAStateManager) vals[i], cols[i]);
+ }
+ }
+ return val;
+ }
+
+ /**
+ * Throw the proper exception if the given handler-controlled value
+ * represents an unjoinable relation.
+ */
+ public static void assertJoinable(ValueMapping vm) {
+ ClassMapping rel = vm.getTypeMapping();
+ if (rel != null && (rel.getTable() == null
+ || !rel.getTable().equals(vm.getFieldMapping().getTable())))
+ throw RelationStrategies.unjoinable(vm);
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerStrategies.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/IdentityJoinable.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/IdentityJoinable.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/IdentityJoinable.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/IdentityJoinable.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.sql.SQLException;
+
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.Joinable;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.ForeignKey;
+import org.apache.openjpa.jdbc.sql.Joins;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.util.Id;
+import serp.util.Numbers;
+
+/**
+ * {@link Joinable} for the datastore identity column.
+ *
+ * @author Abe White
+ */
+class IdentityJoinable
+ implements Joinable {
+
+ private final ClassMapping mapping;
+
+ /**
+ * Constructor; supply datastore identity mapping.
+ */
+ public IdentityJoinable(ClassMapping mapping) {
+ this.mapping = mapping;
+ }
+
+ public int getFieldIndex() {
+ return -1;
+ }
+
+ public Object getPrimaryKeyValue(Result res, Column[] cols, ForeignKey fk,
+ Joins joins)
+ throws SQLException {
+ Column col = cols[0];
+ if (fk != null)
+ col = fk.getColumn(col);
+ long id = res.getLong(col);
+ if (id == 0 && res.wasNull())
+ return null;
+ return Numbers.valueOf(id);
+ }
+
+ public Column[] getColumns() {
+ return mapping.getPrimaryKeyColumns();
+ }
+
+ public Object getJoinValue(Object val, Column col, JDBCStore store) {
+ return val;
+ }
+
+ public Object getJoinValue(OpenJPAStateManager sm, Column col,
+ JDBCStore store) {
+ return Numbers.valueOf(((Id) sm.getObjectId()).getId());
+ }
+
+ public void setAutoAssignedValue(OpenJPAStateManager sm, JDBCStore store,
+ Column col, Object autogen) {
+ long id = ((Number) autogen).longValue();
+ sm.setObjectId(store.newDataStoreId(id, (ClassMapping)
+ sm.getMetaData(), true));
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/IdentityJoinable.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ImmutableValueHandler.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ImmutableValueHandler.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ImmutableValueHandler.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ImmutableValueHandler.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
+import org.apache.openjpa.jdbc.meta.ValueMapping;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.ColumnIO;
+import org.apache.openjpa.meta.JavaTypes;
+
+/**
+ * Handler for simple type and string values.
+ *
+ * @nojavadoc
+ */
+public class ImmutableValueHandler
+ extends AbstractValueHandler {
+
+ private static final ImmutableValueHandler _instance =
+ new ImmutableValueHandler();
+
+ /**
+ * Singleton instance.
+ */
+ public static ImmutableValueHandler getInstance() {
+ return _instance;
+ }
+
+ public Column[] map(ValueMapping vm, String name, ColumnIO io,
+ boolean adapt) {
+ Column col = new Column();
+ col.setName(name);
+ if (vm.getTypeCode() == JavaTypes.DATE)
+ col.setJavaType(JavaSQLTypes.getDateTypeCode(vm.getType()));
+ else
+ col.setJavaType(vm.getTypeCode());
+ return new Column[]{ col };
+ }
+
+ public boolean isVersionable(ValueMapping vm) {
+ switch (vm.getTypeCode()) {
+ case JavaTypes.BOOLEAN:
+ case JavaTypes.BYTE:
+ case JavaTypes.CHAR:
+ case JavaTypes.INT:
+ case JavaTypes.LONG:
+ case JavaTypes.SHORT:
+ case JavaTypes.BOOLEAN_OBJ:
+ case JavaTypes.BYTE_OBJ:
+ case JavaTypes.CHAR_OBJ:
+ case JavaTypes.INT_OBJ:
+ case JavaTypes.LONG_OBJ:
+ case JavaTypes.SHORT_OBJ:
+ case JavaTypes.STRING:
+ case JavaTypes.DATE:
+ case JavaTypes.BIGINTEGER:
+ case JavaTypes.LOCALE:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public Object toDataStoreValue(ValueMapping vm, Object val,
+ JDBCStore store) {
+ if (val != null)
+ return val;
+
+ FieldMapping field = vm.getFieldMapping();
+ if (field.getNullValue() != FieldMapping.NULL_DEFAULT)
+ return null;
+
+ Column[] cols = vm.getColumns();
+ if (cols[0].getDefaultString() != null)
+ return null;
+
+ // honor the user's null-value=default
+ return JavaSQLTypes.getEmptyValue(vm.getTypeCode());
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ImmutableValueHandler.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/InValueDiscriminatorStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/InValueDiscriminatorStrategy.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/InValueDiscriminatorStrategy.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/InValueDiscriminatorStrategy.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.sql.SQLException;
+
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.DiscriminatorMappingInfo;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.Index;
+import org.apache.openjpa.jdbc.sql.Joins;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.jdbc.sql.Row;
+import org.apache.openjpa.jdbc.sql.RowManager;
+import org.apache.openjpa.jdbc.sql.SQLBuffer;
+import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.util.MetaDataException;
+
+/**
+ * Base discriminator strategy that determines the class of database
+ * records using a column holding a value mapped to a class, and limits
+ * SELECTs using an IN (...) statement.
+ *
+ * @author Abe White
+ */
+public abstract class InValueDiscriminatorStrategy
+ extends AbstractDiscriminatorStrategy {
+
+ private static final Localizer _loc = Localizer.forPackage
+ (InValueDiscriminatorStrategy.class);
+
+ /**
+ * Return the Java type code from {@link JavaTypes} for the discriminator
+ * values. This method is only used during mapping installation.
+ */
+ protected abstract int getJavaType();
+
+ /**
+ * Return the discriminator value for the given type.
+ */
+ protected abstract Object getDiscriminatorValue(ClassMapping cls);
+
+ /**
+ * Convert the given discriminator value to the corresponding class.
+ */
+ protected abstract Class getClass(Object val, JDBCStore store)
+ throws ClassNotFoundException;
+
+ public void map(boolean adapt) {
+ ClassMapping cls = disc.getClassMapping();
+ if (cls.getJoinablePCSuperclassMapping() != null
+ || cls.getEmbeddingMetaData() != null)
+ throw new MetaDataException(_loc.get("not-base-disc", cls));
+
+ DiscriminatorMappingInfo info = disc.getMappingInfo();
+ info.assertNoJoin(disc, true);
+ info.assertNoForeignKey(disc, !adapt);
+ info.assertNoUnique(disc, false);
+
+ Column tmplate = new Column();
+ tmplate.setJavaType(getJavaType());
+ tmplate.setName("typ");
+
+ Column[] cols = info.getColumns(disc, new Column[]{ tmplate }, adapt);
+ disc.setColumns(cols);
+ disc.setColumnIO(info.getColumnIO());
+
+ Index idx = info.getIndex(disc, cols, adapt);
+ disc.setIndex(idx);
+ }
+
+ public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+ throws SQLException {
+ Row row = rm.getRow(disc.getClassMapping().getTable(),
+ Row.ACTION_INSERT, sm, true);
+ Object cls = getDiscriminatorValue((ClassMapping) sm.getMetaData());
+ if (disc.getColumnIO().isInsertable(0, cls == null))
+ row.setObject(disc.getColumns()[0], cls);
+ }
+
+ public boolean select(Select sel, ClassMapping mapping) {
+ if (isFinal)
+ return false;
+ sel.select(disc.getColumns());
+ return true;
+ }
+
+ public Class getClass(JDBCStore store, ClassMapping base, Result res)
+ throws SQLException, ClassNotFoundException {
+ if (isFinal || !res.contains(disc.getColumns()[0])
+ || (base.getPCSuperclass() == null
+ && base.getJoinablePCSubclassMappings().length == 0))
+ return base.getDescribedType();
+
+ Object cls = res.getObject(disc.getColumns()[0], -1, null);
+ return getClass(cls, store);
+ }
+
+ public SQLBuffer getClassConditions(JDBCStore store, Select sel,
+ Joins joins, ClassMapping base, boolean subclasses) {
+ // if selecting the first mapped class and all subclasses, no need
+ // to limit the query
+ if (isFinal || (base.getJoinablePCSuperclassMapping() == null
+ && subclasses))
+ return null;
+
+ // if no subclasses or superclass, no need for conditions
+ ClassMapping[] subs = base.getJoinablePCSubclassMappings();
+ if (subs.length == 0 && base.getJoinablePCSuperclassMapping() == null)
+ return null;
+
+ // if not selecting subclasses, limit to just the given class
+ Column col = disc.getColumns()[0];
+ SQLBuffer sql = new SQLBuffer(store.getDBDictionary());
+ sql.append(sel.getColumnAlias(col, joins));
+ if (!subclasses || subs.length == 0)
+ return sql.append(" = ").appendValue(getDiscriminatorValue(base),
+ col);
+
+ sql.append(" IN (");
+ sql.appendValue(getDiscriminatorValue(base), col);
+ for (int i = 0; i < subs.length; i++)
+ sql.append(", ").appendValue(getDiscriminatorValue(subs[i]), col);
+ sql.append(")");
+ return sql;
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/InValueDiscriminatorStrategy.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LRSCollectionFieldStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LRSCollectionFieldStrategy.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LRSCollectionFieldStrategy.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LRSCollectionFieldStrategy.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.sql.SQLException;
+
+import org.apache.openjpa.jdbc.kernel.JDBCFetchState;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.meta.FieldStrategy;
+import org.apache.openjpa.jdbc.meta.ValueMapping;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.ForeignKey;
+import org.apache.openjpa.jdbc.sql.Joins;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+
+/**
+ * Interface implemented by collection strategies so that they can
+ * support large result set collections.
+ *
+ * @author Abe White
+ */
+public interface LRSCollectionFieldStrategy
+ extends FieldStrategy {
+
+ /**
+ * The owning field mapping.
+ */
+ public FieldMapping getFieldMapping();
+
+ /**
+ * Return all independent mappings to which this strategy must join in
+ * order to access collection elements, or empty array if none.
+ *
+ * @param traverse whether we're traversing through to the related type
+ * @see ValueMapping#getIndependentTypeMappings
+ * @see ClassMapping#EMPTY_MAPPINGS
+ */
+ public ClassMapping[] getIndependentElementMappings(boolean traverse);
+
+ /**
+ * Return the foreign key used to join to the owning field for the given
+ * element mapping from {@link #getIndependentElementMappings} (or null).
+ */
+ public ForeignKey getJoinForeignKey(ClassMapping elem);
+
+ /**
+ * Return the columns holding the data for a collection element for the
+ * given element mapping from {@link #getIndependentElementMappings}
+ * (or null).
+ */
+ public Column[] getElementColumns(ClassMapping elem);
+
+ /**
+ * Implement this method to select the elements of this field for the
+ * given element mapping from {@link #getIndependentElementMappings}
+ * (or null). Elements of the result will be loaded with
+ * {@link #loadElement}.
+ */
+ public void selectElement(Select sel, ClassMapping elem,
+ JDBCStore store, JDBCFetchState fetchState, int eagerMode,
+ Joins joins);
+
+ /**
+ * Load an element of the collection. The given state manager might be
+ * null if the load is for a projection or for processing eager parallel
+ * results.
+ */
+ public Object loadElement(OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState, Result res, Joins joins)
+ throws SQLException;
+
+ /**
+ * Join this value's table to the table for the given element mapping
+ * from {@link #getIndependentElementMappings} (or null).
+ *
+ * @see FieldMapping#joinRelation
+ */
+ public Joins joinElementRelation(Joins joins, ClassMapping elem);
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LRSCollectionFieldStrategy.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LRSMapFieldStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LRSMapFieldStrategy.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LRSMapFieldStrategy.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LRSMapFieldStrategy.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.sql.SQLException;
+
+import org.apache.openjpa.jdbc.kernel.JDBCFetchState;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.meta.FieldStrategy;
+import org.apache.openjpa.jdbc.meta.ValueMapping;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.schema.ForeignKey;
+import org.apache.openjpa.jdbc.sql.Joins;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+
+/**
+ * Interface implemented by map strategies so that they can
+ * support large result set maps.
+ *
+ * @author Abe White
+ */
+public interface LRSMapFieldStrategy
+ extends FieldStrategy {
+
+ /**
+ * The owning field mapping.
+ */
+ public FieldMapping getFieldMapping();
+
+ /**
+ * Return all independent mappings to which this strategy must join in
+ * order to access map keys, or empty array if none.
+ *
+ * @see ValueMapping#getIndependentTypeMappings
+ * @see ClassMapping#EMPTY_MAPPINGS
+ */
+ public ClassMapping[] getIndependentKeyMappings(boolean traverse);
+
+ /**
+ * Return all independent mappings to which this strategy must join in
+ * order to access map values, or empty array if none.
+ *
+ * @see ValueMapping#getIndependentTypeMappings
+ * @see ClassMapping#EMPTY_MAPPINGS
+ */
+ public ClassMapping[] getIndependentValueMappings(boolean traverse);
+
+ /**
+ * Return the foreign key used to join to the owning field for the given
+ * mapping from either {@link #getIndependentKeyMappings} or
+ * {@link #getIndependentValueMappings} (or null).
+ */
+ public ForeignKey getJoinForeignKey(ClassMapping cls);
+
+ /**
+ * Return the columns holding data for a map key for the given key mapping
+ * from {@link #getIndependentKeyMappings} or
+ * {@link #getIndependentValueMappings} (or null).
+ */
+ public Column[] getKeyColumns(ClassMapping cls);
+
+ /**
+ * Return the columns holding data for a map value for the given value
+ * mapping from {@link #getIndependentKeyMappings} or
+ * {@link #getIndependentValueMappings} (or null).
+ */
+ public Column[] getValueColumns(ClassMapping cls);
+
+ /**
+ * Implement this method to select the keys of this field.
+ * Elements of the result will be loaded with {@link #loadKey}.
+ * This method is only used if the key is not derived from the value.
+ */
+ public void selectKey(Select sel, ClassMapping key, OpenJPAStateManager sm,
+ JDBCStore store, JDBCFetchState fetchState, Joins joins);
+
+ /**
+ * Load a key from the given result.
+ * This method is only used if the key is not derived from the value.
+ */
+ public Object loadKey(OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState, Result res, Joins joins)
+ throws SQLException;
+
+ /**
+ * Some mapping derive keys from map values. Other mappings may return null.
+ */
+ public Object deriveKey(JDBCStore store, Object value);
+
+ /**
+ * Some mapping derive values from map keys. Other mappings may return null.
+ */
+ public Object deriveValue(JDBCStore store, Object key);
+
+ /**
+ * Implement this method to select the values of this field.
+ * Elements of the result will be loaded with {@link #loadValue}.
+ */
+ public void selectValue(Select sel, ClassMapping val,
+ OpenJPAStateManager sm,
+ JDBCStore store, JDBCFetchState fetchState, Joins joins);
+
+ /**
+ * Load a value from the given result.
+ */
+ public Object loadValue(OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState, Result res, Joins joins)
+ throws SQLException;
+
+ /**
+ * Return results containing all keys and values for this map. If only
+ * one result is needed, set both array indexes to the same result
+ * instance. Also fill in the key and value joins in the given array.
+ * The results will be loaded with the {@link #loadKey} or
+ * {@link #deriveKey} and {@link #loadValue} methods.
+ */
+ public Result[] getResults(OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState, int eagerMode, Joins[] joins, boolean lrs)
+ throws SQLException;
+
+ /**
+ * Join this value's table to the table for the given key mapping
+ * from {@link #getIndependentKeyMappings} (or null).
+ */
+ public Joins joinKeyRelation(Joins joins, ClassMapping key);
+
+ /**
+ * Join this value's table to the table for the given value mapping
+ * from {@link #getIndependentValueMappings} (or null).
+ */
+ public Joins joinValueRelation(Joins joins, ClassMapping val);
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LRSMapFieldStrategy.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LRSProxyCollection.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LRSProxyCollection.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LRSProxyCollection.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LRSProxyCollection.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.sql.SQLException;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
+import org.apache.openjpa.jdbc.kernel.JDBCFetchState;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.sql.Joins;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.jdbc.sql.SQLBuffer;
+import org.apache.openjpa.jdbc.sql.SQLExceptions;
+import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.jdbc.sql.Union;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.lib.util.Closeable;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.AbstractLRSProxyCollection;
+import org.apache.openjpa.util.InvalidStateException;
+
+/**
+ * Large result set collection.
+ *
+ * @author Abe White
+ */
+public class LRSProxyCollection
+ extends AbstractLRSProxyCollection {
+
+ private static final Localizer _loc = Localizer.forPackage
+ (LRSProxyCollection.class);
+
+ private final LRSCollectionFieldStrategy _strat;
+
+ public LRSProxyCollection(LRSCollectionFieldStrategy strat,
+ OpenJPAConfiguration conf) {
+ super(strat.getFieldMapping().getElement().getDeclaredType(),
+ strat.getFieldMapping().getOrderColumn() != null, conf);
+ _strat = strat;
+ }
+
+ protected int count() {
+ final ClassMapping[] elems = _strat.getIndependentElementMappings
+ (false);
+ final OpenJPAStateManager sm = assertOwner();
+ final JDBCStore store = getStore();
+ Union union = store.getSQLFactory().newUnion
+ (Math.max(1, elems.length));
+ union.select(new Union.Selector() {
+ public void select(Select sel, int idx) {
+ ClassMapping elem = (elems.length == 0) ? null : elems[idx];
+ sel.whereForeignKey(_strat.getJoinForeignKey(elem),
+ sm.getObjectId(), _strat.getFieldMapping().
+ getDefiningMapping(), store);
+ }
+ });
+
+ try {
+ return union.getCount(store);
+ } catch (SQLException se) {
+ throw SQLExceptions.getStore(se, store.getDBDictionary());
+ }
+ }
+
+ protected boolean has(final Object obj) {
+ final ClassMapping[] elems = _strat.getIndependentElementMappings
+ (false);
+ final OpenJPAStateManager sm = assertOwner();
+ final JDBCStore store = getStore();
+ Union union = store.getSQLFactory().newUnion
+ (Math.max(1, elems.length));
+ union.select(new Union.Selector() {
+ public void select(Select sel, int idx) {
+ ClassMapping elem = (elems.length == 0) ? null : elems[idx];
+ sel.whereForeignKey(_strat.getJoinForeignKey(elem),
+ sm.getObjectId(), _strat.getFieldMapping().
+ getDefiningMapping(), store);
+
+ Object val = _strat.toDataStoreValue(obj, store);
+ Column[] cols = _strat.getElementColumns(elem);
+ Object[] vals = (cols.length == 1) ? null : (Object[]) val;
+ SQLBuffer sql = new SQLBuffer(store.getDBDictionary());
+ for (int i = 0; i < cols.length; i++) {
+ if (i > 0)
+ sql.append(" AND ");
+
+ sql.append(sel.getColumnAlias(cols[i]));
+ if (vals == null)
+ sql.append((val == null) ? " IS " : " = ").
+ appendValue(val, cols[i]);
+ else
+ sql.append((vals[i] == null) ? " IS " : " = ").
+ appendValue(vals[i], cols[i]);
+ }
+ sel.where(sql);
+ }
+ });
+
+ try {
+ return union.getCount(store) > 0;
+ } catch (SQLException se) {
+ throw SQLExceptions.getStore(se, store.getDBDictionary());
+ }
+ }
+
+ protected Iterator itr() {
+ final ClassMapping[] elems = _strat.getIndependentElementMappings(true);
+ final OpenJPAStateManager sm = assertOwner();
+ final JDBCStore store = getStore();
+ final JDBCFetchConfiguration fetch = store.getFetchConfiguration();
+ final JDBCFetchState fetchState =
+ (JDBCFetchState) fetch.newFetchState();
+ final Joins[] resJoins = new Joins[Math.max(1, elems.length)];
+ final FieldMapping fm = _strat.getFieldMapping();
+
+ Union union = store.getSQLFactory().newUnion
+ (Math.max(1, elems.length));
+ if (fetch.getSubclassFetchMode(fm.getElementMapping().
+ getTypeMapping()) != fetch.EAGER_JOIN)
+ union.abortUnion();
+ union.setLRS(true);
+ union.select(new Union.Selector() {
+ public void select(Select sel, int idx) {
+ ClassMapping elem = (elems.length == 0) ? null : elems[idx];
+ sel.whereForeignKey(_strat.getJoinForeignKey(elem),
+ sm.getObjectId(), fm.getDefiningMapping(), store);
+
+ // order before select in case we're faking union with
+ // multiple selects; order vals used to merge results
+ fm.orderLocal(sel, elem, null);
+ resJoins[idx] = _strat.joinElementRelation(sel.newJoins(),
+ elem);
+ fm.orderRelation(sel, elem, resJoins[idx]);
+ _strat.selectElement(sel, elem, store, fetchState,
+ fetch.EAGER_JOIN, resJoins[idx]);
+ }
+ });
+
+ try {
+ Result res = union.execute(store, fetch);
+ return new ResultIterator(sm, store, fetchState, res, resJoins);
+ } catch (SQLException se) {
+ throw SQLExceptions.getStore(se, store.getDBDictionary());
+ }
+ }
+
+ private OpenJPAStateManager assertOwner() {
+ OpenJPAStateManager sm = getOwner();
+ if (sm == null)
+ throw new InvalidStateException(_loc.get("lrs-no-owner",
+ _strat.getFieldMapping()));
+ return sm;
+ }
+
+ private JDBCStore getStore() {
+ return (JDBCStore) getOwner().getContext().getStoreManager().
+ getInnermostDelegate();
+ }
+
+ /**
+ * Closeable iterator built around a JDBC result.
+ */
+ private class ResultIterator
+ implements Iterator, Closeable {
+
+ private final OpenJPAStateManager _sm;
+ private final JDBCStore _store;
+ private final JDBCFetchState _fetchState;
+ private final Result _res;
+ private final Joins[] _joins;
+ private Boolean _next = null;
+
+ public ResultIterator(OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState, Result res, Joins[] joins) {
+ _sm = sm;
+ _store = store;
+ _fetchState = fetchState;
+ _res = res;
+ _joins = joins;
+ }
+
+ public boolean hasNext() {
+ if (_next == null) {
+ try {
+ _next = (_res.next()) ? Boolean.TRUE : Boolean.FALSE;
+ } catch (SQLException se) {
+ throw SQLExceptions.getStore(se, _store.getDBDictionary());
+ }
+ }
+ return _next.booleanValue();
+ }
+
+ public Object next() {
+ if (!hasNext())
+ throw new NoSuchElementException();
+ try {
+ _next = null;
+ return _strat.loadElement(_sm, _store, _fetchState, _res,
+ _joins[_res.indexOf()]);
+ } catch (SQLException se) {
+ throw SQLExceptions.getStore(se, _store.getDBDictionary());
+ }
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void close() {
+ _next = Boolean.FALSE;
+ _res.close();
+ }
+ }
+}
+
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LRSProxyCollection.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LRSProxyMap.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LRSProxyMap.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LRSProxyMap.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LRSProxyMap.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,430 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
+import org.apache.openjpa.jdbc.kernel.JDBCFetchState;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.sql.Joins;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.jdbc.sql.SQLBuffer;
+import org.apache.openjpa.jdbc.sql.SQLExceptions;
+import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.jdbc.sql.Union;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.lib.util.Closeable;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.AbstractLRSProxyMap;
+import org.apache.openjpa.util.InvalidStateException;
+
+/**
+ * Large result set map.
+ *
+ * @author Abe White
+ */
+class LRSProxyMap
+ extends AbstractLRSProxyMap {
+
+ private static final Localizer _loc = Localizer.forPackage
+ (LRSProxyMap.class);
+
+ private final LRSMapFieldStrategy _strat;
+
+ public LRSProxyMap(LRSMapFieldStrategy strat, OpenJPAConfiguration conf) {
+ super(strat.getFieldMapping().getKey().getDeclaredType(),
+ strat.getFieldMapping().getElement().getDeclaredType(), conf);
+ _strat = strat;
+ }
+
+ protected synchronized int count() {
+ boolean derivedVal = _strat.getFieldMapping().getElement().
+ getValueMappedBy() != null;
+ final ClassMapping[] clss = (derivedVal)
+ ? _strat.getIndependentKeyMappings(false)
+ : _strat.getIndependentValueMappings(false);
+ final OpenJPAStateManager sm = assertOwner();
+ final JDBCStore store = getStore();
+ Union union = store.getSQLFactory().newUnion
+ (Math.max(1, clss.length));
+ union.select(new Union.Selector() {
+ public void select(Select sel, int idx) {
+ ClassMapping cls = (clss.length == 0) ? null : clss[idx];
+ sel.whereForeignKey(_strat.getJoinForeignKey(cls),
+ sm.getObjectId(), _strat.getFieldMapping().
+ getDefiningMapping(), store);
+ }
+ });
+
+ try {
+ return union.getCount(store);
+ } catch (SQLException se) {
+ throw SQLExceptions.getStore(se, store.getDBDictionary());
+ }
+ }
+
+ protected boolean hasKey(Object key) {
+ return has(key, true);
+ }
+
+ protected boolean hasValue(Object value) {
+ return has(value, false);
+ }
+
+ private boolean has(final Object obj, final boolean key) {
+ final boolean derivedKey = key && _strat.getFieldMapping().
+ getKey().getValueMappedBy() != null;
+ final boolean derivedVal = !key && _strat.getFieldMapping().
+ getElement().getValueMappedBy() != null;
+
+ final ClassMapping[] clss = ((key && !derivedKey) || derivedVal)
+ ? _strat.getIndependentKeyMappings(derivedVal)
+ : _strat.getIndependentValueMappings(derivedKey);
+ final OpenJPAStateManager sm = assertOwner();
+ final JDBCStore store = getStore();
+
+ Union union = store.getSQLFactory().newUnion
+ (Math.max(1, clss.length));
+ union.select(new Union.Selector() {
+ public void select(Select sel, int idx) {
+ ClassMapping cls = (clss.length == 0) ? null : clss[idx];
+ sel.whereForeignKey(_strat.getJoinForeignKey(cls),
+ sm.getObjectId(), _strat.getFieldMapping().
+ getDefiningMapping(), store);
+
+ Joins joins = null;
+ Column[] cols;
+ Object val;
+ if (key) {
+ if (derivedKey)
+ joins = _strat.joinValueRelation(sel.newJoins(), cls);
+ val = _strat.toKeyDataStoreValue(obj, store);
+ cols = _strat.getKeyColumns(cls);
+ } else {
+ if (derivedVal)
+ joins = _strat.joinKeyRelation(sel.newJoins(), cls);
+ val = _strat.toDataStoreValue(obj, store);
+ cols = _strat.getValueColumns(cls);
+ }
+ Object[] vals = (cols.length == 1) ? null : (Object[]) val;
+ SQLBuffer sql = new SQLBuffer(store.getDBDictionary());
+ for (int i = 0; i < cols.length; i++) {
+ if (i > 0)
+ sql.append(" AND ");
+
+ sql.append(sel.getColumnAlias(cols[i], joins));
+ if (vals == null)
+ sql.append((val == null) ? " IS " : " = ").
+ appendValue(val, cols[i]);
+ else
+ sql.append((vals[i] == null) ? " IS " : " = ").
+ appendValue(vals[i], cols[i]);
+ }
+ sel.where(sql, joins);
+ }
+ });
+
+ try {
+ return union.getCount(store) > 0;
+ } catch (SQLException se) {
+ throw SQLExceptions.getStore(se, store.getDBDictionary());
+ }
+ }
+
+ protected Collection keys(final Object obj) {
+ final OpenJPAStateManager sm = assertOwner();
+ final JDBCStore store = getStore();
+ if (_strat.getFieldMapping().getKey().getValueMappedBy() != null) {
+ Object key = _strat.deriveKey(store, obj);
+ if (hasKey(key))
+ return Collections.singleton(key);
+ return Collections.EMPTY_LIST;
+ }
+
+ final ClassMapping[] clss = _strat.getIndependentKeyMappings(true);
+ final JDBCFetchConfiguration fetch = store.getFetchConfiguration();
+ final JDBCFetchState jfetchState = (JDBCFetchState) fetch
+ .newFetchState();
+ final Joins[] resJoins = new Joins[Math.max(1, clss.length)];
+
+ Union union = store.getSQLFactory().newUnion
+ (Math.max(1, clss.length));
+ if (fetch.getSubclassFetchMode(_strat.getFieldMapping().
+ getKeyMapping().getTypeMapping()) != fetch.EAGER_JOIN)
+ union.abortUnion();
+ union.select(new Union.Selector() {
+ public void select(Select sel, int idx) {
+ ClassMapping cls = (clss.length == 0) ? null : clss[idx];
+ sel.whereForeignKey(_strat.getJoinForeignKey(cls),
+ sm.getObjectId(), _strat.getFieldMapping().
+ getDefiningMapping(), store);
+ if (_strat.getFieldMapping().getElement().getValueMappedBy()
+ != null)
+ resJoins[idx] = _strat.joinKeyRelation(sel.newJoins(),
+ cls);
+
+ Object val = _strat.toDataStoreValue(obj, store);
+ Column[] cols = _strat.getValueColumns(cls);
+ Object[] vals = (cols.length == 1) ? null : (Object[]) val;
+ SQLBuffer sql = new SQLBuffer(store.getDBDictionary());
+ for (int i = 0; i < cols.length; i++) {
+ if (i > 0)
+ sql.append(" AND ");
+
+ sql.append(sel.getColumnAlias(cols[i]));
+ if (vals == null)
+ sql.append((val == null) ? " IS " : " = ").
+ appendValue(val, cols[i]);
+ else
+ sql.append((vals[i] == null) ? " IS " : " = ").
+ appendValue(vals[i], cols[i]);
+ }
+ sel.where(sql);
+
+ if (resJoins[idx] == null)
+ resJoins[idx] = _strat.joinKeyRelation(sel.newJoins(),
+ cls);
+ _strat.selectKey(sel, cls, sm, store, jfetchState,
+ resJoins[idx]);
+ }
+ });
+
+ Result res = null;
+ Collection keys = new ArrayList(3);
+ try {
+ res = union.execute(store, fetch);
+ while (res.next())
+ keys.add(_strat.loadKey(sm, store, jfetchState, res,
+ resJoins[res.indexOf()]));
+ return keys;
+ } catch (SQLException se) {
+ throw SQLExceptions.getStore(se, store.getDBDictionary());
+ } finally {
+ if (res != null)
+ res.close();
+ }
+ }
+
+ protected Object value(final Object obj) {
+ final OpenJPAStateManager sm = assertOwner();
+ final JDBCStore store = getStore();
+ if (_strat.getFieldMapping().getElement().getValueMappedBy() != null) {
+ Object val = _strat.deriveValue(store, obj);
+ if (hasValue(val))
+ return val;
+ return null;
+ }
+
+ final JDBCFetchConfiguration fetch = store.getFetchConfiguration();
+ final JDBCFetchState fetchState =
+ (JDBCFetchState) fetch.newFetchState();
+ final ClassMapping[] clss = _strat.getIndependentValueMappings(true);
+ final Joins[] resJoins = new Joins[Math.max(1, clss.length)];
+ Union union = store.getSQLFactory().newUnion
+ (Math.max(1, clss.length));
+ union.setSingleResult(true);
+ if (fetch.getSubclassFetchMode(_strat.getFieldMapping().
+ getElementMapping().getTypeMapping())
+ != JDBCFetchConfiguration.EAGER_JOIN)
+ union.abortUnion();
+ union.select(new Union.Selector() {
+ public void select(Select sel, int idx) {
+ ClassMapping cls = (clss.length == 0) ? null : clss[idx];
+ sel.whereForeignKey(_strat.getJoinForeignKey(cls),
+ sm.getObjectId(), _strat.getFieldMapping().
+ getDefiningMapping(), store);
+ if (_strat.getFieldMapping().getKey().getValueMappedBy()
+ != null)
+ resJoins[idx] = _strat.joinValueRelation(sel.newJoins(),
+ cls);
+
+ Object key = _strat.toKeyDataStoreValue(obj, store);
+ Column[] cols = _strat.getKeyColumns(cls);
+ Object[] vals = (cols.length == 1) ? null : (Object[]) key;
+ SQLBuffer sql = new SQLBuffer(store.getDBDictionary());
+ for (int i = 0; i < cols.length; i++) {
+ if (i > 0)
+ sql.append(" AND ");
+
+ sql.append(sel.getColumnAlias(cols[i], resJoins[idx]));
+ if (vals == null)
+ sql.append((key == null) ? " IS " : " = ").
+ appendValue(key, cols[i]);
+ else
+ sql.append((vals[i] == null) ? " IS " : " = ").
+ appendValue(vals[i], cols[i]);
+ }
+ sel.where(sql, resJoins[idx]);
+
+ if (resJoins[idx] == null)
+ resJoins[idx] = _strat.joinValueRelation(sel.newJoins(),
+ cls);
+ _strat.selectValue(sel, cls, sm, store, fetchState,
+ resJoins[idx]);
+ }
+ });
+
+ Result res = null;
+ try {
+ res = union.execute(store, fetch);
+ if (res.next())
+ return _strat.loadValue(sm, store, fetchState, res,
+ resJoins[res.indexOf()]);
+ return null;
+ } catch (SQLException se) {
+ throw SQLExceptions.getStore(se, store.getDBDictionary());
+ } finally {
+ if (res != null)
+ res.close();
+ }
+ }
+
+ protected Iterator itr() {
+ OpenJPAStateManager sm = assertOwner();
+ JDBCStore store = getStore();
+ JDBCFetchConfiguration fetch = store.getFetchConfiguration();
+ JDBCFetchState jfetchState = (JDBCFetchState) fetch.newFetchState();
+ try {
+ Joins[] joins = new Joins[2];
+ Result[] res = _strat.getResults(sm, store, jfetchState,
+ fetch.EAGER_JOIN, joins, true);
+ return new ResultIterator(sm, store, jfetchState, res, joins);
+ } catch (SQLException se) {
+ throw SQLExceptions.getStore(se, store.getDBDictionary());
+ }
+ }
+
+ private OpenJPAStateManager assertOwner() {
+ OpenJPAStateManager sm = getOwner();
+ if (sm == null)
+ throw new InvalidStateException(_loc.get("lrs-no-owner",
+ _strat.getFieldMapping()));
+ return sm;
+ }
+
+ private JDBCStore getStore() {
+ return (JDBCStore) getOwner().getContext().getStoreManager().
+ getInnermostDelegate();
+ }
+
+ /**
+ * Closeable iterator built around key and value JDBC results.
+ */
+ private class ResultIterator
+ implements Iterator, Closeable {
+
+ private final OpenJPAStateManager _sm;
+ private final JDBCStore _store;
+ private final JDBCFetchState _fetchState;
+ private final Result[] _res;
+ private final Joins[] _joins;
+ private Boolean _next = null;
+
+ public ResultIterator(OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState, Result[] res, Joins[] joins) {
+ _sm = sm;
+ _store = store;
+ _fetchState = fetchState;
+ _res = res;
+ _joins = joins;
+ }
+
+ public boolean hasNext() {
+ if (_next == null) {
+ try {
+ _next = (_res[0].next()) ? Boolean.TRUE : Boolean.FALSE;
+ if (_next.booleanValue() && _res[1] != _res[0])
+ _res[1].next();
+ } catch (SQLException se) {
+ throw SQLExceptions.getStore(se, _store.getDBDictionary());
+ }
+ }
+ return _next.booleanValue();
+ }
+
+ public Object next() {
+ if (!hasNext())
+ throw new NoSuchElementException();
+ _next = null;
+
+ boolean keyDerived = _strat.getFieldMapping().getKey().
+ getValueMappedBy() != null;
+ boolean valDerived = _strat.getFieldMapping().getElement().
+ getValueMappedBy() != null;
+ Entry entry = new Entry();
+ try {
+
+ if (!keyDerived)
+ entry.key = _strat.loadKey(_sm, _store, _fetchState,
+ _res[0], _joins[0]);
+ if (!valDerived)
+ entry.val = _strat.loadValue(_sm, _store, _fetchState,
+ _res[1], _joins[1]);
+ if (keyDerived)
+ entry.key = _strat.deriveKey(_store, entry.val);
+ if (valDerived)
+ entry.val = _strat.deriveValue(_store, entry.key);
+ return entry;
+ } catch (SQLException se) {
+ throw SQLExceptions.getStore(se, _store.getDBDictionary());
+ }
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void close() {
+ _next = Boolean.FALSE;
+ _res[0].close();
+ if (_res[1] != _res[0])
+ _res[1].close();
+ }
+ }
+
+ /**
+ * Map.Entry struct.
+ */
+ private static class Entry
+ implements Map.Entry {
+
+ public Object key;
+ public Object val;
+
+ public Object getKey() {
+ return key;
+ }
+
+ public Object getValue() {
+ return val;
+ }
+
+ public Object setValue(Object val) {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
+
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LRSProxyMap.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MapTableFieldStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MapTableFieldStrategy.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MapTableFieldStrategy.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MapTableFieldStrategy.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.sql.SQLException;
+import java.util.Map;
+
+import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
+import org.apache.openjpa.jdbc.kernel.JDBCFetchState;
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.FieldMapping;
+import org.apache.openjpa.jdbc.meta.FieldStrategy;
+import org.apache.openjpa.jdbc.schema.ForeignKey;
+import org.apache.openjpa.jdbc.sql.Joins;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.jdbc.sql.Row;
+import org.apache.openjpa.jdbc.sql.RowManager;
+import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.util.MetaDataException;
+
+/**
+ * Base class for map mappings. Handles managing the secondary table
+ * used to hold map keys and values and loading. Subclasses must implement
+ * abstract methods and insert/update behavior as well as overriding
+ * {@link FieldStrategy#toDataStoreValue},
+ * {@link FieldStrategy#toKeyDataStoreValue},
+ * {@link FieldStrategy#joinRelation}, and
+ * {@link FieldStrategy#joinKeyRelation} if necessary.
+ *
+ * @author Abe White
+ */
+public abstract class MapTableFieldStrategy
+ extends ContainerFieldStrategy
+ implements LRSMapFieldStrategy {
+
+ private static final Localizer _loc = Localizer.forPackage
+ (MapTableFieldStrategy.class);
+
+ public FieldMapping getFieldMapping() {
+ return field;
+ }
+
+ public ClassMapping[] getIndependentKeyMappings(boolean traverse) {
+ return (traverse) ? field.getKeyMapping().getIndependentTypeMappings()
+ : ClassMapping.EMPTY_MAPPINGS;
+ }
+
+ public ClassMapping[] getIndependentValueMappings(boolean traverse) {
+ return (traverse) ? field.getElementMapping().
+ getIndependentTypeMappings() : ClassMapping.EMPTY_MAPPINGS;
+ }
+
+ public ForeignKey getJoinForeignKey(ClassMapping cls) {
+ return field.getJoinForeignKey();
+ }
+
+ public Object deriveKey(JDBCStore store, Object value) {
+ return null;
+ }
+
+ public Object deriveValue(JDBCStore store, Object key) {
+ return null;
+ }
+
+ /**
+ * Invokes {@link FieldStrategy#joinKeyRelation} by default.
+ */
+ public Joins joinKeyRelation(Joins joins, ClassMapping key) {
+ return joinKeyRelation(joins, false, false);
+ }
+
+ /**
+ * Invokes {@link FieldStrategy#joinRelation} by default.
+ */
+ public Joins joinValueRelation(Joins joins, ClassMapping val) {
+ return joinRelation(joins, false, false);
+ }
+
+ public void map(boolean adapt) {
+ if (field.getTypeCode() != JavaTypes.MAP)
+ throw new MetaDataException(_loc.get("not-map", field));
+ if (field.getKey().getValueMappedBy() != null)
+ throw new MetaDataException(_loc.get("mapped-by-key", field));
+ field.getValueInfo().assertNoSchemaComponents(field, !adapt);
+ }
+
+ public void delete(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
+ throws SQLException {
+ Row row = rm.getAllRows(field.getTable(), Row.ACTION_DELETE);
+ row.whereForeignKey(field.getJoinForeignKey(), sm);
+ rm.flushAllRows(row);
+ }
+
+ public int supportsSelect(Select sel, int type, OpenJPAStateManager sm,
+ JDBCStore store, JDBCFetchConfiguration fetch) {
+ return 0;
+ }
+
+ public void load(OpenJPAStateManager sm, JDBCStore store,
+ JDBCFetchState fetchState)
+ throws SQLException {
+ if (field.isLRS()) {
+ sm.storeObjectField(field.getIndex(), new LRSProxyMap(this,
+ store.getConfiguration()));
+ return;
+ }
+
+ // select all and load into a normal proxy
+ Joins[] joins = new Joins[2];
+ Result[] res = getResults(sm, store, fetchState,
+ JDBCFetchConfiguration.EAGER_PARALLEL, joins, false);
+ try {
+ Map map = (Map) sm.newProxy(field.getIndex());
+ Object key, val;
+ while (res[0].next()) {
+ if (res[1] != res[0] && !res[1].next())
+ break;
+
+ key = loadKey(sm, store, fetchState, res[0], joins[0]);
+ val = loadValue(sm, store, fetchState, res[1], joins[1]);
+ map.put(key, val);
+ }
+ sm.storeObject(field.getIndex(), map);
+ } finally {
+ res[0].close();
+ if (res[1] != res[0])
+ res[1].close();
+ }
+ }
+
+ public Object loadKeyProjection(JDBCStore store,
+ JDBCFetchState fetchState, Result res, Joins joins)
+ throws SQLException {
+ return loadKey(null, store, fetchState, res, joins);
+ }
+
+ public Object loadProjection(JDBCStore store, JDBCFetchState fetchState,
+ Result res, Joins joins)
+ throws SQLException {
+ return loadValue(null, store, fetchState, res, joins);
+ }
+
+ public Joins join(Joins joins, boolean forceOuter) {
+ return field.join(joins, forceOuter, true);
+ }
+
+ public Joins joinKey(Joins joins, boolean forceOuter) {
+ return field.join(joins, forceOuter, true);
+ }
+
+ protected ForeignKey getJoinForeignKey() {
+ return field.getJoinForeignKey();
+ }
+
+ protected ClassMapping[] getIndependentElementMappings(boolean traverse) {
+ return ClassMapping.EMPTY_MAPPINGS;
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MapTableFieldStrategy.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedBlobFieldStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedBlobFieldStrategy.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedBlobFieldStrategy.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedBlobFieldStrategy.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.jdbc.sql.Row;
+import org.apache.openjpa.jdbc.sql.SQLExceptions;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.util.MetaDataException;
+
+/**
+ * Mapping for serialized fields on a dictionary that has a maximum embedded
+ * BLOB size.
+ *
+ * @author Abe White
+ * @nojavadoc
+ * @since 4.0
+ */
+public class MaxEmbeddedBlobFieldStrategy
+ extends MaxEmbeddedLobFieldStrategy {
+
+ private static final Localizer _loc = Localizer.forPackage
+ (MaxEmbeddedBlobFieldStrategy.class);
+
+ private int _maxSize = 0;
+
+ protected int getExpectedJavaType() {
+ return JavaTypes.OBJECT;
+ }
+
+ protected void update(OpenJPAStateManager sm, Row row)
+ throws SQLException {
+ byte[] b = (byte[]) sm.getImplData(field.getIndex());
+ if (b == null || b.length > _maxSize)
+ row.setNull(field.getColumns()[0], true);
+ else {
+ sm.setImplData(field.getIndex(), null);
+ DBDictionary.SerializedData dat =
+ new DBDictionary.SerializedData(b);
+ row.setObject(field.getColumns()[0], dat);
+ }
+ }
+
+ protected Boolean isCustom(OpenJPAStateManager sm, JDBCStore store) {
+ // have we already stored our serialized data?
+ byte[] b = (byte[]) sm.getImplData(field.getIndex());
+ if (b == null) {
+ Object o = sm.fetch(field.getIndex());
+ if (o == null)
+ return Boolean.FALSE;
+
+ // serialize field value
+ DBDictionary dict = field.getMappingRepository().getDBDictionary();
+ try {
+ b = dict.serialize(o, store);
+ } catch (SQLException se) {
+ throw SQLExceptions.getStore(se, dict);
+ }
+
+ // set in impl data so that we don't have to re-serialize on store
+ sm.setImplData(field.getIndex(), b);
+ }
+ return (b.length > _maxSize) ? null : Boolean.FALSE;
+ }
+
+ protected void putData(OpenJPAStateManager sm, ResultSet rs,
+ DBDictionary dict)
+ throws SQLException {
+ byte[] b = (byte[]) sm.setImplData(field.getIndex(), null);
+ Object blob = rs.getBlob(1);
+ dict.putBytes(blob, b);
+ }
+
+ public void map(boolean adapt) {
+ if (!field.isSerialized())
+ throw new MetaDataException(_loc.get("not-serialized", field));
+ super.map(adapt);
+ }
+
+ public void initialize() {
+ DBDictionary dict = field.getMappingRepository().getDBDictionary();
+ _maxSize = dict.maxEmbeddedBlobSize;
+ field.setUsesImplData(Boolean.TRUE);
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedBlobFieldStrategy.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedByteArrayFieldStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedByteArrayFieldStrategy.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedByteArrayFieldStrategy.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedByteArrayFieldStrategy.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.meta.strats;
+
+import java.lang.reflect.Array;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.apache.openjpa.jdbc.kernel.JDBCStore;
+import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
+import org.apache.openjpa.jdbc.schema.Column;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.jdbc.sql.Joins;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.jdbc.sql.Row;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.MetaDataException;
+
+/**
+ * Mapping for byte array fields on a dictionary that has a maximum embedded
+ * BLOB size.
+ *
+ * @author Abe White
+ * @nojavadoc
+ * @since 4.0
+ */
+public class MaxEmbeddedByteArrayFieldStrategy
+ extends MaxEmbeddedLobFieldStrategy {
+
+ private static final Localizer _loc = Localizer.forPackage
+ (MaxEmbeddedByteArrayFieldStrategy.class);
+
+ private int _maxSize = 0;
+
+ protected int getExpectedJavaType() {
+ return JavaSQLTypes.BYTES;
+ }
+
+ protected void update(OpenJPAStateManager sm, Row row)
+ throws SQLException {
+ byte[] b = PrimitiveWrapperArrays.toByteArray(sm.fetchObject
+ (field.getIndex()));
+ if (b == null || b.length > _maxSize)
+ row.setBytes(field.getColumns()[0], null);
+ else
+ row.setBytes(field.getColumns()[0], b);
+ }
+
+ protected Boolean isCustom(OpenJPAStateManager sm, JDBCStore store) {
+ Object val = sm.fetchObject(field.getIndex());
+ return (val != null && Array.getLength(val) > _maxSize) ? null
+ : Boolean.FALSE;
+ }
+
+ protected void putData(OpenJPAStateManager sm, ResultSet rs,
+ DBDictionary dict)
+ throws SQLException {
+ Object blob = rs.getBlob(1);
+ dict.putBytes(blob, PrimitiveWrapperArrays.toByteArray(sm.fetchObject
+ (field.getIndex())));
+ }
+
+ protected Object load(Column col, Result res, Joins joins)
+ throws SQLException {
+ return PrimitiveWrapperArrays.toObjectValue(field,
+ (byte[]) res.getBytes(col, joins));
+ }
+
+ public void map(boolean adapt) {
+ if (field.getType() != byte[].class && field.getType() != Byte[].class)
+ throw new MetaDataException(_loc.get("not-bytes", field));
+ super.map(adapt);
+ }
+
+ public void initialize() {
+ DBDictionary dict = field.getMappingRepository().getDBDictionary();
+ _maxSize = dict.maxEmbeddedBlobSize;
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedByteArrayFieldStrategy.java
------------------------------------------------------------------------------
svn:executable = *