UNPKG

@clickup/ent-framework

Version:

A PostgreSQL graph-database-alike library with microsharding and row-level security

84 lines 4.24 kB
import type { Client } from "../abstract/Client"; import type { Cluster } from "../abstract/Cluster"; import type { Shard } from "../abstract/Shard"; import type { Table } from "../types"; import type { Inverse } from "./Inverse"; import type { ShardAffinity } from "./ShardAffinity"; import type { VC } from "./VC"; /** * Knows how to locate Shard(s) based on various inputs. In some contexts, we * expect exactly one Shard returned, and in other contexts, multiple Shards are * okay. */ export declare class ShardLocator<TClient extends Client, TTable extends Table, TField extends string> { private cluster; private entName; private shardAffinity; private uniqueKey; private inverses; private globalShard; private idAndShardAffinity; constructor({ cluster, entName, shardAffinity, uniqueKey, inverses, }: { cluster: Cluster<TClient>; entName: string; shardAffinity: ShardAffinity<TField>; uniqueKey: readonly string[] | undefined; inverses: ReadonlyArray<Inverse<TClient, TTable>>; }); /** * Called in a context when we must know exactly 1 Shard to work with (e.g. * INSERT, UPSERT etc.). If op === "insert" (fallback to random Shard), then * returns a random Shard in case when it can't infer the Shard number from * the input (used in e.g. INSERT operations); otherwise throws ShardError * (happens in e.g. UPSERT). * * The "randomness" of the "random Shard" is deterministic by the Ent's unique * key (if it's defined), so Ents with the same unique key will map to the * same "random" Shard (considering the total number of discovered Shards is * unchanged). Notice that this logic applies at INSERT time: since we often * times add Shards to the Cluster, we can't rely on it consistently at SELECT * time (but relying at INSERT time is more or less fine: it protects against * most of "unique key violation" problems, although still doesn't prevent all * of them for a fraction of the second when the number of Shards has just * been changed). */ singleShardForInsert(input: Record<string, unknown>, op: "insert" | "upsert"): Promise<Shard<TClient>>; /** * Called in a context when multiple Shards may be involved, e.g. when * selecting Ents referred by some Inverses. May also return the empty list of * Shards when, although there are fields with Inverses in input (i.e. the * filtering is correct), there are no Inverse rows existing in the database. */ multiShardsFromInput(vc: VC, input: Record<string, unknown>, op: string): Promise<Array<Shard<TClient>>>; /** * A wrapper for Cluster#shard() which injects Ent name to the exception (in * case of e.g. "Cannot locate Shard" exception). This is just a convenience * for debugging. * * If this method returns null, that means the caller should give up trying to * load the Ent with this ID, because it won't find it anyways (e.g. when we * try to load a sharded Ent using an ID from the global Shard). This is * identical to the case of an Ent not existing in the database. */ singleShardFromID(field: string, id: string | null | undefined, op: string): Promise<Shard<TClient> | null>; /** * All shards for this particular Ent depending on its affinity. */ allShards(): Promise<ReadonlyArray<Shard<TClient>>>; /** * Infers Shard number from shardAffinity info and the input record. * - Returns null if it can't do this; the caller should likely throw in this * case (although not always). * - If a field's value is an array of IDs from multiple Shards, then returns * the 1st inferred Shard still. This is the current limitation: we don't * even try to infer multiple Shards if we have some affinity fields in the * request, which e.g. simplifies Ent creation logic. Cross-Shard logic is * only enabled when using Inverses; see multiShardsFromInput(). */ private singleShardFromAffinity; /** * A helper to build uniform ShardError error messages. */ private buildShardErrorMessage; } //# sourceMappingURL=ShardLocator.d.ts.map