123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- import { Meteor } from 'meteor/meteor';
- import { DDP } from 'meteor/ddp';
- import { mongodbConnectionManager } from './mongodbConnectionManager';
- import { mongodbDriverManager } from './mongodbDriverManager';
- /**
- * Meteor MongoDB Integration
- *
- * This module integrates the MongoDB driver manager with Meteor's
- * built-in MongoDB connection system to provide automatic driver
- * selection and version detection.
- *
- * Features:
- * - Hooks into Meteor's MongoDB connection process
- * - Automatic driver selection based on detected version
- * - Fallback mechanism for connection failures
- * - Integration with Meteor's DDP and reactive systems
- */
- class MeteorMongoIntegration {
- constructor() {
- this.originalMongoConnect = null;
- this.originalMongoCollection = null;
- this.isInitialized = false;
- this.connectionString = null;
- this.customConnection = null;
- }
- /**
- * Initialize the integration
- * @param {string} connectionString - MongoDB connection string
- */
- initialize(connectionString) {
- if (this.isInitialized) {
- console.log('Meteor MongoDB Integration already initialized');
- return;
- }
- this.connectionString = connectionString;
- console.log('Initializing Meteor MongoDB Integration...');
- // Store original methods
- this.originalMongoConnect = Meteor.connect;
- this.originalMongoCollection = Mongo.Collection;
- // Override Meteor's connection method
- this.overrideMeteorConnection();
- // Override Mongo.Collection to use our connection manager
- this.overrideMongoCollection();
- this.isInitialized = true;
- // Meteor MongoDB Integration initialized successfully (status available in Admin Panel)
- }
- /**
- * Override Meteor's connection method
- */
- overrideMeteorConnection() {
- const self = this;
-
- // Override Meteor.connect if it exists
- if (typeof Meteor.connect === 'function') {
- Meteor.connect = async function(url, options) {
- try {
- console.log('Meteor.connect called, using custom MongoDB connection manager');
- return await self.createCustomConnection(url, options);
- } catch (error) {
- console.error('Custom connection failed, falling back to original method:', error.message);
- return self.originalMongoConnect.call(this, url, options);
- }
- };
- }
- }
- /**
- * Override Mongo.Collection to use our connection manager
- */
- overrideMongoCollection() {
- const self = this;
- const originalCollection = Mongo.Collection;
- // Override Mongo.Collection constructor
- Mongo.Collection = function(name, options = {}) {
- // If we have a custom connection, use it
- if (self.customConnection) {
- options.connection = self.customConnection;
- }
- // Create the collection with original constructor
- const collection = new originalCollection(name, options);
- // Add our custom methods
- self.enhanceCollection(collection);
- return collection;
- };
- // Copy static methods from original constructor
- Object.setPrototypeOf(Mongo.Collection, originalCollection);
- Object.assign(Mongo.Collection, originalCollection);
- }
- /**
- * Create a custom MongoDB connection
- * @param {string} url - MongoDB connection URL
- * @param {Object} options - Connection options
- * @returns {Promise<Object>} - MongoDB connection object
- */
- async createCustomConnection(url, options = {}) {
- try {
- console.log('Creating custom MongoDB connection...');
-
- // Use our connection manager
- const connection = await mongodbConnectionManager.createConnection(url, options);
-
- // Store the custom connection
- this.customConnection = connection;
-
- // Create a Meteor-compatible connection object
- const meteorConnection = this.createMeteorCompatibleConnection(connection);
-
- console.log('Custom MongoDB connection created successfully');
- return meteorConnection;
- } catch (error) {
- console.error('Failed to create custom MongoDB connection:', error.message);
- throw error;
- }
- }
- /**
- * Create a Meteor-compatible connection object
- * @param {Object} connection - MongoDB connection object
- * @returns {Object} - Meteor-compatible connection
- */
- createMeteorCompatibleConnection(connection) {
- const self = this;
- return {
- // Basic connection properties
- _driver: connection,
- _name: 'custom-mongodb-connection',
-
- // Collection creation method
- createCollection: function(name, options = {}) {
- const db = connection.db();
- return db.collection(name);
- },
- // Database access
- db: function(name = 'meteor') {
- return connection.db(name);
- },
- // Connection status
- status: function() {
- return {
- status: 'connected',
- connected: true,
- retryCount: 0
- };
- },
- // Close connection
- close: async function() {
- try {
- await connection.close();
- self.customConnection = null;
- console.log('Meteor-compatible connection closed');
- } catch (error) {
- console.error('Error closing Meteor-compatible connection:', error.message);
- }
- },
- // Raw connection access
- rawConnection: connection
- };
- }
- /**
- * Enhance a collection with additional methods
- * @param {Object} collection - Mongo.Collection instance
- */
- enhanceCollection(collection) {
- const self = this;
- // Add connection info method
- collection.getConnectionInfo = function() {
- if (self.customConnection) {
- const stats = mongodbConnectionManager.getConnectionStats();
- const driverStats = mongodbDriverManager.getConnectionStats();
- return {
- connectionType: 'custom',
- driver: driverStats.currentDriver,
- version: driverStats.detectedVersion,
- connectionStats: stats,
- driverStats: driverStats
- };
- }
- return {
- connectionType: 'default',
- driver: 'meteor-default',
- version: 'unknown'
- };
- };
- // Add version detection method
- collection.detectMongoDBVersion = async function() {
- try {
- if (self.customConnection) {
- const admin = self.customConnection.db().admin();
- const buildInfo = await admin.buildInfo();
- return buildInfo.version;
- }
- return null;
- } catch (error) {
- console.error('Error detecting MongoDB version:', error.message);
- return null;
- }
- };
- }
- /**
- * Get connection statistics
- * @returns {Object} - Connection statistics
- */
- getStats() {
- return {
- isInitialized: this.isInitialized,
- hasCustomConnection: !!this.customConnection,
- connectionString: this.connectionString,
- connectionStats: mongodbConnectionManager.getConnectionStats(),
- driverStats: mongodbDriverManager.getConnectionStats()
- };
- }
- /**
- * Reset the integration
- */
- reset() {
- if (this.originalMongoConnect) {
- Meteor.connect = this.originalMongoConnect;
- }
-
- if (this.originalMongoCollection) {
- Mongo.Collection = this.originalMongoCollection;
- }
- this.isInitialized = false;
- this.connectionString = null;
- this.customConnection = null;
- mongodbConnectionManager.reset();
- mongodbDriverManager.reset();
- console.log('Meteor MongoDB Integration reset');
- }
- /**
- * Test the connection
- * @returns {Promise<Object>} - Test results
- */
- async testConnection() {
- try {
- if (!this.customConnection) {
- throw new Error('No custom connection available');
- }
- const db = this.customConnection.db();
- const result = await db.admin().ping();
-
- return {
- success: true,
- result,
- driver: mongodbDriverManager.selectedDriver,
- version: mongodbDriverManager.detectedVersion
- };
- } catch (error) {
- return {
- success: false,
- error: error.message,
- driver: mongodbDriverManager.selectedDriver,
- version: mongodbDriverManager.detectedVersion
- };
- }
- }
- }
- // Create singleton instance
- const meteorMongoIntegration = new MeteorMongoIntegration();
- // Export for use in other modules
- export { meteorMongoIntegration, MeteorMongoIntegration };
- // Auto-initialize if MONGO_URL is available
- if (Meteor.isServer && process.env.MONGO_URL) {
- // Auto-initializing Meteor MongoDB Integration with MONGO_URL (status available in Admin Panel)
- meteorMongoIntegration.initialize(process.env.MONGO_URL);
- }
- // Meteor MongoDB Integration module loaded (status available in Admin Panel)
|