File size: 3,026 Bytes
1d4dc07
 
 
 
f0b765c
838cd23
 
 
1d4dc07
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
04aa1ba
 
 
 
 
 
 
 
 
1d4dc07
 
 
 
 
04aa1ba
 
1d4dc07
 
 
 
04aa1ba
 
1d4dc07
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""
Database connection and operations for analytics.
"""

import os
import ssl
import logging
from motor.motor_asyncio import AsyncIOMotorClient
from typing import Optional

logger = logging.getLogger(__name__)

# Global database connection
_client: Optional[AsyncIOMotorClient] = None
_database = None

async def get_database():
    """Get or create MongoDB database connection"""
    global _client, _database
    
    if _database is None:
        await connect_to_database()
    
    return _database

async def connect_to_database():
    """Connect to MongoDB database"""
    global _client, _database
    
    try:
        # Get MongoDB connection string from environment
        mongodb_url = os.getenv("MONGODB_URL")
        
        if not mongodb_url:
            # For learning project, use JSON file fallback if no MongoDB
            logger.warning("MONGODB_URL not set. Analytics will use JSON file storage.")
            return None
            
        # Create motor client with SSL configuration
        _client = AsyncIOMotorClient(
            mongodb_url,
            tls=True,
            tlsInsecure=True,
            serverSelectionTimeoutMS=5000,
            connectTimeoutMS=20000,
            socketTimeoutMS=20000
        )
        
        # Get database (atlas_analytics by default)
        database_name = os.getenv("MONGODB_DATABASE", "atlas_analytics")
        _database = _client[database_name]
        
        # Test the connection immediately
        await _database.command("ping")
        logger.info(f"Connected to MongoDB database: {database_name}")
        return _database
        
    except Exception as e:
        logger.warning(f"MongoDB connection failed : {e}")
        logger.info("Falling back to JSON file storage for analytics")
        _client = None
        _database = None
        return None

async def test_connection() -> bool:
    """Test database connection"""
    try:
        db = await get_database()
        if db is None:
            return False
            
        # Simple ping test
        await db.command("ping")
        logger.info("MongoDB connection test successful")
        return True
        
    except Exception as e:
        logger.error(f"MongoDB connection test failed: {e}")
        return False

async def close_connection():
    """Close database connection"""
    global _client, _database
    
    if _client:
        _client.close()
        _client = None
        _database = None
        logger.info("MongoDB connection closed")

# Collection helpers
async def get_sessions_collection():
    """Get sessions collection"""
    db = await get_database()
    return db.sessions if db is not None else None

async def get_messages_collection():
    """Get messages collection"""
    db = await get_database()
    return db.messages if db is not None else None

async def get_search_analytics_collection():
    """Get search analytics collection"""
    db = await get_database()
    return db.search_analytics if db is not None else None