/// <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);
        }
Пример #6
0
        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);
        }
Пример #8
0
 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);
        }
Пример #11
0
        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>();
        }
Пример #13
0
        /**
         *
         * @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();
                }
            }
        }
Пример #14
0
        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));
        }
Пример #23
0
        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);
        }
Пример #25
0
        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);
        }
Пример #26
0
        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);
        }
Пример #27
0
        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;
 }
Пример #29
0
        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);
        }
Пример #31
0
        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);
        }
Пример #32
0
 public MiddleRelatedComponentMapper(MiddleIdData relatedIdData)
 {
     this.relatedIdData = relatedIdData;
 }
 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);
 }