summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2020-12-11 17:41:42 +0200
committerLars Wirzenius <liw@liw.fi>2020-12-11 18:12:46 +0200
commit4d810f49298cce32ee0165b144af1917588c2de7 (patch)
treea1b51a323f89a80eeded6032f906fce1bb197bf6 /src
parentc2df16bb3644fc270a3f5ce7e048d509de0e4b51 (diff)
downloadobnam2-4d810f49298cce32ee0165b144af1917588c2de7.tar.gz
feat! store file metadata as JSON
This avoids having to add extra columns when we add more metadata support. This may be worth re-thinking later, once things stabilize.
Diffstat (limited to 'src')
-rw-r--r--src/fsentry.rs5
-rw-r--r--src/generation.rs35
2 files changed, 14 insertions, 26 deletions
diff --git a/src/fsentry.rs b/src/fsentry.rs
index 97274ed..ca73ef6 100644
--- a/src/fsentry.rs
+++ b/src/fsentry.rs
@@ -1,3 +1,4 @@
+use serde::{Deserialize, Serialize};
use std::path::{Path, PathBuf};
/// A file system entry.
@@ -9,7 +10,7 @@ use std::path::{Path, PathBuf};
///
/// This is everything Obnam cares about each file system object, when
/// making a backup.
-#[derive(Debug)]
+#[derive(Debug, Serialize, Deserialize)]
pub struct FilesystemEntry {
kind: FilesystemKind,
path: PathBuf,
@@ -54,7 +55,7 @@ impl FilesystemEntry {
}
/// Different types of file system entries.
-#[derive(Debug, Copy, Clone, PartialEq)]
+#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
pub enum FilesystemKind {
Regular,
Directory,
diff --git a/src/generation.rs b/src/generation.rs
index a2a2cdb..875221f 100644
--- a/src/generation.rs
+++ b/src/generation.rs
@@ -1,11 +1,7 @@
-use crate::fsentry::{FilesystemEntry, FilesystemKind};
-use std::ffi::OsStr;
-use std::os::unix::ffi::OsStrExt;
-//use crate::fsiter::FsIterator;
use crate::chunkid::ChunkId;
+use crate::fsentry::FilesystemEntry;
use rusqlite::{params, Connection, OpenFlags, Row, Transaction};
-use std::os::unix::ffi::OsStringExt;
-use std::path::{Path, PathBuf};
+use std::path::Path;
/// A backup generation.
pub struct Generation {
@@ -21,7 +17,7 @@ impl Generation {
let flags = OpenFlags::SQLITE_OPEN_CREATE | OpenFlags::SQLITE_OPEN_READ_WRITE;
let conn = Connection::open_with_flags(filename, flags)?;
conn.execute(
- "CREATE TABLE files (fileno INTEGER PRIMARY KEY, path BLOB, kind INTEGER, len INTEGER)",
+ "CREATE TABLE files (fileno INTEGER PRIMARY KEY, json TEXT)",
params![],
)?;
conn.execute(
@@ -75,7 +71,8 @@ impl Generation {
let iter = stmt.query_map(params![], |row| row_to_entry(row))?;
let mut files: Vec<(u64, FilesystemEntry)> = vec![];
for x in iter {
- let (fileno, entry) = x?;
+ let (fileno, json) = x?;
+ let entry = serde_json::from_str(&json)?;
files.push((fileno, entry));
}
Ok(files)
@@ -96,19 +93,11 @@ impl Generation {
}
}
-fn row_to_entry(row: &Row) -> rusqlite::Result<(u64, FilesystemEntry)> {
+fn row_to_entry(row: &Row) -> rusqlite::Result<(u64, String)> {
let fileno: i64 = row.get(row.column_index("fileno")?)?;
let fileno = fileno as u64;
- let path: Vec<u8> = row.get(row.column_index("path")?)?;
- let path: &OsStr = OsStrExt::from_bytes(&path);
- let path: PathBuf = PathBuf::from(path);
- let kind = row.get(row.column_index("kind")?)?;
- let kind = FilesystemKind::from_code(kind).unwrap();
- let entry = match kind {
- FilesystemKind::Regular => FilesystemEntry::regular(path, 0),
- FilesystemKind::Directory => FilesystemEntry::directory(path),
- };
- Ok((fileno, entry))
+ let json: String = row.get(row.column_index("json")?)?;
+ Ok((fileno, json))
}
fn insert_one(
@@ -117,13 +106,11 @@ fn insert_one(
fileno: u64,
ids: &[ChunkId],
) -> anyhow::Result<()> {
- let path = e.path().as_os_str().to_os_string().into_vec();
- let kind = e.kind().as_code();
- let len = e.len() as i64;
let fileno = fileno as i64;
+ let json = serde_json::to_string(&e)?;
t.execute(
- "INSERT INTO files (fileno, path, kind, len) VALUES (?1, ?2, ?3, ?4)",
- params![fileno, path, kind, len],
+ "INSERT INTO files (fileno, json) VALUES (?1, ?2)",
+ params![fileno, &json],
)?;
for id in ids {
t.execute(