/// <summary> /// Create query restrictions used to retrieve actual data and deletions that took place at exactly given revision. /// </summary> private void createValidAndRemovedDataRestrictions(IAuditStrategy auditStrategy, MiddleIdData referencedIdData, string versionsMiddleEntityName, QueryBuilder remQb, IEnumerable <MiddleComponentData> componentData) { var disjoint = remQb.RootParameters.AddSubParameters("or"); var valid = disjoint.AddSubParameters("and"); // Restrictions to match all valid rows. var removed = disjoint.AddSubParameters("and"); // Restrictions to match all rows deleted at exactly given revision. var revisionPropertyPath = VerEntCfg.RevisionNumberPath; var revisionTypePropName = RevisionTypePath(); // Excluding current revision, because we need to match data valid at the previous one. createValidDataRestrictions(auditStrategy, referencedIdData, versionsMiddleEntityName, remQb, valid, false, componentData); // ee.revision = :revision removed.AddWhereWithNamedParam(revisionPropertyPath, "=", QueryConstants.RevisionParameter); // e.revision = :revision removed.AddWhereWithNamedParam(QueryConstants.ReferencedEntityAlias + "." + revisionPropertyPath, false, "=", QueryConstants.RevisionParameter); // f.revision = :revision removed.AddWhereWithNamedParam(QueryConstants.IndexEntityAlias + "." + revisionPropertyPath, false, "=", QueryConstants.RevisionParameter); // ee.revision_type = DEL removed.AddWhereWithNamedParam(revisionTypePropName, "=", QueryConstants.DelRevisionTypeParameter); // e.revision_type = DEL removed.AddWhereWithNamedParam(QueryConstants.ReferencedEntityAlias + "." + revisionTypePropName, false, "=", QueryConstants.DelRevisionTypeParameter); // f.revision_type = DEL removed.AddWhereWithNamedParam(QueryConstants.IndexEntityAlias + "." + revisionTypePropName, false, "=", QueryConstants.DelRevisionTypeParameter); }
public OneEntityQueryGenerator(AuditEntitiesConfiguration verEntCfg, IAuditStrategy auditStrategy, string versionsMiddleEntityName, MiddleIdData referencingIdData, bool revisionTypeInId, IEnumerable <MiddleComponentData> componentDatas) : base(verEntCfg, referencingIdData, revisionTypeInId) { /* * The query that we need to create: * SELECT new list(ee) FROM middleEntity ee WHERE * (only entities referenced by the association; id_ref_ing = id of the referencing entity) * ee.originalId.id_ref_ing = :id_ref_ing AND * (the association at revision :revision) * --> for DefaultAuditStrategy: * ee.revision = (SELECT max(ee2.revision) FROM middleEntity ee2 * WHERE ee2.revision <= :revision AND ee2.originalId.* = ee.originalId.*) * --> for ValidityAuditStrategy * ee.revision <= :revision and (ee.endRevision > :revision or ee.endRevision is null) * AND * (only non-deleted entities and associations) * ee.revision_type != DEL */ var commonPart = commonQueryPart(versionsMiddleEntityName); var validQuery = (QueryBuilder)commonPart.Clone(); var removedQuery = (QueryBuilder)commonPart.Clone(); createValidDataRestrictions(auditStrategy, versionsMiddleEntityName, validQuery, validQuery.RootParameters, true, componentDatas); createValidAndRemovedDataRestrictions(auditStrategy, versionsMiddleEntityName, removedQuery, componentDatas); _queryString = QueryToString(validQuery); _queryRemovedString = QueryToString(removedQuery); }
public TwoEntityOneAuditedQueryGenerator(AuditEntitiesConfiguration verEntCfg, IAuditStrategy auditStrategy, string versionsMiddleEntityName, MiddleIdData referencingIdData, MiddleIdData referencedIdData, IEnumerable<MiddleComponentData> componentDatas) { this.referencingIdData = referencingIdData; /* * The query that we need to create: * SELECT new list(ee, e) FROM referencedEntity e, middleEntity ee * WHERE * (entities referenced by the middle table; id_ref_ed = id of the referenced entity) * ee.id_ref_ed = e.id_ref_ed AND * (only entities referenced by the association; id_ref_ing = id of the referencing entity) * ee.id_ref_ing = :id_ref_ing AND * * (the association at revision :revision) * --> For DefaultAuditStrategy: * ee.revision = (SELECT max(ee2.revision) FROM middleEntity ee2 * WHERE ee2.revision <= :revision AND ee2.originalId.* = ee.originalId.*) * --> for ValidityAuditStrategy: * ee.revision <= :revision and (ee.endRevision > :revision or ee.endRevision is null) * * AND * * (only non-deleted entities and associations) * ee.revision_type != DEL */ var revisionPropertyPath = verEntCfg.RevisionNumberPath; var originalIdPropertyName = verEntCfg.OriginalIdPropName; var eeOriginalIdPropertyPath = "ee." + originalIdPropertyName; // SELECT new list(ee) FROM middleEntity ee var qb = new QueryBuilder(versionsMiddleEntityName, "ee"); qb.AddFrom(referencedIdData.EntityName, "e"); qb.AddProjection("new list", "ee, e", false, false); // WHERE var rootParameters = qb.RootParameters; // ee.id_ref_ed = e.id_ref_ed referencedIdData.PrefixedMapper.AddIdsEqualToQuery(rootParameters, eeOriginalIdPropertyPath, referencedIdData.OriginalMapper, "e"); // ee.originalId.id_ref_ing = :id_ref_ing referencingIdData.PrefixedMapper.AddNamedIdEqualsToQuery(rootParameters, originalIdPropertyName, true); // (with ee association at revision :revision) // --> based on auditStrategy (see above) auditStrategy.AddAssociationAtRevisionRestriction(qb, revisionPropertyPath, verEntCfg.RevisionEndFieldName, true, referencingIdData, versionsMiddleEntityName, eeOriginalIdPropertyPath, revisionPropertyPath, originalIdPropertyName, componentDatas.ToArray()); // ee.revision_type != DEL rootParameters.AddWhereWithNamedParam(verEntCfg.RevisionTypePropName, "!=", "delrevisiontype"); var sb = new StringBuilder(); qb.Build(sb, null); queryString = sb.ToString(); }
public OneAuditEntityQueryGenerator(AuditEntitiesConfiguration verEntCfg, IAuditStrategy auditStrategy, MiddleIdData referencingIdData, string referencedEntityName, MiddleIdData referencedIdData, bool revisionTypeInId) : base(verEntCfg, referencingIdData, revisionTypeInId) { /* * The valid query that we need to create: * SELECT new list(e) FROM versionsReferencedEntity e * WHERE * (only entities referenced by the association; id_ref_ing = id of the referencing entity) * e.id_ref_ing = :id_ref_ing AND * (selecting e entities at revision :revision) * --> for DefaultAuditStrategy: * e.revision = (SELECT max(e2.revision) FROM versionsReferencedEntity e2 * WHERE e2.revision <= :revision AND e2.id = e.id) * --> for ValidityAuditStrategy * e.revision <= :revision and (e.endRevision > :revision or e.endRevision is null) * AND * (only non-deleted entities) * e.revision_type != DEL */ var commonPart = commonQueryPart(verEntCfg.GetAuditEntityName(referencedEntityName)); var validQuery = (QueryBuilder)commonPart.Clone(); var removedQuery = (QueryBuilder)commonPart.Clone(); createValidDataRestrictions(auditStrategy, referencedIdData, validQuery, validQuery.RootParameters); createValidAndRemovedDataRestrictions(auditStrategy, referencedIdData, removedQuery); _queryString = QueryToString(validQuery); _queryRemovedString = QueryToString(removedQuery); }
private void createValidDataRestrictions(IAuditStrategy auditStrategy, MiddleIdData referencedIdData, String versionsMiddleEntityName, QueryBuilder qb, Parameters rootParameters, bool inclusive, IEnumerable <MiddleComponentData> componentData) { var revisionPropertyPath = VerEntCfg.RevisionNumberPath; var originalIdPropertyName = VerEntCfg.OriginalIdPropName; var eeOriginalIdPropertyPath = QueryConstants.MiddleEntityAlias + "." + originalIdPropertyName; var revisionTypePropName = RevisionTypePath(); // (selecting e entities at revision :revision) // --> based on auditStrategy (see above) auditStrategy.AddEntityAtRevisionRestriction(qb, rootParameters, QueryConstants.ReferencedEntityAlias + "." + revisionPropertyPath, QueryConstants.ReferencedEntityAlias + "." + VerEntCfg.RevisionEndFieldName, false, referencedIdData, revisionPropertyPath, originalIdPropertyName, QueryConstants.ReferencedEntityAlias, QueryConstants.ReferencedEntityAliasDefAudStr); // (with ee association at revision :revision) // --> based on auditStrategy (see above) auditStrategy.AddAssociationAtRevisionRestriction(qb, rootParameters, revisionPropertyPath, VerEntCfg.RevisionEndFieldName, true, ReferencingIdData, versionsMiddleEntityName, eeOriginalIdPropertyPath, revisionPropertyPath, originalIdPropertyName, QueryConstants.MiddleEntityAlias, inclusive, componentData.ToArray()); // ee.revision_type != DEL rootParameters.AddWhereWithNamedParam(revisionTypePropName, "!=", QueryConstants.DelRevisionTypeParameter); // e.revision_type != DEL rootParameters.AddWhereWithNamedParam(QueryConstants.ReferencedEntityAlias + "." + revisionTypePropName, false, "!=", QueryConstants.DelRevisionTypeParameter); }
public static void AddAssociationAtRevision(QueryBuilder qb, Parameters rootParameters, MiddleIdData referencingIdData, String versionsMiddleEntityName, String eeOriginalIdPropertyPath, String revisionPropertyPath, String originalIdPropertyName, IEnumerable <MiddleComponentData> componentDatas) { // SELECT max(ee2.revision) FROM middleEntity ee2 QueryBuilder maxEeRevQb = qb.NewSubQueryBuilder(versionsMiddleEntityName, "ee2"); maxEeRevQb.AddProjection("max", revisionPropertyPath, false); // WHERE Parameters maxEeRevQbParameters = maxEeRevQb.RootParameters; // ee2.revision <= :revision maxEeRevQbParameters.AddWhereWithNamedParam(revisionPropertyPath, "<=", "revision"); // ee2.originalId.* = ee.originalId.* String ee2OriginalIdPropertyPath = "ee2." + originalIdPropertyName; referencingIdData.PrefixedMapper.AddIdsEqualToQuery(maxEeRevQbParameters, eeOriginalIdPropertyPath, ee2OriginalIdPropertyPath); foreach (MiddleComponentData componentData in componentDatas) { componentData.ComponentMapper.AddMiddleEqualToQuery(maxEeRevQbParameters, eeOriginalIdPropertyPath, ee2OriginalIdPropertyPath); } // ee.revision = (SELECT max(...) ...) rootParameters.AddWhere(revisionPropertyPath, "=", maxEeRevQb); }
/// <summary> /// Compute common part for both queries. /// </summary> private QueryBuilder commonQueryPart(MiddleIdData referencedIdData, MiddleIdData indexIdData, string versionsMiddleEntityName, string originalIdPropertyName) { var eeOriginalIdPropertyPath = QueryConstants.MiddleEntityAlias + "." + originalIdPropertyName; // SELECT new list(ee) FROM middleEntity ee var qb = new QueryBuilder(versionsMiddleEntityName, QueryConstants.MiddleEntityAlias); qb.AddFrom(referencedIdData.AuditEntityName, QueryConstants.ReferencedEntityAlias, false); qb.AddFrom(indexIdData.AuditEntityName, QueryConstants.IndexEntityAlias, false); qb.AddProjection("new list", QueryConstants.MiddleEntityAlias + ", " + QueryConstants.ReferencedEntityAlias + ", " + QueryConstants.IndexEntityAlias, null, false); // WHERE var rootParameters = qb.RootParameters; // ee.id_ref_ed = e.id_ref_ed referencedIdData.PrefixedMapper.AddIdsEqualToQuery(rootParameters, eeOriginalIdPropertyPath, referencedIdData.OriginalMapper, QueryConstants.ReferencedEntityAlias + "." + originalIdPropertyName); // ee.id_ref_ind = f.id_ref_ind indexIdData.PrefixedMapper.AddIdsEqualToQuery(rootParameters, eeOriginalIdPropertyPath, indexIdData.OriginalMapper, QueryConstants.IndexEntityAlias + "." + originalIdPropertyName); // ee.originalId.id_ref_ing = :id_ref_ing ReferencingIdData.PrefixedMapper.AddNamedIdEqualsToQuery(rootParameters, originalIdPropertyName, true); return(qb); }
protected AbstractRelationQueryGenerator(AuditEntitiesConfiguration verEntCfg, MiddleIdData referencingIdData, bool revisionTypeInId) { VerEntCfg = verEntCfg; ReferencingIdData = referencingIdData; _revisionTypeInId = revisionTypeInId; }
public OneEntityQueryGenerator(AuditEntitiesConfiguration verEntCfg, String versionsMiddleEntityName, MiddleIdData referencingIdData, IEnumerable <MiddleComponentData> componentDatas) { this._referencingIdData = referencingIdData; /* * The query that we need to create: * SELECT new list(ee) FROM middleEntity ee WHERE * (only entities referenced by the association; id_ref_ing = id of the referencing entity) * ee.originalId.id_ref_ing = :id_ref_ing AND * (the association at revision :revision) * ee.revision = (SELECT max(ee2.revision) FROM middleEntity ee2 * WHERE ee2.revision <= :revision AND ee2.originalId.* = ee.originalId.*) AND * (only non-deleted entities and associations) * ee.revision_type != DEL */ String revisionPropertyPath = verEntCfg.RevisionNumberPath; String originalIdPropertyName = verEntCfg.OriginalIdPropName; // SELECT new list(ee) FROM middleEntity ee QueryBuilder qb = new QueryBuilder(versionsMiddleEntityName, "ee"); qb.AddProjection("new list", "ee", false, false); // WHERE Parameters rootParameters = qb.RootParameters; // ee.originalId.id_ref_ing = :id_ref_ing referencingIdData.PrefixedMapper.AddNamedIdEqualsToQuery(rootParameters, originalIdPropertyName, true); // SELECT max(ee2.revision) FROM middleEntity ee2 QueryBuilder maxRevQb = qb.NewSubQueryBuilder(versionsMiddleEntityName, "ee2"); maxRevQb.AddProjection("max", revisionPropertyPath, false); // WHERE Parameters maxRevQbParameters = maxRevQb.RootParameters; // ee2.revision <= :revision maxRevQbParameters.AddWhereWithNamedParam(revisionPropertyPath, "<=", "revision"); // ee2.originalId.* = ee.originalId.* String eeOriginalIdPropertyPath = "ee." + originalIdPropertyName; String ee2OriginalIdPropertyPath = "ee2." + originalIdPropertyName; referencingIdData.PrefixedMapper.AddIdsEqualToQuery(maxRevQbParameters, eeOriginalIdPropertyPath, ee2OriginalIdPropertyPath); foreach (MiddleComponentData componentData in componentDatas) { componentData.ComponentMapper.AddMiddleEqualToQuery(maxRevQbParameters, eeOriginalIdPropertyPath, ee2OriginalIdPropertyPath); } // ee.revision = (SELECT max(...) ...) rootParameters.AddWhere(revisionPropertyPath, "=", maxRevQb); // ee.revision_type != DEL rootParameters.AddWhereWithNamedParam(verEntCfg.RevisionTypePropName, "!=", "delrevisiontype"); StringBuilder sb = new StringBuilder(); qb.Build(sb, EmptyDictionary <String, object> .Instance); _queryString = sb.ToString(); }
protected override void FillResult(IList result) { /* * The query that we need to create: * SELECT new list(e) FROM versionsReferencedEntity e * WHERE * (all specified conditions, transformed, on the "e" entity) AND * (selecting e entities at revision :revision) * --> for DefaultAuditStrategy: * e.revision = (SELECT max(e2.revision) FROM versionsReferencedEntity e2 * WHERE e2.revision <= :revision AND e2.id = e.id) * * --> for ValidityAuditStrategy: * e.revision <= :revision and (e.endRevision > :revision or e.endRevision is null) * * AND * (only non-deleted entities) * e.revision_type != DEL */ var verEntCfg = VerCfg.AuditEntCfg; var revisionPropertyPath = verEntCfg.RevisionNumberPath; var originalIdPropertyName = verEntCfg.OriginalIdPropName; var referencedIdData = new MiddleIdData(verEntCfg, VerCfg.EntCfg[EntityName].IdMappingData, null, EntityName, VerCfg.EntCfg.IsVersioned(EntityName)); // (selecting e entities at revision :revision) // --> based on auditStrategy (see above) VerCfg.GlobalCfg.AuditStrategy.AddEntityAtRevisionRestriction(QueryBuilder, QueryBuilder.RootParameters, revisionPropertyPath, verEntCfg.RevisionEndFieldName, true, referencedIdData, revisionPropertyPath, originalIdPropertyName, QueryConstants.ReferencedEntityAlias, QueryConstants.ReferencedEntityAliasDefAudStr); // e.revision_type != DEL if (!_includeDeletions) { QueryBuilder.RootParameters.AddWhereWithParam(verEntCfg.RevisionTypePropName, "<>", RevisionType.Deleted); } // all specified conditions foreach (var criterion in Criterions) { criterion.AddToQuery(VerCfg, VersionsReader, EntityName, QueryBuilder, QueryBuilder.RootParameters); } foreach (var associationQuery in AssociationQueries) { associationQuery.AddCriterionsToQuery(VersionsReader); } var query = BuildQuery(); // add named parameter (only used for ValidAuditTimeStrategy and association queries) if (query.NamedParameters.Contains(QueryConstants.RevisionParameter)) { query.SetParameter(QueryConstants.RevisionParameter, _revision); } ApplyProjections(query, result, _revision); }
public OneAuditEntityQueryGenerator(GlobalConfiguration globalCfg, AuditEntitiesConfiguration verEntCfg, MiddleIdData referencingIdData, String referencedEntityName, IIdMapper referencedIdMapper) { this.referencingIdData = referencingIdData; /* * The query that we need to create: * SELECT new list(e) FROM versionsReferencedEntity e * WHERE * (only entities referenced by the association; id_ref_ing = id of the referencing entity) * e.id_ref_ing = :id_ref_ing AND * (selecting e entities at revision :revision) * e.revision = (SELECT max(e2.revision) FROM versionsReferencedEntity e2 * WHERE e2.revision <= :revision AND e2.id = e.id) AND * (only non-deleted entities) * e.revision_type != DEL */ String revisionPropertyPath = verEntCfg.RevisionNumberPath; String originalIdPropertyName = verEntCfg.OriginalIdPropName; String versionsReferencedEntityName = verEntCfg.GetAuditEntityName(referencedEntityName); // SELECT new list(e) FROM versionsEntity e QueryBuilder qb = new QueryBuilder(versionsReferencedEntityName, "e"); qb.AddProjection("new list", "e", false, false); // WHERE Parameters rootParameters = qb.RootParameters; // e.id_ref_ed = :id_ref_ed referencingIdData.PrefixedMapper.AddNamedIdEqualsToQuery(rootParameters, null, true); // SELECT max(e.revision) FROM versionsReferencedEntity e2 QueryBuilder maxERevQb = qb.NewSubQueryBuilder(versionsReferencedEntityName, "e2"); maxERevQb.AddProjection("max", revisionPropertyPath, false); // WHERE Parameters maxERevQbParameters = maxERevQb.RootParameters; // e2.revision <= :revision maxERevQbParameters.AddWhereWithNamedParam(revisionPropertyPath, "<=", "revision"); // e2.id = e.id referencedIdMapper.AddIdsEqualToQuery(maxERevQbParameters, "e." + originalIdPropertyName, "e2." + originalIdPropertyName); // e.revision = (SELECT max(...) ...) rootParameters.AddWhere(revisionPropertyPath, false, globalCfg.getCorrelatedSubqueryOperator(), maxERevQb); // e.revision_type != DEL rootParameters.AddWhereWithNamedParam(verEntCfg.RevisionTypePropName, false, "!=", "delrevisiontype"); StringBuilder sb = new StringBuilder(); qb.Build(sb, EmptyDictionary <String, object> .Instance); queryString = sb.ToString(); }
public QueryGeneratorBuilder(GlobalConfiguration globalCfg, AuditEntitiesConfiguration verEntCfg, MiddleIdData referencingIdData, String auditMiddleEntityName) { this._globalCfg = globalCfg; this._verEntCfg = verEntCfg; this._referencingIdData = referencingIdData; this._auditMiddleEntityName = auditMiddleEntityName; _idDatas = new List <MiddleIdData>(); }
/** * * @param value Value, which should be mapped to the middle-table, either as a relation to another entity, * or as a simple value. * @param xmlMapping If not <code>null</code>, xml mapping for this value is added to this element. * @param queryGeneratorBuilder In case <code>value</code> is a relation to another entity, information about it * should be added to the given. * @param prefix Prefix for proeprty names of related entities identifiers. * @param joinColumns Names of columns to use in the xml mapping, if this array isn't null and has any elements. * @return Data for mapping this component. */ //@SuppressWarnings({"unchecked"}) private MiddleComponentData AddValueToMiddleTable(IValue value, XmlElement xmlMapping, QueryGeneratorBuilder queryGeneratorBuilder, String prefix, JoinColumnAttribute[] joinColumns) { IType type = value.Type; if (type is ManyToOneType) { String prefixRelated = prefix + "_"; String referencedEntityName = MappingTools.getReferencedEntityName(value); IdMappingData referencedIdMapping = mainGenerator.GetReferencedIdMappingData(referencingEntityName, referencedEntityName, propertyAuditingData, true); // Adding related-entity (in this case: the referenced entities id) id mapping to the xml only if the // relation isn't inverse (so when <code>xmlMapping</code> is not null). if (xmlMapping != null) { AddRelatedToXmlMapping(xmlMapping, prefixRelated, joinColumns != null && joinColumns.Length > 0 ? MetadataTools.GetColumnNameEnumerator(joinColumns) : MetadataTools.GetColumnNameEnumerator(value.ColumnIterator.GetEnumerator()), referencedIdMapping); } // Storing the id data of the referenced entity: original mapper, prefixed mapper and entity name. MiddleIdData referencedIdData = CreateMiddleIdData(referencedIdMapping, prefixRelated, referencedEntityName); // And adding it to the generator builder. queryGeneratorBuilder.AddRelation(referencedIdData); return(new MiddleComponentData(new MiddleRelatedComponentMapper(referencedIdData), queryGeneratorBuilder.CurrentIndex)); } else { // Last but one parameter: collection components are always insertable bool mapped = mainGenerator.BasicMetadataGenerator.AddBasic(xmlMapping, new PropertyAuditingData(prefix, "field", ModificationStore.FULL, RelationTargetAuditMode.AUDITED, null, null, false), value, null, true, true); if (mapped) { // Simple values are always stored in the first item of the array returned by the query generator. return(new MiddleComponentData(new MiddleSimpleComponentMapper(mainGenerator.VerEntCfg, prefix), 0)); } else { mainGenerator.ThrowUnsupportedTypeException(type, referencingEntityName, propertyName); // Impossible to get here. throw new AssertionFailure(); } } }
public QueryGeneratorBuilder(AuditEntitiesConfiguration verEntCfg, IAuditStrategy auditStrategy, MiddleIdData referencingIdData, string auditMiddleEntityName, bool revisionTypeInId) { _verEntCfg = verEntCfg; _auditStrategy = auditStrategy; _referencingIdData = referencingIdData; _auditMiddleEntityName = auditMiddleEntityName; _revisionTypeInId = revisionTypeInId; _idDatas = new List <MiddleIdData>(); }
public TwoEntityOneAuditedQueryGenerator( AuditEntitiesConfiguration verEntCfg, String versionsMiddleEntityName, MiddleIdData referencingIdData, MiddleIdData referencedIdData, IEnumerable <MiddleComponentData> componentDatas) { this.referencingIdData = referencingIdData; /* * The query that we need to create: * SELECT new list(ee, e) FROM referencedEntity e, middleEntity ee * WHERE * (entities referenced by the middle table; id_ref_ed = id of the referenced entity) * ee.id_ref_ed = e.id_ref_ed AND * (only entities referenced by the association; id_ref_ing = id of the referencing entity) * ee.id_ref_ing = :id_ref_ing AND * (the association at revision :revision) * ee.revision = (SELECT max(ee2.revision) FROM middleEntity ee2 * WHERE ee2.revision <= :revision AND ee2.originalId.* = ee.originalId.*) AND * (only non-deleted entities and associations) * ee.revision_type != DEL */ String revisionPropertyPath = verEntCfg.RevisionNumberPath; String originalIdPropertyName = verEntCfg.OriginalIdPropName; String eeOriginalIdPropertyPath = "ee." + originalIdPropertyName; // SELECT new list(ee) FROM middleEntity ee QueryBuilder qb = new QueryBuilder(versionsMiddleEntityName, "ee"); qb.AddFrom(referencedIdData.EntityName, "e"); qb.AddProjection("new list", "ee, e", false, false); // WHERE Parameters rootParameters = qb.RootParameters; // ee.id_ref_ed = e.id_ref_ed referencedIdData.PrefixedMapper.AddIdsEqualToQuery(rootParameters, eeOriginalIdPropertyPath, referencedIdData.OriginalMapper, "e"); // ee.originalId.id_ref_ing = :id_ref_ing referencingIdData.PrefixedMapper.AddNamedIdEqualsToQuery(rootParameters, originalIdPropertyName, true); // ee.revision = (SELECT max(...) ...) QueryGeneratorTools.AddAssociationAtRevision(qb, rootParameters, referencingIdData, versionsMiddleEntityName, eeOriginalIdPropertyPath, revisionPropertyPath, originalIdPropertyName, componentDatas); // ee.revision_type != DEL rootParameters.AddWhereWithNamedParam(verEntCfg.RevisionTypePropName, "!=", "delrevisiontype"); StringBuilder sb = new StringBuilder(); qb.Build(sb, EmptyDictionary <String, Object> .Instance); queryString = sb.ToString(); }
/// <summary> /// Creates query restrictions used to retrieve only actual data. /// </summary> private void createValidDataRestrictions(IAuditStrategy auditStrategy, MiddleIdData referencedIdData, QueryBuilder qb, Parameters rootParameters) { var revisionPropertyPath = VerEntCfg.RevisionNumberPath; // (selecting e entities at revision :revision) // --> based on auditStrategy (see above) auditStrategy.AddEntityAtRevisionRestriction(qb, rootParameters, revisionPropertyPath, VerEntCfg.RevisionEndFieldName, true, referencedIdData, revisionPropertyPath, VerEntCfg.OriginalIdPropName, QueryConstants.ReferencedEntityAlias, QueryConstants.ReferencedEntityAliasDefAudStr); // e.revision_type != DEL rootParameters.AddWhereWithNamedParam(RevisionTypePath(), false, "!=", QueryConstants.DelRevisionTypeParameter); }
public OneAuditEntityQueryGenerator(GlobalConfiguration globalCfg, AuditEntitiesConfiguration verEntCfg, MiddleIdData referencingIdData, String referencedEntityName, IIdMapper referencedIdMapper) { this.referencingIdData = referencingIdData; /* * The query that we need to create: * SELECT new list(e) FROM versionsReferencedEntity e * WHERE * (only entities referenced by the association; id_ref_ing = id of the referencing entity) * e.id_ref_ing = :id_ref_ing AND * (selecting e entities at revision :revision) * e.revision = (SELECT max(e2.revision) FROM versionsReferencedEntity e2 * WHERE e2.revision <= :revision AND e2.id = e.id) AND * (only non-deleted entities) * e.revision_type != DEL */ String revisionPropertyPath = verEntCfg.RevisionNumberPath; String originalIdPropertyName = verEntCfg.OriginalIdPropName; String versionsReferencedEntityName = verEntCfg.GetAuditEntityName(referencedEntityName); // SELECT new list(e) FROM versionsEntity e QueryBuilder qb = new QueryBuilder(versionsReferencedEntityName, "e"); qb.AddProjection("new list", "e", false, false); // WHERE Parameters rootParameters = qb.RootParameters; // e.id_ref_ed = :id_ref_ed referencingIdData.PrefixedMapper.AddNamedIdEqualsToQuery(rootParameters, null, true); // SELECT max(e.revision) FROM versionsReferencedEntity e2 QueryBuilder maxERevQb = qb.NewSubQueryBuilder(versionsReferencedEntityName, "e2"); maxERevQb.AddProjection("max", revisionPropertyPath, false); // WHERE Parameters maxERevQbParameters = maxERevQb.RootParameters; // e2.revision <= :revision maxERevQbParameters.AddWhereWithNamedParam(revisionPropertyPath, "<=", "revision"); // e2.id = e.id referencedIdMapper.AddIdsEqualToQuery(maxERevQbParameters, "e." + originalIdPropertyName, "e2." + originalIdPropertyName); // e.revision = (SELECT max(...) ...) rootParameters.AddWhere(revisionPropertyPath, false, globalCfg.getCorrelatedSubqueryOperator(), maxERevQb); // e.revision_type != DEL rootParameters.AddWhereWithNamedParam(verEntCfg.RevisionTypePropName, false, "!=", "delrevisiontype"); StringBuilder sb = new StringBuilder(); qb.Build(sb, EmptyDictionary<String, object>.Instance); queryString = sb.ToString(); }
public OneEntityQueryGenerator(AuditEntitiesConfiguration verEntCfg, String versionsMiddleEntityName, MiddleIdData referencingIdData, IEnumerable<MiddleComponentData> componentDatas) { this._referencingIdData = referencingIdData; /* * The query that we need to create: * SELECT new list(ee) FROM middleEntity ee WHERE * (only entities referenced by the association; id_ref_ing = id of the referencing entity) * ee.originalId.id_ref_ing = :id_ref_ing AND * (the association at revision :revision) * ee.revision = (SELECT max(ee2.revision) FROM middleEntity ee2 * WHERE ee2.revision <= :revision AND ee2.originalId.* = ee.originalId.*) AND * (only non-deleted entities and associations) * ee.revision_type != DEL */ String revisionPropertyPath = verEntCfg.RevisionNumberPath; String originalIdPropertyName = verEntCfg.OriginalIdPropName; // SELECT new list(ee) FROM middleEntity ee QueryBuilder qb = new QueryBuilder(versionsMiddleEntityName, "ee"); qb.AddProjection("new list", "ee", false, false); // WHERE Parameters rootParameters = qb.RootParameters; // ee.originalId.id_ref_ing = :id_ref_ing referencingIdData.PrefixedMapper.AddNamedIdEqualsToQuery(rootParameters, originalIdPropertyName, true); // SELECT max(ee2.revision) FROM middleEntity ee2 QueryBuilder maxRevQb = qb.NewSubQueryBuilder(versionsMiddleEntityName, "ee2"); maxRevQb.AddProjection("max", revisionPropertyPath, false); // WHERE Parameters maxRevQbParameters = maxRevQb.RootParameters; // ee2.revision <= :revision maxRevQbParameters.AddWhereWithNamedParam(revisionPropertyPath, "<=", "revision"); // ee2.originalId.* = ee.originalId.* String eeOriginalIdPropertyPath = "ee." + originalIdPropertyName; String ee2OriginalIdPropertyPath = "ee2." + originalIdPropertyName; referencingIdData.PrefixedMapper.AddIdsEqualToQuery(maxRevQbParameters, eeOriginalIdPropertyPath, ee2OriginalIdPropertyPath); foreach (MiddleComponentData componentData in componentDatas) { componentData.ComponentMapper.AddMiddleEqualToQuery(maxRevQbParameters, eeOriginalIdPropertyPath, ee2OriginalIdPropertyPath); } // ee.revision = (SELECT max(...) ...) rootParameters.AddWhere(revisionPropertyPath, "=", maxRevQb); // ee.revision_type != DEL rootParameters.AddWhereWithNamedParam(verEntCfg.RevisionTypePropName, "!=", "delrevisiontype"); StringBuilder sb = new StringBuilder(); qb.Build(sb, EmptyDictionary<String, object>.Instance); _queryString = sb.ToString(); }
public TwoEntityOneAuditedQueryGenerator( AuditEntitiesConfiguration verEntCfg, String versionsMiddleEntityName, MiddleIdData referencingIdData, MiddleIdData referencedIdData, IEnumerable<MiddleComponentData> componentDatas) { this.referencingIdData = referencingIdData; /* * The query that we need to create: * SELECT new list(ee, e) FROM referencedEntity e, middleEntity ee * WHERE * (entities referenced by the middle table; id_ref_ed = id of the referenced entity) * ee.id_ref_ed = e.id_ref_ed AND * (only entities referenced by the association; id_ref_ing = id of the referencing entity) * ee.id_ref_ing = :id_ref_ing AND * (the association at revision :revision) * ee.revision = (SELECT max(ee2.revision) FROM middleEntity ee2 * WHERE ee2.revision <= :revision AND ee2.originalId.* = ee.originalId.*) AND * (only non-deleted entities and associations) * ee.revision_type != DEL */ String revisionPropertyPath = verEntCfg.RevisionNumberPath; String originalIdPropertyName = verEntCfg.OriginalIdPropName; String eeOriginalIdPropertyPath = "ee." + originalIdPropertyName; // SELECT new list(ee) FROM middleEntity ee QueryBuilder qb = new QueryBuilder(versionsMiddleEntityName, "ee"); qb.AddFrom(referencedIdData.EntityName, "e"); qb.AddProjection("new list", "ee, e", false, false); // WHERE Parameters rootParameters = qb.RootParameters; // ee.id_ref_ed = e.id_ref_ed referencedIdData.PrefixedMapper.AddIdsEqualToQuery(rootParameters, eeOriginalIdPropertyPath, referencedIdData.OriginalMapper, "e"); // ee.originalId.id_ref_ing = :id_ref_ing referencingIdData.PrefixedMapper.AddNamedIdEqualsToQuery(rootParameters, originalIdPropertyName, true); // ee.revision = (SELECT max(...) ...) QueryGeneratorTools.AddAssociationAtRevision(qb, rootParameters, referencingIdData, versionsMiddleEntityName, eeOriginalIdPropertyPath, revisionPropertyPath, originalIdPropertyName, componentDatas); // ee.revision_type != DEL rootParameters.AddWhereWithNamedParam(verEntCfg.RevisionTypePropName, "!=", "delrevisiontype"); StringBuilder sb = new StringBuilder(); qb.Build(sb, EmptyDictionary<String, Object>.Instance); queryString = sb.ToString(); }
public void AddCriterionsToQuery(IAuditReaderImplementor versionsReader) { if (hasCriterions() || hasOrders() || hasProjections()) { if (_auditConfiguration.EntCfg.IsVersioned(_entityName)) { var verEntCfg = _auditConfiguration.AuditEntCfg; var auditEntityName = verEntCfg.GetAuditEntityName(_entityName); _queryBuilder.AddFrom(auditEntityName, _alias, false); // owner.reference_id = target.originalId.Id var originalIdPropertyName = verEntCfg.OriginalIdPropName; var idMapperTarget = _auditConfiguration.EntCfg[_entityName].IdMapper; var prefix = _alias + "." + originalIdPropertyName; _ownerAssociationIdMapper.AddIdsEqualToQuery(_queryBuilder.RootParameters, _ownerAlias, idMapperTarget, prefix); //filter reference of target entity var revisionPropertyPath = verEntCfg.RevisionNumberPath; var referencedIdData = new MiddleIdData( verEntCfg, _auditConfiguration.EntCfg[_entityName].IdMappingData, prefix: null, _entityName, _auditConfiguration.EntCfg.IsVersioned(_entityName)); _auditConfiguration.GlobalCfg.AuditStrategy.AddEntityAtRevisionRestriction(_queryBuilder, _parameters, revisionPropertyPath, verEntCfg.RevisionEndFieldName, true, referencedIdData, revisionPropertyPath, originalIdPropertyName, _alias, _queryBuilder.GenerateAlias()); } else { _queryBuilder.AddFrom(_entityName, _alias, false); //owner.reference_id = target.id var idMapperTarget = _auditConfiguration.EntCfg.GetNotVersionEntityConfiguration(_entityName).IdMapper; _ownerAssociationIdMapper.AddIdsEqualToQuery(_queryBuilder.RootParameters, _ownerAlias, idMapperTarget, _alias); } foreach (var criterion in _criterions) { criterion.AddToQuery(_auditConfiguration, versionsReader, _entityName, _queryBuilder, _parameters); } foreach (var sub in _associationQueries) { sub.AddCriterionsToQuery(versionsReader); } } }
public static void AddEntityAtRevision(GlobalConfiguration globalCfg, QueryBuilder qb, Parameters rootParameters, MiddleIdData idData, String revisionPropertyPath, String originalIdPropertyName, String alias1, String alias2) { // SELECT max(e.revision) FROM versionsReferencedEntity e2 QueryBuilder maxERevQb = qb.NewSubQueryBuilder(idData.AuditEntityName, alias2); maxERevQb.AddProjection("max", revisionPropertyPath, false); // WHERE Parameters maxERevQbParameters = maxERevQb.RootParameters; // e2.revision <= :revision maxERevQbParameters.AddWhereWithNamedParam(revisionPropertyPath, "<=", "revision"); // e2.id_ref_ed = e.id_ref_ed idData.OriginalMapper.AddIdsEqualToQuery(maxERevQbParameters, alias1 + "." + originalIdPropertyName, alias2 +"." + originalIdPropertyName); // e.revision = (SELECT max(...) ...) rootParameters.AddWhere("e." + revisionPropertyPath, false, globalCfg.getCorrelatedSubqueryOperator(), maxERevQb); }
public override IEnumerable <TEntity> Results() { /* * The query that should be executed in the versions table: * SELECT e FROM ent_ver e * WHERE * (all specified conditions, transformed, on the "e" entity) AND * (selecting e entities at revision :revision) * --> for DefaultAuditStrategy: * e.revision = (SELECT max(e2.revision) FROM versionsReferencedEntity e2 * WHERE e2.revision <= :revision AND e2.id = e.id) * * --> for ValidityAuditStrategy: * e.revision <= :revision and (e.endRevision > :revision or e.endRevision is null) * * AND * (only non-deleted entities) * e.revision_type != DEL */ var verEntCfg = AuditConfiguration.AuditEntCfg; var revisionPropertyPath = verEntCfg.RevisionNumberPath; var originalIdPropertyName = verEntCfg.OriginalIdPropName; var referencedIdData = new MiddleIdData(verEntCfg, AuditConfiguration.EntCfg[EntityName].IdMappingData, prefix: null, EntityName, AuditConfiguration.EntCfg.IsVersioned(EntityName)); // (selecting e entities at revision :revision) // --> based on auditStrategy (see above) AuditConfiguration.GlobalCfg.AuditStrategy.AddEntityAtRevisionRestriction(QueryBuilder, QueryBuilder.RootParameters, revisionPropertyPath, verEntCfg.RevisionEndFieldName, true, referencedIdData, revisionPropertyPath, originalIdPropertyName, QueryConstants.ReferencedEntityAlias, QueryConstants.ReferencedEntityAliasDefAudStr); SetIncludeDeletationClause(); AddCriterions(); // the result of BuildAndExecuteQuery is always the name-value pair of EntityMode.Map return(from versionsEntity in BuildAndExecuteQuery <IDictionary>() select(TEntity) EntityInstantiator.CreateInstanceFromVersionsEntity(EntityName, versionsEntity, _revision)); }
public static void AddEntityAtRevision(GlobalConfiguration globalCfg, QueryBuilder qb, Parameters rootParameters, MiddleIdData idData, String revisionPropertyPath, String originalIdPropertyName, String alias1, String alias2) { // SELECT max(e.revision) FROM versionsReferencedEntity e2 QueryBuilder maxERevQb = qb.NewSubQueryBuilder(idData.AuditEntityName, alias2); maxERevQb.AddProjection("max", revisionPropertyPath, false); // WHERE Parameters maxERevQbParameters = maxERevQb.RootParameters; // e2.revision <= :revision maxERevQbParameters.AddWhereWithNamedParam(revisionPropertyPath, "<=", "revision"); // e2.id_ref_ed = e.id_ref_ed idData.OriginalMapper.AddIdsEqualToQuery(maxERevQbParameters, alias1 + "." + originalIdPropertyName, alias2 + "." + originalIdPropertyName); // e.revision = (SELECT max(...) ...) rootParameters.AddWhere("e." + revisionPropertyPath, false, globalCfg.getCorrelatedSubqueryOperator(), maxERevQb); }
public static void AddAssociationAtRevision(QueryBuilder qb, Parameters rootParameters, MiddleIdData referencingIdData, String versionsMiddleEntityName, String eeOriginalIdPropertyPath, String revisionPropertyPath, String originalIdPropertyName, IEnumerable<MiddleComponentData> componentDatas) { // SELECT max(ee2.revision) FROM middleEntity ee2 QueryBuilder maxEeRevQb = qb.NewSubQueryBuilder(versionsMiddleEntityName, "ee2"); maxEeRevQb.AddProjection("max", revisionPropertyPath, false); // WHERE Parameters maxEeRevQbParameters = maxEeRevQb.RootParameters; // ee2.revision <= :revision maxEeRevQbParameters.AddWhereWithNamedParam(revisionPropertyPath, "<=", "revision"); // ee2.originalId.* = ee.originalId.* String ee2OriginalIdPropertyPath = "ee2." + originalIdPropertyName; referencingIdData.PrefixedMapper.AddIdsEqualToQuery(maxEeRevQbParameters, eeOriginalIdPropertyPath, ee2OriginalIdPropertyPath); foreach (MiddleComponentData componentData in componentDatas) { componentData.ComponentMapper.AddMiddleEqualToQuery(maxEeRevQbParameters, eeOriginalIdPropertyPath, ee2OriginalIdPropertyPath); } // ee.revision = (SELECT max(...) ...) rootParameters.AddWhere(revisionPropertyPath, "=", maxEeRevQb); }
public void AddEntityAtRevisionRestriction(QueryBuilder rootQueryBuilder, Parameters parameters, string revisionProperty, string revisionEndProperty, bool addAlias, MiddleIdData idData, string revisionPropertyPath, string originalIdPropertyName, string alias1, string alias2) { // create a subquery builder // SELECT max(e.revision) FROM versionsReferencedEntity e2 var maxERevQb = rootQueryBuilder.NewSubQueryBuilder(idData.AuditEntityName, alias2); maxERevQb.AddProjection("max", revisionPropertyPath, false); // WHERE var maxERevQbParameters = maxERevQb.RootParameters; // e2.revision <= :revision maxERevQbParameters.AddWhereWithNamedParam(revisionPropertyPath, "<=", QueryConstants.RevisionParameter); // e2.id_ref_ed = e.id_ref_ed idData.OriginalMapper.AddIdsEqualToQuery(maxERevQbParameters, alias1 + "." + originalIdPropertyName, alias2 + "." + originalIdPropertyName); // add subquery to rootParameters var subqueryOperator = _auditConfiguration.GlobalCfg.CorrelatedSubqueryOperator; parameters.AddWhere(revisionProperty, addAlias, subqueryOperator, maxERevQb); }
public void AddAssociationAtRevisionRestriction(QueryBuilder rootQueryBuilder, Parameters parameters, string revisionProperty, string revisionEndProperty, bool addAlias, MiddleIdData referencingIdData, string versionsMiddleEntityName, string eeOriginalIdPropertyPath, string revisionPropertyPath, string originalIdPropertyName, string alias1, bool inclusive, params MiddleComponentData[] componentDatas) { // SELECT max(ee2.revision) FROM middleEntity ee2 var maxEeRevQb = rootQueryBuilder.NewSubQueryBuilder(versionsMiddleEntityName, QueryConstants.MiddleEntityAliasDefAudStr); maxEeRevQb.AddProjection("max", revisionPropertyPath, false); // WHERE var maxEeRevQbParameters = maxEeRevQb.RootParameters; // ee2.revision <= :revision maxEeRevQbParameters.AddWhereWithNamedParam(revisionPropertyPath, inclusive ? "<=" : "<", QueryConstants.RevisionParameter); // ee2.originalId.* = ee.originalId.* var ee2OriginalIdPropertyPath = QueryConstants.MiddleEntityAliasDefAudStr + "." + originalIdPropertyName; referencingIdData.PrefixedMapper.AddIdsEqualToQuery(maxEeRevQbParameters, eeOriginalIdPropertyPath, ee2OriginalIdPropertyPath); foreach (var componentData in componentDatas) { componentData.ComponentMapper.AddMiddleEqualToQuery(maxEeRevQbParameters, eeOriginalIdPropertyPath, alias1, ee2OriginalIdPropertyPath, QueryConstants.MiddleEntityAliasDefAudStr); } // add subquery to rootParameters parameters.AddWhere(revisionProperty, addAlias, "=", maxEeRevQb); }
private void addOneToManyAttached(bool fakeOneToManyBidirectional) { log.Debug("Adding audit mapping for property {0}. {1}" + ": one-to-many collection, using a join column on the referenced entity.", _referencingEntityName, _propertyName); var mappedByProperty = getMappedByProperty(_propertyValue); var mappedBy = mappedByProperty?.Name; var referencedIdMapping = _mainGenerator.GetReferencedIdMappingData(_referencingEntityName, _referencedEntityName, _propertyAuditingData, false); var referencingIdMapping = _referencingEntityConfiguration.IdMappingData; //// Generating the id mappers data for the referencing side of the relation. //var referencingIdData = createMiddleIdData(referencingIdMapping, // mappedBy + MappingTools.RelationCharacter, _referencingEntityName); MiddleIdData referencingIdData; // HACK: Terrible hack to fix LegOrSectorID if ("AviMall.Supplier.Data.Permit" == _referencedEntityName && "AviMall.Supplier.Data.AdhocFlightLeg" == _referencingEntityName) { // The relational property is Id and navigation. referencingIdData = new MiddleIdData( _mainGenerator.VerEntCfg, referencingIdMapping, mappedByProperty, _referencingEntityName, _mainGenerator.EntitiesConfigurations.ContainsKey(_referencingEntityName) ); } else { // Generating the id mappers data for the referencing side of the relation. referencingIdData = createMiddleIdData(referencingIdMapping, mappedBy + MappingTools.RelationCharacter, _referencingEntityName); } // And for the referenced side. The prefixed mapper won't be used (as this collection isn't persisted // in a join table, so the prefix value is arbitrary). var referencedIdData = createMiddleIdData(referencedIdMapping, null, _referencedEntityName); // Generating the element mapping. var elementComponentData = new MiddleComponentData( new MiddleRelatedComponentMapper(referencedIdData), 0); // Generating the index mapping, if an index exists. It can only exists in case a javax.persistence.MapKey // annotation is present on the entity. So the middleEntityXml will be not be used. The queryGeneratorBuilder // will only be checked for nullnes. var indexComponentData = addIndex(null, null); // Generating the query generator - it should read directly from the related entity. var queryGenerator = new OneAuditEntityQueryGenerator(_mainGenerator.VerEntCfg, _mainGenerator.GlobalCfg.AuditStrategy, referencingIdData, _referencedEntityName, referencedIdData, isEmbeddableElementType()); // Creating common mapper data. var commonCollectionMapperData = new CommonCollectionMapperData( _mainGenerator.VerEntCfg, _referencedEntityName, _propertyAuditingData.GetPropertyData(), referencingIdData, queryGenerator); IPropertyMapper fakeBidirectionalRelationMapper; IPropertyMapper fakeBidirectionalRelationIndexMapper; if (fakeOneToManyBidirectional) { // In case of a fake many-to-one bidirectional relation, we have to generate a mapper which maps // the mapped-by property name to the id of the related entity (which is the owner of the collection). var auditMappedBy = _propertyAuditingData.MappedBy; // Creating a prefixed relation mapper. var relMapper = referencingIdMapping.IdMapper.PrefixMappedProperties( MappingTools.CreateToOneRelationPrefix(auditMappedBy)); fakeBidirectionalRelationMapper = new ToOneIdMapper( relMapper, // The mapper will only be used to map from entity to map, so no need to provide other details // when constructing the PropertyData. new PropertyData(auditMappedBy, null, null), _referencedEntityName, false); // Checking if there's an index defined. If so, adding a mapper for it. if (_propertyAuditingData.PositionMappedBy != null) { var positionMappedBy = _propertyAuditingData.PositionMappedBy; fakeBidirectionalRelationIndexMapper = new SinglePropertyMapper(new PropertyData(positionMappedBy, null, null)); // Also, overwriting the index component data to properly read the index. indexComponentData = new MiddleComponentData(new MiddleStraightComponentMapper(positionMappedBy), 0); } else { fakeBidirectionalRelationIndexMapper = null; } } else { fakeBidirectionalRelationMapper = null; fakeBidirectionalRelationIndexMapper = null; } // Checking the type of the collection and adding an appropriate mapper. addMapper(commonCollectionMapperData, elementComponentData, indexComponentData); // Storing information about this relation. _referencingEntityConfiguration.AddToManyNotOwningRelation(_propertyName, mappedBy, _referencedEntityName, referencingIdData.PrefixedMapper, fakeBidirectionalRelationMapper, fakeBidirectionalRelationIndexMapper); }
public MiddleRelatedComponentMapper(MiddleIdData relatedIdData) { this.relatedIdData = relatedIdData; }
private void AddOneToManyAttached(bool fakeOneToManyBidirectional) { //throw new NotImplementedException(); log.Debug("Adding audit mapping for property " + referencingEntityName + "." + propertyName + ": one-to-many collection, using a join column on the referenced entity."); String mappedBy = GetMappedBy(propertyValue); IdMappingData referencedIdMapping = mainGenerator.GetReferencedIdMappingData(referencingEntityName, referencedEntityName, propertyAuditingData, false); IdMappingData referencingIdMapping = referencingEntityConfiguration.IdMappingData; // Generating the id mappers data for the referencing side of the relation. MiddleIdData referencingIdData = CreateMiddleIdData(referencingIdMapping, mappedBy + "_", referencingEntityName); // And for the referenced side. The prefixed mapper won't be used (as this collection isn't persisted // in a join table, so the prefix value is arbitrary). MiddleIdData referencedIdData = CreateMiddleIdData(referencedIdMapping, null, referencedEntityName); // Generating the element mapping. MiddleComponentData elementComponentData = new MiddleComponentData( new MiddleRelatedComponentMapper(referencedIdData), 0); // Generating the index mapping, if an index exists. It can only exists in case a javax.persistence.MapKey // annotation is present on the entity. So the middleEntityXml will be not be used. The queryGeneratorBuilder // will only be checked for nullnes. MiddleComponentData indexComponentData = AddIndex(null, null); // Generating the query generator - it should read directly from the related entity. IRelationQueryGenerator queryGenerator = new OneAuditEntityQueryGenerator(mainGenerator.GlobalCfg, mainGenerator.VerEntCfg, referencingIdData, referencedEntityName, referencedIdMapping.IdMapper); // Creating common mapper data. CommonCollectionMapperData commonCollectionMapperData = new CommonCollectionMapperData( mainGenerator.VerEntCfg, referencedEntityName, propertyAuditingData.getPropertyData(), referencingIdData, queryGenerator); IPropertyMapper fakeBidirectionalRelationMapper; IPropertyMapper fakeBidirectionalRelationIndexMapper; if (fakeOneToManyBidirectional) { // In case of a fake many-to-one bidirectional relation, we have to generate a mapper which maps // the mapped-by property name to the id of the related entity (which is the owner of the collection). String auditMappedBy = propertyAuditingData.AuditMappedBy; // Creating a prefixed relation mapper. IIdMapper relMapper = referencingIdMapping.IdMapper.PrefixMappedProperties( MappingTools.createToOneRelationPrefix(auditMappedBy)); fakeBidirectionalRelationMapper = new ToOneIdMapper( relMapper, // The mapper will only be used to map from entity to map, so no need to provide other details // when constructing the PropertyData. new PropertyData(auditMappedBy, null, null, ModificationStore._NULL), referencedEntityName, false); // Checking if there's an index defined. If so, adding a mapper for it. if (propertyAuditingData.PositionMappedBy != null) { String positionMappedBy = propertyAuditingData.PositionMappedBy; fakeBidirectionalRelationIndexMapper = new SinglePropertyMapper(new PropertyData(positionMappedBy, null, null, ModificationStore._NULL)); // Also, overwriting the index component data to properly read the index. indexComponentData = new MiddleComponentData(new MiddleStraightComponentMapper(positionMappedBy), 0); } else { fakeBidirectionalRelationIndexMapper = null; } } else { fakeBidirectionalRelationMapper = null; fakeBidirectionalRelationIndexMapper = null; } // Checking the type of the collection and adding an appropriate mapper. AddMapper(commonCollectionMapperData, elementComponentData, indexComponentData); // Storing information about this relation. referencingEntityConfiguration.AddToManyNotOwningRelation(propertyName, mappedBy, referencedEntityName, referencingIdData.PrefixedMapper, fakeBidirectionalRelationMapper, fakeBidirectionalRelationIndexMapper); }
/// <summary> /// Create query restrictions used to retrieve actual data and deletions that took place at exactly given revision. /// </summary> private void createValidAndRemovedDataRestrictions(IAuditStrategy auditStrategy, MiddleIdData referencedIdData, QueryBuilder remQb) { var disjoint = remQb.RootParameters.AddSubParameters("or"); var valid = disjoint.AddSubParameters("and"); // Restrictions to match all valid rows. var removed = disjoint.AddSubParameters("and"); // Restrictions to match all rows deleted at exactly given revision. // Excluding current revision, because we need to match data valid at the previous one. createValidDataRestrictions(auditStrategy, referencedIdData, remQb, valid); // e.revision = :revision removed.AddWhereWithNamedParam(VerEntCfg.RevisionNumberPath, false, "=", QueryConstants.RevisionParameter); // e.revision_type = DEL removed.AddWhereWithNamedParam(RevisionTypePath(), false, "=", QueryConstants.DelRevisionTypeParameter); }
private void AddWithMiddleTable() { log.Debug("Adding audit mapping for property " + referencingEntityName + "." + propertyName + ": collection with a join table."); // Generating the name of the middle table String auditMiddleTableName; String auditMiddleEntityName; if (!String.IsNullOrEmpty(propertyAuditingData.JoinTable.Name)) { auditMiddleTableName = propertyAuditingData.JoinTable.Name; auditMiddleEntityName = propertyAuditingData.JoinTable.Name; } else { String middleTableName = GetMiddleTableName(propertyValue, referencingEntityName); auditMiddleTableName = mainGenerator.VerEntCfg.GetAuditTableName(null, middleTableName); auditMiddleEntityName = mainGenerator.VerEntCfg.GetAuditEntityName(middleTableName); } log.Debug("Using join table name: " + auditMiddleTableName); // Generating the XML mapping for the middle entity, only if the relation isn't inverse. // If the relation is inverse, will be later checked by comparing middleEntityXml with null. XmlElement middleEntityXml; if (!propertyValue.IsInverse) { // Generating a unique middle entity name auditMiddleEntityName = mainGenerator.AuditEntityNameRegister.createUnique(auditMiddleEntityName); // Registering the generated name mainGenerator.AuditEntityNameRegister.register(auditMiddleEntityName); middleEntityXml = CreateMiddleEntityXml(auditMiddleTableName, auditMiddleEntityName, propertyValue.Where); } else { middleEntityXml = null; } // ****** // Generating the mapping for the referencing entity (it must be an entity). // ****** // Getting the id-mapping data of the referencing entity (the entity that "owns" this collection). IdMappingData referencingIdMapping = referencingEntityConfiguration.IdMappingData; // Only valid for an inverse relation; null otherwise. String mappedBy; // The referencing prefix is always for a related entity. So it has always the "_" at the end added. String referencingPrefixRelated; String referencedPrefix; if (propertyValue.IsInverse) { // If the relation is inverse, then referencedEntityName is not null. mappedBy = GetMappedBy(propertyValue.CollectionTable, mainGenerator.Cfg.GetClassMapping(referencedEntityName)); referencingPrefixRelated = mappedBy + "_"; referencedPrefix = StringTools.GetLastComponent(referencedEntityName); } else { mappedBy = null; referencingPrefixRelated = StringTools.GetLastComponent(referencingEntityName) + "_"; referencedPrefix = referencedEntityName == null ? "element" : propertyName; } // Storing the id data of the referencing entity: original mapper, prefixed mapper and entity name. MiddleIdData referencingIdData = CreateMiddleIdData(referencingIdMapping, referencingPrefixRelated, referencingEntityName); // Creating a query generator builder, to which additional id data will be added, in case this collection // references some entities (either from the element or index). At the end, this will be used to build // a query generator to read the raw data collection from the middle table. QueryGeneratorBuilder queryGeneratorBuilder = new QueryGeneratorBuilder(mainGenerator.GlobalCfg, mainGenerator.VerEntCfg, referencingIdData, auditMiddleEntityName); // Adding the XML mapping for the referencing entity, if the relation isn't inverse. if (middleEntityXml != null) { // Adding related-entity (in this case: the referencing's entity id) id mapping to the xml. AddRelatedToXmlMapping(middleEntityXml, referencingPrefixRelated, MetadataTools.GetColumnNameEnumerator(propertyValue.Key.ColumnIterator.GetEnumerator()), referencingIdMapping); } // ****** // Generating the element mapping. // ****** MiddleComponentData elementComponentData = AddValueToMiddleTable(propertyValue.Element, middleEntityXml, queryGeneratorBuilder, referencedPrefix, propertyAuditingData.JoinTable.InverseJoinColumns); // ****** // Generating the index mapping, if an index exists. // ****** MiddleComponentData indexComponentData = AddIndex(middleEntityXml, queryGeneratorBuilder); // ****** // Generating the property mapper. // ****** // Building the query generator. IRelationQueryGenerator queryGenerator = queryGeneratorBuilder.Build(new Collection <MiddleComponentData> { elementComponentData, indexComponentData }); // Creating common data CommonCollectionMapperData commonCollectionMapperData = new CommonCollectionMapperData( mainGenerator.VerEntCfg, auditMiddleEntityName, propertyAuditingData.getPropertyData(), referencingIdData, queryGenerator); // Checking the type of the collection and adding an appropriate mapper. AddMapper(commonCollectionMapperData, elementComponentData, indexComponentData); // ****** // Storing information about this relation. // ****** StoreMiddleEntityRelationInformation(mappedBy); }
public void AddEntityAtRevisionRestriction(QueryBuilder rootQueryBuilder, Parameters parameters, string revisionProperty, string revisionEndProperty, bool addAlias, MiddleIdData idData, string revisionPropertyPath, string originalIdPropertyName, string alias1, string alias2) { addRevisionRestriction(parameters, revisionProperty, revisionEndProperty, addAlias, true); }
public void AddAssociationAtRevisionRestriction(QueryBuilder rootQueryBuilder, Parameters parameters, string revisionProperty, string revisionEndProperty, bool addAlias, MiddleIdData referencingIdData, string versionsMiddleEntityName, string eeOriginalIdPropertyPath, string revisionPropertyPath, string originalIdPropertyName, string alias1, bool inclusive, params MiddleComponentData[] componentDatas) { addRevisionRestriction(parameters, revisionProperty, revisionEndProperty, addAlias, inclusive); }
public void AddRelation(MiddleIdData idData) { _idDatas.Add(idData); }