rust: a first connection to postgres
The first example of code I wrote is a basic connection to postgres. It is a nice exercise because it learns you how to interact with a config file, to handle errors, to import crates and to organize the file structure.
Here is my current structure:
.
├── .env
├── .gitignore
├── Cargo.lock
├── Cargo.toml
├── Settings.toml
├── docker-compose.yml
└── src
├── backend
│ ├── mod.rs
│ └── postgres.rs
└── main.rs
docker-compose.yml
: it only contains my postgres configuration
The first step of this project was to import some crates and to search and find crates corresponding to my needs. For that, I went to crates.io. This is the repository for all rust packages.
Cargo.toml
:
[package]
name = "note-sh"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
postgres = "0.19.1"
config = "0.11.0"
Currently, I have only two dependencies:
postgres
: a synchronous client for the PostgreSQL database (I will see later to use the asynchronous client tokio-postgres).config
: layered configuration system for Rust applications
My file looks like this:
use config::{Config,File};
mod backend;
fn main() {
let mut settings = Config::default();
// reads the config file called `Settings.toml`
settings.merge(File::with_name("Settings")).unwrap();
// makes the connection to the database
let conn = backend::postgres::connect(settings.get_str("postgres_url").unwrap().as_str());
// checks connection & error
match conn {
Ok(..) => println!("connected to the databse"),
Err(error) => panic!("{}", error),
};
}
For this little example, I wanted to understand how to call external file in main.rs
.
If we zoom in the src/
:
.
├── backend
│ ├── mod.rs
│ └── postgres.rs
└── main.rs
mod.rs
is a specific file used to define which parts of the code must be public (pub
) or not. see rust by example and Clear explanation of Rust's module system.
The backend/postgres.rs
is my simplest file at the moment since it only makes the connection and returns a postgres client.
use postgres::{Client, Error, NoTls};
// postgres structure that contains the client
pub struct Postgres {
// postgres client
client: Client,
}
// makes the connection to the postgres database with the given url
pub fn connect(url: &str) -> Result<Postgres, Error> {
let client = Client::connect(url, NoTls)?;
Ok(Postgres { client: client })
}
with its backend/mod.rs
:
// export postgres file
pub mod postgres;
And finally:
$ cargo run
Compiling note-sh v0.1.0 (/Users/myuser/workspace/src/github.com/fberrez/note-sh)
Finished dev [unoptimized + debuginfo] target(s) in 7.86s
Running `target/debug/note-sh test`
connected to the databse