Skip to content

Commit e0a65fd

Browse files
Merge pull request #110 from theseus-rs/initial-postgresql-extensions
feat!: initial postgresql_extensions crate
2 parents 9a4ee97 + 012a145 commit e0a65fd

File tree

50 files changed

+2442
-1105
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+2442
-1105
lines changed

Cargo.lock

Lines changed: 217 additions & 394 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ default-members = [
33
"postgresql_archive",
44
"postgresql_commands",
55
"postgresql_embedded",
6+
"postgresql_extensions",
67
]
78
members = [
89
"examples/*",
910
"postgresql_archive",
1011
"postgresql_commands",
1112
"postgresql_embedded",
13+
"postgresql_extensions",
1214
]
1315
resolver = "2"
1416

@@ -31,10 +33,10 @@ hex = "0.4.3"
3133
home = "0.5.9"
3234
http = "1.1.0"
3335
human_bytes = { version = "0.4.3", default-features = false }
34-
lazy_static = "1.5.0"
36+
indoc = "2.0.5"
3537
md-5 = "0.10.6"
3638
num-format = "0.4.4"
37-
quick-xml = "0.35.0"
39+
quick-xml = "0.36.1"
3840
rand = "0.8.5"
3941
regex = "1.10.5"
4042
reqwest = { version = "0.12.5", default-features = false }
@@ -43,21 +45,22 @@ reqwest-retry = "0.6.0"
4345
reqwest-tracing = "0.5.2"
4446
semver = "1.0.23"
4547
serde = "1.0.204"
46-
serde_json = "1.0.118"
48+
serde_json = "1.0.121"
4749
sha1 = "0.10.6"
4850
sha2 = "0.10.8"
4951
sha3 = "0.10.8"
50-
sqlx = { version = "0.7.4", default-features = false, features = ["postgres"] }
52+
sqlx = { version = "0.8.0", default-features = false, features = ["postgres"] }
5153
tar = "0.4.41"
5254
target-triple = "0.1.3"
5355
test-log = "0.2.16"
5456
tempfile = "3.10.1"
55-
thiserror = "1.0.62"
56-
tokio = "1.38.1"
57+
thiserror = "1.0.63"
58+
tokio = "1.39.2"
5759
tracing = "0.1.40"
60+
tracing-subscriber = "0.3.18"
5861
url = "2.5.2"
5962
xz2 = "0.1.7"
60-
zip = "2.1.3"
63+
zip = "2.1.6"
6164

6265
[workspace.metadata.release]
6366
shared-version = true

examples/postgres_embedded/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ version.workspace = true
77

88
[dependencies]
99
anyhow = { workspace = true }
10-
postgres = { version = "0.19.7" }
10+
postgres = { version = "0.19.8" }
1111
postgresql_embedded = { path = "../../postgresql_embedded", features = ["blocking"] }

examples/sqlx_embedded/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ version.workspace = true
88
[dependencies]
99
anyhow = { workspace = true }
1010
postgresql_embedded = { path = "../../postgresql_embedded" }
11-
sqlx = { version = "0.7.4", default-features = true, features = ["postgres", "runtime-tokio"] }
11+
sqlx = { workspace = true, features = ["runtime-tokio"] }
1212
tokio = { workspace = true, features = ["full"] }
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[package]
2+
edition.workspace = true
3+
name = "vector_extension"
4+
publish = false
5+
license.workspace = true
6+
version.workspace = true
7+
8+
[dependencies]
9+
anyhow = { workspace = true }
10+
indoc = { workspace = true }
11+
postgresql_extensions = { path = "../../postgresql_extensions" }
12+
postgresql_embedded = { path = "../../postgresql_embedded" }
13+
sqlx = { workspace = true, features = ["runtime-tokio"] }
14+
tracing = { workspace = true }
15+
tracing-subscriber = { workspace = true }
16+
tokio = { workspace = true, features = ["full"] }
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
#![forbid(unsafe_code)]
2+
#![deny(clippy::pedantic)]
3+
4+
use anyhow::Result;
5+
use indoc::indoc;
6+
use postgresql_embedded::{PostgreSQL, Settings, VersionReq};
7+
use sqlx::PgPool;
8+
use tracing::info;
9+
10+
/// Example of how to install and configure the vector extension.
11+
///
12+
/// See: <https://github.com/tensorchord/pgvecto.rs/?tab=readme-ov-file#quick-start>
13+
#[tokio::main]
14+
async fn main() -> Result<()> {
15+
tracing_subscriber::fmt().compact().init();
16+
17+
info!("Installing PostgreSQL");
18+
let settings = Settings {
19+
version: VersionReq::parse("=16.3.0")?,
20+
..Default::default()
21+
};
22+
let mut postgresql = PostgreSQL::new(settings);
23+
postgresql.setup().await?;
24+
25+
info!("Installing the vector extension from TensorChord");
26+
postgresql_extensions::install(
27+
postgresql.settings(),
28+
"tensor-chord",
29+
"pgvecto.rs",
30+
&VersionReq::parse("=0.3.0")?,
31+
)
32+
.await?;
33+
34+
info!("Starting PostgreSQL");
35+
postgresql.start().await?;
36+
37+
let database_name = "vector-example";
38+
info!("Creating database {database_name}");
39+
postgresql.create_database(database_name).await?;
40+
41+
info!("Configuring extension");
42+
let settings = postgresql.settings();
43+
let database_url = settings.url(database_name);
44+
let pool = PgPool::connect(database_url.as_str()).await?;
45+
configure_extension(&pool).await?;
46+
pool.close().await;
47+
48+
info!("Restarting database");
49+
postgresql.stop().await?;
50+
postgresql.start().await?;
51+
52+
info!("Enabling extension");
53+
let pool = PgPool::connect(database_url.as_str()).await?;
54+
enable_extension(&pool).await?;
55+
56+
info!("Creating table");
57+
create_table(&pool).await?;
58+
59+
info!("Creating data");
60+
create_data(&pool).await?;
61+
62+
info!("Stopping database");
63+
postgresql.stop().await?;
64+
Ok(())
65+
}
66+
67+
async fn configure_extension(pool: &PgPool) -> Result<()> {
68+
sqlx::query("ALTER SYSTEM SET shared_preload_libraries = \"vectors.so\"")
69+
.execute(pool)
70+
.await?;
71+
sqlx::query("ALTER SYSTEM SET search_path = \"$user\", public, vectors")
72+
.execute(pool)
73+
.await?;
74+
Ok(())
75+
}
76+
77+
async fn enable_extension(pool: &PgPool) -> Result<()> {
78+
sqlx::query("DROP EXTENSION IF EXISTS vectors")
79+
.execute(pool)
80+
.await?;
81+
sqlx::query("CREATE EXTENSION vectors")
82+
.execute(pool)
83+
.await?;
84+
Ok(())
85+
}
86+
87+
async fn create_table(pool: &PgPool) -> Result<()> {
88+
sqlx::query(indoc! {"
89+
CREATE TABLE IF NOT EXISTS items (
90+
id bigserial PRIMARY KEY,
91+
embedding vector(3) NOT NULL
92+
)
93+
"})
94+
.execute(pool)
95+
.await?;
96+
Ok(())
97+
}
98+
99+
async fn create_data(pool: &PgPool) -> Result<()> {
100+
sqlx::query(indoc! {"
101+
INSERT INTO items (embedding)
102+
VALUES
103+
('[1,2,3]'),
104+
('[4,5,6]')
105+
"})
106+
.execute(pool)
107+
.await?;
108+
sqlx::query(indoc! {"
109+
INSERT INTO items (embedding)
110+
VALUES
111+
(ARRAY[1, 2, 3]::real[]),
112+
(ARRAY[4, 5, 6]::real[]
113+
)
114+
"})
115+
.execute(pool)
116+
.await?;
117+
Ok(())
118+
}
119+
120+
#[cfg(target_os = "linux")]
121+
#[cfg(test)]
122+
mod test {
123+
use super::*;
124+
125+
#[test]
126+
fn test_main() -> Result<()> {
127+
main()
128+
}
129+
}

postgresql_archive/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ flate2 = { workspace = true, optional = true }
1616
hex = { workspace = true }
1717
http = { workspace = true }
1818
human_bytes = { workspace = true, default-features = false }
19-
lazy_static = { workspace = true }
2019
md-5 = { workspace = true, optional = true }
2120
num-format = { workspace = true }
2221
quick-xml = { workspace = true, features = ["serialize"], optional = true }

0 commit comments

Comments
 (0)