Skip to content

Commit

Permalink
Add some documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
wichert committed Oct 2, 2023
1 parent 73b8c5c commit 1c75e43
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 1 deletion.
68 changes: 68 additions & 0 deletions src/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,39 @@ use std::string::String;
const MIN_SUPPORTED_VERSION: Version = (1, 10, 0);
const MAX_SUPPORTED_VERSION: Version = (1, 15, 0);

/// An object providing access to a PostgreSQL archive
///
/// `Archive` instances should be created using `Archive::parse`, which will parse
/// the file header and return an initialized `Archive` instance.
///
/// # Example
///
/// ```rust
/// use std::fs::File;
/// use pgarchive::Archive;
///
/// let mut file = File::open("tests/test.pgdump").unwrap();
/// match Archive::parse(&mut file) {
/// Ok(archive) => println!("This is a backup of {}", archive.database_name),
/// Err(e) => println!("can not read file: {:?}", e),
/// };
/// ```
#[derive(Debug, PartialEq)]
pub struct Archive {
/// Archive format version.
///
/// This is generally aligned with the PostgreSQL version, but only updated
/// when the file format changes.
pub version: Version,

/// Compression method used for data and blobs
pub compression_method: CompressionMethod,

/// Date when the archive was created
pub create_date: NaiveDateTime,

/// Name of the database that was dumped
pub database_name: String,

/// Version information for PostgreSQL server that pg_dump was accessing.
Expand Down Expand Up @@ -54,6 +78,10 @@ impl fmt::Display for Archive {
}

impl Archive {
/// Read and parse the archive header.
///
/// This function reads the archive header from a file-like object, and returns
/// a new `Archive` instance.
pub fn parse(f: &mut (impl io::Read + ?Sized)) -> Result<Archive, ArchiveError> {
let mut buffer = vec![0; 5];
f.read_exact(buffer.as_mut_slice())?;
Expand Down Expand Up @@ -132,12 +160,52 @@ impl Archive {
})
}

/// Find a TOC entry by name and section.
///
/// This function provides a simple method to find a TOC entry, so you
/// do not need to iterate over `toc_entries`.
///
/// ```rust
/// # use std::fs::File;
/// # use pgarchive::Archive;
///
/// # let mut file = File::open("tests/test.pgdump").unwrap();
/// # let archive = Archive::parse(&mut file).unwrap();
/// let employee_toc = archive.get_toc_entry(pgarchive::Section::Data, "employee");
/// ```
pub fn get_toc_entry(&self, section: Section, tag: &str) -> Option<&TocEntry> {
self.toc_entries
.iter()
.find(|e| e.section == section && e.tag == tag)
}

/// Access data for a TOC entry.
///
/// This function provides access to the data for a TOC entry. This is only
/// applicable to entries in the `Section::Data` section.
///
/// Decompression is automatically handled, so you can read the data directly
/// from the returned [`Read`](io::Read) instance.
///
/// # Example
///
/// ```rust
/// # use std::fs::File;
/// # use pgarchive::Archive;
///
/// # fn main() -> Result<(), pgarchive::ArchiveError> {
/// # let mut file = File::open("tests/test.pgdump").unwrap();
/// # let archive = Archive::parse(&mut file).unwrap();
/// let employee_toc = archive
/// .get_toc_entry(pgarchive::Section::Data, "pizza")
/// .expect("no data for pizza table present");
/// let mut data = archive.read_data(&mut file, &employee_toc)?;
/// let mut buffer = Vec::new();
/// let size = data.read_to_end(&mut buffer)?;
/// println!("the pizza table data has {} bytes of data", size);
/// # Ok(())
/// # }
/// ```
pub fn read_data(
&self,
f: &mut File,
Expand Down
19 changes: 18 additions & 1 deletion src/toc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,46 @@ use crate::io::ReadConfig;
use crate::types::{ArchiveError, Offset, Oid, Section};
use std::io::prelude::*;

/// Type used for object identifiers
pub type ID = i64;

/// Object containing the data for a TOC entry.
///
/// All data in an archive is specific in the [table of
/// contents](crate::archive::Archive::toc_entries). The TOC entry contains all
/// metadata, including the SQL statements to create and destroy database
/// elements.
#[derive(Debug, PartialEq)]
pub struct TocEntry {
pub id: ID,
pub had_dumper: bool,
pub table_oid: u64,
pub oid: u64,
pub oid: Oid,
pub tag: String,
pub desc: String,
pub section: Section,
/// SQL statement to create the database object or change a setting.
pub defn: String,
/// SQL statement to destroy the database object.
pub drop_stmt: String,
pub copy_stmt: String,
/// PostgreSQL schema in which the object is located
pub namespace: String,
pub tablespace: String,
pub table_access_method: String,
/// PostgreSQL user that owns the object.
pub owner: String,
/// List of TOC entries that must be created first.
pub dependencies: Vec<Oid>,
/// File offset where data or blob content is stored.
pub offset: Offset,
}

impl TocEntry {
/// Read and parse a TOC entry from a file.
///
/// This function is used by [`Archive::parse`](crate::archive::Archive::parse),
/// and should not ne called directly.
pub fn parse(f: &mut (impl Read + ?Sized), cfg: &ReadConfig) -> Result<TocEntry, ArchiveError> {
let id: ID = cfg.read_int(f)?;
if id < 0 {
Expand Down

0 comments on commit 1c75e43

Please sign in to comment.