Skip to content

Commit

Permalink
Representing documents using trait instead of wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
katyo committed Oct 26, 2018
1 parent 7fa4d83 commit df9bd49
Show file tree
Hide file tree
Showing 16 changed files with 500 additions and 270 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[workspace]

members = [
"ledb-types",
"ledb",
"ledb-actix",
]
Expand Down
6 changes: 3 additions & 3 deletions ledb-actix/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "ledb-actix"
version = "0.1.1"
authors = ["Kayo Phoenix <kayo@illumium.org>"]
version = "0.2.0"
authors = ["Kayo <kayo@illumium.org>"]
license = "MIT"
readme = "README.md"
repository = "https://github.com/katyo/ledb"
Expand All @@ -25,7 +25,7 @@ required-features = ["web"]
serde = "1"
serde_derive = { version = "1", optional = true }
serde_with = { version = "0.2", optional = true, features = ["json"] }
ledb = { version = "0.1.1", path = "../ledb" }
ledb = { version = "0.2", path = "../ledb" }
futures = "0.1"
actix = "0.7"
actix-web = { version = "0.7", optional = true }
Expand Down
12 changes: 10 additions & 2 deletions ledb-actix/examples/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,25 @@ extern crate pretty_env_logger;

use actix::System;
use futures::Future;
use ledb_actix::{Storage, Options, StorageAddrExt};
use ledb_actix::{Storage, Options, StorageAddrExt, Primary, Document, Identifier};
use serde_json::from_value;
use std::env;
use tokio::spawn;

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
struct BlogPost {
pub id: Option<Primary>,
pub title: String,
pub tags: Vec<String>,
pub content: String,
}

impl Document for BlogPost {
fn primary_field() -> Identifier {
"id".into()
}
}

fn main() {
env::set_var("RUST_LOG", "info");
pretty_env_logger::init().unwrap();
Expand Down Expand Up @@ -81,12 +88,13 @@ fn main() {
info!("Found document: {:?}", doc);

let doc_data: BlogPost = from_value(json!({
"id": 1,
"title": "Absurd",
"tags": ["absurd", "psychology"],
"content": "Still nothing..."
})).unwrap();

assert_eq!(doc.get_data(), &doc_data);
assert_eq!(&doc, &doc_data);
assert!(docs.next().is_none());

System::current().stop();
Expand Down
34 changes: 20 additions & 14 deletions ledb-actix/src/actor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,11 +247,11 @@ pub fn Insert<C: Into<Identifier>, T: Serialize>(coll: C, data: T) -> InsertMsg<
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InsertMsg<T>(Identifier, T);

impl<T: Serialize> Message for InsertMsg<T> {
impl<T> Message for InsertMsg<T> {
type Result = LeResult<Primary>;
}

impl<T: Serialize> Handler<InsertMsg<T>> for Storage {
impl<T: Serialize + Document> Handler<InsertMsg<T>> for Storage {
type Result = <InsertMsg<T> as Message>::Result;

fn handle(&mut self, InsertMsg(collection, document): InsertMsg<T>, _: &mut Self::Context) -> Self::Result {
Expand All @@ -261,7 +261,7 @@ impl<T: Serialize> Handler<InsertMsg<T>> for Storage {

/// Get the previously inserted document by primary key
#[allow(non_snake_case)]
pub fn Get<C: Into<Identifier>, T: DeserializeOwned>(coll: C, id: Primary) -> GetMsg<T> {
pub fn Get<C: Into<Identifier>, T>(coll: C, id: Primary) -> GetMsg<T> {
GetMsg(coll.into(), id, PhantomData)
}

Expand All @@ -271,11 +271,11 @@ pub fn Get<C: Into<Identifier>, T: DeserializeOwned>(coll: C, id: Primary) -> Ge
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct GetMsg<T>(Identifier, Primary, PhantomData<T>);

impl<T: DeserializeOwned + 'static> Message for GetMsg<T> {
type Result = LeResult<Option<Document<T>>>;
impl<T: 'static> Message for GetMsg<T> {
type Result = LeResult<Option<T>>;
}

impl<T: DeserializeOwned + 'static> Handler<GetMsg<T>> for Storage {
impl<T: DeserializeOwned + Document + 'static> Handler<GetMsg<T>> for Storage {
type Result = <GetMsg<T> as Message>::Result;

fn handle(&mut self, GetMsg(collection, identifier, ..): GetMsg<T>, _: &mut Self::Context) -> Self::Result {
Expand All @@ -285,21 +285,21 @@ impl<T: DeserializeOwned + 'static> Handler<GetMsg<T>> for Storage {

/// Put new version of the previously inserted document
#[allow(non_snake_case)]
pub fn Put<C: Into<Identifier>, T: Serialize>(coll: C, data: Document<T>) -> PutMsg<T> {
pub fn Put<C: Into<Identifier>, T>(coll: C, data: T) -> PutMsg<T> {
PutMsg(coll.into(), data)
}

/// Put new version of the previously inserted document
///
/// *NOTE: Use `Put` for creating message*
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PutMsg<T>(Identifier, Document<T>);
pub struct PutMsg<T>(Identifier, T);

impl<T: Serialize> Message for PutMsg<T> {
impl<T: Serialize + Document> Message for PutMsg<T> {
type Result = LeResult<()>;
}

impl<T: Serialize> Handler<PutMsg<T>> for Storage {
impl<T: Serialize + Document> Handler<PutMsg<T>> for Storage {
type Result = <PutMsg<T> as Message>::Result;

fn handle(&mut self, PutMsg(collection, document): PutMsg<T>, _: &mut Self::Context) -> Self::Result {
Expand Down Expand Up @@ -391,11 +391,11 @@ pub fn Find<C: Into<Identifier>, T>(coll: C, filter: Option<Filter>, order: Orde
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FindMsg<T>(Identifier, Option<Filter>, Order, PhantomData<T>);

impl<T: DeserializeOwned + 'static> Message for FindMsg<T> {
impl<T: 'static> Message for FindMsg<T> {
type Result = LeResult<DocumentsIterator<T>>;
}

impl<T: DeserializeOwned + 'static> Handler<FindMsg<T>> for Storage {
impl<T: DeserializeOwned + Document + 'static> Handler<FindMsg<T>> for Storage {
type Result = <FindMsg<T> as Message>::Result;

fn handle(&mut self, FindMsg(collection, filter, order, ..): FindMsg<T>, _: &mut Self::Context) -> Self::Result {
Expand All @@ -410,7 +410,7 @@ mod tests {
use futures::{Future};
use tokio::{spawn};
use actix::{System};
use super::{Storage, Options, EnsureIndex, Insert, Find, IndexKind, KeyType};
use super::{Storage, Options, EnsureIndex, Insert, Find, IndexKind, KeyType, Document, Identifier, Primary};

macro_rules! json_val {
($($json:tt)+) => {
Expand All @@ -420,11 +420,16 @@ mod tests {

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
struct BlogPost {
pub id: Option<Primary>,
pub title: String,
pub tags: Vec<String>,
pub content: String,
}

impl Document for BlogPost {
fn primary_field() -> Identifier { "id".into() }
}

static DB_PATH: &'static str = "test_db";

#[test]
Expand Down Expand Up @@ -469,11 +474,12 @@ mod tests {
assert_eq!(docs.size_hint(), (1, Some(1)));
let doc = docs.next().unwrap().unwrap();
let doc_data: BlogPost = json_val!({
"id": 1,
"title": "Absurd",
"tags": ["absurd", "psychology"],
"content": "Still nothing..."
});
assert_eq!(doc.get_data(), &doc_data);
assert_eq!(&doc, &doc_data);
assert!(docs.next().is_none());

System::current().stop();
Expand Down
12 changes: 10 additions & 2 deletions ledb-actix/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,25 @@ extern crate pretty_env_logger;
use actix::System;
use futures::Future;
use ledb_actix::{Storage, Options, StorageAddrExt};
use ledb_actix::{Storage, Options, StorageAddrExt, Primary, Identifier, Document};
use serde_json::from_value;
use std::env;
use tokio::spawn;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
struct BlogPost {
pub id: Option<Primary>,
pub title: String,
pub tags: Vec<String>,
pub content: String,
}
impl Document for BlogPost {
fn primary_field() -> Identifier {
"id".into()
}
}
fn main() {
env::set_var("RUST_LOG", "info");
pretty_env_logger::init().unwrap();
Expand Down Expand Up @@ -94,12 +101,13 @@ fn main() {
info!("Found document: {:?}", doc);
let doc_data: BlogPost = from_value(json!({
"id": 1,
"title": "Absurd",
"tags": ["absurd", "psychology"],
"content": "Still nothing..."
})).unwrap();
assert_eq!(doc.get_data(), &doc_data);
assert_eq!(&doc, &doc_data);
assert!(docs.next().is_none());
System::current().stop();
Expand Down
6 changes: 3 additions & 3 deletions ledb-node/native/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ledb-node"
version = "0.1.1"
version = "0.2.0"
authors = ["Kayo <kayo@illumium.org>"]
license = "MIT"
build = "build.rs"
Expand All @@ -14,7 +14,7 @@ crate-type = ["cdylib"]
neon-build = "0.2.0"

[dependencies]
ledb = "0.1.1"
ledb = "0.2.0"
neon = "0.2.0"
neon-serde = "0.0.3"

Expand All @@ -25,5 +25,5 @@ lto = true

[patch.crates-io]
neon-serde = { git = "https://github.com/apendleton/neon-serde", branch = "oh-point-two" }
ledb = { path = "../../ledb" }
#ledb = { path = "../../ledb" }
#ledb = { git = "https://github.com/katyo/ledb" }
8 changes: 3 additions & 5 deletions ledb-node/native/src/collection.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use ledb::{
Collection, Document, Filter, Identifier, IndexKind, KeyType, Modify, Order, Primary, Value,
};
use ledb::{Collection, Filter, Identifier, IndexKind, KeyType, Modify, Order, Primary, Value};
use neon::prelude::*;
use neon_serde::{from_value, to_value};
use std::u32;
Expand Down Expand Up @@ -172,7 +170,7 @@ declare_types! {

let this = cx.this();

let doc: Option<Document> = js_try!(cx, {
let doc: Option<Value> = js_try!(cx, {
let guard = cx.lock();
let collection = this.borrow(&guard);
collection.get(id)
Expand All @@ -183,7 +181,7 @@ declare_types! {

method put(mut cx) {
let raw = cx.argument(0)?;
let doc: Document<Value> = from_value(&mut cx, raw)?;
let doc: Value = from_value(&mut cx, raw)?;

let this = cx.this();

Expand Down
8 changes: 4 additions & 4 deletions ledb-node/native/src/documents.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use ledb::{Document, Result, Value};
use ledb::{Result, Value};
use neon::prelude::*;
use neon_serde::to_value;
use std::mem::replace;
use std::usize;

pub struct Documents(pub(crate) Option<Box<Iterator<Item = Result<Document<Value>>>>>);
pub struct Documents(pub(crate) Option<Box<Iterator<Item = Result<Value>>>>);

static INVALID_RANGE: &'static str = "Argument not in range 0..N";
static INVALID_ITERATOR: &'static str = "Invalid documents iterator";
Expand Down Expand Up @@ -83,7 +83,7 @@ declare_types! {
method next(mut cx) {
let mut this = cx.this();

let doc: Option<Document<Value>> = js_try!(cx, {
let doc: Option<Value> = js_try!(cx, {
let guard = cx.lock();
let mut this = this.borrow_mut(&guard);

Expand All @@ -110,7 +110,7 @@ declare_types! {
method collect(mut cx) {
let mut this = cx.this();

let docs: Vec<Document<Value>> = js_try!(cx, {
let docs: Vec<Value> = js_try!(cx, {
let guard = cx.lock();
let mut this = this.borrow_mut(&guard);

Expand Down
26 changes: 26 additions & 0 deletions ledb-types/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[package]
name = "ledb-types"
version = "0.2.0"
authors = ["Kayo <kayo@illumium.org>"]
license = "MIT"
readme = "README.md"
repository = "https://github.com/katyo/ledb"
homepage = "https://github.com/katyo/ledb/tree/master/ledb-types"
keywords = ["storage", "document", "json", "cbor"]
categories = ["database"]
description = "Basic types for storable documents"

[badges]
travis-ci = { repository = "katyo/ledb" }
appveyor = { repository = "katyo/ledb" }

[dependencies]
serde = "1"
serde_derive = "1"
serde_json = { version = "1", optional = true }
serde_cbor = { version = "0.9", optional = true }

[features]
default = []
json = ["serde_json"]
cbor = ["serde_cbor"]
48 changes: 48 additions & 0 deletions ledb-types/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Types for defining storable documents

[![License: MIT](https://img.shields.io/badge/License-MIT-brightgreen.svg)](https://opensource.org/licenses/MIT)
[![Travis-CI Build Status](https://travis-ci.org/katyo/ledb.svg?branch=master)](https://travis-ci.org/katyo/ledb)
[![Appveyor Build status](https://ci.appveyor.com/api/projects/status/1wrmhivii22emfxg)](https://ci.appveyor.com/project/katyo/ledb)
[![Crates.io Package](https://img.shields.io/crates/v/ledb.svg?style=popout)](https://crates.io/crates/ledb)
[![Docs.rs API Documentation](https://docs.rs/ledb/badge.svg)](https://docs.rs/ledb)

This types and traits widely used for documents which can be managed using persistent storages like *LEDB*.

The **LEDB** is an attempt to implement simple but efficient, lightweight but powerful document storage.

The abbreviation *LEDB* may be treated as an Lightweight Embedded DB, also Low End DB, also Literium Engine DB, also LitE DB, and so on.

## Links

* [ledb-types Crate on crates.io](https://crates.io/crates/ledb-types)
* [ledb-types API Docs on docs.rs](https://docs.rs/ledb-types)
* [ledb Crate on crates.io](https://crates.io/crates/ledb)
* [ledb API Docs on docs.rs](https://docs.rs/ledb)

## Usage example

```rust

extern crate serde;
#[macro_use] extern crate serde_derive;
extern crate ledb_types;

use ledb_types::{Document, Identifier, Primary};

#[derive(Serialize, Deserialize)]
struct MyDoc {
// define optional primary key field
id: Option<Primary>,
// define other fields
title: String,
tag: Vec<String>,
timestamp: u32,
}

impl Document for MyDoc {
// declare primary key field name
fn primary_field() -> Identifier {
"id".into()
}
}
```
Loading

0 comments on commit df9bd49

Please sign in to comment.