Add ltree, lquery and ltxtquery support
This commit is contained in:
parent
a638adaf79
commit
944b72974f
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "postgres-protocol"
|
name = "postgres-protocol"
|
||||||
version = "0.6.3"
|
version = "0.6.4"
|
||||||
authors = ["Steven Fackler <sfackler@gmail.com>"]
|
authors = ["Steven Fackler <sfackler@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
description = "Low level Postgres protocol APIs"
|
description = "Low level Postgres protocol APIs"
|
||||||
|
@ -1059,3 +1059,19 @@ impl Inet {
|
|||||||
self.netmask
|
self.netmask
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Serializes a Postgres l{tree,query,txtquery} string
|
||||||
|
#[inline]
|
||||||
|
pub fn ltree_to_sql(v: &str, buf: &mut BytesMut) {
|
||||||
|
// A version number is prepended to an Ltree string per spec
|
||||||
|
buf.put_u8(1);
|
||||||
|
// Append the rest of the query
|
||||||
|
buf.put_slice(v.as_bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deserialize a Postgres l{tree,query,txtquery} string
|
||||||
|
#[inline]
|
||||||
|
pub fn ltree_from_sql(buf: &[u8]) -> Result<&str, StdBox<dyn Error + Sync + Send>> {
|
||||||
|
// Remove the version number from the front of the string per spec
|
||||||
|
Ok(str::from_utf8(&buf[1..])?)
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "postgres-types"
|
name = "postgres-types"
|
||||||
version = "0.2.2"
|
version = "0.2.3"
|
||||||
authors = ["Steven Fackler <sfackler@gmail.com>"]
|
authors = ["Steven Fackler <sfackler@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
@ -28,7 +28,7 @@ with-time-0_3 = ["time-03"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
bytes = "1.0"
|
bytes = "1.0"
|
||||||
fallible-iterator = "0.2"
|
fallible-iterator = "0.2"
|
||||||
postgres-protocol = { version = "0.6.1", path = "../postgres-protocol" }
|
postgres-protocol = { version = "0.6.4", path = "../postgres-protocol" }
|
||||||
postgres-derive = { version = "0.4.0", optional = true, path = "../postgres-derive" }
|
postgres-derive = { version = "0.4.0", optional = true, path = "../postgres-derive" }
|
||||||
|
|
||||||
array-init = { version = "2", optional = true }
|
array-init = { version = "2", optional = true }
|
||||||
|
@ -594,8 +594,8 @@ impl<'a> FromSql<'a> for &'a [u8] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FromSql<'a> for String {
|
impl<'a> FromSql<'a> for String {
|
||||||
fn from_sql(_: &Type, raw: &'a [u8]) -> Result<String, Box<dyn Error + Sync + Send>> {
|
fn from_sql(ty: &Type, raw: &'a [u8]) -> Result<String, Box<dyn Error + Sync + Send>> {
|
||||||
types::text_from_sql(raw).map(ToString::to_string)
|
<&str as FromSql>::from_sql(ty, raw).map(ToString::to_string)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accepts(ty: &Type) -> bool {
|
fn accepts(ty: &Type) -> bool {
|
||||||
@ -604,8 +604,8 @@ impl<'a> FromSql<'a> for String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FromSql<'a> for Box<str> {
|
impl<'a> FromSql<'a> for Box<str> {
|
||||||
fn from_sql(_: &Type, raw: &'a [u8]) -> Result<Box<str>, Box<dyn Error + Sync + Send>> {
|
fn from_sql(ty: &Type, raw: &'a [u8]) -> Result<Box<str>, Box<dyn Error + Sync + Send>> {
|
||||||
types::text_from_sql(raw)
|
<&str as FromSql>::from_sql(ty, raw)
|
||||||
.map(ToString::to_string)
|
.map(ToString::to_string)
|
||||||
.map(String::into_boxed_str)
|
.map(String::into_boxed_str)
|
||||||
}
|
}
|
||||||
@ -616,14 +616,26 @@ impl<'a> FromSql<'a> for Box<str> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FromSql<'a> for &'a str {
|
impl<'a> FromSql<'a> for &'a str {
|
||||||
fn from_sql(_: &Type, raw: &'a [u8]) -> Result<&'a str, Box<dyn Error + Sync + Send>> {
|
fn from_sql(ty: &Type, raw: &'a [u8]) -> Result<&'a str, Box<dyn Error + Sync + Send>> {
|
||||||
types::text_from_sql(raw)
|
match *ty {
|
||||||
|
ref ty if (
|
||||||
|
ty.name() == "ltree" ||
|
||||||
|
ty.name() == "lquery" ||
|
||||||
|
ty.name() == "ltxtquery"
|
||||||
|
) => types::ltree_from_sql(raw),
|
||||||
|
_ => types::text_from_sql(raw)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accepts(ty: &Type) -> bool {
|
fn accepts(ty: &Type) -> bool {
|
||||||
match *ty {
|
match *ty {
|
||||||
Type::VARCHAR | Type::TEXT | Type::BPCHAR | Type::NAME | Type::UNKNOWN => true,
|
Type::VARCHAR | Type::TEXT | Type::BPCHAR | Type::NAME | Type::UNKNOWN => true,
|
||||||
ref ty if ty.name() == "citext" => true,
|
ref ty if (
|
||||||
|
ty.name() == "citext" ||
|
||||||
|
ty.name() == "ltree" ||
|
||||||
|
ty.name() == "lquery" ||
|
||||||
|
ty.name() == "ltxtquery"
|
||||||
|
) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -924,15 +936,27 @@ impl ToSql for Vec<u8> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ToSql for &'a str {
|
impl<'a> ToSql for &'a str {
|
||||||
fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
|
fn to_sql(&self, ty: &Type, w: &mut BytesMut) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
|
||||||
types::text_to_sql(*self, w);
|
match ty {
|
||||||
|
ref ty if (
|
||||||
|
ty.name() == "ltree" ||
|
||||||
|
ty.name() == "lquery" ||
|
||||||
|
ty.name() == "ltxtquery"
|
||||||
|
) => types::ltree_to_sql(*self, w),
|
||||||
|
_ => types::text_to_sql(*self, w)
|
||||||
|
}
|
||||||
Ok(IsNull::No)
|
Ok(IsNull::No)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accepts(ty: &Type) -> bool {
|
fn accepts(ty: &Type) -> bool {
|
||||||
match *ty {
|
match *ty {
|
||||||
Type::VARCHAR | Type::TEXT | Type::BPCHAR | Type::NAME | Type::UNKNOWN => true,
|
Type::VARCHAR | Type::TEXT | Type::BPCHAR | Type::NAME | Type::UNKNOWN => true,
|
||||||
ref ty if ty.name() == "citext" => true,
|
ref ty if (
|
||||||
|
ty.name() == "citext" ||
|
||||||
|
ty.name() == "ltree" ||
|
||||||
|
ty.name() == "lquery" ||
|
||||||
|
ty.name() == "ltxtquery"
|
||||||
|
) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "tokio-postgres"
|
name = "tokio-postgres"
|
||||||
version = "0.7.5"
|
version = "0.7.6"
|
||||||
authors = ["Steven Fackler <sfackler@gmail.com>"]
|
authors = ["Steven Fackler <sfackler@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
@ -50,8 +50,8 @@ parking_lot = "0.12"
|
|||||||
percent-encoding = "2.0"
|
percent-encoding = "2.0"
|
||||||
pin-project-lite = "0.2"
|
pin-project-lite = "0.2"
|
||||||
phf = "0.10"
|
phf = "0.10"
|
||||||
postgres-protocol = { version = "0.6.1", path = "../postgres-protocol" }
|
postgres-protocol = { version = "0.6.4", path = "../postgres-protocol" }
|
||||||
postgres-types = { version = "0.2.2", path = "../postgres-types" }
|
postgres-types = { version = "0.2.3", path = "../postgres-types" }
|
||||||
socket2 = "0.4"
|
socket2 = "0.4"
|
||||||
tokio = { version = "1.0", features = ["io-util"] }
|
tokio = { version = "1.0", features = ["io-util"] }
|
||||||
tokio-util = { version = "0.7", features = ["codec"] }
|
tokio-util = { version = "0.7", features = ["codec"] }
|
||||||
|
@ -648,3 +648,78 @@ async fn inet() {
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn ltree() {
|
||||||
|
let client = connect("user=postgres").await;
|
||||||
|
client.execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]).await.unwrap();
|
||||||
|
|
||||||
|
test_type("ltree", &[
|
||||||
|
(Some("b.c.d".to_owned()), "'b.c.d'"),
|
||||||
|
(None, "NULL"),
|
||||||
|
]).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn ltree_any() {
|
||||||
|
let client = connect("user=postgres").await;
|
||||||
|
client.execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]).await.unwrap();
|
||||||
|
|
||||||
|
test_type("ltree[]", &[
|
||||||
|
(Some(vec![]), "ARRAY[]"),
|
||||||
|
(Some(vec!["a.b.c".to_string()]), "ARRAY['a.b.c']"),
|
||||||
|
(Some(vec!["a.b.c".to_string(), "e.f.g".to_string()]), "ARRAY['a.b.c','e.f.g']"),
|
||||||
|
(None, "NULL"),
|
||||||
|
]).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn lquery() {
|
||||||
|
let client = connect("user=postgres").await;
|
||||||
|
client.execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]).await.unwrap();
|
||||||
|
|
||||||
|
test_type("lquery", &[
|
||||||
|
(Some("b.c.d".to_owned()), "'b.c.d'"),
|
||||||
|
(Some("b.c.*".to_owned()), "'b.c.*'"),
|
||||||
|
(Some("b.*{1,2}.d|e".to_owned()), "'b.*{1,2}.d|e'"),
|
||||||
|
(None, "NULL"),
|
||||||
|
]).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn lquery_any() {
|
||||||
|
let client = connect("user=postgres").await;
|
||||||
|
client.execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]).await.unwrap();
|
||||||
|
|
||||||
|
test_type("lquery[]", &[
|
||||||
|
(Some(vec![]), "ARRAY[]"),
|
||||||
|
(Some(vec!["b.c.*".to_string()]), "ARRAY['b.c.*']"),
|
||||||
|
(Some(vec!["b.c.*".to_string(), "b.*{1,2}.d|e".to_string()]), "ARRAY['b.c.*','b.*{1,2}.d|e']"),
|
||||||
|
(None, "NULL"),
|
||||||
|
]).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn ltxtquery() {
|
||||||
|
let client = connect("user=postgres").await;
|
||||||
|
client.execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]).await.unwrap();
|
||||||
|
|
||||||
|
test_type("ltxtquery", &[
|
||||||
|
(Some("b & c & d".to_owned()), "'b & c & d'"),
|
||||||
|
(Some("b@* & !c".to_owned()), "'b@* & !c'"),
|
||||||
|
(None, "NULL"),
|
||||||
|
]).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn ltxtquery_any() {
|
||||||
|
let client = connect("user=postgres").await;
|
||||||
|
client.execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]).await.unwrap();
|
||||||
|
|
||||||
|
test_type("ltxtquery[]", &[
|
||||||
|
(Some(vec![]), "ARRAY[]"),
|
||||||
|
(Some(vec!["b & c & d".to_string()]), "ARRAY['b & c & d']"),
|
||||||
|
(Some(vec!["b & c & d".to_string(), "b@* & !c".to_string()]), "ARRAY['b & c & d','b@* & !c']"),
|
||||||
|
(None, "NULL"),
|
||||||
|
]).await;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user