private void GenerateBidirectionalCollectionChangeWorkUnits(AuditSync verSync, AbstractCollectionEvent evt, PersistentCollectionChangeWorkUnit workUnit, RelationDescription rd) { // Checking if this is enabled in configuration ... if (!verCfg.GlobalCfg.isGenerateRevisionsForCollections()) { return; } // Checking if this is not a bidirectional relation - then, a revision needs also be generated for // the other side of the relation. // relDesc can be null if this is a collection of simple values (not a relation). if (rd != null && rd.Bidirectional) { String relatedEntityName = rd.ToEntityName; IIdMapper relatedIdMapper = verCfg.EntCfg[relatedEntityName].GetIdMapper(); foreach (PersistentCollectionChangeData changeData in workUnit.getCollectionChanges()) { Object relatedObj = changeData.GetChangedElement(); object relatedId = relatedIdMapper.MapToIdFromEntity(relatedObj); verSync.AddWorkUnit(new CollectionChangeWorkUnit(evt.Session, relatedEntityName, verCfg, relatedId, relatedObj)); } } }
public FakeRelationChange(object owningEntity, RelationDescription rd, RevisionType revisionType, object index) { this.owningEntity = owningEntity; this.rd = rd; this.revisionType = revisionType; this.index = index; }
//private OrmObjectsDef GetSearchScope(string name, out string localName) //{ // return GetSearchScope(name, out localName, false); //} //internal OrmObjectsDef GetSearchScope(string name, out string localName, bool throwNotFondException) //{ // Match nameMatch = GetNsNameMatch(name); // OrmObjectsDef searchScope = this; // if(nameMatch.Success) // { // if(nameMatch.Groups["prefix"].Success) // { // string prefix = nameMatch.Groups["prefix"].Value; // ImportDescription import = Includes[prefix]; // if(import == null) // if(throwNotFondException) // throw new KeyNotFoundException(string.Format("Import with prefix '{0}' not found.", prefix)); // else // { // localName = null; // return null; // } // searchScope = import.Content; // } // localName = nameMatch.Groups["name"].Value; // } // else // { // localName = name; // } // return searchScope; //} //internal static Match GetNsNameMatch(string name) //{ // Regex regex = new Regex(@"^(?:(?'prefix'[\w]{1,}):){0,1}(?'name'[\w\d-_.]+){1}$"); // return regex.Match(name); //} public RelationDescription GetSimilarRelation(RelationDescription relation) { return(_relations.Find(delegate(RelationDescription match) { return RelationDescription.IsSimilar(relation, match); })); }
public void AddToQuery(AuditConfiguration auditCfg, String entityName, QueryBuilder qb, Parameters parameters) { String propertyName = propertyNameGetter.Get(auditCfg); RelationDescription relatedEntity = CriteriaTools.GetRelatedEntity(auditCfg, entityName, propertyName); if (relatedEntity == null) { parameters.AddWhereWithParam(propertyName, "=", null); } else { relatedEntity.IdMapper.AddIdEqualsToQuery(parameters, null, propertyName, true); } }
public FakeBidirectionalRelationWorkUnit(ISessionImplementor sessionImplementor, String entityName, AuditConfiguration verCfg, Object id, String referencingPropertyName, Object owningEntity, RelationDescription rd, RevisionType revisionType, Object index, IAuditWorkUnit nestedWorkUnit) : base(sessionImplementor, entityName, verCfg, id) { this.nestedWorkUnit = nestedWorkUnit; // Adding the change for the relation. fakeRelationChanges = new Dictionary <String, FakeRelationChange>(); fakeRelationChanges.Add(referencingPropertyName, new FakeRelationChange(owningEntity, rd, revisionType, index)); }
public void AddToQuery(AuditConfiguration auditCfg, String entityName, QueryBuilder qb, Parameters parameters) { String propertyName = propertyNameGetter.Get(auditCfg); RelationDescription relatedEntity = CriteriaTools.GetRelatedEntity(auditCfg, entityName, propertyName); if (relatedEntity == null) { throw new AuditException("This criterion can only be used on a property that is " + "a relation to another property."); } else { relatedEntity.IdMapper.AddIdEqualsToQuery(parameters, id, propertyName, equals); } }
public static RelationDescription GetRelatedEntity(AuditConfiguration verCfg, String entityName, String propertyName) { RelationDescription relationDesc = verCfg.EntCfg.GetRelationDescription(entityName, propertyName); if (relationDesc == null) { return(null); } if (relationDesc.RelationType == RelationType.TO_ONE) { return(relationDesc); } throw new AuditException("This type of relation (" + entityName + "." + propertyName + ") isn't supported and can't be used in queries."); }
private void generateFakeBidirecationalRelationWorkUnits(AuditProcess auditProcess, IPersistentCollection newColl, object oldColl, string collectionEntityName, string referencingPropertyName, AbstractCollectionEvent evt, RelationDescription rd) { // First computing the relation changes var collectionChanges = VerCfg.EntCfg[collectionEntityName].PropertyMapper .MapCollectionChanges(evt.Session, referencingPropertyName, newColl, oldColl, evt.AffectedOwnerIdOrNull); // Getting the id mapper for the related entity, as the work units generated will corrspond to the related // entities. var relatedEntityName = rd.ToEntityName; var relatedIdMapper = VerCfg.EntCfg[relatedEntityName].IdMapper; // For each collection change, generating the bidirectional work unit. foreach (var changeData in collectionChanges) { var relatedObj = changeData.GetChangedElement(); var relatedId = relatedIdMapper.MapToIdFromEntity(relatedObj); var revType = (RevisionType)changeData.Data[VerCfg.AuditEntCfg.RevisionTypePropName]; // This can be different from relatedEntityName, in case of inheritance (the real entity may be a subclass // of relatedEntityName). var realRelatedEntityName = evt.Session.BestGuessEntityName(relatedObj); // By default, the nested work unit is a collection change work unit. var nestedWorkUnit = new CollectionChangeWorkUnit(evt.Session, realRelatedEntityName, rd.MappedByPropertyName, VerCfg, relatedId, relatedObj); auditProcess.AddWorkUnit(new FakeBidirectionalRelationWorkUnit(evt.Session, realRelatedEntityName, VerCfg, relatedId, referencingPropertyName, evt.AffectedOwnerOrNull, rd, revType, changeData.GetChangedElementIndex(), nestedWorkUnit)); } // We also have to generate a collection change work unit for the owning entity. auditProcess.AddWorkUnit(new CollectionChangeWorkUnit(evt.Session, collectionEntityName, referencingPropertyName, VerCfg, evt.AffectedOwnerIdOrNull, evt.AffectedOwnerOrNull)); }
private void OnCollectionAction(AbstractCollectionEvent evt, IPersistentCollection newColl, object oldColl, CollectionEntry collectionEntry) { String entityName = evt.GetAffectedOwnerEntityName(); if (verCfg.EntCfg.IsVersioned(entityName)) { AuditSync verSync = verCfg.AuditSyncManager.get(evt.Session); String ownerEntityName = ((AbstractCollectionPersister)collectionEntry.LoadedPersister).OwnerEntityName; String referencingPropertyName = collectionEntry.Role.Substring(ownerEntityName.Length + 1); // Checking if this is not a "fake" many-to-one bidirectional relation. The relation description may be // null in case of collections of non-entities. RelationDescription rd = verCfg.EntCfg[entityName].GetRelationDescription(referencingPropertyName); if (rd != null && rd.MappedByPropertyName != null) { GenerateFakeBidirecationalRelationWorkUnits(verSync, newColl, oldColl, entityName, referencingPropertyName, evt, rd); } else { PersistentCollectionChangeWorkUnit workUnit = new PersistentCollectionChangeWorkUnit(evt.Session, entityName, verCfg, newColl, collectionEntry, oldColl, evt.AffectedOwnerIdOrNull, referencingPropertyName); verSync.AddWorkUnit(workUnit); if (workUnit.ContainsWork()) { // There are some changes: a revision needs also be generated for the collection owner verSync.AddWorkUnit(new CollectionChangeWorkUnit(evt.Session, evt.GetAffectedOwnerEntityName(), verCfg, evt.AffectedOwnerIdOrNull, evt.AffectedOwnerOrNull)); GenerateBidirectionalCollectionChangeWorkUnits(verSync, evt, workUnit, rd); } } } }
public void AddToQuery(AuditConfiguration auditCfg, String entityName, QueryBuilder qb, Parameters parameters) { String propertyName = propertyNameGetter.Get(auditCfg); RelationDescription relatedEntity = CriteriaTools.GetRelatedEntity(auditCfg, entityName, propertyName); if (relatedEntity == null) { parameters.AddWhereWithParam(propertyName, op, value); } else { if (!"=".Equals(op) && !"<>".Equals(op)) { throw new AuditException("This type of operation: " + op + " (" + entityName + "." + propertyName + ") isn't supported and can't be used in queries."); } Object id = relatedEntity.IdMapper.MapToIdFromEntity(value); relatedEntity.IdMapper.AddIdEqualsToQuery(parameters, id, propertyName, "=".Equals(op)); } }
private void generateBidirectionalCollectionChangeWorkUnits(AuditProcess auditProcess, AbstractCollectionEvent evt, PersistentCollectionChangeWorkUnit workUnit, RelationDescription rd) { // Checking if this is enabled in configuration ... if (!VerCfg.GlobalCfg.GenerateRevisionsForCollections) { return; } // Checking if this is not a bidirectional relation - then, a revision needs also be generated for // the other side of the relation. // relDesc can be null if this is a collection of simple values (not a relation). if (rd != null && rd.Bidirectional) { var relatedEntityName = rd.ToEntityName; var relatedIdMapper = VerCfg.EntCfg[relatedEntityName].IdMapper; foreach (var changeData in workUnit.CollectionChanges) { var relatedObj = changeData.GetChangedElement(); var relatedId = relatedIdMapper.MapToIdFromEntity(relatedObj); var toPropertyNames = VerCfg.EntCfg.ToPropertyNames(evt.GetAffectedOwnerEntityName(), rd.FromPropertyName, relatedEntityName); var toPropertyName = toPropertyNames.First(); auditProcess.AddWorkUnit(new CollectionChangeWorkUnit(evt.Session, evt.Session.BestGuessEntityName(relatedObj), toPropertyName, VerCfg, relatedId, relatedObj)); } } }
private void addCollectionChangeWorkUnit(AuditProcess auditProcess, ISessionImplementor session, string fromEntityName, RelationDescription relDesc, object value) { // relDesc.getToEntityName() doesn't always return the entity name of the value - in case // of subclasses, this will be root class, no the actual class. So it can't be used here. string toEntityName; object id; if (value is INHibernateProxy newValueAsProxy) { toEntityName = session.BestGuessEntityName(value); id = newValueAsProxy.HibernateLazyInitializer.Identifier; // We've got to initialize the object from the proxy to later read its state. value = Toolz.GetTargetFromProxy(session, newValueAsProxy); } else { toEntityName = session.GuessEntityName(value); var idMapper = VerCfg.EntCfg[toEntityName].IdMapper; id = idMapper.MapToIdFromEntity(value); } var toPropertyNames = VerCfg.EntCfg.ToPropertyNames(fromEntityName, relDesc.FromPropertyName, toEntityName); var toPropertyName = toPropertyNames.First(); auditProcess.AddWorkUnit(new CollectionChangeWorkUnit(session, toEntityName, toPropertyName, VerCfg, id, value)); }
private void GenerateBidirectionalCollectionChangeWorkUnits(AuditSync verSync, IEntityPersister entityPersister, String entityName, Object[] newState, Object[] oldState, ISessionImplementor session) { // Checking if this is enabled in configuration ... if (!verCfg.GlobalCfg.isGenerateRevisionsForCollections()) { return; } // Checks every property of the entity, if it is an "owned" to-one relation to another entity. // If the value of that property changed, and the relation is bi-directional, a new revision // for the related entity is generated. String[] propertyNames = entityPersister.PropertyNames; for (int i = 0; i < propertyNames.GetLength(0); i++) { String propertyName = propertyNames[i]; RelationDescription relDesc = verCfg.EntCfg.GetRelationDescription(entityName, propertyName); if (relDesc != null && relDesc.Bidirectional && relDesc.RelationType == RelationType.TO_ONE && relDesc.Insertable) { // Checking for changes Object oldValue = oldState == null ? null : oldState[i]; Object newValue = newState == null ? null : newState[i]; if (!Toolz.EntitiesEqual(session, oldValue, newValue)) { // We have to generate changes both in the old collection (size decreses) and new collection // (size increases). //<TODO Simon: doua if-uri cu cod duplicat, refact. if (newValue != null) { // relDesc.getToEntityName() doesn't always return the entity name of the value - in case // of subclasses, this will be root class, no the actual class. So it can't be used here. String toEntityName; // Java: Serializable id object id; if (newValue is INHibernateProxy) { INHibernateProxy hibernateProxy = (INHibernateProxy)newValue; toEntityName = session.BestGuessEntityName(newValue); id = hibernateProxy.HibernateLazyInitializer.Identifier; // We've got to initialize the object from the proxy to later read its state. newValue = NHibernate.Envers.Tools.Toolz.GetTargetFromProxy(session.Factory, hibernateProxy); } else { toEntityName = session.GuessEntityName(newValue); IIdMapper idMapper = verCfg.EntCfg[toEntityName].GetIdMapper(); id = idMapper.MapToIdFromEntity(newValue); } verSync.AddWorkUnit(new CollectionChangeWorkUnit(session, toEntityName, verCfg, id, newValue)); } if (oldValue != null) { String toEntityName; object id; if (oldValue is INHibernateProxy) { INHibernateProxy hibernateProxy = (INHibernateProxy)oldValue; toEntityName = session.BestGuessEntityName(oldValue); id = hibernateProxy.HibernateLazyInitializer.Identifier; // We've got to initialize the object as we'll read it's state anyway. oldValue = Toolz.GetTargetFromProxy(session.Factory, hibernateProxy); } else { toEntityName = session.GuessEntityName(oldValue); IIdMapper idMapper = verCfg.EntCfg[toEntityName].GetIdMapper(); id = idMapper.MapToIdFromEntity(oldValue); } verSync.AddWorkUnit(new CollectionChangeWorkUnit(session, toEntityName, verCfg, id, oldValue)); } } } } }
protected void ProcessM2M(Dictionary <Column, Column> columns, OrmObjectsDef odef) { List <Pair <string> > tables = new List <Pair <string> >(); using (DbConnection conn = GetDBConn(_server, _m, _db, _i, _user, _psw)) { using (DbCommand cmd = conn.CreateCommand()) { cmd.CommandType = CommandType.Text; cmd.CommandText = @"select table_schema,table_name from INFORMATION_SCHEMA.TABLE_CONSTRAINTS where constraint_type = 'FOREIGN KEY' group by table_schema,table_name having count(*) = 2" ; conn.Open(); using (DbDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { tables.Add(new Pair <string>(reader.GetString(reader.GetOrdinal("table_schema")), reader.GetString(reader.GetOrdinal("table_name")))); } } } } foreach (Pair <string> p in tables) { string underlying = GetEntityName(p.First, p.Second); EntityDescription ued = odef.GetEntity(underlying); using (DbConnection conn = GetDBConn(_server, _m, _db, _i, _user, _psw)) { using (DbCommand cmd = conn.CreateCommand()) { cmd.CommandType = CommandType.Text; cmd.CommandText = @"select cc.table_schema,cc.table_name,cc2.column_name,rc.delete_rule from INFORMATION_SCHEMA.constraint_column_usage cc join INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc on rc.unique_constraint_name = cc.constraint_name join INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc on tc.constraint_name = rc.constraint_name join INFORMATION_SCHEMA.constraint_column_usage cc2 on cc2.constraint_name = tc.constraint_name and cc2.table_schema = tc.table_schema and cc2.table_name = tc.table_name where tc.table_name = @tbl and tc.table_schema = @schema and tc.constraint_type = 'FOREIGN KEY'" ; DbParameter tbl = cmd.CreateParameter(); tbl.ParameterName = "tbl"; tbl.Value = p.Second; cmd.Parameters.Add(tbl); DbParameter schema = cmd.CreateParameter(); schema.ParameterName = "schema"; schema.Value = p.First; cmd.Parameters.Add(schema); conn.Open(); List <LinkTarget> targets = new List <LinkTarget>(); using (DbDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { //string ename = reader.GetString(reader.GetOrdinal("table_schema")) + "." + // reader.GetString(reader.GetOrdinal("table_name")); bool deleteCascade = false; switch (reader.GetString(reader.GetOrdinal("delete_rule"))) { case "NO ACTION": break; case "CASCADE": deleteCascade = true; break; default: throw new NotSupportedException("Cascade " + reader.GetString(reader.GetOrdinal("delete_rule")) + " is not supported"); } bool c; LinkTarget lt = new LinkTarget( GetEntity(odef, reader.GetString(reader.GetOrdinal("table_schema")), reader.GetString(reader.GetOrdinal("table_name")), out c), reader.GetString(reader.GetOrdinal("column_name")), deleteCascade); targets.Add(lt); } } RelationDescription rd = odef.GetSimilarRelation( new RelationDescription(targets[0], targets[1], null, null)); if (rd == null) { rd = new RelationDescription(targets[0], targets[1], GetTable(odef, p.First, p.Second), ued); odef.Relations.Add(rd); } } } } }
internal protected void FillRelations() { XmlNodeList relationNodes; #region Relations relationNodes = _ormXmlDocument.DocumentElement.SelectNodes(string.Format("{0}:EntityRelations/{0}:Relation", OrmObjectsDef.NS_PREFIX), _nsMgr); foreach (XmlNode relationNode in relationNodes) { XmlNode leftTargetNode = relationNode.SelectSingleNode(string.Format("{0}:Left", OrmObjectsDef.NS_PREFIX), _nsMgr); XmlNode rightTargetNode = relationNode.SelectSingleNode(string.Format("{0}:Right", OrmObjectsDef.NS_PREFIX), _nsMgr); XmlElement relationElement = (XmlElement)relationNode; string relationTableId = relationElement.GetAttribute("table"); string underlyingEntityId = relationElement.GetAttribute("underlyingEntity"); string disabledValue = relationElement.GetAttribute("disabled"); XmlElement leftTargetElement = (XmlElement)leftTargetNode; string leftLinkTargetEntityId = leftTargetElement.GetAttribute("entity"); XmlElement rightTargetElement = (XmlElement)rightTargetNode; string rightLinkTargetEntityId = rightTargetElement.GetAttribute("entity"); string leftFieldName = leftTargetElement.GetAttribute("fieldName"); string rightFieldName = rightTargetElement.GetAttribute("fieldName"); bool leftCascadeDelete = XmlConvert.ToBoolean(leftTargetElement.GetAttribute("cascadeDelete")); bool rightCascadeDelete = XmlConvert.ToBoolean(rightTargetElement.GetAttribute("cascadeDelete")); TableDescription relationTable = _ormObjectsDef.GetTable(relationTableId); EntityDescription underlyingEntity; if (string.IsNullOrEmpty(underlyingEntityId)) { underlyingEntity = null; } else { underlyingEntity = _ormObjectsDef.GetEntity(underlyingEntityId); } bool disabled; if (string.IsNullOrEmpty(disabledValue)) { disabled = false; } else { disabled = XmlConvert.ToBoolean(disabledValue); } EntityDescription leftLinkTargetEntity = _ormObjectsDef.GetEntity(leftLinkTargetEntityId); EntityDescription rightLinkTargetEntity = _ormObjectsDef.GetEntity(rightLinkTargetEntityId); LinkTarget leftLinkTarget = new LinkTarget(leftLinkTargetEntity, leftFieldName, leftCascadeDelete); LinkTarget rightLinkTarget = new LinkTarget(rightLinkTargetEntity, rightFieldName, rightCascadeDelete); RelationDescription relation = new RelationDescription(leftLinkTarget, rightLinkTarget, relationTable, underlyingEntity, disabled); _ormObjectsDef.Relations.Add(relation); } #endregion #region Relations relationNodes = _ormXmlDocument.DocumentElement.SelectNodes(string.Format("{0}:EntityRelations/{0}:SelfRelation", OrmObjectsDef.NS_PREFIX), _nsMgr); foreach (XmlNode relationNode in relationNodes) { XmlNode directTargetNode = relationNode.SelectSingleNode(string.Format("{0}:Direct", OrmObjectsDef.NS_PREFIX), _nsMgr); XmlNode reverseTargetNode = relationNode.SelectSingleNode(string.Format("{0}:Reverse", OrmObjectsDef.NS_PREFIX), _nsMgr); XmlElement relationElement = (XmlElement)relationNode; string relationTableId = relationElement.GetAttribute("table"); string underlyingEntityId = relationElement.GetAttribute("underlyingEntity"); string disabledValue = relationElement.GetAttribute("disabled"); string entityId = relationElement.GetAttribute("entity"); XmlElement directTargetElement = (XmlElement)directTargetNode; XmlElement reverseTargetElement = (XmlElement)reverseTargetNode; string directFieldName = directTargetElement.GetAttribute("fieldName"); string reverseFieldName = reverseTargetElement.GetAttribute("fieldName"); bool directCascadeDelete = XmlConvert.ToBoolean(directTargetElement.GetAttribute("cascadeDelete")); bool reverseCascadeDelete = XmlConvert.ToBoolean(reverseTargetElement.GetAttribute("cascadeDelete")); TableDescription relationTable = _ormObjectsDef.GetTable(relationTableId); EntityDescription underlyingEntity; if (string.IsNullOrEmpty(underlyingEntityId)) { underlyingEntity = null; } else { underlyingEntity = _ormObjectsDef.GetEntity(underlyingEntityId); } bool disabled; if (string.IsNullOrEmpty(disabledValue)) { disabled = false; } else { disabled = XmlConvert.ToBoolean(disabledValue); } EntityDescription entity = _ormObjectsDef.GetEntity(entityId); SelfRelationTarget directTarget = new SelfRelationTarget(directFieldName, directCascadeDelete); SelfRelationTarget reverseTarget = new SelfRelationTarget(reverseFieldName, reverseCascadeDelete); SelfRelationDescription relation = new SelfRelationDescription(entity, directTarget, reverseTarget, relationTable, underlyingEntity, disabled); _ormObjectsDef.SelfRelations.Add(relation); } #endregion }