-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathdatabase.ts
More file actions
91 lines (79 loc) · 2.98 KB
/
Copy pathdatabase.ts
File metadata and controls
91 lines (79 loc) · 2.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/**
* Core Database Service
* Provides database connection, core utilities, and base operations∂ƒ
*/
import { drizzle } from 'drizzle-orm/d1';
import * as Sentry from '@sentry/cloudflare';
import * as schema from './schema';
import type { DrizzleD1Database } from 'drizzle-orm/d1';
import type { HealthStatusResult } from './types';
// ========================================
// TYPE DEFINITIONS AND INTERFACES
// ========================================
export type {
User, NewUser, Session, NewSession,
App, NewApp,
AppLike, NewAppLike, AppComment, NewAppComment,
AppView, NewAppView, OAuthState, NewOAuthState,
SystemSetting, NewSystemSetting,
UserModelConfig, NewUserModelConfig,
} from './schema';
/**
* Core Database Service - Connection and Base Operations
*
* Provides database connection, shared utilities, and core operations.
* Domain-specific operations are handled by dedicated service classes.
*/
export class DatabaseService {
public readonly db: DrizzleD1Database<typeof schema>;
private readonly d1: D1Database;
private readonly enableReplicas: boolean;
constructor(env: Env) {
const instrumented = Sentry.instrumentD1WithSentry(env.DB);
this.d1 = instrumented;
this.db = drizzle(instrumented, { schema });
this.enableReplicas = env.ENABLE_READ_REPLICAS === 'true';
}
/**
* Get a read-optimized database connection using D1 Sessions API
* This routes queries to read replicas for lower global latency
*
* @param strategy - Session strategy:
* - 'fast' (default): Routes to any replica for lowest latency
* - 'fresh': Routes first query to primary for latest data
* @returns Drizzle database instance configured for read operations
*/
public getReadDb(strategy: 'fast' | 'fresh' = 'fast'): DrizzleD1Database<typeof schema> {
// Return regular db if replicas are disabled
if (!this.enableReplicas) {
return this.db;
}
const sessionType = strategy === 'fresh' ? 'first-primary' : 'first-unconstrained';
const session = this.d1.withSession(sessionType);
// D1DatabaseSession is compatible with D1Database for Drizzle operations
return drizzle(session as unknown as D1Database, { schema });
}
// ========================================
// UTILITY METHODS
// ========================================
async getHealthStatus(): Promise<HealthStatusResult> {
try {
await this.db.select().from(schema.systemSettings).limit(1);
return {
healthy: true,
timestamp: new Date().toISOString(),
};
} catch (error) {
return {
healthy: false,
timestamp: new Date().toISOString(),
};
}
}
}
/**
* Factory function to create database service instance
*/
export function createDatabaseService(env: Env): DatabaseService {
return new DatabaseService(env);
}