[CDO] How to manually create DDL for schema updates? [message #1809646] |
Fri, 19 July 2019 09:39 |
Linuxhippy Mising name Messages: 72 Registered: July 2009 |
Member |
|
|
Hi,
I am currently migrating from CDO-4.5 to the latest available weekly build (may 2019) and so far the migration has been progressing very smooth.
The only real show-stopper left is generating DDL off-line for manually patching the production systems (automatic schema migration performed by CDO is not an option there).
The application has code which worked for CDO 4.5 and looks like:
IDBSchemaTransaction schemaTransaction = ((DBStore) store).getDatabase().openSchemaTransaction();
IDBSchema schema = ((DBStore) store).getDatabase().getSchema();
((InternalDBSchema) schema).unlock();
IMappingStrategy mappingStrategy = ((DBStore) store).getMappingStrategy();
EList<EClassifier> eClassifiers = emfPackage.getEClassifiers();
for (EClassifier eClassifier : eClassifiers) {
if (eClassifier instanceof EClass && !((EClass) eClassifier).isInterface()
&& !((EClass) eClassifier).isAbstract()) {
// required to initalize als mappings
IClassMapping mapping = mappingStrategy.getClassMapping((EClass) eClassifier);
.......
IDBSchemaDelta schemaDelta = schemaTransaction.getSchemaDelta();
//manually generate schema using the delta
However in the latest CDO-Version SchemaTransaction.ensureSchema is called as soon as adding a Repository - furthermorethe the policy used doesn't seem to be configureable (DEFAULT_ENSURE_SCHEMA_POLICY is final and frozen).
In my case a lot of changes are detected (seem to be mostly "remove"-changes - please see the file attached) but discarded because of the default policy - yet ensureSchema applies the delta to the on-memory representation and later on calls to getSchemaDelta() return no delta at all.
Furthermore, because the schema stays unchanged, I later get NPEs accessing attributes that were added:
Caused by: java.lang.NullPointerException
at org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.AbstractHorizontalClassMapping.readValuesFromResultSet(AbstractHorizontalClassMapping.java:486)
at org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.AbstractHorizontalClassMapping.readValuesFromStatement(AbstractHorizontalClassMapping.java:413)
at org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalAuditClassMapping.readRevision(HorizontalAuditClassMapping.java:309)
at org.eclipse.emf.cdo.server.internal.db.DBStoreAccessor.readRevision(DBStoreAccessor.java:269)
at org.eclipse.emf.cdo.internal.server.Repository.loadRevisions(Repository.java:571)
Could you think of a sane way how to generate the DDL off-line?
And is there a way to change the policy used by ensureSchema when called during initialization to also support (this way I could wrap a java.sql.Connection and at least dump the generated SQL to a file)?
As always thank you very much in advance.
Best regards, Clemens
[Updated on: Fri, 19 July 2019 09:41] Report message to a moderator
|
|
|
|
|
|
Re: [CDO] How to manually create DDL for schema updates? [message #1809682 is a reply to message #1809675] |
Sat, 20 July 2019 07:02 |
|
Hi Clemens,
I see, you don't want to generate the DDL for the new schema, but for the delta between old and new schema, right?
The ensureSchema() call in DBStore.doActivate() only makes sure that CDO's system tables exist, as defined by CDODBSchema.INSTANCE. As you found out, the attribute and list tables of the mapped EClasses are created lazily by default, see AbstractHorizontalClassMapping and XyzListTableWithRanges. You can create those tables eagerly with <property name="eagerTableCreation" value="true"/> under the <mappingStrategy> element in cdo-server.xml. You may also want to use the <initialPackage> element under the <repository> element, see the example in cdo-server.xml.
You can generate your DLL for IDBSchemaDeltas with the following code:
database.addListener(new IListener()
{
public void notifyEvent(IEvent event)
{
if (event instanceof SchemaChangedEvent)
{
SchemaChangedEvent e = (SchemaChangedEvent)event;
IDBSchemaDelta schemaDelta = e.getSchemaDelta();
System.out.println(schemaDelta);
// Manually generate schema using the delta...
}
}
});
Unfortunately at the moment I see no way to add this listener right after the database instance is created, so you can only patch DBStore.doActivate(). I can add a respective hook if you submit a bugzilla. I can probably also find a way then to customize the IDBDeltaVisitor.Filter.Policy for IDBSchemaTransaction.ensureSchema(IDBSchema).
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
|
Powered by
FUDForum. Page generated in 0.03753 seconds