reversible migrations

This commit is contained in:
John Estropia committed 2015-07-07 19:38:46 +09:00
1 parent 5b85b0749e
commit 5f04f4c496
5 files changed
+130 -23

No files matched your search

+28 -20
View File
@@ -446,6 +446,18 @@ public extension DataStack {
private func startMigrationForSQLiteStore(fileURL fileURL: NSURL, sourceModel: NSManagedObjectModel, destinationModel: NSManagedObjectModel, mappingModel: NSMappingModel) throws {
autoreleasepool {
let journalUpdatingCoordinator = NSPersistentStoreCoordinator(managedObjectModel: sourceModel)
let store = try! journalUpdatingCoordinator.addPersistentStoreWithType(
NSSQLiteStoreType,
configuration: nil,
URL: fileURL,
options: [NSSQLitePragmasOption: ["journal_mode": "DELETE"]]
)
try! journalUpdatingCoordinator.removePersistentStore(store)
}
let migrationManager = NSMigrationManager(
sourceModel: sourceModel,
destinationModel: destinationModel
@@ -475,21 +487,18 @@ public extension DataStack {
withIntermediateDirectories: true,
attributes: nil
)
let temporaryFileURL = temporaryDirectoryURL.URLByAppendingPathComponent(fileURL.lastPathComponent!, isDirectory: false)
do {
try migrationManager.migrateStoreFromURL(
fileURL,
type: NSSQLiteStoreType,
options: [
NSSQLitePragmasOption: ["WAL": "journal_mode"]
],
options: nil,
withMappingModel: mappingModel,
toDestinationURL: temporaryDirectoryURL.URLByAppendingPathComponent(fileURL.lastPathComponent!, isDirectory: false),
toDestinationURL: temporaryFileURL,
destinationType: NSSQLiteStoreType,
destinationOptions: [
NSSQLitePragmasOption: ["WAL": "journal_mode"],
NSSQLiteManualVacuumOption: true
]
destinationOptions: nil
)
}
catch {
@@ -515,20 +524,19 @@ public extension DataStack {
do {
let originalDirectoryURL = fileURL.URLByDeletingLastPathComponent!
for temporaryFileURL in try fileManager.contentsOfDirectoryAtURL(temporaryDirectoryURL, includingPropertiesForKeys: nil, options: .SkipsSubdirectoryDescendants) {
try fileManager.replaceItemAtURL(
fileURL,
withItemAtURL: temporaryFileURL,
backupItemName: nil,
options: [],
resultingItemURL: nil
)
do {
try fileManager.replaceItemAtURL(
originalDirectoryURL.URLByAppendingPathComponent(
temporaryFileURL.lastPathComponent!,
isDirectory: false
),
withItemAtURL: temporaryFileURL,
backupItemName: nil,
options: [],
resultingItemURL: nil
)
try fileManager.removeItemAtPath(fileURL.path! + "-shm")
}
catch _ { }
}
catch {
+14 -2
View File
@@ -199,7 +199,7 @@ public final class DataStack {
configuration: configuration,
URL: fileURL,
options: [
NSSQLitePragmasOption: ["WAL": "journal_mode"],
NSSQLitePragmasOption: ["journal_mode": "WAL"],
NSInferMappingModelAutomaticallyOption: true,
NSMigratePersistentStoresAutomaticallyOption: automigrating
]
@@ -254,7 +254,7 @@ public final class DataStack {
configuration: configuration,
URL: fileURL,
options: [
NSSQLitePragmasOption: ["WAL": "journal_mode"],
NSSQLitePragmasOption: ["journal_mode": "WAL"],
NSInferMappingModelAutomaticallyOption: true,
NSMigratePersistentStoresAutomaticallyOption: automigrating
]
@@ -376,4 +376,16 @@ public final class DataStack {
private let storeMetadataUpdateQueue = GCDQueue.createConcurrent("com.coreStore.persistentStoreBarrierQueue")
private var configurationStoreMapping = [String: NSPersistentStore]()
private var entityConfigurationsMapping = [String: Set<String>]()
deinit {
for store in self.coordinator.persistentStores {
do {
try self.coordinator.removePersistentStore(store)
}
catch _ { }
}
}
}
@@ -11,6 +11,7 @@
B503FAE01AFDC71700F90881 /* ObjectObserverDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B503FADC1AFDC71700F90881 /* ObjectObserverDemoViewController.swift */; };
B503FAE11AFDC71700F90881 /* Palette.swift in Sources */ = {isa = PBXBuildFile; fileRef = B503FADD1AFDC71700F90881 /* Palette.swift */; };
B503FAE21AFDC71700F90881 /* PaletteTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B503FADE1AFDC71700F90881 /* PaletteTableViewCell.swift */; };
B50D67911B4BCFED00124277 /* OrganismV3ToV2.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = B50D67901B4BCFED00124277 /* OrganismV3ToV2.xcmappingmodel */; };
B52977D91B120B80003D50A5 /* ObserversViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52977D81B120B80003D50A5 /* ObserversViewController.swift */; };
B52977DD1B120F3B003D50A5 /* TransactionsDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52977DC1B120F3B003D50A5 /* TransactionsDemoViewController.swift */; };
B52977DF1B120F83003D50A5 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B52977DE1B120F83003D50A5 /* MapKit.framework */; };
@@ -96,6 +97,7 @@
B503FADC1AFDC71700F90881 /* ObjectObserverDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectObserverDemoViewController.swift; sourceTree = "<group>"; };
B503FADD1AFDC71700F90881 /* Palette.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Palette.swift; sourceTree = "<group>"; };
B503FADE1AFDC71700F90881 /* PaletteTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaletteTableViewCell.swift; sourceTree = "<group>"; };
B50D67901B4BCFED00124277 /* OrganismV3ToV2.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; name = OrganismV3ToV2.xcmappingmodel; path = "CoreStoreDemo/MIgrations Demo/OrganismV3ToV2.xcmappingmodel"; sourceTree = SOURCE_ROOT; };
B52977D81B120B80003D50A5 /* ObserversViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObserversViewController.swift; sourceTree = "<group>"; };
B52977DC1B120F3B003D50A5 /* TransactionsDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionsDemoViewController.swift; sourceTree = "<group>"; };
B52977DE1B120F83003D50A5 /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; };
@@ -265,6 +267,7 @@
B5EE258B1B36E40D0000406B /* MigrationsDemoViewController.swift */,
B5F45A601B4AE5A700831F2F /* OrganismV2ToV3.xcmappingmodel */,
B560070E1B3EC90F00A9A8F9 /* OrganismV2ToV3MigrationPolicy.swift */,
B50D67901B4BCFED00124277 /* OrganismV3ToV2.xcmappingmodel */,
);
path = "Migrations Demo";
sourceTree = "<group>";
@@ -394,6 +397,7 @@
B5F45A611B4AE5A700831F2F /* OrganismV2ToV3.xcmappingmodel in Sources */,
B503FAE11AFDC71700F90881 /* Palette.swift in Sources */,
B503FAE21AFDC71700F90881 /* PaletteTableViewCell.swift in Sources */,
B50D67911B4BCFED00124277 /* OrganismV3ToV2.xcmappingmodel in Sources */,
B560070F1B3EC90F00A9A8F9 /* OrganismV2ToV3MigrationPolicy.swift in Sources */,
B503FADF1AFDC71700F90881 /* ListObserverDemoViewController.swift in Sources */,
B54AAD4F1AF4D26E00848AE0 /* AppDelegate.swift in Sources */,
@@ -170,7 +170,7 @@ class MigrationsDemoViewController: UITableViewController {
let navigationItem = self.navigationItem
navigationItem.leftBarButtonItem?.enabled = enabled
navigationItem.rightBarButtonItem?.enabled = enabled
navigationItem.backBarButtonItem?.enabled = enabled
navigationItem.hidesBackButton = !enabled
if let tableView = self.tableView {
@@ -0,0 +1,83 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE database SYSTEM "file:///System/Library/DTDs/CoreData.dtd">
<database>
<databaseInfo>
<version>134481920</version>
<UUID>8160C973-F2E8-4296-AC28-7329092D6700</UUID>
<nextObjectID>106</nextObjectID>
<metadata>
<plist version="1.0">
<dict>
<key>NSPersistenceFrameworkVersion</key>
<integer>526</integer>
<key>NSStoreModelVersionHashes</key>
<dict>
<key>XDDevAttributeMapping</key>
<data>
0plcXXRN7XHKl5CcF+fwriFmUpON3ZtcI/AfK748aWc=
</data>
<key>XDDevEntityMapping</key>
<data>
qeN1Ym3TkWN1G6dU9RfX6Kd2ccEvcDVWHpd3LpLgboI=
</data>
<key>XDDevMappingModel</key>
<data>
EqtMzvRnVZWkXwBHu4VeVGy8UyoOe+bi67KC79kphlQ=
</data>
<key>XDDevPropertyMapping</key>
<data>
XN33V44TTGY4JETlMoOB5yyTKxB+u4slvDIinv0rtGA=
</data>
<key>XDDevRelationshipMapping</key>
<data>
akYY9LhehVA/mCb4ATLWuI9XGLcjpm14wWL1oEBtIcs=
</data>
</dict>
<key>NSStoreModelVersionHashesVersion</key>
<integer>3</integer>
<key>NSStoreModelVersionIdentifiers</key>
<array>
<string></string>
</array>
</dict>
</plist>
</metadata>
</databaseInfo>
<object type="XDDEVMAPPINGMODEL" id="z102">
<attribute name="sourcemodelpath" type="string">CoreStoreDemo/MigrationDemo.xcdatamodeld/MigrationDemoV3.xcdatamodel</attribute>
<attribute name="sourcemodeldata" type="binary">YnBsaXN0MDDUAAEAAgADAAQABQAGBrMGtFgkdmVyc2lvblgkb2JqZWN0c1kkYXJjaGl2ZXJUJHRv
cBIAAYagrxCuAAcACAAXADMANAA1AD0APgBZAFoAWwBhAGIAbgCEAIUAhgCHAIgAiQCKAIsAjACNAKYAqQCwALYAxQDUANcA5gD1APgAWAEIARcBGwEfAS4BNAE1AT0BTAFNAVYBYgFjAWQBZQFmAXsBfAGEAYUBhgGSAaYBpwGoAakBqgGrAawBrQGuAb0BzAHbAd8B7gH9AgwCGwIqAjYCSAJJAkoCSwJMAk0CTgJPAl4CXwJuAn0CjAKNApwCqwK6AsIC1wLYAuAC7AMAAw8DHgMtAzEDQANPA14DbQN8A4gDmgOpA7gDxwPWA9cD5gP1BAQEGQQaBCIELgRCBFEEYARvBHMEggSRBKAErwS+BMoE3ATrBPoFCQUYBScFNgVFBVoFWwVjBW8FgwWSBaEFsAW0BcMF0gXhBfAF/wYLBh0GLAY7BkoGWQZoBncGhgaHBooGkwaXBpsGnwanBqoGrgavVSRudWxs1wAJAAoACwAMAA0ADgAPABAAEQASABMAFAATABZfEA9feGRfcm9vdFBhY2thZ2VWJGNsYXNzXF94ZF9jb21tZW50c18QEF94ZF9tb2RlbE1hbmFnZXJfEBVfY29uZmlndXJhdGlvbnNCeU5hbWVdX3hkX21vZGVsTmFtZV8QF19tb2RlbFZlcnNpb25JZGVudGlmaWVygAKArYCqgACAq4AAgKzeABgAGQAaABsAHAAdAB4ACgAfACAAIQAiACMAJAAlACYAJwAoACUAEwArACwALQAuAC8AJQAlABNfEBxYREJ1Y2tldEZvckNsYXNzZXN3YXNFbmNvZGVkXxAaWERCdWNrZXRGb3JQYWNrYWdlc3N0b3JhZ2VfEBxYREJ1Y2tldEZvckludGVyZmFjZXNzdG9yYWdlXxAPX3hkX293bmluZ01vZGVsXxAdWERCdWNrZXRGb3JQYWNrYWdlc3dhc0VuY29kZWRWX293bmVyXxAbWERCdWNrZXRGb3JEYXRhVHlwZXNzdG9yYWdlW192aXNpYmlsaXR5XxAZWERCdWNrZXRGb3JDbGFzc2Vzc3RvcmFnZVVfbmFtZV8QH1hEQnVja2V0Rm9ySW50ZXJmYWNlc3dhc0VuY29kZWRfEB5YREJ1Y2tldEZvckRhdGFUeXBlc3dhc0VuY29kZWRfEBBfdW5pcXVlRWxlbWVudElEgASAqICmgAGABIAAgKeAqRAAgAWAA4AEgASAAFBTWUVT0wA2ADcACgA4ADoAPFdOUy5rZXlzWk5TLm9iamVjdHOhADmABqEAO4AHgCVYT3JnYW5pc23fEBAAPwBAAEEAQgAdAEMARAAfAEUARgAKACEARwBIACQASQBKAEsAJQAlABAATwBQAC0AJQBKAFMAOQBKAFYAVwBYXxAhWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXNvcmRlcmVkXxAhWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXNzdG9yYWdlXxAgWERCdWNrZXRGb3JTdGVyZW90eXBlc3dhc0VuY29kZWRfECRYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3dhc0VuY29kZWRfEB1YREJ1Y2tldEZvclN0ZXJlb3R5cGVzc3RvcmFnZV8QJFhEQnVja2V0Rm9yR2VuZXJhbGl6YXRpb25zZHVwbGljYXRlc18QJFhEQnVja2V0Rm9yR2VuZXJhbGl6YXRpb25zd2FzRW5jb2RlZF8QHVhEQnVja2V0Rm9yU3RlcmVvdHlwZXNvcmRlcmVkXxAhWERCdWNrZXRGb3JHZW5lcmFsaXphdGlvbnNvcmRlcmVkXxAhWERCdWNrZXRGb3JHZW5lcmFsaXphdGlvbnNzdG9yYWdlW19pc0Fic3RyYWN0gAmALYAEgASAAoAKgKOABIAJgKWABoAJgKSACAgSborVM1dvcmRlcmVk0wA2ADcACgBcAF4APKEAXYALoQBfgAyAJV5YRF9QU3RlcmVvdHlwZdkAHQAhAGMACgAkAGQAHwBJAGUAOwBdAEoAaQATACUALQBYAG1fECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc29yZGVyZWRfECRYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3dhc0VuY29kZWRfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3N0b3JhZ2WAB4ALgAmALIAAgAQIgA3TADYANwAKAG8AeQA8qQBwAHEAcgBzAHQAdQB2AHcAeIAOgA+AEIARgBKAE4AUgBWAFqkAegB7AHwAfQB+AH8AgACBAIKAF4AbgByAHoAfgCGAI4AmgCqAJV8QE1hEUE1Db21wb3VuZEluZGV4ZXNfEBBYRF9QU0tfZWxlbWVudElEXxAZWERQ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 truncated
</attribute>
<attribute name="destinationmodelpath" type="string">CoreStoreDemo/MigrationDemo.xcdatamodeld/MigrationDemoV2.xcdatamodel</attribute>
<attribute name="destinationmodeldata" type="binary">YnBsaXN0MDDUAAEAAgADAAQABQAGBW8FcFgkdmVyc2lvblgkb2JqZWN0c1kkYXJjaGl2ZXJUJHRv
cBIAAYagrxCWAAcACAAXADMANAA1AD0APgBZAFoAWwBhAGIAbgCEAIUAhgCHAIgAiQCKAIsAjACNAKYAqQCwALYAxQDUANcA5gD1APgAWAEIARcBGwEfAS4BNAE1AT0BTAFNAVYBYAFhAWIBYwF4AXkBgQGCAYMBjwGjAaQBpQGmAacBqAGpAaoBqwG6AckB2AHcAesB+gIJAhgCJwIzAkUCRgJHAkgCSQJKAksCTAJbAmoCeQKIAokCmAKnArYCvgLTAtQC3ALoAvwDCwMaAykDLQM8A0sDWgNpA3gDhAOWA6UDtAPDA9ID4QPwA/8EFAQVBB0EKQQ9BEwEWwRqBG4EfQSMBJsEqgS5BMUE1wTmBOcE9gUFBRQFFQUkBTMFQgVDBUYFTwVTBVcFWwVjBWYFagVrVSRudWxs1wAJAAoACwAMAA0ADgAPABAAEQASABMAFAATABZfEA9feGRfcm9vdFBhY2thZ2VWJGNsYXNzXF94ZF9jb21tZW50c18QEF94ZF9tb2RlbE1hbmFnZXJfEBVfY29uZmlndXJhdGlvbnNCeU5hbWVdX3hkX21vZGVsTmFtZV8QF19tb2RlbFZlcnNpb25JZGVudGlmaWVygAKAlYCSgACAk4AAgJTeABgAGQAaABsAHAAdAB4ACgAfACAAIQAiACMAJAAlACYAJwAoACUAEwArACwALQAuAC8AJQAlABNfEBxYREJ1Y2tldEZvckNsYXNzZXN3YXNFbmNvZGVkXxAaWERCdWNrZXRGb3JQYWNrYWdlc3N0b3JhZ2VfEBxYREJ1Y2tldEZvckludGVyZmFjZXNzdG9yYWdlXxAPX3hkX293bmluZ01vZGVsXxAdWERCdWNrZXRGb3JQYWNrYWdlc3dhc0VuY29kZWRWX293bmVyXxAbWERCdWNrZXRGb3JEYXRhVHlwZXNzdG9yYWdlW192aXNpYmlsaXR5XxAZWERCdWNrZXRGb3JDbGFzc2Vzc3RvcmFnZVVfbmFtZV8QH1hEQnVja2V0Rm9ySW50ZXJmYWNlc3dhc0VuY29kZWRfEB5YREJ1Y2tldEZvckRhdGFUeXBlc3dhc0VuY29kZWRfEBBfdW5pcXVlRWxlbWVudElEgASAkICOgAGABIAAgI+AkRAAgAWAA4AEgASAAFBTWUVT0wA2ADcACgA4ADoAPFdOUy5rZXlzWk5TLm9iamVjdHOhADmABqEAO4AHgCVYT3JnYW5pc23fEBAAPwBAAEEAQgAdAEMARAAfAEUARgAKACEARwBIACQASQBKAEsAJQAlABAATwBQAC0AJQBKAFMAOQBKAFYAVwBYXxAhWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXNvcmRlcmVkXxAhWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXNzdG9yYWdlXxAgWERCdWNrZXRGb3JTdGVyZW90eXBlc3dhc0VuY29kZWRfECRYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3dhc0VuY29kZWRfEB1YREJ1Y2tldEZvclN0ZXJlb3R5cGVzc3RvcmFnZV8QJFhEQnVja2V0Rm9yR2VuZXJhbGl6YXRpb25zZHVwbGljYXRlc18QJFhEQnVja2V0Rm9yR2VuZXJhbGl6YXRpb25zd2FzRW5jb2RlZF8QHVhEQnVja2V0Rm9yU3RlcmVvdHlwZXNvcmRlcmVkXxAhWERCdWNrZXRGb3JHZW5lcmFsaXphdGlvbnNvcmRlcmVkXxAhWERCdWNrZXRGb3JHZW5lcmFsaXphdGlvbnNzdG9yYWdlW19pc0Fic3RyYWN0gAmALYAEgASAAoAKgIuABIAJgI2ABoAJgIyACAgSoyHsjFdvcmRlcmVk0wA2ADcACgBcAF4APKEAXYALoQBfgAyAJV5YRF9QU3RlcmVvdHlwZdkAHQAhAGMACgAkAGQAHwBJAGUAOwBdAEoAaQATACUALQBYAG1fECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc29yZGVyZWRfECRYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3dhc0VuY29kZWRfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3N0b3JhZ2WAB4ALgAmALIAAgAQIgA3TADYANwAKAG8AeQA8qQBwAHEAcgBzAHQAdQB2AHcAeIAOgA+AEIARgBKAE4AUgBWAFqkAegB7AHwAfQB+AH8AgACBAIKAF4AbgByAHoAfgCGAI4AmgCqAJV8QE1hEUE1Db21wb3VuZEluZGV4ZXNfEBBYRF9QU0tfZWxlbWVudElEXxAZWERQTVVuaXF1ZW5lc3NDb25zdHJhaW50c18QGlhEX1BTS192ZXJzaW9uSGFzaE1vZGlm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 truncated
</attribute>
<relationship name="entitymappings" type="0/0" destination="XDDEVENTITYMAPPING" idrefs="z103"></relationship>
</object>
<object type="XDDEVENTITYMAPPING" id="z103">
<attribute name="sourcename" type="string">Organism</attribute>
<attribute name="mappingtypename" type="string">Undefined</attribute>
<attribute name="mappingnumber" type="int16">1</attribute>
<attribute name="destinationname" type="string">Organism</attribute>
<attribute name="autogenerateexpression" type="bool">1</attribute>
<relationship name="mappingmodel" type="1/1" destination="XDDEVMAPPINGMODEL" idrefs="z102"></relationship>
<relationship name="attributemappings" type="0/0" destination="XDDEVATTRIBUTEMAPPING" idrefs="z106 z105 z104"></relationship>
<relationship name="relationshipmappings" type="0/0" destination="XDDEVRELATIONSHIPMAPPING"></relationship>
</object>
<object type="XDDEVATTRIBUTEMAPPING" id="z104">
<attribute name="valueexpressiondata" type="binary">YnBsaXN0MDDUAQIDBAUGPD1YJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKwH
CBMUGRoiJywtMjZVJG51bGzVCQoLDA0ODxAREllOU09wZXJhbmReTlNTZWxlY3Rvck5hbWVfEBBOU0V4cHJlc3Npb25UeXBlW05TQXJndW1lbnRzViRjbGFzc4ADgAIQBIAGgAtfEBB2YWx1ZUZvcktleVBhdGg60xULDRYXGFpOU1ZhcmlhYmxlgAQQAoAFVnNvdXJjZdIbHB0eWiRjbGFzc25hbWVYJGNsYXNzZXNfEBROU1ZhcmlhYmxlRXhwcmVzc2lvbqMfICFfEBROU1ZhcmlhYmxlRXhwcmVzc2lvblxOU0V4cHJlc3Npb25YTlNPYmplY3TSIw0kJlpOUy5vYmplY3RzoSWAB4AK0w0LKCkqK1lOU0tleVBhdGiACRAKgAhdbnVtYmVyT2ZMaW1ic9IbHC4vXxAcTlNLZXlQYXRoU3BlY2lmaWVyRXhwcmVzc2lvbqMwMSFfEBxOU0tleVBhdGhTcGVjaWZpZXJFeHByZXNzaW9uXE5TRXhwcmVzc2lvbtIbHDM0Xk5TTXV0YWJsZUFycmF5ozM1IVdOU0FycmF50hscNzhfEBNOU0tleVBhdGhFeHByZXNzaW9upDk6OyFfEBNOU0tleVBhdGhFeHByZXNzaW9uXxAUTlNGdW5jdGlvbkV4cHJlc3Npb25cTlNFeHByZXNzaW9uXxAPTlNLZXllZEFyY2hpdmVy0T4/VHJvb3SAAQAIABEAGgAjAC0AMgA3AEQASgBVAF8AbgCBAI0AlACWAJgAmgCcAJ4AsQC4AMMAxQDHAMkA0ADVAOAA6QEAAQQBGwEoATEBNgFBAUMBRQFHAU4BWAFaAVwBXgFsAXEBkAGUAbMBwAHFAdQB2AHgAeUB+wIAAhYCLQI6AkwCTwJUAAAAAAAAAgEAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAlY=
</attribute>
<attribute name="name" type="string">numberOfFlippers</attribute>
<relationship name="entitymapping" type="1/1" destination="XDDEVENTITYMAPPING" idrefs="z103"></relationship>
</object>
<object type="XDDEVATTRIBUTEMAPPING" id="z105">
<attribute name="name" type="string">hasTail</attribute>
<relationship name="entitymapping" type="1/1" destination="XDDEVENTITYMAPPING" idrefs="z103"></relationship>
</object>
<object type="XDDEVATTRIBUTEMAPPING" id="z106">
<attribute name="name" type="string">hasHead</attribute>
<relationship name="entitymapping" type="1/1" destination="XDDEVENTITYMAPPING" idrefs="z103"></relationship>
</object>
</database>