This commit is contained in:
K Simmons 2022-10-13 15:43:42 -07:00
parent 318b923bac
commit dbc03e2668
5 changed files with 53 additions and 7717 deletions

7675
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -15,7 +15,7 @@ collections = { path = "../collections" }
anyhow = "1.0.57"
async-trait = "0.1"
parking_lot = "0.11.1"
rocksdb = "0.18"
sqlx = { version = "0.6.2", features = ["sqlite", "macros", "offline", "json", "runtime-async-std-rustls"] }
[dev-dependencies]
gpui = { path = "../gpui", features = ["test-support"] }

View File

@ -0,0 +1,4 @@
CREATE TABLE kv_store(
key TEXT NOT NULL,
value TEXT NOT NULL
) STRICT;

View File

@ -1,24 +1,50 @@
use anyhow::Result;
use sqlx::sqlite::{SqliteConnectOptions, SqlitePoolOptions};
use sqlx::{Pool, Sqlite, SqlitePool};
use std::path::Path;
use std::str::FromStr;
use std::sync::Arc;
pub struct Db(DbStore);
enum DbStore {
Null,
Real(rocksdb::DB),
#[cfg(any(test, feature = "test-support"))]
Fake {
data: parking_lot::Mutex<collections::HashMap<Vec<u8>, Vec<u8>>>,
},
Live(Pool<Sqlite>),
}
// Things we need to think about:
// Concurrency? - Needs some research
// We need to configure or setup our database, create the tables and such
// Write our first migration
//
// To make a migration:
// Add to the migrations directory, a file with the name:
// <NUMBER>_<DESCRIPTION>.sql. Migrations are executed in order of number
impl Db {
/// Open or create a database at the given file path.
pub fn open(path: &Path) -> Result<Arc<Self>> {
let db = rocksdb::DB::open_default(path)?;
Ok(Arc::new(Self(DbStore::Real(db))))
let options = SqliteConnectOptions::from_str(path)?.create_if_missing(true);
Self::initialize(options)
}
/// Open a fake database for testing.
#[cfg(any(test, feature = "test-support"))]
pub fn open_fake() -> Arc<Self> {
let options = SqliteConnectOptions::from_str(":memory:")?;
Self::initialize(options)
}
fn initialize(options: SqliteConnectOptions) -> Result<Arc<Self>> {
let pool = Pool::<Sqlite>::connect_with(options)?;
sqlx::migrate!().run(&pool).await?;
Ok(Arc::new(Self(DbStore::Live(pool))))
}
/// Open a null database that stores no data, for use as a fallback
@ -27,14 +53,6 @@ impl Db {
Arc::new(Self(DbStore::Null))
}
/// Open a fake database for testing.
#[cfg(any(test, feature = "test-support"))]
pub fn open_fake() -> Arc<Self> {
Arc::new(Self(DbStore::Fake {
data: Default::default(),
}))
}
pub fn read<K, I>(&self, keys: I) -> Result<Vec<Option<Vec<u8>>>>
where
K: AsRef<[u8]>,
@ -48,15 +66,6 @@ impl Db {
.collect(),
DbStore::Null => Ok(keys.into_iter().map(|_| None).collect()),
#[cfg(any(test, feature = "test-support"))]
DbStore::Fake { data: db } => {
let db = db.lock();
Ok(keys
.into_iter()
.map(|key| db.get(key.as_ref()).cloned())
.collect())
}
}
}
@ -75,14 +84,6 @@ impl Db {
}
DbStore::Null => {}
#[cfg(any(test, feature = "test-support"))]
DbStore::Fake { data: db } => {
let mut db = db.lock();
for key in keys {
db.remove(key.as_ref());
}
}
}
Ok(())
}
@ -103,14 +104,6 @@ impl Db {
}
DbStore::Null => {}
#[cfg(any(test, feature = "test-support"))]
DbStore::Fake { data: db } => {
let mut db = db.lock();
for (key, value) in entries {
db.insert(key.as_ref().into(), value.as_ref().into());
}
}
}
Ok(())
}

14
script/generate-zed-sqlx-data Executable file
View File

@ -0,0 +1,14 @@
#!/bin/bash
set -e
# Install sqlx-cli if needed
[[ "$(sqlx --version)" == "sqlx-cli 0.5.7" ]] || cargo install sqlx-cli --version 0.5.7
cd crates/db
mkdir /tmp/zed-client-db
DATABASE_URL=sqlite:///tmp/zed-client-db/test.db
cargo sqlx -D $DATABASE_URL database setup
cargo sqlx -D $DATABASE_URL prepare