Replace literal SQL with Diesel abstractions
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::db::DbConnection as Connection;
|
||||
use keyring::Entry;
|
||||
use reqwest::blocking::Client;
|
||||
use rusqlite::Connection;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{Value, json};
|
||||
|
||||
@@ -681,7 +681,7 @@ fn get_optional_setting(conn: &Connection, key: &str) -> EngineResult<Option<Str
|
||||
match setting::get_setting_by_key(conn, key) {
|
||||
Ok(setting) if setting.value.trim().is_empty() => Ok(None),
|
||||
Ok(setting) => Ok(Some(setting.value)),
|
||||
Err(rusqlite::Error::QueryReturnedNoRows) => Ok(None),
|
||||
Err(diesel::result::Error::NotFound) => Ok(None),
|
||||
Err(error) => Err(EngineError::Db(error)),
|
||||
}
|
||||
}
|
||||
@@ -724,7 +724,7 @@ mod tests {
|
||||
use crate::db::Database;
|
||||
|
||||
fn setup() -> Database {
|
||||
let mut db = Database::open_in_memory().unwrap();
|
||||
let db = Database::open_in_memory().unwrap();
|
||||
db.migrate().unwrap();
|
||||
db
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::path::Path;
|
||||
|
||||
use rusqlite::Connection;
|
||||
use crate::db::DbConnection as Connection;
|
||||
|
||||
use crate::db::queries::post as post_q;
|
||||
use crate::engine::EngineResult;
|
||||
@@ -65,7 +65,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn calendar_empty_project() {
|
||||
let mut db = Database::open_in_memory().unwrap();
|
||||
let db = Database::open_in_memory().unwrap();
|
||||
let _ = db.migrate();
|
||||
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::path::PathBuf;
|
||||
|
||||
/// Shared context passed to engine operations.
|
||||
pub struct EngineContext<'a> {
|
||||
pub conn: &'a rusqlite::Connection,
|
||||
pub conn: &'a crate::db::DbConnection,
|
||||
pub project_id: String,
|
||||
pub data_dir: PathBuf,
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@ use std::fmt;
|
||||
/// Errors produced by engine operations.
|
||||
#[derive(Debug)]
|
||||
pub enum EngineError {
|
||||
Db(rusqlite::Error),
|
||||
Db(diesel::result::Error),
|
||||
DbConnection(diesel::ConnectionError),
|
||||
Io(std::io::Error),
|
||||
Parse(String),
|
||||
NotFound(String),
|
||||
@@ -15,6 +16,7 @@ impl fmt::Display for EngineError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Db(e) => write!(f, "database error: {e}"),
|
||||
Self::DbConnection(e) => write!(f, "database connection error: {e}"),
|
||||
Self::Io(e) => write!(f, "I/O error: {e}"),
|
||||
Self::Parse(msg) => write!(f, "parse error: {msg}"),
|
||||
Self::NotFound(msg) => write!(f, "not found: {msg}"),
|
||||
@@ -28,18 +30,34 @@ impl std::error::Error for EngineError {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
match self {
|
||||
Self::Db(e) => Some(e),
|
||||
Self::DbConnection(e) => Some(e),
|
||||
Self::Io(e) => Some(e),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<rusqlite::Error> for EngineError {
|
||||
fn from(e: rusqlite::Error) -> Self {
|
||||
impl From<diesel::result::Error> for EngineError {
|
||||
fn from(e: diesel::result::Error) -> Self {
|
||||
Self::Db(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<diesel::ConnectionError> for EngineError {
|
||||
fn from(e: diesel::ConnectionError) -> Self {
|
||||
Self::DbConnection(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<crate::db::DatabaseError> for EngineError {
|
||||
fn from(e: crate::db::DatabaseError) -> Self {
|
||||
match e {
|
||||
crate::db::DatabaseError::Connection(e) => Self::DbConnection(e),
|
||||
crate::db::DatabaseError::Query(e) => Self::Db(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for EngineError {
|
||||
fn from(e: std::io::Error) -> Self {
|
||||
Self::Io(e)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::path::Path;
|
||||
|
||||
use crate::db::DbConnection as Connection;
|
||||
use chrono::{DateTime, TimeZone, Utc};
|
||||
use pagefind::api::PagefindIndex;
|
||||
use pagefind::options::PagefindServiceConfig;
|
||||
use rusqlite::Connection;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
use crate::db::queries;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
use rusqlite::Connection;
|
||||
use crate::db::DbConnection as Connection;
|
||||
use uuid::Uuid;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
@@ -670,7 +670,7 @@ mod tests {
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn setup() -> (Database, TempDir) {
|
||||
let mut db = Database::open_in_memory().unwrap();
|
||||
let db = Database::open_in_memory().unwrap();
|
||||
db.migrate().unwrap();
|
||||
ensure_fts_tables(db.conn()).unwrap();
|
||||
insert_project(db.conn(), &make_test_project("p1", "blog")).unwrap();
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::collections::HashSet;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
use rusqlite::Connection;
|
||||
use crate::db::DbConnection as Connection;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
use crate::db::from_row::{script_kind_to_str, template_kind_to_str};
|
||||
@@ -629,7 +629,7 @@ mod tests {
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn setup() -> (Database, TempDir) {
|
||||
let mut db = Database::open_in_memory().unwrap();
|
||||
let db = Database::open_in_memory().unwrap();
|
||||
db.migrate().unwrap();
|
||||
ensure_fts_tables(db.conn()).unwrap();
|
||||
insert_project(db.conn(), &make_test_project("p1", "blog")).unwrap();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
use rusqlite::{Connection, params};
|
||||
use crate::db::DbConnection as Connection;
|
||||
use uuid::Uuid;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
@@ -189,7 +189,7 @@ pub fn update_post(
|
||||
|
||||
/// Publish a post: write file, clear content, set published_at.
|
||||
pub fn publish_post(conn: &Connection, data_dir: &Path, post_id: &str) -> EngineResult<Post> {
|
||||
let mut post = qp::get_post_by_id(conn, post_id)?;
|
||||
let post = qp::get_post_by_id(conn, post_id)?;
|
||||
|
||||
// Require Draft or Archived status
|
||||
match post.status {
|
||||
@@ -201,10 +201,27 @@ pub fn publish_post(conn: &Connection, data_dir: &Path, post_id: &str) -> Engine
|
||||
}
|
||||
}
|
||||
|
||||
// Compute file_path from created_at + slug
|
||||
// Use a savepoint for atomicity
|
||||
// Note: savepoint auto-rolls-back if not released (on error propagation)
|
||||
conn.execute_batch("SAVEPOINT publish_post")?;
|
||||
conn.begin_savepoint()?;
|
||||
match publish_post_in_savepoint(conn, data_dir, post) {
|
||||
Ok(post) => {
|
||||
conn.release_savepoint()?;
|
||||
Ok(post)
|
||||
}
|
||||
Err(error) => {
|
||||
let _ = conn.rollback_savepoint();
|
||||
Err(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn publish_post_in_savepoint(
|
||||
conn: &Connection,
|
||||
data_dir: &Path,
|
||||
mut post: Post,
|
||||
) -> EngineResult<Post> {
|
||||
let post_id = post.id.clone();
|
||||
|
||||
// Compute file_path from created_at + slug.
|
||||
let rel_path = post_file_path(post.created_at, &post.slug);
|
||||
let abs_path = data_dir.join(&rel_path);
|
||||
|
||||
@@ -245,7 +262,7 @@ pub fn publish_post(conn: &Connection, data_dir: &Path, post_id: &str) -> Engine
|
||||
|
||||
qp::set_published_snapshot(
|
||||
conn,
|
||||
post_id,
|
||||
&post_id,
|
||||
&post.title,
|
||||
&body,
|
||||
&tags_json,
|
||||
@@ -256,27 +273,24 @@ pub fn publish_post(conn: &Connection, data_dir: &Path, post_id: &str) -> Engine
|
||||
)?;
|
||||
|
||||
// Set file_path and checksum in DB
|
||||
qp::set_post_file_path(conn, post_id, &post.file_path, now)?;
|
||||
conn.execute(
|
||||
"UPDATE posts SET checksum = ?1 WHERE id = ?2",
|
||||
params![post.checksum, post_id],
|
||||
)?;
|
||||
qp::set_post_file_path(conn, &post_id, &post.file_path, now)?;
|
||||
qp::set_post_checksum(conn, &post_id, post.checksum.as_deref())?;
|
||||
|
||||
// Clear content in DB
|
||||
qp::clear_post_content(conn, post_id, now)?;
|
||||
qp::clear_post_content(conn, &post_id, now)?;
|
||||
post.content = None;
|
||||
|
||||
// Set status = Published
|
||||
qp::update_post_status(conn, post_id, &PostStatus::Published, now)?;
|
||||
qp::update_post_status(conn, &post_id, &PostStatus::Published, now)?;
|
||||
|
||||
// Publish all translations
|
||||
let translations = qt::list_post_translations_by_post(conn, post_id)?;
|
||||
let translations = qt::list_post_translations_by_post(conn, &post_id)?;
|
||||
for mut t in translations {
|
||||
publish_translation(conn, data_dir, &mut t, &post)?;
|
||||
}
|
||||
|
||||
// Parse inter-post links and update link graph
|
||||
ql::delete_links_by_source(conn, post_id)?;
|
||||
ql::delete_links_by_source(conn, &post_id)?;
|
||||
let link_body = if let Some(ref pc) = post.published_content {
|
||||
pc.as_str()
|
||||
} else {
|
||||
@@ -287,7 +301,7 @@ pub fn publish_post(conn: &Connection, data_dir: &Path, post_id: &str) -> Engine
|
||||
if let Ok(target) = qp::get_post_by_project_and_slug(conn, &post.project_id, target_slug) {
|
||||
let link = PostLink {
|
||||
id: Uuid::new_v4().to_string(),
|
||||
source_post_id: post_id.to_string(),
|
||||
source_post_id: post_id.clone(),
|
||||
target_post_id: target.id.clone(),
|
||||
link_text: Some(link_text.clone()),
|
||||
created_at: now,
|
||||
@@ -299,8 +313,6 @@ pub fn publish_post(conn: &Connection, data_dir: &Path, post_id: &str) -> Engine
|
||||
// Re-index FTS
|
||||
fts_index_post(conn, &post)?;
|
||||
|
||||
conn.execute_batch("RELEASE publish_post")?;
|
||||
|
||||
Ok(post)
|
||||
}
|
||||
|
||||
@@ -515,16 +527,10 @@ pub fn delete_post(conn: &Connection, data_dir: &Path, post_id: &str) -> EngineR
|
||||
|
||||
// Delete post links (source and target)
|
||||
ql::delete_links_by_source(conn, post_id)?;
|
||||
conn.execute(
|
||||
"DELETE FROM post_links WHERE target_post_id = ?1",
|
||||
params![post_id],
|
||||
)?;
|
||||
ql::delete_links_by_target(conn, post_id)?;
|
||||
|
||||
// Delete post-media associations
|
||||
conn.execute(
|
||||
"DELETE FROM post_media WHERE post_id = ?1",
|
||||
params![post_id],
|
||||
)?;
|
||||
crate::db::queries::post_media::delete_post_media_by_post(conn, post_id)?;
|
||||
|
||||
// Remove from FTS
|
||||
fts::remove_post_from_index(conn, post_id)?;
|
||||
@@ -882,13 +888,6 @@ fn publish_translation(
|
||||
t.content = None;
|
||||
|
||||
qt::update_post_translation(conn, t)?;
|
||||
// Clear content after update (the update already set content=None via the struct)
|
||||
// but we also do an explicit clear to be safe
|
||||
conn.execute(
|
||||
"UPDATE post_translations SET content = NULL WHERE id = ?1",
|
||||
params![t.id],
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1149,7 +1148,7 @@ mod tests {
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn setup() -> (Database, TempDir) {
|
||||
let mut db = Database::open_in_memory().unwrap();
|
||||
let db = Database::open_in_memory().unwrap();
|
||||
db.migrate().unwrap();
|
||||
ensure_fts_tables(db.conn()).unwrap();
|
||||
insert_project(db.conn(), &make_test_project("p1", "blog")).unwrap();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::path::Path;
|
||||
|
||||
use rusqlite::Connection;
|
||||
use crate::db::DbConnection as Connection;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::db::queries::media as qm;
|
||||
@@ -109,22 +109,17 @@ mod tests {
|
||||
|
||||
use crate::db::Database;
|
||||
use crate::db::queries::media::{insert_media, make_test_media};
|
||||
use crate::db::queries::post::{insert_post, make_test_post};
|
||||
use crate::db::queries::post_media::list_post_media_by_post;
|
||||
use crate::db::queries::project::{insert_project, make_test_project};
|
||||
use crate::util::sidecar::read_sidecar;
|
||||
|
||||
fn setup() -> (Database, TempDir) {
|
||||
let mut db = Database::open_in_memory().unwrap();
|
||||
let db = Database::open_in_memory().unwrap();
|
||||
db.migrate().unwrap();
|
||||
insert_project(db.conn(), &make_test_project("p1", "blog")).unwrap();
|
||||
let dir = TempDir::new().unwrap();
|
||||
// Create a post
|
||||
db.conn()
|
||||
.execute(
|
||||
"INSERT INTO posts (id, project_id, title, slug, status, file_path, created_at, updated_at) VALUES ('post1', 'p1', 'Test', 'test', 'draft', '', 1000, 1000)",
|
||||
[],
|
||||
)
|
||||
.unwrap();
|
||||
insert_post(db.conn(), &make_test_post("post1", "p1", "test")).unwrap();
|
||||
(db, dir)
|
||||
}
|
||||
|
||||
@@ -197,13 +192,10 @@ mod tests {
|
||||
let (db, dir) = setup();
|
||||
insert_test_media(&db, dir.path(), "m1");
|
||||
|
||||
// Create a second post
|
||||
db.conn()
|
||||
.execute(
|
||||
"INSERT INTO posts (id, project_id, title, slug, status, file_path, created_at, updated_at) VALUES ('post2', 'p1', 'Test2', 'test2', 'draft', '', 2000, 2000)",
|
||||
[],
|
||||
)
|
||||
.unwrap();
|
||||
let mut post = make_test_post("post2", "p1", "test2");
|
||||
post.created_at = 2000;
|
||||
post.updated_at = 2000;
|
||||
insert_post(db.conn(), &post).unwrap();
|
||||
|
||||
link_media_to_post(db.conn(), dir.path(), "p1", "post1", "m1", 0).unwrap();
|
||||
link_media_to_post(db.conn(), dir.path(), "p1", "post2", "m1", 0).unwrap();
|
||||
|
||||
@@ -453,7 +453,7 @@ mod tests {
|
||||
meta::write_project_json(dir.path(), &make_metadata()).unwrap();
|
||||
|
||||
let db_path = dir.path().join("bds.db");
|
||||
let mut db = Database::open(&db_path).unwrap();
|
||||
let db = Database::open(&db_path).unwrap();
|
||||
db.migrate().unwrap();
|
||||
queries::project::insert_project(
|
||||
db.conn(),
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::collections::HashMap;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
use rusqlite::Connection;
|
||||
use crate::db::DbConnection as Connection;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::db::queries::project as q;
|
||||
@@ -64,7 +64,7 @@ pub fn ensure_default_project(
|
||||
) -> EngineResult<Project> {
|
||||
match q::get_project_by_id(conn, DEFAULT_PROJECT_ID) {
|
||||
Ok(p) => Ok(p),
|
||||
Err(rusqlite::Error::QueryReturnedNoRows) => {
|
||||
Err(diesel::result::Error::NotFound) => {
|
||||
let now = now_unix_ms();
|
||||
let project = Project {
|
||||
id: DEFAULT_PROJECT_ID.to_string(),
|
||||
@@ -94,7 +94,7 @@ pub fn ensure_default_project(
|
||||
pub fn get_active_project(conn: &Connection) -> EngineResult<Option<Project>> {
|
||||
match q::get_active_project(conn) {
|
||||
Ok(p) => Ok(Some(p)),
|
||||
Err(rusqlite::Error::QueryReturnedNoRows) => Ok(None),
|
||||
Err(diesel::result::Error::NotFound) => Ok(None),
|
||||
Err(e) => Err(EngineError::Db(e)),
|
||||
}
|
||||
}
|
||||
@@ -280,7 +280,7 @@ mod tests {
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn setup() -> (Database, TempDir) {
|
||||
let mut db = Database::open_in_memory().unwrap();
|
||||
let db = Database::open_in_memory().unwrap();
|
||||
db.migrate().unwrap();
|
||||
let dir = TempDir::new().unwrap();
|
||||
(db, dir)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
use rusqlite::Connection;
|
||||
use crate::db::DbConnection as Connection;
|
||||
|
||||
use crate::db::fts;
|
||||
use crate::engine::EngineResult;
|
||||
@@ -157,7 +157,7 @@ mod tests {
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn setup() -> (Database, TempDir) {
|
||||
let mut db = Database::open_in_memory().unwrap();
|
||||
let db = Database::open_in_memory().unwrap();
|
||||
db.migrate().unwrap();
|
||||
fts::ensure_fts_tables(db.conn()).unwrap();
|
||||
insert_project(db.conn(), &make_test_project("p1", "blog")).unwrap();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
use rusqlite::Connection;
|
||||
use crate::db::DbConnection as Connection;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::db::queries::script as qs;
|
||||
@@ -305,7 +305,7 @@ mod tests {
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn setup() -> (Database, TempDir) {
|
||||
let mut db = Database::open_in_memory().unwrap();
|
||||
let db = Database::open_in_memory().unwrap();
|
||||
db.migrate().unwrap();
|
||||
insert_project(db.conn(), &make_test_project("p1", "blog")).unwrap();
|
||||
let dir = TempDir::new().unwrap();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
use rusqlite::Connection;
|
||||
use crate::db::DbConnection as Connection;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
use crate::db::queries::script as qs;
|
||||
@@ -145,7 +145,7 @@ mod tests {
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn setup() -> (Database, TempDir) {
|
||||
let mut db = Database::open_in_memory().unwrap();
|
||||
let db = Database::open_in_memory().unwrap();
|
||||
db.migrate().unwrap();
|
||||
insert_project(db.conn(), &make_test_project("p1", "blog")).unwrap();
|
||||
let dir = TempDir::new().unwrap();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! Full-text search reindexing engine functions.
|
||||
|
||||
use rusqlite::Connection;
|
||||
use crate::db::DbConnection as Connection;
|
||||
|
||||
use crate::db::fts;
|
||||
use crate::db::queries::{media as media_q, media_translation, post as post_q, post_translation};
|
||||
@@ -32,8 +32,7 @@ pub fn reindex_all_with_progress(
|
||||
on_item: Option<ItemProgressFn>,
|
||||
) -> EngineResult<ReindexReport> {
|
||||
// Wipe existing FTS content
|
||||
conn.execute("DELETE FROM posts_fts", [])?;
|
||||
conn.execute("DELETE FROM media_fts", [])?;
|
||||
fts::clear_indexes(conn)?;
|
||||
|
||||
// Reindex all posts
|
||||
let posts = post_q::list_posts_by_project(conn, project_id)?;
|
||||
@@ -124,7 +123,7 @@ mod tests {
|
||||
use crate::engine;
|
||||
|
||||
fn setup() -> (Database, String) {
|
||||
let mut db = Database::open_in_memory().unwrap();
|
||||
let db = Database::open_in_memory().unwrap();
|
||||
let _ = db.migrate();
|
||||
ensure_fts_tables(db.conn()).unwrap();
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
use rusqlite::Connection;
|
||||
use crate::db::DbConnection as Connection;
|
||||
|
||||
use crate::engine::{EngineError, EngineResult};
|
||||
use crate::render::{GeneratedWriteOutcome, write_generated_bytes};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::path::Path;
|
||||
|
||||
use rusqlite::Connection;
|
||||
use crate::db::DbConnection as Connection;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::db::queries::post as post_q;
|
||||
@@ -360,7 +360,7 @@ mod tests {
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn setup() -> (Database, TempDir) {
|
||||
let mut db = Database::open_in_memory().unwrap();
|
||||
let db = Database::open_in_memory().unwrap();
|
||||
db.migrate().unwrap();
|
||||
let dir = TempDir::new().unwrap();
|
||||
std::fs::create_dir_all(dir.path().join("meta")).unwrap();
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
use rusqlite::Connection;
|
||||
use crate::db::DbConnection as Connection;
|
||||
use crate::db::schema::{posts, tags};
|
||||
use diesel::prelude::*;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::db::queries::template as qt;
|
||||
@@ -383,36 +385,40 @@ fn validate_liquid_blocks(content: &str) -> Result<(), String> {
|
||||
}
|
||||
|
||||
fn count_posts_using_template(conn: &Connection, slug: &str) -> EngineResult<usize> {
|
||||
let count: i64 = conn.query_row(
|
||||
"SELECT COUNT(*) FROM posts WHERE template_slug = ?1",
|
||||
rusqlite::params![slug],
|
||||
|row| row.get(0),
|
||||
)?;
|
||||
let count: i64 = conn.with(|c| {
|
||||
posts::table
|
||||
.filter(posts::template_slug.eq(slug))
|
||||
.count()
|
||||
.get_result(c)
|
||||
})?;
|
||||
Ok(count as usize)
|
||||
}
|
||||
|
||||
fn count_tags_using_template(conn: &Connection, slug: &str) -> EngineResult<usize> {
|
||||
let count: i64 = conn.query_row(
|
||||
"SELECT COUNT(*) FROM tags WHERE post_template_slug = ?1",
|
||||
rusqlite::params![slug],
|
||||
|row| row.get(0),
|
||||
)?;
|
||||
let count: i64 = conn.with(|c| {
|
||||
tags::table
|
||||
.filter(tags::post_template_slug.eq(slug))
|
||||
.count()
|
||||
.get_result(c)
|
||||
})?;
|
||||
Ok(count as usize)
|
||||
}
|
||||
|
||||
fn null_template_slug_on_posts(conn: &Connection, slug: &str) -> EngineResult<()> {
|
||||
conn.execute(
|
||||
"UPDATE posts SET template_slug = NULL WHERE template_slug = ?1",
|
||||
rusqlite::params![slug],
|
||||
)?;
|
||||
conn.with(|c| {
|
||||
diesel::update(posts::table.filter(posts::template_slug.eq(slug)))
|
||||
.set(posts::template_slug.eq(None::<String>))
|
||||
.execute(c)
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn null_template_slug_on_tags(conn: &Connection, slug: &str) -> EngineResult<()> {
|
||||
conn.execute(
|
||||
"UPDATE tags SET post_template_slug = NULL WHERE post_template_slug = ?1",
|
||||
rusqlite::params![slug],
|
||||
)?;
|
||||
conn.with(|c| {
|
||||
diesel::update(tags::table.filter(tags::post_template_slug.eq(slug)))
|
||||
.set(tags::post_template_slug.eq(None::<String>))
|
||||
.execute(c)
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -424,7 +430,7 @@ mod tests {
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn setup() -> (Database, TempDir) {
|
||||
let mut db = Database::open_in_memory().unwrap();
|
||||
let db = Database::open_in_memory().unwrap();
|
||||
db.migrate().unwrap();
|
||||
insert_project(db.conn(), &make_test_project("p1", "blog")).unwrap();
|
||||
let dir = TempDir::new().unwrap();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
use rusqlite::Connection;
|
||||
use crate::db::DbConnection as Connection;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
use crate::db::queries::template as qt;
|
||||
@@ -144,7 +144,7 @@ mod tests {
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn setup() -> (Database, TempDir) {
|
||||
let mut db = Database::open_in_memory().unwrap();
|
||||
let db = Database::open_in_memory().unwrap();
|
||||
db.migrate().unwrap();
|
||||
insert_project(db.conn(), &make_test_project("p1", "blog")).unwrap();
|
||||
let dir = TempDir::new().unwrap();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
use rusqlite::Connection;
|
||||
use crate::db::DbConnection as Connection;
|
||||
|
||||
use crate::db::queries::media as mq;
|
||||
use crate::db::queries::post_media as pmq;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::collections::HashSet;
|
||||
use std::path::Path;
|
||||
|
||||
use rusqlite::Connection;
|
||||
use crate::db::DbConnection as Connection;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
use crate::db::queries;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use rusqlite::Connection;
|
||||
use crate::db::DbConnection as Connection;
|
||||
|
||||
use crate::db::queries::{post as post_q, post_translation};
|
||||
use crate::engine::EngineResult;
|
||||
|
||||
Reference in New Issue
Block a user