Supported PostgreSQL binary repositories
mainpostgresql_archive provides implementations for downloading binaries from the following sources:
repository·main·Indexed 18 days ago
https://github.com/theseus-rs/postgresql-embeddedA Rust library that allows developers to install and run a PostgreSQL database locally on Linux, MacOS, or Windows. It manages the downloading, installation, and lifecycle of a PostgreSQL process, providing an experience similar to SQLite. The project includes crates for downloading archives (postgresql_archive), executing command line utilities (postgresql_commands), managing extensions (postgresql_extensions), and bundling the database directly into application binaries.
postgresql_archive provides implementations for downloading binaries from the following sources:
PostgreSQL binaries are downloaded either at build time (if bundled is enabled) or at runtime.
Rate Limiting: You can set the GITHUB_TOKEN environment variable to a GitHub personal access token to increase download rate limits.
Cache Locations:
$HOME/.theseus/postgresql%USERPROFILE%\.theseus\postgresqlPerformance Tip: Specifying an exact version (e.g., =16.4.0) via POSTGRESQL_VERSION or in Settings improves performance by avoiding version match queries after the initial download.
To include the PostgreSQL installation archive directly within your application executable, enable the bundled feature.
POSTGRESQL_VERSION environment variable to a specific version (e.g., =17.2.0) to determine which archive to download and include.Settings object using VersionReq to ensure the runtime uses the bundled version.If POSTGRESQL_VERSION is not set during build, postgresql_archive::LATEST is used.
To use a custom GitHub source for releases, set the POSTGRESQL_RELEASES_URL environment variable. The repository must follow the structure used by theseus-rs/postgresql_binaries.
use postgresql_embedded::{Result, Settings, VersionReq};
use std::str::FromStr;
#[tokio::main]
async fn main() -> Result<()> {
let settings = Settings {
version: VersionReq::from_str("=17.2.0")?,
..Default::default()
};
// Use settings with PostgreSQL::new(settings)
Ok(())
}If you prefer a blocking API, use postgresql_embedded::blocking::PostgreSQL. This provides a synchronous interface for setup, starting, and managing the database instance.
Note: This requires the blocking feature to be enabled.
use postgresql_embedded::Result;
use postgresql_embedded::blocking::PostgreSQL;
fn main() -> Result<()> {
let mut postgresql = PostgreSQL::default();
postgresql.setup()?;
postgresql.start()?;
let database_name = "test";
postgresql.create_database(database_name)?;
postgresql.database_exists(database_name)?;
postgresql.drop_database(database_name)?;
postgresql.stop()
}The asynchronous API allows you to manage a PostgreSQL instance using tokio. You can initialize a PostgreSQL instance with default settings, set it up, start the process, and perform database operations like creating or dropping databases.
Note: This requires the tokio feature to be enabled.
use postgresql_embedded::{PostgreSQL, Result};
#[tokio::main]
async fn main() -> Result<()> {
let mut postgresql = PostgreSQL::default();
postgresql.setup().await?;
postgresql.start().await?;
let database_name = "test";
postgresql.create_database(database_name).await?;
postgresql.database_exists(database_name).await?;
postgresql.drop_database(database_name).await?;
postgresql.stop().await
}To use postgresql_embedded, you can initialize a PostgreSQL instance, set it up, and start the database process. The library supports both async and blocking APIs. By default, it downloads and installs PostgreSQL during runtime, but you can also enable a bundled feature to include the PostgreSQL archive directly in your binary at compile time.
Key capabilities include:
native-tls or rustls (with AWS-LC or Ring).use postgresql_embedded::{PostgreSQL, Result};
#[tokio::main]
async fn main() -> Result<()> {
let mut postgresql = PostgreSQL::default();
postgresql.setup().await?;
postgresql.start().await?;
let database_name = "test";
postgresql.create_database(database_name).await?;
postgresql.database_exists(database_name).await?;
postgresql.drop_database(database_name).await?;
postgresql.stop().await
}native-tls or rustls with AWS-LC or Ring).The library uses feature flags to manage binary size and compile-time dependencies.
tls-native-tls (Default): Enables Native TLS support.tls-rustls-aws-lc-rs: Enables Rustls with the AWS-LC crypto provider.tls-rustls-ring: Enables Rustls with the Ring crypto provider. To use Ring without compiling AWS-LC, disable default features and enable tls-rustls-ring.These flags enable specific sets of PostgreSQL extensions:
portal-corp (Default): Enables PortalCorp PostgreSQL extensions.steampipe (Default): Enables Steampipe PostgreSQL extensions.tensor-chord (Default): Enables TensorChord PostgreSQL extensions.Use the SettingsBuilder to fluently construct a Settings object for your embedded PostgreSQL instance. This is the recommended way to customize connection details, installation paths, and server configurations.
Commonly configured fields include:
host and port: TCP connection details.username and password: Database credentials.temporary: If true (default), the database is cleaned up on drop.configuration: A map of server configuration options (e.g., max_connections).socket_dir: Sets a Unix socket directory (Unix-only).use postgresql_embedded::SettingsBuilder;
use std::path::PathBuf;
let settings = SettingsBuilder::new()
.host("127.0.0.1")
.port(5433)
.username("admin")
.password("secret")
.temporary(false)
.build();
// To configure a Unix socket:
let socket_settings = SettingsBuilder::new()
.socket_dir(PathBuf::from("/tmp/pg_socket"))
.build();The PostgreSQL struct is the primary entrypoint for managing an embedded PostgreSQL instance. It handles the full lifecycle of the database: installation from archives, initialization of the data directory, starting the server, and stopping it.
setup(): A high-level method that ensures the server is installed (extracting archives if necessary) and initialized (creating the data directory and configuration files).start(): Starts the PostgreSQL server. If the port is set to 0, it will bind to a random available port.stop(): Gracefully stops the server using pg_ctl in Fast shutdown mode.drop(): Automatically stops the server if it is running. If the temporary setting is enabled, it also deletes the data directory, password file, and socket directory.You can manage individual databases within the embedded instance using these methods:
create_database(name): Creates a new database.database_exists(name): Checks if a database exists.drop_database(name): Drops a database if it exists.Note: Database operations use a connection pool to the bootstrap database (the default superuser database) to execute commands.
```rust
use postgresql_embedded::Settings;
use postgresql_embedded::PostgreSQL;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let settings = Settings::default();
let mut pg = PostgreSQL::new(settings);
// 1. Install and initialize
pg.setup().await?;
// 2. Start the server
pg.start().await?;
// 3. Perform database operations
pg.create_database("my_app_db").await?;
if pg.database_exists("my_app_db").await? {
println!("Database is ready!");
}
// 4. Stop the server
pg.stop().await?;
Ok(())
}
```埋Use PsqlBuilder from postgresql_commands::psql to construct and execute PostgreSQL command line utility calls. You can configure the command string, host, port, username, and password using a builder pattern. The execute() method returns a tuple containing stdout and stderr as strings.
use postgresql_commands::Result;
use postgresql_commands::psql::PsqlBuilder;
fn main() -> Result<()> {
let psql = PsqlBuilder::new()
.command("CREATE DATABASE \"test\"")
.host("127.0.0.1")
.port(5432)
.username("postgresql")
.pg_password("password")
.build();
let (stdout, stderr) = psql.execute()?;
Ok(())
}The postgresql_archive crate provides an asynchronous API for fetching and extracting PostgreSQL binaries. You can use get_archive to retrieve a specific archive version based on a VersionReq and extract to unpack it into a target directory.
To use this API, ensure you have an async runtime like tokio available.
use postgresql_archive::{extract, get_archive, Result, VersionReq};
use postgresql_archive::configuration::theseus;
#[tokio::main]
async fn main() -> Result<()> {
let url = theseus::URL;
let (archive_version, archive) = get_archive(url, &VersionReq::STAR).await?;
let out_dir = std::env::temp_dir();
extract(url, &archive, &out_dir).await
}