forked from rust-postgres/rust-postgres
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlib.rs
More file actions
132 lines (112 loc) · 3.04 KB
/
Copy pathlib.rs
File metadata and controls
132 lines (112 loc) · 3.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#![allow(unknown_lints)] // for clippy
extern crate hex;
extern crate fallible_iterator;
extern crate phf;
extern crate postgres_protocol;
use fallible_iterator::{FallibleIterator, FromFallibleIterator};
use std::ascii::AsciiExt;
use std::ops::Range;
use types::Type;
pub mod error;
pub mod params;
pub mod types;
/// Contains information necessary to cancel queries for a session.
#[derive(Copy, Clone, Debug)]
pub struct CancelData {
/// The process ID of the session.
pub process_id: i32,
/// The secret key for the session.
pub secret_key: i32,
}
pub struct RowData {
buf: Vec<u8>,
indices: Vec<Option<Range<usize>>>,
}
impl<'a> FromFallibleIterator<Option<&'a [u8]>> for RowData {
fn from_fallible_iterator<I>(mut it: I) -> Result<RowData, I::Error>
where I: FallibleIterator<Item = Option<&'a [u8]>>
{
let mut row = RowData {
buf: vec![],
indices: Vec::with_capacity(it.size_hint().0),
};
while let Some(cell) = try!(it.next()) {
let index = match cell {
Some(cell) => {
let base = row.buf.len();
row.buf.extend_from_slice(cell);
Some(base..row.buf.len())
}
None => None,
};
row.indices.push(index);
}
Ok(row)
}
}
impl RowData {
pub fn len(&self) -> usize {
self.indices.len()
}
pub fn get(&self, index: usize) -> Option<&[u8]> {
match &self.indices[index] {
&Some(ref range) => Some(&self.buf[range.clone()]),
&None => None,
}
}
}
pub struct Column {
name: String,
type_: Type,
}
impl Column {
#[doc(hidden)]
pub fn new(name: String, type_: Type) -> Column {
Column {
name: name,
type_: type_,
}
}
pub fn name(&self) -> &str {
&self.name
}
pub fn type_(&self) -> &Type {
&self.type_
}
}
/// A trait implemented by types that can index into columns of a row.
pub trait RowIndex {
/// Returns the index of the appropriate column, or `None` if no such
/// column exists.
fn idx(&self, stmt: &[Column]) -> Option<usize>;
}
impl RowIndex for usize {
#[inline]
fn idx(&self, stmt: &[Column]) -> Option<usize> {
if *self >= stmt.len() {
None
} else {
Some(*self)
}
}
}
impl<'a> RowIndex for str {
#[inline]
fn idx(&self, stmt: &[Column]) -> Option<usize> {
if let Some(idx) = stmt.iter().position(|d| d.name() == self) {
return Some(idx);
};
// FIXME ASCII-only case insensitivity isn't really the right thing to
// do. Postgres itself uses a dubious wrapper around tolower and JDBC
// uses the US locale.
stmt.iter().position(|d| d.name().eq_ignore_ascii_case(self))
}
}
impl<'a, T: ?Sized> RowIndex for &'a T
where T: RowIndex
{
#[inline]
fn idx(&self, columns: &[Column]) -> Option<usize> {
T::idx(*self, columns)
}
}