How to get a list of schema differences between replicas


Summary
The process of replica creation involves defining the datasets to replicate. Once a replica is created, changes can be independently made to the schemas of the datasets in each replicated geodatabase. Tools are provided to compare the replicas and return the list of the schema differences. Additional tools can be used to apply the schema changes from one replica geodatabase to the other.
The classes from the schema change export and import object model in the geodatabase-distributed library allow you to get the schema differences programmatically. This topic describes how to use the object model to get the list of schema differences.

In this topic


Getting a list of schema differences between replicas

To get the schema differences, you must first initialize the SchemaChanges class using the ISchemaChangesInit interface.
The interface provides three Init methods. All three require you to specify the target workspace. The target references the replica that you are comparing to. Each method differs in how it allows you to reference the source. The source is the replica that you are comparing from.
If both replica geodatabases are on the same network, the source can be specified using the replica directly from the source geodatabase. If the geodatabases are on different networks, a replica schema file that describes the replica in the source geodatabase can be generated, sent, and used for the comparison. See the ReplicaSchemaExporter co-class and IExportSchema interface for how to generate the replica schema file. The third way to specify the source is by using a replica schema differences file. This file already contains the schema differences between the replicas. See the ReplicaSchemaExporter co-class and IExportSchema interface for how to generate the replica schema differences file.
The following code example shows two methods to initialize the SchemaChange class. One method is for the case where you are comparing against the source replica directly, and one is for either of the files previously described.
[Java]
//  This function takes the 2 sde workspaces and replica and gets the schema changes 
public void listSchemaChanges(IWorkspace targetWorkspace, IWorkspace sourceWorkspace,
    String replicaName)throws Exception{
    //  Get the replica from the source and the workspace name object for the target
    IWorkspaceReplicas workspaceReplicas = (IWorkspaceReplicas)sourceWorkspace;
    IReplica replica = workspaceReplicas.getReplicaByName(replicaName);
    IDataset dataset = new IDatasetProxy(targetWorkspace);
    IWorkspaceName workspaceName = (IWorkspaceName)dataset.getFullName();

    //  initialize the schema changes object
    ISchemaChangesInit schemaChangesInit = new SchemaChanges();
    schemaChangesInit.init(replica, workspaceName);
    ISchemaChanges schemaChanges = (ISchemaChanges)schemaChangesInit;

    //  print the changes
    printSchemaChanges((IEnumSchemaChange)schemaChanges.getChanges(), "");
}

//  This function takes the target workspaces and either the schema file 
//  for the relative replica or a schema changes file and gets the schema changes
//  Set the schemaChangesFileType to True if it is a schema changes file
public void listSchemaChanges(IWorkspace targetWorkspace, String schemaFile, boolean
    schemaChangesFileType)throws Exception{
    //  Workspace name object for the target
    IDataset dataset = new IDatasetProxy(targetWorkspace);
    IWorkspaceName workspaceName = (IWorkspaceName)dataset.getFullName();

    //  initialize the schema changes object
    ISchemaChangesInit schemaChangesInit = new SchemaChanges();
    if (schemaChangesFileType){
        schemaChangesInit.initFromSchemaDifferencesDocument(schemaFile,
            workspaceName);
    }
    else{
        schemaChangesInit.initFromSchemaDocument(schemaFile, workspaceName);
    }
    ISchemaChanges schemaChanges = (ISchemaChanges)schemaChangesInit;

    //  print the changes
    printSchemaChanges((IEnumSchemaChange)schemaChanges.getChanges(), "");
}

Calling the PrintSchemaChanges method

At the end of each procedure, the PrintSchemaChanges method is called. This method, which is provided with the following code example, prints out the schema differences. It is a recursive method that takes an enumeration of schema changes. The enumeration returns objects that implement ISchemaChangeInfo. This interface describes the feature datasets, feature classes, fields, and other schema elements that have changed. It also describes the type of change needed for the target replica to be equivalent to the source replica. Each object can also return an enumeration that further describes the schema changes.
For example, if you have added fields to a feature class in a feature dataset in the source replica, an object is returned to describe that the feature dataset has changed. This object also returns an enumeration that includes an object to describe that the feature class has changed. This, in turn, returns an enumeration, which has objects to describe each added field.
[Java]
// recursive function that steps through the schema changes info
public void printSchemaChanges(IEnumSchemaChange enumSchemaChanges, String
    schemaChange)throws Exception{
    enumSchemaChanges.reset();
    ISchemaChangeInfo schemeChangesInfo = enumSchemaChanges.next();
    String sDataName = "";

    // Step through the schema changes
    while ((schemeChangesInfo != null)){
        // Get the name of the feature class, feature dataset etc that has changed
        if (!(schemeChangesInfo.getSchemaChangeType() ==
            esriSchemaChangeType.esriSchemaChangeTypeNoChange)){
            if (!(schemeChangesInfo.getToObject() == null)){
                sDataName = getDataName(schemeChangesInfo.getToObject());
            }
            else if (!(schemeChangesInfo.getFromObject() == null)){
                sDataName = getDataName(schemeChangesInfo.getFromObject());
            }
        }

        // If at the end of the list for the schema change, print the schema change. 
        // Otherwise continue through the list
        if (!(schemeChangesInfo.getChanges() == null)){
            schemaChange = schemaChange + sDataName + "; ";
            printSchemaChanges(schemeChangesInfo.getChanges(), schemaChange);
        }
        else{
            System.out.println(schemaChange + sDataName + "; " + getSchemaChangeType
                (schemeChangesInfo.getSchemaChangeType()));
        }
        schemeChangesInfo = enumSchemaChanges.next();
    }
}
The following is an example of the output from this method:
BOB.USA_1/BOB.us_counties: esriSchemaChangeTypeDeleteTable
BOB.USA_1/BOB.us_cities: esriSchemaChangeTypeNewTable
BOB.USA_1/BOB.us_states/Field Changes/POP2006: esriSchemaChangeTypeNewField
BOB.USA_1/BOB.us_states/Field Changes/POP2000: esriSchemaChangeTypeDeleteField
BOB.USA_1/BOB.us_states/Field Changes/POP1990: esriSchemaChangeTypeDeleteField
BOB.USA_1/BOB.us_states/Field Changes/POP1996: esriSchemaChangeTypeDeleteField
Each line in the output describes a different schema change. From these results, you can see that for the target replica to match the source replica, the following needs to be applied to the target:
To apply these changes, you need to augment the PrintSchemaChanges method and set the ISchemaChangeInfo.ApplySchemaChange property for the changes to apply. You then need to use the ReplicaSchemaImporter to import the changes.
The previous PrintSchemaChanges method calls the following utility function. To run this code in your applications, be sure to include this function. See the following code example:
[Java]
//  Gets the name of the object returned from the schemachangesinfo class
public String getDataName(Object unKnown)throws Exception{
    if (unKnown instanceof IDataElement){
        IDataElement dataElement = (IDataElement)unKnown;
        return dataElement.getName();
    }
    else if (unKnown instanceof IFields){
        return "Field Changes";
    }
    else if (unKnown instanceof IField){
        IField field = (IField)unKnown;
        return field.getName();
    }
    else if (unKnown instanceof IDomain){
        IDomain domain = (IDomain)unKnown;
        return domain.getName();
    }
    else{
        return "unknown name";
    }
}

//  Maps the esriSchemaChangeType values to their corresponding strings
public String getSchemaChangeType(int schemaChangeType)throws Exception{
    switch (schemaChangeType){
        case esriSchemaChangeType.esriSchemaChangeTypeNoChange:
            return "esriSchemaChangeTypeNoChange";
            case esriSchemaChangeType. esriSchemaChangeTypeAny: return 
                "esriSchemaChangeTypeAny";
            case esriSchemaChangeType. esriSchemaChangeTypeNewFeatureDataset: return
                "esriSchemaChangeTypeNewFeatureDataset";
            case esriSchemaChangeType. esriSchemaChangeTypeUpdateFeatureDataset:
                return "esriSchemaChangeTypeUpdateFeatureDataset";

            case esriSchemaChangeType. esriSchemaChangeTypeDeleteFeatureDataset:
                return " esriSchemaChangeTypeDeleteFeatureDataset";

            case esriSchemaChangeType. esriSchemaChangeTypeNewTable: return 
                "esriSchemaChangeTypeNewTable";

            case esriSchemaChangeType. esriSchemaChangeTypeDeleteTable: return 
                "esriSchemaChangeTypeDeleteTable";

            case esriSchemaChangeType. esriSchemaChangeTypeUpdateTable: return 
                "esriSchemaChangeTypeUpdateTable";

            case esriSchemaChangeType. esriSchemaChangeTypeNewRelationshipClass:
                return "esriSchemaChangeTypeNewRelationshipClass";

            case esriSchemaChangeType. esriSchemaChangeTypeDeleteRelationshipClass:
                return "esriSchemaChangeTypeDeleteRelationshipClass";

            case esriSchemaChangeType. esriSchemaChangeTypeUpdateRelationshipClass:
                return "esriSchemaChangeTypeUpdateRelationshipClass";

            case esriSchemaChangeType. esriSchemaChangeTypeNewField: return 
                "esriSchemaChangeTypeNewField";

            case esriSchemaChangeType. esriSchemaChangeTypeUpdateField: return 
                "esriSchemaChangeTypeUpdateField";

            case esriSchemaChangeType. esriSchemaChangeTypeDeleteField: return 
                "esriSchemaChangeTypeDeleteField";

            case esriSchemaChangeType. esriSchemaChangeTypeNewDomain: return 
                "esriSchemaChangeTypeNewDomain";

            case esriSchemaChangeType. esriSchemaChangeTypeUpdateDomain: return 
                "esriSchemaChangeTypeUpdateDomain";

            case esriSchemaChangeType. esriSchemaChangeTypeDeleteDomain: return 
                "esriSchemaChangeTypeDeleteDomain";

            case esriSchemaChangeType. esriSchemaChangeTypeUpdateFields: return 
                "esriSchemaChangeTypeUpdateFields";

            case esriSchemaChangeType. esriSchemaChangeTypeUpdateDomains: return 
                "esriSchemaChangeTypeUpdateDomains";

            case esriSchemaChangeType. esriSchemaChangeTypeNewGeometricNetwork:
                return "esriSchemaChangeTypeNewGeometricNetwork";

            case esriSchemaChangeType. esriSchemaChangeTypeUpdateGeometricNetwork:
                return "esriSchemaChangeTypeUpdateGeometricNetwork";

            case esriSchemaChangeType. esriSchemaChangeTypeDeleteGeometricNetwork:
                return "esriSchemaChangeTypeDeleteGeometricNetwork";

            case esriSchemaChangeType. esriSchemaChangeTypeNewTopology: return 
                "esriSchemaChangeTypeNewTopology";

            case esriSchemaChangeType. esriSchemaChangeTypeUpdateTopology: return 
                "esriSchemaChangeTypeUpdateTopology";

            case esriSchemaChangeType. esriSchemaChangeTypeDeleteTopology: return 
                "esriSchemaChangeTypeDeleteTopology";

        default:
            return "Unknown";
    }
}






Development licensingDeployment licensing
ArcGIS for Desktop StandardArcGIS for Desktop Standard
ArcGIS for Desktop AdvancedArcGIS for Desktop Advanced
Engine Developer KitEngine: Geodatabase Update