### Example SQL with pg_hint_plan and GUC Settings Source: https://docs.ent-framework.net/advanced/query-planner-hints This is an example of the SQL query that Ent Framework generates when using the raw prepend hint with 'pg_hint_plan' and other GUC settings. It shows the custom hint, temporary GUC settings, the actual SELECT statement, and the subsequent RESET commands. This structure ensures a single transaction and round-trip to the server. ```sql /*+IndexScan(comments comments_created_at_idx)*/ SET LOCAL search_path TO sh0123; SET LOCAL work_mem TO 10MB; SET LOCAL statement_timeout TO 20s; SELECT ... FROM comments WHERE topic_id=? ORDER BY created_at DESC LIMIT 100; RESET statement_timeout; RESET work_mem; SELECT pg_last_wal_replay_lsn(); ``` -------------------------------- ### Querying Debug Views Example (SQL) Source: https://docs.ent-framework.net/scalability/shards-rebalancing-and-pg-microsharding-tool An example `psql` session demonstrating how to query a debug view (`users`) to retrieve data from all microshards, including those on remote PostgreSQL nodes. This query is for debugging purposes only. ```sql $ psql postgres=# SELECT shard, email FROM users WHERE created_at > now() - '1 hour'::interval; -- Prints all recent users from all microshards, including -- the microshards on other PosgreSQL nodes! Use for -- debugging purposes only. ``` -------------------------------- ### Example Migration File List (Happy Path) Source: https://docs.ent-framework.net/advanced/database-schema-migrations Illustrates a typical scenario where new migration version files are appended chronologically to an existing list, leading to a smooth application process by the pg-mig tool. ```shell 20231017204837.do-something.sh 20241201204837.change-other-thing.sh 20241202001000.and-one-more-thing.sh ``` ```shell 20241202002000.their-thing.sh.up.sql ``` ```shell 20231017204837.do-something.sh.up.sql 20241201204837.change-other-thing.sh.up.sql 20241202001000.and-one-more-thing.sh.up.sql 20241202002000.their-thing.sh.up.sql <-- new version pulled ``` -------------------------------- ### Install Microshard Schema - pg-microsharding CLI Source: https://docs.ent-framework.net/scalability/shards-rebalancing-and-pg-microsharding-tool Command to install a new microshard schema using the pg-microsharding CLI. It allows specifying the schema name format and connection details (DSN) for the PostgreSQL server(s). ```bash pg-microsharding install [--schema-name-fmt=SCHEMA_NAME_FMT] [--dsn=DSN | --dsns=DNS1,DSN2,...] ``` -------------------------------- ### Basic Ent Select Call with Custom PostgreSQL Options Source: https://docs.ent-framework.net/advanced/postgresql-specific-features Demonstrates a basic select call in TypeScript using the Ent Framework, passing custom options for PostgreSQL-specific features. This example shows the initial setup before detailing the custom object structure. ```typescript const comments = await EntComment.select( vc, { creator_id: "101" }, 20, undefined, // order custom, // untyped, but of type SelectInputCustom ); ``` -------------------------------- ### Batching load() Calls with Ent Framework Source: https://docs.ent-framework.net/getting-started/automatic-batching-examples Demonstrates how multiple EntTopic.loadX() calls within a Promise.all() block are automatically batched into a single SQL query. This reduces the number of database round trips for read operations. ```typescript await Promise.all([ EntTopic.loadX(vc, "123"), EntTopic.loadX(vc, "456"), EntTopic.loadX(vc, "789"), ]); ``` -------------------------------- ### Optimized Comment Loading with Helper Methods (TypeScript) Source: https://docs.ent-framework.net/getting-started/n%2B1-selects-solution This TypeScript example shows how to add helper methods like `topic()` and `creator()` to Ent classes to simplify data loading. These methods, when used with `mapJoin`, still leverage Ent Framework's automatic batching for efficient database interaction. ```typescript class EntComment extends ... { async topic() { return EntTopic.loadX(this.vc, this.topic_id); } async creator() { return EntUser.loadX(this.vc, this.creator_id); } } class EntTopic extends ... { async creator() { return EntUser.loadX(this.vc, this.creator_id); } } app.get("/comments", async (req, res) => { const commentIDs = String(req.query.ids).split(","); res.json( await mapJoin(commentIDs, async (commentID) => { const comment = await EntComment.loadX(req.vc, commentID); const topic = await comment.topic(); const [commentCreator, topicCreator] = await Promise.all([ comment.creator(), topic.creator(), ]); return { comment, commentCreator, topic, topicCreator }; }) ); }); ``` -------------------------------- ### pg-microsharding Configuration File Setup Source: https://docs.ent-framework.net/scalability/shards-rebalancing-and-pg-microsharding-tool Defines how to export configuration values from a `pg-microsharding.config.ts` file, providing an alternative to environment variables. It derives connection details from the Ent Framework cluster configuration. ```javascript import { cluster } from "ents/cluster"; export default async function(action: "apply" | "undo" | string) { const islands = cluster.options.islands(); return { PGDSNS: islands .map((island) => island.nodes.map(({ host }) => host) .flat() .join(","), PGPORT: 5432, // we don't want to use pgbouncer port here PGUSER: firstNode.user, PGPASSWORD: firstNode.password, PGDATABASE: firstNode.database, PGSSLMODE: firstNode.ssl ? "prefer" : undefined, MIGRATE_CMD: "yarn -s pg-mig", }; } ``` -------------------------------- ### Get Shard Client using cluster.shardByNo() Source: https://docs.ent-framework.net/scalability/sharding-low-level-api Illustrates how to obtain a `Shard` instance by its number using `cluster.shardByNo()` and then acquire a PostgreSQL client (`pgClient`) for either the master or a replica using `shard.client()`. It also shows how to use a `Timeline` object for automatic replication lag tracking. ```typescript import { MASTER } from "ent-framework"; const shard = cluster.shardByNo(42); const pgClient = await shard.client(MASTER); // Using Timeline for replication lag tracking const timeline = vc.timeline(shard, "users"); const pgClientWithTimeline = await shard.client(timeline); ``` -------------------------------- ### SQL Table Schema for Topics with Tags Source: https://docs.ent-framework.net/advanced/loaders-and-custom-batching Defines the 'topics' table schema in PostgreSQL, including an array of text for tags and a GIN index for efficient searching on this array field. This schema is crucial for the subsequent data retrieval examples. ```sql CREATE TABLE topics( id bigserial PRIMARY KEY, tags text[] NOT NULL DEFAULT '{}', slug varchar(64) NOT NULL UNIQUE, creator_id bigint NOT NULL, subject text DEFAULT NULL ); CREATE INDEX topics_tags ON topics USING gin(tags); ``` -------------------------------- ### Batching insertReturning() Calls with Ent Framework Source: https://docs.ent-framework.net/getting-started/automatic-batching-examples Shows how multiple EntTopic.insertReturning() calls, even when nested within functions, are batched. It explains that while inserting and then loading data results in two SQL queries (INSERT and SELECT), the framework batches these operations efficiently. ```typescript await Promise.all([ EntTopic.insertReturning(vc, { ... }), EntTopic.insertReturning(vc, { ... }), EntTopic.insertReturning(vc, { ... }), ]); ``` ```typescript async function insertTopicsBatch(n: number) { await mapJoin(range(n), async (i) => EntTopic.insertReturning(vc, { ... })); } ... await Promise.all([ insertTopicsBatch(42), insertTopicsBatch(101), ]); ``` -------------------------------- ### Example Migration File List (Explicit Conflict) Source: https://docs.ent-framework.net/advanced/database-schema-migrations Demonstrates an explicit merge conflict where a new migration version file is introduced in the middle of the existing chronological order, causing the pg-mig tool to refuse execution and providing a specific error message. ```shell 20231017204837.do-something.sh 20241201204837.change-other-thing.sh 20241202001000.and-one-more-thing.sh <-- you work on this ``` ```shell 20231017204837.do-something.sh.up.sql 20241201204837.change-other-thing.sh.up.sql 20241202000000.middle-thing.sh.up.sql <-- new version pulled 20241202001000.and-one-more-thing.sh.up.sql ``` -------------------------------- ### Use a Custom Loader for Batched Topic Retrieval in TypeScript Source: https://docs.ent-framework.net/advanced/loaders-and-custom-batching This TypeScript example illustrates how to utilize a custom `TopicSimpleLoader` within the Ent Framework. It defines a `getTopic` function that leverages the loader and shows how multiple calls to `getTopic` within `mapJoin` are batched into a single database query for efficiency. ```typescript async function getTopic(vc: VC, id: string) { const topic = await vc.loader(TopicSimpleLoader).load(id); return topic; } ... // The following calls will be batched into 1 SELECT query. await mapJoin([id1, id2, ...], async (id) => getTopic(vc, id)); ``` -------------------------------- ### Install PostgreSQL Stored Functions: pg-microsharding install Source: https://docs.ent-framework.net/scalability/shards-rebalancing-and-pg-microsharding-tool Installs or upgrades the pg-microsharding stored functions into your PostgreSQL database. This can be done manually via the CLI or by including specific SQL files in your database migrations. ```APIDOC ## pg-microsharding install ### Description Installs the pg-microsharding stored functions into the PostgreSQL database. This can be performed using the CLI command or by executing the provided SQL migration files. ### Method CLI Command / SQL Execution ### Endpoint N/A (CLI Tool / SQL Script) ### Parameters #### CLI Arguments - **install** - Command to initiate the installation. #### SQL Files - **sql/pg-microsharding-up.sql**: Script to install or upgrade the library. - **sql/pg-microsharding-down.sql**: Script to uninstall the library. ### Request Example #### CLI ```bash pg-microsharding install ``` #### SQL Migration (Up) ```sql -- mig/20250628100000.add-pg-microsharding.public.up.sql CREATE SCHEMA microsharding; SET search_path TO microsharding; \ir ../pg-microsharding/sql/pg-microsharding-up.sql ``` ### Response #### Success Response (Database operations complete without errors) #### Response Example (No specific JSON response for CLI commands or SQL execution in this context) ``` -------------------------------- ### Show Cluster Layout with pg-microsharding list Source: https://docs.ent-framework.net/scalability/shards-rebalancing-and-pg-microsharding-tool Demonstrates the command-line usage for listing the cluster layout of pg-microsharding. It shows the basic command and mentions options like `--json` for JSON output and `--verbose` for detailed statistics. ```bash pg-microsharding list ``` -------------------------------- ### Install pg-microsharding Stored Functions API Source: https://docs.ent-framework.net/scalability/shards-rebalancing-and-pg-microsharding-tool Installs or upgrades the pg-microsharding library's stored functions into a PostgreSQL database. This can be done via a command-line action or by executing provided SQL scripts for up and down migrations. It supports installing into a dedicated schema or the 'public' schema. ```bash pg-microsharding install ``` ```sql -- mig/20250628100000.add-pg-microsharding.public.up.sql CREATE SCHEMA microsharding; SET search_path TO microsharding; \ir ../pg-microsharding/sql/pg-microsharding-up.sql ``` ```sql -- mig/20250628100000.add-pg-microsharding.public.dn.sql SET search_path TO microsharding; \ir ../pg-microsharding/sql/pg-microsharding-down.sql DROP SCHEMA microsharding; ``` -------------------------------- ### pg-mig Command Line Usage Source: https://docs.ent-framework.net/advanced/database-schema-migrations Demonstrates the command-line interface for the pg-mig tool, outlining various options for database migration management. These options include specifying migration directories, host configurations, user credentials, database names, and controlling migration behavior like undoing, creating, listing, and parallel execution. ```bash pg-mig [--migdir=path/to/my-migrations/directory] [--hosts=host1,host2,...] [--hosts=host[:port][/db],...] [--hosts=postgres://[user][:password][@]host[:port][/db],...] [--port=5432] [--user=user-that-can-apply-ddl] [--pass=password] [--db=my-database-name] [--createdb] [--undo=20191107201239.my-migration-name.sh] [--make=my-migration-name@sh] [--list | --list=digest] [--parallelism=8] [--dry] ``` -------------------------------- ### Configure Ent Framework Cluster with Custom Pool Source: https://docs.ent-framework.net/scalability/sharding-low-level-api Demonstrates how to initialize the Ent Framework `Cluster` with custom `islands`, `createClient` configuration (including substituting the default node-postgres Pool with a custom `pg.Pool` instance), and a `ShardNamer`. ```typescript import pg from "pg"; export const cluster = new Cluster({ islands: async () => [ { no: 0, nodes: [ { name: "abc-writer-1", config: { host: "...", ... } }, { name: "abc-reader-2", config: { host: "...", ... } }, ], }, { no: 1, nodes: [ { name: "abc-writer-3", config: { host: "...", ... } }, { name: "abc-reader-4", config: { host: "...", ... } }, ], }, ], createClient: (node) => new PgClient({ ...node, createPool: (config) => new pg.Pool(config), } satisfies PgClientOptions), shardNamer: new ShardNamer({ nameFormat: "sh%04d", discoverQuery: "SELECT unnest FROM unnest(microsharding.microsharding_list_active_shards())", }), ..., }); ``` -------------------------------- ### UUID v4 Generation Example Source: https://docs.ent-framework.net/scalability/locating-a-shard-id-format Provides an example of a UUID v4 format generated by the `id_gen_uuid()` function. The format includes environment and microshard information at the beginning, followed by randomly generated digits. This function is useful for primary keys when UUID format is desired. ```text 10246xxx-xxxx-4xxx-Nxxx-xxxxxxxxxxxx ``` -------------------------------- ### Create Database Tables (SQL) Source: https://docs.ent-framework.net/getting-started/connect-to-a-database This SQL script defines the schema for tables used in the Ent Framework, including 'users', 'topics', 'comments', 'organizations', and 'organization_users'. These tables store application data such as user information, discussion topics, comments, and organization details. ```sql CREATE TABLE users( id bigserial PRIMARY KEY, email varchar(256) NOT NULL UNIQUE, is_admin boolean NOT NULL DEFAULT FALSE ); CREATE TABLE topics( id bigserial PRIMARY KEY, created_at timestamptz NOT NULL, updated_at timestamptz NOT NULL, slug varchar(64) NOT NULL UNIQUE, creator_id bigint NOT NULL, subject text DEFAULT NULL ); CREATE TABLE comments( id bigserial PRIMARY KEY, created_at timestamptz NOT NULL, topic_id bigint REFERENCES topics, creator_id bigint NOT NULL, message text NOT NULL ); CREATE TABLE organizations( id bigserial PRIMARY KEY, name text NOT NULL UNIQUE ); CREATE TABLE organization_users( id bigserial PRIMARY KEY, organization_id bigint REFERENCES organizations, user_id bigint REFERENCES users, UNIQUE (organization_id, user_id) ); ``` -------------------------------- ### afterInsert Trigger Example Source: https://docs.ent-framework.net/getting-started/triggers This trigger executes after a successful insert operation. It can be used for auxiliary tasks. However, failures in this trigger do not roll back the database operation. ```typescript afterInsert: [ async (vc, { input }) => { ... }, ], ``` -------------------------------- ### Create and Use VC Principal for Loading Ents Source: https://docs.ent-framework.net/advanced/vc-flavors Demonstrates the initial creation of a guest VC, loading an EntUser with specific criteria, and subsequently using the VC to load other Ents like EntTopic and EntComment. It highlights that Ents carry the VC used for their loading, with potential downgrading based on privacy configurations. ```typescript const guestVC = VC.createGuestPleaseDoNotUseCreationPointsMustBeLimited(); const user = await EntUser.loadX(guestVC.toOmniDangerous(), { email: session.user.email, }); vc = user.vc; const user = await EntUser.loadX(vc, vc.principal); const topic = await EntTopic.loadX(user.vc, topicID); const comments = await EntComment.select(topic.vc, ...); ``` -------------------------------- ### beforeUpdate Trigger Example in TypeScript Source: https://docs.ent-framework.net/getting-started/triggers Demonstrates a beforeUpdate trigger in TypeScript. It adds an entry to Kafka and updates a slug if the subject changes, ensuring the slug is unique. ```typescript beforeUpdate: [ async (vc, { oldRow, input, newRow }) => { await addToKafka(this.name, newRow.id); if (newRow.subject !== oldRow.subject) { // Notice that newRow.subject is a non-optional // string property, whilst input.slug is optional // (i.e. string | undefined). let slug = slugufy(newRow.subject); if (await EntTopic.exists(vc, { slug })) { slug += `-${Date.now()}`; } input.slug = slug; } }, ], ... await topic.updateReturningX({ subject: "Hello" }); ``` -------------------------------- ### Ent Framework Data Insertion Example Source: https://docs.ent-framework.net/advanced/custom-field-refactoring Illustrates how to insert data into an Ent Topic, specifically for the 'actors' field, using the `ActorsV1` format. ```typescript const topic = await EntTopic.insertReturning(vc, { ..., actors: { editor_ids: ["42"], viewer_ids: [] }, }); ``` -------------------------------- ### Create New Migration File with pg-mig Source: https://docs.ent-framework.net/advanced/database-schema-migrations Command to create a new pair of empty migration files (.up.sql and .dn.sql) with a specified name and schema prefix using pg-mig. ```shell pg-mig --make=my-migration-name@sh ``` -------------------------------- ### afterMutation Trigger Example Source: https://docs.ent-framework.net/getting-started/triggers This trigger executes after any successful mutation (insert, update, or delete). It receives the operation type and the affected row, but not the input object. Failures here are not transactional. ```typescript afterMutation: [ async (vc, { op, newOrOldRow }) => { ... }, ], ``` -------------------------------- ### Define Initial Schema in SQL Source: https://docs.ent-framework.net/advanced/database-schema-migrations These SQL snippets define the structure for an initial database migration. The 'up' file contains `CREATE TABLE` statements, while the 'dn' file contains the corresponding `DROP TABLE` statement for rollback. These files are intended to be edited and applied by pg-mig. ```sql -- 20251203493744.initial.public.up.sql CREATE TABLE users( id bigserial PRIMARY KEY, email varchar(256) NOT NULL ); ``` ```sql -- 20251203493744.initial.public.dn.sql DROP TABLE users; ``` -------------------------------- ### afterUpdate Trigger Example Source: https://docs.ent-framework.net/getting-started/triggers This trigger executes after a successful update operation. It receives the old and new row data but not the input object. Failures here do not affect the database transaction. ```typescript afterUpdate: [ async (vc, { oldRow, newRow }) => { ... }, ], ``` -------------------------------- ### SQL Expressions: ANY and IN Builders Source: https://docs.ent-framework.net/architecture/jit-in-sql-queries-batching Demonstrates utility methods for constructing SQL expressions like ANY('{values}') and IN('values'). These are part of PgRunner and help in dynamically building SQL queries based on input data. ```typescript createAnyBuilder() { return (vals: string[]) => `ANY('{${vals.join(',')}}')`; } createInBuilder() { return (vals: string[]) => `IN('${vals.join("', '")}')`; } ``` -------------------------------- ### Next.js Server Component for User Welcome Message Source: https://docs.ent-framework.net/getting-started/vc-viewer-context-and-principal This Next.js server component fetches the user's session using `getServerSession()`. If a session exists, it displays a welcome message with the user's name; otherwise, it prompts the user to sign in. It relies on the next-auth library for session management. ```typescript import { getServerSession } from "next-auth"; export default async function Home() { const session = await getServerSession(); return session ? (
Welcome, {session.user?.name}!
) : (
Please sign in to continue.
); } ``` -------------------------------- ### beforeDelete Trigger Example in TypeScript Source: https://docs.ent-framework.net/getting-started/triggers Illustrates a beforeDelete trigger in TypeScript. It sends a deletion event to Kafka and recursively deletes associated comments before the main record is deleted. ```typescript beforeDelete: [ async (vc, { oldRow }) => { await addToKafka(this.name, oldRow.id); await mapJoin( await EntComment.select(vc, { topic_id: oldRow.id }, 1000000), async (comment) => comment.deleteOriginal(), ); }, ], ... await topic.deleteOriginal(); ``` -------------------------------- ### afterDelete Trigger Example Source: https://docs.ent-framework.net/getting-started/triggers This trigger executes after a successful delete operation, allowing for cleanup of associated resources. It's important to note that these operations are non-transactional; failures are not retried and the row is already deleted. ```typescript afterDelete: [ async (vc, { oldRow }) => { ... }, ], ``` -------------------------------- ### Example Migration File List (Implicit Conflict) Source: https://docs.ent-framework.net/advanced/database-schema-migrations Illustrates an implicit merge conflict scenario where a developer adds a new migration file locally, pulls changes that include another new migration file placed after the local one, creating a potential ordering issue before pushing to Git. ```shell 20231017204837.do-something.sh.up.sql 20241202001000.your-new-thing.sh.up.sql <-- not yet pushed ``` ```shell 20231017204837.do-something.sh.up.sql 20241202001000.your-new-thing.sh.up.sql <-- not yet pushed 20241202002000.other-dev-thing.sh.up.sql <-- just pulled ``` -------------------------------- ### Ent Framework Insert with Nullable and Optional Field Source: https://docs.ent-framework.net/getting-started/built-in-field-types Shows an example of inserting a record into EntTopic where `company_id` is both optional and nullable. The insert operation succeeds even if `company_id` is not explicitly provided. ```typescript await EntTopic.insertReturning(vc, { slug: "abc" }); // ^ OK: company_id is both optional and nullable. ``` -------------------------------- ### TypeScript Type Definition Example Source: https://docs.ent-framework.net/advanced/custom-field-refactoring Demonstrates TypeScript type definitions for custom field data, showing an older version (`ActorsV1`) and a newer, more complex version (`Actors`) with user IDs and timestamps. ```typescript type ActorsV1 = { editor_ids: string[]; viewer_ids: string[]; }; type Actors = { editor_ids: Array<{ id: string; ts: number; }>; viewer_ids: Array<{ id: string; ts: number; }>; }; ``` -------------------------------- ### Build getServerVC Function (TypeScript) Source: https://docs.ent-framework.net/getting-started/vc-viewer-context-and-principal Creates a memoized VC instance for the current HTTP request. It handles authenticated users by fetching or creating their `EntUser` and assigning their VC, or returns a guest VC if the user is not logged in. Uses `WeakMap` and `headers()` for memoization. ```typescript import { VC } from "ent-framework"; import { getServerSession } from "next-auth"; import { headers } from "next/headers"; import { EntUser } from "./EntUser"; const vcStore = new WeakMap(); export async function getServerVC(): Promise { const [heads, session] = await Promise.all([headers(), getServerSession()]); let vc = vcStore.get(heads); if (!vc) { vc = VC.createGuestPleaseDoNotUseCreationPointsMustBeLimited(); if (session?.user?.email) { const vcOmni = vc.toOmniDangerous(); let user = await EntUser.loadByNullable(vcOmni, { email: session.user.email, }); if (!user) { // User did not exist: upsert the Ent. await EntUser.insertIfNotExists(vcOmni, { email: session.user.email, is_admin: false, }); user = await EntUser.loadByX(vcOmni, { email: session.user.email, }); } // Thanks to EntUser's privacyInferPrincipal rule, user.vc is // automatically assigned to a new derived VC with principal equals to // user.id. vc = user.vc; } vcStore.set(heads, vc); } return vc; } ``` -------------------------------- ### Batch upsert() calls in TypeScript Source: https://docs.ent-framework.net/getting-started/ent-api-upsert Demonstrates how to use multiple upsert() calls in parallel using Promise.all for batching. This example highlights the behavior with autoInsert fields like created_at, showing how they are handled on insert versus update. ```typescript await Promise.all([ EntTopic.upsert(vc, { slug: "s1", creator_id: "123", subject: "test1", }), EntTopic.upsert(vc, { created_at: new Date("2020-01-01"), slug: "s2", creator_id: "456", subject: "test2", }), ]); ``` -------------------------------- ### Ent Framework Insert with Explicit Null Value Source: https://docs.ent-framework.net/getting-started/built-in-field-types Provides an example of successfully inserting a record where the `company_id` field is explicitly set to `null`. This shows how to handle nullable fields when they are present in the data. ```typescript await EntTopic.insertReturning(vc, { company_id: null, slug: "abc" }); // ^ OK. ``` -------------------------------- ### Run Ent Ping Tool using pnpm Source: https://docs.ent-framework.net/advanced/logging-and-diagnostic-tools This snippet shows how to execute the Ent Ping Tool using the pnpm package manager. It's the primary command to initiate the tool's operation. ```bash pnpm exec ent-ping ``` -------------------------------- ### List Microshard Schemas - pg-microsharding CLI Source: https://docs.ent-framework.net/scalability/shards-rebalancing-and-pg-microsharding-tool Command to list existing microshard schemas with options for weight calculation, verbosity, connection details, and JSON output. ```bash pg-microsharding list | ls [--weight-sql='SELECT returning weight with optional unit'] [--verbose] [--dsn=DSN | --dsns=DNS1,DSN2,...] [--json] ``` -------------------------------- ### Get List of All Shards with cluster.nonGlobalShards() Source: https://docs.ent-framework.net/scalability/sharding-low-level-api Retrieves a list of all microshard instances within the cluster, excluding the global shard (shard 0). This method is asynchronous and returns a promise that resolves to an array of shard objects. ```typescript const shards = await cluster.nonGlobalShards(); ``` -------------------------------- ### Apply Migrations with pg-mig Source: https://docs.ent-framework.net/advanced/database-schema-migrations Commands to execute the 'up' migration using pg-mig across different package managers and Deno. Ensures migrations are applied in order to all relevant PostgreSQL schemas. ```shell pnpm pg-mig yarn pg-mig npm exec pg-mig deno run pg-mig ``` -------------------------------- ### Count Ents using TypeScript Source: https://docs.ent-framework.net/getting-started/ent-api-count-by-expression Demonstrates how to use the Ent.count() function in TypeScript to count entities based on different criteria. This example shows parallel execution and internal batching of count operations into a single SQL query. ```typescript const [count1, count2] = await Promise.all([ EntTopic.count(vc, { creator_id: "123" }), EntTopic.count(vc, { updated_at: { $gt: new Date("2024-01-01") } }), ]); ``` -------------------------------- ### Next.js Sign-In Button Component Source: https://docs.ent-framework.net/getting-started/vc-viewer-context-and-principal A simple React component for a Next.js application that provides a 'Sign in' link. Clicking this link initiates the Google sign-in process using the signIn function from 'next-auth/react'. ```typescript import { signIn } from "next-auth/react"; ... signIn("google")}>Sign in ``` -------------------------------- ### Retrieve Shards on an Island (TypeScript) Source: https://docs.ent-framework.net/scalability/sharding-low-level-api Gets a list of currently known shards residing on a specific island. This is commonly used for constructing 'cross-shard' queries, such as UNION ALL operations, to efficiently retrieve data from multiple shards. ```typescript const shards = island.shards(); const masters = await mapJoin( shards, async (shard) => shard.client(MASTER), ); const query = masters .map((client) => ` (SELECT id FROM ${client.shardName}.users WHERE needs_processing LIMIT 100) `.trim()) .join("\n UNION ALL\n"); const ids = await island.master().query({ query: [query], ... }); ``` -------------------------------- ### Load Comments with Batching (TypeScript) Source: https://docs.ent-framework.net/getting-started/n%2B1-selects-solution This TypeScript code snippet demonstrates how Ent Framework automatically batches multiple `loadX` calls for comments, topics, and users into a few efficient SQL queries. It highlights the framework's ability to coalesce and cache requests. ```typescript app.get("/comments", async (req, res) => { const commentIDs = uniq(String(req.query.ids).split(",")); res.json( await Promise.all( commentIDs.map(async (commentID) => { const comment = await EntComment.loadX(req.vc, commentID); const topic = await EntTopic.loadX(req.vc, comment.topic_id); const [commentCreator, topicCreator] = await Promise.all([ EntUser.loadX(req.vc, comment.creator_id), EntUser.loadX(req.vc, topic.creator_id), ]); return { comment, commentCreator, topic, topicCreator }; }) ) ); }); ``` -------------------------------- ### Querying Comments with Filters and Pagination Source: https://docs.ent-framework.net/getting-started/ent-api-select-by-expression Demonstrates how to use the `select()` API to query `EntComment` entities. It filters by `topic_id` and `created_at`, applies a limit, and specifies sorting order. This example showcases basic filtering and pagination with Ent Framework. ```typescript const comments = await EntComment.select( vc, { topic_id: ["123", "456"], created_at: { $gte: new Date(Date.now() - 1000 * 3600 * 24) }, }, 100, // limit [{ created_at: "ASC" }] // order by ); ``` -------------------------------- ### Allocate New Microshards with pg-microsharding allocate Source: https://docs.ent-framework.net/scalability/shards-rebalancing-and-pg-microsharding-tool Illustrates how to allocate new microshards using the `pg-microsharding allocate` command. It shows the syntax for specifying shard ranges and activating them, along with explanations of the `--shards` and `--activate` flags. ```typescript pg-microsharding allocate --shards=301-309 --activate=yes ```