/// <summary>
 /// Recupera o nome do provedor associado com o queryinfo informado.
 /// </summary>
 /// <param name="queryInfo"></param>
 /// <returns></returns>
 public string GetProviderName(Colosoft.Query.QueryInfo queryInfo)
 {
     if (queryInfo.StoredProcedureName != null)
     {
         return((!string.IsNullOrEmpty(queryInfo.StoredProcedureProvider)) ? queryInfo.StoredProcedureProvider : GDA.GDASettings.DefaultProviderName);
     }
     else
     {
         var typeMetadata = _typeSchema.GetTypeMetadata(queryInfo.Entities[0].FullName);
         return(typeMetadata == null ? GDA.GDASettings.DefaultProviderName : typeMetadata.TableName.Catalog);
     }
 }
 /// <summary>
 /// Verifica se nas informações da consulta existe algum inner join.
 /// </summary>
 /// <param name="queryInfo"></param>
 /// <returns></returns>
 protected virtual bool ContainsJoin(Colosoft.Query.QueryInfo queryInfo)
 {
     if (queryInfo.Joins != null && queryInfo.Joins.Length > 0)
     {
         return(true);
     }
     if (queryInfo.NestedQueries != null)
     {
         foreach (var nestedQuery in queryInfo.NestedQueries)
         {
             if (ContainsJoin(nestedQuery))
             {
                 return(true);
             }
         }
     }
     return(false);
 }
        /// <summary>
        /// Desserializa o objeto.
        /// </summary>
        /// <param name="reader"></param>
        public void Deserialize(Serialization.IO.CompactReader reader)
        {
            ActionId       = reader.ReadInt32();
            Type           = (PersistenceActionType)reader.ReadInt32();
            EntityFullName = reader.ReadString();
            ProviderName   = reader.ReadString();
            var RowVersionString = reader.ReadString();

            if (!string.IsNullOrEmpty(RowVersionString))
            {
                RowVersion = long.Parse(RowVersionString);
            }
            else
            {
                RowVersion = null;
            }
            var parameters = new List <PersistenceParameter>();
            var count      = reader.ReadInt32();

            for (var i = 0; i < count; i++)
            {
                var parameter = new PersistenceParameter();
                ((ICompactSerializable)parameter).Deserialize(reader);
                parameters.Add(parameter);
            }
            Parameters = new PersistenceParameterCollection(parameters);
            if (reader.ReadBoolean())
            {
                var conditional = new Colosoft.Query.ConditionalContainer();
                ((ICompactSerializable)conditional).Deserialize(reader);
                this.Conditional = conditional;
            }
            var actions = new List <PersistenceAction>();

            count = reader.ReadInt32();
            for (var i = 0; i < count; i++)
            {
                var persistenceAction = new PersistenceAction();
                ((ICompactSerializable)persistenceAction).Deserialize(reader);
                actions.Add(persistenceAction);
            }
            AlternativeActions.AddRange(actions);
            var beforeActions = new List <PersistenceAction>();

            count = reader.ReadInt32();
            for (var i = 0; i < count; i++)
            {
                var persistenceAction = new PersistenceAction();
                ((ICompactSerializable)persistenceAction).Deserialize(reader);
                beforeActions.Add(persistenceAction);
            }
            BeforeActions.AddRange(beforeActions);
            var afterActions = new List <PersistenceAction>();

            count = reader.ReadInt32();
            for (var i = 0; i < count; i++)
            {
                var persistenceAction = new PersistenceAction();
                ((ICompactSerializable)persistenceAction).Deserialize(reader);
                afterActions.Add(persistenceAction);
            }
            AfterActions.AddRange(afterActions);
            if (reader.ReadBoolean())
            {
                _storedProcedureName = new Colosoft.Query.StoredProcedureName();
                ((ICompactSerializable)_storedProcedureName).Deserialize(reader);
            }
            if (reader.ReadBoolean())
            {
                var query = new Colosoft.Query.QueryInfo();
                ((ICompactSerializable)query).Deserialize(reader);
                this.Query = query;
            }
        }
        /// <summary>
        /// Lê os dados do XML.
        /// </summary>
        /// <param name="reader"></param>
        void System.Xml.Serialization.IXmlSerializable.ReadXml(System.Xml.XmlReader reader)
        {
            reader.MoveToAttribute("ActionId");
            ActionId = reader.ReadContentAsInt();
            reader.MoveToAttribute("Type");
            var typeString = reader.ReadContentAsString();

            Type = (PersistenceActionType)Enum.Parse(typeof(PersistenceActionType), typeString);
            reader.MoveToAttribute("EntityFullName");
            EntityFullName = reader.ReadContentAsString();
            reader.MoveToAttribute("ProviderName");
            ProviderName = reader.ReadContentAsString();
            reader.MoveToAttribute("RowVersion");
            var RowVersionString = reader.ReadContentAsString();

            if (!string.IsNullOrEmpty(RowVersionString))
            {
                RowVersion = long.Parse(RowVersionString);
            }
            else
            {
                RowVersion = null;
            }
            if (reader.MoveToAttribute("CommandTimeout"))
            {
                var timeout = 0;
                if (int.TryParse(reader.ReadContentAsString(), out timeout))
                {
                    CommandTimeout = timeout;
                }
            }
            reader.MoveToElement();
            reader.ReadStartElement();
            if (!reader.IsEmptyElement)
            {
                reader.ReadStartElement("Parameters", Namespaces.Data);
                var parameters = new List <PersistenceParameter>();
                while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
                {
                    if (reader.LocalName == "Parameter")
                    {
                        var parameter = new PersistenceParameter();
                        ((System.Xml.Serialization.IXmlSerializable)parameter).ReadXml(reader);
                        parameters.Add(parameter);
                    }
                    else
                    {
                        reader.Skip();
                    }
                }
                Parameters = new PersistenceParameterCollection(parameters);
                reader.ReadEndElement();
            }
            else
            {
                reader.Skip();
            }
            if (!reader.IsEmptyElement)
            {
                var conditional = new Colosoft.Query.ConditionalContainer();
                ((System.Xml.Serialization.IXmlSerializable)conditional).ReadXml(reader);
                this.Conditional = conditional;
            }
            else
            {
                reader.Skip();
            }
            if (!reader.IsEmptyElement)
            {
                reader.ReadStartElement("AlternativeActions");
                var actions = new List <PersistenceAction>();
                while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
                {
                    if (reader.LocalName == "PersistenceAction")
                    {
                        var persistenceAction = new PersistenceAction();
                        ((System.Xml.Serialization.IXmlSerializable)persistenceAction).ReadXml(reader);
                        actions.Add(persistenceAction);
                    }
                    else
                    {
                        reader.Skip();
                    }
                }
                AlternativeActions.AddRange(actions);
                reader.ReadEndElement();
            }
            else
            {
                reader.Skip();
            }
            if (!reader.IsEmptyElement)
            {
                reader.ReadStartElement("BeforeActions");
                var actions = new List <PersistenceAction>();
                while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
                {
                    if (reader.LocalName == "PersistenceAction")
                    {
                        var persistenceAction = new PersistenceAction();
                        ((System.Xml.Serialization.IXmlSerializable)persistenceAction).ReadXml(reader);
                        actions.Add(persistenceAction);
                    }
                    else
                    {
                        reader.Skip();
                    }
                }
                BeforeActions.AddRange(actions);
                reader.ReadEndElement();
            }
            else
            {
                reader.Skip();
            }
            if (!reader.IsEmptyElement)
            {
                reader.ReadStartElement("AfterActions");
                var actions = new List <PersistenceAction>();
                while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
                {
                    if (reader.LocalName == "PersistenceAction")
                    {
                        var persistenceAction = new PersistenceAction();
                        ((System.Xml.Serialization.IXmlSerializable)persistenceAction).ReadXml(reader);
                        actions.Add(persistenceAction);
                    }
                    else
                    {
                        reader.Skip();
                    }
                }
                AfterActions.AddRange(actions);
                reader.ReadEndElement();
            }
            else
            {
                reader.Skip();
            }
            _storedProcedureName = ReadItem <Colosoft.Query.StoredProcedureName>(reader, "StoredProcedureName");
            if (!reader.IsEmptyElement)
            {
                var query = new Colosoft.Query.QueryInfo();
                ((System.Xml.Serialization.IXmlSerializable)query).ReadXml(reader);
                this.Query = query;
            }
            else
            {
                reader.Skip();
            }
            reader.ReadEndElement();
        }
        /// <summary>
        /// Recarrega os dados dos tipos informados para o cache.
        /// </summary>
        /// <param name="typeNames"></param>
        /// <returns></returns>
        public RealoadDataCacheResult Reload(Colosoft.Reflection.TypeName[] typeNames)
        {
            if (CacheLoaderConfiguration == null)
            {
                throw new InvalidOperationException("CacheLoaderConfiguration undefined.");
            }
            var loaderProvider = CacheLoaderConfiguration.Provider;

            Colosoft.Caching.ICacheLoader cacheLoader;
            try
            {
                var cacheLoaderType = Type.GetType(string.Format("{0}, {1}", loaderProvider.ClassName, loaderProvider.AssemblyName));
                cacheLoader = (Colosoft.Caching.ICacheLoader)Activator.CreateInstance(cacheLoaderType);
            }
            catch (InvalidCastException ex)
            {
                throw new Colosoft.Caching.Exceptions.ConfigurationException(ResourceMessageFormatter.Create(() => Properties.Resources.ConfigurationException_ICacheLoaderNotImplemented).Format(), ex);
            }
            catch (Exception ex)
            {
                throw new Colosoft.Caching.Exceptions.ConfigurationException(ex.Message, ex);
            }
            var resultErrors  = new List <RealoadDataCacheResult.Error>();
            var typesMetadata = new List <ITypeMetadata>();

            foreach (var i in typeNames)
            {
                var metadata = _typeSchema.GetTypeMetadata(i.FullName);
                if (metadata == null)
                {
                    resultErrors.Add(new RealoadDataCacheResult.Error {
                        Type      = i,
                        Exception = new DetailsException(ResourceMessageFormatter.Create(() => Properties.Resources.DataCacheManager_Reload_TypeNotFound, i.FullName))
                    });
                }
                else
                {
                    typesMetadata.Add(metadata);
                }
            }
            var observerManager = Colosoft.Query.RecordObserverManager.Instance;

            for (var i = 0; i < typesMetadata.Count; i++)
            {
                var metadata = typesMetadata[i];
                var typeName = metadata.GetTypeName();
                Colosoft.Caching.Queries.QueryResultSet queryResult = null;
                var queryInfo = new Colosoft.Query.QueryInfo()
                {
                    Entities = new Query.EntityInfo[] {
                        new Query.EntityInfo(typeName.FullName)
                    }
                };
                try
                {
                    queryResult = _cache.Search(string.Format("select {0}.{1}", metadata.Namespace, metadata.Name), null);
                }
                catch (Exception ex)
                {
                    resultErrors.Add(new RealoadDataCacheResult.Error {
                        Type      = Colosoft.Data.Schema.TypeSchemaExtensions.GetTypeName(metadata),
                        Exception = new DetailsException(ResourceMessageFormatter.Create(() => Properties.Resources.DataCacheManager_Reload_QueryItemsToDelete, metadata.FullName), ex)
                    });
                    typesMetadata.RemoveAt(i--);
                    continue;
                }
                var recordKeys = new Dictionary <string, Colosoft.Query.RecordKey>();
                using (var recordEnumerator = new Colosoft.Caching.Queries.QueryResultSetRecordEnumerator(_typeSchema, Cache, queryResult, queryInfo))
                {
                    while (recordEnumerator.MoveNext())
                    {
                        recordKeys.Add(recordEnumerator.CurrentKey is string?(string)recordEnumerator.CurrentKey: (recordEnumerator.CurrentKey ?? "").ToString(), Colosoft.Query.RecordKeyFactory.Instance.Create(typeName, recordEnumerator.Current));
                    }
                }
                var cacheLoaderParameters = new System.Collections.Hashtable();
                cacheLoaderParameters.Add("sourceContext", _sourceContext);
                cacheLoaderParameters.Add("manager", this);
                cacheLoaderParameters.Add("logger", _logger);
                cacheLoaderParameters.Add("typeMetadata", null);
                cacheLoaderParameters.Add("cacheLoaderObserver", _cacheLoaderObserver);
                cacheLoaderParameters.Add("typesMetadata", new List <ITypeMetadata> {
                    metadata
                });
                if (cacheLoader is DataCacheLoader)
                {
                    ((DataCacheLoader)cacheLoader).Observer.OnTotalProgressChanged(new System.ComponentModel.ProgressChangedEventArgs(i * 100 / typesMetadata.Count, null));
                }
                cacheLoader.Init(cacheLoaderParameters);
                using (var startupLoader = new Colosoft.Caching.Loaders.CacheStartupLoader(new System.Collections.Hashtable(), Cache, _logger))
                {
                    var isNewEntry = false;
                    startupLoader.Initialize(cacheLoader);
                    startupLoader.InsertingEntry += (sender, e) => {
                        var key = e.Key is string?(string)e.Key : (e.Key ?? "").ToString();
                        if (recordKeys.Remove(key))
                        {
                            isNewEntry = false;
                            Cache.Remove(key, new Colosoft.Caching.OperationContext(Colosoft.Caching.OperationContextFieldName.OperationType, Colosoft.Caching.OperationContextOperationType.CacheOperation));
                        }
                        else
                        {
                            isNewEntry = true;
                        }
                    };
                    startupLoader.InsertedEntry += (sender, e) => {
                        if (e.Value is Colosoft.Query.IRecord)
                        {
                            var record    = e.Value as Colosoft.Query.IRecord;
                            var recordKey = Colosoft.Query.RecordKeyFactory.Instance.Create(typeName, record);
                            if (!isNewEntry)
                            {
                                var notifier = observerManager.GetRecordChangedNotifier(typeName, recordKey);
                                if (notifier.IsValid)
                                {
                                    notifier.Notify(record);
                                }
                            }
                            else
                            {
                                observerManager.NotifyRecordsInserted(typeName, new Query.IRecord[] {
                                    record
                                });
                            }
                        }
                    };
                    startupLoader.LoadCache();
                }
                foreach (var key in recordKeys)
                {
                    try
                    {
                        Cache.Remove(key.Key, new Colosoft.Caching.OperationContext(Colosoft.Caching.OperationContextFieldName.OperationType, Colosoft.Caching.OperationContextOperationType.CacheOperation));
                    }
                    catch (Exception ex)
                    {
                        resultErrors.Add(new RealoadDataCacheResult.Error {
                            Type      = Colosoft.Data.Schema.TypeSchemaExtensions.GetTypeName(metadata),
                            Exception = new DetailsException(ResourceMessageFormatter.Create(() => Properties.Resources.DataCacheManager_Reload_ClearItems, metadata.FullName), ex)
                        });
                        typesMetadata.RemoveAt(i--);
                        break;
                    }
                    observerManager.NotifyRecordDeleted(typeName, new Colosoft.Query.RecordKey[] {
                        key.Value
                    });
                }
            }
            return(new RealoadDataCacheResult {
                Success = resultErrors.Count == 0,
                Errors = resultErrors.ToArray()
            });
        }