mirror of
https://github.com/neondatabase/neon.git
synced 2026-05-20 06:30:43 +00:00
Add library
This commit is contained in:
8
Cargo.lock
generated
8
Cargo.lock
generated
@@ -1414,6 +1414,7 @@ name = "integration_tests"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"pg_bin",
|
||||
"tokio",
|
||||
"tokio-postgres",
|
||||
"utils",
|
||||
@@ -1988,6 +1989,13 @@ dependencies = [
|
||||
"indexmap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pg_bin"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"tokio-postgres",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.10.1"
|
||||
|
||||
@@ -7,6 +7,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
utils = { path = "../libs/utils" }
|
||||
pg_bin = { path = "../libs/pg_bin" }
|
||||
tokio-postgres = { git = "https://github.com/zenithdb/rust-postgres.git", rev="d052ee8b86fff9897c77b0fe89ea9daba0e1fa38" }
|
||||
tokio = { version = "1.17", features = ["macros", "rt", "rt-multi-thread"] }
|
||||
anyhow = "1.0.62"
|
||||
|
||||
@@ -1,91 +1,10 @@
|
||||
use std::{fs::{File, remove_dir_all}, path::PathBuf, process::{Child, Command, Stdio}, time::Duration};
|
||||
use std::io::Write;
|
||||
|
||||
pub trait PgProtocol {
|
||||
fn conn_info(&self) -> tokio_postgres::Config;
|
||||
}
|
||||
|
||||
type Port = u16;
|
||||
|
||||
pub struct LocalPostgres {
|
||||
datadir: PathBuf,
|
||||
pg_prefix: PathBuf,
|
||||
port: Port,
|
||||
running: Option<Child>,
|
||||
}
|
||||
|
||||
impl LocalPostgres {
|
||||
fn new(datadir: PathBuf, pg_prefix: PathBuf) -> Self {
|
||||
LocalPostgres {
|
||||
datadir,
|
||||
pg_prefix,
|
||||
port: 54729,
|
||||
running: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn start(&mut self) {
|
||||
remove_dir_all(self.datadir.as_os_str()).ok();
|
||||
|
||||
let status = Command::new(self.pg_prefix.join("initdb"))
|
||||
.arg("-D")
|
||||
.arg(self.datadir.as_os_str())
|
||||
.stdout(Stdio::null()) // TODO to file instead
|
||||
.stderr(Stdio::null()) // TODO to file instead
|
||||
.status()
|
||||
.expect("failed to get status");
|
||||
assert!(status.success());
|
||||
|
||||
// Write conf
|
||||
let mut conf = File::create(self.datadir.join("postgresql.conf"))
|
||||
.expect("failed to create file");
|
||||
writeln!(&mut conf, "port = {}", self.port)
|
||||
.expect("failed to write conf");
|
||||
|
||||
let out_file = File::create(self.datadir.join("pg.log")).expect("can't make file");
|
||||
let err_file = File::create(self.datadir.join("pg.err")).expect("can't make file");
|
||||
self.running.replace(Command::new(self.pg_prefix.join("postgres"))
|
||||
.env("PGDATA", self.datadir.as_os_str())
|
||||
.stdout(Stdio::from(out_file))
|
||||
.stderr(Stdio::from(err_file))
|
||||
.spawn()
|
||||
.expect("postgres failed to spawn"));
|
||||
|
||||
std::thread::sleep(Duration::from_millis(300));
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for LocalPostgres {
|
||||
fn drop(&mut self) {
|
||||
if let Some(mut child) = self.running.take() {
|
||||
child.kill().expect("failed to kill child");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PgProtocol for LocalPostgres {
|
||||
fn conn_info(&self) -> tokio_postgres::Config {
|
||||
// I don't like this, but idk what else to do
|
||||
let whoami = Command::new("whoami").output().unwrap().stdout;
|
||||
let user = String::from_utf8_lossy(&whoami);
|
||||
let user = user.trim();
|
||||
|
||||
let mut config = tokio_postgres::Config::new();
|
||||
config
|
||||
.host("127.0.0.1")
|
||||
.port(self.port)
|
||||
.dbname("postgres")
|
||||
.user(&user);
|
||||
config
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use tokio_postgres::NoTls;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use super::*;
|
||||
use tokio_postgres::NoTls;
|
||||
use pg_bin::LocalPostgres;
|
||||
use pg_bin::PgProtocol;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_postgres_select_1() -> anyhow::Result<()> {
|
||||
|
||||
9
libs/pg_bin/Cargo.toml
Normal file
9
libs/pg_bin/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "pg_bin"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
tokio-postgres = { git = "https://github.com/zenithdb/rust-postgres.git", rev="d052ee8b86fff9897c77b0fe89ea9daba0e1fa38" }
|
||||
84
libs/pg_bin/src/lib.rs
Normal file
84
libs/pg_bin/src/lib.rs
Normal file
@@ -0,0 +1,84 @@
|
||||
//! Utils for runnig postgres binaries as subprocesses.
|
||||
use std::{fs::{File, remove_dir_all}, path::PathBuf, process::{Child, Command, Stdio}, time::Duration};
|
||||
use std::io::Write;
|
||||
|
||||
// TODO put these in a different mod
|
||||
type Port = u16;
|
||||
pub trait PgProtocol {
|
||||
fn conn_info(&self) -> tokio_postgres::Config;
|
||||
}
|
||||
|
||||
pub struct LocalPostgres {
|
||||
datadir: PathBuf,
|
||||
pg_prefix: PathBuf,
|
||||
port: Port,
|
||||
running: Option<Child>,
|
||||
}
|
||||
|
||||
impl LocalPostgres {
|
||||
pub fn new(datadir: PathBuf, pg_prefix: PathBuf) -> Self {
|
||||
LocalPostgres {
|
||||
datadir,
|
||||
pg_prefix,
|
||||
port: 54729,
|
||||
running: None,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO is this the right interface? Why not start it?
|
||||
pub fn start(&mut self) {
|
||||
remove_dir_all(self.datadir.as_os_str()).ok();
|
||||
|
||||
let status = Command::new(self.pg_prefix.join("initdb"))
|
||||
.arg("-D")
|
||||
.arg(self.datadir.as_os_str())
|
||||
.stdout(Stdio::null()) // TODO to file instead
|
||||
.stderr(Stdio::null()) // TODO to file instead
|
||||
.status()
|
||||
.expect("failed to get status");
|
||||
assert!(status.success());
|
||||
|
||||
// Write conf
|
||||
let mut conf = File::create(self.datadir.join("postgresql.conf"))
|
||||
.expect("failed to create file");
|
||||
writeln!(&mut conf, "port = {}", self.port)
|
||||
.expect("failed to write conf");
|
||||
|
||||
// TODO check if already running
|
||||
let out_file = File::create(self.datadir.join("pg.log")).expect("can't make file");
|
||||
let err_file = File::create(self.datadir.join("pg.err")).expect("can't make file");
|
||||
self.running.replace(Command::new(self.pg_prefix.join("postgres"))
|
||||
.env("PGDATA", self.datadir.as_os_str())
|
||||
.stdout(Stdio::from(out_file))
|
||||
.stderr(Stdio::from(err_file))
|
||||
.spawn()
|
||||
.expect("postgres failed to spawn"));
|
||||
|
||||
std::thread::sleep(Duration::from_millis(300));
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for LocalPostgres {
|
||||
fn drop(&mut self) {
|
||||
if let Some(mut child) = self.running.take() {
|
||||
child.kill().expect("failed to kill child");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PgProtocol for LocalPostgres {
|
||||
fn conn_info(&self) -> tokio_postgres::Config {
|
||||
// I don't like this, but idk what else to do
|
||||
let whoami = Command::new("whoami").output().unwrap().stdout;
|
||||
let user = String::from_utf8_lossy(&whoami);
|
||||
let user = user.trim();
|
||||
|
||||
let mut config = tokio_postgres::Config::new();
|
||||
config
|
||||
.host("127.0.0.1")
|
||||
.port(self.port)
|
||||
.dbname("postgres")
|
||||
.user(&user);
|
||||
config
|
||||
}
|
||||
}
|
||||
0
libs/utils/src/pg_bin.rs
Normal file
0
libs/utils/src/pg_bin.rs
Normal file
Reference in New Issue
Block a user