private void FullDownload(IPersistenceEngine client, IPersistenceEngine server, bool bulk) { if (client is SyncEngine) { ((SyncEngine)client).IgnoreClientMetadata = true; } // Contains id translation table Hashtable translationTable = new Hashtable(); Hashtable reverseTable = new Hashtable(); Transaction t = new Transaction(client.Factory.Model); StringCollection queries = new StringCollection(); // Creates the list of items to load depending whether filters are set or not if (filters.Count > 0) { queries = filters; } else { foreach (Model.Entity entity in server.Factory.Model.Entities.Values) { // Process only root types as it will load all children if (entity.Inherit != String.Empty && entity.Inherit != null && server.Factory.Model.Entities.ContainsKey(entity.Inherit)) continue; queries.Add("from " + entity.Type + " e select e"); } } if (Progressed != null) { // Returns opaths.Count * 2 so that half the processed is reached once entities are processed Progressed(this, new ProgressEventArgs(0, "Synchronization started", queries.Count * 2)); } int position = 0; // Import all entities foreach (string filter in queries) { if (Progressed != null) { // Returns opaths.Count * 2 so that half the processed is reached once entities are processed ProgressEventArgs args = new ProgressEventArgs(position++, "Processing " + filter, queries.Count * 2); Progressed(this, args); if (args.Cancel) { return; } } int count = Convert.ToInt32(server.LoadScalar(String.Concat("(", filter, ").Count()"))); // System.Diagnostics.Trace.WriteLine("Processing " + opaths + "(" + count.ToString() + ")"); // Loads a set of entities (span) if (count > 0) { t = new Transaction(client.Factory.Model); IList<Entity> entities = server.Load(filter); foreach (Entity e in entities) { e.State = State.New; t.Serialize(e); } t.Commit(client, false); // Retrieves the translated ids foreach (KeyValuePair<string, string> de in t.NewIds) { translationTable.Add(String.Concat(entities[0].Type, ".", de.Key), de.Value); reverseTable.Add(String.Concat(entities[0].Type, ".", de.Value), de.Key); } } } if (bulk) { t = new Transaction(client.Factory.Model); } position = 0; // Import all relationships foreach (Model.Entity entity in client.Factory.Model.Entities.Values) { if (Progressed != null) { ProgressEventArgs args = new ProgressEventArgs(queries.Count + position++, "Processing " + entity.Type + " relationships", queries.Count + client.Factory.Model.Entities.Count); Progressed(this, args); if (args.Cancel) { return; } } // Process only root types as it will load all children if (entity.Inherit != String.Empty && entity.Inherit != null) continue; foreach (Entity parent in client.Load(entity.Type)) { foreach (Model.Reference reference in server.Factory.Model.GetInheritedReferences(parent.Type)) { string uniqueParentKey = String.Concat(entity.Type, ".", parent.Id); string reversedParentId = reverseTable.Contains(uniqueParentKey) ? reverseTable[uniqueParentKey].ToString() : parent.Id; string query = String.Concat(entity.Type, "[id('", reversedParentId, "')].", reference.Name); int count = Convert.ToInt32(server.LoadScalar(String.Concat("count(", query, ")"))); // Loads a set of entities (span) if (count > 0) { if (!bulk) { t = new Transaction(client.Factory.Model); } IList<Entity> entities = server.Load(query); foreach (Entity e in entities) { string uniqueChildKey = String.Concat(e.Type, ".", e.Id); string childId = translationTable.Contains(uniqueChildKey) ? translationTable[uniqueChildKey].ToString() : e.Id; t.PushCommand(new Commands.CreateReferenceCommand(reference, parent, e)); } if (!bulk) { t.Commit(client, false); } } } } } if (bulk) { t.Commit(client, false); } // Creates a Connection token if the providers permit it if (client is SyncEngine && server is SyncEngine) { Entity connection = GetConnection(((SyncEngine)client).ClientId, (SyncEngine)server); Transaction it; Entity info = null; IPersistenceEngine engine = GetPeerMetadataEngine((SyncEngine)server, Peer.Server); IList<Entity> infos = engine.Load("from " + SyncUtils.INFO + "i select i"); if (infos.Count > 0) { info = infos[0]; } else { info = new Entity(SyncUtils.INFO); info.SetValue(SyncUtils.TRANSACTION, 0); info.SetValue(SyncUtils.CLIENTID, String.Empty); it = new Transaction(engine.Factory.Model); it.Serialize(info); it.Commit(engine, false); } connection.SetValue(SyncUtils.TRANSACTION, info.GetInt32(SyncUtils.TRANSACTION)); it = new Transaction(engine.Factory.Model); it.Serialize(connection); it.Commit(engine, false); ((SyncEngine)client).IgnoreClientMetadata = false; } }