use mnm_core::types::EmbeddingModel;
use sqlx::PgPool;
use uuid::Uuid;
use crate::error::Result;
pub async fn get_by_name_revision(
pool: &PgPool,
name: &str,
revision: i32,
) -> Result<EmbeddingModel> {
let row = sqlx::query_as::<_, EmbeddingModelRow>(
"SELECT id, name, revision, dim, provider, created_at \
FROM embedding_model WHERE name = $1 AND revision = $2",
)
.bind(name)
.bind(revision)
.fetch_one(pool)
.await?;
Ok(row.into())
}
pub async fn get_active(pool: &PgPool) -> Result<EmbeddingModel> {
let row = sqlx::query_as::<_, EmbeddingModelRow>(
"SELECT em.id, em.name, em.revision, em.dim, em.provider, em.created_at \
FROM embedding_model em \
LEFT JOIN source_version sv \
ON sv.embedding_model_id = em.id AND sv.is_active = true \
ORDER BY sv.ingested_at DESC NULLS LAST, em.created_at DESC \
LIMIT 1",
)
.fetch_one(pool)
.await?;
Ok(row.into())
}
pub async fn get_by_id(pool: &PgPool, id: Uuid) -> Result<EmbeddingModel> {
let row = sqlx::query_as::<_, EmbeddingModelRow>(
"SELECT id, name, revision, dim, provider, created_at \
FROM embedding_model WHERE id = $1",
)
.bind(id)
.fetch_one(pool)
.await?;
Ok(row.into())
}
pub async fn upsert(
pool: &PgPool,
name: &str,
revision: i32,
dim: i32,
provider: &str,
) -> Result<Uuid> {
let row: (Uuid,) = sqlx::query_as(
"INSERT INTO embedding_model (name, revision, dim, provider) VALUES ($1, $2, $3, $4) \
ON CONFLICT (name, revision) DO UPDATE SET name = EXCLUDED.name \
RETURNING id",
)
.bind(name)
.bind(revision)
.bind(dim)
.bind(provider)
.fetch_one(pool)
.await?;
Ok(row.0)
}
#[derive(sqlx::FromRow)]
struct EmbeddingModelRow {
id: Uuid,
name: String,
revision: i32,
dim: i32,
provider: String,
created_at: time::OffsetDateTime,
}
impl From<EmbeddingModelRow> for EmbeddingModel {
fn from(r: EmbeddingModelRow) -> Self {
Self {
id: r.id,
name: r.name,
revision: r.revision,
dim: r.dim,
provider: r.provider,
created_at: r.created_at,
}
}
}