Skip to content

Commit 904a774

Browse files
authored
Feat: Bolt 6.0 (vector types) (#45)
1 parent a5760a9 commit 904a774

File tree

33 files changed

+1822
-102
lines changed

33 files changed

+1822
-102
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
## NEXT
66
***
7+
**⭐️ New Features**
8+
- Add Support for Bolt 6.0: vector types.
9+
710
**👏️ Improvements**
811
- Reduce network latency in some cases by setting `TCP_NODELAY`.
912
- ⚠️ Reduce the size of `Neo4jError`. The `ServerError` variant is now wrapped in a Box.

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ A bump in MSRV is considered a minor breaking change.
165165
* [x] (GQL errors)
166166
* [x] (new bolt version handshake)
167167
* [x] 5.8 (home db resolution cache)
168+
* [x] 6.0
169+
* [x] (vector types)
170+
* [ ] (unsupported type)
168171
* [x] Types
169172
* [x] `Null`
170173
* [x] `Integer`

neo4j/src/driver/home_db_cache.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use std::time::Instant;
2323

2424
use super::auth::AuthToken;
2525
use crate::value::spatial;
26+
use crate::value::vector;
2627
use crate::{value, ValueSend};
2728

2829
#[derive(Debug)]
@@ -220,6 +221,16 @@ impl SessionAuthKey {
220221
ValueSend::LocalDateTime(v) => v.hash(state),
221222
ValueSend::DateTime(v) => v.hash(state),
222223
ValueSend::DateTimeFixed(v) => v.hash(state),
224+
ValueSend::Vector(vector::Vector::F64(v)) => {
225+
v.iter().for_each(|v| v.to_bits().hash(state))
226+
}
227+
ValueSend::Vector(vector::Vector::F32(v)) => {
228+
v.iter().for_each(|v| v.to_bits().hash(state))
229+
}
230+
ValueSend::Vector(vector::Vector::I64(v)) => v.hash(state),
231+
ValueSend::Vector(vector::Vector::I32(v)) => v.hash(state),
232+
ValueSend::Vector(vector::Vector::I16(v)) => v.hash(state),
233+
ValueSend::Vector(vector::Vector::I8(v)) => v.hash(state),
223234
}
224235
}
225236
}

neo4j/src/driver/io/bolt.rs

Lines changed: 44 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ mod bolt5x4;
2323
mod bolt5x6;
2424
mod bolt5x7;
2525
mod bolt5x8;
26+
mod bolt6x0;
2627
mod bolt_handler;
2728
mod bolt_state;
2829
mod chunk;
@@ -64,6 +65,7 @@ use bolt5x4::{Bolt5x4, Bolt5x4StructTranslator};
6465
use bolt5x6::{Bolt5x6, Bolt5x6StructTranslator};
6566
use bolt5x7::{Bolt5x7, Bolt5x7StructTranslator};
6667
use bolt5x8::{Bolt5x8, Bolt5x8StructTranslator};
68+
use bolt6x0::{Bolt6x0, Bolt6x0StructTranslator};
6769
use bolt_common::ServerAwareBoltVersion;
6870
use bolt_handler::{
6971
BeginHandler, CommitHandler, DiscardHandler, GoodbyeHandler, HandleResponseHandler,
@@ -203,6 +205,7 @@ pub(crate) struct Bolt<RW: Read + Write> {
203205
protocol: BoltProtocol,
204206
}
205207

208+
// [bolt-version-bump] search tag when changing bolt version support
206209
impl<RW: Read + Write> Bolt<RW> {
207210
fn new(
208211
version: (u8, u8),
@@ -211,44 +214,39 @@ impl<RW: Read + Write> Bolt<RW> {
211214
local_port: Option<u16>,
212215
address: Arc<Address>,
213216
) -> Self {
214-
let (protocol_version, protocol) = match version {
215-
(5, 8) => (
216-
ServerAwareBoltVersion::V5x8,
217-
Bolt5x8::<Bolt5x0StructTranslator>::default().into(),
218-
),
219-
(5, 7) => (
220-
ServerAwareBoltVersion::V5x7,
221-
Bolt5x7::<Bolt5x0StructTranslator>::default().into(),
222-
),
223-
(5, 6) => (
224-
ServerAwareBoltVersion::V5x6,
225-
Bolt5x6::<Bolt5x0StructTranslator>::default().into(),
226-
),
227-
(5, 4) => (
228-
ServerAwareBoltVersion::V5x4,
229-
Bolt5x4::<Bolt5x0StructTranslator>::default().into(),
230-
),
231-
(5, 3) => (
232-
ServerAwareBoltVersion::V5x3,
233-
Bolt5x3::<Bolt5x0StructTranslator>::default().into(),
234-
),
235-
(5, 2) => (
236-
ServerAwareBoltVersion::V5x2,
237-
Bolt5x2::<Bolt5x0StructTranslator>::default().into(),
238-
),
239-
(5, 1) => (
240-
ServerAwareBoltVersion::V5x1,
241-
Bolt5x1::<Bolt5x0StructTranslator>::default().into(),
242-
),
243-
(5, 0) => (
244-
ServerAwareBoltVersion::V5x0,
245-
Bolt5x0::<Bolt5x0StructTranslator>::default().into(),
246-
),
247-
(4, 4) => (
248-
ServerAwareBoltVersion::V4x4,
249-
Bolt4x4::<Bolt4x4StructTranslator>::default().into(),
250-
),
251-
_ => panic!("implement protocol for version {version:?}"),
217+
let protocol_version = ServerAwareBoltVersion::parse(version.0, version.1)
218+
.unwrap_or_else(|| panic!("implement protocol for version {version:?}"));
219+
let protocol = match protocol_version {
220+
ServerAwareBoltVersion::V6x0 => {
221+
Bolt6x0::<Bolt6x0StructTranslator>::new(protocol_version).into()
222+
}
223+
ServerAwareBoltVersion::V5x8 => {
224+
Bolt5x8::<Bolt5x8StructTranslator>::new(protocol_version).into()
225+
}
226+
ServerAwareBoltVersion::V5x7 => {
227+
Bolt5x7::<Bolt5x7StructTranslator>::new(protocol_version).into()
228+
}
229+
ServerAwareBoltVersion::V5x6 => {
230+
Bolt5x6::<Bolt5x6StructTranslator>::new(protocol_version).into()
231+
}
232+
ServerAwareBoltVersion::V5x4 => {
233+
Bolt5x4::<Bolt5x4StructTranslator>::new(protocol_version).into()
234+
}
235+
ServerAwareBoltVersion::V5x3 => {
236+
Bolt5x3::<Bolt5x3StructTranslator>::new(protocol_version).into()
237+
}
238+
ServerAwareBoltVersion::V5x2 => {
239+
Bolt5x2::<Bolt5x2StructTranslator>::new(protocol_version).into()
240+
}
241+
ServerAwareBoltVersion::V5x1 => {
242+
Bolt5x1::<Bolt5x1StructTranslator>::new(protocol_version).into()
243+
}
244+
ServerAwareBoltVersion::V5x0 => {
245+
Bolt5x0::<Bolt5x0StructTranslator>::new(protocol_version).into()
246+
}
247+
ServerAwareBoltVersion::V4x4 => {
248+
Bolt4x4::<Bolt4x4StructTranslator>::new(protocol_version).into()
249+
}
252250
};
253251
let data = BoltData::new(
254252
version,
@@ -505,6 +503,7 @@ enum BoltProtocol {
505503
V5x6(Bolt5x6<Bolt5x6StructTranslator>),
506504
V5x7(Bolt5x7<Bolt5x7StructTranslator>),
507505
V5x8(Bolt5x8<Bolt5x8StructTranslator>),
506+
V6x0(Bolt6x0<Bolt6x0StructTranslator>),
508507
}
509508

510509
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
@@ -783,7 +782,9 @@ impl AuthResetHandle {
783782
}
784783
}
785784

786-
pub(crate) trait BoltStructTranslator: Debug + Default {
785+
pub(crate) trait BoltStructTranslator: Debug {
786+
fn new(bolt_version: ServerAwareBoltVersion) -> Self;
787+
787788
fn serialize<S: PackStreamSerializer>(
788789
&self,
789790
serializer: &mut S,
@@ -794,6 +795,10 @@ pub(crate) trait BoltStructTranslator: Debug + Default {
794795
}
795796

796797
impl<T: BoltStructTranslator> BoltStructTranslator for Arc<AtomicRefCell<T>> {
798+
fn new(bolt_version: ServerAwareBoltVersion) -> Self {
799+
Arc::new(AtomicRefCell::new(T::new(bolt_version)))
800+
}
801+
797802
fn serialize<S: PackStreamSerializer>(
798803
&self,
799804
serializer: &mut S,

neo4j/src/driver/io/bolt/bolt4x4/protocol.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use std::sync::Arc;
1717

1818
use atomic_refcell::AtomicRefCell;
1919

20+
use super::super::bolt_common::ServerAwareBoltVersion;
2021
use super::super::bolt_handler::{
2122
begin_5x0::BeginHandler5x0, commit_5x0::CommitHandler5x0, goodbye_5x0::GoodbyeHandler5x0,
2223
hello_4x4::HelloHandler4x4, impl_begin, impl_commit, impl_discard, impl_goodbye, impl_hello,
@@ -30,11 +31,19 @@ use super::super::bolt_handler::{
3031
};
3132
use super::super::BoltStructTranslatorWithUtcPatch;
3233

33-
#[derive(Debug, Default)]
34+
#[derive(Debug)]
3435
pub(crate) struct Bolt4x4<T: BoltStructTranslatorWithUtcPatch + Sync + Send + 'static> {
3536
translator: Arc<AtomicRefCell<T>>,
3637
}
3738

39+
impl<T: BoltStructTranslatorWithUtcPatch + Sync + Send + 'static> Bolt4x4<T> {
40+
pub(crate) fn new(bolt_version: ServerAwareBoltVersion) -> Self {
41+
Self {
42+
translator: Arc::new(AtomicRefCell::new(T::new(bolt_version))),
43+
}
44+
}
45+
}
46+
3847
impl_hello!((BoltStructTranslatorWithUtcPatch, Sync, Send, 'static), Bolt4x4<T>, HelloHandler4x4);
3948
impl_reauth!((BoltStructTranslatorWithUtcPatch, Sync, Send, 'static), Bolt4x4<T>, ReauthUnsupportedHandler);
4049
impl_goodbye!((BoltStructTranslatorWithUtcPatch, Sync, Send, 'static), Bolt4x4<T>, GoodbyeHandler5x0);

neo4j/src/driver/io/bolt/bolt4x4/translator.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,27 @@ use usize_cast::IntoIsize;
1919

2020
use super::super::bolt5x0::Bolt5x0StructTranslator;
2121
use super::super::bolt_common::*;
22-
use super::super::{BoltStructTranslator, BoltStructTranslatorWithUtcPatch};
23-
use crate::driver::io::bolt::PackStreamSerializer;
22+
use super::super::{BoltStructTranslator, BoltStructTranslatorWithUtcPatch, PackStreamSerializer};
2423
use crate::value::graph::{Node, Path, Relationship, UnboundRelationship};
2524
use crate::value::time::chrono::{FixedOffset, LocalResult, Offset, TimeZone};
2625
use crate::value::time::chrono_tz::Tz;
2726
use crate::value::time::{local_date_time_from_timestamp, DateTime, DateTimeFixed};
2827
use crate::value::{BrokenValue, BrokenValueInner, ValueReceive, ValueSend};
2928

30-
#[derive(Debug, Default)]
29+
#[derive(Debug)]
3130
pub(crate) struct Bolt4x4StructTranslator {
3231
utc_patch: bool,
3332
bolt5x0_translator: Bolt5x0StructTranslator,
3433
}
3534

3635
impl BoltStructTranslator for Bolt4x4StructTranslator {
36+
fn new(bolt_version: ServerAwareBoltVersion) -> Self {
37+
Self {
38+
utc_patch: false,
39+
bolt5x0_translator: Bolt5x0StructTranslator::new(bolt_version),
40+
}
41+
}
42+
3743
fn serialize<S: PackStreamSerializer>(
3844
&self,
3945
serializer: &mut S,

neo4j/src/driver/io/bolt/bolt5x0/protocol.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
use super::super::bolt_common::ServerAwareBoltVersion;
1516
use super::super::bolt_handler::{
1617
begin_5x0::BeginHandler5x0, commit_5x0::CommitHandler5x0, goodbye_5x0::GoodbyeHandler5x0,
1718
hello_5x0::HelloHandler5x0, impl_begin, impl_commit, impl_discard, impl_goodbye, impl_hello,
@@ -30,6 +31,14 @@ pub(crate) struct Bolt5x0<T: BoltStructTranslator> {
3031
translator: T,
3132
}
3233

34+
impl<T: BoltStructTranslator> Bolt5x0<T> {
35+
pub(crate) fn new(bolt_version: ServerAwareBoltVersion) -> Self {
36+
Self {
37+
translator: T::new(bolt_version),
38+
}
39+
}
40+
}
41+
3342
impl_hello!((BoltStructTranslator), Bolt5x0<T>, HelloHandler5x0);
3443
impl_reauth!((BoltStructTranslator), Bolt5x0<T>, ReauthUnsupportedHandler);
3544
impl_goodbye!((BoltStructTranslator), Bolt5x0<T>, GoodbyeHandler5x0);

neo4j/src/driver/io/bolt/bolt5x0/translator.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ use std::collections::VecDeque;
1717
use usize_cast::{FromUsize, IntoIsize};
1818

1919
use super::super::bolt_common::*;
20-
use super::super::BoltStructTranslator;
21-
use crate::driver::io::bolt::PackStreamSerializer;
20+
use super::super::{BoltStructTranslator, PackStreamSerializer};
2221
use crate::value::graph::{Node, Path, Relationship, UnboundRelationship};
2322
use crate::value::spatial::{
2423
Cartesian2D, Cartesian3D, SRID_CARTESIAN_2D, SRID_CARTESIAN_3D, SRID_WGS84_2D, SRID_WGS84_3D,
@@ -27,8 +26,10 @@ use crate::value::spatial::{
2726
use crate::value::time::{Date, DateTime, DateTimeFixed, Duration, LocalDateTime, LocalTime, Time};
2827
use crate::value::{BrokenValue, BrokenValueInner, ValueReceive, ValueSend};
2928

30-
#[derive(Debug, Default)]
31-
pub(crate) struct Bolt5x0StructTranslator {}
29+
#[derive(Debug)]
30+
pub(crate) struct Bolt5x0StructTranslator {
31+
bolt_version: ServerAwareBoltVersion,
32+
}
3233

3334
impl Bolt5x0StructTranslator {
3435
fn write_2d_point<S: PackStreamSerializer>(
@@ -58,6 +59,10 @@ impl Bolt5x0StructTranslator {
5859
}
5960

6061
impl BoltStructTranslator for Bolt5x0StructTranslator {
62+
fn new(bolt_version: ServerAwareBoltVersion) -> Self {
63+
Self { bolt_version }
64+
}
65+
6166
fn serialize<S: PackStreamSerializer>(
6267
&self,
6368
serializer: &mut S,
@@ -154,6 +159,11 @@ impl BoltStructTranslator for Bolt5x0StructTranslator {
154159
serializer.write_int(tz_offset.into())?;
155160
Ok(())
156161
}
162+
ValueSend::Vector(_) => Err(serializer.error(unsupported_protocol_feature_message(
163+
"vector types",
164+
self.bolt_version,
165+
ServerAwareBoltVersion::V6x0,
166+
))),
157167
}
158168
}
159169

neo4j/src/driver/io/bolt/bolt5x1/protocol.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
use super::super::bolt_common::ServerAwareBoltVersion;
1516
use super::super::bolt_handler::{
1617
begin_5x0::BeginHandler5x0, commit_5x0::CommitHandler5x0, goodbye_5x0::GoodbyeHandler5x0,
1718
hello_5x1::HelloHandler5x1, impl_begin, impl_commit, impl_discard, impl_goodbye, impl_hello,
@@ -30,6 +31,14 @@ pub(crate) struct Bolt5x1<T: BoltStructTranslator> {
3031
translator: T,
3132
}
3233

34+
impl<T: BoltStructTranslator> Bolt5x1<T> {
35+
pub(crate) fn new(bolt_version: ServerAwareBoltVersion) -> Self {
36+
Self {
37+
translator: T::new(bolt_version),
38+
}
39+
}
40+
}
41+
3342
impl_hello!((BoltStructTranslator), Bolt5x1<T>, HelloHandler5x1);
3443
impl_reauth!((BoltStructTranslator), Bolt5x1<T>, ReauthHandler5x1);
3544
impl_goodbye!((BoltStructTranslator), Bolt5x1<T>, GoodbyeHandler5x0);

neo4j/src/driver/io/bolt/bolt5x2/protocol.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
use super::super::bolt_common::ServerAwareBoltVersion;
1516
use super::super::bolt_handler::{
1617
begin_5x2::BeginHandler5x2, commit_5x0::CommitHandler5x0, goodbye_5x0::GoodbyeHandler5x0,
1718
hello_5x2::HelloHandler5x2, impl_begin, impl_commit, impl_discard, impl_goodbye, impl_hello,
@@ -30,6 +31,14 @@ pub(crate) struct Bolt5x2<T: BoltStructTranslator> {
3031
translator: T,
3132
}
3233

34+
impl<T: BoltStructTranslator> Bolt5x2<T> {
35+
pub(crate) fn new(bolt_version: ServerAwareBoltVersion) -> Self {
36+
Self {
37+
translator: T::new(bolt_version),
38+
}
39+
}
40+
}
41+
3342
impl_hello!((BoltStructTranslator), Bolt5x2<T>, HelloHandler5x2);
3443
impl_reauth!((BoltStructTranslator), Bolt5x2<T>, ReauthHandler5x1);
3544
impl_goodbye!((BoltStructTranslator), Bolt5x2<T>, GoodbyeHandler5x0);

0 commit comments

Comments
 (0)