1#[cfg(test)]
2extern crate serde;
3#[cfg(test)]
4extern crate flate2;
5#[cfg(test)]
6extern crate serde_json;
7#[cfg(test)]
8#[macro_use]
9extern crate serde_derive;
10extern crate rusqlite;
11
12mod map;
13pub use map::SqliteMap;
14
15#[cfg(test)]
16mod tests {
17 use super::*;
18 use rusqlite;
19 use rusqlite::Connection;
20 use rusqlite::Error;
21 use rusqlite::types::{ToSql, FromSql, ValueRef, FromSqlError, FromSqlResult, ToSqlOutput};
22
23 #[test]
24 fn it_works() {
25 let connection = Connection::open_in_memory().unwrap();
26 let mut book_reviews = SqliteMap::new(&connection, "map", "TEXT", "TEXT").unwrap();
27
28 assert!(book_reviews.is_empty().unwrap());
29
30 assert_eq!(book_reviews.insert::<String>(&"Adventures of Huckleberry Finn", &"My favorite book.").unwrap(), None);
32 assert_eq!(book_reviews.insert::<String>(&"Grimms' Fairy Tales", &"Masterpiece.").unwrap(), None);
33 assert_eq!(book_reviews.insert::<String>(&"The Adventures of Sherlock Holmes", &"Eye lyked it alot.").unwrap(), None);
34 assert_eq!(book_reviews.get(&"The Adventures of Sherlock Holmes").unwrap(), Some(String::from("Eye lyked it alot.")));
35 assert_eq!(book_reviews.get::<String>(&"The Adventures of Somebody Else").unwrap(), None);
36
37 assert_eq!(book_reviews.insert::<String>(&"Pride and Prejudice", &"Very enjoyable.").unwrap(), None);
39 assert_eq!(book_reviews.insert(&"Pride and Prejudice", &"Just terrible.").unwrap(), Some(String::from("Very enjoyable.")));
40 assert_eq!(book_reviews.get(&"Pride and Prejudice").unwrap(), Some(String::from("Just terrible.")));
41
42 assert!(!book_reviews.is_empty().unwrap());
43
44 assert_eq!(book_reviews.len().unwrap(), 4);
45
46 assert!(!book_reviews.contains_key(&"Les Misérables").unwrap());
48
49 assert_eq!(book_reviews.remove(&"The Adventures of Sherlock Holmes").unwrap(), Some(String::from("Eye lyked it alot.")));
51 assert_eq!(book_reviews.remove::<String>(&"The Adventures of Sherlock Holmes").unwrap(), None);
52
53 let x: Result<Vec<String>, Error> = book_reviews.keys().unwrap().collect();
54 assert_eq!(x.unwrap(), ["Adventures of Huckleberry Finn", "Grimms' Fairy Tales", "Pride and Prejudice"]);
55
56 let x: Result<Vec<String>, Error> = book_reviews.values().unwrap().collect();
57 assert_eq!(x.unwrap(), ["My favorite book.", "Masterpiece.", "Just terrible."]);
58
59 let x: Result<Vec<(String, String)>, Error> = book_reviews.iter().unwrap().collect();
60 assert_eq!(x.unwrap(), [
61 (String::from("Adventures of Huckleberry Finn"), String::from("My favorite book.")),
62 (String::from("Grimms' Fairy Tales"), String::from("Masterpiece.")),
63 (String::from("Pride and Prejudice"), String::from("Just terrible."))]);
64
65 assert_eq!(book_reviews.len().unwrap(), 3);
66 }
67
68 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
69 struct Foo {
70 x: i32,
71 y: String,
72 }
73
74 impl ToSql for Foo {
75 fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> {
76 let string = serde_json::to_string(self).map_err(|err| rusqlite::Error::ToSqlConversionFailure(Box::new(err)))?;
77 Ok(ToSqlOutput::from(string))
78 }
79 }
80
81 impl FromSql for Foo {
82 fn column_result(value: ValueRef) -> FromSqlResult<Self> {
83 match value {
84 ValueRef::Text(s) => serde_json::from_str(s),
85 ValueRef::Blob(b) => serde_json::from_slice(b),
86 _ => return Err(FromSqlError::InvalidType),
87 }.map_err(|err| FromSqlError::Other(Box::new(err)))
88 }
89 }
90
91
92 #[test]
93 fn json_output() {
94 let connection = Connection::open_in_memory().unwrap();
95 let mut book_reviews = SqliteMap::new(&connection, "map", "TEXT", "TEXT").unwrap();
96 let foo = Foo{
97 x: 8,
98 y: String::from("This is a test string"),
99 };
100
101 assert_eq!(book_reviews.insert::<Foo>(&"foo", &foo).unwrap(), None);
102 assert_eq!(book_reviews.insert(&"foo", &foo).unwrap(), Some(foo));
103 }
104
105 use std::io::prelude::*;
106 use flate2::Compression;
107 use flate2::write::ZlibEncoder;
108 use flate2::read::ZlibDecoder;
109
110 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
111 struct ZipFoo(Foo);
112
113 impl ToSql for ZipFoo {
114 fn to_sql(&self) -> rusqlite::Result<ToSqlOutput> {
115 let mut e = ZlibEncoder::new(Vec::new(), Compression::default());
116 let string = serde_json::to_vec(self).map_err(|err| rusqlite::Error::ToSqlConversionFailure(Box::new(err)))?;
117 e.write_all(&string).map_err(|err| rusqlite::Error::ToSqlConversionFailure(Box::new(err)))?;
118 Ok(ToSqlOutput::from(e.finish().map_err(|err| rusqlite::Error::ToSqlConversionFailure(Box::new(err)))?))
119 }
120 }
121
122 impl FromSql for ZipFoo {
123 fn column_result(value: ValueRef) -> FromSqlResult<Self> {
124 let mut s = String::new();
125 match value {
126 ValueRef::Blob(b) => {
127 let mut z = ZlibDecoder::new(b);
128 z.read_to_string(&mut s).map_err(|err| FromSqlError::Other(Box::new(err)))?;
129 serde_json::from_str(&s)
130 },
131 _ => return Err(FromSqlError::InvalidType),
132 }.map_err(|err| FromSqlError::Other(Box::new(err)))
133 }
134 }
135
136 #[test]
137 fn zip_json_output() {
138 let connection = Connection::open_in_memory().unwrap();
139 let mut book_reviews = SqliteMap::new(&connection, "map", "BLOB", "BLOB").unwrap();
140 let foo = ZipFoo(Foo{
141 x: 8,
142 y: String::from("This is a test string"),
143 });
144
145 assert_eq!(book_reviews.insert::<Foo>(&"foo", &foo).unwrap(), None);
146 assert_eq!(book_reviews.insert(&"foo", &foo).unwrap(), Some(foo));
147 }
148}