Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<JasperFxVersion>2.13.3</JasperFxVersion>
<JasperFxVersion>2.14.0</JasperFxVersion>
<LangVersion>13</LangVersion>
<NoWarn>1570;1571;1572;1573;1574;1587;1591;1701;1702;1711;1735;0618</NoWarn>
<Authors>Jeremy D. Miller;Jaedyn Tonee</Authors>
Expand Down
39 changes: 38 additions & 1 deletion src/JasperFx/Descriptors/DocumentMappingDescriptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,31 @@ public class DocumentMappingDescriptor
/// <summary>
/// Number of subclass mappings registered against this aggregate root —
/// non-zero indicates a hierarchy (<c>doc_type</c> column is present).
/// Retained for back-compat; <see cref="SubClasses"/> carries the list.
/// </summary>
public int SubClassCount { get; set; }

/// <summary>
/// The subclass-mapping document types registered against this root, so a
/// console can render the hierarchy rather than just a "has subclasses"
/// hint. Empty when the type is not a hierarchy root.
/// </summary>
public TypeDescriptor[] SubClasses { get; set; } = [];

/// <summary>
/// CLR type name of the <c>IPartitionStrategy</c> in effect, or
/// <see langword="null"/> when the table is not partitioned.
/// <see langword="null"/> when the table is not partitioned. Retained for
/// back-compat; <see cref="Partitioning"/> carries the structured shape.
/// </summary>
public string? PartitioningStrategy { get; set; }

/// <summary>
/// Structured partitioning shape (strategy + declared partition names), or
/// <see langword="null"/> when the table is not partitioned. Lets the
/// console render the actual partitions, not just the strategy label.
/// </summary>
public PartitioningDescriptor? Partitioning { get; set; }

/// <summary>
/// Full DDL the store will generate for this document type — table
/// definition, indexes, foreign keys, and any partition declarations.
Expand All @@ -86,3 +102,24 @@ public class DocumentMappingDescriptor
/// </summary>
public string Ddl { get; set; } = "";
}

/// <summary>
/// Structured description of a partitioned document table: the partition
/// strategy (e.g. <c>"List"</c>, <c>"Hash"</c>, <c>"Range"</c>) plus the
/// declared partition names where the store can surface them.
/// </summary>
public class PartitioningDescriptor
{
/// <summary>
/// Partition strategy label — <c>"List"</c>, <c>"Hash"</c>, <c>"Range"</c>,
/// etc. Mirrors the store's partition-strategy kind as a string for
/// serialization-friendliness across version skews.
/// </summary>
public string Strategy { get; set; } = "";

/// <summary>
/// Declared partition names where known (e.g. per-tenant or per-range
/// partition table suffixes). Empty when the partitions are not enumerable.
/// </summary>
public string[] PartitionNames { get; set; } = [];
}
45 changes: 45 additions & 0 deletions src/JasperFx/Documents/IDocumentStoreDiagnostics.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
namespace JasperFx.Documents;

/// <summary>
/// Store-agnostic, read-only query surface over a document store's stored documents (#544 / #545,
/// JasperFx/CritterWatch). Mirrors the role <c>JasperFx.Events.IEventStore</c> plays for event streams:
/// it lets a monitoring console (which must not reference Marten / Polecat directly) browse, page, and
/// fetch stored documents as JSON regardless of the backing store. Implemented by Marten and Polecat
/// and registered in DI; consumers use the graceful-no-op pattern
/// (<c>services.GetServices&lt;IDocumentStoreDiagnostics&gt;()</c> is empty on a store that predates this,
/// so the feature degrades to "not available").
/// </summary>
public interface IDocumentStoreDiagnostics
{
/// <summary>
/// The mapped document types this store can query (CLR type name + table alias + schema), so a
/// console can populate a type picker without a separate metadata round-trip.
/// </summary>
Task<IReadOnlyList<DocumentTypeRef>> DocumentTypesAsync(CancellationToken token = default);

/// <summary>
/// A page of documents of the named type, each as raw JSON, plus the total matching count.
/// </summary>
Task<DocumentQueryResult> QueryDocumentsAsync(
string documentTypeName, DocumentQueryOptions options, CancellationToken token = default);

/// <summary>
/// One document of the named type by its string id, as raw JSON, or <see langword="null"/> when
/// not found.
/// </summary>
Task<string?> LoadDocumentJsonAsync(
string documentTypeName, string id, CancellationToken token = default);
}

/// <summary>A queryable document type on a store: CLR type name, table alias, and schema.</summary>
public record DocumentTypeRef(string TypeName, string Alias, string SchemaName);

/// <summary>
/// Options for <see cref="IDocumentStoreDiagnostics.QueryDocumentsAsync"/>. Paging is required; the
/// optional <see cref="IdEquals"/> narrows to a single id. Room to grow simple criteria later without a
/// signature break.
/// </summary>
public record DocumentQueryOptions(int PageNumber, int PageSize, string? IdEquals = null);

/// <summary>A page of stored documents as raw JSON, with the total matching count for pager UIs.</summary>
public record DocumentQueryResult(IReadOnlyList<string> DocumentsJson, long TotalCount, int PageNumber, int PageSize);
Loading