Class ObjectStorageProviderBase

Assembly: redb.Core.dll

🚀 BULK INSERT - high-performance creation of multiple objects

public abstract class ObjectStorageProviderBase : IObjectStorageProvider

Inheritance

ObjectObjectStorageProviderBase

Implements

Derived

Properties

Cache

Domain-bound metadata cache for this provider.

protected GlobalMetadataCache Cache { get; }

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; }

PropsCache

Domain-bound props cache for this provider.

protected GlobalPropsCache PropsCache { 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