Beispiel #1
0
 internal Query(AppMetadata metadata,
                ExecutionPlanByServer executionPlanByServer,
                IEnumerable <SqlConnection> connections,
                int formatVersion)
 {
     _metadata = metadata;
     _executionPlanByServer = executionPlanByServer;
     _connections           = connections.ToImmutableHashSet();
     _dispatcher            = new QueryDispatcher();
     _dispatcher.InitProviders(metadata, connections);
     FormatVersion = formatVersion;
 }
        private static void FetchMetadata(IQueryDispatcher dispatcher, ref MetadataContainer container)
        {
            dispatcher.InitProviders(container.Metadatas, container.ConnectionStrings);

            foreach (var cs in container.ConnectionStrings)
            {
                var provider = dispatcher.GetQueryHelper(cs.Id);

                foreach (var database in provider.GetDatabasesName())
                {
                    provider.GetColumns(container.Metadatas.LoadColumns, cs.Id, database);
                    provider.GetForeignKeys(container.Metadatas.LoadForeignKeys, cs.Id, database);
                    provider.GetUniqueKeys(container.Metadatas.LoadUniqueKeys, cs.Id, database);
                }
            }
        }
        /// <summary>
        /// Verify if the last build of the container's metadata still match with the sql servers (application's connectionStrings).
        /// </summary>
        /// <param name="dispatcher">Query dispatcher</param>
        /// <param name="proj">Project config</param>
        /// <param name="container">Metadata container</param>
        public static void VerifyIntegrityOfSqlMetadata(IQueryDispatcher dispatcher, ProjectContainer proj, ref MetadataContainer container)
        {
            if (dispatcher == null)
            {
                throw new ArgumentNullException(nameof(dispatcher));
            }
            if (proj == null)
            {
                throw new ArgumentNullException(nameof(proj));
            }
            if (proj.ConnectionStrings != null && !proj.ConnectionStrings.Any())
            {
                throw new NullReferenceException("ConnectionStrings");
            }

            var containerFileName = proj.Name + ".schema";

            //Hash the connnectionStrings to see if it match the last build
            var configData = new MemoryStream();

            SerializationHelper.Serialize(configData, proj.ConnectionStrings);
            configData.Position = 0;

            //HashAlgorithm murmur = MurmurHash.Create32(managed: false);
            //var configHash = Encoding.UTF8.GetString(murmur.ComputeHash(configData));
            var configHash = container.ConfigFileHash + "random";

            //If in-memory container is good, we use it
            if (container != null && container.ConfigFileHash == configHash)
            {
                return;
            }
            //If container on disk is good, we use it
            container = TryLoadContainer(containerFileName, configHash);
            if (container != null)
            {
                dispatcher.InitProviders(container.Metadatas, container.ConnectionStrings);
            }
            //We rebuild the container
            else
            {
                container = BuildMetadata(dispatcher, containerFileName, proj.ConnectionStrings, configHash);
            }
        }
        /// <summary>
        /// Verify if the last build of the container's metadata still match with the current cloning settings.
        /// </summary>
        /// <param name="dispatcher">Query dispatcher</param>
        /// <param name="app">Application user config</param>
        /// <param name="mapId">MapId</param>
        /// <param name="behaviourId">BehaviourId</param>
        /// <param name="container">Container</param>
        public static void VerifyIntegrityWithSettings(IQueryDispatcher dispatcher, Settings settings, ref MetadataContainer container)
        {
            if (dispatcher == null)
            {
                throw new ArgumentNullException(nameof(dispatcher));
            }
            if (settings == null)
            {
                throw new ArgumentNullException(nameof(settings));
            }
            if (settings.Project == null)
            {
                throw new ArgumentNullException(nameof(settings.Project));
            }
            if (String.IsNullOrWhiteSpace(settings.Project.Name))
            {
                throw new ArgumentException(nameof(settings.Project.Name));
            }
            if (settings.Project.ConnectionStrings != null &&
                !settings.Project.ConnectionStrings.Any())
            {
                throw new NullReferenceException("settings.Project.ConnectionStrings");
            }

            var       project           = settings.Project;
            var       containerFileName = project.Name + "_";
            Map       map             = null;
            Behaviour clonerBehaviour = null;

            //Hash the selected map, connnectionStrings and the cloner
            //configuration to see if it match the lasted builded container
            var configData = new MemoryStream();

            SerializationHelper.Serialize(configData, project.ConnectionStrings);

            if (settings.MapId.HasValue)
            {
                map = settings.Project.Maps.FirstOrDefault(m => m.Id == settings.MapId);
                if (map == null)
                {
                    throw new Exception($"Map id '{settings.MapId}' not found in configuration file for application '{project.Name}'!");
                }
                containerFileName += map.From + "-" + map.To;
                SerializationHelper.Serialize(configData, map);

                if (map.UsableBehaviours != null && map.UsableBehaviours.Split(',').ToList().Contains(settings.BehaviourId.ToString()))
                {
                    clonerBehaviour = project.Behaviours.FirstOrDefault(c => c.Id == settings.BehaviourId);
                    if (clonerBehaviour == null)
                    {
                        throw new KeyNotFoundException(
                                  $"There is no behaviour '{settings.BehaviourId}' in the configuration for the appName name '{project.Name}'.");
                    }

                    SerializationHelper.Serialize(configData, clonerBehaviour);
                    SerializationHelper.Serialize(configData, project.Templates);
                }
            }
            else
            {
                containerFileName += "defaultMap";
            }

            if (settings.BehaviourId != null)
            {
                containerFileName += "_" + settings.BehaviourId;
            }
            containerFileName += ".cache";

            //Hash user config
            configData.Position = 0;
            //var murmur = MurmurHash.Create32(managed: false);
            //var configHash = Encoding.UTF8.GetString(murmur.ComputeHash(configData));
            var configHash = container.ConfigFileHash + "random";

            //If in-memory container is good, we use it
            if (container != null && container.ConfigFileHash == configHash)
            {
                return;
            }

            if (!settings.UseInMemoryCacheOnly)
            {
                //If container on disk is good, we use it
                container = TryLoadContainer(containerFileName, configHash);
                if (container != null)
                {
                    dispatcher.InitProviders(container.Metadatas, container.ConnectionStrings);
                    return;
                }
            }

            //We rebuild the container
            container = BuildMetadataWithSettings(dispatcher, containerFileName, project, clonerBehaviour, map, configHash);

            //Persist container
            if (!settings.UseInMemoryCacheOnly)
            {
                container.Save(containerFileName);
            }
        }