diff --git a/.gitignore b/.gitignore
index 3a8cabc..7b881bc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
/target
.idea
+database/
diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md
index 5b80663..2aabc82 100644
--- a/ARCHITECTURE.md
+++ b/ARCHITECTURE.md
@@ -8,6 +8,8 @@
The database is the core storage of Geoffrey. All models will be stored here. It is tightly
coupled with the GeoffreyAPI.
+![DB Architecture](figures/db_arch.svg)
+
## Geoffrey API
The API provides the main logic to how models are manipulated in the Database. It is split
into two parts, the Command API and Model API.
diff --git a/Cargo.lock b/Cargo.lock
index 5eed643..c9e1162 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6,6 +6,24 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
+[[package]]
+name = "bitflags"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
+
+[[package]]
+name = "byteorder"
+version = "1.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
[[package]]
name = "chrono"
version = "0.4.19"
@@ -20,6 +38,70 @@ dependencies = [
"winapi",
]
+[[package]]
+name = "crc32fast"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2584f639eb95fea8c798496315b297cf81b9b58b6d30ab066a75455333cf4b12"
+dependencies = [
+ "cfg-if",
+ "crossbeam-utils",
+ "lazy_static",
+ "memoffset",
+ "scopeguard",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49"
+dependencies = [
+ "autocfg",
+ "cfg-if",
+ "lazy_static",
+]
+
+[[package]]
+name = "fs2"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "fxhash"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
+name = "geoffrey_db"
+version = "0.1.0"
+dependencies = [
+ "byteorder",
+ "geoffrey_models",
+ "lazy_static",
+ "serde",
+ "serde_json",
+ "sled",
+]
+
[[package]]
name = "geoffrey_models"
version = "0.1.0"
@@ -29,18 +111,60 @@ dependencies = [
"serde_json",
]
+[[package]]
+name = "instant"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
+dependencies = [
+ "cfg-if",
+]
+
[[package]]
name = "itoa"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
[[package]]
name = "libc"
version = "0.2.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a"
+[[package]]
+name = "lock_api"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312"
+dependencies = [
+ "scopeguard",
+]
+
+[[package]]
+name = "log"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "memoffset"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87"
+dependencies = [
+ "autocfg",
+]
+
[[package]]
name = "num-integer"
version = "0.1.44"
@@ -60,6 +184,31 @@ dependencies = [
"autocfg",
]
+[[package]]
+name = "parking_lot"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb"
+dependencies = [
+ "instant",
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018"
+dependencies = [
+ "cfg-if",
+ "instant",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "winapi",
+]
+
[[package]]
name = "proc-macro2"
version = "1.0.24"
@@ -78,12 +227,27 @@ dependencies = [
"proc-macro2",
]
+[[package]]
+name = "redox_syscall"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9"
+dependencies = [
+ "bitflags",
+]
+
[[package]]
name = "ryu"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
+[[package]]
+name = "scopeguard"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+
[[package]]
name = "serde"
version = "1.0.123"
@@ -115,6 +279,28 @@ dependencies = [
"serde",
]
+[[package]]
+name = "sled"
+version = "0.34.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d0132f3e393bcb7390c60bb45769498cf4550bcb7a21d7f95c02b69f6362cdc"
+dependencies = [
+ "crc32fast",
+ "crossbeam-epoch",
+ "crossbeam-utils",
+ "fs2",
+ "fxhash",
+ "libc",
+ "log",
+ "parking_lot",
+]
+
+[[package]]
+name = "smallvec"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
+
[[package]]
name = "syn"
version = "1.0.61"
diff --git a/Cargo.toml b/Cargo.toml
index e442523..5d7f8dc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,4 +1,5 @@
[workspace]
members = [
- "geoffrey_models"
+ "geoffrey_models",
+ "geoffrey_db"
]
\ No newline at end of file
diff --git a/figures/db_arch.svg b/figures/db_arch.svg
new file mode 100644
index 0000000..14613fc
--- /dev/null
+++ b/figures/db_arch.svg
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/geoffrey_db/Cargo.toml b/geoffrey_db/Cargo.toml
new file mode 100644
index 0000000..0190f89
--- /dev/null
+++ b/geoffrey_db/Cargo.toml
@@ -0,0 +1,17 @@
+[package]
+name = "geoffrey_db"
+version = "0.1.0"
+authors = ["Joey Hines "]
+edition = "2018"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+sled = "0.34.6"
+serde = "1.0"
+serde_json = "1.0"
+geoffrey_models = { path = "../geoffrey_models" }
+byteorder = "1.4.2"
+
+[dev-dependencies]
+lazy_static = "1.4.0"
diff --git a/geoffrey_db/src/database.rs b/geoffrey_db/src/database.rs
new file mode 100644
index 0000000..73175b9
--- /dev/null
+++ b/geoffrey_db/src/database.rs
@@ -0,0 +1,91 @@
+use crate::error::Result;
+use std::path::Path;
+use geoffrey_models::GeoffreyDatabaseModel;
+use crate::u64_to_bytes;
+
+pub struct Database {
+ db: sled::Db,
+}
+
+impl Database {
+ pub fn new(db_path: &Path) -> Result {
+ let db = sled::open(db_path)?;
+
+ Ok(Self {
+ db,
+ })
+ }
+
+ fn get_tree(&self) -> Result where T: GeoffreyDatabaseModel {
+ Ok(self.db.open_tree::(T::tree())?)
+ }
+
+ pub fn insert<'a, T>(&self, mut model: T) -> Result where T: GeoffreyDatabaseModel {
+ let id = self.db.generate_id()?;
+ let tree = self.get_tree::()?;
+ let data = serde_json::to_vec(&model).unwrap();
+ let id_bytes = u64_to_bytes(id);
+
+ tree.insert(id_bytes, data)?;
+
+ model.set_id(id);
+
+ Ok(model)
+ }
+
+
+ pub fn get(&self, id: u64) -> Result