Class ObjectStorageProviderBase
🚀 BULK INSERT - high-performance creation of multiple objects
public abstract class ObjectStorageProviderBase : IObjectStorageProvider
Inheritance
Implements
Derived
Properties
Configuration
protected RedbServiceConfiguration Configuration { get; }
Context
protected IRedbContext Context { get; }
ListProvider
protected IListProvider? ListProvider { get; }
Logger
protected ILogger? Logger { get; }
PermissionProvider
protected IPermissionProvider PermissionProvider { get; }
SchemeSyncProvider
protected ISchemeSyncProvider SchemeSyncProvider { get; }
SecurityContext
protected IRedbSecurityContext SecurityContext { get; }
Serializer
protected IRedbObjectSerializer Serializer { get; }
Sql
protected ISqlDialect Sql { get; }
Methods
AddNewObjectsAsync<TProps>(IEnumerable<IRedbObject<TProps>>, IRedbUser)
🚀 BULK INSERT with explicit user: Create multiple new objects (WITHOUT permission checks)
public Task<List<long>> AddNewObjectsAsync<TProps>(IEnumerable<IRedbObject<TProps>> objects, IRedbUser user) where TProps : class, new()
AddNewObjectsAsync<TProps>(IEnumerable<IRedbObject<TProps>>)
🚀 BULK INSERT: Create multiple new objects in one operation (WITHOUT permission checks)
public Task<List<long>> AddNewObjectsAsync<TProps>(IEnumerable<IRedbObject<TProps>> objects) where TProps : class, new()
AssignMissingIds(List<IRedbObject>, IRedbUser)
🎯 STEP 3: Assigning ID via GetNextKey() to all objects without ID
protected Task AssignMissingIds(List<IRedbObject> objects, IRedbUser user)
CacheNestedObjects(object)
Recursively caches all nested RedbObject found in Props
protected void CacheNestedObjects(object obj)
CollectAllObjectsRecursively(IRedbObject, List<IRedbObject>, HashSet<long>)
🔍 STEP 2: Recursive collection of all IRedbObject (main + nested)
protected Task CollectAllObjectsRecursively(IRedbObject rootObject, List<IRedbObject> collector, HashSet<long> processed)
ConvertToObjectRecord(IRedbObject)
Convert IRedbObject to RedbObjectRow for bulk operations
protected RedbObjectRow ConvertToObjectRecord(IRedbObject obj)
CreateLazyPropsLoader()
Creates a LazyPropsLoader instance. Override in derived classes for custom implementations (e.g., ProLazyPropsLoader).
protected abstract ILazyPropsLoader CreateLazyPropsLoader()
DeleteAsync(IEnumerable<IRedbObject>, IRedbUser)
Bulk deletion of objects by interface with explicit user
public Task<int> DeleteAsync(IEnumerable<IRedbObject> objects, IRedbUser user)
DeleteAsync(IEnumerable<IRedbObject>)
Bulk deletion of objects by interface (uses _securityContext)
public Task<int> DeleteAsync(IEnumerable<IRedbObject> objects)
DeleteAsync(IEnumerable<long>, IRedbUser)
Bulk deletion of objects by ID with explicit user
public Task<int> DeleteAsync(IEnumerable<long> objectIds, IRedbUser user)
DeleteAsync(IEnumerable<long>)
Bulk deletion of objects by ID (uses _securityContext)
public Task<int> DeleteAsync(IEnumerable<long> objectIds)
DeleteAsync(IRedbObject, IRedbUser)
Deletes an object from the database using atomic ExecuteDeleteAsync.
public Task<bool> DeleteAsync(IRedbObject obj, IRedbUser user)
DeleteAsync(IRedbObject)
Delete object (uses _securityContext and config.DefaultCheckPermissionsOnDelete).
public Task<bool> DeleteAsync(IRedbObject obj)
DeleteAsync(long, IRedbUser)
Delete object by ID with explicit user
public Task<bool> DeleteAsync(long objectId, IRedbUser user)
DeleteAsync(long)
Delete object by ID (uses _securityContext)
public Task<bool> DeleteAsync(long objectId)
DeleteWithPurgeAsync(IEnumerable<long>, int, IProgress<PurgeProgress>?, CancellationToken, long?)
Delete objects with background purge and progress reporting.
public Task DeleteWithPurgeAsync(IEnumerable<long> objectIds, int batchSize = 10, IProgress<PurgeProgress>? progress = null, CancellationToken cancellationToken = default, long? trashParentId = null)
EnsureSchemesForAllTypes(List<IRedbObject>)
🏗️ STEP 4: Creating/verifying schemas for all object types (using PostgresSchemeSyncProvider)
protected Task EnsureSchemesForAllTypes(List<IRedbObject> objects)
ExecuteBatchByStrategy(EavSaveStrategy, List<IRedbObject>, List<RedbValue>)
Executes batch save by strategy. OpenSource: only DeleteInsert.
protected virtual Task ExecuteBatchByStrategy(EavSaveStrategy strategy, List<IRedbObject> allObjectsToSave, List<RedbValue> allValuesToSave)
GetDeletionProgressAsync(long)
Gets deletion progress for a specific trash container from database.
public Task<PurgeProgress?> GetDeletionProgressAsync(long trashId)
GetOrphanedDeletionTasksAsync(int)
Gets orphaned deletion tasks for recovery at startup.
public Task<List<OrphanedTask>> GetOrphanedDeletionTasksAsync(int timeoutMinutes = 30)
GetSchemeFromCacheOrDbAsync(long)
🚀 OPTIMIZATION: Get scheme from cache WITHOUT hash validation
protected Task<IRedbScheme?> GetSchemeFromCacheOrDbAsync(long schemeId)
GetSchemeIdForObject(long)
Get scheme ID for object
protected Task<long?> GetSchemeIdForObject(long objectId)
GetStructureDbType(IRedbStructure)
Gets DbType for structure from cache.
protected Task<string> GetStructureDbType(IRedbStructure structure)
GetUserActiveDeletionsAsync(long)
Gets all active (pending/running) deletions for a user from database.
public Task<List<PurgeProgress>> GetUserActiveDeletionsAsync(long userId)
LoadAsync(IEnumerable<long>, int, bool?)
Bulk load objects by ID (uses _securityContext)
public Task<List<IRedbObject>> LoadAsync(IEnumerable<long> objectIds, int depth = 10, bool? lazyLoadProps = null)
LoadAsync(IEnumerable<long>, IRedbUser, int, bool?)
Bulk loading of objects by ID with explicit user
public Task<List<IRedbObject>> LoadAsync(IEnumerable<long> objectIds, IRedbUser user, int depth = 10, bool? lazyLoadProps = null)
LoadAsync<TProps>(IRedbObject, int, bool?)
Load object from EAV (uses _securityContext and config.DefaultCheckPermissionsOnLoad)
public Task<RedbObject<TProps>?> LoadAsync<TProps>(IRedbObject obj, int depth = 10, bool? lazyLoadProps = null) where TProps : class, new()
LoadAsync<TProps>(IRedbObject, IRedbUser, int, bool?)
Load object from EAV with explicitly specified user (uses config.DefaultCheckPermissionsOnLoad)
public Task<RedbObject<TProps>?> LoadAsync<TProps>(IRedbObject obj, IRedbUser user, int depth = 10, bool? lazyLoadProps = null) where TProps : class, new()
LoadAsync<TProps>(long, int, bool?)
Load object from EAV by ID (uses _securityContext and config.DefaultCheckPermissionsOnLoad)
public Task<RedbObject<TProps>?> LoadAsync<TProps>(long objectId, int depth = 10, bool? lazyLoadProps = null) where TProps : class, new()
LoadAsync<TProps>(long, IRedbUser, int, bool?)
MAIN loading method - all other LoadAsync methods call it
public Task<RedbObject<TProps>?> LoadAsync<TProps>(long objectId, IRedbUser user, int depth = 10, bool? lazyLoadProps = null) where TProps : class, new()
LoadEagerAsync<TProps>(long, int)
✅ Virtual method for EAGER loading of Props.
protected virtual Task<RedbObject<TProps>?> LoadEagerAsync<TProps>(long objectId, int depth) where TProps : class, new()
LoadObjectsEagerAsync(List<long>, int)
EAGER loading: get_object_json for all IDs
protected virtual Task<List<IRedbObject>> LoadObjectsEagerAsync(List<long> objectIds, int depth)
LoadObjectsLazyAsync(List<long>)
LAZY loading: base fields from _objects + LoadPropsForManyAsync
protected Task<List<IRedbObject>> LoadObjectsLazyAsync(List<long> objectIds)
LoadWithParentsAsync(IEnumerable<long>, int, bool?)
Bulk polymorphic load with parent chains (uses _securityContext).
public Task<List<ITreeRedbObject>> LoadWithParentsAsync(IEnumerable<long> objectIds, int depth = 10, bool? lazyLoadProps = null)
LoadWithParentsAsync(IEnumerable<long>, IRedbUser, int, bool?)
MAIN bulk polymorphic LoadWithParentsAsync.
public Task<List<ITreeRedbObject>> LoadWithParentsAsync(IEnumerable<long> objectIds, IRedbUser user, int depth = 10, bool? lazyLoadProps = null)
LoadWithParentsAsync<TProps>(IEnumerable<long>, int, bool?)
Bulk load objects with parent chains (uses _securityContext).
public Task<List<TreeRedbObject<TProps>>> LoadWithParentsAsync<TProps>(IEnumerable<long> objectIds, int depth = 10, bool? lazyLoadProps = null) where TProps : class, new()
LoadWithParentsAsync<TProps>(IEnumerable<long>, IRedbUser, int, bool?)
MAIN bulk LoadWithParentsAsync - loads objects with parent chains to root.
public Task<List<TreeRedbObject<TProps>>> LoadWithParentsAsync<TProps>(IEnumerable<long> objectIds, IRedbUser user, int depth = 10, bool? lazyLoadProps = null) where TProps : class, new()
LoadWithParentsAsync<TProps>(IRedbObject, int, bool?)
Load object with parent chain to root (uses _securityContext).
public Task<TreeRedbObject<TProps>?> LoadWithParentsAsync<TProps>(IRedbObject obj, int depth = 10, bool? lazyLoadProps = null) where TProps : class, new()
LoadWithParentsAsync<TProps>(IRedbObject, IRedbUser, int, bool?)
Load object by ID with parent chain to root with explicit user.
public Task<TreeRedbObject<TProps>?> LoadWithParentsAsync<TProps>(IRedbObject obj, IRedbUser user, int depth = 10, bool? lazyLoadProps = null) where TProps : class, new()
LoadWithParentsAsync<TProps>(long, int, bool?)
Load object by ID with parent chain to root (uses _securityContext).
public Task<TreeRedbObject<TProps>?> LoadWithParentsAsync<TProps>(long objectId, int depth = 10, bool? lazyLoadProps = null) where TProps : class, new()
LoadWithParentsAsync<TProps>(long, IRedbUser, int, bool?)
MAIN LoadWithParentsAsync - loads single object with parent chain.
public Task<TreeRedbObject<TProps>?> LoadWithParentsAsync<TProps>(long objectId, IRedbUser user, int depth = 10, bool? lazyLoadProps = null) where TProps : class, new()
PrepareValuesByStrategy(List<IRedbObject>, List<RedbValue>, bool)
Step 6: Strategy selection for values processing.
protected virtual Task PrepareValuesByStrategy(List<IRedbObject> objects, List<RedbValue> valuesList, bool isRootObjectNew)
PrepareValuesWithTreeDeleteInsert(List<IRedbObject>, List<RedbValue>)
DeleteInsert strategy: delete all existing values, then insert new ones.
protected Task PrepareValuesWithTreeDeleteInsert(List<IRedbObject> objects, List<RedbValue> valuesList)
ProcessAllObjectsPropertiesRecursively(List<IRedbObject>, List<RedbValue>)
🔄 STEP 5: Recursive processing of Props of all objects → RedbValue lists
protected Task ProcessAllObjectsPropertiesRecursively(List<IRedbObject> objects, List<RedbValue> valuesList)
PurgeTrashAsync(long, int, int, IProgress<PurgeProgress>?, CancellationToken)
Purge a trash container created by SoftDeleteAsync.
public Task PurgeTrashAsync(long trashId, int totalCount, int batchSize = 10, IProgress<PurgeProgress>? progress = null, CancellationToken cancellationToken = default)
SaveAsync(IEnumerable<IRedbObject>, IRedbUser)
🚀 BATCH SAVE with explicit user
public Task<List<long>> SaveAsync(IEnumerable<IRedbObject> objects, IRedbUser user)
SaveAsync(IEnumerable<IRedbObject>)
🚀 BATCH SAVE: Save multiple objects (new + updates)
public Task<List<long>> SaveAsync(IEnumerable<IRedbObject> objects)
SaveAsync(IRedbObject, IRedbUser)
Save single object via interface with explicit user.
public Task<long> SaveAsync(IRedbObject obj, IRedbUser user)
SaveAsync(IRedbObject)
Save single object via interface. Type determined internally.
public Task<long> SaveAsync(IRedbObject obj)
SaveAsync<TProps>(IRedbObject<TProps>, IRedbUser)
Save generic object to EAV with explicit user (uses config.DefaultCheckPermissionsOnSave).
public Task<long> SaveAsync<TProps>(IRedbObject<TProps> obj, IRedbUser user) where TProps : class, new()
SaveAsync<TProps>(IRedbObject<TProps>)
Save generic object to EAV (uses _securityContext and config.DefaultCheckPermissionsOnSave).
public Task<long> SaveAsync<TProps>(IRedbObject<TProps> obj) where TProps : class, new()
SaveAsyncNew<TProps>(IRedbObject<TProps>, IRedbUser)
🚀 NEW SAVEASYNC: Correct recursive processing of all data types
public Task<long> SaveAsyncNew<TProps>(IRedbObject<TProps> obj, IRedbUser user) where TProps : class, new()
SaveBatchWithDeleteInsertStrategy(List<IRedbObject>, List<RedbValue>)
DeleteInsert batch strategy: delete ALL values, BulkInsert/BulkUpdate of objects, BulkInsert of values.
protected Task SaveBatchWithDeleteInsertStrategy(List<IRedbObject> allObjectsToSave, List<RedbValue> allValuesToSave)
SoftDeleteAsync(IEnumerable<IRedbObject>, IRedbUser, long?)
Mark objects for soft-deletion with explicit user.
public Task<DeletionMark> SoftDeleteAsync(IEnumerable<IRedbObject> objects, IRedbUser user, long? trashParentId = null)
SoftDeleteAsync(IEnumerable<IRedbObject>, long?)
Mark objects for soft-deletion (uses _securityContext).
public Task<DeletionMark> SoftDeleteAsync(IEnumerable<IRedbObject> objects, long? trashParentId = null)
SoftDeleteAsync(IEnumerable<long>, IRedbUser, long?)
Mark objects for soft-deletion with explicit user.
public Task<DeletionMark> SoftDeleteAsync(IEnumerable<long> objectIds, IRedbUser user, long? trashParentId = null)
SoftDeleteAsync(IEnumerable<long>, long?)
Mark objects for soft-deletion (uses _securityContext).
public Task<DeletionMark> SoftDeleteAsync(IEnumerable<long> objectIds, long? trashParentId = null)
TryClaimOrphanedTaskAsync(long, int)
Atomically claim an orphaned task for processing.
public Task<bool> TryClaimOrphanedTaskAsync(long trashId, int timeoutMinutes = 30)
UpdateExistingValueFields(RedbValue, RedbValue, Dictionary<long, string>)
Updates existing value fields from new value (only significant fields).
protected void UpdateExistingValueFields(RedbValue existingValue, RedbValue newValue, Dictionary<long, string> structuresInfo)
Constructors
ObjectStorageProviderBase(IRedbContext, IRedbObjectSerializer, IPermissionProvider, IRedbSecurityContext, ISchemeSyncProvider, RedbServiceConfiguration, ISqlDialect, IListProvider?, ILogger?)
Creates a new ObjectStorageProviderBase instance.