Skip to content

Commit

Permalink
Remove insertPostProcessing from MappingCallbacks. Merge insert and
Browse files Browse the repository at this point in the history
update post processing into setPostProcessing(...) on JavaTypeMapping,
and add specific callback in UpdateRequest rather than just dumping it
into postUpdate. Remove MappingCallbacks from some of the Oracle type
mappings that don't need any actual relationship management (what
MappingCallbacks is intended for). Add placeholder for setPostProcessing
on OracleCollection/OracleMap/OracleArray for when we want to handle
BLOB/CLOB in a join table (#14).
Fixes #365.
  • Loading branch information
andyjefferson committed Jun 28, 2021
1 parent d8f9a60 commit 6ada436
Show file tree
Hide file tree
Showing 25 changed files with 201 additions and 358 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,11 @@
import org.datanucleus.state.ObjectProvider;

/**
* Interface defining a series of callbacks that are called when this mapping goes through
* certain lifecycle events. This interface would be implemented by any type of mapping that handles
* a relation and so may need to perform action just before or just after a lifecycle event.
* Interface defining a series of callbacks that are called when this mapping goes through certain lifecycle events.
* This interface would be implemented by any type of mapping that handles a relation and so may need to perform action just before or just after a lifecycle event.
*/
public interface MappingCallbacks
{
/**
* Hook so that we can handle any post-processing on the insert of a particular field.
* For example with Oracle we need to insert "EMPTY_CLOB" and then immediately after do a SELECT of it
* and update the contents of the CLOB/BLOB.
* @param op ObjectProvider
*/
void insertPostProcessing(ObjectProvider op);

/**
* Method called after the insert of the object so that additional operations can be performed if necessary.
* @param op ObjectProvider of the owner
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@
import org.datanucleus.state.ObjectProvider;

/**
* Interface implemented by any ColumnMapping that requires a post-insert step.
* Interface implemented by any ColumnMapping that requires a post-set (insert/update) step.
* For example, with Oracle CLOB/BLOB the INSERT will just put "EMPTY_CLOB" or "EMPTY_BLOB" and this will SELECT the column and update it.
*/
public interface ColumnMappingPostInsert
public interface ColumnMappingPostSet
{
/**
* Perform any INSERT post processing on this column, using the provided value.
* @param op ObjectProvider for object being inserted
* @param value The value to use on the insert
* Perform any post "set" processing on this column, using the provided value.
* @param op ObjectProvider for object being set
* @param value The value to use on the set
*/
void insertPostProcessing(ObjectProvider op, Object value);
void setPostProcessing(ObjectProvider op, Object value);
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
* Mapping for an Oracle BLOB column.
* Extends the standard JDBC handler so that we can insert an empty BLOB, and then update it (Oracle non-standard behaviour).
*/
public class OracleBlobColumnMapping extends AbstractColumnMapping implements ColumnMappingPostInsert, ColumnMappingPostUpdate
public class OracleBlobColumnMapping extends AbstractColumnMapping implements ColumnMappingPostSet
{
/**
* Constructor.
Expand Down Expand Up @@ -295,13 +295,7 @@ public boolean includeInSQLFetchStatement()
}

@Override
public void updatePostProcessing(ObjectProvider op, Object value)
{
updateBlobColumn(op, getJavaTypeMapping().getTable(), this, (byte[])value); // TODO Remove byte[] cast
}

@Override
public void insertPostProcessing(ObjectProvider op, Object value)
public void setPostProcessing(ObjectProvider op, Object value)
{
updateBlobColumn(op, getJavaTypeMapping().getTable(), this, (byte[])value); // TODO Remove byte[] cast
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
* Mapping for an Oracle CLOB column.
* Extends the standard JDBC handler so that we can insert an empty CLOB, and then update it (Oracle non-standard behaviour).
*/
public class OracleClobColumnMapping extends ClobColumnMapping implements ColumnMappingPostInsert, ColumnMappingPostUpdate
public class OracleClobColumnMapping extends ClobColumnMapping implements ColumnMappingPostSet
{
public OracleClobColumnMapping(JavaTypeMapping mapping, RDBMSStoreManager storeMgr, Column col)
{
Expand Down Expand Up @@ -175,13 +175,7 @@ public Object getObject(ResultSet rs, int param)
}

@Override
public void insertPostProcessing(ObjectProvider op, Object value)
{
updateClobColumn(op, getJavaTypeMapping().getTable(), this, (String)value); // TODO Remove String cast
}

@Override
public void updatePostProcessing(ObjectProvider op, Object value)
public void setPostProcessing(ObjectProvider op, Object value)
{
updateClobColumn(op, getJavaTypeMapping().getTable(), this, (String)value); // TODO Remove String cast
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,6 @@ protected boolean containerIsStoredInSingleColumn()

// ---------------------- Implementation of MappingCallbacks ----------------------------------

public void insertPostProcessing(ObjectProvider op)
{
}

/**
* Method to be called after the insert of the owner class element.
* @param ownerOP ObjectProvider of the owner
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,6 @@ public Class getJavaType()

// --------------- Implementation of MappingCallbacks -------------------

public void insertPostProcessing(ObjectProvider ownerOP)
{
}

/**
* Method to be called after the insert of the owner class element.
* @param ownerOP ObjectProvider of the owner
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,6 @@ public void initialize(AbstractMemberMetaData mmd, Table table, ClassLoaderResol
initialize(mmd, table, clr, mmd.getEmbeddedMetaData(), mmd.getTypeName(), ObjectProvider.EMBEDDED_PC);
}

public void insertPostProcessing(ObjectProvider op)
{
}

/**
* MappingCallback called when the owning object is being fetched.
* @param op ObjectProvider of the owning object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@
import org.datanucleus.state.ObjectProvider;
import org.datanucleus.store.rdbms.RDBMSStoreManager;
import org.datanucleus.store.rdbms.mapping.column.ColumnMapping;
import org.datanucleus.store.rdbms.mapping.column.ColumnMappingPostInsert;
import org.datanucleus.store.rdbms.mapping.column.ColumnMappingPostUpdate;
import org.datanucleus.store.rdbms.mapping.column.ColumnMappingPostSet;
import org.datanucleus.store.rdbms.table.Table;
import org.datanucleus.util.Localiser;

Expand Down Expand Up @@ -802,15 +801,14 @@ else if (role == FieldRole.ROLE_MAP_VALUE)
}

/**
* Accessor for whether any of the column mappings requires INSERT post processing.
* TODO Not yet utilised, see RDBMS-14
* @return True if a column needs an INSERT post processing call
* Accessor for whether any of the column mappings requires INSERT/UPDATE post processing.
* @return True if a column needs an INSERT/UPDATE post processing call
*/
public boolean requiresInsertPostProcessing()
public boolean requiresSetPostProcessing()
{
for (int i=0; i<columnMappings.length; i++)
{
if (columnMappings[i] instanceof ColumnMappingPostInsert)
if (columnMappings[i] instanceof ColumnMappingPostSet)
{
return true;
}
Expand All @@ -819,55 +817,20 @@ public boolean requiresInsertPostProcessing()
}

/**
* Perform any INSERT post processing as required by constituent ColumnMappings.
* TODO Not yet utilised, see RDBMS-14
* Perform any INSERT/UPDATE post processing as required by constituent ColumnMappings.
* Default implementation does nothing.
* @param op ObjectProvider of the object with this mapping
*/
public void insertPostProcessing(ObjectProvider op)
{
String value = (String)op.provideField(mmd.getAbsoluteFieldNumber());
op.isLoaded(mmd.getAbsoluteFieldNumber());
for (int i=0; i<columnMappings.length; i++)
{
if (columnMappings[i] instanceof ColumnMappingPostInsert)
{
((ColumnMappingPostInsert)columnMappings[i]).insertPostProcessing(op, getValueForColumnMapping(storeMgr.getNucleusContext(), i, value));
}
}
}

/**
* Accessor for whether any of the column mappings requires UPDATE post processing.
* TODO Not yet utilised, see RDBMS-14
* @return True if a column needs an UPDATE post processing call
*/
public boolean requiresUpdatePostProcessing()
{
for (int i=0; i<columnMappings.length; i++)
{
if (columnMappings[i] instanceof ColumnMappingPostUpdate)
{
return true;
}
}
return false;
}

/**
* Perform any UPDATE post processing as required by constituent ColumnMappings.
* TODO Not yet utilised, see RDBMS-14
* @param op ObjectProvider of the object with this mapping
*/
public void updatePostProcessing(ObjectProvider op)
{
String value = (String)op.provideField(mmd.getAbsoluteFieldNumber());
op.isLoaded(mmd.getAbsoluteFieldNumber());
for (int i=0; i<columnMappings.length; i++)
{
if (columnMappings[i] instanceof ColumnMappingPostUpdate)
{
((ColumnMappingPostUpdate)columnMappings[i]).updatePostProcessing(op, getValueForColumnMapping(storeMgr.getNucleusContext(), i, value));
}
}
public void performSetPostProcessing(ObjectProvider op)
{
// Object value = op.provideField(mmd.getAbsoluteFieldNumber());
// op.isLoaded(mmd.getAbsoluteFieldNumber());
// for (int i=0; i<columnMappings.length; i++)
// {
// if (columnMappings[i] instanceof ColumnMappingPostSet)
// {
// ((ColumnMappingPostSet)columnMappings[i]).setPostProcessing(op, getValueForColumnMapping(storeMgr.getNucleusContext(), i, value));
// }
// }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,6 @@ public Class getJavaType()

// ---------------- Implementation of MappingCallbacks --------------------

public void insertPostProcessing(ObjectProvider ownerOP)
{
}

/**
* Method to be called after the insert of the owner class element.
* @param ownerOP ObjectProvider of the owner
Expand Down Expand Up @@ -275,7 +271,6 @@ public void postUpdate(ObjectProvider ownerOP)
*/
public void preDelete(ObjectProvider ownerOP)
{
// Do nothing - dependent deletion is performed by deleteDependent()
if (containerIsStoredInSingleColumn())
{
// Do nothing when serialised since we are handled in the main request
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,19 @@
import org.datanucleus.store.rdbms.mapping.column.OracleBlobColumnMapping;
import org.datanucleus.store.types.converters.ArrayConversionHelper;
import org.datanucleus.util.Localiser;
import org.datanucleus.util.NucleusLogger;

/**
* Oracle variant of the ArrayMapping for cases where we are serialising the field into a single column.
* This is necessary so we can perform any necessary postInsert, postUpdate nonsense for inserting BLOBs.
*/
public class OracleArrayMapping extends ArrayMapping
{
public void performSetPostProcessing(ObjectProvider op)
{
NucleusLogger.GENERAL.info(">> OracleArrayMapping.performSetPostProc - DO NOTHING");
}

/**
* Method to be called after the insert of the owner class element.
* @param ownerOP ObjectProvider of the owner
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,21 @@

import org.datanucleus.exceptions.NucleusDataStoreException;
import org.datanucleus.state.ObjectProvider;
import org.datanucleus.store.rdbms.mapping.MappingCallbacks;
import org.datanucleus.store.rdbms.mapping.column.BlobImpl;
import org.datanucleus.store.rdbms.mapping.column.OracleBlobColumnMapping;
import org.datanucleus.store.rdbms.mapping.column.ColumnMappingPostSet;
import org.datanucleus.store.types.converters.ArrayConversionHelper;
import org.datanucleus.util.Localiser;

/**
* Mapping for a BitSet type for Oracle.
*/
public class OracleBitSetMapping extends BitSetMapping implements MappingCallbacks
public class OracleBitSetMapping extends BitSetMapping
{
/**
* Method to handle post-processing of the insert of the BLOB/CLOB for Oracle.
* @param op ObjectProvider of the owner
* Retrieve the empty BLOB created by the insert statement and write out the current BLOB field value to the Oracle BLOB object
* @param op the current ObjectProvider
*/
public void insertPostProcessing(ObjectProvider op)
public void performSetPostProcessing(ObjectProvider op)
{
Object value = op.provideField(mmd.getAbsoluteFieldNumber());
if (value == null)
Expand Down Expand Up @@ -86,36 +85,9 @@ else if (value instanceof java.util.BitSet)
// Do nothing
}

// Update the BLOB
OracleBlobColumnMapping.updateBlobColumn(op, getTable(), getColumnMapping(0), bytes);
}

/**
* Method to be called after the insert of the owner class element.
* @param op ObjectProvider of the owner
**/
public void postInsert(ObjectProvider op)
{
}

/**
* Method to be called after any update of the owner class element.
* @param op ObjectProvider of the owner
*/
public void postUpdate(ObjectProvider op)
{
insertPostProcessing(op);
}

public void deleteDependent(ObjectProvider op)
{
}

public void postFetch(ObjectProvider op)
{
}

public void preDelete(ObjectProvider op)
{
if (columnMappings[0] instanceof ColumnMappingPostSet)
{
((ColumnMappingPostSet)columnMappings[0]).setPostProcessing(op, bytes);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,19 @@
import org.datanucleus.ExecutionContext;
import org.datanucleus.state.ObjectProvider;
import org.datanucleus.store.rdbms.mapping.column.OracleBlobColumnMapping;
import org.datanucleus.util.NucleusLogger;

/**
* Oracle variant of the CollectionMapping for cases where we are serialising the field into a single column.
* This is necessary so we can perform any necessary postInsert, postUpdate nonsense for inserting BLOBs.
*/
public class OracleCollectionMapping extends CollectionMapping
{
public void performSetPostProcessing(ObjectProvider op)
{
NucleusLogger.GENERAL.info(">> OracleCollectionMapping.performSetPostProc - DO NOTHING");
}

/**
* Retrieve the empty BLOB created by the insert statement and write out the
* current BLOB field value to the Oracle BLOB object.
Expand Down Expand Up @@ -120,6 +126,7 @@ public void postUpdate(ObjectProvider ownerOP)
}
}

// TODO This should really just be the generate the contents of the BLOB followed by call to OracleBlobColumnMapping.updateBlobColumn
postInsert(ownerOP);
}
else
Expand Down
Loading

0 comments on commit 6ada436

Please sign in to comment.