/// <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; }
public static IPersistentCollection Conj(IPersistentCollection collection, object obj) { if (collection == null) return new PersistentList(obj); return collection.Cons(obj); }
/// <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); }
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; }
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); }
/// <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); } }
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); }
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; }
/// <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); } }
//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) } }
public void initializeCollection(IPersistentCollection collection, bool writing) { delegat.InitializeCollection(collection, writing); }
public CollectionCacheEntry(IPersistentCollection collection, ICollectionPersister persister) { state = collection.Disassemble(persister); }
/// <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)); } } }
/// <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); } }
public abstract Task InitializeCollectionAsync(IPersistentCollection collection, bool writing, CancellationToken cancellationToken);
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(); } } }
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)); } }
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); } }
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); }
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); }
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); } } }
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); } }
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; }
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; }
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)) {}
public void PostInitialize(IPersistentCollection collection) { snapshot = LoadedPersister.IsMutable ? collection.GetSnapshot(LoadedPersister) : null; collection.SetSnapshot(loadedKey, role, snapshot); }
private static bool CollectionIsInitialized(object collection) { IPersistentCollection pc = collection as IPersistentCollection; return(pc == null || pc.WasInitialized); }
public void Recreate(IPersistentCollection collection, object key, ISessionImplementor session) { // TODO: Add CollectionPersisterStub.Recreate implementation }