a
    bg=                     @  s   d dl mZ d dlZd dlZd dlZd dlZd dlmZmZm	Z	m
Z
mZmZmZ d dlmZ d dlmZ d dlmZ erd dlZeeZddd	d
dZG dd deZdS )    )annotationsN)TYPE_CHECKINGAnyIterableListOptionalTupleType)Document)
Embeddings)VectorStoreList[float]bytes)vectorreturnc                 C  s   t jdt|  g| R  S )zSerializes a list of floats into a compact "raw bytes" format

    Source: https://github.com/asg017/sqlite-vec/blob/21c5a14fc71c83f135f5b00c84115139fd12c492/examples/simple-python/demo.py#L8-L10
    z%sf)structpacklen)r    r   x/var/www/html/cobodadashboardai.evdpl.com/venv/lib/python3.9/site-packages/langchain_community/vectorstores/sqlitevec.pyserialize_f32   s    r   c                   @  s   e Zd ZdZd/dddddddZd	d
ddZd0dddddddZd1dddddddZd2dddddddZd3dddddd d!Z	d4dddddd"d#Z
ed5d%ddddddd d&d'd(Zedd)d*d+d,Zdd
d-d.ZdS )6	SQLiteVecaL  SQLite with Vec extension as a vector database.

    To use, you should have the ``sqlite-vec`` python package installed.
    Example:
        .. code-block:: python
            from langchain_community.vectorstores import SQLiteVec
            from langchain_community.embeddings.openai import OpenAIEmbeddings
            ...
    vec.dbstrzOptional[sqlite3.Connection]r   )table
connection	embeddingdb_filec                 C  sh   zddl }W n ty&   tdY n0 |s6| |}t|tsJtd || _|| _|| _	| 
  dS )z1Initialize with sqlite client with vss extension.r   Nz\Could not import sqlite-vec python package. Please install it with `pip install sqlite-vec`.z+embeddings input must be Embeddings object.)
sqlite_vecImportErrorcreate_connection
isinstancer   warningswarn_connection_table
_embeddingcreate_table_if_not_exists)selfr   r   r   r   r   r   r   r   __init__.   s    



zSQLiteVec.__init__None)r   c                 C  sb   | j d| j d | j d| j d|   d | j d| j d| j d | j   d S )	Nz(
            CREATE TABLE IF NOT EXISTS z
            (
                rowid INTEGER PRIMARY KEY AUTOINCREMENT,
                text TEXT,
                metadata BLOB,
                text_embedding BLOB
            )
            ;
            z0
            CREATE VIRTUAL TABLE IF NOT EXISTS za_vec USING vec0(
                rowid INTEGER PRIMARY KEY,
                text_embedding float[z*]
            )
            ;
            zZ
                CREATE TRIGGER IF NOT EXISTS embed_text 
                AFTER INSERT ON z7
                BEGIN
                    INSERT INTO z_vec(rowid, text_embedding)
                    VALUES (new.rowid, new.text_embedding) 
                    ;
                END;
            )r$   executer%   get_dimensionalitycommit)r(   r   r   r   r'   J   s(    	z$SQLiteVec.create_table_if_not_existsNzIterable[str]zOptional[List[dict]]r   z	List[str])texts	metadataskwargsr   c                 K  s   | j d| j  d }|du r(d}| jt|}|sJdd |D }dd t|||D }| j d| j d	| | j 	  | j d
| j d| }dd |D S )a  Add more texts to the vectorstore index.
        Args:
            texts: Iterable of strings to add to the vectorstore.
            metadatas: Optional list of metadatas associated with the texts.
            kwargs: vectorstore specific parameters
        z SELECT max(rowid) as rowid FROM rowidNr   c                 S  s   g | ]}i qS r   r   ).0_r   r   r   
<listcomp>       z'SQLiteVec.add_texts.<locals>.<listcomp>c                 S  s&   g | ]\}}}|t |t|fqS r   )jsondumpsr   )r2   textmetadataZembedr   r   r   r4      s   zINSERT INTO z/(text, metadata, text_embedding) VALUES (?,?,?)zSELECT rowid FROM z WHERE rowid > c                 S  s   g | ]}|d  qS )r1   r   )r2   rowr   r   r   r4      r5   )
r$   r+   r%   Zfetchoner&   Zembed_documentslistzipZexecutemanyr-   )r(   r.   r/   r0   Zmax_idZembedsZ
data_inputresultsr   r   r   	add_textsm   s,    


zSQLiteVec.add_texts   r   intzList[Tuple[Document, float]])r   kr0   r   c                 K  s   d| j  d| j  d}| j }||t||g | }g }|D ]8}t|d pXi }	t|d |	d}
|	|
|d f qD|S )Nzo
            SELECT 
                text,
                metadata,
                distance
            FROM z AS e
            INNER JOIN z_vec AS v on v.rowid = e.rowid  
            WHERE
                v.text_embedding MATCH ?
                AND k = ?
            ORDER BY distance
        r9   r8   )Zpage_contentr9   Zdistance)
r%   r$   cursorr+   r   Zfetchallr6   loadsr
   append)r(   r   rA   r0   Z	sql_queryrB   r=   	documentsr:   r9   docr   r   r   &similarity_search_with_score_by_vector   s"    

z0SQLiteVec.similarity_search_with_score_by_vectorzList[Document])queryrA   r0   r   c                 K  s(   | j |}| j||d}dd |D S )"Return docs most similar to query.r   rA   c                 S  s   g | ]\}}|qS r   r   r2   rF   r3   r   r   r   r4      r5   z/SQLiteVec.similarity_search.<locals>.<listcomp>r&   embed_queryrG   r(   rH   rA   r0   r   rE   r   r   r   similarity_search   s
    zSQLiteVec.similarity_searchc                 K  s   | j |}| j||d}|S )rI   rJ   rL   rN   r   r   r   similarity_search_with_score   s
    z&SQLiteVec.similarity_search_with_scorec                 K  s   | j ||d}dd |D S )NrJ   c                 S  s   g | ]\}}|qS r   r   rK   r   r   r   r4      r5   z9SQLiteVec.similarity_search_by_vector.<locals>.<listcomp>)rG   )r(   r   rA   r0   rE   r   r   r   similarity_search_by_vector   s    z%SQLiteVec.similarity_search_by_vector	langchainzType[SQLiteVec])clsr.   r   r/   r   r   r0   r   c           	      K  s,   |  |}| ||||d}|j||d |S )z9Return VectorStore initialized from texts and embeddings.)r   r   r   r   )r.   r/   )r    r>   )	rS   r.   r   r/   r   r   r0   r   Zvecr   r   r   
from_texts   s    
zSQLiteVec.from_textszsqlite3.Connection)r   r   c                 C  sD   dd l }dd l}|| }|j|_|d || |d |S )Nr   TF)sqlite3r   connectRowZrow_factoryZenable_load_extensionload)r   rU   r   r   r   r   r   r       s    



zSQLiteVec.create_connectionc                 C  s   d}| j |}t|S )z
        Function that does a dummy embedding to figure out how many dimensions
        this embedding function returns. Needed for the virtual table DDL.
        zThis is a dummy text)r&   rM   r   )r(   Z
dummy_textZdummy_embeddingr   r   r   r,      s    zSQLiteVec.get_dimensionality)r   )N)r?   )r?   )r?   )r?   )NrR   r   )__name__
__module____qualname____doc__r)   r'   r>   rG   rO   rP   rQ   classmethodrT   staticmethodr    r,   r   r   r   r   r   #   s,    & &        r   )
__future__r   r6   loggingr   r"   typingr   r   r   r   r   r   r	   Zlangchain_core.documentsr
   Zlangchain_core.embeddingsr   Zlangchain_core.vectorstoresr   rU   	getLoggerrY   loggerr   r   r   r   r   r   <module>   s   $

