Skip to content

Commit 96974bd

Browse files
tomproyukibtc
authored andcommitted
sqldb: init
This implements a basic driver for using Postgres, SQLite or MySQL as storage engine for nostr-database. Uses async Diesel as driver and Diesel migrations to set up the schema. Pull-Request: #835 Pull-Request: #855 Signed-off-by: Yuki Kishimoto <[email protected]>
1 parent 1ff0fc9 commit 96974bd

File tree

32 files changed

+2092
-252
lines changed

32 files changed

+2092
-252
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ members = [
88
"database/nostr-indexeddb",
99
"database/nostr-lmdb",
1010
"database/nostr-ndb",
11+
"database/nostr-sqldb",
1112

1213
# Gossip
1314
"gossip/nostr-gossip",

contrib/scripts/check-crates.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ buildargs=(
3939
"-p nostr-gossip-memory"
4040
"-p nostr-gossip-test-suite"
4141
"-p nostr-lmdb"
42+
"-p nostr-sqldb --no-default-features --features postgres" # PostgreSQL
43+
"-p nostr-sqldb --no-default-features --features mysql" # MySQL
44+
"-p nostr-sqldb --no-default-features --features sqlite" # SQLite
4245
"-p nostr-indexeddb --target wasm32-unknown-unknown"
4346
"-p nostr-ndb"
4447
"-p nostr-keyring"

database/nostr-sqldb/Cargo.toml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
[package]
2+
name = "nostr-sqldb"
3+
version = "0.42.0"
4+
edition = "2021"
5+
description = "SQL storage backend for Nostr apps"
6+
authors.workspace = true
7+
homepage.workspace = true
8+
repository.workspace = true
9+
license.workspace = true
10+
readme = "README.md"
11+
rust-version.workspace = true
12+
keywords = ["nostr", "database", "postgres", "mysql", "sqlite"]
13+
14+
[features]
15+
default = ["postgres"]
16+
postgres = [
17+
"diesel/postgres",
18+
"diesel-async/postgres",
19+
"diesel_migrations/postgres",
20+
]
21+
mysql = ["diesel/mysql", "diesel-async/mysql", "diesel_migrations/mysql"]
22+
sqlite = [
23+
"diesel/sqlite",
24+
"diesel-async/sqlite",
25+
"diesel_migrations/sqlite",
26+
"diesel/returning_clauses_for_sqlite_3_35",
27+
]
28+
29+
[dependencies]
30+
deadpool = { version = "0.12", features = ["managed", "rt_tokio_1"] }
31+
diesel = { version = "2.2", features = ["serde_json"] }
32+
diesel-async = { version = "0.5", features = ["deadpool"] }
33+
diesel_migrations = "2.2"
34+
nostr = { workspace = true, features = ["std"] }
35+
nostr-database = { workspace = true, features = ["flatbuf"] }
36+
tracing.workspace = true
37+
38+
[dev-dependencies]
39+
nostr-relay-builder.workspace = true
40+
tokio.workspace = true
41+
tracing-subscriber.workspace = true
42+
43+
[[example]]
44+
name = "postgres-relay"
45+
required-features = ["postgres"]

database/nostr-sqldb/README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Nostr SQL database backend
2+
3+
SQL storage backend for nostr apps working with Postgres, SQLite and MySQL.
4+
5+
## Crate Feature Flags
6+
7+
The following crate feature flags are available:
8+
9+
| Feature | Default | Description |
10+
|-------------|:-------:|-------------------------------|
11+
| `postgres` | Yes | Enable support for PostgreSQL |
12+
| `mysql` | No | Enable support for MySQL |
13+
| `sqlite` | No | Enable support for SQLite |
14+
15+
## State
16+
17+
**This library is in an ALPHA state**, things that are implemented generally work but the API will change in breaking ways.
18+
19+
## Donations
20+
21+
`rust-nostr` is free and open-source. This means we do not earn any revenue by selling it. Instead, we rely on your financial support. If you actively use any of the `rust-nostr` libs/software/services, then please [donate](https://rust-nostr.org/donate).
22+
23+
## License
24+
25+
This project is distributed under the MIT software license - see the [LICENSE](../../LICENSE) file for details
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright (c) 2025 Protom
2+
// Distributed under the MIT software license
3+
4+
use std::time::Duration;
5+
6+
use nostr_database::prelude::*;
7+
use nostr_relay_builder::prelude::*;
8+
use nostr_sqldb::NostrPostgres;
9+
10+
// Your database URL
11+
const DB_URL: &str = "postgres://postgres:password@localhost:5432";
12+
13+
#[tokio::main]
14+
async fn main() -> Result<()> {
15+
tracing_subscriber::fmt::init();
16+
17+
// Create a nostr db instance and run pending db migrations if any
18+
let db = NostrPostgres::new(DB_URL).await?;
19+
20+
// Add db to builder
21+
let builder = RelayBuilder::default().database(db);
22+
23+
// Create local relay
24+
let relay = LocalRelay::run(builder).await?;
25+
println!("Url: {}", relay.url());
26+
27+
// Keep up the program
28+
loop {
29+
tokio::time::sleep(Duration::from_secs(60)).await;
30+
}
31+
}

database/nostr-sqldb/migrations/.keep

Whitespace-only changes.

database/nostr-sqldb/migrations/mysql/.keep

Whitespace-only changes.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
-- This file should undo anything in `up.sql`
2+
DROP TABLE IF EXISTS event_tags;
3+
DROP TABLE IF EXISTS events;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
-- The actual event data
2+
CREATE TABLE IF NOT EXISTS events (
3+
id BLOB(32) PRIMARY KEY NOT NULL,
4+
pubkey BLOB(32) NOT NULL,
5+
created_at BIGINT NOT NULL,
6+
kind BIGINT NOT NULL,
7+
payload BLOB NOT NULL,
8+
deleted BOOLEAN NOT NULL
9+
);
10+
11+
-- Direct indexes
12+
CREATE INDEX event_pubkey ON events (pubkey);
13+
CREATE INDEX event_date ON events (created_at);
14+
CREATE INDEX event_kind ON events (kind);
15+
CREATE INDEX event_deleted ON events (deleted);
16+
17+
-- The tag index, the primary will give us the index automatically
18+
CREATE TABLE IF NOT EXISTS event_tags (
19+
tag VARCHAR(64) NOT NULL,
20+
tag_value VARCHAR(512) NOT NULL,
21+
event_id BLOB(32) NOT NULL
22+
REFERENCES events (id)
23+
ON DELETE CASCADE
24+
ON UPDATE CASCADE,
25+
PRIMARY KEY (tag, tag_value, event_id)
26+
);

0 commit comments

Comments
 (0)