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); } }