public static void LoadStream(this Oms oms, System.IO.Stream stream) { MochaClassLibraryObjectModel mcl = new MochaClassLibraryObjectModel(); Document.Load(mcl, mcldf, new StreamAccessor(stream)); oms.LoadObjectModel(mcl); }
public static void LoadFile(this Oms oms, string file) { MochaClassLibraryObjectModel mcl = new MochaClassLibraryObjectModel(); Document.Load(mcl, mcldf, new FileAccessor(file, false, false, true)); oms.LoadObjectModel(mcl); }
public static void Initialize(this Oms oms, Accessor accessor) { MochaClassLibraryObjectModel mcl = new MochaClassLibraryObjectModel(); Document.Load(mcl, mcldf, accessor); oms.Initialize(mcl); }
protected override void BeforeSaveInternal(Stack <ObjectModel> objectModels) { base.BeforeSaveInternal(objectModels); MochaClassLibraryObjectModel mcl = (objectModels.Pop() as MochaClassLibraryObjectModel); MarkupObjectModel mom = new MarkupObjectModel(); objectModels.Push(mom); }
public static void Initialize(this Oms oms, string[] path) { string[] files = path; MochaClassLibraryObjectModel mcl = new MochaClassLibraryObjectModel(); for (int i = 0; i < files.Length; i++) { MochaClassLibraryObjectModel mcl1 = new MochaClassLibraryObjectModel(); Document.Load(mcl1, mcldf, new FileAccessor(files[i], false, false, true)); mcl1.CopyTo(mcl); } oms.Initialize(mcl); }
private static void Initialize(this Oms oms, MochaClassLibraryObjectModel mcl) { oms.BeginTransaction(); for (int i = 0; i < mcl.Libraries.Count; i++) { for (int j = 0; j < mcl.Libraries[i].Instances.Count; j++) { oms.CreateInstance(mcl.Libraries[i].Instances[j].ID, Guid.Empty); } } oms.CommitTransaction(); oms.BeginTransaction(); for (int i = 0; i < mcl.Libraries.Count; i++) { for (int j = 0; j < mcl.Libraries[i].Instances.Count; j++) { for (int k = 0; k < mcl.Libraries[i].Instances[j].AttributeValues.Count; k++) { oms.SetAttributeValue(oms.GetInstance(mcl.Libraries[i].Instances[j].ID), oms.GetInstance(mcl.Libraries[i].Instances[j].AttributeValues[k].AttributeInstanceID), mcl.Libraries[i].Instances[j].AttributeValues[k].Value); } } for (int j = 0; j < mcl.Libraries[i].Relationships.Count; j++) { Guid[] ids = new Guid[mcl.Libraries[i].Relationships[j].DestinationInstanceIDs.Count]; for (int k = 0; k < mcl.Libraries[i].Relationships[j].DestinationInstanceIDs.Count; k++) { ids[k] = mcl.Libraries[i].Relationships[j].DestinationInstanceIDs[k]; } oms.CreateRelationship(oms.GetInstance(mcl.Libraries[i].Relationships[j].SourceInstanceID), oms.GetInstance(mcl.Libraries[i].Relationships[j].RelationshipInstanceID), GuidsToInstances(oms, ids)); } } oms.CommitTransaction(); oms.BeginTransaction(); // create the Class::Instance.has parent Class relationship oms.CreateRelationship(oms.GetInstance(KnownInstanceGuids.Classes.Class), oms.GetInstance(KnownRelationshipGuids.Class__has__Instance), oms.GetInstance(KnownInstanceGuids.Classes.Class)); oms.CreateRelationship(oms.GetInstance(KnownInstanceGuids.Classes.Class), oms.GetInstance(KnownRelationshipGuids.Instance__for__Class), oms.GetInstance(KnownInstanceGuids.Classes.Class)); oms.CommitTransaction(); }
private static void LoadObjectModel(this Oms oms, MochaClassLibraryObjectModel mcl) { foreach (MochaTenant tenant in mcl.Tenants) { oms.DefaultTenant = oms.GetTenant(tenant.Name); if (oms.DefaultTenant.IsEmpty) { throw new InvalidOperationException("attempted to load snapshot for nonexistent tenant"); } oms.BeginTransaction(); for (int j = 0; j < tenant.Instances.Count; j++) { oms.CreateInstance(tenant.Instances[j].ID, Guid.Empty); } oms.CommitTransaction(); } }
public static void Main(string[] args) { List <string> listFileNames = new List <string>(); string outputFileName = "output.mcx"; bool foundFileName = false; for (int i = 0; i < args.Length; i++) { if (args[i].StartsWith("/") && !foundFileName) { if (args[i].StartsWith("/out:")) { outputFileName = args[i].Substring(5); } } else { // is file name foundFileName = true; listFileNames.Add(args[i]); } } MochaClassLibraryObjectModel mcl = new MochaClassLibraryObjectModel(); MochaBinaryDataFormat mcx = new MochaBinaryDataFormat(); MochaXMLDataFormat xml = new MochaXMLDataFormat(); System.Text.StringBuilder sb = new System.Text.StringBuilder(); int totalInstances = 0, totalRelationships = 0; for (int i = 0; i < listFileNames.Count; i++) { Console.Error.WriteLine("reading {0}", listFileNames[i]); MochaClassLibraryObjectModel mcl1 = new MochaClassLibraryObjectModel(); FileAccessor fain = new FileAccessor(listFileNames[i]); Document.Load(mcl1, xml, fain); for (int j = 0; j < mcl1.Libraries.Count; j++) { mcl.Libraries.Merge(mcl1.Libraries[j]); totalInstances += mcl1.Libraries[j].Instances.Count; totalRelationships += mcl1.Libraries[j].Relationships.Count; } for (int j = 0; j < mcl1.Tenants.Count; j++) { Console.Error.WriteLine("registered tenant {0}", mcl1.Tenants[j].Name); mcl.Tenants.Merge(mcl1.Tenants[j]); } } Console.Error.WriteLine("wrote {0} libraries with {1} instances and {2} relationships total", mcl.Libraries.Count, totalInstances, totalRelationships); string outputDir = System.IO.Path.GetDirectoryName(outputFileName); if (!System.IO.Directory.Exists(outputDir)) { System.IO.Directory.CreateDirectory(outputDir); } FileAccessor faout = new FileAccessor(outputFileName, true, true); Document.Save(mcl, mcx, faout); }
protected override void AfterLoadInternal(Stack <ObjectModel> objectModels) { base.AfterLoadInternal(objectModels); MarkupObjectModel mom = (objectModels.Pop() as MarkupObjectModel); MochaClassLibraryObjectModel mcl = (objectModels.Pop() as MochaClassLibraryObjectModel); MarkupTagElement tagMocha = (mom.Elements["mocha"] as MarkupTagElement); if (tagMocha == null) { throw new InvalidDataFormatException("file does not contain top-level 'mocha' tag"); } MarkupTagElement tagLibraries = (tagMocha.Elements["libraries"] as MarkupTagElement); if (tagLibraries != null) { for (int i = 0; i < tagLibraries.Elements.Count; i++) { MochaLibrary library = LoadLibrary(mcl, tagLibraries.Elements[i] as MarkupTagElement); if (library == null) { continue; } mcl.Libraries.Merge(library); } } MarkupTagElement tagTenants = (tagMocha.Elements["tenants"] as MarkupTagElement); if (tagTenants != null) { foreach (MarkupTagElement tagTenant in tagTenants.Elements.OfType <MarkupTagElement>()) { if (tagTenant == null) { continue; } if (tagTenant.FullName != "tenant") { continue; } MarkupAttribute attTenantID = tagTenant.Attributes["id"]; MarkupAttribute attTenantName = tagTenant.Attributes["name"]; if (attTenantID == null || attTenantName == null) { continue; } MochaTenant tenant = new MochaTenant(); tenant.ID = new Guid(attTenantID.Value); tenant.Name = attTenantName.Value; MarkupTagElement tagLibraryReferences = tagTenant.Elements["libraryReferences"] as MarkupTagElement; if (tagLibraryReferences != null) { foreach (MarkupTagElement tagLibraryReference in tagLibraryReferences.Elements.OfType <MarkupTagElement>()) { MarkupAttribute attLibraryId = tagLibraryReference.Attributes["libraryId"]; if (attLibraryId == null) { continue; } tenant.LibraryReferences.Add(new MochaLibraryReference(new Guid(attLibraryId.Value))); } } MarkupTagElement tagInstances = tagTenant.Elements["instances"] as MarkupTagElement; if (tagInstances != null) { foreach (MarkupTagElement tagInstance in tagInstances.Elements.OfType <MarkupTagElement>()) { MochaInstance inst = LoadInstance(tenant, tagInstance); tenant.Instances.Add(inst); } } mcl.Tenants.Add(tenant); } } }
private MochaLibrary LoadLibrary(MochaClassLibraryObjectModel parent, MarkupTagElement tag) { if (tag == null) { return(null); } if (tag.FullName != "library") { return(null); } MarkupAttribute attGuid = tag.Attributes["id"]; if (attGuid == null) { return(null); } Guid id = new Guid(attGuid.Value); MochaLibrary library = parent.Libraries[id]; if (library == null) { library = new MochaLibrary(); library.ID = id; } MarkupAttribute attDefaultObjectSourceId = tag.Attributes["defaultObjectSourceId"]; if (attDefaultObjectSourceId != null) { library.DefaultObjectSourceID = new Guid(attDefaultObjectSourceId.Value); } else { library.DefaultObjectSourceID = global::Mocha.Core.KnownInstanceGuids.ObjectSources.System; } MarkupTagElement tagMetadata = tag.Elements["metadata"] as MarkupTagElement; if (tagMetadata != null) { for (int i = 0; i < tagMetadata.Elements.Count; i++) { MarkupTagElement tagMetadataItem = tagMetadata.Elements[i] as MarkupTagElement; if (tagMetadataItem == null) { continue; } library.Metadata.Add(new MochaLibraryMetadata(tagMetadataItem.Name, tagMetadataItem.Value)); } } MarkupTagElement tagInstances = tag.Elements["instances"] as MarkupTagElement; if (tagInstances != null) { for (int i = 0; i < tagInstances.Elements.Count; i++) { MochaInstance inst = LoadInstance(library, tagInstances.Elements[i] as MarkupTagElement); if (inst == null) { continue; } library.Instances.Add(inst); } } return(library); }
protected override void AfterLoadInternal(Stack <ObjectModel> objectModels) { base.AfterLoadInternal(objectModels); if (objectModels.Count < 2) { throw new ObjectModelNotSupportedException("must have a FileSystemObjectModel and a MochaClassLibraryObjectModel in the stack"); } FileSystemObjectModel fsom = (objectModels.Pop() as FileSystemObjectModel); if (fsom == null) { throw new ObjectModelNotSupportedException(); } ObjectModel om = objectModels.Pop(); MochaSnapshotObjectModel mcx = (om as MochaSnapshotObjectModel); MochaClassLibraryObjectModel mcl = (om as MochaClassLibraryObjectModel); if (mcl == null && mcx == null) { throw new ObjectModelNotSupportedException(); } List <Guid> _instanceGuids = new List <Guid>(); List <string> _stringTable = new List <string>(); LIBRARY_INFO[] library_info = null; // COMMON TABLES #region Guid Table { File fGlobalIdentifiers = fsom.FindFile("GlobalIdentifiers"); using (MemoryAccessor ma = new MemoryAccessor(fGlobalIdentifiers.GetData())) { int instanceCount = ma.Reader.ReadInt32(); for (int i = 0; i < instanceCount; i++) { _instanceGuids.Add(ma.Reader.ReadGuid()); } } } #endregion #region String Table { File f = fsom.FindFile("StringTable"); using (MemoryAccessor ma = new MemoryAccessor(f.GetData())) { int stringTableCount = ma.Reader.ReadInt32(); for (int i = 0; i < stringTableCount; i++) { string value = ma.Reader.ReadNullTerminatedString(); _stringTable.Add(value); } } } #endregion // MCL-SPECIFIC #region Libraries File fLibraries = fsom.FindFile("Libraries"); if (mcl != null && fLibraries != null) { using (MemoryAccessor ma = new MemoryAccessor(fLibraries.GetData())) { int libraryCount = ma.Reader.ReadInt32(); library_info = new LIBRARY_INFO[libraryCount]; for (int i = 0; i < libraryCount; i++) { MochaLibrary library = new MochaLibrary(); library.ID = ma.Reader.ReadGuid(); library_info[i].instanceCount = ma.Reader.ReadInt32(); // library_info[i].attributeValueCount = ma.Reader.ReadInt32(); library_info[i].relationshipCount = ma.Reader.ReadInt32(); mcl.Libraries.Add(library); } } } else { Console.Error.WriteLine("mocha: mcl: error: ignoring 'Libraries' section found in non-mcl file"); } #endregion INSTANCE_INFO[] instance_info = null; #region Instances File fInstances = fsom.FindFile("Instances"); if (mcl != null && fInstances != null) { using (MemoryAccessor ma = new MemoryAccessor(fInstances.GetData())) { for (int i = 0; i < mcl.Libraries.Count; i++) { int instanceCount = ma.Reader.ReadInt32(); instance_info = new INSTANCE_INFO[instanceCount]; for (int j = 0; j < instanceCount; j++) { instance_info[j].instanceIndex = ma.Reader.ReadInt32(); instance_info[j].attributeValueCount = ma.Reader.ReadInt32(); MochaInstanceFlags flags = (MochaInstanceFlags)ma.Reader.ReadInt32(); int?index = null; if ((flags & MochaInstanceFlags.HasIndex) == MochaInstanceFlags.HasIndex) { index = ma.Reader.ReadInt32(); } MochaInstance inst = new MochaInstance(); inst.ID = _instanceGuids[instance_info[j].instanceIndex]; inst.Index = index; mcl.Libraries[i].Instances.Add(inst); } } } } else { Console.Error.WriteLine("mocha: mcl: error: ignoring 'Instances' section found in non-mcl file"); } #endregion #region Attributes File fAttributes = fsom.FindFile("Attributes"); if (mcl != null && fAttributes != null) { using (MemoryAccessor ma = new MemoryAccessor(fAttributes.GetData())) { for (int i = 0; i < mcl.Libraries.Count; i++) { for (int j = 0; j < mcl.Libraries[i].Instances.Count; j++) { for (int k = 0; k < instance_info[j].attributeValueCount; k++) { int attributeInstanceIndex = ma.Reader.ReadInt32(); MochaAttributeValue val = new MochaAttributeValue(); val.AttributeInstanceID = _instanceGuids[attributeInstanceIndex]; MochaAttributeType attributeType = (MochaAttributeType)ma.Reader.ReadInt32(); switch (attributeType) { case MochaAttributeType.None: break; case MochaAttributeType.Text: { int stringTableIndex = ma.Reader.ReadInt32(); string value = _stringTable[stringTableIndex]; val.Value = value; break; } case MochaAttributeType.Boolean: { bool value = ma.Reader.ReadBoolean(); val.Value = value; break; } case MochaAttributeType.Date: { DateTime value = ma.Reader.ReadDateTime(); val.Value = value; break; } case MochaAttributeType.Unknown: { break; } } mcl.Libraries[i].Instances[j].AttributeValues.Add(val); } } } } } else { Console.Error.WriteLine("mocha: mcl: error: ignoring 'Attributes' section found in non-mcl file"); } #endregion #region Relationships File fRelationships = fsom.FindFile("Relationships"); if (mcl != null && fRelationships != null) { using (MemoryAccessor ma = new MemoryAccessor(fRelationships.GetData())) { for (int i = 0; i < mcl.Libraries.Count; i++) { for (int j = 0; j < library_info[i].relationshipCount; j++) { int relationshipIndex = ma.Reader.ReadInt32(); int sourceInstanceIndex = ma.Reader.ReadInt32(); MochaRelationship rel = new MochaRelationship(); rel.RelationshipInstanceID = _instanceGuids[relationshipIndex]; rel.SourceInstanceID = _instanceGuids[sourceInstanceIndex]; int targetInstanceCount = ma.Reader.ReadInt32(); for (int k = 0; k < targetInstanceCount; k++) { int instanceIndex = ma.Reader.ReadInt32(); rel.DestinationInstanceIDs.Add(_instanceGuids[instanceIndex]); } mcl.Libraries[i].Relationships.Add(rel); } } } } else { Console.Error.WriteLine("mocha: mcl: error: ignoring 'Relationships' section found in non-mcl file"); } #endregion #region Tenants File fTenants = fsom.FindFile("Tenants"); if (mcl != null && fTenants != null) { using (MemoryAccessor ma = new MemoryAccessor(fTenants.GetData())) { int tenantCount = ma.Reader.ReadInt32(); for (int i = 0; i < tenantCount; i++) { int instanceIndex = ma.Reader.ReadInt32(); Guid instanceGuid = _instanceGuids[instanceIndex]; int tenantNameIndex = ma.Reader.ReadInt32(); string tenantName = _stringTable[tenantNameIndex]; MochaTenant tenant = new MochaTenant(); tenant.ID = instanceGuid; tenant.Name = tenantName; int libraryReferenceCount = ma.Reader.ReadInt32(); for (int j = 0; j < libraryReferenceCount; j++) { int libraryIndex = ma.Reader.ReadInt32(); Guid libraryID = _instanceGuids[libraryIndex]; tenant.LibraryReferences.Add(new MochaLibraryReference(libraryID)); } int instanceCount = ma.Reader.ReadInt32(); for (int j = 0; j < instanceCount; j++) { int instanceIndex2 = ma.Reader.ReadInt32(); MochaInstance inst = new MochaInstance(); inst.ID = _instanceGuids[instanceIndex2]; tenant.Instances.Add(inst); } int relationshipCount = ma.Reader.ReadInt32(); for (int j = 0; j < relationshipCount; j++) { int sourceInex = ma.Reader.ReadInt32(); Guid ssource = _instanceGuids[sourceInex]; int relationshipInex = ma.Reader.ReadInt32(); Guid relati = _instanceGuids[relationshipInex]; MochaRelationship rel = new MochaRelationship(); rel.SourceInstanceID = ssource; rel.RelationshipInstanceID = relati; int count = ma.Reader.ReadInt32(); for (int k = 0; k < count; k++) { int targetIndex = ma.Reader.ReadInt32(); Guid targ = _instanceGuids[targetIndex]; rel.DestinationInstanceIDs.Add(targ); } tenant.Relationships.Add(rel); } mcl.Tenants.Add(tenant); } ma.Close(); fTenants.SetData(ma.ToArray()); } } else { Console.Error.WriteLine("mocha: mcl: error: ignoring 'Tenants' section found in non-mcl file"); } #endregion #region Journal // journal is present in MCX / MCD (application, data files) // is an opcode based format // eg. 0x01 = create instance, 0x02 = delete instance // 0x04 = set attribute value, 0x05 = delete attribute value // 0x08 = create relationship, 0x09 = remove relationship File fJournal = fsom.FindFile("Journal"); if (mcx != null && fJournal != null) { using (MemoryAccessor ma = new MemoryAccessor(fJournal.GetData())) { MochaSnapshotTransaction currentTransaction = null; while (!ma.Reader.EndOfStream) { MochaOpcode opcode = (MochaOpcode)ma.Reader.ReadByte(); switch (opcode) { case MochaOpcode.BeginTransaction: { currentTransaction = new MochaSnapshotTransaction(); currentTransaction.TenantName = _stringTable[ma.Reader.ReadInt32()]; break; } case MochaOpcode.EndTransaction: { mcx.Transactions.Add(currentTransaction); currentTransaction = null; break; } case MochaOpcode.CreateInstance: { DateTime effectiveDate = ma.Reader.ReadDateTime(); int guidIndex = ma.Reader.ReadInt32(); int classGuidIndex = ma.Reader.ReadInt32(); MochaSnapshotCreateInstanceTransactionOperation op = new MochaSnapshotCreateInstanceTransactionOperation(); op.GlobalIdentifier = _instanceGuids[guidIndex]; op.ClassGlobalIdentifier = _instanceGuids[classGuidIndex]; op.EffectiveDate = effectiveDate; currentTransaction.Operations.Add(op); break; } case MochaOpcode.CreateRelationship: case MochaOpcode.RemoveRelationship: { DateTime effectiveDate = ma.Reader.ReadDateTime(); int sourceInstanceIndex = ma.Reader.ReadInt32(); int relationshipIndex = ma.Reader.ReadInt32(); int targetInstanceCount = ma.Reader.ReadInt32(); MochaSnapshotAssociateRelationshipTransactionOperation rel = new MochaSnapshotAssociateRelationshipTransactionOperation(); rel.RelationshipInstanceID = _instanceGuids[relationshipIndex]; rel.SourceInstanceID = _instanceGuids[sourceInstanceIndex]; rel.EffectiveDate = effectiveDate; for (int k = 0; k < targetInstanceCount; k++) { int instanceIndex = ma.Reader.ReadInt32(); rel.TargetInstanceIDs.Add(_instanceGuids[instanceIndex]); } if (opcode == MochaOpcode.RemoveRelationship) { rel.Remove = true; } currentTransaction.Operations.Add(rel); break; } case MochaOpcode.AssignAttribute: { DateTime effectiveDate = ma.Reader.ReadDateTime(); int instanceIndex = ma.Reader.ReadInt32(); Guid instanceID = _instanceGuids[instanceIndex]; int attributeIndex = ma.Reader.ReadInt32(); Guid attributeInstanceID = _instanceGuids[attributeIndex]; object value = ReadMochaValue(ma.Reader, _stringTable); MochaSnapshotAssignAttributeTransactionOperation mav = new MochaSnapshotAssignAttributeTransactionOperation(); mav.SourceInstanceID = instanceID; mav.AttributeInstanceID = attributeInstanceID; mav.EffectiveDate = effectiveDate; mav.Value = value; currentTransaction.Operations.Add(mav); break; } } } } } else { Console.Error.WriteLine("mocha: mcl: error: ignoring 'Journal' section found in non-mcx file"); } #endregion }
protected override void BeforeSaveInternal(Stack <ObjectModel> objectModels) { base.BeforeSaveInternal(objectModels); FileNameSize = 32; ObjectModel om = objectModels.Pop(); MochaClassLibraryObjectModel mcl = (om as MochaClassLibraryObjectModel); MochaSnapshotObjectModel mcx = (om as MochaSnapshotObjectModel); if (mcl == null && mcx == null) { throw new ObjectModelNotSupportedException(); } FileSystemObjectModel fsom = new FileSystemObjectModel(); List <Guid> _instanceIndices = new List <Guid>(); List <string> _stringTable = new List <string>(); if (mcl != null) { #region Libraries { File f = fsom.AddFile("Libraries"); MemoryAccessor ma = new MemoryAccessor(); ma.Writer.WriteInt32(mcl.Libraries.Count); for (int i = 0; i < mcl.Libraries.Count; i++) { ma.Writer.WriteGuid(mcl.Libraries[i].ID); ma.Writer.WriteInt32(mcl.Libraries[i].Instances.Count); ma.Writer.WriteInt32(mcl.Libraries[i].Relationships.Count); } ma.Close(); f.SetData(ma.ToArray()); } #endregion #region Instances { File f = fsom.AddFile("Instances"); MemoryAccessor ma = new MemoryAccessor(); for (int i = 0; i < mcl.Libraries.Count; i++) { ma.Writer.WriteInt32(mcl.Libraries[i].Instances.Count); for (int j = 0; j < mcl.Libraries[i].Instances.Count; j++) { ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, mcl.Libraries[i].Instances[j].ID)); ma.Writer.WriteInt32(mcl.Libraries[i].Instances[j].AttributeValues.Count); MochaInstanceFlags flags = MochaInstanceFlags.None; if (mcl.Libraries[i].Instances[j].Index != null) { flags |= MochaInstanceFlags.HasIndex; } ma.Writer.WriteInt32((int)flags); if ((flags & MochaInstanceFlags.HasIndex) == MochaInstanceFlags.HasIndex) { ma.Writer.WriteInt32(mcl.Libraries[i].Instances[j].Index.Value); } } } ma.Close(); f.SetData(ma.ToArray()); } #endregion #region Attributes { File f = fsom.AddFile("Attributes"); MemoryAccessor ma = new MemoryAccessor(); for (int i = 0; i < mcl.Libraries.Count; i++) { /* * writer.WriteInt32(mcl.Libraries[i].Metadata.Count); * for (int j = 0; j < mcl.Libraries[i].Metadata.Count; j++) * { * writer.WriteNullTerminatedString(mcl.Libraries[i].Metadata[j].Name); * writer.WriteNullTerminatedString(mcl.Libraries[i].Metadata[j].Value); * } */ for (int j = 0; j < mcl.Libraries[i].Instances.Count; j++) { for (int k = 0; k < mcl.Libraries[i].Instances[j].AttributeValues.Count; k++) { ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, mcl.Libraries[i].Instances[j].AttributeValues[k].AttributeInstanceID)); if (mcl.Libraries[i].Instances[j].AttributeValues[k].Value == null) { ma.Writer.WriteInt32((int)MochaAttributeType.None); } else if (mcl.Libraries[i].Instances[j].AttributeValues[k].Value is string) { ma.Writer.WriteInt32((int)MochaAttributeType.Text); ma.Writer.WriteInt32(AddOrUpdateLookupTable <string>(_stringTable, mcl.Libraries[i].Instances[j].AttributeValues[k].Value as string)); } else { ma.Writer.WriteInt32((int)MochaAttributeType.Unknown); ma.Writer.WriteObject(mcl.Libraries[i].Instances[j].AttributeValues[k].Value); } } } } ma.Close(); f.SetData(ma.ToArray()); } #endregion #region Relationships { File f = fsom.AddFile("Relationships"); MemoryAccessor ma = new MemoryAccessor(); for (int i = 0; i < mcl.Libraries.Count; i++) { for (int j = 0; j < mcl.Libraries[i].Relationships.Count; j++) { ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, mcl.Libraries[i].Relationships[j].RelationshipInstanceID)); ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, mcl.Libraries[i].Relationships[j].SourceInstanceID)); ma.Writer.WriteInt32(mcl.Libraries[i].Relationships[j].DestinationInstanceIDs.Count); for (int k = 0; k < mcl.Libraries[i].Relationships[j].DestinationInstanceIDs.Count; k++) { ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, mcl.Libraries[i].Relationships[j].DestinationInstanceIDs[k])); } } } ma.Close(); f.SetData(ma.ToArray()); } #endregion #region Tenants { if (mcl.Tenants.Count > 0) { File f = fsom.AddFile("Tenants"); MemoryAccessor ma = new MemoryAccessor(); ma.Writer.WriteInt32(mcl.Tenants.Count); foreach (MochaTenant tenant in mcl.Tenants) { ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, tenant.ID)); ma.Writer.WriteInt32(AddOrUpdateLookupTable <string>(_stringTable, tenant.Name)); ma.Writer.WriteInt32(tenant.LibraryReferences.Count); for (int i = 0; i < tenant.LibraryReferences.Count; i++) { ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, tenant.LibraryReferences[i].LibraryID)); } ma.Writer.WriteInt32(tenant.Instances.Count); for (int i = 0; i < tenant.Instances.Count; i++) { ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, tenant.Instances[i].ID)); } ma.Writer.WriteInt32(tenant.Relationships.Count); for (int i = 0; i < tenant.Relationships.Count; i++) { ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, tenant.Relationships[i].SourceInstanceID)); ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, tenant.Relationships[i].RelationshipInstanceID)); ma.Writer.WriteInt32(tenant.Relationships[i].DestinationInstanceIDs.Count); for (int j = 0; j < tenant.Relationships[i].DestinationInstanceIDs.Count; j++) { ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, tenant.Relationships[i].DestinationInstanceIDs[j])); } } } ma.Close(); f.SetData(ma.ToArray()); } } #endregion } else if (mcx != null) { #region Journal { if (mcx.Transactions.Count > 0) { File f = fsom.AddFile("Journal"); MemoryAccessor ma = new MemoryAccessor(); foreach (MochaSnapshotTransaction t in mcx.Transactions) { ma.Writer.WriteByte((byte)MochaOpcode.BeginTransaction); ma.Writer.WriteInt32(AddOrUpdateLookupTable <string>(_stringTable, t.TenantName)); foreach (MochaSnapshotTransactionOperation op in t.Operations) { if (op is MochaSnapshotCreateInstanceTransactionOperation ci) { ma.Writer.WriteByte((byte)MochaOpcode.CreateInstance); ma.Writer.WriteDateTime(ci.EffectiveDate); ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, ci.GlobalIdentifier)); ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, ci.ClassGlobalIdentifier)); } else if (op is MochaSnapshotAssignAttributeTransactionOperation aa) { ma.Writer.WriteByte((byte)MochaOpcode.AssignAttribute); ma.Writer.WriteDateTime(aa.EffectiveDate); ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, aa.SourceInstanceID)); ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, aa.AttributeInstanceID)); WriteMochaValue(ma.Writer, aa.Value, _stringTable); } else if (op is MochaSnapshotAssociateRelationshipTransactionOperation ar) { ma.Writer.WriteByte((byte)MochaOpcode.CreateRelationship); ma.Writer.WriteDateTime(ar.EffectiveDate); ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, ar.SourceInstanceID)); ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, ar.RelationshipInstanceID)); ma.Writer.WriteInt32(ar.TargetInstanceIDs.Count); foreach (Guid id in ar.TargetInstanceIDs) { ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, id)); } } } ma.Writer.WriteByte((byte)MochaOpcode.EndTransaction); } ma.Close(); f.SetData(ma.ToArray()); } } #endregion } #region Guid Table { File f = fsom.AddFile("GlobalIdentifiers"); MemoryAccessor ma = new MemoryAccessor(); ma.Writer.WriteInt32(_instanceIndices.Count); foreach (Guid id in _instanceIndices) { ma.Writer.WriteGuid(id); } ma.Close(); f.SetData(ma.ToArray()); } #endregion #region String Table { File f = fsom.AddFile("StringTable"); MemoryAccessor ma = new MemoryAccessor(); ma.Writer.WriteInt32(_stringTable.Count); foreach (string id in _stringTable) { ma.Writer.WriteNullTerminatedString(id); } ma.Close(); f.SetData(ma.ToArray()); } #endregion objectModels.Push(fsom); }