Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
f5237c3
Fixing errors while moving to the latest libraries and Rust 2018 stan…
mibes Feb 2, 2020
f260c41
All tests pass! :-)
mibes Feb 2, 2020
6527b31
Compiles without warnings.
mibes Feb 3, 2020
0bffd99
Updated Readme's.
mibes Feb 3, 2020
dcf9e6f
Updated installation instructions.
mibes Feb 3, 2020
5d533dd
Allow for bulk operations.
mibes Feb 3, 2020
b549fdb
Removed unneeded code.
mibes Feb 3, 2020
f630f29
Elaborated example
mibes Feb 3, 2020
8d89d20
Simplified the example a bit.
mibes Feb 3, 2020
19f1604
Return an error in case a document can not be found (404).
mibes Feb 4, 2020
8460189
Example on how to work with typed documents.
mibes Feb 4, 2020
710fbef
Updated comment
mibes Feb 4, 2020
ab5e184
Create a client with a custom timeout. Default set to 10 seconds.
mibes Feb 4, 2020
c62c576
Find with an optional bookmark.
mibes Feb 4, 2020
a078ae2
Tested with CouchDB 2.3
mibes Feb 4, 2020
093521c
Fix optional bookmark
mibes Feb 4, 2020
3d8baa9
Use localhost in the example
mibes Feb 4, 2020
c956499
Use replace
mibes Feb 5, 2020
21b0986
Support for batched reads.
mibes Feb 5, 2020
b1399ed
Use json unmarshalling from reqwest.
mibes Feb 5, 2020
548ec03
Asynchronous batch read example.
mibes Feb 5, 2020
36a3892
Updated dependency in README
mibes Feb 5, 2020
faae707
Async operations
mibes Feb 8, 2020
bfe6f8a
Updated README
mibes Feb 8, 2020
5786023
Make the tests point to localhost again
mibes Feb 8, 2020
553fe8e
Use tokio channels
mibes Feb 8, 2020
cd9ed89
no async-traits (yet).
mibes Feb 8, 2020
152e9f6
Some de-duplication
mibes Feb 8, 2020
48670f8
Updated README
mibes Feb 8, 2020
d0f05c0
Updated README
mibes Feb 9, 2020
8954291
Some clean-up.
mibes Feb 10, 2020
ad16a33
Updated for Couch 3.0
mibes Feb 29, 2020
2ca5ef3
Updated the tests for use with CouchDB 3.0
mibes Feb 29, 2020
2d9d4c4
Updated tokio and reqwest versions.
mibes Apr 10, 2020
5484a68
Include version in dependency
mibes Apr 10, 2020
6867964
bulk_get will only return the requested documents.
mibes May 19, 2020
6d38df2
Aligned versions
mibes May 19, 2020
9a1a76b
Do not panic on missing documents in bulk_get
mibes May 19, 2020
c702b2a
Aligned versions
mibes May 19, 2020
d61c30a
Use version in favour of tag.
mibes May 25, 2020
7b76193
Added create and execute view
hmacias-avaya Jul 7, 2020
88e1939
Check design creation result for errors
hmacias-avaya Jul 8, 2020
fb45bd3
Merge pull request #1 from horacimacias/master
mibes Jul 13, 2020
ec9cb37
statics: Remove unneeded (and kinda odd) static str's
kallisti5 Jul 14, 2020
3aada27
Updated dependencies
mibes Jul 25, 2020
8de2497
Updated version
mibes Jul 25, 2020
695fd0c
Addressed some Clippy warnings
mibes Jul 25, 2020
e508c82
Convenience function to retrieve the database name.
mibes Sep 5, 2020
953c75f
Included the find_batched operation.
mibes Sep 9, 2020
50190ab
Allow FindQuery to be converted to Value
mibes Sep 9, 2020
b27ac58
Allow FindQuery to be converted to Value
mibes Sep 9, 2020
db5d5ef
Implemented Display for FindQuery
mibes Sep 9, 2020
7b7aacc
`json_extr!` does not panic when called on a non-existent field. Like…
mibes Sep 9, 2020
05b094d
get_all_params now takes a typed QueryParams as input, and uses POST,…
mibes Sep 9, 2020
ce78ef8
Allow to query a view with a different design name
mibes Sep 9, 2020
24935e1
Check response success for create_view
mibes Sep 10, 2020
d114fc7
Allow executing update functions
hmacias-avaya Sep 10, 2020
46ce1a9
Pass document_id to execute update
hmacias-avaya Sep 10, 2020
cc59cfc
Renamed
hmacias-avaya Sep 10, 2020
6198744
Merge pull request #2 from kallisti5/fix-statics
mibes Sep 11, 2020
f53af20
Merge branch 'master' into master
mibes Sep 11, 2020
6de383c
Merge pull request #3 from horacimacias/master
mibes Sep 11, 2020
d6bbe54
Use reqwest's `error_for_status()` on responses & return an Error whe…
mibes Sep 11, 2020
465c54e
Return value in ViewItem as Value.
mibes Sep 14, 2020
ea58106
Make id in ViewItem optional.
mibes Sep 14, 2020
b51db4d
Updated version to 0.7.15
mibes Sep 14, 2020
0fc7baf
Make total_rows in ViewCollection optional
mibes Sep 14, 2020
7e23947
Sort takes an array of key/value pairs, like: [{"first_name":"desc"}]
mibes Sep 14, 2020
34db8bb
Delete execute_view as it's doing 99% the same as query
hmacias-avaya Sep 24, 2020
a36f616
ViewItem can now contain a doc for 'include_docs=true' view queries
hmacias-avaya Sep 25, 2020
9d46c15
Use QueryParams when executing views
hmacias-avaya Sep 25, 2020
4f10456
Merge pull request #4 from horacimacias/master
mibes Sep 25, 2020
75a946f
Updated the CHANGELOG and versions.
mibes Sep 25, 2020
97968b6
the `find()` operations takes a FindQuery
mibes Sep 26, 2020
aee6ddb
Spin-off notice
mibes Sep 28, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,9 @@ Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk

# Exclude IntelliJ files
.idea

test_db.json

# End of https://www.gitignore.io/api/rust
60 changes: 58 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,72 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

## [0.6.0] - 2018-08-23
## [0.8.0] - 2020-09-26

- the `find()` operations takes a FindQuery

## [0.7.18] - 2020-09-25

- Views now use QueryParams instead of an untyped map.
- Views can now return the optional "doc" item.
- BREAKING CHANGE: `execute_view` has been removed. Use `query` instead.

## [0.7.17] - 2020-09-14

- Sort takes an array of key/value pairs, like: [{"first_name":"desc"}]

## [0.7.16] - 2020-09-14

- Make total_rows in ViewCollection optional.

## [0.7.15] - 2020-09-14

- Make id in ViewItem optional.

## [0.7.14] - 2020-09-14
- Return value in ViewItem as a Value, not String

## [0.7.13] - 2020-09-11
- Use reqwest's `error_for_status()` on responses, where we are not actively checking the result.
- Return an Error when one occurs during batch reading.
- Removed the `'static` lifetime on some of the `str` parameters; contribution from kallisti5
- Included `execute_update()` operation; contribution from horacimacias

## [0.7.12] - 2020-09-10
- Check response success for create_view()

## [0.7.11] - 2020-09-09
- Allow to query a view with a different design name

## [0.7.10] - 2020-09-09
- BREAKING CHANGE: get_all_params now takes a typed QueryParams as input.
- get_all_params uses POST, instead of GET, for greater flexibility.

## [0.7.9] - 2020-09-09
- `json_extr!` does not panic when called on a non-existent field. Like in find for _id,
when the find result does not include an _id.

## [0.7.8] - 2020-09-09
- Implemented Display for FindQuery

## [0.7.7] - 2020-09-09
- Allow FindQuery to be converted to Value

## [0.7.6] - 2020-09-09
- Added `find_batched` to allow asynchronous customized searches

## [0.7.0] - 2020-02-03

### Added

- Added `failure` dependency
- Added `Client::make_db`
- Added `docker-compose.yml`
- Added `.rustfmt.toml`

### Changed

- Updated to the Rust 2018 edition standards
- Compiles against the latest reqwest and serde libraries
- Optimized memory consumption by moving `iter()` calls to `into_iter()` where needed
- Changed `SofaError` to derive `failure`
- Changed `Client::check_status` signature to remove potentially panicking `unwrap()` calls
Expand Down Expand Up @@ -45,3 +100,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Removed

- Removed env files that were necessary for single-threaded test run. Added section in README to reflect that.
- Removed the `failure` dependency
21 changes: 13 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "sofa"
version = "0.6.0"
authors = ["Mathieu Amiot <mathieu.amiot@yellowinnovation.fr>"]
version = "0.8.0"
authors = ["Mathieu Amiot <mathieu.amiot@yellowinnovation.fr>", "mibes <mibes@mibesco.com>"]
license = "MIT/Apache-2.0"
description = "Sofa - CouchDB for Rust"
readme = "README.md"
Expand All @@ -10,17 +10,22 @@ homepage = "https://github.com/YellowInnovation/sofa"
repository = "https://github.com/YellowInnovation/sofa"
keywords = ["couchdb", "orm", "database", "nosql"]
categories = ["database"]
edition = "2018"
include = [
"**/*.rs",
"Cargo.toml"
]

[dependencies]
failure = "0.1"
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
reqwest = "0.8"
serde = { version = "^1.0.114", features = ["derive"] }
serde_json = "^1.0.56"
url = "^2.1.1"
tokio = { version = "^0.2.22", features = ["full"] }

[dependencies.reqwest]
version = "^0.10.7"
features = ["json", "gzip", "cookies"]

[dev-dependencies]
pretty_assertions = "0.5"
pretty_assertions = "^0.6.1"
tokio = { version = "^0.2.22", features = ["full"] }
154 changes: 91 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,67 +1,95 @@
# Sofa - CouchDB for Rust

[![Crates.io](https://img.shields.io/crates/v/sofa.svg)](https://crates.io/crates/sofa)[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FYellowInnovation%2Fsofa.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2FYellowInnovation%2Fsofa?ref=badge_shield)

[![docs.rs](https://docs.rs/sofa/badge.svg)](https://docs.rs/sofa)

![sofa-logo](https://raw.githubusercontent.com/YellowInnovation/sofa/master/docs/logo-sofa.png "Logo Sofa")

## Documentation

Here: [http://docs.rs/sofa](http://docs.rs/sofa)

## Installation

```toml
[dependencies]
sofa = "0.6"
```

## Description

This crate is an interface to CouchDB HTTP REST API. Works with stable Rust.

Does not support `#![no_std]`

After trying most crates for CouchDB in Rust (`chill`, `couchdb` in particular), none of them fit our needs hence the need to create our own.

No async I/O (yet), uses a mix of Reqwest and Serde under the hood, with a few nice abstractions out there.

**NOT 1.0 YET, so expect changes**

**Supports CouchDB 2.0 and up.**

Be sure to check [CouchDB's Documentation](http://docs.couchdb.org/en/latest/index.html) in detail to see what's possible.

## Running tests

Make sure that you have an instance of CouchDB 2.0+ running, either via the supplied `docker-compose.yml` file or by yourself. It must be listening on the default port.

And then
`cargo test -- --test-threads=1`

Single-threading the tests is very important because we need to make sure that the basic features are working before actually testing features on dbs/documents.

## Why the name "Sofa"

CouchDB has a nice name, and I wanted to reflect that.

## License

Licensed under either of these:

* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
[https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or
[https://opensource.org/licenses/MIT](https://opensource.org/licenses/MIT))

# Sofa - CouchDB for Rust

[![Crates.io](https://img.shields.io/crates/v/sofa.svg)](https://crates.io/crates/sofa)
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FYellowInnovation%2Fsofa.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2FYellowInnovation%2Fsofa?ref=badge_shield)

[![docs.rs](https://docs.rs/sofa/badge.svg)](https://docs.rs/sofa)

![sofa-logo](https://raw.githubusercontent.com/mibes/sofa/master/docs/logo-sofa.png "Logo Sofa")

## Migration Notice

Please note that we are no longer maintaining this fork, but have spun off a new project:
[couch-rs](https://github.com/mibes/couch-rs)

## Documentation

Here: [http://docs.rs/sofa](http://docs.rs/sofa)

## Installation

If you want to use this particular fork, include this dependency in the Cargo.toml file:
```toml
[dependencies]
sofa = { git = "https://github.com/mibes/sofa.git", version = "0.8.0" }
```

If you want to continue to use the "old" 0.6 version use this dependency instead:
```toml
[dependencies]
sofa = "0.6"
```

## Description

This crate is an interface to CouchDB HTTP REST API. Works with stable Rust.

After trying most crates for CouchDB in Rust (`chill`, `couchdb` in particular), none of them fit our needs hence the need to create our own.

Uses async I/O, with a mix of Reqwest and Serde under the hood, and a few nice abstractions out there.

**NOT 1.0 YET, so expect changes**

**Supports CouchDB 2.3.0 and up, including the newly released 3.0 version.**

Be sure to check [CouchDB's Documentation](http://docs.couchdb.org/en/latest/index.html) in detail to see what's possible.

The 0.7 version is based on the 0.6 release from https://github.com/YellowInnovation/sofa.
It has been updated to the Rust 2018 edition standards, uses async I/O, and compiles against the latest serde and
reqwest libraries.

## Example code

You can launch the included example with:
```shell script
cargo run --example basic_operations
```

## Running tests

Make sure that you have an instance of CouchDB 2.0+ running, either via the supplied `docker-compose.yml` file or by yourself. It must be listening on the default port.
Since Couch 3.0 the "Admin Party" mode is no longer supported. This means you need to provide a username and password during launch.
The tests and examples assume an "admin" CouchDB user with a "password" CouchDB password. Docker run command:

```shell script
docker run --rm -p 5984:5984 -e COUCHDB_USER=admin -e COUCHDB_PASSWORD=password couchdb:3
```

And then
`cargo test -- --test-threads=1`

Single-threading the tests is very important because we need to make sure that the basic features are working before actually testing features on dbs/documents.

## Why the name "Sofa"

CouchDB has a nice name, and I wanted to reflect that.

## License

Licensed under either of these:

* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
[https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or
[https://opensource.org/licenses/MIT](https://opensource.org/licenses/MIT))


[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FYellowInnovation%2Fsofa.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2FYellowInnovation%2Fsofa?ref=badge_large)

## Yellow Innovation
Yellow Innovation is the innovation laboratory of the French postal service: La Poste.
We create innovative user experiences and journeys through services with a focus on IoT lately.
## Yellow Innovation

Yellow Innovation is the innovation laboratory of the French postal service: La Poste.

We create innovative user experiences and journeys through services with a focus on IoT lately.

[Yellow Innovation's website and works](http://yellowinnovation.fr/en/)
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ version: '3'
services:

couchdb:
image: couchdb:2.2
image: couchdb:3
restart: always
ports:
- '5984:5984'
54 changes: 54 additions & 0 deletions examples/async_batch_read/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
extern crate sofa;

use sofa::document::DocumentCollection;
use std::fs::File;
use std::io::prelude::*;
use std::time::SystemTime;
use tokio::sync::mpsc;
use tokio::sync::mpsc::{Receiver, Sender};

const DB_HOST: &str = "http://admin:password@localhost:5984";
const TEST_DB: &str = "test_db";

#[tokio::main]
async fn main() {
println!("Connecting...");
let now = SystemTime::now();

// Create a sender and receiver channel pair
let (tx, mut rx): (Sender<DocumentCollection>, Receiver<DocumentCollection>) = mpsc::channel(100);

// Spawn a separate thread to retrieve the batches from Couch
let t = tokio::spawn(async move {
let client = sofa::Client::new_with_timeout(DB_HOST, 120).unwrap();
let db = client.db(TEST_DB).await.unwrap();

if let Err(err) = db.get_all_batched(tx, 0, 0).await {
println!("error during batch read: {:?}", err);
}
});

// Open a file for writing
let mut file = File::create("test_db.json").unwrap();

// Loop until the receiving channel is closed.
while let Some(all_docs) = rx.recv().await {
println!("Received {} docs", all_docs.total_rows);

// unmarshal the documents and write them to a file.
// (there is probably a more efficient way of doing this...)
for row in all_docs.rows {
file.write_all(serde_json::to_string(&row.doc).unwrap().as_bytes())
.unwrap();
}
}

// Make sure the file is written before exiting
file.sync_all().unwrap();

let elapsed = now.elapsed().unwrap_or_default();
println!("{} ms", elapsed.as_millis());

// Wait for the spawned task to finish (should be done by now).
t.await.unwrap();
}
Loading