use memista::{AppState, Config, InsertChunkRequest, SearchRequest, ChunkData, ensure_table_exists, load_or_create_index};
use async_sqlite::{PoolBuilder, JournalMode};
use std::sync::Arc;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Demonstrating Memista library usage...");
let config = Config {
database_path: "memista_library_example.db".to_string(),
server_host: "127.0.0.1".to_string(),
server_port: 8085,
log_level: "info".to_string(),
};
let db_pool = PoolBuilder::new()
.path(&config.database_path)
.journal_mode(JournalMode::Wal)
.open()
.await
.expect("Failed to create database pool");
let app_state = Arc::new(AppState { db_pool });
let database_id = "example_db";
ensure_table_exists(&app_state.db_pool, database_id).await?;
let mut index = load_or_create_index(database_id)?;
let chunks = vec![
ChunkData {
embedding: vec![0.1, 0.2],
text: "This is the first example chunk".to_string(),
metadata: "{\"source\": \"example1\"}".to_string(),
},
ChunkData {
embedding: vec![0.3, 0.4],
text: "This is the second example chunk".to_string(),
metadata: "{\"source\": \"example2\"}".to_string(),
},
ChunkData {
embedding: vec![0.5, 0.6],
text: "This is the third example chunk".to_string(),
metadata: "{\"source\": \"example3\"}".to_string(),
},
];
let insert_request = InsertChunkRequest {
database_id: database_id.to_string(),
chunks: chunks.clone(),
};
println!("Inserting {} chunks into the database...", chunks.len());
let table_name = format!("chunks_{}", database_id);
let mut inserted_ids = Vec::new();
for chunk in &insert_request.chunks {
let chunk = chunk.clone();
let table_name = table_name.clone();
let chunk_id: i64 = app_state.db_pool.conn(move |conn| {
conn.query_row(
&format!("INSERT INTO {} (text, metadata) VALUES (?, ?) RETURNING chunk_id", table_name),
[&chunk.text, &chunk.metadata],
|row| row.get(0),
)
}).await?;
index.add(chunk_id as u64, &chunk.embedding)?;
inserted_ids.push(chunk_id);
}
let index_file = format!("{}.usearch", database_id);
index.save(&index_file)?;
println!("Successfully inserted chunks with IDs: {:?}", inserted_ids);
println!("\nSearching for similar chunks...");
let search_request = SearchRequest {
database_id: database_id.to_string(),
embeddings: vec![vec![0.1, 0.2]], num_results: 5, };
let index = load_or_create_index(&search_request.database_id)?;
let query_embedding = &search_request.embeddings[0];
let results = index.search(query_embedding, search_request.num_results)?;
let mut ranked_chunks = Vec::new();
for (chunk_id, score) in results.keys.iter().zip(results.distances.iter()) {
let chunk_id = *chunk_id;
let score = *score;
let table_name = table_name.clone();
let chunk = app_state.db_pool.conn(move |conn| {
conn.query_row(
&format!("SELECT text, metadata FROM {} WHERE chunk_id = ?", table_name),
[chunk_id.to_string()],
|row| Ok((row.get::<_, String>(0)?, row.get::<_, Option<String>>(1)?)),
)
}).await?;
println!("Found chunk: '{}' with score: {} and metadata: {:?}", chunk.0, score, chunk.1);
ranked_chunks.push((chunk.0, chunk.1, score));
}
println!("\nLibrary usage example completed successfully!");
println!("Found {} similar chunks", ranked_chunks.len());
Ok(())
}