@crvouga/mockingbird-service-postgres 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,13 +1,11 @@
1
- import type { Database } from "../api/database.js";
1
+ import { Database } from "../api/database.js";
2
2
  /**
3
3
  * What every connection of one server shares: the engine, and the coordination the engine
4
4
  * (single-session, synchronous) does not do itself.
5
5
  *
6
- * - The **turn**: the engine holds one transaction at a time, so a connection inside an
7
- * explicit transaction block holds the turn until it commits or rolls back, and every other
8
- * connection's statement waits. A statement outside a block takes the turn for itself only.
9
- * Uncommitted rows are therefore never visible to another connection (read committed holds),
10
- * at the cost of running transaction blocks one at a time.
6
+ * - The **turn** serializes individual synchronous engine calls. Explicit transactions use
7
+ * per-session copy-on-write workspaces in the connection, so the turn is released after every
8
+ * statement and unrelated sessions keep progressing.
11
9
  * - **Advisory locks** per session, with waiters woken in order, and deadlock detection
12
10
  * between a lock and the turn (`40P01`).
13
11
  * - **LISTEN / NOTIFY** fan-out, delivered when a listening connection is idle.
@@ -15,7 +13,7 @@ import type { Database } from "../api/database.js";
15
13
  * (`pg_backend_pid`, `pg_advisory_lock`, `pg_notify`, …) know whom they serve.
16
14
  */
17
15
  export declare class Cluster {
18
- readonly db: Database;
16
+ readonly defaultDatabaseName: string;
19
17
  turnHolder: Session | null;
20
18
  private readonly turnQueue;
21
19
  readonly locks: Map<string, {
@@ -28,7 +26,19 @@ export declare class Cluster {
28
26
  readonly sessions: Map<number, Session>;
29
27
  current: Session | null;
30
28
  private nextPid;
31
- constructor(db: Database);
29
+ private readonly databases;
30
+ constructor(db: Database, defaultDatabaseName?: string);
31
+ /** The initial database, retained for the server's backwards-compatible public handle. */
32
+ get db(): Database;
33
+ databaseNames(): string[];
34
+ getDatabase(name: string): Database | undefined;
35
+ requireDatabase(name: string): Database;
36
+ createDatabase(name: string, template?: string): void;
37
+ dropDatabase(name: string, requester: Session): void;
38
+ renameDatabase(from: string, to: string, requester: Session): void;
39
+ private requireTemplate;
40
+ private activeConnections;
41
+ private installDatabase;
32
42
  newPid(): number;
33
43
  /** Wait until this session may execute: at once when nobody holds the turn, or it does. */
34
44
  acquireTurn(session: Session): Promise<void>;
@@ -59,6 +69,8 @@ export declare class LockWait extends Error {
59
69
  /** What the cluster needs from a connection. */
60
70
  export interface Session {
61
71
  readonly pid: number;
72
+ database: Database;
73
+ databaseName: string;
62
74
  waitingForTurn: Waiter | null;
63
75
  waitingForLock: string | null;
64
76
  /** NOTIFYs issued inside the current transaction block, sent at commit. */
@@ -1,4 +1,5 @@
1
1
  import type { Socket } from "node:net";
2
+ import type { Database } from "../api/database.js";
2
3
  import { type Cluster, type Session } from "./cluster.js";
3
4
  export type ServerFaults = {
4
5
  /** Destroy the socket of the next connection that runs a statement inside a transaction block. */
@@ -43,6 +44,8 @@ export declare class Connection implements Session {
43
44
  channel: string;
44
45
  payload: string;
45
46
  }[];
47
+ database: Database;
48
+ databaseName: string;
46
49
  private readonly frames;
47
50
  private readonly inbox;
48
51
  private pumping;
@@ -59,6 +62,10 @@ export declare class Connection implements Session {
59
62
  private readonly prepared;
60
63
  private readonly portals;
61
64
  private readonly notifications;
65
+ private copyIn;
66
+ private copyDrain;
67
+ /** Successful writes in this session's READ COMMITTED transaction workspace. */
68
+ private transaction;
62
69
  private closed;
63
70
  constructor(socket: Socket, cluster: Cluster, options: ConnectionOptions);
64
71
  private receive;
@@ -88,12 +95,29 @@ export declare class Connection implements Session {
88
95
  private waitForLock;
89
96
  /** The engine call itself: statement-atomic, and transaction control handled as the server sees it. */
90
97
  private runStatement;
91
- /** Release the turn and transaction-scoped locks once no block is open; deliver NOTIFYs at commit. */
98
+ /** Release the statement turn; transaction-scoped locks live until COMMIT / ROLLBACK. */
92
99
  private afterStatement;
100
+ private transactionControl;
101
+ private findSavepoint;
102
+ /** Rebase this transaction's successful writes onto the latest committed state. */
103
+ private openWorkspace;
104
+ private replay;
105
+ private runQuery;
106
+ private lockRows;
107
+ private rowLockKey;
93
108
  private flushNotifies;
109
+ private executeClusterDdl;
94
110
  private listen;
95
111
  private unlisten;
96
112
  private query;
113
+ private copyStatement;
114
+ private copyColumnCount;
115
+ private handleCopyIn;
116
+ private beginCopyIn;
117
+ private finishCopyIn;
118
+ private flushCopyRecords;
119
+ private abortCopyIn;
120
+ private sendCopyOut;
97
121
  private sendOutcome;
98
122
  private columnFormats;
99
123
  private fields;
@@ -67,6 +67,10 @@ export type PostgresServer = {
67
67
  readonly connectionString: string;
68
68
  /** The shared engine, for seeding, snapshotting or asserting from the test process. */
69
69
  readonly database: Database;
70
+ /** Names in the cluster catalog, in deterministic order. */
71
+ databaseNames(): readonly string[];
72
+ /** Resolve a named database, or throw SQLSTATE `3D000`. */
73
+ getDatabase(name: string): Database;
70
74
  /** The underlying `net.Server`. */
71
75
  readonly server: Server;
72
76
  /** Open connections right now. */
@@ -74,7 +78,7 @@ export type PostgresServer = {
74
78
  /** Arm a fault preset for the next statement / connection (see {@link ServerFaults}). */
75
79
  fault(fault: ServerFaults): void;
76
80
  /** Freeze the live state (the admin `snapshot()` control). */
77
- snapshot(): Snapshot;
81
+ snapshot(name?: string): Snapshot;
78
82
  /** Stop listening and close every connection. */
79
83
  close(): Promise<void>;
80
84
  };