
    ג[i,                     p    d Z ddlZddlmZmZmZmZ ddlmZ ddl	m
Z
 ddlmZ ddlZ G d d          ZdS )	a  
MongoDB Service Layer

This module provides all MongoDB database access for the IGF Admin application.
All database operations must go through this service to maintain separation of concerns.

Key principles:
- Single source of truth: MongoDB database
- No hardcoded collection names or database names
- All configuration comes from app_config.yaml
- Read/write operations are explicit and controlled
    N)ListDictAnyOptional)MongoClient)Database)
Collectionc                      e Zd ZdZddefdZdedeeef         fdZde	fdZ
de	fdZdee         fd	Zdefd
Zdee         fdZdedee         fdZdedefdZ	 	 d dedededeeeef                  fdZdedeeef         fdZdee         fdZdedee         fdZ	 d!dededee         deeeef                  fdZdedeeef         fdZdededee         fdZd ZdS )"MongoServicez
    MongoDB service for managing database connections and operations.
    
    This service loads configuration from app_config.yaml and provides
    safe, controlled access to MongoDB collections.
    config/app_config.yamlconfig_pathc                 d    |                      |          | _        d| _        d| _        d| _        dS )z
        Initialize MongoDB service with configuration.
        
        Args:
            config_path: Path to YAML configuration file
        N)_load_configconfigclientdb_connection_error)selfr   s     */var/www/html/IGF-ODF-V3/services/mongo.py__init__zMongoService.__init__   s5     ''44-1&*04    returnc                 ,   t          |d          5 }t          j        |          }ddd           n# 1 swxY w Y   |                    di                               dd          }t	          j        |          }|r||d         d<   nd|d         d<   |S )z
        Load configuration from YAML file.
        
        Args:
            config_path: Path to configuration file
            
        Returns:
            Configuration dictionary
        rNmongodburi_env	MONGO_URIurizpmongodb://AdminUser:WnE0TjGIafVJutreZL7cTIoWNWU52YyxLVgwCUqIGCGg3YUT@18.184.249.241:27017/?authMechanism=DEFAULT)openyaml	safe_loadgetosgetenv)r   r   fr   r   env_uris         r   r   zMongoService._load_config*   s     +s## 	'q^A&&F	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' **Y++//	;GG)G$$ 	Z'.F9e$$ (ZF9e$s   266c                    	 | j         d         d         }| j         d         d         }| j         d                             dd          }| j         d                             dd          }t          |||          | _        | j        j                            d           | j        |         | _        d	| _        d
S # t          $ r}t          |          | _        Y d	}~dS d	}~ww xY w)z
        Establish connection to MongoDB.
        
        Returns:
            True if connection successful, False otherwise
        r   r   databaseconnection_timeouti  server_selection_timeout)serverSelectionTimeoutMSconnectTimeoutMSpingNTF)
r   r"   r   r   admincommandr   r   	Exceptionstr)r   	mongo_uridatabase_namer)   r*   es         r   connectzMongoService.connectC   s    	I.u5I K	2:>M!%Y!7!;!;<PRV!W!W'+{9'='A'AB\^b'c'c$ &)A!3  DK K%%f--- k-0DG%)D"4 	 	 	%(VVD"55555	s   B7B; ;
C$CC$c                 v    | j         | j        dS 	 | j         j                            d           dS #  Y dS xY w)z
        Check if MongoDB connection is active.
        
        Returns:
            True if connected, False otherwise
        NFr-   T)r   r   r.   r/   r   s    r   is_connectedzMongoService.is_connectedd   sO     ; 	$' 	5	K%%f---4	55s   3 8c                     | j         S )z
        Get the last connection error message.
        
        Returns:
            Error message or None if no error
        )r   r7   s    r   get_connection_errorz!MongoService.get_connection_errort   s     %%r   c                 (    | j         d         d         S )zz
        Get the configured database name.
        
        Returns:
            Database name from configuration
        r   r(   )r   r7   s    r   get_database_namezMongoService.get_database_name}   s     {9%j11r   c                 t    | j                             di           }d |                                D             S )z
        Get list of enabled collections from configuration.
        
        Returns:
            List of collection names that are enabled
        collectionsc                 D    g | ]\  }}|                     d d          |S )enabledT)r"   ).0namer   s      r   
<listcomp>z1MongoService.list_collections.<locals>.<listcomp>   s1    cccvvzzR[]aGbGbccccr   )r   r"   items)r   collections_configs     r   list_collectionszMongoService.list_collections   s;     "[__]B??cc);)A)A)C)Cccccr   rB   c                 .    | j         dS | j         |         S )z
        Get a MongoDB collection by name.
        
        Args:
            name: Collection name
            
        Returns:
            Collection object or None if not connected
        N)r   )r   rB   s     r   get_collectionzMongoService.get_collection   s     7 	4wt}r   collection_namec                     	 |                      |          }|dS |                    i           S # t          $ r Y dS w xY w)z
        Count total documents in a collection.
        
        Args:
            collection_name: Name of the collection
            
        Returns:
            Number of documents, or 0 if error
        Nr   )rH   count_documentsr0   )r   rI   
collections      r   rK   zMongoService.count_documents   s]    	,,_==J q--b111 	 	 	11	s   0 0 
>>2   r   limitskipc                 *   	 |                      |          }|g S |                    i                               |                              |          }t	          |          }|S # t
          $ r!}t          d| d|            g cY d}~S d}~ww xY w)a<  
        Retrieve sample documents from a collection.
        
        Args:
            collection_name: Name of the collection
            limit: Maximum number of documents to return
            skip: Number of documents to skip
            
        Returns:
            List of documents as dictionaries
        NzError sampling documents from : )rH   findrO   rN   listr0   print)r   rI   rN   rO   rL   cursor	documentsr4   s           r   sample_documentszMongoService.sample_documents   s    "	,,_==J 	  __R((--d3399%@@FVI 	 	 	I?IIaIIJJJIIIIII	s#   A' AA' '
B1BBBc                    	 |                      |          }|i S | j                            d|          }|                    dd          |                    dd          |                    dd          |                    dd          |                    dd          d	S # t          $ r |                     |          ddddd	cY S w xY w)
z
        Get statistics for a collection.
        
        Args:
            collection_name: Name of the collection
            
        Returns:
            Dictionary with collection statistics
        N	collStatscountr   size
avgObjSizestorageSizenindexes)rZ   r[   r\   r]   indexes)rH   r   r/   r"   r0   rK   )r   rI   rL   statss       r   get_collection_statsz!MongoService.get_collection_stats   s    	,,_==J 	GOOKAAE 7A..		&!,,#iia88$yy:: 99Z33    	 	 	--o>>     	s   B" BB" "%C
	C
c                     	 |                                  sg S | j                                        }d |D             S # t          $ r}t	          d|            g cY d}~S d}~ww xY w)zx
        List all databases on the MongoDB server.
        
        Returns:
            List of database names
        c                     g | ]}|d v|	S ))r.   localr    )rA   r   s     r   rC   z3MongoService.list_all_databases.<locals>.<listcomp>  s#    SSS2B6R,RSBSSSr   zError listing databases: N)r8   r   list_database_namesr0   rT   )r   db_listr4   s      r   list_all_databaseszMongoService.list_all_databases   s    	$$&& 	 k5577G TSSSSS 	 	 	1a11222IIIIII	s   = $= 
A%A A% A%r3   c                     	 |                                  sg S | j        |         }|                                S # t          $ r!}t	          d| d|            g cY d}~S d}~ww xY w)z
        List all collections in a specific database.
        
        Args:
            database_name: Name of the database
            
        Returns:
            List of collection names
        zError listing collections in rQ   N)r8   r   list_collection_namesr0   rT   )r   r3   r   r4   s       r   list_collections_in_databasez)MongoService.list_collections_in_database  s    		$$&& 	]+B++--- 	 	 	F-FF1FFGGGIIIIII	s   9  9 
A$AA$A$Nc           	      Z   	 |                                  sg S | j        |         }||         }|r)|                    i                               |          }n|                    i           }t	          |          S # t
          $ r$}t          d| d| d|            g cY d}~S d}~ww xY w)a)  
        Export all documents from a collection.
        
        Args:
            database_name: Name of the database
            collection_name: Name of the collection
            limit: Optional limit on number of documents
            
        Returns:
            List of documents
        zError exporting .rQ   N)r8   r   rR   rN   rS   r0   rT   )r   r3   rI   rN   r   rL   rU   r4   s           r   export_collection_dataz#MongoService.export_collection_data  s    "	$$&& 	]+BO,J -#,,22599#,,<< 	 	 	K]KK_KKKKLLLIIIIII	s#   A< A#A< <
B*B%B*%B*c                    	 |                                  si S | j        |         }|                    d          }|                    dd          |                    dd          |                    dd          |                    dd          |                    dd          dS # t          $ r!}t          d	| d
|            i cY d}~S d}~ww xY w)z
        Get statistics for a database.
        
        Args:
            database_name: Name of the database
            
        Returns:
            Dictionary with database statistics
        dbStatsr>   r   dataSizer]   r_   objects)r>   rq   r]   r_   rr   zError getting stats for rQ   N)r8   r   r/   r"   r0   rT   )r   r3   r   r`   r4   s        r   get_database_statszMongoService.get_database_stats@  s    	$$&& 	]+BJJy))E  %yy::!IIj!44$yy:: 99Y22 99Y22    	 	 	A]AAaAABBBIIIIII	s#   B& BB& &
C0CCC
field_namec           	          	 | j         |         }|                    |          S # t          $ r$}t          d| d| d|            g cY d}~S d}~ww xY w)z
        Get distinct values for a field in a collection.
        
        Args:
            collection_name: Name of the collection
            field_name: Name of the field
        
        Returns:
            List of distinct values
        z#Error getting distinct values from rm   rQ   N)r   distinctr0   rT   )r   rI   rt   rL   r4   s        r   get_distinct_valuesz MongoService.get_distinct_values]  s}    	1J&&z222 	 	 	[[[*[[XY[[\\\IIIIII	s   !$ 
AAAAc                 f    | j         )| j                                          d| _         d| _        dS dS )z+
        Close MongoDB connection.
        N)r   closer   r7   s    r   ry   zMongoService.closeo  s>     ; 	KDKDGGG	 	r   )r   )rM   r   )N)__name__
__module____qualname____doc__r1   r   r   r   r   boolr5   r8   r   r:   r<   r   rF   r	   rH   intrK   rW   ra   rh   rk   rn   rs   rw   ry   re   r   r   r   r      s        
5 
5C 
5 
5 
5 
5 S#X    2    Bd     &hsm & & & &23 2 2 2 2d$s) d d d d3 8J+?    s s    * 	   	
 
d38n	   @ C  DcN        DDI    *# $s)    2  $	! !! ! }	!
 
d38n	! ! ! !F S#X    :3 C DQTI    $    r   r   )r}   r#   typingr   r   r   r   pymongor   pymongo.databaser   pymongo.collectionr	   r    r   re   r   r   <module>r      s     
			 , , , , , , , , , , , ,       % % % % % % ) ) ) ) ) ) ` ` ` ` ` ` ` ` ` `r   