neo4rs/
lib.rs

1//! Neo4j driver compatible with neo4j 4.x versions
2//!
3//! * An implementation of the [bolt protocol][bolt] to interact with Neo4j server
4//! * async/await apis using [tokio][tokio]
5//! * Supports bolt 4.2 specification
6//! * tested with Neo4j versions: 4.0, 4.1, 4.2
7//!
8//!
9//! [bolt]: https://7687.org/
10//! [tokio]: https://github.com/tokio-rs/tokio
11//!
12//!
13//! # Examples
14//!
15//! ```no_run
16//! use neo4rs::*;
17//!
18//! #[tokio::main]
19//! async fn main() {
20//!    let uri = "127.0.0.1:7687";
21//!    let user = "neo4j";
22//!    let pass = "neo";
23//!    let id = uuid::Uuid::new_v4().to_string();
24//!
25//!    let graph = Graph::new(uri, user, pass).await.unwrap();
26//!
27#![doc = include_str!("../include/example.rs")]
28//! }
29//! ```
30//!
31//! ## Configurations
32//!
33//! Use the config builder to override the default configurations like
34//! * `fetch_size` - number of rows to fetch in batches (default is 200)
35//! * `max_connections` - maximum size of the connection pool (default is 16)
36//! * `db` - the database to connect to (default is `neo4j`)
37//!
38//! ```no_run
39//! use neo4rs::*;
40//!
41//! #[tokio::main]
42//! async fn main() {
43//!    let config = ConfigBuilder::default()
44//!        .uri("127.0.0.1:7687")
45//!        .user("neo4j")
46//!        .password("neo")
47//!        .db("neo4j")
48//!        .fetch_size(500)
49//!        .max_connections(10)
50//!        .build()
51//!        .unwrap();
52//!    let graph = Graph::connect(config).await.unwrap();
53//!
54#![doc = include_str!("../include/configurations.rs")]
55//! }
56//! ```
57//!
58//! ## Nodes
59//! A simple example to create a node and consume the created node from the row stream.
60//!
61//! * [`Graph::run`] just returns [`errors::Result`]`<()>`, usually used for write only queries.
62//! * [`Graph::execute`] returns [`errors::Result`]`<`[`RowStream`]`>`
63//! ```no_run
64//! use neo4rs::*;
65//!
66//! #[tokio::main]
67//! async fn main() {
68//!    let uri = "127.0.0.1:7687";
69//!    let user = "neo4j";
70//!    let pass = "neo";
71//!    let graph = Graph::new(uri, user, pass).await.unwrap();
72//!
73#![doc = include_str!("../include/nodes.rs")]
74//! }
75//! ```
76//!
77//! ## Transactions
78//!
79//! Start a new transaction using [`Graph::start_txn`], which will return a handle [`Txn`] that can
80//! be used to [`Txn::commit`] or [`Txn::rollback`] the transaction.
81//!
82//! Note that the handle takes a connection from the connection pool, which will be released once
83//! the Txn is dropped
84//!
85//!
86//! ```no_run
87//! use neo4rs::*;
88//!
89//! #[tokio::main]
90//! async fn main() {
91//!    let uri = "127.0.0.1:7687";
92//!    let user = "neo4j";
93//!    let pass = "neo";
94//!    let graph = Graph::new(uri, user, pass).await.unwrap();
95//!
96#![doc = include_str!("../include/transactions.rs")]
97//! }
98//!
99//! ```
100//!
101//! ### Streams within a transaction
102//!
103//! Each [`RowStream`] returned by various execute functions within the same
104//! transaction are well isolated, so you can consume the stream anytime
105//! within the transaction using [`RowStream::next`]
106//!
107//!
108//! ```no_run
109//! use neo4rs::*;
110//!
111//! #[tokio::main]
112//! async fn main() {
113//!    let config = ConfigBuilder::default()
114//!        .uri("127.0.0.1:7687")
115//!        .user("neo4j")
116//!        .password("neo")
117//!        .fetch_size(1)
118//!        .build()
119//!        .unwrap();
120//!    let graph = Graph::connect(config).await.unwrap();
121//!
122#![doc = include_str!("../include/streams_within_a_transaction.rs")]
123//! }
124//!
125//! ```
126//!
127//! ### Streams are evaluated lazily
128//!
129//! The [`RowStream`] returned by various `execute` functions need to be
130//! consumed with [`RowStream::next`] in order to actually execute the
131//! query.
132//! The various `run` functions on the other hand are always executed
133//! eagerly.
134//!
135//!
136//! ```no_run
137//! use neo4rs::*;
138//!
139//! #[tokio::main]
140//! async fn main() {
141//!    let uri = "127.0.0.1:7687";
142//!    let user = "neo4j";
143//!    let pass = "neo";
144//!    let graph = Graph::new(uri, user, pass).await.unwrap();
145//!
146#![doc = include_str!("../include/result_stream.rs")]
147//! }
148//!
149//! ```
150//!
151//! ### Rollback a transaction
152//! ```no_run
153//! use neo4rs::*;
154//!
155//! #[tokio::main]
156//! async fn main() {
157//!    let uri = "127.0.0.1:7687";
158//!    let user = "neo4j";
159//!    let pass = "neo";
160//!    let graph = Graph::new(uri, user, pass).await.unwrap();
161//!
162#![doc = include_str!("../include/rollback_a_transaction.rs")]
163//! }
164//!
165//! ```
166//!
167//! ### Txn vs Graph
168//!
169//! Everytime you execute a query using [`Graph::run`] or [`Graph::execute`], a new connection is
170//! taken from the pool and released immediately.
171//!
172//! However, when you execute a query on a transaction using [`Txn::run`] or [`Txn::execute`] the
173//! same connection will be reused, the underlying connection will be released to the pool in a
174//! clean state only after you commit/rollback the transaction and the [`Txn`] handle is dropped.
175//!
176//!
177//! ```no_run
178//! use neo4rs::*;
179//!
180//! #[tokio::main]
181//! async fn main() {
182//!    let uri = "127.0.0.1:7687";
183//!    let user = "neo4j";
184//!    let pass = "neo";
185//!    let graph = Graph::new(uri, user, pass).await.unwrap();
186//!
187#![doc = include_str!("../include/txn_vs_graph.rs")]
188//! }
189//!
190//! ```
191//!
192//! ## Relationships
193//!
194//! Bounded Relationship between nodes are created using cypher queries and the same can be parsed
195//! from the [`RowStream`]
196//!
197//! ```no_run
198//! use neo4rs::*;
199//!
200//! #[tokio::main]
201//! async fn main() {
202//!    let uri = "127.0.0.1:7687";
203//!    let user = "neo4j";
204//!    let pass = "neo";
205//!    let graph = Graph::new(uri, user, pass).await.unwrap();
206//!
207#![doc = include_str!("../include/relationships.rs")]
208//! }
209//! ```
210//!
211//!
212//! Similar to bounded relation, an unbounded relation can also be created/parsed.
213//!
214//! ```no_run
215//! use neo4rs::*;
216//!
217//! #[tokio::main]
218//! async fn main() {
219//!    let uri = "127.0.0.1:7687";
220//!    let user = "neo4j";
221//!    let pass = "neo";
222//!    let graph = Graph::new(uri, user, pass).await.unwrap();
223//!
224#![doc = include_str!("../include/unbounded_relationships.rs")]
225//! }
226//!
227//! ```
228//!
229//!
230//!
231//! ## Points
232//!
233//! A 2d or 3d point can be represented with the types  [`Point2D`] and [`Point3D`]
234//!
235//!
236//! ```no_run
237//! use neo4rs::*;
238//!
239//! #[tokio::main]
240//! async fn main() {
241//!    let uri = "127.0.0.1:7687";
242//!    let user = "neo4j";
243//!    let pass = "neo";
244//!    let graph = Graph::new(uri, user, pass).await.unwrap();
245//!
246//!    let qry = "
247//!        WITH point({ x: 2.3, y: 4.5, crs: 'cartesian' }) AS p1,
248//!             point({ x: 1.1, y: 5.4, crs: 'cartesian' }) AS p2
249//!        RETURN point.distance(p1,p2) AS dist, p1, p2
250//!     ";
251#![doc = include_str!("../include/points.rs")]
252//! }
253//!
254//! ```
255//!
256//! ## Raw bytes
257//!
258//!
259//! ```no_run
260//! use neo4rs::*;
261//!
262//! #[tokio::main]
263//! async fn main() {
264//!    let uri = "127.0.0.1:7687";
265//!    let user = "neo4j";
266//!    let pass = "neo";
267//!    let graph = Graph::new(uri, user, pass).await.unwrap();
268//!
269#![doc = include_str!("../include/raw_bytes.rs")]
270//! }
271//!
272//! ```
273//!
274//! ## Durations
275//!
276//!
277//! ```no_run
278//! use neo4rs::*;
279//!
280//! #[tokio::main]
281//! async fn main() {
282//!    let uri = "127.0.0.1:7687";
283//!    let user = "neo4j";
284//!    let pass = "neo";
285//!    let graph = Graph::new(uri, user, pass).await.unwrap();
286//!
287#![doc = include_str!("../include/durations.rs")]
288//! }
289//!
290//! ```
291//! ## Date
292//!
293//! See [NaiveDate][naive_date] for date abstraction, it captures the date without time component.
294//!
295//! [naive_date]: https://docs.rs/chrono/0.4.19/chrono/naive/struct.NaiveDate.html
296//!
297//! ```no_run
298//! use neo4rs::*;
299//!
300//! #[tokio::main]
301//! async fn main() {
302//!    let uri = "127.0.0.1:7687";
303//!    let user = "neo4j";
304//!    let pass = "neo";
305//!    let graph = Graph::new(uri, user, pass).await.unwrap();
306//!
307#![doc = include_str!("../include/dates.rs")]
308//! }
309//! ```
310//!
311//!
312//! ## Time
313//!
314//! * [NaiveTime][naive_time] captures only the time of the day
315//! * `tuple`([NaiveTime][naive_time], `Option`<[FixedOffset][fixed_offset]>) captures the time of the day along with the
316//! offset
317//!
318//! [naive_time]: https://docs.rs/chrono/0.4.19/chrono/naive/struct.NaiveTime.html
319//! [fixed_offset]: https://docs.rs/chrono/0.4.19/chrono/offset/struct.FixedOffset.html
320//!
321//!
322//! ### Time as param
323//!
324//! Pass a time as a parameter to the query:
325//!
326//! ```no_run
327//! use neo4rs::*;
328//!
329//! #[tokio::main]
330//! async fn main() {
331//!    let uri = "127.0.0.1:7687";
332//!    let user = "neo4j";
333//!    let pass = "neo";
334//!    let graph = Graph::new(uri, user, pass).await.unwrap();
335//!
336#![doc = include_str!("../include/time_as_param.rs")]
337//! }
338//! ```
339//!
340//!
341//! ### Parsing time from result
342//!
343//! ```no_run
344//! use neo4rs::*;
345//!
346//! #[tokio::main]
347//! async fn main() {
348//!    let uri = "127.0.0.1:7687";
349//!    let user = "neo4j";
350//!    let pass = "neo";
351//!    let graph = Graph::new(uri, user, pass).await.unwrap();
352//!
353#![doc = include_str!("../include/parse_time_from_result.rs")]
354//! }
355//!
356//! ```
357//!
358//!
359//! ## DateTime
360//!
361//!
362//! * [DateTime][date_time] captures the date and time with offset
363//! * [NaiveDateTime][naive_date_time] captures the date time without offset
364//! * `tuple`([NaiveDateTime][naive_date_time], String)  captures the date/time and the time zone id
365//!
366//! [date_time]: https://docs.rs/chrono/0.4.19/chrono/struct.DateTime.html
367//! [naive_date_time]: https://docs.rs/chrono/0.4.19/chrono/struct.NaiveDateTime.html
368//!
369//!
370//! ### DateTime as param
371//!
372//! Pass a DateTime as parameter to the query:
373//!
374//! ```no_run
375//! use neo4rs::*;
376//!
377//! #[tokio::main]
378//! async fn main() {
379//!    let uri = "127.0.0.1:7687";
380//!    let user = "neo4j";
381//!    let pass = "neo";
382//!    let graph = Graph::new(uri, user, pass).await.unwrap();
383//!
384#![doc = include_str!("../include/datetime_as_param.rs")]
385//! }
386//! ```
387//!
388//! ### Parsing DateTime from result
389//!
390//! ```no_run
391//! use neo4rs::*;
392//!
393//! #[tokio::main]
394//! async fn main() {
395//!    let uri = "127.0.0.1:7687";
396//!    let user = "neo4j";
397//!    let pass = "neo";
398//!    let graph = Graph::new(uri, user, pass).await.unwrap();
399//!
400#![doc = include_str!("../include/parse_datetime_from_result.rs")]
401//! }
402//!
403//! ```
404//!
405//!
406//!
407//! ## Path
408//!
409//! ```no_run
410//! use neo4rs::*;
411//!
412//! #[tokio::main]
413//! async fn main() {
414//!    let uri = "127.0.0.1:7687";
415//!    let user = "neo4j";
416//!    let pass = "neo";
417//!    let graph = Graph::new(uri, user, pass).await.unwrap();
418//!
419#![doc = include_str!("../include/path.rs")]
420//! }
421//! ```
422//!
423//!
424mod auth;
425mod config;
426mod connection;
427mod convert;
428mod errors;
429mod graph;
430mod messages;
431mod pool;
432mod query;
433mod row;
434mod stream;
435mod txn;
436mod types;
437mod version;
438
439pub use crate::auth::ClientCertificate;
440pub use crate::config::{Config, ConfigBuilder, Database};
441pub use crate::errors::{
442    unexpected, Error, Neo4jClientErrorKind, Neo4jError, Neo4jErrorKind, Neo4jSecurityErrorKind,
443    Result,
444};
445pub use crate::graph::{query, Graph};
446pub use crate::query::Query;
447pub use crate::row::{Node, Path, Point2D, Point3D, Relation, Row, UnboundedRelation};
448pub use crate::stream::RowStream;
449pub use crate::txn::Txn;
450pub use crate::types::serde::{
451    DeError, EndNodeId, Id, Indices, Keys, Labels, Nodes, Offset, Relationships, StartNodeId,
452    Timezone, Type,
453};
454pub use crate::types::{
455    BoltBoolean, BoltBytes, BoltDate, BoltDateTime, BoltDateTimeZoneId, BoltDuration, BoltFloat,
456    BoltInteger, BoltList, BoltLocalDateTime, BoltLocalTime, BoltMap, BoltNode, BoltNull, BoltPath,
457    BoltPoint2D, BoltPoint3D, BoltRelation, BoltString, BoltTime, BoltType, BoltUnboundedRelation,
458};
459pub use crate::version::Version;
460
461pub(crate) use messages::Success;