Example #1
0
        public override CompoundUpdateCommand Visit(CompoundUpdateCommand c)
        {
            foreach (Command cc in c.InnerCommands)
                Visit(cc);

            return c;
        }
Example #2
0
		public void Process(CompoundUpdateCommand c)
		{
			foreach(Command cc in c.InnerCommands)
				cc.Accept(this);
		}
Example #3
0
        public void Process(CompoundUpdateCommand c)
        {
            // As a CompoundUpdateCommand can also contain CreateAttributeCommand we convert them if necessary
            for (int i = 0; i < c.InnerCommands.Count; i++)
                if (c.InnerCommands[i] is CreateAttributeCommand)
                {
                    CreateAttributeCommand uac = c.InnerCommands[i] as CreateAttributeCommand;
                    c.InnerCommands[i] = new UpdateAttributeCommand(uac.ParentId, uac.ParentType, uac.Name, uac.Type, uac.Value);
                }

            ArrayList queries = new ArrayList();
            CacheEntityEntry entityEntry = _Engine.GetCacheEntityEntry(c.ParentType);
            EntityMapping e = (EntityMapping)entityEntry.Mapping;
            Hashtable table = ProcessUpdateAttributeCommands(e, c.InnerCommands);

            foreach (CacheQueryEntry entry in InitializeCompoundUpdateCommand(e, c.InnerCommands).Values)
            {
                ArrayList genericEntries = new ArrayList();
                if (entry.IsAttributeGenericQuery)
                {
                    AttributeMapping a = e.Attributes["*"];
                    for (int index = 0; index < ((ArrayList)table[a]).Count; index++)
                    {
                        genericEntries.Add(entry.Clone());
                    }
                }

                foreach (Parameter p in entry.Parameters)
                {
                    switch (p.Name)
                    {
                        // Process parameter value to "Entity Id"
                        case "EntityId":
                            {
                                DictionaryEntry dEntry = FindDictionaryEntry(entry, queries);
                                if (!queries.Contains(dEntry))
                                    queries.Add(dEntry);

                                if (!((IDbCommand)dEntry.Value).Parameters.Contains("@EntityId"))
                                {
                                    IDbDataParameter param = _Driver.CreateParameter("EntityId", _Dialect.GetDbTypeToPrimaryKey(e.Ids[0].Generator), c.ParentId);
                                    ((IDbCommand)dEntry.Value).Parameters.Add(param);
                                }
                            }
                            break;
                        // Process parameter value to "Entity Discriminator"
                        case "EntityDiscriminator":
                            {
                                DictionaryEntry dEntry = FindDictionaryEntry(entry, queries);
                                if (!queries.Contains(dEntry))
                                    queries.Add(dEntry);

                                if (!((IDbCommand)dEntry.Value).Parameters.Contains("@EntityDiscriminator"))
                                {
                                    IDbDataParameter param = _Driver.CreateParameter("EntityDiscriminator", DbType.String, c.ParentType);
                                    ((IDbCommand)dEntry.Value).Parameters.Add(param);
                                }
                            }
                            break;
                        // Process parameter value to "FK_Entity"
                        case "FK_Entity":
                            {
                                AttributeMapping a = (AttributeMapping)p.TagMapping;
                                if (!entry.IsAttributeGenericQuery && ((ArrayList)table[a]).Count == 0)
                                {
                                    DictionaryEntry dEntry = FindDictionaryEntry(entry, queries);
                                    if (!queries.Contains(dEntry))
                                        queries.Add(dEntry);

                                    IDbDataParameter param = _Driver.CreateParameter("FK_Entity", _Dialect.GetDbTypeToPrimaryKey(e.Ids[0].Generator), c.ParentId);
                                    ((IDbCommand)dEntry.Value).Parameters.Add(param);
                                }
                                foreach (UpdateAttributeCommand cc in (ArrayList)table[a])
                                {
                                    DictionaryEntry dEntry;
                                    if (entry.IsAttributeGenericQuery)
                                        dEntry = FindDictionaryEntry((CacheQueryEntry)genericEntries[((ArrayList)table[a]).IndexOf(cc)], queries);
                                    else
                                        dEntry = FindDictionaryEntry(entry, queries);


                                    if (!queries.Contains(dEntry))
                                        queries.Add(dEntry);
                                    IDbDataParameter param = _Driver.CreateParameter("FK_Entity", DbType.String, c.ParentId);
                                    ((IDbCommand)dEntry.Value).Parameters.Add(param);
                                }
                            }
                            break;
                        // Process parameter value to "AttributeDiscriminator"
                        case "AttributeDiscriminator":
                            {
                                AttributeMapping a = (AttributeMapping)p.TagMapping;
                                if (!entry.IsAttributeGenericQuery && ((ArrayList)table[a]).Count == 0)
                                {
                                    DictionaryEntry dEntry = FindDictionaryEntry(entry, queries);
                                    if (!queries.Contains(dEntry))
                                        queries.Add(dEntry);

                                    IDbDataParameter param = _Driver.CreateParameter("AttributeDiscriminator", DbType.String, a.Name);
                                    ((IDbCommand)dEntry.Value).Parameters.Add(param);
                                }
                                foreach (UpdateAttributeCommand cc in (ArrayList)table[a])
                                {
                                    DictionaryEntry dEntry;
                                    if (entry.IsAttributeGenericQuery)
                                        dEntry = FindDictionaryEntry((CacheQueryEntry)genericEntries[((ArrayList)table[a]).IndexOf(cc)], queries);
                                    else
                                        dEntry = FindDictionaryEntry(entry, queries);

                                    if (!queries.Contains(dEntry))
                                        queries.Add(dEntry);

                                    IDbDataParameter param = _Driver.CreateParameter("AttributeDiscriminator", DbType.String, cc.Name);
                                    ((IDbCommand)dEntry.Value).Parameters.Add(param);
                                }
                            }
                            break;
                        // Process value to attribute
                        default:
                            {
                                if (p.TagMapping as AttributeMapping != null)
                                {
                                    AttributeMapping a = (AttributeMapping)p.TagMapping;
                                    if (!entry.IsAttributeGenericQuery && ((ArrayList)table[a]).Count == 0)
                                    {
                                        DictionaryEntry dEntry = FindDictionaryEntry(entry, queries);
                                        if (!queries.Contains(dEntry))
                                            queries.Add(dEntry);

                                        // if attributecommand not find : apply a default value
                                        // initialize value to parameter
                                        SerializableType serializableType = a.GetSerializableType(a.DbType, a.Type);
                                        object value = null;
                                        if (a.DefaultValue != null)
                                        {
                                            switch (serializableType)
                                            {
                                                case SerializableType.BinarySerialization:
                                                    value = Utils.SerializeToArray(a.DefaultValue);
                                                    break;
                                                case SerializableType.StringSerialization:
                                                    value = Utils.SerializeToString(a.DefaultValue);
                                                    break;
                                                case SerializableType.Standard:
                                                    if (a.DefaultValue != String.Empty)
                                                        value = a.DefaultValue;
                                                    break;
                                                case SerializableType.String:
                                                    value = Utils.ConvertToString(a.DefaultValue, a.Type);
                                                    break;
                                                case SerializableType.Int:
                                                    value = Convert.ToInt32(a.DefaultValue);
                                                    break;
                                            }
                                        }

                                        object formattedValue = _Dialect.PreProcessValue(value);

                                        IDbDataParameter param = _Driver.CreateParameter(p.Name, a.DbType, formattedValue);
                                        ((IDbCommand)dEntry.Value).Parameters.Add(param);
                                    }
                                    foreach (UpdateAttributeCommand cc in (ArrayList)table[a])
                                    {
                                        DictionaryEntry dEntry;
                                        if (entry.IsAttributeGenericQuery)
                                            dEntry = FindDictionaryEntry((CacheQueryEntry)genericEntries[((ArrayList)table[a]).IndexOf(cc)], queries);
                                        else
                                            dEntry = FindDictionaryEntry(entry, queries);


                                        if (!queries.Contains(dEntry))
                                            queries.Add(dEntry);

                                        // if attributecommand not find : apply a default value
                                        object commandValue = cc == null ? a.DefaultValue : cc.Value;
                                        // initialize value to parameter
                                        SerializableType serializableType = a.Type == null ? a.GetSerializableType(a.DbType, cc.Type) : a.GetSerializableType(a.DbType, a.Type);
                                        object value = null;
                                        if (commandValue != null)
                                        {
                                            switch (serializableType)
                                            {
                                                case SerializableType.BinarySerialization:
                                                    value = Utils.SerializeToArray(commandValue);
                                                    break;
                                                case SerializableType.StringSerialization:
                                                    value = Utils.SerializeToString(commandValue);
                                                    break;
                                                case SerializableType.Standard:
                                                    value = commandValue;
                                                    break;
                                                case SerializableType.String:
                                                    //value = Utils.ConvertToString(commandValue, cc.Type, true);
                                                    value = Utils.ConvertToString(commandValue, cc.Type);
                                                    break;
                                                case SerializableType.Int:
                                                    value = Convert.ToInt32(commandValue);
                                                    break;
                                            }
                                        }

                                        object formattedValue = _Dialect.PreProcessValue(value);

                                        IDbDataParameter param = a.CreateDbDataParameter(p.Name, formattedValue);
                                        ((IDbCommand)dEntry.Value).Parameters.Add(param);
                                    }
                                }
                                else if (p.TagMapping as PrimaryKeyMapping != null)
                                {
                                    string[] parentIds = c.ParentId.Split(SqlMapperProvider.IDSEP);

                                    int idPosition = int.Parse(p.Name.Replace("Id", string.Empty));

                                    DictionaryEntry dEntry = FindDictionaryEntry(entry, queries);
                                    if (!queries.Contains(dEntry))
                                        queries.Add(dEntry);

                                    ((IDbCommand)dEntry.Value).Parameters.Add(_Driver.CreateParameter(p.Name, _Dialect.GetDbTypeToPrimaryKey(e.Ids[idPosition].Generator), ConvertId(e.Ids[idPosition].Generator, parentIds[idPosition])));
                                }
                            }
                            break;
                    }
                }
            }


            foreach (DictionaryEntry dEntry in queries)
            {
                IDbCommand command = (IDbCommand)dEntry.Value;

                // By using OleDb, the order of IDataParameter must match
                // the order of the values in the request
                _Driver.PreProcessQuery(command);

                command.Transaction = _Transaction;

                if (_Engine.TraceSqlSwitch.Enabled)
                {
                    TraceHelpler.Trace(command, _Dialect);
                }

                command.ExecuteNonQuery();
            }
        }
Example #4
0
 public abstract CompoundUpdateCommand Visit(CompoundUpdateCommand item);
Example #5
0
        /// <summary>
        /// Creates Compound commands if necessary
        /// </summary>
        /// <param name="commands"></param>
        private Command[] OptimizeCommands(SyncEngine engine, IList<Entity> commands)
        {
            if (commands == null)
                throw new ArgumentNullException("commands");

            if (commands.Count == 0)
                return new Command[0];

            HashedList<Command> optimizedCommands = new HashedList<Command>();

            System.Collections.Generic.List<CompoundCreateCommand> createdCommands = new System.Collections.Generic.List<CompoundCreateCommand>();

            int j;

            for (int i = 0; i < commands.Count; i++)
            {
                Entity e = commands[i];

                string currentId = e.GetString(SyncUtils.PARENTID);
                int transaction = e.GetInt32(SyncUtils.TRANSACTION);

                switch (e.Type)
                {
                    case SyncUtils.CREATE_ENTITY:

                        string createType = e.GetString(SyncUtils.TYPE);

                        j = i + 1;

                        CompoundCreateCommand ccc = new CompoundCreateCommand(currentId, createType, new List<AttributeCommand>());

                        CompoundCreateCommand actual = createdCommands.Find(delegate(CompoundCreateCommand toFind)
                        {
                            return toFind.ClientId == ccc.ClientId &&
                                toFind.ParentId == ccc.ParentId &&
                                toFind.Type == ccc.Type;
                        });

                        if (actual == null)
                        {
                            createdCommands.Add(ccc);
                            optimizedCommands.Add(ccc);

                            while (j < commands.Count)
                            {

                                string subType = commands[j].GetString(SyncUtils.PARENTTYPE);
                                string subId = commands[j].GetString(SyncUtils.PARENTID);
                                int subTransaction = commands[j].GetInt32(SyncUtils.TRANSACTION);
                                string subCommand = commands[j].Type;

                                if (commands[j].Type == SyncUtils.CREATE_ATTRIBUTE && subId == currentId && subType == createType)
                                {
                                    if (subTransaction != transaction)
                                        break;

                                    ccc.InnerCommands.Add((AttributeCommand)engine.CreateCommand(commands[j]));
                                    commands.RemoveAt(j);
                                }
                                else
                                {
                                    j++;
                                }
                            }
                        }
                        else
                        {
                            optimizedCommands.Remove(actual);
                            optimizedCommands.Add(ccc);

                            createdCommands.Remove(actual);
                            createdCommands.Add(ccc);
                        }

                        break;

                    case SyncUtils.UPDATE_ATTRIBUTE:

                        string updateType = e.GetString(SyncUtils.PARENTTYPE);

                        j = i + 1;

                        CompoundUpdateCommand cuc = new CompoundUpdateCommand(currentId, updateType, new List<AttributeCommand>());
                        cuc.InnerCommands.Add((AttributeCommand)engine.CreateCommand(commands[i]));
                        optimizedCommands.Add(cuc);

                        while (j < commands.Count)
                        {
                            string subType = commands[j].GetString(SyncUtils.PARENTTYPE);
                            string subId = commands[j].GetString(SyncUtils.PARENTID);
                            int subTransaction = commands[j].GetInt32(SyncUtils.TRANSACTION);
                            string subCommand = commands[j].Type;

                            if (commands[j].Type == SyncUtils.UPDATE_ATTRIBUTE && subId == currentId && subType == updateType)
                            {
                                if (subTransaction != transaction)
                                    break;

                                cuc.InnerCommands.Add((AttributeCommand)engine.CreateCommand(commands[j]));
                                commands.RemoveAt(j);
                            }
                            else
                            {
                                j++;
                            }
                        }

                        break;

                    default:
                        optimizedCommands.Add(engine.CreateCommand(e));
                        break;

                }
            }

            Command[] result = new Command[optimizedCommands.Count];
            for (int i = 0; i < result.Length; i++)
                result[i] = (Command)optimizedCommands[i];

            return result;
        }
Example #6
0
 public override CompoundUpdateCommand Visit(CompoundUpdateCommand item)
 {
     Mapping.Entity entity = engine.Provider.Mapping.Entities[item.ParentEntity.Type];
     UpdateStatement update = engine.Provider.Mapping.Mapper.Update(entity);
     commands.Add(item.ParentEntity, update);
     foreach (Command command in item.InnerCommands)
         Visit(command);
     return item;
 }
Example #7
0
        /// <summary>
        /// Generated a set of commands to be processed to take into account any modification applied to an entity graph
        /// </summary>
        /// <param name="entity">The Entity to compute</param>
        /// <param name="processing">A collection of all currently processed entities</param>
        /// <param name="commands">A collection of all currently created commands</param>
        public void ComputeChanges(Entity entity, ICollection<Entity> processing, ICollection<Command> commands)
        {
            // Nothing to do if the entity is currently processed
            if (processing.Contains(entity))
                return;

            processing.Add(entity);

            // To know if we can optimize the command with a compound
            bool canCreateCompound = true;

            // Will contain the commands created for the attributes of the current entity
            List<AttributeCommand> attributeCommands = new List<AttributeCommand>(entity.Count);

            // First process all attributes not to increase the stack size because of deep hierarchies in the object graph and the recursive algorithm
            if (entity.State == State.Modified || entity.State == State.New)
                foreach (Entry e in entity)
                {
                    if (!e.IsEntity)
                    {
                        // The current entry is an Attribute
                        switch (e.State)
                        {
                            case State.Deleted:
                                attributeCommands.Add(new DeleteAttributeCommand(e));
                                break;

                            case State.Modified:
                                attributeCommands.Add(new UpdateAttributeCommand(e));
                                break;

                            case State.New:
                                attributeCommands.Add(new CreateAttributeCommand(e));
                                break;
                            default:
                                break;
                        }
                    }
                }

            // Selects the optimized command
            /// TODO: Add a property to PE so that the user could specify whether he wants all attributes to be sent with a compound command
            switch (entity.State)
            {
                case State.New:
                    if (canCreateCompound)
                        commands.Add(new CompoundCreateCommand(entity, attributeCommands));
                    else
                    {
                        commands.Add(new CreateEntityCommand(entity));
                        foreach (Command attributeCommand in attributeCommands)
                            commands.Add(attributeCommand);
                    }

                    break;

                case State.Deleted:
                    commands.Add(new DeleteEntityCommand(entity.Id, entity.Type));
                    break;

                case State.Modified:

                    if (attributeCommands.Count > 1)
                    {
                        CompoundUpdateCommand cuc = new CompoundUpdateCommand(entity, attributeCommands);
                        commands.Add(cuc);
                    }
                    else
                        foreach (Command attributeCommand in attributeCommands)
                            commands.Add(attributeCommand);
                    break;

                default:
                    foreach (Command attributeCommand in attributeCommands)
                        commands.Add(attributeCommand);
                    break;
            }

            foreach (Entry e in entity)
            {
                if (e.IsEntity)
                {
                    Model.Reference referenceModel = Model.GetReference(entity.Type, e.Name);
                    if (e.IsMultiple)
                    {
                        foreach (Entity child in ((IEnumerable<Entity>)e))
                        {
                            ComputeChanges(child, processing, commands);


                            switch (e.State)
                            {
                                case State.New:
                                    CreateReferenceCommand crc1 = new CreateReferenceCommand(referenceModel, entity, child);
                                    commands.Add(crc1);
                                    break;

                                case State.Deleted:
                                    DeleteReferenceCommand drc = new DeleteReferenceCommand(referenceModel, entity, child);
                                    commands.Add(drc);
                                    break;
                            }
                        }
                    }
                    else
                    {
                        // The current entry is an Entity
                        Entity child = (Entity)e.Value;
                        ComputeChanges(child, processing, commands);

                        switch (e.State)
                        {
                            case State.New:
                                CreateReferenceCommand crc1 = new CreateReferenceCommand(referenceModel, entity, child);
                                commands.Add(crc1);
                                break;

                            case State.Deleted:
                                DeleteReferenceCommand drc = new DeleteReferenceCommand(referenceModel, entity, child);
                                commands.Add(drc);
                                break;
                        }
                    }
                }
            }
        }