Skip to content

Commit

Permalink
Add bulk create
Browse files Browse the repository at this point in the history
  • Loading branch information
kuy committed Sep 28, 2019
1 parent e7155d7 commit 4097e3c
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 21 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
- Make `Client::with_base_url()` a method instead of a constructor [[#3](https://github.com/kuy/jsonbox-rs/issues/3)]
- Change visibility of `Client::read_by_id()` and `Client::read_by_query()` (accidently exposed in past versions) [[#2](https://github.com/kuy/jsonbox-rs/issues/2)]

### Added

- Support bulk `CREATE` operation [[#9](https://github.com/kuy/jsonbox-rs/issues/9)]

## [0.1.2] 2019-09-28

### Added
Expand Down
19 changes: 8 additions & 11 deletions examples/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ impl Data {
fn main() -> Result<(), Error> {
let client = Client::new("box_8ed82aef3f93176996145");

let data = Data::new("jsonbox", 42, false);
let mut data = Data::new("kuy", 42, false);
let (record, meta1) = client.create(&data)?;
println!("CREATE: data={:?}, meta={:?}", record, meta1);

let (record, meta1) = client.read().id::<Data>(&meta1.id)?;
println!("READ single: data={:?}, meta={:?}", record, meta1);

let mut data = Data::new("kuy", 16, false);
let (record, meta2) = client.create(&data)?;
println!("CREATE: data={:?}, meta={:?}", record, meta2);
let list = vec![Data::new("jsonbox", 21, false), Data::new("io", 16, true)];
let bulk = client.create_bulk(&list)?;
println!("CREATE bulk: len={}, bulk={:?}", bulk.len(), bulk);

let all = client.read().all::<Data>()?;
println!("READ: len={}, all={:?}", all.len(), all);
Expand All @@ -43,8 +43,8 @@ fn main() -> Result<(), Error> {
let few = client.read().limit(1).run::<Data>()?;
println!("READ: len={}, few={:?}", few.len(), few);

data.name = format!("kuy {}", meta2.id);
client.update(&meta2.id, &data)?;
data.name = format!("kuy {}", meta1.id);
client.update(&meta1.id, &data)?;
println!("UPDATE: OK");

let filtered = client
Expand All @@ -58,12 +58,12 @@ fn main() -> Result<(), Error> {

let filtered = client
.read()
.filter_by("name:*{}", &meta2.id)
.filter_by("name:*{}", &meta1.id)
.run::<Data>()?;
println!("READ: len={}, filtered={:?}", filtered.len(), filtered);

data.age = 8;
client.update(&meta2.id, &data)?;
client.update(&meta1.id, &data)?;
println!("UPDATE: OK");

let filtered = client
Expand All @@ -76,8 +76,5 @@ fn main() -> Result<(), Error> {
client.delete(&meta1.id)?;
println!("DELETE: OK");

client.delete(&meta2.id)?;
println!("DELETE: OK");

Ok(())
}
44 changes: 34 additions & 10 deletions src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pub mod query_builder;

use reqwest;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use serde_json::from_str;
use snafu::ResultExt;
use std::convert::From;

Expand Down Expand Up @@ -75,9 +76,8 @@ impl<'a> Client<'a> {
.context(error::Network {})?;
if res.status().is_success() {
let raw = res.text().context(error::Network {})?;
let data: T = serde_json::from_str(&raw).context(error::Json { reason: "data" })?;
let meta: MetaRaw =
serde_json::from_str(&raw).context(error::Json { reason: "meta" })?;
let data: T = from_str(&raw).context(error::Json { reason: "data" })?;
let meta: MetaRaw = from_str(&raw).context(error::Json { reason: "meta" })?;
Ok((data, Meta::from(meta)))
} else {
let err: ErrorMessage = res.json().context(error::Network {})?;
Expand All @@ -88,6 +88,33 @@ impl<'a> Client<'a> {
}
}

pub fn create_bulk<T>(&self, data: &Vec<T>) -> Result<Vec<(T, Meta)>>
where
T: Serialize + DeserializeOwned,
{
let client = reqwest::Client::new();
let mut res = client
.post(&url::of_box(&self.base_url, &self.box_id))
.json(&data)
.send()
.context(error::Network {})?;
if res.status().is_success() {
let raw = res.text().context(error::Network {})?;
let data: Vec<T> = from_str(&raw).context(error::Json { reason: "data" })?;
let meta: Vec<MetaRaw> = from_str(&raw).context(error::Json { reason: "meta" })?;
Ok(data
.into_iter()
.zip(meta.into_iter().map(|meta| Meta::from(meta)))
.collect())
} else {
let err: ErrorMessage = res.json().context(error::Network {})?;
Err(Error::General {
code: res.status().as_u16(),
message: err.message,
})
}
}

pub fn read(&self) -> QueryBuilder {
QueryBuilder::new(self)
}
Expand All @@ -100,9 +127,8 @@ impl<'a> Client<'a> {
let mut res = reqwest::get(&url).context(error::Network {})?;
if res.status().is_success() {
let raw = res.text().context(error::Network {})?;
let data: T = serde_json::from_str(&raw).context(error::Json { reason: "data" })?;
let meta: MetaRaw =
serde_json::from_str(&raw).context(error::Json { reason: "meta" })?;
let data: T = from_str(&raw).context(error::Json { reason: "data" })?;
let meta: MetaRaw = from_str(&raw).context(error::Json { reason: "meta" })?;
Ok((data, Meta::from(meta)))
} else {
let err: ErrorMessage = res.json().context(error::Network {})?;
Expand All @@ -121,10 +147,8 @@ impl<'a> Client<'a> {
let mut res = reqwest::get(url).context(error::Network {})?;
if res.status().is_success() {
let raw = res.text().context(error::Network {})?;
let data: Vec<T> =
serde_json::from_str(&raw).context(error::Json { reason: "data" })?;
let meta: Vec<MetaRaw> =
serde_json::from_str(&raw).context(error::Json { reason: "meta" })?;
let data: Vec<T> = from_str(&raw).context(error::Json { reason: "data" })?;
let meta: Vec<MetaRaw> = from_str(&raw).context(error::Json { reason: "meta" })?;
Ok(data
.into_iter()
.zip(meta.into_iter().map(|meta| Meta::from(meta)))
Expand Down
34 changes: 34 additions & 0 deletions tests/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,40 @@ fn test_create() {
assert_eq!(meta.updated_on, "2019-09-22T12:24:37.513Z");
}

#[test]
fn test_create_bulk() {
let _m = mock("POST", "/00000000000000000000")
.with_status(200)
.with_header("content-type", "application/json; charset=utf-8")
.with_body(r#"[{"_id":"11111111111111111111","name":"rust","count":42,"_createdOn":"2019-09-22T12:24:37.513Z"},{"_id":"22222222222222222222","name":"cargo","count":7,"_createdOn":"2019-09-22T12:24:37.513Z"}]"#)
.create();
let server_url = mockito::server_url();
let client = Client::new("00000000000000000000").with_base_url(&server_url);
let data = vec![
Data {
name: "rust".into(),
count: 42,
},
Data {
name: "cargo".into(),
count: 7,
},
];
let res = client.create_bulk(&data);
assert!(res.is_ok());

let bulk = res.unwrap();
assert_eq!(bulk.len(), 2);

let (data, meta) = bulk.first().unwrap();
assert_eq!(data.name, "rust");
assert_eq!(meta.id, "11111111111111111111");

let (data, meta) = bulk.last().unwrap();
assert_eq!(data.name, "cargo");
assert_eq!(meta.id, "22222222222222222222");
}

#[test]
fn test_read_all() {
let _m = mock("GET", "/00000000000000000000")
Expand Down

0 comments on commit 4097e3c

Please sign in to comment.