/// <summary> /// Generates the insert query declarations. /// </summary> /// <returns>The resulting query</returns> private string[] GenerateInsertQueryDeclarations() { var Builder = new List <string>(); var ParentMappings = new List <IMapping>(); foreach (var ChildMapping in MappingInformation.GetChildMappings(typeof(TMappedClass))) { var TempParentMappings = MappingInformation.GetParentMapping(ChildMapping.ObjectType); ParentMappings.AddIfUnique(TempParentMappings); } for (int x = 0, ParentMappingsCount = ParentMappings.Count; x < ParentMappingsCount; x++) { var ParentMapping = ParentMappings[x]; //ID Properties to pass to the next set of queries foreach (var IDProperty in ParentMapping.IDProperties) { Builder.Add("DECLARE " + GetParentParameterName(IDProperty) + " AS " + GetParameterType(IDProperty) + ";"); } //Auto ID properties to pass to the next set of queries foreach (var AutoIDProperty in ParentMapping.AutoIDProperties) { Builder.Add("DECLARE " + GetParentParameterName(AutoIDProperty) + " AS " + GetParameterType(AutoIDProperty) + ";"); } } return(Builder.ToArray()); }
/// <summary> /// Generates the parameters. /// </summary> /// <param name="queryObject">The query object.</param> /// <param name="property">The property.</param> /// <param name="propertyItem">The property item.</param> /// <returns>The parameters</returns> private IParameter[] GenerateParameters(TMappedClass queryObject, IManyToManyProperty property, object propertyItem) { var ItemList = propertyItem as IEnumerable; var ReturnValues = new List <IParameter>(); var ParentMappings = MappingInformation.GetChildMappings(property.ParentMapping.ObjectType).SelectMany(x => MappingInformation.GetParentMapping(x.ObjectType)).Distinct(); var ParentWithID = ParentMappings.FirstOrDefault(x => x.IDProperties.Count > 0); var Prefix = string.Empty; if (property.ForeignMapping.Any(TempMapping => ParentWithID == TempMapping)) { Prefix = "Parent_"; } var ParentIDs = ParentMappings.SelectMany(x => x.IDProperties); var ForeignIDs = MappingInformation.GetParentMapping(property.PropertyType).SelectMany(x => x.IDProperties); ReturnValues.AddRange(ParentIDs.ForEach <IIDProperty, IParameter>(x => { var Value = x.GetColumnInfo()[0].GetValue(queryObject); if (x.PropertyType == typeof(string)) { var TempParameter = Value as string; return(new StringParameter(Prefix + x.ParentMapping.TableName + x.ColumnName, TempParameter !)); } return(new Parameter <object>(Prefix + x.ParentMapping.TableName + x.ColumnName, x.PropertyType.To <Type, SqlDbType>(), Value)); })); return(ReturnValues.ToArray()); }
/// <summary> /// Initializes a new instance of the <see cref="SavePropertiesQuery{TMappedClass}"/> class. /// </summary> /// <param name="mappingInformation">Mapping information</param> /// <param name="objectPool">The object pool.</param> public DeletePropertiesQuery(IMappingSource mappingInformation, ObjectPool <StringBuilder> objectPool) : base(mappingInformation, objectPool) { IDProperties = MappingInformation.GetChildMappings(typeof(TMappedClass)) .SelectMany(x => MappingInformation.GetParentMapping(x.ObjectType)) .Distinct() .SelectMany(x => x.IDProperties); }
/// <summary> /// Initializes a new instance of the <see cref="DeleteQuery{TMappedClass}"/> class. /// </summary> /// <param name="mappingInformation">The mapping information.</param> /// <param name="objectPool">The object pool.</param> public DeleteQuery(IMappingSource mappingInformation, ObjectPool <StringBuilder> objectPool) : base(mappingInformation, objectPool) { ParentMappings = MappingInformation.GetChildMappings <TMappedClass>() .SelectMany(x => MappingInformation.GetParentMapping(x.ObjectType)) .Distinct(); IDProperties = ParentMappings.SelectMany(x => x.IDProperties); GenerateQuery(); }
/// <summary> /// Initializes a new instance of the <see cref="DataLoadQuery{TMappedClass}"/> class. /// </summary> /// <param name="mappingInformation">Mapping information</param> /// <param name="objectPool">The object pool.</param> public DataLoadQuery(IMappingSource mappingInformation, ObjectPool <StringBuilder> objectPool) : base(mappingInformation, objectPool) { IDProperties = MappingInformation.GetChildMappings(MappedClassType) .SelectMany(x => MappingInformation.GetParentMapping(x.ObjectType)) .Distinct() .SelectMany(x => x.IDProperties) .ToArray(); IDColumnInfo = IDProperties.Select(x => x.GetColumnInfo()[0]).ToArray(); }
/// <summary> /// Initializes a new instance of the <see cref="UpdateQuery{TMappedClass}"/> class. /// </summary> /// <param name="mappingInformation">The mapping information.</param> /// <param name="objectPool">The object pool.</param> public UpdateQuery(IMappingSource mappingInformation, ObjectPool <StringBuilder> objectPool) : base(mappingInformation, objectPool) { var ParentMappings = MappingInformation.GetChildMappings(typeof(TMappedClass)) .SelectMany(x => mappingInformation.GetParentMapping(x.ObjectType)) .Distinct(); IDProperties = ParentMappings.SelectMany(x => x.IDProperties); ReferenceProperties = ParentMappings.SelectMany(x => x.ReferenceProperties); }
/// <summary> /// Initializes a new instance of the <see cref="SavePropertiesQuery{TMappedClass}"/> class. /// </summary> /// <param name="mappingInformation">Mapping information</param> /// <param name="objectPool">The object pool.</param> public SavePropertiesQuery(IMappingSource mappingInformation, ObjectPool <StringBuilder> objectPool) : base(mappingInformation, objectPool) { IDProperties = MappingInformation.GetChildMappings(typeof(TMappedClass)) .SelectMany(x => MappingInformation.GetParentMapping(x.ObjectType)) .Distinct() .SelectMany(x => x.IDProperties); Queries = new ListMapping <string, QueryGeneratorData>(); SetupQueries(); }
/// <summary> /// Collects all unit seat mappings from a cache file and adds them to a context collection. /// </summary> /// <param name="reader">The stream to read from.</param> /// <param name="cache">The cache file.</param> /// <param name="buildInfo">The build information for this cache file.</param> /// <param name="block">The cache file's unit seat mappings block.</param> /// <param name="collection">The context collection.</param> private static void HandleUnitSeatMappings(IReader reader, ICacheFile cache, EngineDescription buildInfo, KeyValuePair <string, StructureValueCollection[]> block, ScriptingContextCollection collection) { MappingInformation[] information = new MappingInformation[block.Value.Length]; // Collect information for all unti seat mappings in scnr. for (short mappingIndex = 0; mappingIndex < block.Value.Length; mappingIndex++) { var values = block.Value[mappingIndex]; ITag unit = values.GetTagReference("Unit"); int seatIndeces1 = (int)values.GetInteger("Seats 1"); int seatIndeces2 = (int)values.GetInteger("Seats 2"); List <int> seatIndices = GetSeatIndices(seatIndeces1, seatIndeces2); var vehiLayout = buildInfo.Layouts.GetLayout("vehi_seats"); // Read the vehicle meta data from the cache file. reader.SeekTo(unit.MetaLocation.AsOffset()); var vehiValues = CacheStructureReader.ReadStructure(reader, cache, buildInfo, vehiLayout); var seatsBlock = vehiValues.GetTagBlock("seats"); // Guess the name of each mapping entry in scnr. string name = GetVehicleMappingName(seatsBlock, seatIndices); // Add the information to the array. information[mappingIndex] = new MappingInformation { Index = mappingIndex, Name = name, SplitName = name.Split('_'), TagName = cache.FileNames.GetTagName(unit), SeatIndices = seatIndices }; } // Identify and create seat mappings. Mappings will be grouped in this step. IEnumerable <UnitSeatMapping> mappings; if (buildInfo.Name.Contains("Halo 3")) { mappings = CreateUnitSeatMappings(information, PostProcessing.Halo3); } else { mappings = CreateUnitSeatMappings(information, PostProcessing.HaloReach); } // Add the final unit seat mapping objects to the result. foreach (var mapping in mappings) { collection.AddUnitSeatMapping(mapping); } }
/// <summary> /// Initializes a new instance of the <see cref="GeneratorBaseClass{TMappedClass}"/> class. /// </summary> /// <param name="mappingInformation">The mapping information.</param> /// <param name="queryGenerators">The query generators.</param> /// <exception cref="ArgumentNullException"> /// linqQueryGenerator or mappingInformation or queryGenerators /// </exception> /// <exception cref="ArgumentException">Mapping not found for type: AssociatedType</exception> protected GeneratorBaseClass(IMappingSource mappingInformation, IEnumerable <IQueryGenerator <TMappedClass> > queryGenerators) { MappingInformation = mappingInformation ?? throw new ArgumentNullException(nameof(mappingInformation)); if (!MappingInformation.GetChildMappings(AssociatedType).Any()) { throw new ArgumentException("Mapping not found for type: " + AssociatedType); } QueryGenerators = queryGenerators?.ToDictionary(x => x.QueryType) ?? throw new ArgumentNullException(nameof(queryGenerators)); LinqQueryGenerator = (ILinqQueryGenerator <TMappedClass>)queryGenerators.FirstOrDefault(x => x.QueryType == QueryType.LinqQuery); DataQueryGenerator = (IDataQueryGenerator <TMappedClass>)queryGenerators.FirstOrDefault(x => x.QueryType == QueryType.LoadData); }
/// <summary> /// Generates the query. /// </summary> /// <param name="data">The data.</param> /// <returns>The resulting query</returns> public override IQuery[] GenerateQueries(QueryData <TMappedClass> data) { if (data is null) { return(Array.Empty <IQuery>()); } var ReturnValue = new List <IQuery>(); foreach (var ChildMapping in MappingInformation.GetChildMappings(typeof(TMappedClass))) { var TypeGraph = MappingInformation.TypeGraphs[ChildMapping.ObjectType]; ReturnValue.Add(new Query(ChildMapping.ObjectType, CommandType.Text, GenerateSelectQuery(TypeGraph?.Root, data), QueryType, data.Parameters.ToArray())); } return(ReturnValue.ToArray()); }
/// <summary> /// Initializes a new instance of the <see cref="InsertQuery{TMappedClass}"/> class. /// </summary> /// <param name="mappingInformation">The mapping information.</param> /// <param name="objectPool">The object pool.</param> public InsertQuery(IMappingSource mappingInformation, ObjectPool <StringBuilder> objectPool) : base(mappingInformation, objectPool) { if (!MappingInformation.TypeGraphs.ContainsKey(AssociatedType)) { return; } var TypeGraph = MappingInformation.TypeGraphs[AssociatedType]; QueryDeclarationText = GenerateInsertQueryDeclarations(); QueryText = GenerateInsertQuery(TypeGraph?.Root); var ParentMappings = MappingInformation.GetParentMapping(typeof(TMappedClass)); IDProperties = ParentMappings.SelectMany(x => x.IDProperties); ReferenceProperties = ParentMappings.SelectMany(x => x.ReferenceProperties); }
/// <summary> /// Manies to many property. /// </summary> /// <param name="property">The property.</param> /// <param name="queryObject">The query object.</param> /// <returns>The queries</returns> private IQuery[] ManyToManyProperty(IManyToManyProperty property, TMappedClass queryObject) { var ItemList = property.GetValue(queryObject) as IEnumerable; var ForeignIDProperties = MappingInformation.GetChildMappings(property.PropertyType) .SelectMany(x => MappingInformation.GetParentMapping(x.ObjectType)) .Distinct() .SelectMany(x => x.IDProperties); return(new IQuery[] { new Query(property.PropertyType, CommandType.Text, GenerateJoinDeleteQuery(property), QueryType, GenerateParameters(queryObject, property, ItemList !)) });
/// <summary> /// Generates the query. /// </summary> /// <param name="ids"></param> /// <returns>The resulting query</returns> public IQuery[] GenerateQueries(Dynamo[] ids) { if (ids is null || ids.Length == 0) { return(Array.Empty <IQuery>()); } var ReturnValue = new List <IQuery>(); var ItemSize = ids.FirstOrDefault()?.Count ?? 1; foreach (var ChildMapping in MappingInformation.GetChildMappings(MappedClassType)) { var TypeGraph = MappingInformation.TypeGraphs[ChildMapping.ObjectType]; foreach (var Split in SplitList(ids, 1000 / ItemSize)) { ReturnValue.Add(new Query(ChildMapping.ObjectType, CommandType.Text, GenerateSelectQuery(TypeGraph?.Root, Split), QueryType, GetParameters(Split, IDColumnInfo))); } } return(ReturnValue.ToArray()); }
/// <summary> /// Generates the join delete query. /// </summary> /// <param name="property">The property.</param> /// <returns>The join delete query</returns> private string GenerateJoinDeleteQuery(IManyToManyProperty property) { var Builder = ObjectPool.Get(); var PropertyNames = ObjectPool.Get(); var PropertyValues = ObjectPool.Get(); var ParametersList = ObjectPool.Get(); var ParentMappings = MappingInformation.GetChildMappings(property.ParentMapping.ObjectType).SelectMany(x => MappingInformation.GetParentMapping(x.ObjectType)).Distinct(); var ParentWithID = ParentMappings.FirstOrDefault(x => x.IDProperties.Count > 0); var Prefix = string.Empty; if (property.ForeignMapping.Any(TempMapping => ParentWithID == TempMapping)) { Prefix = "Parent_"; } var Splitter2 = string.Empty; foreach (var IDProperty in IDProperties) { ParametersList.Append(Splitter2).Append("([").Append(property.ParentMapping.SchemaName).Append("].[").Append(property.TableName).Append("].[").Append(Prefix).Append(IDProperty.ParentMapping.TableName).Append(IDProperty.ColumnName).Append("] = @").Append(Prefix).Append(IDProperty.ParentMapping.TableName).Append(IDProperty.ColumnName); if (!string.IsNullOrEmpty(Prefix)) { ParametersList.Append(Splitter2).Append(" OR [").Append(property.ParentMapping.SchemaName).Append("].[").Append(property.TableName).Append("].[").Append(IDProperty.ParentMapping.TableName).Append(IDProperty.ColumnName).Append("] = @").Append(Prefix).Append(IDProperty.ParentMapping.TableName).Append(IDProperty.ColumnName); } ParametersList.Append(")"); Splitter2 = " AND "; } Builder.Append("DELETE FROM ").Append(GetTableName(property)).Append(" WHERE ").Append(ParametersList).Append(";"); var Result = Builder.ToString(); ObjectPool.Return(Builder); ObjectPool.Return(PropertyNames); ObjectPool.Return(PropertyValues); ObjectPool.Return(ParametersList); return(Result); }
/// <summary> /// Creates unit seat mappings from mapping information. Also identifies and handles mapping groups. /// </summary> /// <param name="information">The information</param> /// <returns>A <see cref="IEnumerable"/> containing the finalized seat mappings.</returns> private static IEnumerable <UnitSeatMapping> CreateUnitSeatMappings(MappingInformation[] information, PostProcessing postProcessing) { var queue = new Queue <MappingInformation>(information); var result = new List <UnitSeatMapping>(); while (queue.Count > 0) { MappingInformation info = queue.Dequeue(); var members = new List <MappingInformation>(); var processedTags = new List <string>(); members.Add(info); processedTags.Add(info.TagName); // Retrieve other group members. while (queue.Count > 0) { MappingInformation next = queue.Peek(); // The border of a group is reached, when any of these conditions is true. if (next.TagName == info.TagName || next.SplitName[0] != info.SplitName[0] || next.SplitName[1] != info.SplitName[1] || members.Contains(next) || processedTags.Contains(next.TagName)) { break; } else { processedTags.Add(next.TagName); members.Add(queue.Dequeue()); } } // Handle mapping groups. if (members.Count > 1) { if (postProcessing == PostProcessing.HaloReach) { // Some groups are not being detected correctly and need to be postprocessed. // If subsequent group member share the same name, they belong to a separate group. In this case the original group needs to be split. List <MappingInformation> currentGroup = new List <MappingInformation> { members.First() }; foreach (var i in members.Skip(1)) { if (currentGroup.Count > 1 && currentGroup.Last().Name != i.Name && currentGroup.All(i => i.Name == currentGroup[0].Name)) { var group = new UnitSeatMapping(currentGroup.First().Index, (short)currentGroup.Count, currentGroup.First().Name); result.Add(group); currentGroup.Clear(); } currentGroup.Add(i); } // Add the last group. var mapping = new UnitSeatMapping(currentGroup.First().Index, (short)currentGroup.Count, GetMappingGroupName(currentGroup)); result.Add(mapping); currentGroup.Clear(); } else if (postProcessing == PostProcessing.Halo3) { // Halo 3 doesn't require any postprocessing. result.Add(new UnitSeatMapping(members[0].Index, (short)members.Count, GetMappingGroupName(members))); } } // Handle single mappings. else { result.Add(new UnitSeatMapping(members[0].Index, 1, members[0].Name)); } } return(result); }