@earth-app/collegedb 1.1.3 → 1.2.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.
- package/README.md +373 -48
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -9
- package/dist/index.js.map +8 -7
- package/dist/providers-memory.d.ts +111 -0
- package/dist/providers-memory.d.ts.map +1 -0
- package/dist/router.d.ts +73 -0
- package/dist/router.d.ts.map +1 -1
- package/package.json +10 -9
package/README.md
CHANGED
|
@@ -19,6 +19,7 @@ A TypeScript library for **true horizontal scaling** of SQLite-style databases p
|
|
|
19
19
|
- [Provider Adapters](#provider-adapters)
|
|
20
20
|
- [NuxtHub + Drizzle Recipes](#nuxthub--drizzle-recipes)
|
|
21
21
|
- [Sandbox Benchmarks (Docker Compose)](#sandbox-benchmarks-docker-compose)
|
|
22
|
+
- [In-Memory Providers for Testing & Development](#in-memory-providers-for-testing--development)
|
|
22
23
|
- [Basic Usage](#basic-usage)
|
|
23
24
|
- [Multi-Key Shard Mappings](#multi-key-shard-mappings)
|
|
24
25
|
- [Drop-in Replacement for Existing Databases](#drop-in-replacement-for-existing-databases)
|
|
@@ -71,6 +72,7 @@ This allows you to:
|
|
|
71
72
|
- Automatic query routing (primary key to shard mapping)
|
|
72
73
|
- Provider adapters for Redis/Valkey/NuxtHub KV plus PostgreSQL/MySQL/SQLite SQL
|
|
73
74
|
- Drizzle interop through existing SQL providers (`createPostgreSQLProvider`, `createMySQLProvider`, `createSQLiteProvider`)
|
|
75
|
+
- Auto-allocated generated-id inserts via `insert()` and direct-shard inserts via `insertShard()` for AUTOINCREMENT / RETURNING workflows
|
|
74
76
|
- Hyperdrive helpers for PostgreSQL and MySQL
|
|
75
77
|
- Multiple allocation strategies: round-robin, random, hash, location-aware, and mixed read/write strategies
|
|
76
78
|
- Durable Object shard coordination and shard statistics
|
|
@@ -193,18 +195,19 @@ CollegeDB includes a benchmark runner that executes each SQL+KV combination acro
|
|
|
193
195
|
|
|
194
196
|
### Scenario Catalog
|
|
195
197
|
|
|
196
|
-
| Scenario Key | Scenario | What Happens
|
|
197
|
-
| ----------------- | -------------------------------- |
|
|
198
|
-
| basic_crud | Basic CRUD round-trip | Insert, read, update, and delete a user via routed queries.
|
|
199
|
-
| advanced_usage | Advanced lookup workflow | Writes user+post, adds lookup aliases, then validates join and alias-based lookup.
|
|
200
|
-
| migration_mapping | Migration-style mapping creation | Inserts legacy records on a fixed shard, then builds shard mappings in batch and validates routing.
|
|
201
|
-
| bulk_crud | Bulk CRUD pressure | Performs bulk inserts, half updates, and full delete sweep, then validates shard-wide totals.
|
|
202
|
-
|
|
|
203
|
-
|
|
|
204
|
-
|
|
|
205
|
-
|
|
|
206
|
-
|
|
|
207
|
-
|
|
|
198
|
+
| Scenario Key | Scenario | What Happens | Workload Per Run |
|
|
199
|
+
| ----------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
|
|
200
|
+
| basic_crud | Basic CRUD round-trip | Insert, read, update, and delete a user via routed queries. | 20 iterations; 4 routed SQL ops per iteration |
|
|
201
|
+
| advanced_usage | Advanced lookup workflow | Writes user+post, adds lookup aliases, then validates join and alias-based lookup. | 15 iterations; ~5 routed SQL ops + KV lookup-key updates per iteration |
|
|
202
|
+
| migration_mapping | Migration-style mapping creation | Inserts legacy records on a fixed shard, then builds shard mappings in batch and validates routing. | 10 iterations; 20 legacy records mapped per iteration |
|
|
203
|
+
| bulk_crud | Bulk CRUD pressure | Performs bulk inserts, half updates, and full delete sweep, then validates shard-wide totals. | 7 iterations; 160 inserts + 80 updates + 160 deletes per iteration |
|
|
204
|
+
| auto_increment | Auto-generated primary keys | Inserts rows with generated ids on an automatically selected shard, captures the generated key, then validates routed readback. | 6 iterations; insert + generated-id readback per iteration |
|
|
205
|
+
| indexing | Indexed query scan | Creates an index on posts(user_id) and repeatedly queries the indexed path. | 15 iterations after warmup dataset build |
|
|
206
|
+
| metadata_fetch | Metadata inspection | Reads table metadata/introspection rows from one shard. | 14 iterations; 1 metadata query per iteration |
|
|
207
|
+
| pragma_or_info | PRAGMA / server info | Runs provider-specific PRAGMA/info query to sample low-level metadata latency. | 14 iterations; 1 pragma/info query per iteration |
|
|
208
|
+
| counting | Cross-shard counting | Counts users across all shards to measure fanout aggregation overhead. | 14 iterations; all-shard count aggregation per iteration |
|
|
209
|
+
| shard_fanout | Shard fanout query | Runs query fanout to all shards and aggregates shard-level responses. | 14 iterations; 1 all-shards query per iteration |
|
|
210
|
+
| reassignment | Shard reassignment flow | Creates a record, reassigns it to another shard, and verifies routed reads still succeed. | 10 iterations; insert + reassignment + verification per iteration |
|
|
208
211
|
|
|
209
212
|
### Report Matrices
|
|
210
213
|
|
|
@@ -439,6 +442,7 @@ Benchmark coverage includes:
|
|
|
439
442
|
- advanced lookup/routing workflows
|
|
440
443
|
- migration-style mapping creation
|
|
441
444
|
- bulk CRUD
|
|
445
|
+
- auto-generated primary key inserts and readback
|
|
442
446
|
- indexing queries
|
|
443
447
|
- metadata fetch
|
|
444
448
|
- pragma/info queries (provider-specific)
|
|
@@ -453,6 +457,264 @@ How to read benchmark rows:
|
|
|
453
457
|
- `N/A` means the scenario was intentionally skipped in that environment.
|
|
454
458
|
- Use the detailed section for full `avg`, `p50`, `p95`, `min`, `max`, and sample count (`n`).
|
|
455
459
|
|
|
460
|
+
## In-Memory Providers for Testing & Development
|
|
461
|
+
|
|
462
|
+
CollegeDB includes lightweight, zero-dependency in-memory mock implementations of the `KVStorage` and `SQLDatabase` interfaces. These are ideal for:
|
|
463
|
+
|
|
464
|
+
- **Unit testing** without external dependencies
|
|
465
|
+
- **Integration testing** with multiple shard combinations
|
|
466
|
+
- **Local development** and rapid iteration
|
|
467
|
+
- **Sandboxed playtesting** of routing logic
|
|
468
|
+
|
|
469
|
+
The in-memory providers work in Cloudflare Workers, Node.js, and Deno environments.
|
|
470
|
+
|
|
471
|
+
### Quick Start with In-Memory Providers
|
|
472
|
+
|
|
473
|
+
```typescript
|
|
474
|
+
import { createInMemoryKVProvider, createInMemorySQLProvider, initialize, run, first } from '@earth-app/collegedb';
|
|
475
|
+
|
|
476
|
+
// Create fresh in-memory providers for each test
|
|
477
|
+
const config = {
|
|
478
|
+
kv: createInMemoryKVProvider(),
|
|
479
|
+
shards: {
|
|
480
|
+
'shard-1': createInMemorySQLProvider(),
|
|
481
|
+
'shard-2': createInMemorySQLProvider(),
|
|
482
|
+
'shard-3': createInMemorySQLProvider()
|
|
483
|
+
},
|
|
484
|
+
strategy: 'hash'
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
initialize(config);
|
|
488
|
+
|
|
489
|
+
// Use as normal - all operations happen in-memory
|
|
490
|
+
await run('user-1', 'INSERT INTO users (id, name, email) VALUES (?, ?, ?)', ['user-1', 'Alice', 'alice@example.com']);
|
|
491
|
+
|
|
492
|
+
const user = await first<{ id: string; name: string }>('user-1', 'SELECT id, name FROM users WHERE id = ?', ['user-1']);
|
|
493
|
+
console.log(user); // { id: 'user-1', name: 'Alice' }
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
### Unit Testing Example
|
|
497
|
+
|
|
498
|
+
```typescript
|
|
499
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
500
|
+
import { createInMemoryKVProvider, createInMemorySQLProvider, initialize, resetConfig, run, first } from '@earth-app/collegedb';
|
|
501
|
+
|
|
502
|
+
describe('User Shard Routing', () => {
|
|
503
|
+
beforeEach(() => {
|
|
504
|
+
// Fresh providers for each test
|
|
505
|
+
initialize({
|
|
506
|
+
kv: createInMemoryKVProvider(),
|
|
507
|
+
shards: {
|
|
508
|
+
'shard-1': createInMemorySQLProvider(),
|
|
509
|
+
'shard-2': createInMemorySQLProvider(),
|
|
510
|
+
'shard-3': createInMemorySQLProvider()
|
|
511
|
+
},
|
|
512
|
+
strategy: 'hash'
|
|
513
|
+
});
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
afterEach(() => {
|
|
517
|
+
resetConfig();
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
it('should insert and retrieve a user', async () => {
|
|
521
|
+
await run('user-1', 'INSERT INTO users (id, name, email) VALUES (?, ?, ?)', ['user-1', 'Alice', 'alice@example.com']);
|
|
522
|
+
|
|
523
|
+
const user = await first<{ name: string }>('user-1', 'SELECT name FROM users WHERE id = ?', ['user-1']);
|
|
524
|
+
|
|
525
|
+
expect(user?.name).toBe('Alice');
|
|
526
|
+
});
|
|
527
|
+
|
|
528
|
+
it('should distribute users across shards', async () => {
|
|
529
|
+
// Insert multiple users
|
|
530
|
+
for (let i = 0; i < 9; i++) {
|
|
531
|
+
await run(`user-${i}`, 'INSERT INTO users (id, name) VALUES (?, ?)', [`user-${i}`, `User ${i}`]);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// Verify each can be retrieved
|
|
535
|
+
for (let i = 0; i < 9; i++) {
|
|
536
|
+
const user = await first(`user-${i}`, 'SELECT id FROM users WHERE id = ?', [`user-${i}`]);
|
|
537
|
+
expect(user).toBeDefined();
|
|
538
|
+
}
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
it('should handle updates correctly', async () => {
|
|
542
|
+
await run('user-1', 'INSERT INTO users (id, name) VALUES (?, ?)', ['user-1', 'Alice']);
|
|
543
|
+
|
|
544
|
+
await run('user-1', 'UPDATE users SET name = ? WHERE id = ?', ['Alice Updated', 'user-1']);
|
|
545
|
+
|
|
546
|
+
const user = await first<{ name: string }>('user-1', 'SELECT name FROM users WHERE id = ?', ['user-1']);
|
|
547
|
+
|
|
548
|
+
expect(user?.name).toBe('Alice Updated');
|
|
549
|
+
});
|
|
550
|
+
});
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
### Integration Testing with Multiple Providers
|
|
554
|
+
|
|
555
|
+
Test different combinations without Docker or external services:
|
|
556
|
+
|
|
557
|
+
```typescript
|
|
558
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
559
|
+
import {
|
|
560
|
+
createInMemoryKVProvider,
|
|
561
|
+
createInMemorySQLProvider,
|
|
562
|
+
initialize,
|
|
563
|
+
resetConfig,
|
|
564
|
+
run,
|
|
565
|
+
first,
|
|
566
|
+
KVShardMapper
|
|
567
|
+
} from '@earth-app/collegedb';
|
|
568
|
+
|
|
569
|
+
describe('Multi-Provider Integration', () => {
|
|
570
|
+
it('should work with different KV/SQL combinations', async () => {
|
|
571
|
+
const combinations = [{ kvName: 'memory', sqlName: 'memory' }];
|
|
572
|
+
|
|
573
|
+
for (const combo of combinations) {
|
|
574
|
+
resetConfig();
|
|
575
|
+
|
|
576
|
+
initialize({
|
|
577
|
+
kv: createInMemoryKVProvider(),
|
|
578
|
+
shards: {
|
|
579
|
+
'shard-1': createInMemorySQLProvider(),
|
|
580
|
+
'shard-2': createInMemorySQLProvider()
|
|
581
|
+
},
|
|
582
|
+
strategy: 'hash'
|
|
583
|
+
});
|
|
584
|
+
|
|
585
|
+
// Test basic operations
|
|
586
|
+
await run('key-1', 'INSERT INTO data (id, value) VALUES (?, ?)', ['key-1', 'test-value']);
|
|
587
|
+
|
|
588
|
+
const row = await first('key-1', 'SELECT value FROM data WHERE id = ?', ['key-1']);
|
|
589
|
+
|
|
590
|
+
expect(row?.value).toBe('test-value');
|
|
591
|
+
}
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
it('should support lookup key mapping', async () => {
|
|
595
|
+
initialize({
|
|
596
|
+
kv: createInMemoryKVProvider(),
|
|
597
|
+
shards: { 'shard-1': createInMemorySQLProvider() },
|
|
598
|
+
strategy: 'hash'
|
|
599
|
+
});
|
|
600
|
+
|
|
601
|
+
const mapper = new KVShardMapper(createInMemoryKVProvider());
|
|
602
|
+
|
|
603
|
+
// Add lookup keys
|
|
604
|
+
await mapper.addLookupKeys('user-123', ['email:alice@example.com', 'username:alice']);
|
|
605
|
+
|
|
606
|
+
// Retrieve via lookup key
|
|
607
|
+
const mapping = await mapper.getShardMapping('email:alice@example.com');
|
|
608
|
+
expect(mapping?.shard).toBeDefined();
|
|
609
|
+
});
|
|
610
|
+
});
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
### Performance Testing with In-Memory Providers
|
|
614
|
+
|
|
615
|
+
Run quick performance tests locally without external dependencies:
|
|
616
|
+
|
|
617
|
+
```typescript
|
|
618
|
+
import { createInMemoryKVProvider, createInMemorySQLProvider, initialize, run } from '@earth-app/collegedb';
|
|
619
|
+
|
|
620
|
+
async function benchmarkInserts(iterations: number): Promise<number> {
|
|
621
|
+
initialize({
|
|
622
|
+
kv: createInMemoryKVProvider(),
|
|
623
|
+
shards: {
|
|
624
|
+
'shard-1': createInMemorySQLProvider(),
|
|
625
|
+
'shard-2': createInMemorySQLProvider(),
|
|
626
|
+
'shard-3': createInMemorySQLProvider()
|
|
627
|
+
},
|
|
628
|
+
strategy: 'hash'
|
|
629
|
+
});
|
|
630
|
+
|
|
631
|
+
const startTime = performance.now();
|
|
632
|
+
|
|
633
|
+
for (let i = 0; i < iterations; i++) {
|
|
634
|
+
const id = `perf-user-${i}`;
|
|
635
|
+
await run(id, 'INSERT INTO users (id, name) VALUES (?, ?)', [id, `User ${i}`]);
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
return performance.now() - startTime;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
const duration = await benchmarkInserts(1000);
|
|
642
|
+
console.log(`1000 inserts: ${duration.toFixed(2)}ms (${((1000 / duration) * 1000).toFixed(0)} ops/sec)`);
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
### Running the Memory Provider Sandbox
|
|
646
|
+
|
|
647
|
+
CollegeDB includes a ready-made sandbox example demonstrating multiple scenarios:
|
|
648
|
+
|
|
649
|
+
```bash
|
|
650
|
+
bun run test:memory
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
This runs comprehensive benchmarks including:
|
|
654
|
+
|
|
655
|
+
- Basic CRUD operations
|
|
656
|
+
- Multi-shard data distribution
|
|
657
|
+
- KV storage operations
|
|
658
|
+
- Round-robin strategy testing
|
|
659
|
+
- JOIN query performance
|
|
660
|
+
|
|
661
|
+
### Supported Operations
|
|
662
|
+
|
|
663
|
+
Both in-memory providers support the complete CollegeDB API:
|
|
664
|
+
|
|
665
|
+
**SQLDatabase features:**
|
|
666
|
+
|
|
667
|
+
- CREATE TABLE / DROP TABLE
|
|
668
|
+
- INSERT / UPDATE / DELETE
|
|
669
|
+
- SELECT with WHERE clauses
|
|
670
|
+
- COUNT(\*) queries
|
|
671
|
+
- JOIN queries
|
|
672
|
+
- PRAGMA queries (basic support)
|
|
673
|
+
|
|
674
|
+
**KVStorage features:**
|
|
675
|
+
|
|
676
|
+
- `get()` / `put()` / `delete()`
|
|
677
|
+
- `list()` with prefix filtering and cursor-based pagination
|
|
678
|
+
- TTL/expiration support
|
|
679
|
+
|
|
680
|
+
### Limitations
|
|
681
|
+
|
|
682
|
+
The in-memory providers are intentionally simple to avoid dependencies:
|
|
683
|
+
|
|
684
|
+
- **SQL Parser**: Basic pattern matching instead of full SQL parsing; works well for standard CollegeDB patterns but may not handle complex SQL edge cases
|
|
685
|
+
- **Joins**: Supported at application level; cross-shard joins work via multiple routed queries
|
|
686
|
+
- **Transactions**: Not supported; operations are atomic per-statement
|
|
687
|
+
- **Indexes**: Created but not actually used for query optimization
|
|
688
|
+
- **Schema**: Inferred from CREATE TABLE statements; dynamic column detection based on binding order
|
|
689
|
+
|
|
690
|
+
For production use, migrate to appropriate providers (D1, Redis, PostgreSQL, etc.). For testing/development, these limitations are intentional to keep the implementation lightweight and zero-dependency.
|
|
691
|
+
|
|
692
|
+
### Migrating from In-Memory to Production Providers
|
|
693
|
+
|
|
694
|
+
When ready to migrate from testing to production:
|
|
695
|
+
|
|
696
|
+
```typescript
|
|
697
|
+
// Before (testing)
|
|
698
|
+
import { createInMemoryKVProvider, createInMemorySQLProvider } from '@earth-app/collegedb';
|
|
699
|
+
|
|
700
|
+
const config = {
|
|
701
|
+
kv: createInMemoryKVProvider(),
|
|
702
|
+
shards: { 'shard-1': createInMemorySQLProvider() }
|
|
703
|
+
};
|
|
704
|
+
|
|
705
|
+
// After (production)
|
|
706
|
+
import { createRedisKVProvider, createPostgreSQLProvider } from '@earth-app/collegedb';
|
|
707
|
+
|
|
708
|
+
const config = {
|
|
709
|
+
kv: createRedisKVProvider(redisClient),
|
|
710
|
+
shards: { 'shard-1': createPostgreSQLProvider(pgPool) }
|
|
711
|
+
};
|
|
712
|
+
|
|
713
|
+
// Rest of configuration stays the same!
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
The API remains identical - only the provider initialization changes.
|
|
717
|
+
|
|
456
718
|
## Basic Usage
|
|
457
719
|
|
|
458
720
|
```typescript
|
|
@@ -572,6 +834,67 @@ This approach provides:
|
|
|
572
834
|
- **Optimal read performance**: Queries use `hash` strategy for consistent, high-performance routing
|
|
573
835
|
- **Flexibility**: Each operation type can use the most appropriate routing strategy
|
|
574
836
|
|
|
837
|
+
### Auto-Generated Primary Keys
|
|
838
|
+
|
|
839
|
+
When your table assigns the primary key during insert, use `insert()` for the automatic shard-allocation path or `insertShard()` when you already know the target shard. Both helpers capture the generated id from provider metadata or `RETURNING` rows, then store the generated-id mapping so the normal routed `first()` / `all()` helpers can read the row back.
|
|
840
|
+
|
|
841
|
+
```typescript
|
|
842
|
+
import { first, insert, insertShard } from '@earth-app/collegedb';
|
|
843
|
+
|
|
844
|
+
// SQLite / D1
|
|
845
|
+
await createSchema(
|
|
846
|
+
env['db-east'],
|
|
847
|
+
`
|
|
848
|
+
CREATE TABLE IF NOT EXISTS auto_users (
|
|
849
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
850
|
+
name TEXT NOT NULL,
|
|
851
|
+
email TEXT UNIQUE,
|
|
852
|
+
created_at INTEGER
|
|
853
|
+
)
|
|
854
|
+
`
|
|
855
|
+
);
|
|
856
|
+
|
|
857
|
+
const created = await insert('INSERT INTO auto_users (name, email, created_at) VALUES (?, ?, ?)', ['Ada', 'ada@example.com', Date.now()]);
|
|
858
|
+
|
|
859
|
+
const row = await first(String(created.generatedId), 'SELECT * FROM auto_users WHERE id = ?', [created.generatedId]);
|
|
860
|
+
```
|
|
861
|
+
|
|
862
|
+
```typescript
|
|
863
|
+
// Direct shard insert when you want to pin the write to a specific shard
|
|
864
|
+
const directCreated = await insertShard('db-east', 'INSERT INTO auto_users (name, email, created_at) VALUES (?, ?, ?)', [
|
|
865
|
+
'Ada',
|
|
866
|
+
'ada@example.com',
|
|
867
|
+
Date.now()
|
|
868
|
+
]);
|
|
869
|
+
|
|
870
|
+
console.log(directCreated.generatedId);
|
|
871
|
+
```
|
|
872
|
+
|
|
873
|
+
```typescript
|
|
874
|
+
// PostgreSQL / MySQL 8.0.19+ RETURNING path
|
|
875
|
+
await createSchema(
|
|
876
|
+
env['db-east'],
|
|
877
|
+
`
|
|
878
|
+
CREATE TABLE IF NOT EXISTS auto_users (
|
|
879
|
+
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
880
|
+
name VARCHAR(255) NOT NULL,
|
|
881
|
+
email VARCHAR(255) UNIQUE,
|
|
882
|
+
created_at BIGINT
|
|
883
|
+
)
|
|
884
|
+
`
|
|
885
|
+
);
|
|
886
|
+
|
|
887
|
+
const created = await insert('INSERT INTO auto_users (name, email, created_at) VALUES (?, ?, ?) RETURNING id', [
|
|
888
|
+
'Ada',
|
|
889
|
+
'ada@example.com',
|
|
890
|
+
Date.now()
|
|
891
|
+
]);
|
|
892
|
+
|
|
893
|
+
const row = await first(String(created.generatedId), 'SELECT * FROM auto_users WHERE id = ?', [created.generatedId]);
|
|
894
|
+
```
|
|
895
|
+
|
|
896
|
+
If your SQL dialect uses `RETURNING`, include it in the insert statement. The helper will use the returned row instead of provider metadata when present.
|
|
897
|
+
|
|
575
898
|
## Multi-Key Shard Mappings
|
|
576
899
|
|
|
577
900
|
CollegeDB supports **multiple lookup keys** for the same record, allowing you to query by username, email, ID, or any unique identifier. Keys are automatically hashed with SHA-256 for security and privacy.
|
|
@@ -1022,42 +1345,44 @@ await first('user-123', 'SELECT * FROM users WHERE email = ?', [email]);
|
|
|
1022
1345
|
|
|
1023
1346
|
## API Reference
|
|
1024
1347
|
|
|
1025
|
-
| Function | Description
|
|
1026
|
-
| ------------------------------------------------- |
|
|
1027
|
-
| `collegedb(config, callback)` | Initialize CollegeDB, then run a callback
|
|
1028
|
-
| `initialize(config)` | Initialize CollegeDB with configuration
|
|
1029
|
-
| `createSchema(db, schema)` | Create schema on a shard database
|
|
1030
|
-
| `prepare(key, sql)` | Prepare a SQL statement for execution
|
|
1031
|
-
| `run(key, sql, bindings)` | Execute a SQL query with primary key routing
|
|
1032
|
-
| `
|
|
1033
|
-
| `
|
|
1034
|
-
| `
|
|
1035
|
-
| `
|
|
1036
|
-
| `
|
|
1037
|
-
| `
|
|
1038
|
-
| `
|
|
1039
|
-
| `
|
|
1040
|
-
| `
|
|
1041
|
-
| `
|
|
1042
|
-
| `
|
|
1043
|
-
| `
|
|
1044
|
-
| `
|
|
1045
|
-
| `
|
|
1046
|
-
| `
|
|
1047
|
-
| `
|
|
1048
|
-
| `
|
|
1049
|
-
| `
|
|
1050
|
-
| `
|
|
1051
|
-
| `
|
|
1052
|
-
| `
|
|
1053
|
-
| `
|
|
1054
|
-
| `
|
|
1055
|
-
| `
|
|
1056
|
-
| `
|
|
1057
|
-
| `
|
|
1058
|
-
| `
|
|
1059
|
-
| `
|
|
1060
|
-
| `
|
|
1348
|
+
| Function | Description | Parameters |
|
|
1349
|
+
| ------------------------------------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------ |
|
|
1350
|
+
| `collegedb(config, callback)` | Initialize CollegeDB, then run a callback | `CollegeDBConfig, () => T` |
|
|
1351
|
+
| `initialize(config)` | Initialize CollegeDB with configuration | `CollegeDBConfig` |
|
|
1352
|
+
| `createSchema(db, schema)` | Create schema on a shard database | `SQLDatabase, string` |
|
|
1353
|
+
| `prepare(key, sql)` | Prepare a SQL statement for execution | `string, string` |
|
|
1354
|
+
| `run(key, sql, bindings)` | Execute a SQL query with primary key routing | `string, string, any[]` |
|
|
1355
|
+
| `insert(sql, bindings)` | Insert on an automatically selected shard and capture the generated id | `string, any[]` |
|
|
1356
|
+
| `insertShard(shard, sql, bindings)` | Insert directly on a specific shard and capture the generated id | `string, string, any[]` |
|
|
1357
|
+
| `first(key, sql, bindings)` | Execute a SQL query and return first result | `string, string, any[]` |
|
|
1358
|
+
| `all(key, sql, bindings)` | Execute a SQL query and return all results | `string, string, any[]` |
|
|
1359
|
+
| `index(key, table, columns, options)` | Create an index on routed shard | `string, string, string or index-column array, CreateIndexOptions` |
|
|
1360
|
+
| `indexShard(shard, table, columns, options)` | Create an index on one shard | `string, string, string or index-column array, CreateIndexOptions` |
|
|
1361
|
+
| `indexAllShards(table, columns, options)` | Create an index on all shards | `string, string or index-column array, CreateIndexOptions` |
|
|
1362
|
+
| `firstByLookupKey(key, sql, bindings, batchSize)` | Resolve secondary-key mapping, fallback to fanout | `string, string, any[], number` |
|
|
1363
|
+
| `allByLookupKey(key, sql, bindings, batchSize)` | Resolve secondary-key mapping, fallback to fanout | `string, string, any[], number` |
|
|
1364
|
+
| `runShard(shard, sql, bindings)` | Execute a query directly on a specific shard | `string, string, any[]` |
|
|
1365
|
+
| `allShard(shard, sql, bindings)` | Execute a query on specific shard, return all results | `string, string, any[]` |
|
|
1366
|
+
| `firstShard(shard, sql, bindings)` | Execute a query on specific shard, return first result | `string, string, any[]` |
|
|
1367
|
+
| `explain(key, sql, bindings, options)` | Inspect query plan on routed shard | `string, string, any[], ExplainOptions` |
|
|
1368
|
+
| `explainShard(shard, sql, bindings, options)` | Inspect query plan on one shard | `string, string, any[], ExplainOptions` |
|
|
1369
|
+
| `explainAllShards(sql, bindings, options)` | Inspect query plan on all shards | `string, any[], ExplainOptions` |
|
|
1370
|
+
| `count(key, table)` | Count rows on routed shard | `string, string` |
|
|
1371
|
+
| `countShard(shard, table)` | Count rows on a specific shard | `string, string` |
|
|
1372
|
+
| `countAllShards(table, batchSize)` | Count rows per shard and global total | `string, number` |
|
|
1373
|
+
| `runAllShards(sql, bindings, batchSize)` | Execute query on all shards | `string, any[], number` |
|
|
1374
|
+
| `allAllShards(sql, bindings, batchSize)` | Execute query on all shards (SQL pagination applies per shard) | `string, any[], number` |
|
|
1375
|
+
| `firstAllShards(sql, bindings, batchSize)` | Execute query on all shards, return first row per shard | `string, any[], number` |
|
|
1376
|
+
| `allAllShardsGlobal(sql, bindings, options)` | Execute query on all shards, then globally merge/sort/paginate | `string, any[], GlobalAllShardsOptions` |
|
|
1377
|
+
| `firstAllShardsGlobal(sql, bindings, options)` | Return first row after global merge/sort/paginate | `string, any[], GlobalAllShardsOptions` |
|
|
1378
|
+
| `reassignShard(key, newShard)` | Move primary key to different shard | `string, string` |
|
|
1379
|
+
| `listKnownShards()` | Get list of available shards | `void` |
|
|
1380
|
+
| `getShardStats()` | Get statistics for all shards | `void` |
|
|
1381
|
+
| `getDatabaseSizeForKey(key)` | Get size of key-routed shard in bytes | `string` |
|
|
1382
|
+
| `getDatabaseSizeForShard(shard)` | Get size of a specific shard in bytes | `string` |
|
|
1383
|
+
| `getDatabaseSizesAllShards(batchSize)` | Get per-shard size data | `number` |
|
|
1384
|
+
| `getTotalDatabaseSize(batchSize)` | Get total size across all shards | `number` |
|
|
1385
|
+
| `flush()` | Clear all shard mappings (development only) | `void` |
|
|
1061
1386
|
|
|
1062
1387
|
### Provider Adapter Functions
|
|
1063
1388
|
|
package/dist/index.d.ts
CHANGED
|
@@ -8,12 +8,13 @@
|
|
|
8
8
|
* @author Gregory Mitchell
|
|
9
9
|
* @license MIT
|
|
10
10
|
*/
|
|
11
|
-
export { all, allAllShards, allAllShardsGlobal, allByLookupKey, allShard, collegedb, count, countAllShards, countShard, createSchema, explain, explainAllShards, explainShard, first, firstAllShards, firstAllShardsGlobal, firstByLookupKey, firstShard, flush, getClosestRegionFromIP, getDatabaseSizeForKey, getDatabaseSizeForShard, getDatabaseSizesAllShards, getShardStats, getTotalDatabaseSize, index, indexAllShards, indexShard, initialize, initializeAsync, listKnownShards, prepare, reassignShard, resetConfig, run, runAllShards, runShard } from './router';
|
|
12
|
-
export type { CreateIndexOptions, ExplainOptions, GlobalAllShardsOptions, IndexColumnDefinition, ShardSizeResult, ShardTableCount } from './router';
|
|
11
|
+
export { all, allAllShards, allAllShardsGlobal, allByLookupKey, allShard, collegedb, count, countAllShards, countShard, createSchema, explain, explainAllShards, explainShard, first, firstAllShards, firstAllShardsGlobal, firstByLookupKey, firstShard, flush, getClosestRegionFromIP, getDatabaseSizeForKey, getDatabaseSizeForShard, getDatabaseSizesAllShards, getShardStats, getTotalDatabaseSize, index, indexAllShards, indexShard, initialize, initializeAsync, insert, insertShard, listKnownShards, prepare, reassignShard, resetConfig, run, runAllShards, runShard } from './router';
|
|
12
|
+
export type { CreateIndexOptions, ExplainOptions, GlobalAllShardsOptions, IndexColumnDefinition, InsertResult, ShardSizeResult, ShardTableCount } from './router';
|
|
13
13
|
export { ShardCoordinator } from './durable';
|
|
14
14
|
export { CollegeDBError } from './errors';
|
|
15
15
|
export { KVShardMapper } from './kvmap';
|
|
16
16
|
export { createDrizzleSQLProvider, createHyperdriveMySQLProvider, createHyperdrivePostgresProvider, createMySQLProvider, createNuxtHubKVProvider, createPostgreSQLProvider, createRedisKVProvider, createSQLiteProvider, createValkeyKVProvider, isKVStorage, isSQLDatabase, type DrizzleClientLike, type DrizzleSqlChunkLike, type DrizzleSqlTagLike, type HyperdriveBindingLike, type HyperdriveMySQLClientFactory, type HyperdrivePostgresClientFactory, type MySQLClientLike, type NuxtHubKVLike, type PostgresClientLike, type RedisLikeClient, type SQLiteClientLike } from './providers';
|
|
17
|
+
export { InMemoryKVStorage, InMemorySQLDatabase, createInMemoryKVProvider, createInMemorySQLProvider } from './providers-memory';
|
|
17
18
|
export { autoDetectAndMigrate, checkMigrationNeeded, clearMigrationCache, clearShardMigrationCache, createMappingsForExistingKeys, createSchemaAcrossShards, discoverExistingPrimaryKeys, discoverExistingRecordsWithColumns, dropSchema, integrateExistingDatabase, listTables, migrateRecord, schemaExists, validateTableForSharding, type IntegrationOptions, type IntegrationResult, type ValidationResult } from './migrations';
|
|
18
19
|
export type { CollegeDBConfig, D1Region, Env, KVListResult, KVStorage, MixedShardingStrategy, OperationType, PreparedStatement, QueryResult, QueryResultMeta, SQLDatabase, ShardCoordinatorState, ShardLocation, ShardMapping, ShardStats, ShardingStrategy } from './types';
|
|
19
20
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EACN,GAAG,EACH,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,QAAQ,EACR,SAAS,EACT,KAAK,EACL,cAAc,EACd,UAAU,EACV,YAAY,EACZ,OAAO,EACP,gBAAgB,EAChB,YAAY,EACZ,KAAK,EACL,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,UAAU,EACV,KAAK,EACL,sBAAsB,EACtB,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,EACzB,aAAa,EACb,oBAAoB,EACpB,KAAK,EACL,cAAc,EACd,UAAU,EACV,UAAU,EACV,eAAe,EACf,eAAe,EACf,OAAO,EACP,aAAa,EACb,WAAW,EACX,GAAG,EACH,YAAY,EACZ,QAAQ,EACR,MAAM,UAAU,CAAC;AAElB,YAAY,EACX,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACtB,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGxC,OAAO,EACN,wBAAwB,EACxB,6BAA6B,EAC7B,gCAAgC,EAChC,mBAAmB,EACnB,uBAAuB,EACvB,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,sBAAsB,EACtB,WAAW,EACX,aAAa,EACb,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,4BAA4B,EACjC,KAAK,+BAA+B,EACpC,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACN,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,wBAAwB,EACxB,6BAA6B,EAC7B,wBAAwB,EACxB,2BAA2B,EAC3B,kCAAkC,EAClC,UAAU,EACV,yBAAyB,EACzB,UAAU,EACV,aAAa,EACb,YAAY,EACZ,wBAAwB,EACxB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,MAAM,cAAc,CAAC;AAGtB,YAAY,EACX,eAAe,EACf,QAAQ,EACR,GAAG,EACH,YAAY,EACZ,SAAS,EACT,qBAAqB,EACrB,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,eAAe,EACf,WAAW,EACX,qBAAqB,EACrB,aAAa,EACb,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EACN,GAAG,EACH,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,QAAQ,EACR,SAAS,EACT,KAAK,EACL,cAAc,EACd,UAAU,EACV,YAAY,EACZ,OAAO,EACP,gBAAgB,EAChB,YAAY,EACZ,KAAK,EACL,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,UAAU,EACV,KAAK,EACL,sBAAsB,EACtB,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,EACzB,aAAa,EACb,oBAAoB,EACpB,KAAK,EACL,cAAc,EACd,UAAU,EACV,UAAU,EACV,eAAe,EACf,MAAM,EACN,WAAW,EACX,eAAe,EACf,OAAO,EACP,aAAa,EACb,WAAW,EACX,GAAG,EACH,YAAY,EACZ,QAAQ,EACR,MAAM,UAAU,CAAC;AAElB,YAAY,EACX,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACtB,qBAAqB,EACrB,YAAY,EACZ,eAAe,EACf,eAAe,EACf,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGxC,OAAO,EACN,wBAAwB,EACxB,6BAA6B,EAC7B,gCAAgC,EAChC,mBAAmB,EACnB,uBAAuB,EACvB,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,sBAAsB,EACtB,WAAW,EACX,aAAa,EACb,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,4BAA4B,EACjC,KAAK,+BAA+B,EACpC,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAGjI,OAAO,EACN,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,wBAAwB,EACxB,6BAA6B,EAC7B,wBAAwB,EACxB,2BAA2B,EAC3B,kCAAkC,EAClC,UAAU,EACV,yBAAyB,EACzB,UAAU,EACV,aAAa,EACb,YAAY,EACZ,wBAAwB,EACxB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,MAAM,cAAc,CAAC;AAGtB,YAAY,EACX,eAAe,EACf,QAAQ,EACR,GAAG,EACH,YAAY,EACZ,SAAS,EACT,qBAAqB,EACrB,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,eAAe,EACf,WAAW,EACX,qBAAqB,EACrB,aAAa,EACb,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,MAAM,SAAS,CAAC"}
|