protected virtual void OnUpdate(Type structureType, object item) { Ensure.That(item, "item").IsNotNull(); var implType = item.GetType(); var structureSchema = OnUpsertStructureSchema(structureType); var structureId = structureSchema.IdAccessor.GetValue(item); if (!structureSchema.HasConcurrencyToken) { var exists = DbClient.Exists(structureSchema, structureId); if (!exists) { throw new SisoDbException(ExceptionMessages.WriteSession_NoItemExistsForUpdate.Inject(structureSchema.Name, structureId.Value)); } } else { OnEnsureConcurrencyTokenIsValid(structureSchema, structureId, item, implType); } CacheConsumeMode = CacheConsumeModes.DoNotUpdateCacheWithDbResult; Db.CacheProvider.CleanQueriesFor(structureSchema); Db.CacheProvider.Remove(structureSchema, structureId); DbClient.DeleteIndexesAndUniquesById(structureId, structureSchema); var structureBuilder = Db.StructureBuilders.ResolveBuilderForUpdate(structureSchema); var updatedStructure = structureBuilder.CreateStructure(item, structureSchema); var bulkInserter = Db.ProviderFactory.GetStructureInserter(DbClient); bulkInserter.Replace(structureSchema, updatedStructure); InternalEvents.NotifyUpdated(this, structureSchema, updatedStructure, item); }
protected virtual void OnClear(Type structureType) { Ensure.That(structureType, "structureType").IsNotNull(); var structureSchema = OnUpsertStructureSchema(structureType); CacheConsumeMode = CacheConsumeModes.DoNotUpdateCacheWithDbResult; Db.CacheProvider.ClearByType(structureType); DbClient.DeleteAll(structureSchema); }
protected virtual void OnDeleteById(Type structureType, object id) { Ensure.That(id, "id").IsNotNull(); var structureId = StructureId.ConvertFrom(id); var structureSchema = OnUpsertStructureSchema(structureType); CacheConsumeMode = CacheConsumeModes.DoNotUpdateCacheWithDbResult; Db.CacheProvider.Remove(structureSchema, structureId); DbClient.DeleteById(structureId, structureSchema); InternalEvents.NotifyDeleted(this, structureSchema, structureId); }
protected virtual void OnDeleteAllExceptIds(Type structureType, params object[] ids) { Ensure.That(ids, "ids").HasItems(); Ensure.That(structureType, "structureType").IsNotNull(); var structureIds = ids.Yield().Select(StructureId.ConvertFrom).ToArray(); var structureSchema = OnUpsertStructureSchema(structureType); CacheConsumeMode = CacheConsumeModes.DoNotUpdateCacheWithDbResult; Db.CacheProvider.ClearByType(structureType); DbClient.DeleteAllExceptIds(structureIds, structureSchema); }
protected virtual void OnDeleteByIds(Type structureType, params object[] ids) { Ensure.That(ids, "ids").HasItems(); Ensure.That(structureType, "structureType").IsNotNull(); var structureIds = ids.Yield().Select(StructureId.ConvertFrom).ToArray(); var structureSchema = OnUpsertStructureSchema(structureType); CacheConsumeMode = CacheConsumeModes.DoNotUpdateCacheWithDbResult; Db.CacheProvider.Remove(structureSchema, new HashSet <IStructureId>(structureIds)); DbClient.DeleteByIds(structureIds, structureSchema); InternalEvents.NotifyDeleted(this, structureSchema, structureIds); }
protected virtual ISession OnUpdate <TContract, TImpl>(object id, Action <TImpl> modifier, Func <TImpl, bool> proceed = null) where TContract : class where TImpl : class { Try(() => { Ensure.That(id, "id").IsNotNull(); Ensure.That(modifier, "modifier").IsNotNull(); var structureSchema = OnUpsertStructureSchema <TContract>(); var structureId = StructureId.ConvertFrom(id); var existingJson = DbClient.GetJsonByIdWithLock(structureId, structureSchema); if (string.IsNullOrWhiteSpace(existingJson)) { throw new SisoDbException(ExceptionMessages.WriteSession_NoItemExistsForUpdate.Inject(structureSchema.Name, structureId.Value)); } var item = Db.Serializer.Deserialize <TImpl>(existingJson); modifier.Invoke(item); if (proceed != null && !proceed.Invoke(item)) { return; } if (structureSchema.HasConcurrencyToken) { OnEnsureConcurrencyTokenIsValid(structureSchema, structureId, item, typeof(TImpl)); } CacheConsumeMode = CacheConsumeModes.DoNotUpdateCacheWithDbResult; Db.CacheProvider.CleanQueriesFor(structureSchema); Db.CacheProvider.Remove(structureSchema, structureId); DbClient.DeleteIndexesAndUniquesById(structureId, structureSchema); var structureBuilder = Db.StructureBuilders.ResolveBuilderForUpdate(structureSchema); var updatedStructure = structureBuilder.CreateStructure(item, structureSchema); var bulkInserter = Db.ProviderFactory.GetStructureInserter(DbClient); bulkInserter.Replace(structureSchema, updatedStructure); InternalEvents.NotifyUpdated(this, structureSchema, updatedStructure, item); }); return(this); }
protected DbSession(ISisoDatabase db) { Ensure.That(db, "db").IsNotNull(); _id = Guid.NewGuid(); _db = db; DbClient = Db.ProviderFactory.GetTransactionalDbClient(Db); ExecutionContext = new SessionExecutionContext(this); Status = SessionStatus.Active; InternalEvents = new SessionEvents(); SqlStatements = Db.ProviderFactory.GetSqlStatements(); QueryGenerator = Db.ProviderFactory.GetDbQueryGenerator(); SqlExpressionBuilder = Db.ProviderFactory.GetSqlExpressionBuilder(); _queryEngine = new DbQueryEngine(ExecutionContext, QueryGenerator); _advanced = new DbSessionAdvanced(ExecutionContext, QueryGenerator, SqlExpressionBuilder); CacheConsumeMode = CacheConsumeModes.UpdateCacheWithDbResult; }
protected virtual void OnInsert(Type structureType, object item) { Ensure.That(structureType, "structureType").IsNotNull(); Ensure.That(item, "item").IsNotNull(); var structureSchema = OnUpsertStructureSchema(structureType); CacheConsumeMode = CacheConsumeModes.DoNotUpdateCacheWithDbResult; Db.CacheProvider.CleanQueriesFor(structureSchema); var structureBuilder = Db.StructureBuilders.ResolveBuilderForInsert(structureSchema, DbClient); var structure = structureBuilder.CreateStructure(item, structureSchema); var structureInserter = Db.ProviderFactory.GetStructureInserter(DbClient); structureInserter.Insert(structureSchema, new[] { structure }); InternalEvents.NotifyInserted(this, structureSchema, structure, item); }
protected virtual void OnInsertManyJson(Type structureType, IEnumerable <string> json) { Ensure.That(json, "json").IsNotNull(); var structureSchema = OnUpsertStructureSchema(structureType); CacheConsumeMode = CacheConsumeModes.DoNotUpdateCacheWithDbResult; Db.CacheProvider.CleanQueriesFor(structureSchema); var structureBuilder = Db.StructureBuilders.ResolveBuilderForInsert(structureSchema, DbClient); var structureInserter = Db.ProviderFactory.GetStructureInserter(DbClient); foreach (var itemsBatch in Db.Serializer.DeserializeMany(json, structureSchema.Type.Type).Batch(Db.Settings.MaxInsertManyBatchSize)) { var structures = structureBuilder.CreateStructures(itemsBatch, structureSchema); structureInserter.Insert(structureSchema, structures); InternalEvents.NotifyInserted(this, structureSchema, structures, itemsBatch); } }
protected virtual void OnDeleteByQuery <T>(Expression <Func <T, bool> > predicate) where T : class { Ensure.That(predicate, "predicate").IsNotNull(); CacheConsumeMode = CacheConsumeModes.DoNotUpdateCacheWithDbResult; var structureSchema = OnUpsertStructureSchema <T>(); Db.CacheProvider.ClearByType(structureSchema); var queryBuilder = Db.ProviderFactory.GetQueryBuilder <T>(Db.StructureSchemas); queryBuilder.Where(predicate); var query = queryBuilder.Build(); var sql = QueryGenerator.GenerateQueryReturningStrutureIds(query); DbClient.DeleteByQuery(sql, structureSchema); InternalEvents.NotifyDeleted(this, structureSchema, query); }
protected virtual string OnInsertJson(Type structureType, string json) { Ensure.That(json, "json").IsNotNullOrWhiteSpace(); var structureSchema = OnUpsertStructureSchema(structureType); CacheConsumeMode = CacheConsumeModes.DoNotUpdateCacheWithDbResult; Db.CacheProvider.CleanQueriesFor(structureSchema); var item = Db.Serializer.Deserialize(json, structureType); var structureBuilder = Db.StructureBuilders.ResolveBuilderForInsert(structureSchema, DbClient); var structure = structureBuilder.CreateStructure(item, structureSchema); var structureInserter = Db.ProviderFactory.GetStructureInserter(DbClient); structureInserter.Insert(structureSchema, new[] { structure }); InternalEvents.NotifyInserted(this, structureSchema, structure, item); return(structure.Data); }
public static T Consume <T>(this ICacheProvider cacheProvider, IStructureSchema structureSchema, Expression <Func <T, bool> > predicate, Func <Expression <Func <T, bool> >, T> nonCacheQuery, CacheConsumeModes consumeMode) where T : class { if (!cacheProvider.IsEnabledFor(structureSchema)) { return(nonCacheQuery.Invoke(predicate)); } var cache = cacheProvider[structureSchema.Type.Type]; var structure = cache.Query(predicate).SingleOrDefault(); if (structure != null) { return(structure); } structure = nonCacheQuery.Invoke(predicate); if (structure == null || consumeMode == CacheConsumeModes.DoNotUpdateCacheWithDbResult) { return(structure); } return(cacheProvider[structureSchema.Type.Type].Put(structureSchema.IdAccessor.GetValue(structure), structure)); }
public static IEnumerable <T> Consume <T>(this ICacheProvider cacheProvider, IStructureSchema structureSchema, IDbQuery query, Func <IDbQuery, IEnumerable <T> > nonCacheQuery, CacheConsumeModes consumeMode) where T : class { if (!cacheProvider.IsEnabledFor(structureSchema)) { return(nonCacheQuery.Invoke(query)); } var queryChecksum = DbQueryChecksumGenerator.Instance.Generate(query); var cache = cacheProvider[structureSchema.Type.Type]; if (cache.HasQuery(queryChecksum)) { return(cache.GetByQuery <T>(queryChecksum)); } if (!query.IsCacheable || consumeMode == CacheConsumeModes.DoNotUpdateCacheWithDbResult) { return(nonCacheQuery.Invoke(query)); } return(cache.Put( queryChecksum, nonCacheQuery.Invoke(query).Select(s => new KeyValuePair <IStructureId, T>(structureSchema.IdAccessor.GetValue(s), s)))); }
public static IEnumerable <T> Consume <T>(this ICacheProvider cacheProvider, IStructureSchema structureSchema, IStructureId[] structureIds, Func <IStructureId[], IEnumerable <T> > nonCacheQuery, CacheConsumeModes consumeMode) where T : class { if (!cacheProvider.IsEnabledFor(structureSchema)) { return(nonCacheQuery.Invoke(structureIds)); } var cache = cacheProvider[structureSchema.Type.Type]; var cachedResult = cache.GetByIds <T>(structureIds).ToDictionary(kv => kv.Key, kv => kv.Value); //Ok to turn it to in-mem rep and not yield. GetByIds, should not be enormous resultset. if (!cachedResult.Any()) { if (consumeMode == CacheConsumeModes.DoNotUpdateCacheWithDbResult) { return(nonCacheQuery.Invoke(structureIds)); } return(cache.Put(nonCacheQuery.Invoke(structureIds).Select(s => new KeyValuePair <IStructureId, T>(structureSchema.IdAccessor.GetValue(s), s)))); } var allWasCached = cachedResult.Count == structureIds.Length; if (allWasCached) { return(cachedResult.Values); } var deltaIds = structureIds.Where(sid => !cachedResult.ContainsKey(sid)).ToArray(); if (!deltaIds.Any()) { return(cachedResult.Values); } if (consumeMode == CacheConsumeModes.DoNotUpdateCacheWithDbResult) { return(cachedResult.Values.MergeWith(nonCacheQuery.Invoke(deltaIds))); } return(cachedResult.Values.MergeWith(cache.Put(nonCacheQuery.Invoke(deltaIds).Select(s => new KeyValuePair <IStructureId, T>(structureSchema.IdAccessor.GetValue(s), s))))); }
public static T Consume <T>(this ICacheProvider cacheProvider, IStructureSchema structureSchema, IStructureId structureId, Func <IStructureId, T> nonCacheQuery, CacheConsumeModes consumeMode) where T : class { if (!cacheProvider.IsEnabledFor(structureSchema)) { return(nonCacheQuery.Invoke(structureId)); } var cache = cacheProvider[structureSchema.Type.Type]; var structure = cache.GetById <T>(structureId); if (structure != null) { return(structure); } structure = nonCacheQuery.Invoke(structureId); if (structure == null || consumeMode == CacheConsumeModes.DoNotUpdateCacheWithDbResult) { return(structure); } return(cache.Put(structureId, structure)); }
public virtual ISession UpdateMany <T>(Expression <Func <T, bool> > predicate, Action <T> modifier) where T : class { Try(() => { Ensure.That(predicate, "predicate").IsNotNull(); Ensure.That(modifier, "modifier").IsNotNull(); var structureSchema = OnUpsertStructureSchema <T>(); CacheConsumeMode = CacheConsumeModes.DoNotUpdateCacheWithDbResult; Db.CacheProvider.CleanQueriesFor(structureSchema); var deleteIds = new HashSet <IStructureId>(); var keepQueue = new List <T>(Db.Settings.MaxUpdateManyBatchSize); var structureBuilder = Db.StructureBuilders.ResolveBuilderForUpdate(structureSchema); var structureInserter = Db.ProviderFactory.GetStructureInserter(DbClient); var queryBuilder = Db.ProviderFactory.GetQueryBuilder <T>(Db.StructureSchemas); var query = queryBuilder.Where(predicate).Build(); var sqlQuery = QueryGenerator.GenerateQuery(query); foreach (var structure in Db.Serializer.DeserializeMany <T>( DbClient.ReadJson(structureSchema, sqlQuery.Sql, sqlQuery.Parameters))) { var structureIdBefore = structureSchema.IdAccessor.GetValue(structure); modifier.Invoke(structure); var structureIdAfter = structureSchema.IdAccessor.GetValue(structure); if (!structureIdBefore.Value.Equals(structureIdAfter.Value)) { throw new SisoDbException(ExceptionMessages.WriteSession_UpdateMany_NewIdDoesNotMatchOldId.Inject( structureIdAfter.Value, structureIdBefore.Value)); } deleteIds.Add(structureIdBefore); keepQueue.Add(structure); if (keepQueue.Count < Db.Settings.MaxUpdateManyBatchSize) { continue; } Db.CacheProvider.Remove(structureSchema, deleteIds); DbClient.DeleteByIds(deleteIds, structureSchema); deleteIds.Clear(); var items = keepQueue.ToArray(); var structures = structureBuilder.CreateStructures(items, structureSchema); structureInserter.Insert(structureSchema, structures); keepQueue.Clear(); InternalEvents.NotifyUpdated(this, structureSchema, structures, items); } if (keepQueue.Count > 0) { Db.CacheProvider.Remove(structureSchema, deleteIds); DbClient.DeleteByIds(deleteIds, structureSchema); deleteIds.Clear(); var items = keepQueue.ToArray(); var structures = structureBuilder.CreateStructures(items, structureSchema); structureInserter.Insert(structureSchema, structures); keepQueue.Clear(); InternalEvents.NotifyUpdated(this, structureSchema, structures, items); } }); return(this); }