@clickup/ent-framework
Version:
A PostgreSQL graph-database-alike library with microsharding and row-level security
126 lines • 6.93 kB
TypeScript
import type { Client } from "../../abstract/Client";
import type { OmitNew } from "../../internal/misc";
import type { CountInput, ExistsInput, InsertInput, LoadByInput, Order, SelectByInput, Table, UniqueKey, Where } from "../../types";
import { ID } from "../../types";
import type { UpdateOriginalInput } from "../types";
import type { VC } from "../VC";
import type { ConfigClass, ConfigInstance } from "./ConfigMixin";
export interface PrimitiveInstance<TTable extends Table> extends ConfigInstance {
/**
* VC of this Ent.
*/
readonly vc: VC;
/**
* For simplicity, every Ent has an ID field name hardcoded to "id".
*/
readonly [ID]: string;
/**
* Updates the object in the DB, but doesn't update the Ent itself (since it's
* immutable).
* - This method can work with CAS; see $cas property of the passed object.
* - If a special value "skip-if-someone-else-changed-updating-ent-props" is
* passed to $cas, then the list of props for CAS is brought from the input,
* and the values of these props are brought from the Ent itself (i.e. from
* `this`).
* - If a special value, a list of field names, is passed to $cas, then it
* works like described above, but the list of prop names is brought from
* that list of field names.
* - Returns false if there is no such object in the DB, or if CAS check
* didn't succeed.
* - Returns true if the object was found and updated.
*/
updateOriginal(input: UpdateOriginalInput<TTable>): Promise<boolean>;
/**
* Deletes the object in the DB. Returns true if the object was found. Keeps
* the current object untouched (since it's immutable).
*/
deleteOriginal(): Promise<boolean>;
}
export type PrimitiveClass<TTable extends Table, TUniqueKey extends UniqueKey<TTable>, TClient extends Client> = OmitNew<ConfigClass<TTable, TUniqueKey, TClient>> & {
/**
* Runs INSERT mutation for the Ent.
* - The Shard is inferred from the input fields using SHARD_AFFINITY.
* - Returns ID of the newly inserted row.
* - Returns null if the Ent violates unique key constraints.
* - If the Ent has some triggers set up, this will be translated into two
* schema operations: idGen() and insert(), and before-triggers will run in
* between having the ID known in advance.
*/
insertIfNotExists: (vc: VC, input: InsertInput<TTable>) => Promise<string | null>;
/**
* Inserts an Ent or updates an existing one if unique key matches.
* - Don't use upsert() too often, because upsert may still delete IDs even if
* the object was updated, not inserted (there is no good ways to solve this
* in some DB engines like relational DBs so far).
* - Upsert can't work if some triggers are defined for the Ent, because we
* don't know Ent ID in advance (whether the upsert succeeds or skips on
* duplication).
*/
upsert: (vc: VC, input: InsertInput<TTable>) => Promise<string>;
/**
* Loads an Ent by its ID. Returns null if no such Ent exists. Try to use
* loadX() instead as much as you can.
*/
loadNullable: <TEnt extends PrimitiveInstance<TTable>>(this: new () => TEnt, vc: VC, id: string) => Promise<TEnt | null>;
/**
* Loads an Ent by its unique key. Returns null if no such Ent exists. Notice
* that the key must be REALLY unique, otherwise the database may return
* multiple items, and the API will break. Don't try to use this method with
* non-unique keys!
*/
loadByNullable: <TEnt extends PrimitiveInstance<TTable>>(this: new () => TEnt, vc: VC, input: LoadByInput<TTable, TUniqueKey>) => Promise<TEnt | null>;
/**
* Selects the list of Ents by their unique key prefix. The query can span
* multiple Shards if their locations can be inferred from inverses related to
* the fields mentioned in the query. Ordering of the results is not
* guaranteed.
*/
selectBy: <TEnt extends PrimitiveInstance<TTable>>(this: new () => TEnt, vc: VC, input: SelectByInput<TTable, TUniqueKey>) => Promise<TEnt[]>;
/**
* Selects the list of Ents by some predicate.
* - The query can span multiple Shards if their locations can be inferred
* from inverses related to the fields mentioned in the query.
* - In multi-Shard case, ordering of results is not guaranteed.
* - In multi-Shard case, it may return more results than requested by limit
* (basically, limit is applied to each Shard individually). The caller has
* then freedom to reorder & slice the results as they wish.
*/
select: <TEnt extends PrimitiveInstance<TTable>>(this: new () => TEnt, vc: VC, where: Where<TTable>, limit: number, order?: Order<TTable>, custom?: {}) => Promise<TEnt[]>;
/**
* Same as select(), but returns data in chunks.
* - Uses multiple select() queries under the hood.
* - The query can span multiple Shards if their locations can be inferred
* from inverses related to the fields mentioned in the query.
* - Ents in each chunk always belong to the same Shard and are ordered by ID
* (there is no support for custom ordering). Make sure you have the right
* index in the database.
*/
selectChunked: <TEnt extends PrimitiveInstance<TTable>>(this: new () => TEnt, vc: VC, where: Where<TTable>, chunkSize: number, limit: number, custom?: {}) => AsyncIterableIterator<TEnt[]>;
/**
* Returns count of Ents matching a predicate. The query can span multiple
* Shards if their locations can be inferred from inverses related to the
* fields mentioned in the query.
*/
count: (vc: VC, where: CountInput<TTable>) => Promise<number>;
/**
* A more optimal approach than count() when we basically just need to know
* whether we have "0 or not 0" rows.
*/
exists: (vc: VC, where: ExistsInput<TTable>) => Promise<boolean>;
/**
* TS requires us to have a public constructor to infer instance types in
* various places. We make this constructor throw if it's called.
*
* KLUDGE here: it should've been PrimitiveInstance<TTable> & Row<TTable>. But
* unfortunately if we do so, TS disallows inheritance from PrimitiveClass and
* thus breaks the chain of mixins. So we add Row<TTable> only at the very
* late stage, in the latest mixin in the chain and not here.
*/
new (): PrimitiveInstance<TTable>;
};
/**
* Modifies the passed class adding support for the minimal number of basic Ent
* operations. Internally, uses Schema abstractions to run them.
*/
export declare function PrimitiveMixin<TTable extends Table, TUniqueKey extends UniqueKey<TTable>, TClient extends Client>(Base: ConfigClass<TTable, TUniqueKey, TClient>): PrimitiveClass<TTable, TUniqueKey, TClient>;
//# sourceMappingURL=PrimitiveMixin.d.ts.map