a
    bgP*                     @   sF   d dl mZ d dlmZmZmZmZ d dlmZm	Z	 G dd dZ
dS )    )md5)AnyDictListTuple)GraphDocumentRelationshipc                   @   s   e Zd ZdZdeeeddddZeedd	d
Z	i fee
eeeef  dddZddddZddddZeddddZeddddZdee eeeeef  eddddZdS )	KuzuGraphu  Kùzu wrapper for graph operations.

    *Security note*: Make sure that the database connection uses credentials
        that are narrowly-scoped to only include necessary permissions.
        Failure to do so may result in data corruption or loss, since the calling
        code may attempt commands that would result in deletion, mutation
        of data if appropriately prompted or reading sensitive data if such
        data is present in the database.
        The best way to guard against such negative outcomes is to (as appropriate)
        limit the permissions granted to the credentials used with this tool.

        See https://python.langchain.com/docs/security for more information.
    kuzuFN)dbdatabaseallow_dangerous_requestsreturnc                 C   s^   |durt dzddl}W n ty6   tdY n0 || _|| j| _|| _|   dS )u0   Initializes the Kùzu graph database connection.TzThe KuzuGraph class is a powerful tool that can be used to execute arbitrary queries on the database. To enable this functionality, set the `allow_dangerous_requests` parameter to `True` when constructing the KuzuGraph object.r   NuS   Could not import Kùzu python package.Please install Kùzu with `pip install kuzu`.)
ValueErrorr
   ImportErrorr   
Connectionconnr   refresh_schema)selfr   r   r   r
    r   s/var/www/html/cobodadashboardai.evdpl.com/venv/lib/python3.9/site-packages/langchain_community/graphs/kuzu_graph.py__init__   s    
zKuzuGraph.__init__)r   c                 C   s   | j S )u(   Returns the schema of the Kùzu database)schemar   r   r   r   
get_schema/   s    zKuzuGraph.get_schema)queryparamsr   c                 C   sD   | j ||}| }g }| r@| }|tt|| q|S )u   Query Kùzu database)r   executeZget_column_nameshas_nextget_nextappenddictzip)r   r   r   resultZcolumn_namesZreturn_listrowr   r   r   r   4   s    zKuzuGraph.queryc              
   C   s  g }| j  }|D ]}g |d}| j |}|D ]}|| d }d}|| d dkrd|| v r|| d D ]}	|d|	 d7 }qlnt|| d D ]}
|d	7 }q||7 }|d
 ||f q0|| qg }| j  }|D ].}|d|d  d|d  d|d  d qg }|D ]n}|d }g |d}| j d| d}| rv| }|d }|d }|d
 ||f q>|| qd| d| d| d| _	dS )u,   Refreshes the Kùzu graph schema information)
propertieslabeltype 	dimensionr   shape[]z[]r%   z(:srcz)-[:namez]->(:dst)zCALL table_info('z') RETURN *;      zNode properties: z
Relationships properties: z
Relationships: 
N)
r   Z_get_node_table_namesZ_get_node_property_namesranger    Z_get_rel_table_namesr   r   r   r   )r   Znode_propertiesZnode_table_namesZ
table_nameZcurrent_table_schemar%   Zproperty_nameZproperty_typeZlist_type_flagsirelationshipsZ
rel_tablestableZrel_propertiesZquery_resultr$   Z	prop_nameZ	prop_typer   r   r   r   >   sX    



"


zKuzuGraph.refresh_schemac                 C   s   | j d d S )Nz
            CREATE NODE TABLE IF NOT EXISTS Chunk (
                id STRING,
                text STRING,
                type STRING,
                PRIMARY KEY(id)
            );
            r   r   r   r   r   r   _create_chunk_node_tablep   s    z"KuzuGraph._create_chunk_node_table)
node_labelr   c                 C   s   | j d| d d S )Nz-
            CREATE NODE TABLE IF NOT EXISTS zv (
                id STRING,
                type STRING,
                PRIMARY KEY(id)
            );
            r9   )r   r;   r   r   r   _create_entity_node_table|   s
    z#KuzuGraph._create_entity_node_table)relr   c              	   C   s.   | j d|j d|jj d|jj d d S )Nz,
            CREATE REL TABLE IF NOT EXISTS z (
                FROM z TO z
            );
            )r   r   r'   sourcetarget)r   r=   r   r   r   !_create_entity_relationship_table   s    z+KuzuGraph._create_entity_relationship_table)graph_documentsallowed_relationshipsinclude_sourcer   c              
   C   s  t dd |D }|D ]}|rv|   |jjdsTt|jjd |jjd< | j	j
d|jjd |jjdd |D ]}| | qz|jD ]}| j	j
d|j d	d|jid |r|   d
}g }	|D ]}|	d|  qt t|	}	|d|	7 }|d7 }|r| j	
| |j|v r| j	j
d|j d|jjd |jdd q|jD ]\}
| |
 |
jj}|
jj}|
jj}|
jj}| j	j
d| d| d|
j d||dd qRqdS )u/  
        Adds a list of `GraphDocument` objects that represent nodes and relationships
        in a graph to a Kùzu backend.

        Parameters:
          - graph_documents (List[GraphDocument]): A list of `GraphDocument` objects
            that contain the nodes and relationships to be added to the graph. Each
            `GraphDocument` should encapsulate the structure of part of the graph,
            including nodes, relationships, and the source document information.

          - allowed_relationships (List[Tuple[str, str, str]]): A list of allowed
            relationships that exist in the graph. Each tuple contains three elements:
            the source node type, the relationship type, and the target node type.
            Required for Kùzu, as the names of the relationship tables that need to
            pre-exist are derived from these tuples.

          - include_source (bool): If True, stores the source document
            and links it to nodes in the graph using the `MENTIONS` relationship.
            This is useful for tracing back the origin of data. Merges source
            documents based on the `id` property from the source document metadata
            if available; otherwise it calculates the MD5 hash of `page_content`
            for merging process. Defaults to False.
        c                 S   s   h | ]}|j D ]
}|jqqS r   )nodesr'   ).0documentnoder   r   r   	<setcomp>       z0KuzuGraph.add_graph_documents.<locals>.<setcomp>idzutf-8z
                    MERGE (c:Chunk {id: $id}) 
                        SET c.text = $text,
                            c.type = "text_chunk"
                    )rJ   text)
parametersz
                    MERGE (e:zN {id: $id})
                        SET e.type = "entity"
                    z/CREATE REL TABLE GROUP IF NOT EXISTS MENTIONS (zFROM Chunk TO z, z), label STRING, triplet_source_id STRING)z]
                            MATCH (c:Chunk {id: $id}),
                                  (e:z {id: $node_id})
                            MERGE (c)-[m:MENTIONS]->(e)
                          SET m.triplet_source_id = $id
                            )rJ   Znode_idz
                    MATCH (e1:z4 {id: $source_id}),
                            (e2:z4 {id: $target_id})
                    MERGE (e1)-[:z]->(e2)
                    )	source_id	target_idN)listr:   r>   metadatagetr   Zpage_contentencode	hexdigestr   r   r<   rD   r'   rJ   r    setjoinr7   r@   r?   )r   rA   rB   rC   Znode_labelsrF   r;   rG   ZddlZtable_namesr=   Zsource_labelrM   Ztarget_labelrN   r   r   r   add_graph_documents   s~    






zKuzuGraph.add_graph_documents)r
   F)F)__name__
__module____qualname____doc__r   strboolr   propertyr   r!   r   r   r   r   r:   r<   r   r@   r   r   rV   r   r   r   r   r	      s(    "
2 r	   N)hashlibr   typingr   r   r   r   Z)langchain_community.graphs.graph_documentr   r   r	   r   r   r   r   <module>   s   