diff options
Diffstat (limited to 'VNLib.Plugins.Extensions.Data')
-rw-r--r-- | VNLib.Plugins.Extensions.Data/Abstractions/IBulkDataStore.cs | 41 | ||||
-rw-r--r-- | VNLib.Plugins.Extensions.Data/Abstractions/IDataStore.cs | 99 | ||||
-rw-r--r-- | VNLib.Plugins.Extensions.Data/Abstractions/IPaginatedDataStore.cs | 32 | ||||
-rw-r--r-- | VNLib.Plugins.Extensions.Data/Abstractions/IUserEntity.cs | 15 | ||||
-rw-r--r-- | VNLib.Plugins.Extensions.Data/DbModelBase.cs | 24 | ||||
-rw-r--r-- | VNLib.Plugins.Extensions.Data/DbStore.cs | 501 | ||||
-rw-r--r-- | VNLib.Plugins.Extensions.Data/Extensions.cs | 58 | ||||
-rw-r--r-- | VNLib.Plugins.Extensions.Data/IDbModel.cs | 28 | ||||
-rw-r--r-- | VNLib.Plugins.Extensions.Data/ProtectedDbStore.cs | 46 | ||||
-rw-r--r-- | VNLib.Plugins.Extensions.Data/ProtectedEntityExtensions.cs | 62 | ||||
-rw-r--r-- | VNLib.Plugins.Extensions.Data/TransactionalDbContext.cs | 69 | ||||
-rw-r--r-- | VNLib.Plugins.Extensions.Data/VNLib.Plugins.Extensions.Data.csproj | 41 | ||||
-rw-r--r-- | VNLib.Plugins.Extensions.Data/VNLib.Plugins.Extensions.Data.xml | 473 | ||||
-rw-r--r-- | VNLib.Plugins.Extensions.Data/l | 473 |
14 files changed, 1962 insertions, 0 deletions
diff --git a/VNLib.Plugins.Extensions.Data/Abstractions/IBulkDataStore.cs b/VNLib.Plugins.Extensions.Data/Abstractions/IBulkDataStore.cs new file mode 100644 index 0000000..3b6ab62 --- /dev/null +++ b/VNLib.Plugins.Extensions.Data/Abstractions/IBulkDataStore.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +using VNLib.Utils; + +namespace VNLib.Plugins.Extensions.Data.Abstractions +{ + /// <summary> + /// An abstraction that defines a Data-Store that supports + /// bulk data operations + /// </summary> + /// <typeparam name="T">The data-model type</typeparam> + public interface IBulkDataStore<T> + { + /// <summary> + /// Deletes a collection of records from the store + /// </summary> + /// <param name="records">A collection of records to delete</param> + ///<returns>A task the resolves the number of entires removed from the store</returns> + Task<ERRNO> DeleteBulkAsync(ICollection<T> records); + /// <summary> + /// Updates a collection of records + /// </summary> + /// <param name="records">The collection of records to update</param> + /// <returns>A task the resolves an error code (should evaluate to false on failure, and true on success)</returns> + Task<ERRNO> UpdateBulkAsync(ICollection<T> records); + /// <summary> + /// Creates a bulk collection of records as entries in the store + /// </summary> + /// <param name="records">The collection of records to add</param> + /// <returns>A task the resolves an error code (should evaluate to false on failure, and true on success)</returns> + Task<ERRNO> CreateBulkAsync(ICollection<T> records); + /// <summary> + /// Creates or updates individual records from a bulk collection of records + /// </summary> + /// <param name="records">The collection of records to add</param> + /// <returns>A task the resolves an error code (should evaluate to false on failure, and true on success)</returns> + Task<ERRNO> AddOrUpdateBulkAsync(ICollection<T> records); + } + +} diff --git a/VNLib.Plugins.Extensions.Data/Abstractions/IDataStore.cs b/VNLib.Plugins.Extensions.Data/Abstractions/IDataStore.cs new file mode 100644 index 0000000..f923891 --- /dev/null +++ b/VNLib.Plugins.Extensions.Data/Abstractions/IDataStore.cs @@ -0,0 +1,99 @@ +using System; +using System.Threading.Tasks; +using System.Collections.Generic; + +using VNLib.Utils; + +namespace VNLib.Plugins.Extensions.Data.Abstractions +{ + /// <summary> + /// An abstraction that defines a Data-Store and common + /// operations that retrieve or manipulate records of data + /// </summary> + /// <typeparam name="T">The data-model type</typeparam> + public interface IDataStore<T> + { + /// <summary> + /// Gets the total number of records in the current store + /// </summary> + /// <returns>A task that resolves the number of records in the store</returns> + Task<long> GetCountAsync(); + /// <summary> + /// Gets the number of records that belong to the specified constraint + /// </summary> + /// <param name="specifier">A specifier to constrain the reults</param> + /// <returns>The number of records that belong to the specifier</returns> + Task<long> GetCountAsync(string specifier); + /// <summary> + /// Gets a record from its key + /// </summary> + /// <param name="key">The key identifying the unique record</param> + /// <returns>A promise that resolves the record identified by the specified key</returns> + Task<T?> GetSingleAsync(string key); + /// <summary> + /// Gets a record from its key + /// </summary> + /// <param name="specifiers">A variable length specifier arguemnt array for retreiving a single application</param> + /// <returns></returns> + Task<T?> GetSingleAsync(params string[] specifiers); + /// <summary> + /// Gets a record from the store with a partial model, intended to complete the model + /// </summary> + /// <param name="record">The partial model used to query the store</param> + /// <returns>A task the resolves the completed data-model</returns> + Task<T?> GetSingleAsync(T record); + /// <summary> + /// Fills a collection with enires retireved from the store using the specifer + /// </summary> + /// <param name="collection">The collection to add entires to</param> + /// <param name="specifier">A specifier argument to constrain results</param> + /// <param name="limit">The maximum number of elements to retrieve</param> + /// <returns>A Task the resolves to the number of items added to the collection</returns> + Task<ERRNO> GetCollectionAsync(ICollection<T> collection, string specifier, int limit); + /// <summary> + /// Fills a collection with enires retireved from the store using a variable length specifier + /// parameter + /// </summary> + /// <param name="collection">The collection to add entires to</param> + /// <param name="limit">The maximum number of elements to retrieve</param> + /// <param name="args"></param> + /// <returns>A Task the resolves to the number of items added to the collection</returns> + Task<ERRNO> GetCollectionAsync(ICollection<T> collection, int limit, params string[] args); + /// <summary> + /// Updates an entry in the store with the specified record + /// </summary> + /// <param name="record">The record to update</param> + /// <returns>A task the resolves an error code (should evaluate to false on failure, and true on success)</returns> + Task<ERRNO> UpdateAsync(T record); + /// <summary> + /// Creates a new entry in the store representing the specified record + /// </summary> + /// <param name="record">The record to add to the store</param> + /// <returns>A task the resolves an error code (should evaluate to false on failure, and true on success)</returns> + Task<ERRNO> CreateAsync(T record); + /// <summary> + /// Deletes one or more entrires from the store matching the specified record + /// </summary> + /// <param name="record">The record to remove from the store</param> + /// <returns>A task the resolves the number of records removed(should evaluate to false on failure, and deleted count on success)</returns> + Task<ERRNO> DeleteAsync(T record); + /// <summary> + /// Deletes one or more entires from the store matching the specified unique key + /// </summary> + /// <param name="key">The unique key that identifies the record</param> + /// <returns>A task the resolves the number of records removed(should evaluate to false on failure, and deleted count on success)</returns> + Task<ERRNO> DeleteAsync(string key); + /// <summary> + /// Deletes one or more entires from the store matching the supplied specifiers + /// </summary> + /// <param name="specifiers">A variable length array of specifiers used to delete one or more entires</param> + /// <returns>A task the resolves the number of records removed(should evaluate to false on failure, and deleted count on success)</returns> + Task<ERRNO> DeleteAsync(params string[] specifiers); + /// <summary> + /// Updates an entry in the store if it exists, or creates a new entry if one does not already exist + /// </summary> + /// <param name="record">The record to add to the store</param> + /// <returns>A task the resolves the result of the operation</returns> + Task<ERRNO> AddOrUpdateAsync(T record); + } +} diff --git a/VNLib.Plugins.Extensions.Data/Abstractions/IPaginatedDataStore.cs b/VNLib.Plugins.Extensions.Data/Abstractions/IPaginatedDataStore.cs new file mode 100644 index 0000000..44c11f8 --- /dev/null +++ b/VNLib.Plugins.Extensions.Data/Abstractions/IPaginatedDataStore.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace VNLib.Plugins.Extensions.Data.Abstractions +{ + /// <summary> + /// Defines a Data-Store that can retirieve and manipulate paginated + /// data + /// </summary> + /// <typeparam name="T">The data-model type</typeparam> + public interface IPaginatedDataStore<T> + { + /// <summary> + /// Gets a collection of records using a pagination style query, and adds the records to the collecion + /// </summary> + /// <param name="collection">The collection to add records to</param> + /// <param name="page">Pagination page to get records from</param> + /// <param name="limit">The maximum number of items to retrieve from the store</param> + /// <returns>A task that resolves the number of items added to the collection</returns> + Task<int> GetPageAsync(ICollection<T> collection, int page, int limit); + /// <summary> + /// Gets a collection of records using a pagination style query with constraint arguments, and adds the records to the collecion + /// </summary> + /// <param name="collection">The collection to add records to</param> + /// <param name="page">Pagination page to get records from</param> + /// <param name="limit">The maximum number of items to retrieve from the store</param> + /// <param name="constraints">A params array of strings to constrain the result set from the db</param> + /// <returns>A task that resolves the number of items added to the collection</returns> + Task<int> GetPageAsync(ICollection<T> collection, int page, int limit, params string[] constraints); + } + +} diff --git a/VNLib.Plugins.Extensions.Data/Abstractions/IUserEntity.cs b/VNLib.Plugins.Extensions.Data/Abstractions/IUserEntity.cs new file mode 100644 index 0000000..6026f85 --- /dev/null +++ b/VNLib.Plugins.Extensions.Data/Abstractions/IUserEntity.cs @@ -0,0 +1,15 @@ +using System; + +namespace VNLib.Plugins.Extensions.Data.Abstractions +{ + /// <summary> + /// Defines an entity base that has an owner, identified by its user-id + /// </summary> + public interface IUserEntity + { + /// <summary> + /// The user-id of the owner of the entity + /// </summary> + string? UserId { get; set; } + } +} diff --git a/VNLib.Plugins.Extensions.Data/DbModelBase.cs b/VNLib.Plugins.Extensions.Data/DbModelBase.cs new file mode 100644 index 0000000..fc9d1fc --- /dev/null +++ b/VNLib.Plugins.Extensions.Data/DbModelBase.cs @@ -0,0 +1,24 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.Text.Json.Serialization; + +namespace VNLib.Plugins.Extensions.Data +{ + /// <summary> + /// Provides a base for DBSet Records with a timestamp/version + /// a unique ID key, and create/modified timestamps + /// </summary> + public abstract class DbModelBase : IDbModel + { + ///<inheritdoc/> + public abstract string Id { get; set; } + ///<inheritdoc/> + [Timestamp] + [JsonIgnore] + public virtual byte[]? Version { get; set; } + ///<inheritdoc/> + public abstract DateTime Created { get; set; } + ///<inheritdoc/> + public abstract DateTime LastModified { get; set; } + } +} diff --git a/VNLib.Plugins.Extensions.Data/DbStore.cs b/VNLib.Plugins.Extensions.Data/DbStore.cs new file mode 100644 index 0000000..19ada7f --- /dev/null +++ b/VNLib.Plugins.Extensions.Data/DbStore.cs @@ -0,0 +1,501 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +using Microsoft.EntityFrameworkCore; + +using VNLib.Utils; +using VNLib.Utils.Memory.Caching; +using VNLib.Plugins.Extensions.Data.Abstractions; + +namespace VNLib.Plugins.Extensions.Data +{ + /// <summary> + /// Implements basic data-store functionality with abstract query builders + /// </summary> + /// <typeparam name="T">A <see cref="DbModelBase"/> implemented type</typeparam> + public abstract class DbStore<T> : IDataStore<T>, IPaginatedDataStore<T> where T: class, IDbModel + { + /// <summary> + /// Gets a unique ID for a new record being added to the store + /// </summary> + public abstract string RecordIdBuilder { get; } + /// <summary> + /// Gets a new <see cref="TransactionalDbContext"/> ready for use + /// </summary> + /// <returns></returns> + public abstract TransactionalDbContext NewContext(); + + /// <summary> + /// An object rental for entity collections + /// </summary> + public ObjectRental<List<T>> ListRental { get; } = ObjectRental.Create<List<T>>(null, static ret => ret.Clear()); + + #region Add Or Update + ///<inheritdoc/> + public virtual async Task<ERRNO> AddOrUpdateAsync(T record) + { + //Open new db context + await using TransactionalDbContext ctx = NewContext(); + //Open transaction + await ctx.OpenTransactionAsync(); + IQueryable<T> query; + if (string.IsNullOrWhiteSpace(record.Id)) + { + //Get the application + query = AddOrUpdateQueryBuilder(ctx, record); + } + else + { + //Get the application + query = (from et in ctx.Set<T>() + where et.Id == record.Id + select et); + } + //Using single + T? entry = await query.SingleOrDefaultAsync(); + //Check if creted + if (entry == null) + { + //Create a new template id + record.Id = RecordIdBuilder; + //Set the created/lm times + record.Created = record.LastModified = DateTime.UtcNow; + //Add the new template to the ctx + ctx.Add(record); + } + else + { + OnRecordUpdate(record, entry); + } + //Save changes + ERRNO result = await ctx.SaveChangesAsync(); + if (result) + { + //commit transaction if update was successful + await ctx.CommitTransactionAsync(); + } + return result; + } + ///<inheritdoc/> + public virtual async Task<ERRNO> UpdateAsync(T record) + { + //Open new db context + await using TransactionalDbContext ctx = NewContext(); + //Open transaction + await ctx.OpenTransactionAsync(); + //Get the application + IQueryable<T> query = UpdateQueryBuilder(ctx, record); + //Using single to make sure only one app is in the db (should never be an issue) + T? oldEntry = await query.SingleOrDefaultAsync(); + if (oldEntry == null) + { + return false; + } + //Update the template meta-data + OnRecordUpdate(record, oldEntry); + //Only publish update if changes happened + if (!ctx.ChangeTracker.HasChanges()) + { + //commit transaction if no changes need to be made + await ctx.CommitTransactionAsync(); + return true; + } + //Save changes + ERRNO result = await ctx.SaveChangesAsync(); + if (result) + { + //commit transaction if update was successful + await ctx.CommitTransactionAsync(); + } + return result; + } + ///<inheritdoc/> + public virtual async Task<ERRNO> CreateAsync(T record) + { + //Open new db context + await using TransactionalDbContext ctx = NewContext(); + //Open transaction + await ctx.OpenTransactionAsync(); + //Create a new template id + record.Id = RecordIdBuilder; + //Update the created/last modified time of the record + record.Created = record.LastModified = DateTime.UtcNow; + //Add the new template + ctx.Add(record); + //save changes + ERRNO result = await ctx.SaveChangesAsync(); + if (result) + { + //Commit transaction + await ctx.CommitTransactionAsync(); + } + return result; + } + + /// <summary> + /// Builds a query that attempts to get a single entry from the + /// store based on the specified record if it does not have a + /// valid <see cref="DbModelBase.Id"/> property + /// </summary> + /// <param name="context">The active context to query</param> + /// <param name="record">The record to search for</param> + /// <returns>A query that yields a single record if it exists in the store</returns> + protected virtual IQueryable<T> AddOrUpdateQueryBuilder(TransactionalDbContext context, T record) + { + //default to get single of the specific record + return GetSingleQueryBuilder(context, record); + } + /// <summary> + /// Builds a query that attempts to get a single entry from the + /// store to update based on the specified record + /// </summary> + /// <param name="context">The active context to query</param> + /// <param name="record">The record to search for</param> + /// <returns>A query that yields a single record to update if it exists in the store</returns> + protected virtual IQueryable<T> UpdateQueryBuilder(TransactionalDbContext context, T record) + { + //default to get single of the specific record + return GetSingleQueryBuilder(context, record); + } + /// <summary> + /// Updates the current record (if found) to the new record before + /// storing the updates. + /// </summary> + /// <param name="newRecord">The new record to capture data from</param> + /// <param name="currentRecord">The current record to be updated</param> + protected abstract void OnRecordUpdate(T newRecord, T currentRecord); + #endregion + + #region Delete + ///<inheritdoc/> + public virtual async Task<ERRNO> DeleteAsync(string key) + { + //Open new db context + await using TransactionalDbContext ctx = NewContext(); + //Open transaction + await ctx.OpenTransactionAsync(); + //Get the template by its id + IQueryable<T> query = (from temp in ctx.Set<T>() + where temp.Id == key + select temp); + T? record = await query.SingleOrDefaultAsync(); + if (record == null) + { + return false; + } + //Add the new application + ctx.Remove(record); + //Save changes + ERRNO result = await ctx.SaveChangesAsync(); + if (result) + { + //Commit transaction + await ctx.CommitTransactionAsync(); + } + return result; + } + ///<inheritdoc/> + public virtual async Task<ERRNO> DeleteAsync(T record) + { + //Open new db context + await using TransactionalDbContext ctx = NewContext(); + //Open transaction + await ctx.OpenTransactionAsync(); + //Get a query for a a single item + IQueryable<T> query = GetSingleQueryBuilder(ctx, record); + //Get the entry + T? entry = await query.SingleOrDefaultAsync(); + if (entry == null) + { + return false; + } + //Add the new application + ctx.Remove(entry); + //Save changes + ERRNO result = await ctx.SaveChangesAsync(); + if (result) + { + //Commit transaction + await ctx.CommitTransactionAsync(); + } + return result; + } + ///<inheritdoc/> + public virtual async Task<ERRNO> DeleteAsync(params string[] specifiers) + { + //Open new db context + await using TransactionalDbContext ctx = NewContext(); + //Open transaction + await ctx.OpenTransactionAsync(); + //Get the template by its id + IQueryable<T> query = DeleteQueryBuilder(ctx, specifiers); + T? entry = await query.SingleOrDefaultAsync(); + if (entry == null) + { + return false; + } + //Add the new application + ctx.Remove(entry); + //Save changes + ERRNO result = await ctx.SaveChangesAsync(); + if (result) + { + //Commit transaction + await ctx.CommitTransactionAsync(); + } + return result; + } + + /// <summary> + /// Builds a query that results in a single entry to delete from the + /// constraint arguments + /// </summary> + /// <param name="context">The active context</param> + /// <param name="constraints">A variable length parameter array of query constraints</param> + /// <returns>A query that yields a single record (or no record) to delete</returns> + protected virtual IQueryable<T> DeleteQueryBuilder(TransactionalDbContext context, params string[] constraints) + { + //default use the get-single method, as the implementation is usually identical + return GetSingleQueryBuilder(context, constraints); + } + #endregion + + #region Get Collection + ///<inheritdoc/> + public virtual async Task<ERRNO> GetCollectionAsync(ICollection<T> collection, string specifier, int limit) + { + //Open new db context + await using TransactionalDbContext ctx = NewContext(); + //Open transaction + await ctx.OpenTransactionAsync(); + //Get the single template by its id + IAsyncEnumerable<T> entires = GetCollectionQueryBuilder(ctx, specifier).Take(limit).AsAsyncEnumerable(); + int count = 0; + //Enumrate the template and add them to collection + await foreach (T entry in entires) + { + collection.Add(entry); + count++; + } + //close db and transaction + await ctx.CommitTransactionAsync(); + //Return the number of elements add to the collection + return count; + } + ///<inheritdoc/> + public virtual async Task<ERRNO> GetCollectionAsync(ICollection<T> collection, int limit, params string[] args) + { + //Open new db context + await using TransactionalDbContext ctx = NewContext(); + //Open transaction + await ctx.OpenTransactionAsync(); + //Get the single template by its id + IAsyncEnumerable<T> entires = GetCollectionQueryBuilder(ctx, args).Take(limit).AsAsyncEnumerable(); + int count = 0; + //Enumrate the template and add them to collection + await foreach (T entry in entires) + { + collection.Add(entry); + count++; + } + //close db and transaction + await ctx.CommitTransactionAsync(); + //Return the number of elements add to the collection + return count; + } + + /// <summary> + /// Builds a query to get a count of records constrained by the specifier + /// </summary> + /// <param name="context">The active context to run the query on</param> + /// <param name="specifier">The specifier constrain</param> + /// <returns>A query that can be counted</returns> + protected virtual IQueryable<T> GetCollectionQueryBuilder(TransactionalDbContext context, string specifier) + { + return GetCollectionQueryBuilder(context, new string[] { specifier }); + } + + /// <summary> + /// Builds a query to get a collection of records based on an variable length array of parameters + /// </summary> + /// <param name="context">The active context to run the query on</param> + /// <param name="constraints">An arguments array to constrain the results of the query</param> + /// <returns>A query that returns a collection of records from the store</returns> + protected abstract IQueryable<T> GetCollectionQueryBuilder(TransactionalDbContext context, params string[] constraints); + + #endregion + + #region Get Count + ///<inheritdoc/> + public virtual async Task<long> GetCountAsync() + { + //Open db connection + await using TransactionalDbContext ctx = NewContext(); + //Open transaction + await ctx.OpenTransactionAsync(); + //Async get the number of records of the given entity type + long count = await ctx.Set<T>().LongCountAsync(); + //close db and transaction + await ctx.CommitTransactionAsync(); + return count; + } + ///<inheritdoc/> + public virtual async Task<long> GetCountAsync(string specifier) + { + await using TransactionalDbContext ctx = NewContext(); + //Open transaction + await ctx.OpenTransactionAsync(); + //Async get the number of records of the given entity type + long count = await GetCountQueryBuilder(ctx, specifier).LongCountAsync(); + //close db and transaction + await ctx.CommitTransactionAsync(); + return count; + } + + /// <summary> + /// Builds a query to get a count of records constrained by the specifier + /// </summary> + /// <param name="context">The active context to run the query on</param> + /// <param name="specifier">The specifier constrain</param> + /// <returns>A query that can be counted</returns> + protected virtual IQueryable<T> GetCountQueryBuilder(TransactionalDbContext context, string specifier) + { + //Default use the get collection and just call the count method + return GetCollectionQueryBuilder(context, specifier); + } + #endregion + + #region Get Single + ///<inheritdoc/> + public virtual async Task<T?> GetSingleAsync(string key) + { + //Open db connection + await using TransactionalDbContext ctx = NewContext(); + //Open transaction + await ctx.OpenTransactionAsync(); + //Get the single template by its id + T? record = await (from entry in ctx.Set<T>() + where entry.Id == key + select entry) + .SingleOrDefaultAsync(); + //close db and transaction + await ctx.CommitTransactionAsync(); + return record; + } + ///<inheritdoc/> + public virtual async Task<T?> GetSingleAsync(T record) + { + //Open db connection + await using TransactionalDbContext ctx = NewContext(); + //Open transaction + await ctx.OpenTransactionAsync(); + //Get the single template by its id + T? entry = await GetSingleQueryBuilder(ctx, record).SingleOrDefaultAsync(); + //close db and transaction + await ctx.CommitTransactionAsync(); + return record; + } + ///<inheritdoc/> + public virtual async Task<T?> GetSingleAsync(params string[] specifiers) + { + //Open db connection + await using TransactionalDbContext ctx = NewContext(); + //Open transaction + await ctx.OpenTransactionAsync(); + //Get the single template by its id + T? record = await GetSingleQueryBuilder(ctx, specifiers).SingleOrDefaultAsync(); + //close db and transaction + await ctx.CommitTransactionAsync(); + return record; + } + /// <summary> + /// Builds a query to get a single record from the variable length parameter arguments + /// </summary> + /// <param name="context">The context to execute query against</param> + /// <param name="constraints">Arguments to constrain the results of the query to a single record</param> + /// <returns>A query that yields a single record</returns> + protected abstract IQueryable<T> GetSingleQueryBuilder(TransactionalDbContext context, params string[] constraints); + /// <summary> + /// <para> + /// Builds a query to get a single record from the specified record. + /// </para> + /// <para> + /// Unless overridden, performs an ID based query for a single entry + /// </para> + /// </summary> + /// <param name="context">The context to execute query against</param> + /// <param name="record">A record to referrence the lookup</param> + /// <returns>A query that yields a single record</returns> + protected virtual IQueryable<T> GetSingleQueryBuilder(TransactionalDbContext context, T record) + { + return from entry in context.Set<T>() + where entry.Id == record.Id + select entry; + } + #endregion + + #region Get Page + ///<inheritdoc/> + public virtual async Task<int> GetPageAsync(ICollection<T> collection, int page, int limit) + { + //Open db connection + await using TransactionalDbContext ctx = NewContext(); + //Open transaction + await ctx.OpenTransactionAsync(); + //Get a page offset and a limit for the + IAsyncEnumerable<T> records = ctx.Set<T>() + .Skip(page * limit) + .Take(limit) + .AsAsyncEnumerable(); + int count = 0; + //Enumrate the template and add them to collection + await foreach (T record in records) + { + collection.Add(record); + count++; + } + //close db and transaction + await ctx.CommitTransactionAsync(); + //Return the number of elements add to the collection + return count; + } + ///<inheritdoc/> + public virtual async Task<int> GetPageAsync(ICollection<T> collection, int page, int limit, params string[] constraints) + { + //Open new db context + await using TransactionalDbContext ctx = NewContext(); + //Open transaction + await ctx.OpenTransactionAsync(); + //Get the single template by its id + IAsyncEnumerable<T> entires = GetPageQueryBuilder(ctx, constraints) + .Skip(page * limit) + .Take(limit) + .AsAsyncEnumerable(); + int count = 0; + //Enumrate the template and add them to collection + await foreach (T entry in entires) + { + collection.Add(entry); + count++; + } + //close db and transaction + await ctx.CommitTransactionAsync(); + //Return the number of elements add to the collection + return count; + } + /// <summary> + /// Builds a query to get a collection of records based on an variable length array of parameters + /// </summary> + /// <param name="context">The active context to run the query on</param> + /// <param name="constraints">An arguments array to constrain the results of the query</param> + /// <returns>A query that returns a paginated collection of records from the store</returns> + protected virtual IQueryable<T> GetPageQueryBuilder(TransactionalDbContext context, params string[] constraints) + { + //Default to getting the entire collection and just selecting a single page + return GetCollectionQueryBuilder(context, constraints); + } + #endregion + } +} diff --git a/VNLib.Plugins.Extensions.Data/Extensions.cs b/VNLib.Plugins.Extensions.Data/Extensions.cs new file mode 100644 index 0000000..3962a6d --- /dev/null +++ b/VNLib.Plugins.Extensions.Data/Extensions.cs @@ -0,0 +1,58 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using System.Collections.Generic; +using System.Collections.Immutable; + +using Microsoft.EntityFrameworkCore; + +using VNLib.Utils; +using VNLib.Plugins.Extensions.Data.Abstractions; + +namespace VNLib.Plugins.Extensions.Data +{ + public static class Extensions + { + + public static int GetPageOrDefault(this IReadOnlyDictionary<string, string> queryArgs, int @default, int minClamp = 0, int maxClamp = int.MaxValue) + { + return queryArgs.TryGetValue("page", out string? pageStr) && int.TryParse(pageStr, out int page) ? Math.Clamp(page, minClamp, maxClamp) : @default; + } + + public static int GetLimitOrDefault(this IReadOnlyDictionary<string, string> queryArgs, int @default, int minClamp = 0, int maxClamp = int.MaxValue) + { + return queryArgs.TryGetValue("limit", out string? limitStr) && int.TryParse(limitStr, out int limit) ? Math.Clamp(limit, minClamp, maxClamp) : @default; + } + + public static async Task<ERRNO> AddBulkAsync<TEntity>(this DbStore<TEntity> store, IEnumerable<TEntity> records, string userId, bool overwriteTime = true) + where TEntity : class, IDbModel, IUserEntity + { + //Open context and transaction + await using TransactionalDbContext database = store.NewContext(); + await database.OpenTransactionAsync(); + //Get the entity set + DbSet<TEntity> set = database.Set<TEntity>(); + //Generate random ids for the feeds and set user-id + foreach (TEntity entity in records) + { + entity.Id = store.RecordIdBuilder; + //Explicitly assign the user-id + entity.UserId = userId; + //If the entity has the default created time, update it, otherwise leave it as is + if (overwriteTime || entity.Created == default) + { + entity.Created = DateTime.UtcNow; + } + //Update last-modified time + entity.LastModified = DateTime.UtcNow; + } + //Add feeds to database + set.AddRange(records); + //Commit changes + ERRNO count = await database.SaveChangesAsync(); + //Commit transaction and exit + await database.CommitTransactionAsync(); + return count; + } + } +} diff --git a/VNLib.Plugins.Extensions.Data/IDbModel.cs b/VNLib.Plugins.Extensions.Data/IDbModel.cs new file mode 100644 index 0000000..fa05307 --- /dev/null +++ b/VNLib.Plugins.Extensions.Data/IDbModel.cs @@ -0,0 +1,28 @@ +using System; + +namespace VNLib.Plugins.Extensions.Data +{ + /// <summary> + /// Represents a basic data model for an EFCore entity + /// for support in data-stores + /// </summary> + public interface IDbModel + { + /// <summary> + /// A unique id for the entity + /// </summary> + string Id { get; set; } + /// <summary> + /// The <see cref="DateTime"/> the entity was created in the store + /// </summary> + DateTime Created { get; set; } + /// <summary> + /// The <see cref="DateTime"/> the entity was last modified in the store + /// </summary> + DateTime LastModified { get; set; } + /// <summary> + /// Entity concurrency token + /// </summary> + byte[]? Version { get; set; } + } +}
\ No newline at end of file diff --git a/VNLib.Plugins.Extensions.Data/ProtectedDbStore.cs b/VNLib.Plugins.Extensions.Data/ProtectedDbStore.cs new file mode 100644 index 0000000..00f0bf2 --- /dev/null +++ b/VNLib.Plugins.Extensions.Data/ProtectedDbStore.cs @@ -0,0 +1,46 @@ +using System; +using System.Linq; + +using VNLib.Plugins.Extensions.Data.Abstractions; + +namespace VNLib.Plugins.Extensions.Data +{ +#nullable enable + /// <summary> + /// A data store that provides unique identities and protections based on an entity that has an owner <see cref="IUserEntity"/> + /// </summary> + public abstract class ProtectedDbStore<TEntity> : DbStore<TEntity> where TEntity : class, IDbModel, IUserEntity + { + ///<inheritdoc/> + protected override IQueryable<TEntity> GetCollectionQueryBuilder(TransactionalDbContext context, params string[] constraints) + { + string userId = constraints[0]; + //Query items for the user and its id + return from item in context.Set<TEntity>() + where item.UserId == userId + orderby item.Created descending + select item; + } + + /// <summary> + /// Gets a single item contrained by a given user-id and item id + /// </summary> + /// <param name="context"></param> + /// <param name="constraints"></param> + /// <returns></returns> + protected override IQueryable<TEntity> GetSingleQueryBuilder(TransactionalDbContext context, params string[] constraints) + { + string key = constraints[0]; + string userId = constraints[1]; + //Query items for the user and its id + return from item in context.Set<TEntity>() + where item.Id == key && item.UserId == userId + select item; + } + ///<inheritdoc/> + protected override IQueryable<TEntity> GetSingleQueryBuilder(TransactionalDbContext context, TEntity record) + { + return this.GetSingleQueryBuilder(context, record.Id, record.UserId); + } + } +} diff --git a/VNLib.Plugins.Extensions.Data/ProtectedEntityExtensions.cs b/VNLib.Plugins.Extensions.Data/ProtectedEntityExtensions.cs new file mode 100644 index 0000000..6d0dcec --- /dev/null +++ b/VNLib.Plugins.Extensions.Data/ProtectedEntityExtensions.cs @@ -0,0 +1,62 @@ +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +using VNLib.Utils; +using VNLib.Plugins.Extensions.Data.Abstractions; + +namespace VNLib.Plugins.Extensions.Data +{ + public static class ProtectedEntityExtensions + { + /// <summary> + /// Updates the specified record within the store + /// </summary> + /// <param name="store"></param> + /// <param name="record">The record to update</param> + /// <param name="userId">The userid of the record owner</param> + /// <returns>A task that evaluates to the number of records modified</returns> + public static Task<ERRNO> UpdateAsync<TEntity>(this IDataStore<TEntity> store, TEntity record, string userId) where TEntity : class, IDbModel, IUserEntity + { + record.UserId = userId; + return store.UpdateAsync(record); + } + + /// <summary> + /// Updates the specified record within the store + /// </summary> + /// <param name="store"></param> + /// <param name="record">The record to update</param> + /// <param name="userId">The userid of the record owner</param> + /// <returns>A task that evaluates to the number of records modified</returns> + public static Task<ERRNO> CreateAsync<TEntity>(this IDataStore<TEntity> store, TEntity record, string userId) where TEntity : class, IDbModel, IUserEntity + { + record.UserId = userId; + return store.CreateAsync(record); + } + + /// <summary> + /// Gets a single entity from its ID and user-id + /// </summary> + /// <param name="store"></param> + /// <param name="key">The unique id of the entity</param> + /// <param name="userId">The user's id that owns the resource</param> + /// <returns>A task that resolves the entity or null if not found</returns> + public static Task<TEntity?> GetSingleAsync<TEntity>(this IDataStore<TEntity> store, string key, string userId) where TEntity : class, IDbModel, IUserEntity + { + return store.GetSingleAsync(key, userId); + } + + /// <summary> + /// Deletes a single entiry by its ID only if it belongs to the speicifed user + /// </summary> + /// <param name="store"></param> + /// <param name="key">The unique id of the entity</param> + /// <param name="userId">The user's id that owns the resource</param> + /// <returns>A task the resolves the number of eneities deleted (should evaluate to true or false)</returns> + public static Task<ERRNO> DeleteAsync<TEntity>(this IDataStore<TEntity> store, string key, string userId) where TEntity : class, IDbModel, IUserEntity + { + return store.DeleteAsync(key, userId); + } + } +} diff --git a/VNLib.Plugins.Extensions.Data/TransactionalDbContext.cs b/VNLib.Plugins.Extensions.Data/TransactionalDbContext.cs new file mode 100644 index 0000000..8573c8f --- /dev/null +++ b/VNLib.Plugins.Extensions.Data/TransactionalDbContext.cs @@ -0,0 +1,69 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Storage; + +namespace VNLib.Plugins.Extensions.Data +{ + public abstract class TransactionalDbContext : DbContext, IAsyncDisposable, IDisposable + { + /// <summary> + /// <inheritdoc/> + /// </summary> + protected TransactionalDbContext() + {} + /// <summary> + /// <inheritdoc/> + /// </summary> + protected TransactionalDbContext(DbContextOptions options) : base(options) + {} + + /// <summary> + /// The transaction that was opened on the current context + /// </summary> + public IDbContextTransaction? Transaction { get; set; } + ///<inheritdoc/> + public override void Dispose() + { + //dispose the transaction + this.Transaction?.Dispose(); + base.Dispose(); + } + + /// <summary> + /// Opens a single transaction on the current context. If a transaction is already open, + /// it is disposed and a new transaction is begun. + /// </summary> + public async Task OpenTransactionAsync(CancellationToken cancellationToken = default) + { + //open a new transaction on the current database + this.Transaction = await base.Database.BeginTransactionAsync(cancellationToken); + } + /// <summary> + /// Invokes the <see cref="IDbContextTransaction.Commit"/> on the current context + /// </summary> + public Task CommitTransactionAsync(CancellationToken token = default) + { + return Transaction != null ? Transaction.CommitAsync(token) : Task.CompletedTask; + } + /// <summary> + /// Invokes the <see cref="IDbContextTransaction.Rollback"/> on the current context + /// </summary> + public Task RollbackTransctionAsync(CancellationToken token = default) + { + return Transaction != null ? Transaction.RollbackAsync(token) : Task.CompletedTask; + } + ///<inheritdoc/> + public override async ValueTask DisposeAsync() + { + //If transaction has been created, dispose the transaction + if(this.Transaction != null) + { + await this.Transaction.DisposeAsync(); + } + await base.DisposeAsync(); + GC.SuppressFinalize(this); + } + } +}
\ No newline at end of file diff --git a/VNLib.Plugins.Extensions.Data/VNLib.Plugins.Extensions.Data.csproj b/VNLib.Plugins.Extensions.Data/VNLib.Plugins.Extensions.Data.csproj new file mode 100644 index 0000000..2a87627 --- /dev/null +++ b/VNLib.Plugins.Extensions.Data/VNLib.Plugins.Extensions.Data.csproj @@ -0,0 +1,41 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <TargetFramework>net6.0</TargetFramework> + <RootNamespace>VNLib.Plugins.Extensions.Data</RootNamespace> + <Platforms>AnyCPU;x64</Platforms> + </PropertyGroup> + + <!-- Resolve nuget dll files and store them in the output dir --> + <PropertyGroup> + <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> + <AssemblyName>VNLib.Plugins.Extensions.Data</AssemblyName> + <Authors>Vaughn Nugent</Authors> + <Description>Data extensions for VNLib Plugins</Description> + <Copyright>Copyright © 2022 Vaughn Nugent</Copyright> + <PackageProjectUrl>www.vaughnnugent.com/resources</PackageProjectUrl> + <Version>1.0.0.1</Version> + <GeneratePackageOnBuild>false</GeneratePackageOnBuild> + <Nullable>enable</Nullable> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <DocumentationFile>l</DocumentationFile> + </PropertyGroup> + + <ItemGroup> + <PackageReference Include="ErrorProne.NET.CoreAnalyzers" Version="0.1.2"> + <PrivateAssets>all</PrivateAssets> + <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> + </PackageReference> + <PackageReference Include="ErrorProne.NET.Structs" Version="0.1.2"> + <PrivateAssets>all</PrivateAssets> + <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> + </PackageReference> + <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.10" /> + </ItemGroup> + + <ItemGroup> + <ProjectReference Include="..\..\..\VNLib\Utils\src\VNLib.Utils.csproj" /> + </ItemGroup> + +</Project> diff --git a/VNLib.Plugins.Extensions.Data/VNLib.Plugins.Extensions.Data.xml b/VNLib.Plugins.Extensions.Data/VNLib.Plugins.Extensions.Data.xml new file mode 100644 index 0000000..638637d --- /dev/null +++ b/VNLib.Plugins.Extensions.Data/VNLib.Plugins.Extensions.Data.xml @@ -0,0 +1,473 @@ +<?xml version="1.0"?> +<doc> + <assembly> + <name>VNLib.Plugins.Extensions.Data</name> + </assembly> + <members> + <member name="T:VNLib.Plugins.Extensions.Data.Abstractions.IBulkDataStore`1"> + <summary> + An abstraction that defines a Data-Store that supports + bulk data operations + </summary> + <typeparam name="T">The data-model type</typeparam> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IBulkDataStore`1.DeleteBulkAsync(System.Collections.Generic.ICollection{`0})"> + <summary> + Deletes a collection of records from the store + </summary> + <param name="records">A collection of records to delete</param> + <returns>A task the resolves the number of entires removed from the store</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IBulkDataStore`1.UpdateBulkAsync(System.Collections.Generic.ICollection{`0})"> + <summary> + Updates a collection of records + </summary> + <param name="records">The collection of records to update</param> + <returns>A task the resolves an error code (should evaluate to false on failure, and true on success)</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IBulkDataStore`1.CreateBulkAsync(System.Collections.Generic.ICollection{`0})"> + <summary> + Creates a bulk collection of records as entries in the store + </summary> + <param name="records">The collection of records to add</param> + <returns>A task the resolves an error code (should evaluate to false on failure, and true on success)</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IBulkDataStore`1.AddOrUpdateBulkAsync(System.Collections.Generic.ICollection{`0})"> + <summary> + Creates or updates individual records from a bulk collection of records + </summary> + <param name="records">The collection of records to add</param> + <returns>A task the resolves an error code (should evaluate to false on failure, and true on success)</returns> + </member> + <member name="T:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1"> + <summary> + An abstraction that defines a Data-Store and common + operations that retrieve or manipulate records of data + </summary> + <typeparam name="T">The data-model type</typeparam> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.GetCountAsync"> + <summary> + Gets the total number of records in the current store + </summary> + <returns>A task that resolves the number of records in the store</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.GetCountAsync(System.String)"> + <summary> + Gets the number of records that belong to the specified constraint + </summary> + <param name="specifier">A specifier to constrain the reults</param> + <returns>The number of records that belong to the specifier</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.GetSingleAsync(System.String)"> + <summary> + Gets a record from its key + </summary> + <param name="key">The key identifying the unique record</param> + <returns>A promise that resolves the record identified by the specified key</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.GetSingleAsync(System.String[])"> + <summary> + Gets a record from its key + </summary> + <param name="specifiers">A variable length specifier arguemnt array for retreiving a single application</param> + <returns></returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.GetSingleAsync(`0)"> + <summary> + Gets a record from the store with a partial model, intended to complete the model + </summary> + <param name="record">The partial model used to query the store</param> + <returns>A task the resolves the completed data-model</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.GetCollectionAsync(System.Collections.Generic.ICollection{`0},System.String,System.Int32)"> + <summary> + Fills a collection with enires retireved from the store using the specifer + </summary> + <param name="collection">The collection to add entires to</param> + <param name="specifier">A specifier argument to constrain results</param> + <param name="limit">The maximum number of elements to retrieve</param> + <returns>A Task the resolves to the number of items added to the collection</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.GetCollectionAsync(System.Collections.Generic.ICollection{`0},System.Int32,System.String[])"> + <summary> + Fills a collection with enires retireved from the store using a variable length specifier + parameter + </summary> + <param name="collection">The collection to add entires to</param> + <param name="limit">The maximum number of elements to retrieve</param> + <param name="args"></param> + <returns>A Task the resolves to the number of items added to the collection</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.UpdateAsync(`0)"> + <summary> + Updates an entry in the store with the specified record + </summary> + <param name="record">The record to update</param> + <returns>A task the resolves an error code (should evaluate to false on failure, and true on success)</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.CreateAsync(`0)"> + <summary> + Creates a new entry in the store representing the specified record + </summary> + <param name="record">The record to add to the store</param> + <returns>A task the resolves an error code (should evaluate to false on failure, and true on success)</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.DeleteAsync(`0)"> + <summary> + Deletes one or more entrires from the store matching the specified record + </summary> + <param name="record">The record to remove from the store</param> + <returns>A task the resolves the number of records removed(should evaluate to false on failure, and deleted count on success)</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.DeleteAsync(System.String)"> + <summary> + Deletes one or more entires from the store matching the specified unique key + </summary> + <param name="key">The unique key that identifies the record</param> + <returns>A task the resolves the number of records removed(should evaluate to false on failure, and deleted count on success)</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.DeleteAsync(System.String[])"> + <summary> + Deletes one or more entires from the store matching the supplied specifiers + </summary> + <param name="specifiers">A variable length array of specifiers used to delete one or more entires</param> + <returns>A task the resolves the number of records removed(should evaluate to false on failure, and deleted count on success)</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.AddOrUpdateAsync(`0)"> + <summary> + Updates an entry in the store if it exists, or creates a new entry if one does not already exist + </summary> + <param name="record">The record to add to the store</param> + <returns>A task the resolves the result of the operation</returns> + </member> + <member name="T:VNLib.Plugins.Extensions.Data.Abstractions.IPaginatedDataStore`1"> + <summary> + Defines a Data-Store that can retirieve and manipulate paginated + data + </summary> + <typeparam name="T">The data-model type</typeparam> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IPaginatedDataStore`1.GetPageAsync(System.Collections.Generic.ICollection{`0},System.Int32,System.Int32)"> + <summary> + Gets a collection of records using a pagination style query, and adds the records to the collecion + </summary> + <param name="collection">The collection to add records to</param> + <param name="page">Pagination page to get records from</param> + <param name="limit">The maximum number of items to retrieve from the store</param> + <returns>A task that resolves the number of items added to the collection</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IPaginatedDataStore`1.GetPageAsync(System.Collections.Generic.ICollection{`0},System.Int32,System.Int32,System.String[])"> + <summary> + Gets a collection of records using a pagination style query with constraint arguments, and adds the records to the collecion + </summary> + <param name="collection">The collection to add records to</param> + <param name="page">Pagination page to get records from</param> + <param name="limit">The maximum number of items to retrieve from the store</param> + <param name="constraints">A params array of strings to constrain the result set from the db</param> + <returns>A task that resolves the number of items added to the collection</returns> + </member> + <member name="T:VNLib.Plugins.Extensions.Data.Abstractions.IUserEntity"> + <summary> + Defines an entity base that has an owner, identified by its user-id + </summary> + </member> + <member name="P:VNLib.Plugins.Extensions.Data.Abstractions.IUserEntity.UserId"> + <summary> + The user-id of the owner of the entity + </summary> + </member> + <member name="T:VNLib.Plugins.Extensions.Data.DbModelBase"> + <summary> + Provides a base for DBSet Records with a timestamp/version + a unique ID key, and create/modified timestamps + </summary> + </member> + <member name="P:VNLib.Plugins.Extensions.Data.DbModelBase.Id"> + <inheritdoc/> + </member> + <member name="P:VNLib.Plugins.Extensions.Data.DbModelBase.Version"> + <inheritdoc/> + </member> + <member name="P:VNLib.Plugins.Extensions.Data.DbModelBase.Created"> + <inheritdoc/> + </member> + <member name="P:VNLib.Plugins.Extensions.Data.DbModelBase.LastModified"> + <inheritdoc/> + </member> + <member name="T:VNLib.Plugins.Extensions.Data.DbStore`1"> + <summary> + Implements basic data-store functionality with abstract query builders + </summary> + <typeparam name="T">A <see cref="T:VNLib.Plugins.Extensions.Data.DbModelBase"/> implemented type</typeparam> + </member> + <member name="P:VNLib.Plugins.Extensions.Data.DbStore`1.RecordIdBuilder"> + <summary> + Gets a unique ID for a new record being added to the store + </summary> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.NewContext"> + <summary> + Gets a new <see cref="T:VNLib.Plugins.Extensions.Data.TransactionalDbContext"/> ready for use + </summary> + <returns></returns> + </member> + <member name="P:VNLib.Plugins.Extensions.Data.DbStore`1.ListRental"> + <summary> + An object rental for entity collections + </summary> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.AddOrUpdateAsync(`0)"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.UpdateAsync(`0)"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.CreateAsync(`0)"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.AddOrUpdateQueryBuilder(VNLib.Plugins.Extensions.Data.TransactionalDbContext,`0)"> + <summary> + Builds a query that attempts to get a single entry from the + store based on the specified record if it does not have a + valid <see cref="P:VNLib.Plugins.Extensions.Data.DbModelBase.Id"/> property + </summary> + <param name="context">The active context to query</param> + <param name="record">The record to search for</param> + <returns>A query that yields a single record if it exists in the store</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.UpdateQueryBuilder(VNLib.Plugins.Extensions.Data.TransactionalDbContext,`0)"> + <summary> + Builds a query that attempts to get a single entry from the + store to update based on the specified record + </summary> + <param name="context">The active context to query</param> + <param name="record">The record to search for</param> + <returns>A query that yields a single record to update if it exists in the store</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.OnRecordUpdate(`0,`0)"> + <summary> + Updates the current record (if found) to the new record before + storing the updates. + </summary> + <param name="newRecord">The new record to capture data from</param> + <param name="currentRecord">The current record to be updated</param> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.DeleteAsync(System.String)"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.DeleteAsync(`0)"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.DeleteAsync(System.String[])"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.DeleteQueryBuilder(VNLib.Plugins.Extensions.Data.TransactionalDbContext,System.String[])"> + <summary> + Builds a query that results in a single entry to delete from the + constraint arguments + </summary> + <param name="context">The active context</param> + <param name="constraints">A variable length parameter array of query constraints</param> + <returns>A query that yields a single record (or no record) to delete</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetCollectionAsync(System.Collections.Generic.ICollection{`0},System.String,System.Int32)"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetCollectionAsync(System.Collections.Generic.ICollection{`0},System.Int32,System.String[])"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetCollectionQueryBuilder(VNLib.Plugins.Extensions.Data.TransactionalDbContext,System.String)"> + <summary> + Builds a query to get a count of records constrained by the specifier + </summary> + <param name="context">The active context to run the query on</param> + <param name="specifier">The specifier constrain</param> + <returns>A query that can be counted</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetCollectionQueryBuilder(VNLib.Plugins.Extensions.Data.TransactionalDbContext,System.String[])"> + <summary> + Builds a query to get a collection of records based on an variable length array of parameters + </summary> + <param name="context">The active context to run the query on</param> + <param name="constraints">An arguments array to constrain the results of the query</param> + <returns>A query that returns a collection of records from the store</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetCountAsync"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetCountAsync(System.String)"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetCountQueryBuilder(VNLib.Plugins.Extensions.Data.TransactionalDbContext,System.String)"> + <summary> + Builds a query to get a count of records constrained by the specifier + </summary> + <param name="context">The active context to run the query on</param> + <param name="specifier">The specifier constrain</param> + <returns>A query that can be counted</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetSingleAsync(System.String)"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetSingleAsync(`0)"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetSingleAsync(System.String[])"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetSingleQueryBuilder(VNLib.Plugins.Extensions.Data.TransactionalDbContext,System.String[])"> + <summary> + Builds a query to get a single record from the variable length parameter arguments + </summary> + <param name="context">The context to execute query against</param> + <param name="constraints">Arguments to constrain the results of the query to a single record</param> + <returns>A query that yields a single record</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetSingleQueryBuilder(VNLib.Plugins.Extensions.Data.TransactionalDbContext,`0)"> + <summary> + <para> + Builds a query to get a single record from the specified record. + </para> + <para> + Unless overridden, performs an ID based query for a single entry + </para> + </summary> + <param name="context">The context to execute query against</param> + <param name="record">A record to referrence the lookup</param> + <returns>A query that yields a single record</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetPageAsync(System.Collections.Generic.ICollection{`0},System.Int32,System.Int32)"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetPageAsync(System.Collections.Generic.ICollection{`0},System.Int32,System.Int32,System.String[])"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetPageQueryBuilder(VNLib.Plugins.Extensions.Data.TransactionalDbContext,System.String[])"> + <summary> + Builds a query to get a collection of records based on an variable length array of parameters + </summary> + <param name="context">The active context to run the query on</param> + <param name="constraints">An arguments array to constrain the results of the query</param> + <returns>A query that returns a paginated collection of records from the store</returns> + </member> + <member name="T:VNLib.Plugins.Extensions.Data.IDbModel"> + <summary> + Represents a basic data model for an EFCore entity + for support in data-stores + </summary> + </member> + <member name="P:VNLib.Plugins.Extensions.Data.IDbModel.Id"> + <summary> + A unique id for the entity + </summary> + </member> + <member name="P:VNLib.Plugins.Extensions.Data.IDbModel.Created"> + <summary> + The <see cref="T:System.DateTimeOffset"/> the entity was created in the store + </summary> + </member> + <member name="P:VNLib.Plugins.Extensions.Data.IDbModel.LastModified"> + <summary> + The <see cref="T:System.DateTimeOffset"/> the entity was last modified in the store + </summary> + </member> + <member name="P:VNLib.Plugins.Extensions.Data.IDbModel.Version"> + <summary> + Entity concurrency token + </summary> + </member> + <member name="T:VNLib.Plugins.Extensions.Data.ProtectedDbStore`1"> + <summary> + A data store that provides unique identities and protections based on an entity that has an owner <see cref="T:VNLib.Plugins.Extensions.Data.Abstractions.IUserEntity"/> + </summary> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.ProtectedDbStore`1.GetCollectionQueryBuilder(VNLib.Plugins.Extensions.Data.TransactionalDbContext,System.String[])"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.ProtectedDbStore`1.GetSingleQueryBuilder(VNLib.Plugins.Extensions.Data.TransactionalDbContext,System.String[])"> + <summary> + Gets a single item contrained by a given user-id and item id + </summary> + <param name="context"></param> + <param name="constraints"></param> + <returns></returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.ProtectedDbStore`1.GetSingleQueryBuilder(VNLib.Plugins.Extensions.Data.TransactionalDbContext,`0)"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.ProtectedEntityExtensions.UpdateAsync``1(VNLib.Plugins.Extensions.Data.Abstractions.IDataStore{``0},``0,System.String)"> + <summary> + Updates the specified record within the store + </summary> + <param name="store"></param> + <param name="record">The record to update</param> + <param name="userId">The userid of the record owner</param> + <returns>A task that evaluates to the number of records modified</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.ProtectedEntityExtensions.CreateAsync``1(VNLib.Plugins.Extensions.Data.Abstractions.IDataStore{``0},``0,System.String)"> + <summary> + Updates the specified record within the store + </summary> + <param name="store"></param> + <param name="record">The record to update</param> + <param name="userId">The userid of the record owner</param> + <returns>A task that evaluates to the number of records modified</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.ProtectedEntityExtensions.GetSingleAsync``1(VNLib.Plugins.Extensions.Data.Abstractions.IDataStore{``0},System.String,System.String)"> + <summary> + Gets a single entity from its ID and user-id + </summary> + <param name="store"></param> + <param name="key">The unique id of the entity</param> + <param name="userId">The user's id that owns the resource</param> + <returns>A task that resolves the entity or null if not found</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.ProtectedEntityExtensions.DeleteAsync``1(VNLib.Plugins.Extensions.Data.Abstractions.IDataStore{``0},System.String,System.String)"> + <summary> + Deletes a single entiry by its ID only if it belongs to the speicifed user + </summary> + <param name="store"></param> + <param name="key">The unique id of the entity</param> + <param name="userId">The user's id that owns the resource</param> + <returns>A task the resolves the number of eneities deleted (should evaluate to true or false)</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.TransactionalDbContext.#ctor"> + <summary> + <inheritdoc/> + </summary> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.TransactionalDbContext.#ctor(Microsoft.EntityFrameworkCore.DbContextOptions)"> + <summary> + <inheritdoc/> + </summary> + </member> + <member name="P:VNLib.Plugins.Extensions.Data.TransactionalDbContext.Transaction"> + <summary> + The transaction that was opened on the current context + </summary> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.TransactionalDbContext.Dispose"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.TransactionalDbContext.OpenTransactionAsync(System.Threading.CancellationToken)"> + <summary> + Opens a single transaction on the current context. If a transaction is already open, + it is disposed and a new transaction is begun. + </summary> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.TransactionalDbContext.CommitTransactionAsync(System.Threading.CancellationToken)"> + <summary> + Invokes the <see cref="M:Microsoft.EntityFrameworkCore.Storage.IDbContextTransaction.Commit"/> on the current context + </summary> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.TransactionalDbContext.RollbackTransctionAsync(System.Threading.CancellationToken)"> + <summary> + Invokes the <see cref="M:Microsoft.EntityFrameworkCore.Storage.IDbContextTransaction.Rollback"/> on the current context + </summary> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.TransactionalDbContext.DisposeAsync"> + <inheritdoc/> + </member> + </members> +</doc> diff --git a/VNLib.Plugins.Extensions.Data/l b/VNLib.Plugins.Extensions.Data/l new file mode 100644 index 0000000..72817ee --- /dev/null +++ b/VNLib.Plugins.Extensions.Data/l @@ -0,0 +1,473 @@ +<?xml version="1.0"?> +<doc> + <assembly> + <name>VNLib.Plugins.Extensions.Data</name> + </assembly> + <members> + <member name="T:VNLib.Plugins.Extensions.Data.Abstractions.IBulkDataStore`1"> + <summary> + An abstraction that defines a Data-Store that supports + bulk data operations + </summary> + <typeparam name="T">The data-model type</typeparam> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IBulkDataStore`1.DeleteBulkAsync(System.Collections.Generic.ICollection{`0})"> + <summary> + Deletes a collection of records from the store + </summary> + <param name="records">A collection of records to delete</param> + <returns>A task the resolves the number of entires removed from the store</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IBulkDataStore`1.UpdateBulkAsync(System.Collections.Generic.ICollection{`0})"> + <summary> + Updates a collection of records + </summary> + <param name="records">The collection of records to update</param> + <returns>A task the resolves an error code (should evaluate to false on failure, and true on success)</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IBulkDataStore`1.CreateBulkAsync(System.Collections.Generic.ICollection{`0})"> + <summary> + Creates a bulk collection of records as entries in the store + </summary> + <param name="records">The collection of records to add</param> + <returns>A task the resolves an error code (should evaluate to false on failure, and true on success)</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IBulkDataStore`1.AddOrUpdateBulkAsync(System.Collections.Generic.ICollection{`0})"> + <summary> + Creates or updates individual records from a bulk collection of records + </summary> + <param name="records">The collection of records to add</param> + <returns>A task the resolves an error code (should evaluate to false on failure, and true on success)</returns> + </member> + <member name="T:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1"> + <summary> + An abstraction that defines a Data-Store and common + operations that retrieve or manipulate records of data + </summary> + <typeparam name="T">The data-model type</typeparam> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.GetCountAsync"> + <summary> + Gets the total number of records in the current store + </summary> + <returns>A task that resolves the number of records in the store</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.GetCountAsync(System.String)"> + <summary> + Gets the number of records that belong to the specified constraint + </summary> + <param name="specifier">A specifier to constrain the reults</param> + <returns>The number of records that belong to the specifier</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.GetSingleAsync(System.String)"> + <summary> + Gets a record from its key + </summary> + <param name="key">The key identifying the unique record</param> + <returns>A promise that resolves the record identified by the specified key</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.GetSingleAsync(System.String[])"> + <summary> + Gets a record from its key + </summary> + <param name="specifiers">A variable length specifier arguemnt array for retreiving a single application</param> + <returns></returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.GetSingleAsync(`0)"> + <summary> + Gets a record from the store with a partial model, intended to complete the model + </summary> + <param name="record">The partial model used to query the store</param> + <returns>A task the resolves the completed data-model</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.GetCollectionAsync(System.Collections.Generic.ICollection{`0},System.String,System.Int32)"> + <summary> + Fills a collection with enires retireved from the store using the specifer + </summary> + <param name="collection">The collection to add entires to</param> + <param name="specifier">A specifier argument to constrain results</param> + <param name="limit">The maximum number of elements to retrieve</param> + <returns>A Task the resolves to the number of items added to the collection</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.GetCollectionAsync(System.Collections.Generic.ICollection{`0},System.Int32,System.String[])"> + <summary> + Fills a collection with enires retireved from the store using a variable length specifier + parameter + </summary> + <param name="collection">The collection to add entires to</param> + <param name="limit">The maximum number of elements to retrieve</param> + <param name="args"></param> + <returns>A Task the resolves to the number of items added to the collection</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.UpdateAsync(`0)"> + <summary> + Updates an entry in the store with the specified record + </summary> + <param name="record">The record to update</param> + <returns>A task the resolves an error code (should evaluate to false on failure, and true on success)</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.CreateAsync(`0)"> + <summary> + Creates a new entry in the store representing the specified record + </summary> + <param name="record">The record to add to the store</param> + <returns>A task the resolves an error code (should evaluate to false on failure, and true on success)</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.DeleteAsync(`0)"> + <summary> + Deletes one or more entrires from the store matching the specified record + </summary> + <param name="record">The record to remove from the store</param> + <returns>A task the resolves the number of records removed(should evaluate to false on failure, and deleted count on success)</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.DeleteAsync(System.String)"> + <summary> + Deletes one or more entires from the store matching the specified unique key + </summary> + <param name="key">The unique key that identifies the record</param> + <returns>A task the resolves the number of records removed(should evaluate to false on failure, and deleted count on success)</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.DeleteAsync(System.String[])"> + <summary> + Deletes one or more entires from the store matching the supplied specifiers + </summary> + <param name="specifiers">A variable length array of specifiers used to delete one or more entires</param> + <returns>A task the resolves the number of records removed(should evaluate to false on failure, and deleted count on success)</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IDataStore`1.AddOrUpdateAsync(`0)"> + <summary> + Updates an entry in the store if it exists, or creates a new entry if one does not already exist + </summary> + <param name="record">The record to add to the store</param> + <returns>A task the resolves the result of the operation</returns> + </member> + <member name="T:VNLib.Plugins.Extensions.Data.Abstractions.IPaginatedDataStore`1"> + <summary> + Defines a Data-Store that can retirieve and manipulate paginated + data + </summary> + <typeparam name="T">The data-model type</typeparam> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IPaginatedDataStore`1.GetPageAsync(System.Collections.Generic.ICollection{`0},System.Int32,System.Int32)"> + <summary> + Gets a collection of records using a pagination style query, and adds the records to the collecion + </summary> + <param name="collection">The collection to add records to</param> + <param name="page">Pagination page to get records from</param> + <param name="limit">The maximum number of items to retrieve from the store</param> + <returns>A task that resolves the number of items added to the collection</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.Abstractions.IPaginatedDataStore`1.GetPageAsync(System.Collections.Generic.ICollection{`0},System.Int32,System.Int32,System.String[])"> + <summary> + Gets a collection of records using a pagination style query with constraint arguments, and adds the records to the collecion + </summary> + <param name="collection">The collection to add records to</param> + <param name="page">Pagination page to get records from</param> + <param name="limit">The maximum number of items to retrieve from the store</param> + <param name="constraints">A params array of strings to constrain the result set from the db</param> + <returns>A task that resolves the number of items added to the collection</returns> + </member> + <member name="T:VNLib.Plugins.Extensions.Data.Abstractions.IUserEntity"> + <summary> + Defines an entity base that has an owner, identified by its user-id + </summary> + </member> + <member name="P:VNLib.Plugins.Extensions.Data.Abstractions.IUserEntity.UserId"> + <summary> + The user-id of the owner of the entity + </summary> + </member> + <member name="T:VNLib.Plugins.Extensions.Data.DbModelBase"> + <summary> + Provides a base for DBSet Records with a timestamp/version + a unique ID key, and create/modified timestamps + </summary> + </member> + <member name="P:VNLib.Plugins.Extensions.Data.DbModelBase.Id"> + <inheritdoc/> + </member> + <member name="P:VNLib.Plugins.Extensions.Data.DbModelBase.Version"> + <inheritdoc/> + </member> + <member name="P:VNLib.Plugins.Extensions.Data.DbModelBase.Created"> + <inheritdoc/> + </member> + <member name="P:VNLib.Plugins.Extensions.Data.DbModelBase.LastModified"> + <inheritdoc/> + </member> + <member name="T:VNLib.Plugins.Extensions.Data.DbStore`1"> + <summary> + Implements basic data-store functionality with abstract query builders + </summary> + <typeparam name="T">A <see cref="T:VNLib.Plugins.Extensions.Data.DbModelBase"/> implemented type</typeparam> + </member> + <member name="P:VNLib.Plugins.Extensions.Data.DbStore`1.RecordIdBuilder"> + <summary> + Gets a unique ID for a new record being added to the store + </summary> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.NewContext"> + <summary> + Gets a new <see cref="T:VNLib.Plugins.Extensions.Data.TransactionalDbContext"/> ready for use + </summary> + <returns></returns> + </member> + <member name="P:VNLib.Plugins.Extensions.Data.DbStore`1.ListRental"> + <summary> + An object rental for entity collections + </summary> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.AddOrUpdateAsync(`0)"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.UpdateAsync(`0)"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.CreateAsync(`0)"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.AddOrUpdateQueryBuilder(VNLib.Plugins.Extensions.Data.TransactionalDbContext,`0)"> + <summary> + Builds a query that attempts to get a single entry from the + store based on the specified record if it does not have a + valid <see cref="P:VNLib.Plugins.Extensions.Data.DbModelBase.Id"/> property + </summary> + <param name="context">The active context to query</param> + <param name="record">The record to search for</param> + <returns>A query that yields a single record if it exists in the store</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.UpdateQueryBuilder(VNLib.Plugins.Extensions.Data.TransactionalDbContext,`0)"> + <summary> + Builds a query that attempts to get a single entry from the + store to update based on the specified record + </summary> + <param name="context">The active context to query</param> + <param name="record">The record to search for</param> + <returns>A query that yields a single record to update if it exists in the store</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.OnRecordUpdate(`0,`0)"> + <summary> + Updates the current record (if found) to the new record before + storing the updates. + </summary> + <param name="newRecord">The new record to capture data from</param> + <param name="currentRecord">The current record to be updated</param> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.DeleteAsync(System.String)"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.DeleteAsync(`0)"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.DeleteAsync(System.String[])"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.DeleteQueryBuilder(VNLib.Plugins.Extensions.Data.TransactionalDbContext,System.String[])"> + <summary> + Builds a query that results in a single entry to delete from the + constraint arguments + </summary> + <param name="context">The active context</param> + <param name="constraints">A variable length parameter array of query constraints</param> + <returns>A query that yields a single record (or no record) to delete</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetCollectionAsync(System.Collections.Generic.ICollection{`0},System.String,System.Int32)"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetCollectionAsync(System.Collections.Generic.ICollection{`0},System.Int32,System.String[])"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetCollectionQueryBuilder(VNLib.Plugins.Extensions.Data.TransactionalDbContext,System.String)"> + <summary> + Builds a query to get a count of records constrained by the specifier + </summary> + <param name="context">The active context to run the query on</param> + <param name="specifier">The specifier constrain</param> + <returns>A query that can be counted</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetCollectionQueryBuilder(VNLib.Plugins.Extensions.Data.TransactionalDbContext,System.String[])"> + <summary> + Builds a query to get a collection of records based on an variable length array of parameters + </summary> + <param name="context">The active context to run the query on</param> + <param name="constraints">An arguments array to constrain the results of the query</param> + <returns>A query that returns a collection of records from the store</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetCountAsync"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetCountAsync(System.String)"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetCountQueryBuilder(VNLib.Plugins.Extensions.Data.TransactionalDbContext,System.String)"> + <summary> + Builds a query to get a count of records constrained by the specifier + </summary> + <param name="context">The active context to run the query on</param> + <param name="specifier">The specifier constrain</param> + <returns>A query that can be counted</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetSingleAsync(System.String)"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetSingleAsync(`0)"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetSingleAsync(System.String[])"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetSingleQueryBuilder(VNLib.Plugins.Extensions.Data.TransactionalDbContext,System.String[])"> + <summary> + Builds a query to get a single record from the variable length parameter arguments + </summary> + <param name="context">The context to execute query against</param> + <param name="constraints">Arguments to constrain the results of the query to a single record</param> + <returns>A query that yields a single record</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetSingleQueryBuilder(VNLib.Plugins.Extensions.Data.TransactionalDbContext,`0)"> + <summary> + <para> + Builds a query to get a single record from the specified record. + </para> + <para> + Unless overridden, performs an ID based query for a single entry + </para> + </summary> + <param name="context">The context to execute query against</param> + <param name="record">A record to referrence the lookup</param> + <returns>A query that yields a single record</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetPageAsync(System.Collections.Generic.ICollection{`0},System.Int32,System.Int32)"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetPageAsync(System.Collections.Generic.ICollection{`0},System.Int32,System.Int32,System.String[])"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.DbStore`1.GetPageQueryBuilder(VNLib.Plugins.Extensions.Data.TransactionalDbContext,System.String[])"> + <summary> + Builds a query to get a collection of records based on an variable length array of parameters + </summary> + <param name="context">The active context to run the query on</param> + <param name="constraints">An arguments array to constrain the results of the query</param> + <returns>A query that returns a paginated collection of records from the store</returns> + </member> + <member name="T:VNLib.Plugins.Extensions.Data.IDbModel"> + <summary> + Represents a basic data model for an EFCore entity + for support in data-stores + </summary> + </member> + <member name="P:VNLib.Plugins.Extensions.Data.IDbModel.Id"> + <summary> + A unique id for the entity + </summary> + </member> + <member name="P:VNLib.Plugins.Extensions.Data.IDbModel.Created"> + <summary> + The <see cref="T:System.DateTime"/> the entity was created in the store + </summary> + </member> + <member name="P:VNLib.Plugins.Extensions.Data.IDbModel.LastModified"> + <summary> + The <see cref="T:System.DateTime"/> the entity was last modified in the store + </summary> + </member> + <member name="P:VNLib.Plugins.Extensions.Data.IDbModel.Version"> + <summary> + Entity concurrency token + </summary> + </member> + <member name="T:VNLib.Plugins.Extensions.Data.ProtectedDbStore`1"> + <summary> + A data store that provides unique identities and protections based on an entity that has an owner <see cref="T:VNLib.Plugins.Extensions.Data.Abstractions.IUserEntity"/> + </summary> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.ProtectedDbStore`1.GetCollectionQueryBuilder(VNLib.Plugins.Extensions.Data.TransactionalDbContext,System.String[])"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.ProtectedDbStore`1.GetSingleQueryBuilder(VNLib.Plugins.Extensions.Data.TransactionalDbContext,System.String[])"> + <summary> + Gets a single item contrained by a given user-id and item id + </summary> + <param name="context"></param> + <param name="constraints"></param> + <returns></returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.ProtectedDbStore`1.GetSingleQueryBuilder(VNLib.Plugins.Extensions.Data.TransactionalDbContext,`0)"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.ProtectedEntityExtensions.UpdateAsync``1(VNLib.Plugins.Extensions.Data.Abstractions.IDataStore{``0},``0,System.String)"> + <summary> + Updates the specified record within the store + </summary> + <param name="store"></param> + <param name="record">The record to update</param> + <param name="userId">The userid of the record owner</param> + <returns>A task that evaluates to the number of records modified</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.ProtectedEntityExtensions.CreateAsync``1(VNLib.Plugins.Extensions.Data.Abstractions.IDataStore{``0},``0,System.String)"> + <summary> + Updates the specified record within the store + </summary> + <param name="store"></param> + <param name="record">The record to update</param> + <param name="userId">The userid of the record owner</param> + <returns>A task that evaluates to the number of records modified</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.ProtectedEntityExtensions.GetSingleAsync``1(VNLib.Plugins.Extensions.Data.Abstractions.IDataStore{``0},System.String,System.String)"> + <summary> + Gets a single entity from its ID and user-id + </summary> + <param name="store"></param> + <param name="key">The unique id of the entity</param> + <param name="userId">The user's id that owns the resource</param> + <returns>A task that resolves the entity or null if not found</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.ProtectedEntityExtensions.DeleteAsync``1(VNLib.Plugins.Extensions.Data.Abstractions.IDataStore{``0},System.String,System.String)"> + <summary> + Deletes a single entiry by its ID only if it belongs to the speicifed user + </summary> + <param name="store"></param> + <param name="key">The unique id of the entity</param> + <param name="userId">The user's id that owns the resource</param> + <returns>A task the resolves the number of eneities deleted (should evaluate to true or false)</returns> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.TransactionalDbContext.#ctor"> + <summary> + <inheritdoc/> + </summary> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.TransactionalDbContext.#ctor(Microsoft.EntityFrameworkCore.DbContextOptions)"> + <summary> + <inheritdoc/> + </summary> + </member> + <member name="P:VNLib.Plugins.Extensions.Data.TransactionalDbContext.Transaction"> + <summary> + The transaction that was opened on the current context + </summary> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.TransactionalDbContext.Dispose"> + <inheritdoc/> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.TransactionalDbContext.OpenTransactionAsync(System.Threading.CancellationToken)"> + <summary> + Opens a single transaction on the current context. If a transaction is already open, + it is disposed and a new transaction is begun. + </summary> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.TransactionalDbContext.CommitTransactionAsync(System.Threading.CancellationToken)"> + <summary> + Invokes the <see cref="M:Microsoft.EntityFrameworkCore.Storage.IDbContextTransaction.Commit"/> on the current context + </summary> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.TransactionalDbContext.RollbackTransctionAsync(System.Threading.CancellationToken)"> + <summary> + Invokes the <see cref="M:Microsoft.EntityFrameworkCore.Storage.IDbContextTransaction.Rollback"/> on the current context + </summary> + </member> + <member name="M:VNLib.Plugins.Extensions.Data.TransactionalDbContext.DisposeAsync"> + <inheritdoc/> + </member> + </members> +</doc> |