o
    Zh;                     @  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r@d dlZeeZdddZG dd deZdS )    )annotationsN)TYPE_CHECKINGAnyIterableListOptionalTupleType)Document)
Embeddings)VectorStorevectorList[float]returnbytesc                 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   a/var/www/html/lang_env/lib/python3.10/site-packages/langchain_community/vectorstores/sqlitevec.pyserialize_f32   s   r   c                   @  s   e Zd ZdZ	d3d4d
dZd5ddZ	d6d7ddZ	d8d9dd Z	d8d:d#d$Z	d8d;d%d&Z		d8d<d'd(Z
e		)	d=d>d,d-Zed?d/d0Zd@d1d2ZdS )A	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tablestr
connectionOptional[sqlite3.Connection]	embeddingr   db_filec                 C  sd   zddl }W n ty   tdw |s| |}t|ts#t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__r   Nonec              	   C  sj   | j d| j d | j d| j d|   d | j 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*]
            )
            ;
            z.
                CREATE TRIGGER IF NOT EXISTS z-_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_existsNtextsIterable[str]	metadatasOptional[List[dict]]kwargsr   	List[str]c                 K  s   | j d| j  d }|du rd}| jt|}|s%d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>   s    z'SQLiteVec.add_texts.<locals>.<listcomp>c                 S  s&   g | ]\}}}|t |t|fqS r   )jsondumpsr   )r6   textmetadataZembedr   r   r   r8      s    zINSERT INTO z/(text, metadata, text_embedding) VALUES (?,?,?)zSELECT rowid FROM z WHERE rowid > c                 S  s   g | ]}|d  qS )r5   r   )r6   rowr   r   r   r8          )
r%   r,   r&   Zfetchoner'   Zembed_documentslistzipZexecutemanyr.   )r)   r/   r1   r3   Zmax_idZembedsZ
data_inputresultsr   r   r   	add_textsm   s,   


zSQLiteVec.add_texts   r   kintList[Tuple[Document, float]]c                 K  s   d| j  d| j  d}| j }||t||g | }g }|D ]}t|d p,i }	t|d |	d}
|	|
|d f q"|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
        r<   r;   )Zpage_contentr<   Zdistance)
r&   r%   cursorr,   r   Zfetchallr9   loadsr
   append)r)   r   rD   r3   Z	sql_queryrG   rA   	documentsr=   r<   docr   r   r   &similarity_search_with_score_by_vector   s"   

z0SQLiteVec.similarity_search_with_score_by_vectorqueryList[Document]c                 K  s(   | j |}| j||d}dd |D S )"Return docs most similar to query.r   rD   c                 S     g | ]\}}|qS r   r   r6   rK   r7   r   r   r   r8      r>   z/SQLiteVec.similarity_search.<locals>.<listcomp>r'   embed_queryrL   r)   rM   rD   r3   r   rJ   r   r   r   similarity_search   s
   zSQLiteVec.similarity_searchc                 K  s   | j |}| j||d}|S )rO   rP   rS   rU   r   r   r   similarity_search_with_score   s
   z&SQLiteVec.similarity_search_with_scorec                 K  s   | j ||d}dd |D S )NrP   c                 S  rQ   r   r   rR   r   r   r   r8      r>   z9SQLiteVec.similarity_search_by_vector.<locals>.<listcomp>)rL   )r)   r   rD   r3   rJ   r   r   r   similarity_search_by_vector   s   z%SQLiteVec.similarity_search_by_vector	langchainclsType[SQLiteVec]c           	      K  s,   |  |}| ||||d}|j||d |S )z9Return VectorStore initialized from texts and embeddings.)r   r   r   r   )r/   r1   )r!   rB   )	rZ   r/   r   r1   r   r   r3   r   Zvecr   r   r   
from_texts   s   
zSQLiteVec.from_textssqlite3.Connectionc                 C  sD   dd l }dd l}|| }|j|_|d || |d |S )Nr   TF)sqlite3r   connectRowZrow_factoryZenable_load_extensionload)r   r^   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'   rT   r   )r)   Z
dummy_textZdummy_embeddingr   r   r   r-      s   zSQLiteVec.get_dimensionality)r   )r   r   r   r   r   r   r   r   )r   r+   )N)r/   r0   r1   r2   r3   r   r   r4   )rC   )r   r   rD   rE   r3   r   r   rF   )rM   r   rD   rE   r3   r   r   rN   )rM   r   rD   rE   r3   r   r   rF   )r   r   rD   rE   r3   r   r   rN   )NrY   r   )rZ   r[   r/   r4   r   r   r1   r2   r   r   r   r   r3   r   r   r   )r   r   r   r]   )r   rE   )__name__
__module____qualname____doc__r*   r(   rB   rL   rV   rW   rX   classmethodr\   staticmethodr!   r-   r   r   r   r   r   #   s.    
&%r   )r   r   r   r   )
__future__r   r9   loggingr   r#   typingr   r   r   r   r   r   r	   Zlangchain_core.documentsr
   Zlangchain_core.embeddingsr   Zlangchain_core.vectorstoresr   r^   	getLoggerrb   loggerr   r   r   r   r   r   <module>   s    $


