forked from mongodb/docs-sample-apps
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdatabase.ts
More file actions
121 lines (100 loc) · 3.38 KB
/
database.ts
File metadata and controls
121 lines (100 loc) · 3.38 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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/**
* Database Configuration and Connection Management
*
* This module handles MongoDB connection setup using the Node.js driver
* and implements pre-flight checks to ensure the application has all
* necessary indexes and sample data.
*/
import { MongoClient, Db, Collection, Document } from 'mongodb';
let client: MongoClient;
let database: Db;
async function _connectToDatabase(): Promise<Db> {
// Return existing connection if already established
// This prevents creating multiple connections unnecessarily
if (database) {
return database;
}
// Retrieve MongoDB connection string from environment variables
const uri = process.env.MONGODB_URI;
if (!uri) {
throw new Error(
'MONGODB_URI environment variable is not defined. Please check your .env file and ensure it contains a valid MongoDB connection string.'
);
}
try {
// Create new MongoDB client instance
client = new MongoClient(uri);
// Connect to MongoDB
await client.connect();
// Get reference to the sample_mflix database
database = client.db('sample_mflix');
console.log(`Connected to database: ${database.databaseName}`);
return database;
} catch (error) {
throw error;
}
}
let connect$: Promise<Db>;
/**
* Establishes connection to MongoDB by using the connection string from environment variables
*
* @returns Promise<Db> - The connected database instance
* @throws Error if connection fails or if MONGODB_URI is not provided
*/
export async function connectToDatabase(): Promise<Db> {
// connect$ only gets assigned exactly once on the first request, ensuring all subsequent requests use the same connect$ promise.
connect$ ??= _connectToDatabase();
return await connect$;
}
/**
* Gets a reference to a specific collection in the database
*
* @param collectionName - Name of the collection to access
* @returns Collection instance
* @throws Error if database is not connected
*/
export function getCollection<T extends Document>(collectionName: string): Collection<T> {
if (!database) {
throw new Error(
'Database not connected.'
);
}
return database.collection(collectionName);
}
/**
* Closes the database connection
* This should be called when the application is shutting down
*/
export async function closeDatabaseConnection(): Promise<void> {
if (client) {
await client.close();
console.log('Database connection closed');
}
}
/**
* Verifies that all required indexes exist and sample data is present
*
* If any requirements are missing, this function will attempt to create them.
*/
export async function verifyRequirements(): Promise<void> {
try {
const db = await connectToDatabase();
// Check if the movies collection exists and has data
await verifyMoviesCollection(db);
console.log('All database requirements verified successfully');
} catch (error) {
console.error('Requirements verification failed:', error);
throw error;
}
}
/**
* Verifies the movies collection and creates necessary indexes
*/
async function verifyMoviesCollection(db: Db): Promise<void> {
const moviesCollection = db.collection('movies');
// Check if collection has documents
const movieCount = await moviesCollection.estimatedDocumentCount();
if (movieCount === 0) {
console.warn('Movies collection is empty. Please ensure sample_mflix data is loaded.');
}
}