/// <summary>
		/// Initializes a new instance of <see cref="ScheduledCollectionUpdate"/>.
		/// </summary>
		/// <param name="collection">The <see cref="IPersistentCollection"/> to update.</param>
		/// <param name="persister">The <see cref="ICollectionPersister"/> that is responsible for the persisting the Collection.</param>
		/// <param name="id">The identifier of the Collection owner.</param>
		/// <param name="emptySnapshot">Indicates if the Collection was empty when it was loaded.</param>
		/// <param name="session">The <see cref="ISessionImplementor"/> that the Action is occuring in.</param>
		public ScheduledCollectionUpdate(IPersistentCollection collection, ICollectionPersister persister, object id,
		                                 bool emptySnapshot, ISessionImplementor session)
			: base(persister, id, session)
		{
			_collection = collection;
			_emptySnapshot = emptySnapshot;
		}
Example #2
0
        public static IPersistentCollection Conj(IPersistentCollection collection, object obj)
        {
            if (collection == null)
                return new PersistentList(obj);

            return collection.Cons(obj);
        }
Example #3
0
        /// <summary> 
        /// Initialize the role of the collection. 
        /// </summary>
        /// <param name="collection">The collection to be updated by reachibility. </param>
        /// <param name="type">The type of the collection. </param>
        /// <param name="entity">The owner of the collection. </param>
        /// <param name="session">The session.</param>
        public static void ProcessReachableCollection(IPersistentCollection collection, CollectionType type, object entity, ISessionImplementor session)
        {
            collection.Owner = entity;
            CollectionEntry ce = session.PersistenceContext.GetCollectionEntry(collection);

            if (ce == null)
            {
                // refer to comment in StatefulPersistenceContext.addCollection()
                throw new HibernateException(string.Format("Found two representations of same collection: {0}", type.Role));
            }

            // The CollectionEntry.isReached() stuff is just to detect any silly users
            // who set up circular or shared references between/to collections.
            if (ce.IsReached)
            {
                // We've been here before
                throw new HibernateException(string.Format("Found shared references to a collection: {0}", type.Role));
            }
            ce.IsReached = true;

            ISessionFactoryImplementor factory = session.Factory;
            ICollectionPersister persister = factory.GetCollectionPersister(type.Role);
            ce.CurrentPersister = persister;
            ce.CurrentKey = type.GetKeyOfOwner(entity, session); //TODO: better to pass the id in as an argument?

            if (log.IsDebugEnabled)
            {
                log.Debug("Collection found: " +
                    MessageHelper.InfoString(persister, ce.CurrentKey, factory) + ", was: " +
                    MessageHelper.InfoString(ce.LoadedPersister, ce.LoadedKey, factory) +
                    (collection.WasInitialized ? " (initialized)" : " (uninitialized)"));
            }

            PrepareCollectionForUpdate(collection, ce);
        }
Example #4
0
 public CollectionUpdateAction(
     IPersistentCollection collection, ICollectionPersister persister,
     object key, bool emptySnapshot, ISessionImplementor session)
     : base(persister, collection, key, session)
 {
     this.emptySnapshot = emptySnapshot;
 }
 public IList<PersistentCollectionChangeData> MapCollectionChanges(String referencingPropertyName,
     IPersistentCollection newColl,
     object oldColl,
     object id)
 {
     return null;
 }
Example #6
0
		public LoadingCollectionEntry(IDataReader resultSet, ICollectionPersister persister, object key, IPersistentCollection collection)
		{
			this.resultSet = resultSet;
			this.persister = persister;
			this.key = key;
			this.collection = collection;
		}
        public IList<PersistentCollectionChangeData> MapCollectionChanges(string referencingPropertyName,
																		IPersistentCollection newColl,
																		object oldColl,
																		object id)
        {
            return _delegate.MapCollectionChanges(referencingPropertyName, newColl, oldColl, id);
        }
		/// <summary> Try to initialize a collection from the cache</summary>
		private bool InitializeCollectionFromCache(object id, ICollectionPersister persister, IPersistentCollection collection, ISessionImplementor source)
		{

			if (!(source.EnabledFilters.Count == 0) && persister.IsAffectedByEnabledFilters(source))
			{
				log.Debug("disregarding cached version (if any) of collection due to enabled filters ");
				return false;
			}

			bool useCache = persister.HasCache && ((source.CacheMode & CacheMode.Get) == CacheMode.Get);

			if (!useCache)
			{
				return false;
			}
			else
			{
				ISessionFactoryImplementor factory = source.Factory;

				CacheKey ck = new CacheKey(id, persister.KeyType, persister.Role, source.EntityMode, factory);
				object ce = persister.Cache.Get(ck, source.Timestamp);

				if (factory.Statistics.IsStatisticsEnabled)
				{
					if (ce == null)
					{
						factory.StatisticsImplementor.SecondLevelCacheMiss(persister.Cache.RegionName);
					}
					else
					{
						factory.StatisticsImplementor.SecondLevelCacheHit(persister.Cache.RegionName);
					}
				}

				if (ce == null)
				{
					log.DebugFormat("Collection cache miss: {0}", ck);
				}
				else
				{
					log.DebugFormat("Collection cache hit: {0}", ck);
				}

				if (ce == null)
				{
					return false;
				}
				else
				{
					IPersistenceContext persistenceContext = source.PersistenceContext;

					CollectionCacheEntry cacheEntry = (CollectionCacheEntry)persister.CacheEntryStructure.Destructure(ce, factory);
					cacheEntry.Assemble(collection, persister, persistenceContext.GetCollectionOwner(id, persister));

					persistenceContext.GetCollectionEntry(collection).PostInitialize(collection);
					return true;
				}
			}
		}
		/// <summary> Constructs an AbstractCollectionEvent object. </summary>
		/// <param name="collectionPersister">The collection persister.</param>
		/// <param name="collection">The collection </param>
		/// <param name="source">The Session source </param>
		/// <param name="affectedOwner">The owner that is affected by this event; can be null if unavailable </param>
		/// <param name="affectedOwnerId">
		/// The ID for the owner that is affected by this event; can be null if unavailable
		/// that is affected by this event; can be null if unavailable
		/// </param>
		protected AbstractCollectionEvent(ICollectionPersister collectionPersister, IPersistentCollection collection,
		                               IEventSource source, object affectedOwner, object affectedOwnerId) : base(source)
		{
			this.collection = collection;
			this.affectedOwner = affectedOwner;
			this.affectedOwnerId = affectedOwnerId;
			affectedOwnerEntityName = GetAffectedOwnerEntityName(collectionPersister, affectedOwner, source);
		}
Example #10
0
		/// <summary> 
		/// Record the fact that this collection was dereferenced 
		/// </summary>
		/// <param name="coll">The collection to be updated by unreachability. </param>
		/// <param name="session">The session.</param>
		public static void ProcessUnreachableCollection(IPersistentCollection coll, ISessionImplementor session)
		{
			if (coll.Owner == null)
			{
				ProcessNeverReferencedCollection(coll, session);
			}
			else
			{
				ProcessDereferencedCollection(coll, session);
			}
		}
Example #11
0
		private static void ProcessNeverReferencedCollection(IPersistentCollection coll, ISessionImplementor session)
		{
			CollectionEntry entry = session.PersistenceContext.GetCollectionEntry(coll);

			log.Debug("Found collection with unloaded owner: " + MessageHelper.InfoString(entry.LoadedPersister, entry.LoadedKey, session.Factory));

			entry.CurrentPersister = entry.LoadedPersister;
			entry.CurrentKey = entry.LoadedKey;

			PrepareCollectionForUpdate(coll, entry);
		}
        public PersistentCollectionChangeWorkUnit(ISessionImplementor sessionImplementor, String entityName,
            AuditConfiguration auditCfg, IPersistentCollection collection,
            CollectionEntry collectionEntry, Object snapshot, Object id,
            String referencingPropertyName)
            : base(sessionImplementor, entityName, auditCfg, 
                    new PersistentCollectionChangeWorkUnitId(id, collectionEntry.Role))
        {
            this.ReferencingPropertyName = referencingPropertyName;

            collectionChanges = auditCfg.EntCfg[EntityName].PropertyMapper
                    .MapCollectionChanges(referencingPropertyName, collection, snapshot, id);
        }
Example #13
0
		private void EvictCollection(IPersistentCollection collection)
		{
			CollectionEntry ce = (CollectionEntry)Session.PersistenceContext.CollectionEntries[collection];
			Session.PersistenceContext.CollectionEntries.Remove(collection);
			if (log.IsDebugEnabled)
				log.Debug("evicting collection: " + MessageHelper.InfoString(ce.LoadedPersister, ce.LoadedKey, Session.Factory));
			if (ce.LoadedPersister != null && ce.LoadedKey != null)
			{
				//TODO: is this 100% correct?
				Session.PersistenceContext.CollectionsByKey.Remove(new CollectionKey(ce.LoadedPersister, ce.LoadedKey, Session.EntityMode));
			}
		}
		/// <summary> 
		/// Removes a persistent collection from its loaded owner. 
		/// </summary>
		/// <param name="collection">The collection to to remove; must be non-null </param>
		/// <param name="persister"> The collection's persister </param>
		/// <param name="id">The collection key </param>
		/// <param name="emptySnapshot">Indicates if the snapshot is empty </param>
		/// <param name="session">The session </param>
		/// <remarks>Use this constructor when the collection is non-null.</remarks>
		public CollectionRemoveAction(IPersistentCollection collection, ICollectionPersister persister, object id,
		                              bool emptySnapshot, ISessionImplementor session)
			: base(persister, collection, id, session)
		{
			if (collection == null)
			{
				throw new AssertionFailure("collection == null");
			}

			this.emptySnapshot = emptySnapshot;
			affectedOwner = session.PersistenceContext.GetLoadedCollectionOwnerOrNull(collection);
		}
		private static void ProcessDereferencedCollection(IPersistentCollection coll, ISessionImplementor session)
		{
			IPersistenceContext persistenceContext = session.PersistenceContext;
			CollectionEntry entry = persistenceContext.GetCollectionEntry(coll);
			ICollectionPersister loadedPersister = entry.LoadedPersister;

			if (log.IsDebugEnabled && loadedPersister != null)
				log.Debug("Collection dereferenced: " + MessageHelper.InfoString(loadedPersister, entry.LoadedKey, session.Factory));

			// do a check
			bool hasOrphanDelete = loadedPersister != null && loadedPersister.HasOrphanDelete;
			if (hasOrphanDelete)
			{
				object ownerId = loadedPersister.OwnerEntityPersister.GetIdentifier(coll.Owner, session.EntityMode);
				// TODO NH Different behavior
				//if (ownerId == null)
				//{
				//  // the owning entity may have been deleted and its identifier unset due to
				//  // identifier-rollback; in which case, try to look up its identifier from
				//  // the persistence context
				//  if (session.Factory.Settings.IsIdentifierRollbackEnabled)
				//  {
				//    EntityEntry ownerEntry = persistenceContext.GetEntry(coll.Owner);
				//    if (ownerEntry != null)
				//    {
				//      ownerId = ownerEntry.Id;
				//    }
				//  }
				//  if (ownerId == null)
				//  {
				//    throw new AssertionFailure("Unable to determine collection owner identifier for orphan-delete processing");
				//  }
				//}
				EntityKey key = new EntityKey(ownerId, loadedPersister.OwnerEntityPersister, session.EntityMode);
				object owner = persistenceContext.GetEntity(key);
				if (owner == null)
				{
					throw new AssertionFailure("collection owner not associated with session: " + loadedPersister.Role);
				}
				EntityEntry e = persistenceContext.GetEntry(owner);
				//only collections belonging to deleted entities are allowed to be dereferenced in the case of orphan delete
				if (e != null && e.Status != Status.Deleted && e.Status != Status.Gone)
				{
					throw new HibernateException("A collection with cascade=\"all-delete-orphan\" was no longer referenced by the owning entity instance: " + loadedPersister.Role);
				}
			}

			// do the work
			entry.CurrentPersister = null;
			entry.CurrentKey = null;
			PrepareCollectionForUpdate(coll, entry, session.EntityMode, session.Factory);
		}
        public MonthlyLogFilesHeuristics([NotNull] IPersistentCollection heuristicsPersistentCollection,
            IWurmLogFiles wurmLogFiles,
            MonthlyHeuristicsExtractorFactory monthlyHeuristicsExtractorFactory)
        {
            if (heuristicsPersistentCollection == null)
                throw new ArgumentNullException("heuristicsPersistentCollection");
            if (wurmLogFiles == null) throw new ArgumentNullException("wurmLogFiles");
            if (monthlyHeuristicsExtractorFactory == null) throw new ArgumentNullException("monthlyHeuristicsExtractorFactory");

            this.heuristicsPersistentCollection = heuristicsPersistentCollection;
            this.wurmLogFiles = wurmLogFiles;
            this.monthlyHeuristicsExtractorFactory = monthlyHeuristicsExtractorFactory;
        }
Example #17
0
        /// <summary> 
        /// Reattach a detached (disassociated) initialized or uninitialized
        /// collection wrapper, using a snapshot carried with the collection wrapper
        /// </summary>
        protected internal void ReattachCollection(IPersistentCollection collection, ICollectionSnapshot snapshot)
        {
            if (collection.WasInitialized)
            {
                Session.PersistenceContext.AddInitializedDetachedCollection(collection, snapshot);
            }
            else
            {
                if (!IsCollectionSnapshotValid(snapshot))
                    throw new HibernateException("could not reassociate uninitialized transient collection");

                Session.PersistenceContext.AddUninitializedDetachedCollection(collection, snapshot);
            }
        }
Example #18
0
        //1. record the collection role that this collection is referenced by
        //2. decide if the collection needs deleting/creating/updating (but don't actually schedule the action yet)
        private static void PrepareCollectionForUpdate(IPersistentCollection coll, CollectionEntry entry)
        {
            if (entry.IsProcessed)
                throw new AssertionFailure("collection was processed twice by flush()");

            entry.IsProcessed = true;

            ICollectionPersister loadedPersister = entry.LoadedPersister;
            ICollectionPersister currentPersister = entry.CurrentPersister;
            if (loadedPersister != null || currentPersister != null)
            {
                // it is or was referenced _somewhere_
                bool ownerChanged = loadedPersister != currentPersister ||
                    !currentPersister.KeyType.IsEqual(entry.LoadedKey, entry.CurrentKey, EntityMode.Poco);

                if (ownerChanged)
                {
                    // do a check
                    bool orphanDeleteAndRoleChanged = loadedPersister != null &&
                        currentPersister != null && loadedPersister.HasOrphanDelete;

                    if (orphanDeleteAndRoleChanged)
                    {
                        throw new HibernateException("Don't change the reference to a collection with cascade=\"all-delete-orphan\": " + loadedPersister.Role);
                    }

                    // do the work
                    if (currentPersister != null)
                    {
                        entry.IsDorecreate = true; // we will need to create new entries
                    }

                    if (loadedPersister != null)
                    {
                        entry.IsDoremove = true; // we will need to remove ye olde entries
                        if (entry.IsDorecreate)
                        {
                            log.Debug("Forcing collection initialization");
                            coll.ForceInitialization(); // force initialize!
                        }
                    }
                }
                else if (coll.IsDirty)
                {
                    // else if it's elements changed
                    entry.IsDoupdate = true;
                }
            }
        }
		/// <summary> 
		/// Reattach a detached (disassociated) initialized or uninitialized
		/// collection wrapper, using a snapshot carried with the collection wrapper
		/// </summary>
		protected internal void ReattachCollection(IPersistentCollection collection, CollectionType type)
		{
			if (collection.WasInitialized)
			{
				ICollectionPersister collectionPersister = Session.Factory.GetCollectionPersister(type.Role);
				Session.PersistenceContext.AddInitializedDetachedCollection(collectionPersister, collection);
			}
			else
			{
				if (!IsCollectionSnapshotValid(collection))
				{
					throw new HibernateException("could not reassociate uninitialized transient collection");
				}
				ICollectionPersister collectionPersister = Session.Factory.GetCollectionPersister(collection.Role);
				Session.PersistenceContext.AddUninitializedDetachedCollection(collectionPersister, collection);
			}
		}
        public IList<PersistentCollectionChangeData> MapCollectionChanges(String referencingPropertyName,
            IPersistentCollection newColl,
            Object oldColl,
            Object id)
        {
            IList<PersistentCollectionChangeData> parentCollectionChanges = parentMapper.MapCollectionChanges(
                    referencingPropertyName, newColl, oldColl, id);

            IList<PersistentCollectionChangeData> mainCollectionChanges = main.MapCollectionChanges(
                    referencingPropertyName, newColl, oldColl, id);

            if (parentCollectionChanges == null) {
                return mainCollectionChanges;
            } else {
                if(mainCollectionChanges != null) {
                    parentCollectionChanges.Concat(mainCollectionChanges);
                }
                return parentCollectionChanges;
            }
        }
 public ServerHistoryProviderFactory(
     IPersistentCollection persistentCollection,
     IWurmLogsHistory wurmLogsHistory,
     IWurmServerList wurmServerList,
     ILogger logger,
     IWurmLogsMonitorInternal wurmLogsMonitor,
     IWurmLogFiles wurmLogFiles)
 {
     if (persistentCollection == null) throw new ArgumentNullException("persistentCollection");
     if (wurmLogsHistory == null) throw new ArgumentNullException("wurmLogsHistory");
     if (wurmServerList == null) throw new ArgumentNullException("wurmServerList");
     if (logger == null) throw new ArgumentNullException("logger");
     if (wurmLogsMonitor == null) throw new ArgumentNullException("wurmLogsMonitor");
     if (wurmLogFiles == null) throw new ArgumentNullException("wurmLogFiles");
     this.persistentCollection = persistentCollection;
     this.wurmLogsHistory = wurmLogsHistory;
     this.wurmServerList = wurmServerList;
     this.logger = logger;
     this.wurmLogsMonitor = wurmLogsMonitor;
     this.wurmLogFiles = wurmLogFiles;
 }
 public PostCollectionRemoveEvent(ICollectionPersister collectionPersister, IPersistentCollection collection,
                                  IEventSource source, object loadedOwner)
     : base(collectionPersister, collection, source, loadedOwner, GetOwnerIdOrNull(loadedOwner, source))
 {
 }
		/// <summary> Add an collection to the cache, with a given collection entry. </summary>
		/// <param name="coll">The collection for which we are adding an entry.</param>
		/// <param name="entry">The entry representing the collection. </param>
		/// <param name="key">The key of the collection's entry. </param>
		private void AddCollection(IPersistentCollection coll, CollectionEntry entry, object key)
		{
			collectionEntries[coll] = entry;
			CollectionKey collectionKey = new CollectionKey(entry.LoadedPersister, key, session.EntityMode);
			IPersistentCollection tempObject;
			collectionsByKey.TryGetValue(collectionKey, out tempObject);
			collectionsByKey[collectionKey] = coll;
			IPersistentCollection old = tempObject;
			if (old != null)
			{
				if (old == coll)
				{
					throw new AssertionFailure("bug adding collection twice");
				}
				// or should it actually throw an exception?
				old.UnsetSession(session);
				collectionEntries.Remove(old);
				// watch out for a case where old is still referenced
				// somewhere in the object graph! (which is a user error)
			}
		}
Example #24
0
 public void initializeCollection(IPersistentCollection collection, bool writing)
 {
     delegat.InitializeCollection(collection, writing);
 }
 public CollectionCacheEntry(IPersistentCollection collection, ICollectionPersister persister)
 {
     state = collection.Disassemble(persister);
 }
Example #26
0
        /// <summary> Try to initialize a collection from the cache</summary>
        private bool InitializeCollectionFromCache(
            object collectionKey, ICollectionPersister persister, IPersistentCollection collection,
            ISessionImplementor source)
        {
            if (!(source.EnabledFilters.Count == 0) && persister.IsAffectedByEnabledFilters(source))
            {
                log.Debug("disregarding cached version (if any) of collection due to enabled filters ");
                return(false);
            }

            bool useCache = persister.HasCache && source.CacheMode.HasFlag(CacheMode.Get);

            if (!useCache)
            {
                return(false);
            }

            var batchSize = persister.GetBatchSize();

            CollectionEntry[] collectionEntries = null;
            var collectionBatch = source.PersistenceContext.BatchFetchQueue.QueryCacheQueue
                                  ?.GetCollectionBatch(persister, collectionKey, out collectionEntries);

            if (collectionBatch != null || batchSize > 1 && persister.Cache.PreferMultipleGet())
            {
                // The first item in the array is the item that we want to load
                if (collectionBatch != null)
                {
                    if (collectionBatch.Length == 0)
                    {
                        return(false);                        // The key was already checked
                    }

                    batchSize = collectionBatch.Length;
                }

                if (collectionBatch == null)
                {
                    collectionEntries = new CollectionEntry[batchSize];
                    collectionBatch   = source.PersistenceContext.BatchFetchQueue
                                        .GetCollectionBatch(persister, collectionKey, batchSize, false, collectionEntries);
                }

                // Ignore null values as the retrieved batch may contains them when there are not enough
                // uninitialized collection in the queue
                var keys = new List <CacheKey>(batchSize);
                for (var i = 0; i < collectionBatch.Length; i++)
                {
                    var key = collectionBatch[i];
                    if (key == null)
                    {
                        break;
                    }
                    keys.Add(source.GenerateCacheKey(key, persister.KeyType, persister.Role));
                }
                var cachedObjects = persister.Cache.GetMany(keys.ToArray(), source.Timestamp);
                for (var i = 1; i < cachedObjects.Length; i++)
                {
                    var coll = source.PersistenceContext.BatchFetchQueue.GetBatchLoadableCollection(persister, collectionEntries[i]);
                    Assemble(keys[i], cachedObjects[i], persister, source, coll, collectionBatch[i], false);
                }
                return(Assemble(keys[0], cachedObjects[0], persister, source, collection, collectionKey, true));
            }

            var cacheKey     = source.GenerateCacheKey(collectionKey, persister.KeyType, persister.Role);
            var cachedObject = persister.Cache.Get(cacheKey, source.Timestamp);

            return(Assemble(cacheKey, cachedObject, persister, source, collection, collectionKey, true));
        }
        public async Task DeleteRowsAsync(IPersistentCollection collection, object id, ISessionImplementor session, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            if (!isInverse && RowDeleteEnabled)
            {
                if (log.IsDebugEnabled())
                {
                    log.Debug("Deleting rows of collection: {0}", MessageHelper.CollectionInfoString(this, collection, id, session));
                }

                bool deleteByIndex = !IsOneToMany && hasIndex && !indexContainsFormula;

                try
                {
                    // delete all the deleted entries
                    var offset = 0;
                    var count  = 0;

                    foreach (var entry in await(collection.GetDeletesAsync(this, !deleteByIndex, cancellationToken)).ConfigureAwait(false))
                    {
                        DbCommand st;
                        var       expectation = Expectations.AppropriateExpectation(deleteCheckStyle);
                        //var callable = DeleteCallable;
                        var commandInfo = GetDeleteCommand(deleteByIndex, entry, out var columnNullness);

                        var useBatch = expectation.CanBeBatched;
                        if (useBatch)
                        {
                            st = await(session.Batcher.PrepareBatchCommandAsync(
                                           commandInfo.CommandType, commandInfo.Text, commandInfo.ParameterTypes, cancellationToken)).ConfigureAwait(false);
                        }
                        else
                        {
                            st = await(session.Batcher.PrepareCommandAsync(
                                           commandInfo.CommandType, commandInfo.Text, commandInfo.ParameterTypes, cancellationToken)).ConfigureAwait(false);
                        }
                        try
                        {
                            var loc = offset;
                            if (hasIdentifier)
                            {
                                await(WriteIdentifierAsync(st, entry, loc, session, cancellationToken)).ConfigureAwait(false);
                            }
                            else
                            {
                                loc = await(WriteKeyAsync(st, id, loc, session, cancellationToken)).ConfigureAwait(false);

                                if (deleteByIndex)
                                {
                                    await(WriteIndexToWhereAsync(st, entry, loc, session, cancellationToken)).ConfigureAwait(false);
                                }
                                else
                                {
                                    await(WriteElementToWhereAsync(st, entry, columnNullness, loc, session, cancellationToken)).ConfigureAwait(false);
                                }
                            }
                            if (useBatch)
                            {
                                await(session.Batcher.AddToBatchAsync(expectation, cancellationToken)).ConfigureAwait(false);
                            }
                            else
                            {
                                expectation.VerifyOutcomeNonBatched(await(session.Batcher.ExecuteNonQueryAsync(st, cancellationToken)).ConfigureAwait(false), st);
                            }
                            count++;
                        }
                        catch (OperationCanceledException) { throw; }
                        catch (Exception e)
                        {
                            if (useBatch)
                            {
                                session.Batcher.AbortBatch(e);
                            }
                            throw;
                        }
                        finally
                        {
                            if (!useBatch)
                            {
                                session.Batcher.CloseCommand(st, null);
                            }
                        }
                    }

                    if (log.IsDebugEnabled())
                    {
                        if (count > 0)
                        {
                            log.Debug("done deleting collection rows: {0} deleted", count);
                        }
                        else
                        {
                            log.Debug("no rows to delete");
                        }
                    }
                }
                catch (DbException sqle)
                {
                    throw ADOExceptionHelper.Convert(sqlExceptionConverter, sqle,
                                                     "could not delete collection rows: " + MessageHelper.CollectionInfoString(this, collection, id, session));
                }
            }
        }
 public LoadingCollectionEntry(IDataReader resultSet, ICollectionPersister persister, object key, IPersistentCollection collection)
 {
     this.resultSet  = resultSet;
     this.persister  = persister;
     this.key        = key;
     this.collection = collection;
 }
		/// <summary> Get the snapshot of the pre-flush collection state</summary>
		public object GetSnapshot(IPersistentCollection coll)
		{
			return GetCollectionEntry(coll).Snapshot;
		}
        protected override int DoUpdateRows(object id, IPersistentCollection collection, ISessionImplementor session)
        {
            if (ArrayHelper.IsAllFalse(elementColumnIsSettable))
            {
                return(0);
            }

            try
            {
                DbCommand    st          = null;
                IExpectation expectation = Expectations.AppropriateExpectation(UpdateCheckStyle);
                //bool callable = UpdateCallable;
                bool        useBatch = expectation.CanBeBatched;
                IEnumerable entries  = collection.Entries(this);
                int         i        = 0;
                int         count    = 0;
                foreach (object entry in entries)
                {
                    if (collection.NeedsUpdating(entry, i, ElementType))
                    {
                        int offset = 0;
                        if (useBatch)
                        {
                            if (st == null)
                            {
                                st =
                                    session.Batcher.PrepareBatchCommand(SqlUpdateRowString.CommandType, SqlUpdateRowString.Text,
                                                                        SqlUpdateRowString.ParameterTypes);
                            }
                        }
                        else
                        {
                            st =
                                session.Batcher.PrepareCommand(SqlUpdateRowString.CommandType, SqlUpdateRowString.Text,
                                                               SqlUpdateRowString.ParameterTypes);
                        }

                        try
                        {
                            //offset += expectation.Prepare(st, Factory.ConnectionProvider.Driver);

                            int loc = WriteElement(st, collection.GetElement(entry), offset, session);
                            if (hasIdentifier)
                            {
                                WriteIdentifier(st, collection.GetIdentifier(entry, i), loc, session);
                            }
                            else
                            {
                                loc = WriteKey(st, id, loc, session);
                                if (HasIndex && !indexContainsFormula)
                                {
                                    WriteIndexToWhere(st, collection.GetIndex(entry, i, this), loc, session);
                                }
                                else
                                {
                                    // No nullness handled on update: updates does not occurs with sets or bags, and
                                    // indexed collections allowing formula (maps) force their element columns to
                                    // not-nullable.
                                    WriteElementToWhere(st, collection.GetSnapshotElement(entry, i), null, loc, session);
                                }
                            }

                            if (useBatch)
                            {
                                session.Batcher.AddToBatch(expectation);
                            }
                            else
                            {
                                expectation.VerifyOutcomeNonBatched(session.Batcher.ExecuteNonQuery(st), st);
                            }
                        }
                        catch (Exception e)
                        {
                            if (useBatch)
                            {
                                session.Batcher.AbortBatch(e);
                            }
                            throw;
                        }
                        finally
                        {
                            if (!useBatch)
                            {
                                session.Batcher.CloseCommand(st, null);
                            }
                        }
                        count++;
                    }
                    i++;
                }
                return(count);
            }
            catch (DbException sqle)
            {
                throw ADOExceptionHelper.Convert(SQLExceptionConverter, sqle,
                                                 "could not update collection rows: " + MessageHelper.CollectionInfoString(this, collection, id, session),
                                                 SqlUpdateRowString.Text);
            }
        }
Example #31
0
 public abstract Task InitializeCollectionAsync(IPersistentCollection collection, bool writing, CancellationToken cancellationToken);
Example #32
0
        public static Expr Parse(ParserContext pcon, ISeq form, string name)
        {
            ISeq origForm = form;

            FnExpr fn = new FnExpr(Compiler.TagOf(form));

            fn.Src = form;

            Keyword   retKey          = Keyword.intern(null, "rettag"); // TODO: make static
            object    retTag          = RT.get(RT.meta(form), retKey);
            ObjMethod enclosingMethod = (ObjMethod)Compiler.MethodVar.deref();

            fn._hasEnclosingMethod = enclosingMethod != null;


            if (((IMeta)form.first()).meta() != null)
            {
                fn.OnceOnly = RT.booleanCast(RT.get(RT.meta(form.first()), KW_ONCE));
            }

            fn.ComputeNames(form, name);

            List <string> prims = new List <string>();

            //arglist might be preceded by symbol naming this fn
            Symbol nm = RT.second(form) as Symbol;

            if (nm != null)
            {
                fn.ThisName = nm.Name;
                form        = RT.cons(Compiler.FnSym, RT.next(RT.next(form)));
            }

            // Normalize body
            //now (fn [args] body...) or (fn ([args] body...) ([args2] body2...) ...)
            //turn former into latter
            if (RT.second(form) is IPersistentVector)
            {
                form = RT.list(Compiler.FnSym, RT.next(form));
            }

            fn.SpanMap = (IPersistentMap)Compiler.SourceSpanVar.deref();

            GenContext newContext = null;

            GenContext context = Compiler.CompilerContextVar.deref() as GenContext ?? Compiler.EvalContext;

            newContext = context.WithNewDynInitHelper(fn.InternalName + "__dynInitHelper_" + RT.nextID().ToString());
            Var.pushThreadBindings(RT.map(Compiler.CompilerContextVar, newContext));


            try
            {
                try
                {
                    Var.pushThreadBindings(RT.mapUniqueKeys(
                                               Compiler.ConstantsVar, PersistentVector.EMPTY,
                                               Compiler.ConstantIdsVar, new IdentityHashMap(),
                                               Compiler.KeywordsVar, PersistentHashMap.EMPTY,
                                               Compiler.VarsVar, PersistentHashMap.EMPTY,
                                               Compiler.KeywordCallsitesVar, PersistentVector.EMPTY,
                                               Compiler.ProtocolCallsitesVar, PersistentVector.EMPTY,
                                               Compiler.VarCallsitesVar, Compiler.EmptyVarCallSites(),
                                               Compiler.NoRecurVar, null));
                    SortedDictionary <int, FnMethod> methods = new SortedDictionary <int, FnMethod>();
                    FnMethod variadicMethod = null;
                    bool     usesThis       = false;

                    for (ISeq s = RT.next(form); s != null; s = RT.next(s))
                    {
                        FnMethod f = FnMethod.Parse(fn, (ISeq)RT.first(s), retTag);
                        if (f.UsesThis)
                        {
                            //Console.WriteLine("{0} uses this",fn.Name);
                            usesThis = true;
                        }
                        if (f.IsVariadic)
                        {
                            if (variadicMethod == null)
                            {
                                variadicMethod = f;
                            }
                            else
                            {
                                throw new ParseException("Can't have more than 1 variadic overload");
                            }
                        }
                        else if (!methods.ContainsKey(f.RequiredArity))
                        {
                            methods[f.RequiredArity] = f;
                        }
                        else
                        {
                            throw new ParseException("Can't have 2 overloads with the same arity.");
                        }
                        if (f.Prim != null)
                        {
                            prims.Add(f.Prim);
                        }
                    }

                    if (variadicMethod != null && methods.Count > 0 && methods.Keys.Max() >= variadicMethod.NumParams)
                    {
                        throw new ParseException("Can't have fixed arity methods with more params than the variadic method.");
                    }

                    fn.CanBeDirect = !fn._hasEnclosingMethod && fn.Closes.count() == 0 && !usesThis;

                    IPersistentCollection allMethods = null;
                    foreach (FnMethod method in methods.Values)
                    {
                        allMethods = RT.conj(allMethods, method);
                    }
                    if (variadicMethod != null)
                    {
                        allMethods = RT.conj(allMethods, variadicMethod);
                    }

                    if (fn.CanBeDirect)
                    {
                        for (ISeq s = RT.seq(allMethods); s != null; s = s.next())
                        {
                            FnMethod fm = s.first() as FnMethod;
                            if (fm.Locals != null)
                            {
                                for (ISeq sl = RT.seq(RT.keys(fm.Locals)); sl != null; sl = sl.next())
                                {
                                    LocalBinding lb = sl.first() as LocalBinding;
                                    if (lb.IsArg)
                                    {
                                        lb.Index -= 1;
                                    }
                                }
                            }
                        }
                    }

                    fn.Methods           = allMethods;
                    fn._variadicMethod   = variadicMethod;
                    fn.Keywords          = (IPersistentMap)Compiler.KeywordsVar.deref();
                    fn.Vars              = (IPersistentMap)Compiler.VarsVar.deref();
                    fn.Constants         = (PersistentVector)Compiler.ConstantsVar.deref();
                    fn.KeywordCallsites  = (IPersistentVector)Compiler.KeywordCallsitesVar.deref();
                    fn.ProtocolCallsites = (IPersistentVector)Compiler.ProtocolCallsitesVar.deref();
                    fn.VarCallsites      = (IPersistentSet)Compiler.VarCallsitesVar.deref();

                    fn.ConstantsID = RT.nextID();
                }
                finally
                {
                    Var.popThreadBindings();
                }


                IPersistentMap fmeta = RT.meta(origForm);
                if (fmeta != null)
                {
                    fmeta = fmeta.without(RT.LineKey).without(RT.ColumnKey).without(RT.SourceSpanKey).without(RT.FileKey).without(retKey);
                }
                fn._hasMeta = RT.count(fmeta) > 0;


                IPersistentVector primTypes = PersistentVector.EMPTY;
                foreach (string typename in prims)
                {
                    primTypes = primTypes.cons(Type.GetType(typename));
                }

                fn.Compile(
                    fn.IsVariadic ? typeof(RestFn) : typeof(AFunction),
                    null,
                    primTypes,
                    fn.OnceOnly,
                    newContext);

                if (fn.SupportsMeta)
                {
                    return(new MetaExpr(fn, MapExpr.Parse(pcon.EvalOrExpr(), fmeta)));
                }
                else
                {
                    return(fn);
                }
            }
            finally
            {
                if (newContext != null)
                {
                    Var.popThreadBindings();
                }
            }
        }
Example #33
0
        private static Task ProcessDereferencedCollectionAsync(IPersistentCollection coll, ISessionImplementor session, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(Task.FromCanceled <object>(cancellationToken));
            }
            try
            {
                IPersistenceContext  persistenceContext = session.PersistenceContext;
                CollectionEntry      entry           = persistenceContext.GetCollectionEntry(coll);
                ICollectionPersister loadedPersister = entry.LoadedPersister;

                if (log.IsDebugEnabled() && loadedPersister != null)
                {
                    log.Debug("Collection dereferenced: {0}", MessageHelper.CollectionInfoString(loadedPersister, coll, entry.LoadedKey, session));
                }

                // do a check
                bool hasOrphanDelete = loadedPersister != null && loadedPersister.HasOrphanDelete;
                if (hasOrphanDelete)
                {
                    object ownerId = loadedPersister.OwnerEntityPersister.GetIdentifier(coll.Owner);
                    // TODO NH Different behavior
                    //if (ownerId == null)
                    //{
                    //  // the owning entity may have been deleted and its identifier unset due to
                    //  // identifier-rollback; in which case, try to look up its identifier from
                    //  // the persistence context
                    //  if (session.Factory.Settings.IsIdentifierRollbackEnabled)
                    //  {
                    //    EntityEntry ownerEntry = persistenceContext.GetEntry(coll.Owner);
                    //    if (ownerEntry != null)
                    //    {
                    //      ownerId = ownerEntry.Id;
                    //    }
                    //  }
                    //  if (ownerId == null)
                    //  {
                    //    throw new AssertionFailure("Unable to determine collection owner identifier for orphan-delete processing");
                    //  }
                    //}
                    EntityKey key   = session.GenerateEntityKey(ownerId, loadedPersister.OwnerEntityPersister);
                    object    owner = persistenceContext.GetEntity(key);
                    if (owner == null)
                    {
                        return(Task.FromException <object>(new AssertionFailure("collection owner not associated with session: " + loadedPersister.Role)));
                    }
                    EntityEntry e = persistenceContext.GetEntry(owner);
                    //only collections belonging to deleted entities are allowed to be dereferenced in the case of orphan delete
                    if (e != null && e.Status != Status.Deleted && e.Status != Status.Gone)
                    {
                        return(Task.FromException <object>(new HibernateException("A collection with cascade=\"all-delete-orphan\" was no longer referenced by the owning entity instance: " + loadedPersister.Role)));
                    }
                }

                // do the work
                entry.CurrentPersister = null;
                entry.CurrentKey       = null;
                return(PrepareCollectionForUpdateAsync(coll, entry, session.Factory, cancellationToken));
            }
            catch (System.Exception ex)
            {
                return(Task.FromException <object>(ex));
            }
        }
Example #34
0
        private static Task PrepareCollectionForUpdateAsync(IPersistentCollection collection, CollectionEntry entry, ISessionFactoryImplementor factory, CancellationToken cancellationToken)
        {
            //1. record the collection role that this collection is referenced by
            //2. decide if the collection needs deleting/creating/updating (but don't actually schedule the action yet)

            if (entry.IsProcessed)
            {
                throw new AssertionFailure("collection was processed twice by flush()");
            }
            if (cancellationToken.IsCancellationRequested)
            {
                return(Task.FromCanceled <object>(cancellationToken));
            }
            try
            {
                entry.IsProcessed = true;

                ICollectionPersister loadedPersister  = entry.LoadedPersister;
                ICollectionPersister currentPersister = entry.CurrentPersister;
                if (loadedPersister != null || currentPersister != null)
                {
                    // it is or was referenced _somewhere_
                    bool ownerChanged = loadedPersister != currentPersister ||
                                        !currentPersister.KeyType.IsEqual(entry.LoadedKey, entry.CurrentKey, factory);

                    if (ownerChanged)
                    {
                        // do a check
                        bool orphanDeleteAndRoleChanged = loadedPersister != null &&
                                                          currentPersister != null && loadedPersister.HasOrphanDelete;

                        if (orphanDeleteAndRoleChanged)
                        {
                            return(Task.FromException <object>(new HibernateException("Don't change the reference to a collection with cascade=\"all-delete-orphan\": " + loadedPersister.Role)));
                        }

                        // do the work
                        if (currentPersister != null)
                        {
                            entry.IsDorecreate = true;                             // we will need to create new entries
                        }

                        if (loadedPersister != null)
                        {
                            entry.IsDoremove = true;                             // we will need to remove ye olde entries
                            if (entry.IsDorecreate)
                            {
                                log.Debug("Forcing collection initialization");
                                return(collection.ForceInitializationAsync(cancellationToken));                                // force initialize!
                            }
                        }
                    }
                    else if (collection.IsDirty)
                    {
                        // else if it's elements changed
                        entry.IsDoupdate = true;
                    }
                }
                return(Task.CompletedTask);
            }
            catch (System.Exception ex)
            {
                return(Task.FromException <object>(ex));
            }
        }
		/// <summary> 
		/// add an (initialized) collection that was created by another session and passed
		/// into update() (ie. one with a snapshot and existing state on the database)
		/// </summary>
		public void AddInitializedDetachedCollection(ICollectionPersister collectionPersister, IPersistentCollection collection)
		{
			if (collection.IsUnreferenced)
			{
				//treat it just like a new collection
				AddCollection(collection, collectionPersister);
			}
			else
			{
				CollectionEntry ce = new CollectionEntry(collection, session.Factory);
				AddCollection(collection, ce, collection.Key);
			}
		}
Example #36
0
        protected override async Task <int> DoUpdateRowsAsync(object id, IPersistentCollection collection, ISessionImplementor session, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            // we finish all the "removes" first to take care of possible unique
            // constraints and so that we can take better advantage of batching
            try
            {
                const int offset = 0;
                int       count  = 0;

                if (RowDeleteEnabled)
                {
                    IExpectation   deleteExpectation = Expectations.AppropriateExpectation(DeleteCheckStyle);
                    bool           useBatch          = deleteExpectation.CanBeBatched;
                    SqlCommandInfo sql = SqlDeleteRowString;
                    // update removed rows fks to null
                    int         i       = 0;
                    IEnumerable entries = collection.Entries(this);

                    foreach (object entry in entries)
                    {
                        if (await(collection.NeedsUpdatingAsync(entry, i, ElementType, cancellationToken)).ConfigureAwait(false))
                        {
                            DbCommand st = null;
                            // will still be issued when it used to be null
                            if (useBatch)
                            {
                                st = await(session.Batcher.PrepareBatchCommandAsync(SqlDeleteRowString.CommandType, sql.Text,
                                                                                    SqlDeleteRowString.ParameterTypes, cancellationToken)).ConfigureAwait(false);
                            }
                            else
                            {
                                st = await(session.Batcher.PrepareCommandAsync(SqlDeleteRowString.CommandType, sql.Text,
                                                                               SqlDeleteRowString.ParameterTypes, cancellationToken)).ConfigureAwait(false);
                            }

                            try
                            {
                                int loc = await(WriteKeyAsync(st, id, offset, session, cancellationToken)).ConfigureAwait(false);
                                await(WriteElementToWhereAsync(st, collection.GetSnapshotElement(entry, i), loc, session, cancellationToken)).ConfigureAwait(false);
                                if (useBatch)
                                {
                                    await(session.Batcher.AddToBatchAsync(deleteExpectation, cancellationToken)).ConfigureAwait(false);
                                }
                                else
                                {
                                    deleteExpectation.VerifyOutcomeNonBatched(await(session.Batcher.ExecuteNonQueryAsync(st, cancellationToken)).ConfigureAwait(false), st);
                                }
                            }
                            catch (OperationCanceledException) { throw; }
                            catch (Exception e)
                            {
                                if (useBatch)
                                {
                                    session.Batcher.AbortBatch(e);
                                }
                                throw;
                            }
                            finally
                            {
                                if (!useBatch && st != null)
                                {
                                    session.Batcher.CloseCommand(st, null);
                                }
                            }
                            count++;
                        }
                        i++;
                    }
                }

                if (RowInsertEnabled)
                {
                    IExpectation insertExpectation = Expectations.AppropriateExpectation(InsertCheckStyle);
                    //bool callable = InsertCallable;
                    bool           useBatch = insertExpectation.CanBeBatched;
                    SqlCommandInfo sql      = SqlInsertRowString;

                    // now update all changed or added rows fks
                    int         i       = 0;
                    IEnumerable entries = collection.Entries(this);
                    foreach (object entry in entries)
                    {
                        if (await(collection.NeedsUpdatingAsync(entry, i, ElementType, cancellationToken)).ConfigureAwait(false))
                        {
                            DbCommand st = null;
                            if (useBatch)
                            {
                                st = await(session.Batcher.PrepareBatchCommandAsync(SqlInsertRowString.CommandType, sql.Text,
                                                                                    SqlInsertRowString.ParameterTypes, cancellationToken)).ConfigureAwait(false);
                            }
                            else
                            {
                                st = await(session.Batcher.PrepareCommandAsync(SqlInsertRowString.CommandType, sql.Text,
                                                                               SqlInsertRowString.ParameterTypes, cancellationToken)).ConfigureAwait(false);
                            }

                            try
                            {
                                //offset += insertExpectation.Prepare(st, Factory.ConnectionProvider.Driver);
                                int loc = await(WriteKeyAsync(st, id, offset, session, cancellationToken)).ConfigureAwait(false);
                                if (HasIndex && !indexContainsFormula)
                                {
                                    loc = await(WriteIndexToWhereAsync(st, collection.GetIndex(entry, i, this), loc, session, cancellationToken)).ConfigureAwait(false);
                                }
                                await(WriteElementToWhereAsync(st, collection.GetElement(entry), loc, session, cancellationToken)).ConfigureAwait(false);
                                if (useBatch)
                                {
                                    await(session.Batcher.AddToBatchAsync(insertExpectation, cancellationToken)).ConfigureAwait(false);
                                }
                                else
                                {
                                    insertExpectation.VerifyOutcomeNonBatched(await(session.Batcher.ExecuteNonQueryAsync(st, cancellationToken)).ConfigureAwait(false), st);
                                }
                            }
                            catch (OperationCanceledException) { throw; }
                            catch (Exception e)
                            {
                                if (useBatch)
                                {
                                    session.Batcher.AbortBatch(e);
                                }
                                throw;
                            }
                            finally
                            {
                                if (!useBatch && st != null)
                                {
                                    session.Batcher.CloseCommand(st, null);
                                }
                            }
                            count++;
                        }
                        i++;
                    }
                }
                return(count);
            }
            catch (DbException sqle)
            {
                throw ADOExceptionHelper.Convert(SQLExceptionConverter, sqle, "could not update collection rows: " + MessageHelper.CollectionInfoString(this, collection, id, session));
            }
        }
		/// <summary> 
		/// Register a collection for non-lazy loading at the end of the two-phase load
		/// </summary>
		public void AddNonLazyCollection(IPersistentCollection collection)
		{
			nonlazyCollections.Add(collection);
		}
Example #38
0
 public Task RecreateAsync(IPersistentCollection collection, object key, ISessionImplementor session, CancellationToken cancellationToken)
 {
     return(Task.CompletedTask);
     // TODO:  Add CollectionPersisterStub.Recreate implementation
 }
 protected override IEnumerable GetNewCollectionContent(IPersistentCollection newCollection)
 {
     return((ICollection)newCollection);
 }
Example #40
0
 public void DeleteRows(IPersistentCollection collection, object key, ISessionImplementor session)
 {
     // TODO:  Add CollectionPersisterStub.DeleteRows implementation
 }
 protected abstract Task <int> DoUpdateRowsAsync(object key, IPersistentCollection collection, ISessionImplementor session, CancellationToken cancellationToken);
        public override void Execute()
        {
            object id = GetKey();
            ISessionImplementor   session    = Session;
            ICollectionPersister  persister  = Persister;
            IPersistentCollection collection = Collection;
            bool affectedByFilters           = persister.IsAffectedByEnabledFilters(session);

            bool      statsEnabled = session.Factory.Statistics.IsStatisticsEnabled;
            Stopwatch stopwatch    = null;

            if (statsEnabled)
            {
                stopwatch = Stopwatch.StartNew();
            }

            PreUpdate();

            if (!collection.WasInitialized)
            {
                if (!collection.HasQueuedOperations)
                {
                    throw new AssertionFailure("no queued adds");
                }
                //do nothing - we only need to notify the cache...
            }
            else if (!affectedByFilters && collection.Empty)
            {
                if (!emptySnapshot)
                {
                    persister.Remove(id, session);
                }
            }
            else if (collection.NeedsRecreate(persister))
            {
                if (affectedByFilters)
                {
                    throw new HibernateException("cannot recreate collection while filter is enabled: "
                                                 + MessageHelper.CollectionInfoString(persister, collection, id, session));
                }
                if (!emptySnapshot)
                {
                    persister.Remove(id, session);
                }
                persister.Recreate(collection, id, session);
            }
            else
            {
                persister.DeleteRows(collection, id, session);
                persister.UpdateRows(collection, id, session);
                persister.InsertRows(collection, id, session);
            }

            var entry = Session.PersistenceContext.GetCollectionEntry(collection);

            entry.AfterAction(collection);

            Evict();

            PostUpdate();

            if (statsEnabled)
            {
                stopwatch.Stop();
                Session.Factory.StatisticsImplementor.UpdateCollection(Persister.Role, stopwatch.Elapsed);
            }
        }
        public async Task RecreateAsync(IPersistentCollection collection, object id, ISessionImplementor session, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            if (!isInverse && RowInsertEnabled)
            {
                if (log.IsDebugEnabled())
                {
                    log.Debug("Inserting collection: {0}", MessageHelper.CollectionInfoString(this, collection, id, session));
                }

                try
                {
                    IExpectation expectation = null;
                    bool         useBatch    = false;
                    int          i           = 0;
                    int          count       = 0;

                    // create all the new entries
                    foreach (var entry in collection.Entries(this))
                    {
                        // Init, if we're on the first element.
                        if (count == 0)
                        {
                            expectation = Expectations.AppropriateExpectation(insertCheckStyle);
                            await(collection.PreInsertAsync(this, cancellationToken)).ConfigureAwait(false);
                            //bool callable = InsertCallable;
                            useBatch = expectation.CanBeBatched;
                        }

                        if (collection.EntryExists(entry, i))
                        {
                            object entryId;
                            if (!IsIdentifierAssignedByInsert)
                            {
                                // NH Different implementation: write once
                                entryId = await(PerformInsertAsync(id, collection, expectation, entry, i, useBatch, false, session, cancellationToken)).ConfigureAwait(false);
                            }
                            else
                            {
                                entryId = await(PerformInsertAsync(id, collection, entry, i, session, cancellationToken)).ConfigureAwait(false);
                            }
                            collection.AfterRowInsert(this, entry, i, entryId);
                            count++;
                        }
                        i++;
                    }

                    if (log.IsDebugEnabled())
                    {
                        if (count > 0)
                        {
                            log.Debug("done inserting collection: {0} rows inserted", count);
                        }
                        else
                        {
                            log.Debug("collection was empty");
                        }
                    }
                }
                catch (DbException sqle)
                {
                    throw ADOExceptionHelper.Convert(sqlExceptionConverter, sqle,
                                                     "could not insert collection: " + MessageHelper.CollectionInfoString(this, collection, id, session));
                }
            }
        }
 public CollectionUpdateAction(IPersistentCollection collection, ICollectionPersister persister, object key,
                               bool emptySnapshot, ISessionImplementor session)
     : base(persister, collection, key, session)
 {
     this.emptySnapshot = emptySnapshot;
 }
 public virtual void Assemble(IPersistentCollection collection, ICollectionPersister persister, object owner)
 {
     collection.InitializeFromCache(persister, state, owner);
     collection.AfterInitialize(persister);
 }
        /// <summary>
        /// Retrieve the collection that is being loaded as part of processing this result set.
        /// </summary>
        /// <param name="persister">The persister for the collection being requested. </param>
        /// <param name="key">The key of the collection being requested. </param>
        /// <returns> The loading collection (see discussion above). </returns>
        /// <remarks>
        /// Basically, there are two valid return values from this method:<ul>
        /// <li>an instance of {@link PersistentCollection} which indicates to
        /// continue loading the result set row data into that returned collection
        /// instance; this may be either an instance already associated and in the
        /// midst of being loaded, or a newly instantiated instance as a matching
        /// associated collection was not found.</li>
        /// <li><i>null</i> indicates to ignore the corresponding result set row
        /// data relating to the requested collection; this indicates that either
        /// the collection was found to already be associated with the persistence
        /// context in a fully loaded state, or it was found in a loading state
        /// associated with another result set processing context.</li>
        /// </ul>
        /// </remarks>
        public IPersistentCollection GetLoadingCollection(ICollectionPersister persister, object key)
        {
            EntityMode em = loadContexts.PersistenceContext.Session.EntityMode;

            CollectionKey collectionKey = new CollectionKey(persister, key, em);

            if (log.IsDebugEnabled)
            {
                log.Debug("starting attempt to find loading collection [" + MessageHelper.InfoString(persister.Role, key) + "]");
            }
            LoadingCollectionEntry loadingCollectionEntry = loadContexts.LocateLoadingCollectionEntry(collectionKey);

            if (loadingCollectionEntry == null)
            {
                // look for existing collection as part of the persistence context
                IPersistentCollection collection = loadContexts.PersistenceContext.GetCollection(collectionKey);
                if (collection != null)
                {
                    if (collection.WasInitialized)
                    {
                        log.Debug("collection already initialized; ignoring");
                        return(null);                        // ignore this row of results! Note the early exit
                    }
                    else
                    {
                        // initialize this collection
                        log.Debug("collection not yet initialized; initializing");
                    }
                }
                else
                {
                    object owner            = loadContexts.PersistenceContext.GetCollectionOwner(key, persister);
                    bool   newlySavedEntity = owner != null && loadContexts.PersistenceContext.GetEntry(owner).Status != Status.Loading && em != EntityMode.Xml;
                    if (newlySavedEntity)
                    {
                        // important, to account for newly saved entities in query
                        // todo : some kind of check for new status...
                        log.Debug("owning entity already loaded; ignoring");
                        return(null);
                    }
                    else
                    {
                        // create one
                        if (log.IsDebugEnabled)
                        {
                            log.Debug("instantiating new collection [key=" + key + ", rs=" + resultSet + "]");
                        }
                        collection = persister.CollectionType.Instantiate(loadContexts.PersistenceContext.Session, persister, key);
                    }
                }
                collection.BeforeInitialize(persister, -1);
                collection.BeginRead();
                localLoadingCollectionKeys.Add(collectionKey);
                loadContexts.RegisterLoadingCollectionXRef(collectionKey, new LoadingCollectionEntry(resultSet, persister, key, collection));
                return(collection);
            }
            else
            {
                if (loadingCollectionEntry.ResultSet == resultSet)
                {
                    log.Debug("found loading collection bound to current result set processing; reading row");
                    return(loadingCollectionEntry.Collection);
                }
                else
                {
                    // ignore this row, the collection is in process of
                    // being loaded somewhere further "up" the stack
                    log.Debug("collection is already being initialized; ignoring row");
                    return(null);
                }
            }
        }
Example #47
0
        public override async Task ExecuteAsync(CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            object id = Key;
            ISessionImplementor   session    = Session;
            ICollectionPersister  persister  = Persister;
            IPersistentCollection collection = Collection;
            bool affectedByFilters           = persister.IsAffectedByEnabledFilters(session);

            bool      statsEnabled = session.Factory.Statistics.IsStatisticsEnabled;
            Stopwatch stopwatch    = null;

            if (statsEnabled)
            {
                stopwatch = Stopwatch.StartNew();
            }

            await(PreUpdateAsync(cancellationToken)).ConfigureAwait(false);

            if (!collection.WasInitialized)
            {
                if (!collection.HasQueuedOperations)
                {
                    throw new AssertionFailure("no queued adds");
                }
                //do nothing - we only need to notify the cache...
            }
            else if (!affectedByFilters && collection.Empty)
            {
                if (!emptySnapshot)
                {
                    await(persister.RemoveAsync(id, session, cancellationToken)).ConfigureAwait(false);
                }
            }
            else if (collection.NeedsRecreate(persister))
            {
                if (affectedByFilters)
                {
                    throw new HibernateException("cannot recreate collection while filter is enabled: "
                                                 + MessageHelper.CollectionInfoString(persister, collection, id, session));
                }
                if (!emptySnapshot)
                {
                    await(persister.RemoveAsync(id, session, cancellationToken)).ConfigureAwait(false);
                }
                await(persister.RecreateAsync(collection, id, session, cancellationToken)).ConfigureAwait(false);
            }
            else
            {
                await(persister.DeleteRowsAsync(collection, id, session, cancellationToken)).ConfigureAwait(false);
                await(persister.UpdateRowsAsync(collection, id, session, cancellationToken)).ConfigureAwait(false);
                await(persister.InsertRowsAsync(collection, id, session, cancellationToken)).ConfigureAwait(false);
            }

            Session.PersistenceContext.GetCollectionEntry(collection).AfterAction(collection);

            await(EvictAsync(cancellationToken)).ConfigureAwait(false);

            await(PostUpdateAsync(cancellationToken)).ConfigureAwait(false);

            if (statsEnabled)
            {
                stopwatch.Stop();
                Session.Factory.StatisticsImplementor.UpdateCollection(Persister.Role, stopwatch.Elapsed);
            }
        }
Example #48
0
        protected IEnumerable <AuditLogEntry> CreateCollectionEntries(object affectedOwnerOrNull, Guid id, IPersistentCollection collection)
        {
            var typeName = affectedOwnerOrNull.GetType().Name;

            var excludedProperties = GetExcludedProperties(affectedOwnerOrNull.GetType());

            if (excludedProperties.Any(p => collection.Role.EndsWith(p)) || !(collection.GetValue() is IEnumerable <EntityBase>))
            {
                yield break;
            }

            var newList = ((IEnumerable <EntityBase>)collection.GetValue()).ToList();
            var oldList = ((List <object>)collection.StoredSnapshot).OfType <EntityBase>().ToList();

            foreach (
                var entry in
                ParseCollectionEntries(oldList, newList, typeName,
                                       collection.Role.Replace("Prototype1.Declarations.Entities." + typeName + ".", ""), id))
            {
                yield return(entry);
            }
        }
		/// <summary> 
		/// Add a new collection (ie. a newly created one, just instantiated by the
		/// application, with no database state or snapshot)
		/// </summary>
		/// <param name="collection">The collection to be associated with the persistence context </param>
		/// <param name="persister"></param>
		public void AddNewCollection(ICollectionPersister persister, IPersistentCollection collection)
		{
			AddCollection(collection, persister);
		}
 public abstract void InitializeCollection(IPersistentCollection collection, bool writing);
		/// <summary> Add a collection to the cache, creating a new collection entry for it </summary>
		/// <param name="collection">The collection for which we are adding an entry. </param>
		/// <param name="persister">The collection persister </param>
		private void AddCollection(IPersistentCollection collection, ICollectionPersister persister)
		{
			CollectionEntry ce = new CollectionEntry(persister, collection);
			collectionEntries[collection] = ce;
		}
Example #52
0
        internal bool ShouldTargetsDirtyFlagBeCleared(IPersistentCollection targetPc, IPersistentCollection originalPc, IEnumerable original)
        {
            if (targetPc == null)
            {
                return(false);
            }

            if (originalPc == null)
            {
                if (!targetPc.IsDirty && AreCollectionElementsEqual(original, (IEnumerable)targetPc))
                {
                    return(true);
                }
            }
            else
            {
                if (!originalPc.IsDirty)
                {
                    return(true);
                }
            }
            return(false);
        }
		/// <summary> add a collection we just pulled out of the cache (does not need initializing)</summary>
		public CollectionEntry AddInitializedCollection(ICollectionPersister persister, IPersistentCollection collection,
																										object id)
		{
			CollectionEntry ce = new CollectionEntry(collection, persister, id, flushing);
			ce.PostInitialize(collection);
			AddCollection(collection, ce, id);
			return ce;
		}
        /// <summary> Try to initialize a collection from the cache</summary>
        private async Task <bool> InitializeCollectionFromCacheAsync(object id, ICollectionPersister persister, IPersistentCollection collection, ISessionImplementor source, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            if (!(source.EnabledFilters.Count == 0) && persister.IsAffectedByEnabledFilters(source))
            {
                log.Debug("disregarding cached version (if any) of collection due to enabled filters ");
                return(false);
            }

            bool useCache = persister.HasCache && source.CacheMode.HasFlag(CacheMode.Get);

            if (!useCache)
            {
                return(false);
            }
            else
            {
                ISessionFactoryImplementor factory = source.Factory;

                CacheKey ck = source.GenerateCacheKey(id, persister.KeyType, persister.Role);
                object   ce = await(persister.Cache.GetAsync(ck, source.Timestamp, cancellationToken)).ConfigureAwait(false);

                if (factory.Statistics.IsStatisticsEnabled)
                {
                    if (ce == null)
                    {
                        factory.StatisticsImplementor.SecondLevelCacheMiss(persister.Cache.RegionName);
                    }
                    else
                    {
                        factory.StatisticsImplementor.SecondLevelCacheHit(persister.Cache.RegionName);
                    }
                }

                if (ce == null)
                {
                    log.Debug("Collection cache miss: {0}", ck);
                }
                else
                {
                    log.Debug("Collection cache hit: {0}", ck);
                }

                if (ce == null)
                {
                    return(false);
                }
                else
                {
                    IPersistenceContext persistenceContext = source.PersistenceContext;

                    CollectionCacheEntry cacheEntry = (CollectionCacheEntry)persister.CacheEntryStructure.Destructure(ce, factory);
                    await(cacheEntry.AssembleAsync(collection, persister, persistenceContext.GetCollectionOwner(id, persister), cancellationToken)).ConfigureAwait(false);

                    persistenceContext.GetCollectionEntry(collection).PostInitialize(collection, persistenceContext);
                    return(true);
                }
            }
        }
		/// <summary> Register a <tt>PersistentCollection</tt> object for an array.
		/// Associates a holder with an array - MUST be called after loading 
		/// array, since the array instance is not created until endLoad().
		/// </summary>
		public void AddCollectionHolder(IPersistentCollection holder)
		{
			//TODO:refactor + make this method private
			arrayHolders[holder.GetValue()] = holder;
		}
Example #56
0
 public bool IsSnapshotEmpty(IPersistentCollection collection)
 {
     return(collection.WasInitialized && (LoadedPersister == null || LoadedPersister.IsMutable) && collection.IsSnapshotEmpty(Snapshot));
 }
		public PostCollectionRemoveEvent(ICollectionPersister collectionPersister, IPersistentCollection collection,
		                                 IEventSource source, object loadedOwner)
			: base(collectionPersister, collection, source, loadedOwner, GetOwnerIdOrNull(loadedOwner, source)) {}
Example #58
0
 public void PostInitialize(IPersistentCollection collection)
 {
     snapshot = LoadedPersister.IsMutable ? collection.GetSnapshot(LoadedPersister) : null;
     collection.SetSnapshot(loadedKey, role, snapshot);
 }
Example #59
0
        private static bool CollectionIsInitialized(object collection)
        {
            IPersistentCollection pc = collection as IPersistentCollection;

            return(pc == null || pc.WasInitialized);
        }
Example #60
0
 public void Recreate(IPersistentCollection collection, object key, ISessionImplementor session)
 {
     // TODO:  Add CollectionPersisterStub.Recreate implementation
 }