wip
This commit is contained in:
parent
318b923bac
commit
dbc03e2668
5 changed files with 53 additions and 7717 deletions
7675
Cargo.lock
generated
7675
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -15,7 +15,7 @@ collections = { path = "../collections" }
|
||||||
anyhow = "1.0.57"
|
anyhow = "1.0.57"
|
||||||
async-trait = "0.1"
|
async-trait = "0.1"
|
||||||
parking_lot = "0.11.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]
|
[dev-dependencies]
|
||||||
gpui = { path = "../gpui", features = ["test-support"] }
|
gpui = { path = "../gpui", features = ["test-support"] }
|
||||||
|
|
4
crates/db/migrations/001_init.sql
Normal file
4
crates/db/migrations/001_init.sql
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
CREATE TABLE kv_store(
|
||||||
|
key TEXT NOT NULL,
|
||||||
|
value TEXT NOT NULL
|
||||||
|
) STRICT;
|
|
@ -1,24 +1,50 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use sqlx::sqlite::{SqliteConnectOptions, SqlitePoolOptions};
|
||||||
|
use sqlx::{Pool, Sqlite, SqlitePool};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub struct Db(DbStore);
|
pub struct Db(DbStore);
|
||||||
|
|
||||||
enum DbStore {
|
enum DbStore {
|
||||||
Null,
|
Null,
|
||||||
Real(rocksdb::DB),
|
Live(Pool<Sqlite>),
|
||||||
|
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
|
||||||
Fake {
|
|
||||||
data: parking_lot::Mutex<collections::HashMap<Vec<u8>, Vec<u8>>>,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 {
|
impl Db {
|
||||||
/// Open or create a database at the given file path.
|
/// Open or create a database at the given file path.
|
||||||
pub fn open(path: &Path) -> Result<Arc<Self>> {
|
pub fn open(path: &Path) -> Result<Arc<Self>> {
|
||||||
let db = rocksdb::DB::open_default(path)?;
|
let options = SqliteConnectOptions::from_str(path)?.create_if_missing(true);
|
||||||
Ok(Arc::new(Self(DbStore::Real(db))))
|
|
||||||
|
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
|
/// Open a null database that stores no data, for use as a fallback
|
||||||
|
@ -27,14 +53,6 @@ impl Db {
|
||||||
Arc::new(Self(DbStore::Null))
|
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>>>>
|
pub fn read<K, I>(&self, keys: I) -> Result<Vec<Option<Vec<u8>>>>
|
||||||
where
|
where
|
||||||
K: AsRef<[u8]>,
|
K: AsRef<[u8]>,
|
||||||
|
@ -48,15 +66,6 @@ impl Db {
|
||||||
.collect(),
|
.collect(),
|
||||||
|
|
||||||
DbStore::Null => Ok(keys.into_iter().map(|_| None).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 => {}
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -103,14 +104,6 @@ impl Db {
|
||||||
}
|
}
|
||||||
|
|
||||||
DbStore::Null => {}
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
14
script/generate-zed-sqlx-data
Executable file
14
script/generate-zed-sqlx-data
Executable 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
|
Loading…
Add table
Add a link
Reference in a new issue