@earth-app/collegedb 1.0.1

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.
@@ -0,0 +1,255 @@
1
+ /**
2
+ * @fileoverview KV-based shard mapping implementation for CollegeDB
3
+ *
4
+ * This module provides the KVShardMapper class that uses Cloudflare KV storage
5
+ * to maintain mappings between primary keys and their assigned D1 database shards.
6
+ * It handles the persistence and retrieval of shard assignments, enabling the
7
+ * database router to consistently route queries to the correct shard.
8
+ *
9
+ * Key features:
10
+ * - Primary key to shard mapping storage and retrieval
11
+ * - Shard discovery and management
12
+ * - Key counting and statistics for load balancing
13
+ * - Batch operations for efficient KV usage
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const mapper = new KVShardMapper(env.KV);
18
+ *
19
+ * // Set a mapping
20
+ * await mapper.setShardMapping('user-123', 'db-east');
21
+ *
22
+ * // Get a mapping
23
+ * const mapping = await mapper.getShardMapping('user-123');
24
+ * console.log(mapping?.shard); // 'db-east'
25
+ *
26
+ * // Get statistics
27
+ * const counts = await mapper.getShardKeyCounts();
28
+ * console.log(counts); // { 'db-east': 42, 'db-west': 38 }
29
+ * ```
30
+ *
31
+ * @author Gregory Mitchell
32
+ * @since 1.0.0
33
+ */
34
+ import type { KVNamespace } from '@cloudflare/workers-types';
35
+ import type { ShardMapping } from './types.js';
36
+ /**
37
+ * The KVShardMapper class provides a persistent storage layer for mapping
38
+ * primary keys to their assigned D1 database shards. It uses Cloudflare KV
39
+ * for global, eventually consistent storage with low latency reads.
40
+ *
41
+ * Features:
42
+ * - CRUD operations for shard mappings
43
+ * - Atomic updates with timestamp tracking
44
+ * - Efficient bulk operations and statistics
45
+ * - Prefix-based key organization for performance
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * const mapper = new KVShardMapper(env.KV);
50
+ *
51
+ * // Create a new mapping
52
+ * await mapper.setShardMapping('order-456', 'db-central');
53
+ *
54
+ * // Update an existing mapping
55
+ * await mapper.updateShardMapping('order-456', 'db-west');
56
+ *
57
+ * // Query mapping
58
+ * const mapping = await mapper.getShardMapping('order-456');
59
+ * if (mapping) {
60
+ * console.log(`Order 456 is on ${mapping.shard}`);
61
+ * }
62
+ * ```
63
+ */
64
+ export declare class KVShardMapper {
65
+ private kv;
66
+ /**
67
+ * Cloudflare KV namespace for storing mappings
68
+ * @readonly
69
+ */
70
+ constructor(kv: KVNamespace);
71
+ /**
72
+ * Retrieves the shard assignment for a given primary key from KV storage.
73
+ * Returns null if no mapping exists, indicating the key has not been
74
+ * assigned to any shard yet.
75
+ * @param primaryKey - The primary key to look up
76
+ * @returns Promise resolving to the shard mapping or null if not found
77
+ * @throws {Error} If KV read operation fails
78
+ * @example
79
+ * ```typescript
80
+ * const mapping = await mapper.getShardMapping('user-789');
81
+ * if (mapping) {
82
+ * console.log(`User 789 is on shard: ${mapping.shard}`);
83
+ * console.log(`Created: ${new Date(mapping.createdAt)}`);
84
+ * } else {
85
+ * console.log('User 789 not yet assigned to any shard');
86
+ * }
87
+ * ```
88
+ */
89
+ getShardMapping(primaryKey: string): Promise<ShardMapping | null>;
90
+ /**
91
+ * Creates a new shard assignment for a primary key. This is typically used
92
+ * when a new primary key is first encountered and needs to be assigned to
93
+ * a shard. Sets both created and updated timestamps to the current time.
94
+ *
95
+ * **Note**: This will overwrite any existing mapping for the same key.
96
+ * Use updateShardMapping() if you want to preserve creation timestamp.
97
+ * @param primaryKey - The primary key to map
98
+ * @param shard - The shard binding name to assign
99
+ * @returns Promise that resolves when the mapping is stored
100
+ * @throws {Error} If KV write operation fails
101
+ * @example
102
+ * ```typescript
103
+ * // Assign a new user to the west coast shard
104
+ * await mapper.setShardMapping('user-california-123', 'db-west');
105
+ * ```
106
+ */
107
+ setShardMapping(primaryKey: string, shard: string): Promise<void>;
108
+ /**
109
+ * Changes the shard assignment for a primary key that already has a mapping.
110
+ * Preserves the original creation timestamp while updating the modified
111
+ * timestamp. Throws an error if no existing mapping is found.
112
+ *
113
+ * This is typically used during shard rebalancing or data migration operations.
114
+ * @param primaryKey - The primary key to update
115
+ * @param newShard - The new shard binding name to assign
116
+ * @returns Promise that resolves when the mapping is updated
117
+ * @throws {Error} If no existing mapping found or KV operation fails
118
+ * @example
119
+ * ```typescript
120
+ * try {
121
+ * // Move user to a different shard for rebalancing
122
+ * await mapper.updateShardMapping('user-456', 'db-central');
123
+ * console.log('User successfully moved to central shard');
124
+ * } catch (error) {
125
+ * console.error('Failed to update mapping:', error.message);
126
+ * }
127
+ * ```
128
+ */
129
+ updateShardMapping(primaryKey: string, newShard: string): Promise<void>;
130
+ /**
131
+ * Completely removes the shard assignment for a primary key from KV storage.
132
+ * This is typically used when data is being permanently deleted or when
133
+ * cleaning up orphaned mappings.
134
+ *
135
+ * **WARNING**: After deletion, the primary key will be treated as new
136
+ * and may be assigned to a different shard on next access.
137
+ *
138
+ * @param primaryKey - The primary key mapping to remove
139
+ * @returns Promise that resolves when the mapping is deleted
140
+ * @throws {Error} If KV delete operation fails
141
+ * @example
142
+ * ```typescript
143
+ * // Remove mapping for deleted user
144
+ * await mapper.deleteShardMapping('user-deleted-789');
145
+ * console.log('Mapping removed for deleted user');
146
+ * ```
147
+ */
148
+ deleteShardMapping(primaryKey: string): Promise<void>;
149
+ /**
150
+ * Retrieves the list of all shard binding names that have been registered
151
+ * with the system. This is maintained separately from the individual mappings
152
+ * for efficient shard discovery.
153
+ *
154
+ * @returns Promise resolving to array of shard binding names
155
+ * @throws {Error} If KV read operation fails
156
+ * @example
157
+ * ```typescript
158
+ * const shards = await mapper.getKnownShards();
159
+ * console.log('Available shards:', shards);
160
+ * // Output: ['db-east', 'db-west', 'db-central']
161
+ * ```
162
+ */
163
+ getKnownShards(): Promise<string[]>;
164
+ /**
165
+ * Replaces the entire list of known shards with a new list. This is typically
166
+ * used during system initialization or when shards are added/removed in bulk.
167
+ *
168
+ * @param shards - Array of shard binding names to store
169
+ * @returns Promise that resolves when the list is updated
170
+ * @throws {Error} If KV write operation fails
171
+ * @example
172
+ * ```typescript
173
+ * // Update shard list after adding new regions
174
+ * await mapper.setKnownShards(['db-east', 'db-west', 'db-central', 'db-asia']);
175
+ * ```
176
+ */
177
+ setKnownShards(shards: string[]): Promise<void>;
178
+ /**
179
+ * Appends a new shard to the list of known shards if it's not already present.
180
+ * This operation is idempotent - adding the same shard multiple times has no effect.
181
+ *
182
+ * @param shard - The shard binding name to add
183
+ * @returns Promise that resolves when the shard is added
184
+ * @throws {Error} If KV operations fail
185
+ * @example
186
+ * ```typescript
187
+ * // Register a new shard when it comes online
188
+ * await mapper.addKnownShard('db-europe');
189
+ * console.log('European shard registered');
190
+ * ```
191
+ */
192
+ addKnownShard(shard: string): Promise<void>;
193
+ /**
194
+ * Scans all shard mappings to find primary keys assigned to the specified shard.
195
+ * This operation requires reading all mappings and can be expensive for large
196
+ * datasets. Consider caching results or using getShardKeyCounts() for statistics.
197
+ *
198
+ * @param shard - The shard binding name to search for
199
+ * @returns Promise resolving to array of primary keys assigned to the shard
200
+ * @throws {Error} If KV operations fail
201
+ * @example
202
+ * ```typescript
203
+ * // Find all users on the east coast shard
204
+ * const eastCoastUsers = await mapper.getKeysForShard('db-east');
205
+ * console.log(`East coast has ${eastCoastUsers.length} users`);
206
+ * ```
207
+ */
208
+ getKeysForShard(shard: string): Promise<string[]>;
209
+ /**
210
+ * Scans all shard mappings to count how many primary keys are assigned to
211
+ * each shard. Returns a mapping of shard names to their key counts. This
212
+ * is useful for load balancing and monitoring shard utilization.
213
+ *
214
+ * **Performance Note**: This operation scans all mappings and can be
215
+ * expensive for large datasets. Consider implementing caching for frequently
216
+ * accessed statistics.
217
+ *
218
+ * @returns Promise resolving to object mapping shard names to key counts
219
+ * @throws {Error} If KV operations fail
220
+ * @example
221
+ * ```typescript
222
+ * const counts = await mapper.getShardKeyCounts();
223
+ * console.log('Shard utilization:', counts);
224
+ * // Output: { 'db-east': 1247, 'db-west': 982, 'db-central': 1156 }
225
+ *
226
+ * // Find the least loaded shard
227
+ * const leastLoaded = Object.entries(counts)
228
+ * .sort(([,a], [,b]) => a - b)[0][0];
229
+ * console.log('Least loaded shard:', leastLoaded);
230
+ * ```
231
+ */
232
+ getShardKeyCounts(): Promise<Record<string, number>>;
233
+ /**
234
+ * Deletes ALL shard mappings from KV storage. This is a destructive operation
235
+ * that removes all primary key assignments. After this operation, all keys
236
+ * will be treated as new and may be assigned to different shards.
237
+ *
238
+ * **DANGER**: This operation is irreversible and will cause data routing
239
+ * issues if used in production. Only use during development, testing, or
240
+ * complete system resets.
241
+ *
242
+ * @returns Promise that resolves when all mappings are deleted
243
+ * @throws {Error} If KV operations fail
244
+ * @example
245
+ * ```typescript
246
+ * // Only use in development/testing!
247
+ * if (process.env.NODE_ENV === 'development') {
248
+ * await mapper.clearAllMappings();
249
+ * console.log('All mappings cleared for testing');
250
+ * }
251
+ * ```
252
+ */
253
+ clearAllMappings(): Promise<void>;
254
+ }
255
+ //# sourceMappingURL=kvmap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kvmap.d.ts","sourceRoot":"","sources":["../src/kvmap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAyB/C;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,aAAa;IAKb,OAAO,CAAC,EAAE;IAJtB;;;OAGG;gBACiB,EAAE,EAAE,WAAW;IAEnC;;;;;;;;;;;;;;;;;OAiBG;IACG,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAMvE;;;;;;;;;;;;;;;;OAgBG;IACG,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWvE;;;;;;;;;;;;;;;;;;;;OAoBG;IACG,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB7E;;;;;;;;;;;;;;;;;OAiBG;IACG,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK3D;;;;;;;;;;;;;OAaG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAKzC;;;;;;;;;;;;OAYG;IACG,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAKrD;;;;;;;;;;;;;OAaG;IACG,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUjD;;;;;;;;;;;;;;OAcG;IACG,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAcvD;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACG,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAc1D;;;;;;;;;;;;;;;;;;;OAmBG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;CAKvC"}
@@ -0,0 +1,392 @@
1
+ /**
2
+ * @fileoverview Database schema management and data migration utilities for CollegeDB
3
+ *
4
+ * This module provides utilities for managing database schemas across multiple D1 shards
5
+ * and migrating data between shards. It includes default schema definitions, schema
6
+ * validation, and data migration functions that ensure consistency across the distributed
7
+ * database system.
8
+ *
9
+ * Key features:
10
+ * - Default schema creation for typical use cases
11
+ * - Schema validation and existence checking
12
+ * - Data migration between D1 database instances
13
+ * - Batch schema operations across multiple shards
14
+ * - Table discovery and management utilities
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * import { createSchema, migrateRecord, schemaExists } from './migrations.js';
19
+ *
20
+ * // Create schema on a new shard
21
+ * await createSchema(env.DB_EAST);
22
+ *
23
+ * // Check if schema exists
24
+ * const hasSchema = await schemaExists(env.DB_WEST);
25
+ *
26
+ * // Migrate a user from one shard to another
27
+ * await migrateRecord(env.DB_EAST, env.DB_WEST, 'user-123', 'users');
28
+ * ```
29
+ *
30
+ * @author Gregory Mitchell
31
+ * @since 1.0.0
32
+ */
33
+ import type { D1Database } from '@cloudflare/workers-types';
34
+ import type { KVShardMapper } from './kvmap.js';
35
+ import type { CollegeDBConfig, ShardingStrategy } from './types.js';
36
+ /**
37
+ * Executes SQL statements to create the default table structure and indexes
38
+ * in the specified D1 database. Supports custom schemas and handles SQL
39
+ * statement parsing with comment filtering.
40
+ *
41
+ * The function:
42
+ * 1. Splits the schema into individual SQL statements
43
+ * 2. Filters out comments and empty statements
44
+ * 3. Executes each statement using prepared statements
45
+ * 4. Provides detailed error reporting on failures
46
+ *
47
+ * @param d1 - The D1 database instance to create schema in
48
+ * @param schema - Schema SQL to use
49
+ * @returns Promise that resolves when all schema statements are executed
50
+ * @throws {Error} If any schema statement fails with detailed error information
51
+ * @example
52
+ * ```typescript
53
+ * const sql = `
54
+ * CREATE TABLE products (
55
+ * id TEXT PRIMARY KEY,
56
+ * name TEXT NOT NULL,
57
+ * price REAL
58
+ * );
59
+ * `;
60
+ * await createSchema(env.DB_PRODUCTS, sql);
61
+ * ```
62
+ */
63
+ export declare function createSchema(d1: D1Database, schema: string): Promise<void>;
64
+ /**
65
+ * Applies the schema to all provided D1 database instances in parallel.
66
+ * This is useful for initializing a complete sharded database system
67
+ * where all shards need the same table structure.
68
+ *
69
+ * The function executes schema creation on all shards concurrently for
70
+ * performance, but provides detailed error reporting that identifies
71
+ * which specific shard failed if any errors occur.
72
+ *
73
+ * @param shards - Record mapping shard names to D1 database instances
74
+ * @param schema - Schema SQL to use
75
+ * @returns Promise that resolves when schema is created on all shards
76
+ * @throws {Error} If schema creation fails on any shard, with shard identification
77
+ * @example
78
+ * ```typescript
79
+ * const shards = {
80
+ * 'db-east': env.DB_EAST,
81
+ * 'db-west': env.DB_WEST,
82
+ * 'db-central': env.DB_CENTRAL
83
+ * };
84
+ *
85
+ * try {
86
+ * await createSchemaAcrossShards(shards);
87
+ * console.log('Schema created on all shards successfully');
88
+ * } catch (error) {
89
+ * console.error('Schema creation failed:', error.message);
90
+ * // Error will specify which shard failed
91
+ * }
92
+ * ```
93
+ */
94
+ export declare function createSchemaAcrossShards(shards: Record<string, D1Database>, schema: string): Promise<void>;
95
+ /**
96
+ * Performs a lightweight check to determine if the expected schema is present
97
+ * in the database.
98
+ *
99
+ * @param d1 - The D1 database instance to check
100
+ * @param table - The name of the table to check
101
+ * @returns Promise resolving to true if schema tables exist, false otherwise
102
+ * @example
103
+ * ```typescript
104
+ * const hasSchema = await schemaExists(env.DB_NEW_SHARD, "users");
105
+ * if (!hasSchema) {
106
+ * console.log('Creating schema on new shard...');
107
+ * await createSchema(env.DB_NEW_SHARD, usersSchema);
108
+ * }
109
+ * ```
110
+ */
111
+ export declare function schemaExists(d1: D1Database, table: string): Promise<boolean>;
112
+ /**
113
+ * Removes all tables that are part of the default CollegeDB schema from
114
+ * the specified database. This is a destructive operation that cannot be undone.
115
+ *
116
+ * **DANGER**: This operation permanently deletes all data in the affected
117
+ * tables. Only use during development, testing, or complete system resets.
118
+ *
119
+ * @param d1 - The D1 database instance to drop tables from
120
+ * @param tables - The table schemas to drop
121
+ * @returns Promise that resolves when all tables are dropped
122
+ * @example
123
+ * ```typescript
124
+ * // Only use in development/testing environments!
125
+ * if (process.env.NODE_ENV === 'development') {
126
+ * await dropSchema(env.DB_TEST);
127
+ * console.log('Test database reset completed');
128
+ * }
129
+ * ```
130
+ */
131
+ export declare function dropSchema(d1: D1Database, ...tables: string[]): Promise<void>;
132
+ /**
133
+ * Queries the SQLite system catalog to retrieve all user-created tables
134
+ * in the database. This is useful for schema inspection, validation,
135
+ * and debugging purposes.
136
+ *
137
+ * @param d1 - The D1 database instance to inspect
138
+ * @returns Promise resolving to array of table names, sorted alphabetically
139
+ * @throws Returns empty array if query fails or database is inaccessible
140
+ * @example
141
+ * ```typescript
142
+ * const tables = await listTables(env.DB_EAST);
143
+ * console.log('Available tables:', tables);
144
+ * // Output: ['posts', 'shard_mappings', 'users']
145
+ *
146
+ * // Check for specific table
147
+ * if (tables.includes('users')) {
148
+ * console.log('Users table exists');
149
+ * }
150
+ * ```
151
+ */
152
+ export declare function listTables(d1: D1Database): Promise<string[]>;
153
+ /**
154
+ * Moves a single record from a source D1 database to a target D1 database.
155
+ * This is typically used during shard rebalancing operations when data needs
156
+ * to be redistributed across shards for load balancing.
157
+ *
158
+ * The migration process:
159
+ * 1. Retrieves the complete record from the source database
160
+ * 2. Ensures the target database has the required schema
161
+ * 3. Inserts the record into the target database (using REPLACE for safety)
162
+ * 4. Deletes the record from the source database
163
+ *
164
+ * The operation is atomic from the perspective of each database, but not
165
+ * across databases. If the operation fails partway through, manual cleanup
166
+ * may be required.
167
+ *
168
+ * @param source - Source D1 database containing the record
169
+ * @param target - Target D1 database to receive the record
170
+ * @param primaryKey - Primary key of the record to migrate
171
+ * @param tableName - Name of the table containing the record
172
+ * @returns Promise that resolves when migration is complete
173
+ * @throws {Error} If source record not found, schema creation fails, or database operations fail
174
+ * @example
175
+ * ```typescript
176
+ * // Migrate a user from east to west shard
177
+ * try {
178
+ * await migrateRecord(env.DB_EAST, env.DB_WEST, 'user-123', 'users');
179
+ * console.log('User migration completed successfully');
180
+ * } catch (error) {
181
+ * console.error('Migration failed:', error.message);
182
+ * // May need manual cleanup depending on where it failed
183
+ * }
184
+ *
185
+ * // Migrate a post between shards
186
+ * await migrateRecord(source, target, 'post-456', 'posts');
187
+ * ```
188
+ */
189
+ export declare function migrateRecord(source: D1Database, target: D1Database, primaryKey: string, tableName: string): Promise<void>;
190
+ /**
191
+ * Scans an existing table to find all primary keys that need to be mapped to shards.
192
+ * This is useful when integrating CollegeDB with an existing database that already
193
+ * contains data. The function assumes the table has an 'id' column as the primary key.
194
+ *
195
+ * @param d1 - The D1 database instance to scan
196
+ * @param tableName - Name of the table to discover primary keys from
197
+ * @param primaryKeyColumn - Name of the primary key column (defaults to 'id')
198
+ * @returns Promise resolving to array of primary key values
199
+ * @throws {Error} If table doesn't exist or database query fails
200
+ * @example
201
+ * ```typescript
202
+ * // Discover all user IDs in an existing users table
203
+ * const userIds = await discoverExistingPrimaryKeys(env.DB_EXISTING, 'users');
204
+ * console.log(`Found ${userIds.length} existing users`);
205
+ *
206
+ * // Discover with custom primary key column
207
+ * const orderIds = await discoverExistingPrimaryKeys(env.DB_ORDERS, 'orders', 'order_id');
208
+ * ```
209
+ */
210
+ export declare function discoverExistingPrimaryKeys(d1: D1Database, tableName: string, primaryKeyColumn?: string): Promise<string[]>;
211
+ /**
212
+ * Takes a list of existing primary keys and creates shard mappings for them using
213
+ * the specified allocation strategy. This allows existing data to be integrated
214
+ * into the CollegeDB sharding system without data migration.
215
+ *
216
+ * @param primaryKeys - Array of primary key values to create mappings for
217
+ * @param shardBindings - Array of available shard binding names
218
+ * @param strategy - Allocation strategy to use ('hash', 'round-robin', or 'random')
219
+ * @param mapper - KVShardMapper instance for storing mappings
220
+ * @returns Promise that resolves when all mappings are created
221
+ * @throws {Error} If mapping creation fails
222
+ * @example
223
+ * ```typescript
224
+ * import { KVShardMapper } from './kvmap.js';
225
+ *
226
+ * const mapper = new KVShardMapper(env.KV);
227
+ * const existingIds = await discoverExistingPrimaryKeys(env.DB_EXISTING, 'users');
228
+ * const shards = ['db-east', 'db-west', 'db-central'];
229
+ *
230
+ * await createMappingsForExistingKeys(existingIds, shards, 'hash', mapper);
231
+ * console.log('All existing users mapped to shards');
232
+ * ```
233
+ */
234
+ export declare function createMappingsForExistingKeys(primaryKeys: string[], shardBindings: string[], strategy: 'hash' | 'round-robin' | 'random', mapper: any): Promise<void>;
235
+ /**
236
+ * Represents the result of validating a table for sharding.
237
+ * Contains information about the table structure, primary key, record count,
238
+ * and any issues encountered during validation.
239
+ */
240
+ export type ValidationResult = {
241
+ isValid: boolean;
242
+ tableName: string;
243
+ primaryKeyColumn: string;
244
+ recordCount: number;
245
+ issues: string[];
246
+ };
247
+ /**
248
+ * Checks if a table exists and has a primary key column that can be used
249
+ * for sharding. Returns information about the table structure and primary key.
250
+ *
251
+ * @param d1 - The D1 database instance to check
252
+ * @param tableName - Name of the table to validate
253
+ * @param primaryKeyColumn - Expected primary key column name (defaults to 'id')
254
+ * @returns Promise resolving to validation result with table info
255
+ * @throws {Error} If table doesn't exist or validation fails
256
+ * @example
257
+ * ```typescript
258
+ * const validation = await validateTableForSharding(env.DB_EXISTING, 'users');
259
+ * if (validation.isValid) {
260
+ * console.log(`Table ${validation.tableName} is ready for sharding`);
261
+ * console.log(`Primary key: ${validation.primaryKeyColumn}`);
262
+ * console.log(`Record count: ${validation.recordCount}`);
263
+ * } else {
264
+ * console.error('Table validation failed:', validation.issues);
265
+ * }
266
+ * ```
267
+ */
268
+ export declare function validateTableForSharding(d1: D1Database, tableName: string, primaryKeyColumn: string): Promise<ValidationResult>;
269
+ /**
270
+ * Configuration options for integrating an existing database with CollegeDB.
271
+ * Allows customization of which tables to process, primary key column,
272
+ * sharding strategy, and whether to add the shard_mappings table.
273
+ */
274
+ export type IntegrationOptions = {
275
+ tables?: string[];
276
+ primaryKeyColumn?: string;
277
+ strategy?: ShardingStrategy;
278
+ addShardMappingsTable?: boolean;
279
+ dryRun?: boolean;
280
+ };
281
+ /**
282
+ * Represents the result of integrating an existing database with CollegeDB.
283
+ * Contains information about the success of the integration, shard name,
284
+ * number of tables processed, total records integrated, mappings created,
285
+ * and any issues encountered during the process.
286
+ */
287
+ export type IntegrationResult = {
288
+ success: boolean;
289
+ shardName: string;
290
+ tablesProcessed: number;
291
+ totalRecords: number;
292
+ mappingsCreated: number;
293
+ issues: string[];
294
+ };
295
+ /**
296
+ * Performs a complete drop-in integration of an existing database.
297
+ * This is the main function for integrating CollegeDB with an existing database
298
+ * that already contains data. It discovers tables, validates them, creates shard
299
+ * mappings, and optionally adds the shard_mappings table if needed.
300
+ *
301
+ * @param d1 - The existing D1 database to integrate
302
+ * @param shardName - The shard binding name for this database
303
+ * @param mapper - KVShardMapper instance for storing mappings
304
+ * @param options - Configuration options for the integration
305
+ * @returns Promise resolving to integration summary
306
+ * @throws {Error} If integration fails
307
+ * @example
308
+ * ```typescript
309
+ * import { KVShardMapper } from './kvmap.js';
310
+ *
311
+ * const mapper = new KVShardMapper(env.KV);
312
+ * const result = await integrateExistingDatabase(env.DB_EXISTING, 'db-existing', mapper, {
313
+ * tables: ['users', 'posts'],
314
+ * strategy: 'hash',
315
+ * addShardMappingsTable: true
316
+ * });
317
+ *
318
+ * console.log(`Integrated ${result.totalRecords} records from ${result.tablesProcessed} tables`);
319
+ * ```
320
+ */
321
+ export declare function integrateExistingDatabase(d1: D1Database, shardName: string, mapper: KVShardMapper, options?: IntegrationOptions): Promise<IntegrationResult>;
322
+ /**
323
+ * Automatically detects if a database needs migration and performs it
324
+ *
325
+ * This function is called automatically by CollegeDB operations to detect
326
+ * existing databases that contain data but haven't been integrated into the
327
+ * sharding system. It performs seamless migration without user intervention.
328
+ *
329
+ * The detection process:
330
+ * 1. Checks if the database has data tables with primary keys
331
+ * 2. Verifies if primary key mappings exist in KV
332
+ * 3. If unmapped data is found, performs automatic integration
333
+ * 4. Caches results to avoid repeated checks
334
+ *
335
+ * @param d1 - The D1 database instance to check and potentially migrate
336
+ * @param shardName - The shard binding name for this database
337
+ * @param config - CollegeDB configuration containing KV and strategy
338
+ * @param options - Optional migration configuration
339
+ * @returns Promise resolving to migration result summary
340
+ * @example
341
+ * ```typescript
342
+ * // Called automatically by CollegeDB operations
343
+ * const result = await autoDetectAndMigrate(env.DB_EXISTING, 'db-existing', config);
344
+ * if (result.migrationPerformed) {
345
+ * console.log(`Auto-migrated ${result.recordsMigrated} records`);
346
+ * }
347
+ * ```
348
+ */
349
+ export declare function autoDetectAndMigrate(d1: D1Database, shardName: string, config: CollegeDBConfig, options?: {
350
+ primaryKeyColumn?: string;
351
+ tablesToCheck?: string[];
352
+ skipCache?: boolean;
353
+ maxRecordsToCheck?: number;
354
+ }): Promise<{
355
+ migrationNeeded: boolean;
356
+ migrationPerformed: boolean;
357
+ recordsMigrated: number;
358
+ tablesProcessed: number;
359
+ issues: string[];
360
+ }>;
361
+ /**
362
+ * Performs a lightweight check to determine if a database contains
363
+ * existing data that hasn't been mapped to the sharding system.
364
+ * This is used internally to trigger automatic migration.
365
+ *
366
+ * @param d1 - The D1 database instance to check
367
+ * @param shardName - The shard binding name
368
+ * @param config - CollegeDB configuration
369
+ * @returns Promise resolving to true if migration is needed
370
+ * @example
371
+ * ```typescript
372
+ * const needsMigration = await checkMigrationNeeded(env.DB, 'db-main', config);
373
+ * if (needsMigration) {
374
+ * console.log('Database contains unmapped data');
375
+ * }
376
+ * ```
377
+ */
378
+ export declare function checkMigrationNeeded(d1: D1Database, shardName: string, config: CollegeDBConfig): Promise<boolean>;
379
+ /**
380
+ * Clears the migration status cache
381
+ *
382
+ * Resets the internal cache used to track which databases have been
383
+ * checked for migration. Useful for testing or forcing re-checks.
384
+ *
385
+ * @example
386
+ * ```typescript
387
+ * // Force re-check of all databases
388
+ * clearMigrationCache();
389
+ * ```
390
+ */
391
+ export declare function clearMigrationCache(): void;
392
+ //# sourceMappingURL=migrations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../src/migrations.ts"],"names":[],"mappings":"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"}