diff --git a/Cargo.toml b/Cargo.toml index b2481cc..5fa0f65 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,16 +1,17 @@ [package] name = "postgres_array" -version = "0.9.0" +version = "0.11.1" authors = ["Steven Fackler "] +edition = "2018" license = "MIT" description = "Array support for rust-postgres" repository = "https://github.com/sfackler/rust-postgres-array" -documentation = "https://docs.rs/postgres_array/0.9.0/postgres_array" [dependencies] -fallible-iterator = "0.1" -postgres-shared = "0.4" -postgres-protocol = "0.3" +bytes = "1.0" +fallible-iterator = "0.2" +postgres-types = "0.2" +postgres-protocol = "0.6" [dev-dependencies] -postgres = "0.15" +postgres = "0.19" diff --git a/README.md b/README.md index 1ae0889..0008029 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # rust-postgres-array -[![Build Status](https://travis-ci.org/sfackler/rust-postgres-array.svg?branch=master)](https://travis-ci.org/sfackler/rust-postgres-array) +[![CircleCI](https://circleci.com/gh/sfackler/rust-postgres-array.svg?style=shield)](https://circleci.com/gh/sfackler/rust-postgres-array) -[Documentation](https://sfackler.github.io/rust-postgres-array/doc/v0.7.1/postgres_array) +[Documentation](https://docs.rs/postgres_array) Support for PostgreSQL arrays in [rust-postgres](https://github.com/sfackler/rust-postgres). diff --git a/circle.yml b/circle.yml index a648ab0..8e1b563 100644 --- a/circle.yml +++ b/circle.yml @@ -1,10 +1,9 @@ version: 2 jobs: build: - working_directory: ~/build docker: - - image: jimmycuadra/rust:1.19.0 - - image: postgres:9.6 + - image: rust:1.64.0 + - image: postgres:12 environment: POSTGRES_PASSWORD: password steps: @@ -15,12 +14,12 @@ jobs: - save_cache: key: registry-{{ epoch }} paths: - - ~/.cargo/registry/index + - /usr/local/cargo/registry/index - restore_cache: - key: dependencies-1.19-{{ checksum "Cargo.lock" }} + key: dependencies-1.40-{{ checksum "Cargo.lock" }} - run: cargo test - save_cache: - key: dependencies-1.19-{{ checksum "Cargo.lock" }} + key: dependencies-1.40-{{ checksum "Cargo.lock" }} paths: - target - - ~/.cargo/registry/cache + - /usr/local/cargo/registry/cache diff --git a/src/array.rs b/src/array.rs index 1cf85b3..9886d8d 100644 --- a/src/array.rs +++ b/src/array.rs @@ -1,9 +1,9 @@ +use std::fmt; use std::ops::{Index, IndexMut}; use std::slice; use std::vec; -use std::fmt; -use Dimension; +use crate::Dimension; /// A multi-dimensional array. #[derive(Debug, PartialEq, Eq, Clone)] @@ -13,17 +13,17 @@ pub struct Array { } impl fmt::Display for Array { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { if self.dims.iter().any(|dim| dim.lower_bound != 1) { for dim in &self.dims { - try!(write!( + write!( fmt, "[{}:{}]", dim.lower_bound, dim.lower_bound + dim.len - 1 - )); + )?; } - try!(write!(fmt, "=")); + write!(fmt, "=")?; } fmt_helper(0, &self.dims, &mut self.data.iter(), fmt) } @@ -32,23 +32,27 @@ impl fmt::Display for Array { fn fmt_helper<'a, T, I>( depth: usize, dims: &[Dimension], - mut data: &mut I, - fmt: &mut fmt::Formatter, + data: &mut I, + fmt: &mut fmt::Formatter<'_>, ) -> fmt::Result where I: Iterator, T: 'a + fmt::Display, { + if dims.len() == 0 { + return write!(fmt, "{{}}"); + } + if depth == dims.len() { return write!(fmt, "{}", data.next().unwrap()); } - try!(write!(fmt, "{{")); + write!(fmt, "{{")?; for i in 0..dims[depth].len { if i != 0 { - try!(write!(fmt, ",")); + write!(fmt, ",")?; } - try!(fmt_helper(depth + 1, dims, data, fmt)); + fmt_helper(depth + 1, dims, data, fmt)?; } write!(fmt, "}}") } @@ -65,26 +69,24 @@ impl Array { /// elements specified by the dimensions. pub fn from_parts(data: Vec, dimensions: Vec) -> Array { assert!( - (data.is_empty() && dimensions.is_empty()) || - data.len() as i32 == dimensions.iter().fold(1, |acc, i| acc * i.len), + (data.is_empty() && dimensions.is_empty()) + || data.len() as i32 == dimensions.iter().fold(1, |acc, i| acc * i.len), "size mismatch" ); Array { dims: dimensions, - data: data, + data, } } /// Creates a new one-dimensional array. pub fn from_vec(data: Vec, lower_bound: i32) -> Array { Array { - dims: vec![ - Dimension { - len: data.len() as i32, - lower_bound: lower_bound, - }, - ], - data: data, + dims: vec![Dimension { + len: data.len() as i32, + lower_bound, + }], + data, } } @@ -97,7 +99,7 @@ impl Array { 0, Dimension { len: 1, - lower_bound: lower_bound, + lower_bound, }, ); } @@ -147,14 +149,18 @@ impl Array { /// Returns an iterator over references to the elements of the array in the /// higher-dimensional equivalent of row-major order. - pub fn iter<'a>(&'a self) -> Iter<'a, T> { - Iter { inner: self.data.iter() } + pub fn iter(&self) -> Iter<'_, T> { + Iter { + inner: self.data.iter(), + } } /// Returns an iterator over mutable references to the elements of the /// array in the higher-dimensional equivalent of row-major order. - pub fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T> { - IterMut { inner: self.data.iter_mut() } + pub fn iter_mut(&mut self) -> IterMut<'_, T> { + IterMut { + inner: self.data.iter_mut(), + } } /// Returns the underlying data vector for this Array in the @@ -293,13 +299,15 @@ impl IntoIterator for Array { type IntoIter = IntoIter; fn into_iter(self) -> IntoIter { - IntoIter { inner: self.data.into_iter() } + IntoIter { + inner: self.data.into_iter(), + } } } /// An iterator over references to values of an `Array` in the /// higher-dimensional equivalent of row-major order. -pub struct Iter<'a, T: 'a> { +pub struct Iter<'a, T> { inner: slice::Iter<'a, T>, } @@ -329,7 +337,7 @@ impl<'a, T: 'a> ExactSizeIterator for Iter<'a, T> { /// An iterator over mutable references to values of an `Array` in the /// higher-dimensional equivalent of row-major order. -pub struct IterMut<'a, T: 'a> { +pub struct IterMut<'a, T> { inner: slice::IterMut<'a, T>, } diff --git a/src/impls.rs b/src/impls.rs index 2bf4f15..399a36e 100644 --- a/src/impls.rs +++ b/src/impls.rs @@ -1,41 +1,38 @@ use fallible_iterator::FallibleIterator; -use postgres_shared::types::{Type, Kind, ToSql, FromSql, IsNull}; -use postgres_protocol::types; use postgres_protocol; +use postgres_protocol::types; +use postgres_types::{to_sql_checked, FromSql, IsNull, Kind, ToSql, Type}; use std::error::Error; -use {Array, Dimension}; +use crate::{Array, Dimension}; +use postgres_types::private::BytesMut; -impl FromSql for Array +impl<'de, T> FromSql<'de> for Array where - T: FromSql, + T: FromSql<'de>, { - fn from_sql(ty: &Type, raw: &[u8]) -> Result, Box> { + fn from_sql(ty: &Type, raw: &'de [u8]) -> Result, Box> { let element_type = match *ty.kind() { Kind::Array(ref ty) => ty, _ => unreachable!(), }; - let array = try!(types::array_from_sql(raw)); + let array = types::array_from_sql(raw)?; - let dimensions = try!( - array - .dimensions() - .map(|d| { - Dimension { - len: d.len, - lower_bound: d.lower_bound, - } + let dimensions = array + .dimensions() + .map(|d| { + Ok(Dimension { + len: d.len, + lower_bound: d.lower_bound, }) - .collect() - ); + }) + .collect()?; - let elements = try!( - array - .values() - .and_then(|v| FromSql::from_sql_nullable(element_type, v)) - .collect() - ); + let elements = array + .values() + .map(|v| FromSql::from_sql_nullable(element_type, v)) + .collect()?; Ok(Array::from_parts(elements, dimensions)) } @@ -52,23 +49,20 @@ impl ToSql for Array where T: ToSql, { - fn to_sql(&self, ty: &Type, w: &mut Vec) -> Result> { + fn to_sql(&self, ty: &Type, w: &mut BytesMut) -> Result> { let element_type = match ty.kind() { &Kind::Array(ref ty) => ty, _ => unreachable!(), }; - let dimensions = self.dimensions().iter().map(|d| { - types::ArrayDimension { - len: d.len, - lower_bound: d.lower_bound, - } + let dimensions = self.dimensions().iter().map(|d| types::ArrayDimension { + len: d.len, + lower_bound: d.lower_bound, }); let elements = self.iter(); - try!(types::array_to_sql( + types::array_to_sql( dimensions, - true, element_type.oid(), elements, |v, w| match v.to_sql(element_type, w) { @@ -77,7 +71,7 @@ where Err(e) => Err(e), }, w, - )); + )?; Ok(IsNull::No) } @@ -96,42 +90,49 @@ where mod test { use std::fmt; - use postgres::{Connection, TlsMode}; - use postgres::types::{FromSql, ToSql}; - use Array; + use crate::Array; + use postgres::types::{FromSqlOwned, ToSql}; + use postgres::{Client, NoTls}; - fn test_type( + fn test_type( sql_type: &str, checks: &[(T, S)], ) { - let conn = Connection::connect("postgres://postgres:password@localhost", TlsMode::None) - .unwrap(); + let mut conn = Client::connect("postgres://postgres:password@localhost", NoTls).unwrap(); for &(ref val, ref repr) in checks.iter() { - let stmt = conn.prepare(&format!("SELECT {}::{}", *repr, sql_type)) - .unwrap(); - let result = stmt.query(&[]).unwrap().iter().next().unwrap().get(0); + let result = conn + .query(&*format!("SELECT {}::{}", *repr, sql_type), &[]) + .unwrap()[0] + .get(0); assert!(val == &result); - let stmt = conn.prepare(&format!("SELECT $1::{}", sql_type)).unwrap(); - let result = stmt.query(&[val]).unwrap().iter().next().unwrap().get(0); + let result = conn + .query(&*format!("SELECT $1::{}", sql_type), &[val]) + .unwrap()[0] + .get(0); assert!(val == &result); } } macro_rules! test_array_params { - ($name:expr, $v1:expr, $s1:expr, $v2:expr, $s2:expr, $v3:expr, $s3:expr) => ({ - - let tests = &[(Some(Array::from_vec(vec!(Some($v1), Some($v2), None), 1)), - format!("'{{{},{},NULL}}'", $s1, $s2)), - (None, "NULL".to_string())]; + ($name:expr, $v1:expr, $s1:expr, $v2:expr, $s2:expr, $v3:expr, $s3:expr) => {{ + let tests = &[ + ( + Some(Array::from_vec(vec![Some($v1), Some($v2), None], 1)), + format!("'{{{},{},NULL}}'", $s1, $s2), + ), + (None, "NULL".to_string()), + ]; test_type(&format!("{}[]", $name), tests); - let mut a = Array::from_vec(vec!(Some($v1), Some($v2)), 0); + let mut a = Array::from_vec(vec![Some($v1), Some($v2)], 0); a.wrap(-1); - a.push(Array::from_vec(vec!(None, Some($v3)), 0)); - let tests = &[(Some(a), format!("'[-1:0][0:1]={{{{{},{}}},{{NULL,{}}}}}'", - $s1, $s2, $s3))]; + a.push(Array::from_vec(vec![None, Some($v3)], 0)); + let tests = &[( + Some(a), + format!("'[-1:0][0:1]={{{{{},{}}},{{NULL,{}}}}}'", $s1, $s2, $s3), + )]; test_type(&format!("{}[][]", $name), tests); - }) + }}; } #[test] @@ -236,13 +237,7 @@ mod test { #[test] fn test_empty_array() { - let conn = Connection::connect("postgres://postgres@localhost", TlsMode::None).unwrap(); - let stmt = conn.prepare("SELECT '{}'::INT4[]").unwrap(); - stmt.query(&[]) - .unwrap() - .iter() - .next() - .unwrap() - .get::<_, Array>(0); + let mut conn = Client::connect("postgres://postgres@localhost", NoTls).unwrap(); + conn.query("SELECT '{}'::INT4[]", &[]).unwrap()[0].get::<_, Array>(0); } } diff --git a/src/lib.rs b/src/lib.rs index a4b29af..21240da 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,16 +1,8 @@ //! Multi-dimensional arrays with per-dimension specifiable lower bounds -#![doc(html_root_url="https://docs.rs/postgres_array/0.9.0")] - -extern crate fallible_iterator; -#[macro_use] -extern crate postgres_shared; -extern crate postgres_protocol; - -#[cfg(test)] -extern crate postgres; +#![doc(html_root_url = "https://docs.rs/postgres_array/0.10")] #[doc(inline)] -pub use array::Array; +pub use crate::array::Array; pub mod array; mod impls; @@ -47,13 +39,11 @@ mod tests { fn test_from_vec() { let a = Array::from_vec(vec![0i32, 1, 2], -1); assert!( - &[ - Dimension { - len: 3, - lower_bound: -1, - }, - ] - [..] == a.dimensions() + &[Dimension { + len: 3, + lower_bound: -1, + },][..] + == a.dimensions() ); assert_eq!(0, a[-1]); assert_eq!(1, a[0]); @@ -156,5 +146,8 @@ mod tests { a.push(Array::from_vec(vec![4, 5, 6], 3)); a.wrap(1); assert_eq!("[1:1][-2:-1][3:5]={{{1,2,3},{4,5,6}}}", &format!("{}", a)); + + let a: Array = Array::from_parts(vec![], vec![]); + assert_eq!("{}", &format!("{}", a)); } } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy