style: reorder imports and reformat code for consistency

This commit is contained in:
Andrew Phillips
2025-05-10 10:06:33 -03:00
committed by Andrew Phillips (aider)
parent c936326ac3
commit 9feec61759
13 changed files with 492 additions and 356 deletions

159
src/db.rs
View File

@@ -1,31 +1,37 @@
use std::path::PathBuf;
use std::collections::HashMap;
use std::rc::Rc;
use anyhow::{Context, Result, Error};
use rusqlite::{Connection, OpenFlags};
use rusqlite_migration::{Migrations, M};
use anyhow::{Context, Error, Result};
use chrono::prelude::*;
use lazy_static::lazy_static;
use log::*;
use rusqlite::{Connection, OpenFlags};
use rusqlite_migration::{Migrations, M};
use std::collections::HashMap;
use std::path::PathBuf;
use std::rc::Rc;
lazy_static! {
static ref MIGRATIONS: Migrations<'static> = Migrations::new(vec![
M::up("CREATE TABLE items(
M::up(
"CREATE TABLE items(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
ts TEXT NOT NULL,
size INTEGER NULL,
compression TEXT NOT NULL)"),
M::up("CREATE TABLE tags (
compression TEXT NOT NULL)"
),
M::up(
"CREATE TABLE tags (
id INTEGER NOT NULL,
name TEXT NOT NULL,
FOREIGN KEY(id) REFERENCES items(id) ON DELETE CASCADE,
PRIMARY KEY(id, name));"),
M::up("CREATE TABLE metas (
PRIMARY KEY(id, name));"
),
M::up(
"CREATE TABLE metas (
id INTEGER NOT NULL,
name TEXT NOT NULL,
value TEXT NOT NULL,
FOREIGN KEY(id) REFERENCES items(id) ON DELETE CASCADE,
PRIMARY KEY(id, name));")
PRIMARY KEY(id, name));"
)
]);
}
@@ -34,71 +40,72 @@ pub struct Item {
pub id: Option<i64>,
pub ts: DateTime<Utc>,
pub size: Option<i64>,
pub compression: String
pub compression: String,
}
#[derive(Debug, Clone)]
pub struct Tag {
pub id: i64,
pub name: String
pub name: String,
}
#[derive(Debug, Clone)]
pub struct Meta {
pub id: i64,
pub name: String,
pub value: String
pub value: String,
}
pub fn open(path: PathBuf) -> Result<Connection, Error> {
debug!("DB: Opening file: {:?}", path);
let mut conn = Connection::open_with_flags(path, OpenFlags::SQLITE_OPEN_READ_WRITE | OpenFlags::SQLITE_OPEN_CREATE)
.context("Problem opening file")?;
let mut conn = Connection::open_with_flags(
path,
OpenFlags::SQLITE_OPEN_READ_WRITE | OpenFlags::SQLITE_OPEN_CREATE,
)
.context("Problem opening file")?;
conn.pragma_update(None, "foreign_keys", "ON")
.context("Problem enabling SQLite foreign_keys pragma")?;
MIGRATIONS.to_latest(&mut conn)
MIGRATIONS
.to_latest(&mut conn)
.context("Problem performing database migrations")?;
rusqlite::vtab::array::load_module(&conn)
.context("Problem enabling array module")?;
rusqlite::vtab::array::load_module(&conn).context("Problem enabling array module")?;
Ok(conn)
}
pub fn insert_item(conn: &Connection, item: Item) -> Result<i64> {
debug!("DB: Inserting item: {:?}", item);
conn.execute(
"INSERT INTO items (ts, size, compression) VALUES (?1, ?2, ?3)",
(item.ts, item.size, item.compression))?;
(item.ts, item.size, item.compression),
)?;
Ok(conn.last_insert_rowid())
}
pub fn update_item(conn: &Connection, item: Item) -> Result<()> {
debug!("DB: Updating item: {:?}", item);
conn.execute(
"UPDATE items SET size=?2, compression=?3 WHERE id=?1",
(item.id, item.size, item.compression))?;
(item.id, item.size, item.compression),
)?;
Ok(())
}
pub fn delete_item(conn: &Connection, item: Item) -> Result<()> {
debug!("DB: Deleting item: {:?}", item);
conn.execute("DELETE FROM items WHERE id=?1", [item.id])?;
Ok(())
}
pub fn query_delete_meta(conn: &Connection, meta: Meta) -> Result<()> {
debug!("DB: Deleting meta: {:?}", meta);
conn.execute(
"DELETE FROM metas WHERE id=?1 AND name=?2",
(meta.id, meta.name))?;
(meta.id, meta.name),
)?;
Ok(())
}
@@ -107,7 +114,8 @@ pub fn query_upsert_meta(conn: &Connection, meta: Meta) -> Result<()> {
conn.execute(
"INSERT INTO metas (id, name, value) VALUES (?1, ?2, ?3)
ON CONFLICT(id, name) DO UPDATE SET value=?3",
(meta.id, meta.name, meta.value))?;
(meta.id, meta.name, meta.value),
)?;
Ok(())
}
@@ -121,41 +129,38 @@ pub fn store_meta(conn: &Connection, meta: Meta) -> Result<()> {
Ok(())
}
pub fn insert_tag(conn: &Connection, tag: Tag) -> Result<()> {
debug!("DB: Inserting tag: {:?}", tag);
conn.execute(
"INSERT INTO tags (id, name) VALUES (?1, ?2)",
(tag.id, tag.name))?;
(tag.id, tag.name),
)?;
Ok(())
}
pub fn delete_item_tags(conn: &Connection, item: Item) -> Result<()> {
debug!("DB: Deleting all item tags: {:?}", item);
conn.execute(
"DELETE FROM tags WHERE id=?1",
[item.id])?;
conn.execute("DELETE FROM tags WHERE id=?1", [item.id])?;
Ok(())
}
pub fn set_item_tags(conn: &Connection, item: Item, tags: &Vec<String>) -> Result<()> {
debug!("DB: Setting tags for item: {:?} ?{:?}", item, tags);
delete_item_tags(conn, item.clone())?;
let item_id = item.id.unwrap();
for tag_name in tags {
insert_tag(conn,
insert_tag(
conn,
Tag {
id: item_id,
name: tag_name.to_string()
})?;
name: tag_name.to_string(),
},
)?;
}
Ok(())
}
pub fn query_all_items(conn: &Connection) -> Result<Vec<Item>> {
debug!("DB: Querying all items");
let mut statement = conn
@@ -169,7 +174,7 @@ pub fn query_all_items(conn: &Connection) -> Result<Vec<Item>> {
id: row.get(0)?,
ts: row.get(1)?,
size: row.get(2)?,
compression: row.get(3)?
compression: row.get(3)?,
};
items.push(item);
}
@@ -180,7 +185,8 @@ pub fn query_all_items(conn: &Connection) -> Result<Vec<Item>> {
pub fn query_tagged_items<'a>(conn: &'a Connection, tags: &'a Vec<String>) -> Result<Vec<Item>> {
debug!("DB: Querying tagged items: {:?}", tags);
let mut statement = conn
.prepare_cached("
.prepare_cached(
"
SELECT items.id,
items.ts,
items.size,
@@ -191,12 +197,13 @@ pub fn query_tagged_items<'a>(conn: &'a Connection, tags: &'a Vec<String>) -> Re
WHERE items.id = tags_match.id
GROUP BY items.id
HAVING tags_score = ?2
ORDER BY items.id ASC")
ORDER BY items.id ASC",
)
.context("Problem preparing SQL statement")?;
let tags_values: Vec<rusqlite::types::Value> = tags
.iter()
.map(|s| {rusqlite::types::Value::from(s.clone())})
.map(|s| rusqlite::types::Value::from(s.clone()))
.collect();
let tags_ptr = Rc::new(tags_values);
@@ -209,7 +216,7 @@ pub fn query_tagged_items<'a>(conn: &'a Connection, tags: &'a Vec<String>) -> Re
id: row.get(0)?,
ts: row.get(1)?,
size: row.get(2)?,
compression: row.get(3)?
compression: row.get(3)?,
};
items.push(item);
}
@@ -217,20 +224,24 @@ pub fn query_tagged_items<'a>(conn: &'a Connection, tags: &'a Vec<String>) -> Re
Ok(items)
}
pub fn get_items(conn: &Connection) -> Result<Vec<Item>> {
debug!("DB: Getting all items");
query_all_items(conn)
}
pub fn get_items_matching(conn: &Connection, tags: &Vec<String>, meta: &HashMap<String,String>) -> Result<Vec<Item>> {
debug!("DB: Getting items matching: tags={:?} meta={:?}", tags, meta);
pub fn get_items_matching(
conn: &Connection,
tags: &Vec<String>,
meta: &HashMap<String, String>,
) -> Result<Vec<Item>> {
debug!(
"DB: Getting items matching: tags={:?} meta={:?}",
tags, meta
);
let items = match tags.is_empty() {
true => query_all_items(conn)?,
false => query_tagged_items(conn, tags)?
false => query_tagged_items(conn, tags)?,
};
if meta.is_empty() {
@@ -251,7 +262,7 @@ pub fn get_items_matching(conn: &Connection, tags: &Vec<String>, meta: &HashMap<
for (k, v) in meta.iter() {
match item_meta.get(k) {
Some(value) => item_ok = v.eq(value),
None => item_ok = false
None => item_ok = false,
}
if item_ok {
@@ -265,14 +276,17 @@ pub fn get_items_matching(conn: &Connection, tags: &Vec<String>, meta: &HashMap<
}
Ok(filtered_items)
}
}
pub fn get_item_matching(conn: &Connection, tags: &Vec<String>, _meta: &HashMap<String, String>) -> Result<Option<Item>> {
pub fn get_item_matching(
conn: &Connection,
tags: &Vec<String>,
_meta: &HashMap<String, String>,
) -> Result<Option<Item>> {
debug!("DB: Get item matching tags: {:?}", tags);
let mut statement = conn
.prepare_cached("
.prepare_cached(
"
SELECT items.id,
items.ts,
items.size,
@@ -284,12 +298,13 @@ pub fn get_item_matching(conn: &Connection, tags: &Vec<String>, _meta: &HashMap<
GROUP BY items.id
HAVING score = ?2
ORDER BY items.id DESC
LIMIT 1")
LIMIT 1",
)
.context("Problem preparing SQL statement")?;
let tags_values: Vec<rusqlite::types::Value> = tags
.iter()
.map(|s| {rusqlite::types::Value::from(s.clone()) })
.map(|s| rusqlite::types::Value::from(s.clone()))
.collect();
let tags_ptr = Rc::new(tags_values);
@@ -301,20 +316,21 @@ pub fn get_item_matching(conn: &Connection, tags: &Vec<String>, _meta: &HashMap<
id: row.get(0)?,
ts: row.get(1)?,
size: row.get(2)?,
compression: row.get(3)?
compression: row.get(3)?,
})),
None => Ok(None)
None => Ok(None),
}
}
pub fn get_item(conn: &Connection, item_id: i64) -> Result<Option<Item>> {
debug!("DB: Getting item {:?}", item_id);
let mut statement = conn
.prepare_cached("
.prepare_cached(
"
SELECT id, ts, size, compression
FROM items
WHERE items.id = ?1")
WHERE items.id = ?1",
)
.context("Problem preparing SQL statement")?;
let mut rows = statement.query([item_id])?;
@@ -324,20 +340,22 @@ pub fn get_item(conn: &Connection, item_id: i64) -> Result<Option<Item>> {
id: row.get(0)?,
ts: row.get(1)?,
size: row.get(2)?,
compression: row.get(3)?
compression: row.get(3)?,
})),
None => Ok(None)
None => Ok(None),
}
}
pub fn get_item_last(conn: &Connection) -> Result<Option<Item>> {
debug!("DB: Getting last item");
let mut statement = conn
.prepare_cached("
.prepare_cached(
"
SELECT id, ts, size, compression
FROM items
ORDER BY id DESC
LIMIT 1")
LIMIT 1",
)
.context("Problem preparing SQL statement")?;
let mut rows = statement.query([])?;
@@ -347,9 +365,9 @@ pub fn get_item_last(conn: &Connection) -> Result<Option<Item>> {
id: row.get(0)?,
ts: row.get(1)?,
size: row.get(2)?,
compression: row.get(3)?
compression: row.get(3)?,
})),
None => Ok(None)
None => Ok(None),
}
}
@@ -372,7 +390,6 @@ pub fn get_item_tags(conn: &Connection, item: &Item) -> Result<Vec<Tag>> {
Ok(tags)
}
pub fn get_item_meta(conn: &Connection, item: &Item) -> Result<Vec<Meta>> {
debug!("DB: Getting item meta: {:?}", item);
let mut statement = conn
@@ -386,7 +403,7 @@ pub fn get_item_meta(conn: &Connection, item: &Item) -> Result<Vec<Meta>> {
metas.push(Meta {
id: row.get(0)?,
name: row.get(1)?,
value: row.get(2)?
value: row.get(2)?,
});
}