Skip to main content

DatabaseManager

Struct DatabaseManager 

Source
pub struct DatabaseManager { /* private fields */ }
Expand description

Main type that manages a database directory and its index.

Implementations§

Source§

impl DatabaseManager

Source

pub fn new( path: impl AsRef<Path>, name: impl AsRef<Path>, ) -> Result<Self, DatabaseError>

Creates a new database directory and returns a manager for it.

§Parameters
  • path: parent directory where the database folder will be created.
  • name: database directory name appended to path.
§Errors

Returns an error if:

  • the destination directory already exists,
  • parent directories are missing,
  • the process cannot create directories at the destination.
§Examples
use file_database::{DatabaseError, DatabaseManager};

fn main() -> Result<(), DatabaseError> {
    let _manager = DatabaseManager::new(".", "database")?;
    Ok(())
}
Source

pub fn write_new( &mut self, id: impl Into<ItemId>, parent: impl Into<ItemId>, ) -> Result<(), DatabaseError>

Creates a new file or directory under parent.

Name interpretation is extension-based:

  • if id.name has an extension, a file is created,
  • otherwise, a directory is created.
§Parameters
  • id: name key for the new item. Root ItemId is not allowed.
  • parent: destination parent item. Use ItemId::database_id() for database root.
§Errors

Returns an error if:

  • id is the ItemId::database_id(),
  • parent cannot be found,
  • another item already exists at the target relative path,
  • filesystem create operations fail.
§Examples
use file_database::{DatabaseError, DatabaseManager, ItemId};

fn main() -> Result<(), DatabaseError> {
    let mut manager = DatabaseManager::new(".", "database")?;
    manager.write_new(ItemId::id("notes.txt"), ItemId::database_id())?;
    Ok(())
}
Source

pub fn overwrite_existing<T>( &self, id: impl Into<ItemId>, data: T, ) -> Result<(), DatabaseError>
where T: AsRef<[u8]>,

Overwrites an existing file with raw bytes in a safe way.

It writes to a temp file first, then replaces the target file.

§Parameters
  • id: target file ItemId.
  • data: raw bytes to write.
§Errors

Returns an error if:

  • id cannot be found,
  • id points to a directory,
  • writing, syncing, or renaming fails.
§Examples
use file_database::{DatabaseError, DatabaseManager, ItemId};

fn main() -> Result<(), DatabaseError> {
    let mut manager = DatabaseManager::new(".", "database")?;
    manager.write_new(ItemId::id("blob.bin"), ItemId::database_id())?;
    manager.overwrite_existing(ItemId::id("blob.bin"), [1_u8, 2, 3, 4])?;
    Ok(())
}
Source

pub fn overwrite_existing_json<T: Serialize>( &self, id: impl Into<ItemId>, value: &T, ) -> Result<(), DatabaseError>

Converts value to JSON and overwrites the target file.

§Parameters
  • id: target file ItemId.
  • value: serializable value.
§Errors

Returns an error if:

  • JSON serialization fails,
  • finding id or overwriting the file fails.
§Examples
use file_database::{DatabaseError, DatabaseManager, ItemId};
use serde::Serialize;

#[derive(Serialize)]
struct Config {
    retries: u8,
}

fn main() -> Result<(), DatabaseError> {
    let mut manager = DatabaseManager::new(".", "database")?;
    manager.write_new(ItemId::id("config.json"), ItemId::database_id())?;
    manager.overwrite_existing_json(ItemId::id("config.json"), &Config { retries: 3 })?;
    Ok(())
}
Source

pub fn overwrite_existing_binary<T: Serialize>( &self, id: impl Into<ItemId>, value: &T, ) -> Result<(), DatabaseError>

Converts value to bincode and overwrites the target file.

§Parameters
  • id: target file ItemId.
  • value: serializable value.
§Errors

Returns an error if:

  • bincode serialization fails,
  • finding id or overwriting the file fails.
§Examples
use file_database::{DatabaseError, DatabaseManager, ItemId};
use serde::Serialize;

#[derive(Serialize)]
enum State {
    Ready,
}

fn main() -> Result<(), DatabaseError> {
    let mut manager = DatabaseManager::new(".", "database")?;
    manager.write_new(ItemId::id("state.bin"), ItemId::database_id())?;
    manager.overwrite_existing_binary(ItemId::id("state.bin"), &State::Ready)?;
    Ok(())
}
Source

pub fn overwrite_existing_from_reader<R: Read>( &self, id: impl Into<ItemId>, reader: &mut R, ) -> Result<u64, DatabaseError>

Streams bytes from reader into the target file and returns bytes written.

This uses chunked I/O and a safe replace step, so it works well for large payloads.

§Parameters
  • id: target file ItemId.
  • reader: source stream consumed until EOF.
§Errors

Returns an error if:

  • id cannot be found,
  • target is not a file,
  • stream read/write/sync/rename fails.
§Examples
use std::io::Cursor;
use file_database::{DatabaseError, DatabaseManager, ItemId};

fn main() -> Result<(), DatabaseError> {
    let mut manager = DatabaseManager::new(".", "database")?;
    manager.write_new(ItemId::id("stream.bin"), ItemId::database_id())?;
    let mut source = Cursor::new(vec![9_u8; 1024]);
    let _bytes = manager.overwrite_existing_from_reader(ItemId::id("stream.bin"), &mut source)?;
    Ok(())
}
Source

pub fn read_existing( &self, id: impl Into<ItemId>, ) -> Result<Vec<u8>, DatabaseError>

Reads a managed file and returns its raw bytes.

§Parameters
  • id: target file ItemId.
§Errors

Returns an error if:

  • id cannot be found,
  • id points to a directory,
  • file reading fails.
§Examples
use file_database::{DatabaseError, DatabaseManager, ItemId};

fn main() -> Result<(), DatabaseError> {
    let mut manager = DatabaseManager::new(".", "database")?;
    manager.write_new(ItemId::id("data.bin"), ItemId::database_id())?;
    manager.overwrite_existing(ItemId::id("data.bin"), [1_u8, 2, 3])?;
    let _data = manager.read_existing(ItemId::id("data.bin"))?;
    Ok(())
}
Source

pub fn read_existing_json<T: DeserializeOwned>( &self, id: impl Into<ItemId>, ) -> Result<T, DatabaseError>

Reads a managed file and turns JSON into T.

§Parameters
  • id: target file ItemId.
§Errors

Returns an error if:

  • finding id or reading the file fails,
  • JSON deserialization fails.
§Examples
use file_database::{DatabaseError, DatabaseManager, ItemId};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct Config {
    retries: u8,
}

fn main() -> Result<(), DatabaseError> {
    let mut manager = DatabaseManager::new(".", "database")?;
    manager.write_new(ItemId::id("config.json"), ItemId::database_id())?;
    manager.overwrite_existing_json(ItemId::id("config.json"), &Config { retries: 3 })?;
    let _loaded: Config = manager.read_existing_json(ItemId::id("config.json"))?;
    Ok(())
}
Source

pub fn read_existing_binary<T: DeserializeOwned>( &self, id: impl Into<ItemId>, ) -> Result<T, DatabaseError>

Reads a managed file and turns bincode into T.

§Parameters
  • id: target file ItemId.
§Errors

Returns an error if:

  • finding id or reading the file fails,
  • bincode deserialization fails.
§Examples
use file_database::{DatabaseError, DatabaseManager, ItemId};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
enum State {
    Ready,
}

fn main() -> Result<(), DatabaseError> {
    let mut manager = DatabaseManager::new(".", "database")?;
    manager.write_new(ItemId::id("state.bin"), ItemId::database_id())?;
    manager.overwrite_existing_binary(ItemId::id("state.bin"), &State::Ready)?;
    let _loaded: State = manager.read_existing_binary(ItemId::id("state.bin"))?;
    Ok(())
}
Source

pub fn get_all(&self, sorted: impl Into<bool>) -> Vec<ItemId>

Returns every tracked item in the database.

§Parameters
  • sorted: whether output should be sorted by ItemId ordering.
§Examples
use file_database::{DatabaseError, DatabaseManager, ItemId};

fn main() -> Result<(), DatabaseError> {
    let mut manager = DatabaseManager::new(".", "database")?;
    manager.write_new(ItemId::id("a.txt"), ItemId::database_id())?;
    let _all = manager.get_all(true);
    Ok(())
}
Source

pub fn get_by_parent( &self, parent: impl Into<ItemId>, sorted: impl Into<bool>, ) -> Result<Vec<ItemId>, DatabaseError>

Returns all tracked items that are direct children of parent.

If parent is the ItemId::database_id(), this returns all top-level items.

§Parameters
  • parent: parent directory item to query.
  • sorted: whether output should be sorted by ItemId.
§Errors

Returns an error if:

  • parent cannot be found,
  • parent points to a file instead of a directory.
§Examples
use file_database::{DatabaseError, DatabaseManager, ItemId};

fn main() -> Result<(), DatabaseError> {
    let mut manager = DatabaseManager::new(".", "database")?;
    manager.write_new(ItemId::id("folder"), ItemId::database_id())?;
    manager.write_new(ItemId::id("a.txt"), ItemId::id("folder"))?;
    let _children = manager.get_by_parent(ItemId::id("folder"), true)?;
    Ok(())
}
Source

pub fn get_parent(&self, id: impl Into<ItemId>) -> Result<ItemId, DatabaseError>

Returns the parent ItemId for an item.

Top-level items return ItemId::database_id.

§Parameters
  • id: item whose parent should be looked up.
§Errors

Returns an error if:

  • id cannot be found,
  • parent path data cannot be converted to UTF-8 string.
§Examples
use file_database::{DatabaseError, DatabaseManager, ItemId};

fn main() -> Result<(), DatabaseError> {
    let mut manager = DatabaseManager::new(".", "database")?;
    manager.write_new(ItemId::id("folder"), ItemId::database_id())?;
    manager.write_new(ItemId::id("a.txt"), ItemId::id("folder"))?;
    let _parent = manager.get_parent(ItemId::id("a.txt"))?;
    Ok(())
}
Source

pub fn rename( &mut self, id: impl Into<ItemId>, to: impl AsRef<str>, ) -> Result<(), DatabaseError>

Renames the chosen item to to in the same parent directory.

§Parameters
  • id: source ItemId to rename.
  • to: new file or directory name.
§Errors

Returns an error if:

  • id is the ItemId::database_id(),
  • id cannot be found,
  • id.index is out of range for the list of paths under this name,
  • destination name already exists at the same relative path,
  • underlying filesystem rename fails.
§Examples
use file_database::{DatabaseError, DatabaseManager, ItemId};

fn main() -> Result<(), DatabaseError> {
    let mut manager = DatabaseManager::new(".", "database")?;
    manager.write_new(ItemId::id("old.txt"), ItemId::database_id())?;
    manager.rename(ItemId::id("old.txt"), "new.txt")?;
    Ok(())
}
Source

pub fn delete( &mut self, id: impl Into<ItemId>, force: impl Into<bool>, ) -> Result<(), DatabaseError>

Deletes a file, directory, or the whole database root.

§Parameters
  • id: item to delete. Use ItemId::database_id() to target the database folder itself.
  • force: when deleting directories, controls recursive vs empty-only behavior.
§Errors

Returns an error if:

  • id cannot be found,
  • id.index is out of range for the list of paths under this name,
  • directory deletion does not match force rules,
  • filesystem delete operations fail.
§Examples
use file_database::{DatabaseError, DatabaseManager, ForceDeletion, ItemId};

fn main() -> Result<(), DatabaseError> {
    let mut manager = DatabaseManager::new(".", "database")?;
    manager.write_new(ItemId::id("tmp.txt"), ItemId::database_id())?;
    manager.delete(ItemId::id("tmp.txt"), ForceDeletion::Force)?;
    Ok(())
}
Source

pub fn locate_absolute( &self, id: impl Into<ItemId>, ) -> Result<PathBuf, DatabaseError>

Gets the absolute file path for an ItemId.

For the ItemId::database_id(), this returns the database directory path.

§Parameters
  • id: ItemId to look up.
§Errors

Returns an error if:

  • id.name does not exist,
  • id.index is out of bounds.
§Examples
use file_database::{DatabaseError, DatabaseManager, ItemId};

fn main() -> Result<(), DatabaseError> {
    let mut manager = DatabaseManager::new(".", "database")?;
    manager.write_new(ItemId::id("a.txt"), ItemId::database_id())?;
    let _path = manager.locate_absolute(ItemId::id("a.txt"))?;
    Ok(())
}
Source

pub fn locate_relative( &self, id: impl Into<ItemId>, ) -> Result<&PathBuf, DatabaseError>

Gets the stored relative path reference for an ItemId.

For the ItemId::database_id(), this currently returns a reference to the manager root path.

§Parameters
  • id: ItemId to look up.
§Errors

Returns an error if:

  • id.name does not exist,
  • id.index is out of bounds.
§Examples
use file_database::{DatabaseError, DatabaseManager, ItemId};

fn main() -> Result<(), DatabaseError> {
    let mut manager = DatabaseManager::new(".", "database")?;
    manager.write_new(ItemId::id("a.txt"), ItemId::database_id())?;
    let _relative = manager.locate_relative(ItemId::id("a.txt"))?;
    Ok(())
}
Source

pub fn get_paths_for_id( &self, id: impl Into<ItemId>, ) -> Result<&Vec<PathBuf>, DatabaseError>

Returns all stored relative paths for a shared name.

§Parameters
  • id: shared-name ItemId. index is ignored for lookup.
§Errors

Returns an error if:

  • id is the ItemId::database_id(),
  • no entry exists for id.name.
§Examples
use file_database::{DatabaseError, DatabaseManager, ItemId};

fn main() -> Result<(), DatabaseError> {
    let mut manager = DatabaseManager::new(".", "database")?;
    manager.write_new(ItemId::id("a.txt"), ItemId::database_id())?;
    let _paths = manager.get_paths_for_id(ItemId::id("a.txt"))?;
    Ok(())
}
Source

pub fn get_ids_from_shared_id( &self, id: impl Into<ItemId>, ) -> Result<Vec<ItemId>, DatabaseError>

Returns all specific ItemId values for a shared name.

§Parameters
  • id: shared-name ItemId. index is ignored for lookup.
§Errors

Returns an error if:

  • ItemId::database_id() is provided,
  • no entry exists for id.name.
§Examples
use file_database::{DatabaseError, DatabaseManager, ItemId};

fn main() -> Result<(), DatabaseError> {
    let mut manager = DatabaseManager::new(".", "database")?;
    manager.write_new(ItemId::id("a.txt"), ItemId::database_id())?;
    let _ids = manager.get_ids_from_shared_id(ItemId::id("a.txt"))?;
    Ok(())
}
Source

pub fn scan_for_changes( &mut self, scan_from: impl Into<ItemId>, policy: ScanPolicy, recursive: bool, ) -> Result<ScanReport, DatabaseError>

Scans files on disk and compares them to entries in this scan area.

Missing tracked items are always removed from the items index kept in memory.

Policy behavior for newly discovered external items:

  • DetectOnly: report only.
  • AddNew: report and add to the index.
  • RemoveNew: report and delete from disk.
§Parameters
  • scan_from: root ItemId to scan from (ItemId::database_id() scans the full database).
  • policy: change handling policy.
  • recursive: true scans full subtree, false scans immediate children only.
§Errors

Returns an error if:

  • scan_from cannot be found,
  • scan_from points to a file,
  • path-to-string conversion fails for discovered entries,
  • filesystem read or delete operations fail.
§Examples
use file_database::{DatabaseError, DatabaseManager, ItemId, ScanPolicy};

fn main() -> Result<(), DatabaseError> {
    let mut manager = DatabaseManager::new(".", "database")?;
    let _report = manager.scan_for_changes(ItemId::database_id(), ScanPolicy::AddNew, true)?;
    Ok(())
}
Source

pub fn migrate_database( &mut self, to: impl AsRef<Path>, ) -> Result<(), DatabaseError>

Moves the entire database directory to a new parent directory.

Existing destination database directory with the same name is removed first.

§Parameters
  • to: destination parent directory.
§Errors

Returns an error if:

  • current database path is invalid,
  • destination cleanup fails,
  • recursive copy or source removal fails.
§Examples
use file_database::{DatabaseError, DatabaseManager};

fn main() -> Result<(), DatabaseError> {
    let mut manager = DatabaseManager::new(".", "database")?;
    manager.migrate_database("./new_parent")?;
    Ok(())
}
Source

pub fn migrate_item( &mut self, id: impl Into<ItemId>, to: impl Into<ItemId>, ) -> Result<(), DatabaseError>

Moves a managed item to another directory inside the same database.

§Parameters
  • id: source item to move.
  • to: destination directory item (or ItemId::database_id()).
§Errors

Returns an error if:

  • id is root or cannot be found,
  • destination is not a directory,
  • source and destination are identical,
  • id.index is out of bounds for the source name vector,
  • filesystem move fails.
§Examples
use file_database::{DatabaseError, DatabaseManager, ItemId};

fn main() -> Result<(), DatabaseError> {
    let mut manager = DatabaseManager::new(".", "database")?;
    manager.write_new(ItemId::id("folder"), ItemId::database_id())?;
    manager.write_new(ItemId::id("a.txt"), ItemId::database_id())?;
    manager.migrate_item(ItemId::id("a.txt"), ItemId::id("folder"))?;
    Ok(())
}
Source

pub fn export_item( &mut self, id: impl Into<ItemId>, to: impl AsRef<Path>, mode: ExportMode, ) -> Result<(), DatabaseError>

Exports a managed file or directory to an external destination directory.

Copy keeps the item in the index. Move removes the moved entry from the index.

§Parameters
  • id: source item to export.
  • to: external destination directory path.
  • mode: copy or move behavior.
§Errors

Returns an error if:

  • id is root or cannot be found,
  • destination is inside the database,
  • destination path cannot be created or used as a directory,
  • id.index is out of bounds when removing moved entries,
  • filesystem copy/move operations fail.
§Examples
use file_database::{DatabaseError, DatabaseManager, ExportMode, ItemId};

fn main() -> Result<(), DatabaseError> {
    let mut manager = DatabaseManager::new(".", "database")?;
    manager.write_new(ItemId::id("a.txt"), ItemId::database_id())?;
    manager.export_item(ItemId::id("a.txt"), "./exports", ExportMode::Copy)?;
    Ok(())
}
Source

pub fn import_item( &mut self, from: impl AsRef<Path>, to: impl Into<ItemId>, ) -> Result<(), DatabaseError>

Imports an external file or directory into a database destination directory.

The imported item keeps its original name.

§Parameters
  • from: source path outside the database.
  • to: destination directory item in the database.
§Errors

Returns an error if:

  • source path points inside the database,
  • destination is not a directory,
  • destination path/name already exists,
  • source does not exist as file or directory,
  • filesystem copy operations fail.
§Examples
use file_database::{DatabaseError, DatabaseManager, ItemId};

fn main() -> Result<(), DatabaseError> {
    let mut manager = DatabaseManager::new(".", "database")?;
    manager.write_new(ItemId::id("imports"), ItemId::database_id())?;
    manager.import_item("./outside/example.txt", ItemId::id("imports"))?;
    Ok(())
}
Source

pub fn duplicate_item( &mut self, id: impl Into<ItemId>, parent: impl Into<ItemId>, name: impl AsRef<str>, ) -> Result<(), DatabaseError>

Duplicates a managed item into parent using a caller-provided name.

§Parameters
  • id: source item to duplicate.
  • parent: destination parent directory item (or ItemId::database_id()).
  • name: new name for the duplicate.
§Errors

Returns an error if:

  • id is root or cannot be found,
  • destination parent is not a directory,
  • destination name already exists in the target directory,
  • filesystem copy fails.
§Examples
use file_database::{DatabaseError, DatabaseManager, ItemId};

fn main() -> Result<(), DatabaseError> {
    let mut manager = DatabaseManager::new(".", "database")?;
    manager.write_new(ItemId::id("a.txt"), ItemId::database_id())?;
    manager.duplicate_item(ItemId::id("a.txt"), ItemId::database_id(), "copy.txt")?;
    Ok(())
}
Source

pub fn get_file_information( &self, id: impl Into<ItemId>, ) -> Result<FileInformation, DatabaseError>

Returns filesystem metadata summary for a managed file or directory.

Includes:

  • name/extension,
  • normalized size,
  • Unix timestamps and “time since” timestamps where available.
§Parameters
  • id: item to inspect.
§Errors

Returns an error if:

  • id cannot be found,
  • metadata lookup fails.
§Examples
use file_database::{DatabaseError, DatabaseManager, ItemId};

fn main() -> Result<(), DatabaseError> {
    let mut manager = DatabaseManager::new(".", "database")?;
    manager.write_new(ItemId::id("a.txt"), ItemId::database_id())?;
    let _info = manager.get_file_information(ItemId::id("a.txt"))?;
    Ok(())
}

Trait Implementations§

Source§

impl Debug for DatabaseManager

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for DatabaseManager

Source§

fn eq(&self, other: &DatabaseManager) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl StructuralPartialEq for DatabaseManager

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.