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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#![cfg_attr(feature = "default", doc = include_str!("../README.md"))]
//
// Unsafe code is required for cdylib, so only use it for this crate
#![forbid(unsafe_code)]

#[cfg(not(any(
    feature = "md5",
    feature = "sha1",
    feature = "sha224",
    feature = "sha256",
    feature = "sha384",
    feature = "sha512",
    feature = "fnv",
    feature = "xxhash",
)))]
compile_error!(
    "At least one of these features must be enabled: md5,sha1,sha224,sha256,sha384,sha512,fnv,xxhash"
);

/// Re-export of the [`rusqlite`](https://crates.io/crates/rusqlite) crate to avoid version conflicts.
pub use rusqlite;

use crate::rusqlite::{Connection, Result};

mod aggregate;

mod scalar;
pub use crate::scalar::NamedDigest;

mod state;
pub use crate::state::HashState;

#[cfg(feature = "md5")]
mod md5;

#[cfg(feature = "md5")]
pub use crate::md5::register_md5_functions;

#[cfg(feature = "sha1")]
mod sha1;

#[cfg(feature = "sha1")]
pub use crate::sha1::register_sha1_functions;

#[cfg(feature = "sha224")]
mod sha224;

#[cfg(feature = "sha224")]
pub use crate::sha224::register_sha224_functions;

#[cfg(feature = "sha256")]
mod sha256;

#[cfg(feature = "sha256")]
pub use crate::sha256::register_sha256_functions;

#[cfg(feature = "sha384")]
mod sha384;

#[cfg(feature = "sha384")]
pub use crate::sha384::register_sha384_functions;

#[cfg(feature = "sha512")]
mod sha512;

#[cfg(feature = "sha512")]
pub use crate::sha512::register_sha512_functions;

#[cfg(feature = "fnv")]
mod fnv;

#[cfg(feature = "fnv")]
pub use crate::fnv::register_fnv_functions;

#[cfg(feature = "xxhash")]
mod xxhash;

#[cfg(feature = "xxhash")]
pub use crate::xxhash::register_xxhash_functions;

/// Register all hashing functions for the given `SQLite` connection.
/// This is a convenience function that calls all of the `register_*_function` functions.
/// Features must be enabled for the corresponding functions to be registered.
///
/// # Example
///
/// ```
/// # use sqlite_hashes::rusqlite::{Connection, Result};
/// # use sqlite_hashes::register_hash_functions;
/// # fn main() -> Result<()> {
/// let db = Connection::open_in_memory()?;
/// register_hash_functions(&db)?;
/// # if cfg!(all(feature = "hex", feature = "md5")) {
/// let hash: String = db.query_row("SELECT md5_hex('hello')", [], |r| r.get(0))?;
/// assert_eq!(&hash, "5D41402ABC4B2A76B9719D911017C592");
/// # }
/// # if cfg!(all(feature = "hex", feature = "sha1")) {
/// let hash: String = db.query_row("SELECT sha1_hex('hello')", [], |r| r.get(0))?;
/// assert_eq!(hash, "AAF4C61DDCC5E8A2DABEDE0F3B482CD9AEA9434D");
/// # }
/// # if cfg!(all(feature = "hex", feature = "sha224")) {
/// let hash: String = db.query_row("SELECT sha224_hex('hello')", [], |r| r.get(0))?;
/// assert_eq!(&hash, "EA09AE9CC6768C50FCEE903ED054556E5BFC8347907F12598AA24193");
/// # }
/// # if cfg!(all(feature = "hex", feature = "sha256")) {
/// let hash: String = db.query_row("SELECT sha256_hex('hello')", [], |r| r.get(0))?;
/// assert_eq!(&hash, "2CF24DBA5FB0A30E26E83B2AC5B9E29E1B161E5C1FA7425E73043362938B9824");
/// # }
/// # if cfg!(all(feature = "hex", feature = "sha384")) {
/// let hash: String = db.query_row("SELECT sha384_hex('hello')", [], |r| r.get(0))?;
/// assert_eq!(&hash, "59E1748777448C69DE6B800D7A33BBFB9FF1B463E44354C3553BCDB9C666FA90125A3C79F90397BDF5F6A13DE828684F");
/// # }
/// # if cfg!(all(feature = "hex", feature = "sha512")) {
/// let hash: String = db.query_row("SELECT sha512_hex('hello')", [], |r| r.get(0))?;
/// assert_eq!(hash, "9B71D224BD62F3785D96D46AD3EA3D73319BFBC2890CAADAE2DFF72519673CA72323C3D99BA5C11D7C7ACC6E14B8C5DA0C4663475C2E5C3ADEF46F73BCDEC043");
/// # }
/// # if cfg!(all(feature = "hex", feature = "fnv")) {
/// let hash: String = db.query_row("SELECT fnv1a_hex('hello')", [], |r| r.get(0))?;
/// assert_eq!(hash, "A430D84680AABD0B");
/// # }
/// # if cfg!(all(feature = "hex", feature = "xxhash")) {
/// let hash: String = db.query_row("SELECT xxh32_hex('hello')", [], |r| r.get(0))?;
/// assert_eq!(hash, "FB0077F9");
/// let hash: String = db.query_row("SELECT xxh64_hex('hello')", [], |r| r.get(0))?;
/// assert_eq!(hash, "26C7827D889F6DA3");
/// let hash: String = db.query_row("SELECT xxh3_64_hex('hello')", [], |r| r.get(0))?;
/// assert_eq!(hash, "9555E8555C62DCFD");
/// let hash: String = db.query_row("SELECT xxh3_128_hex('hello')", [], |r| r.get(0))?;
/// assert_eq!(hash, "B5E9C1AD071B3E7FC779CFAA5E523818");
/// # }
/// # Ok(())
/// # }
/// ```
pub fn register_hash_functions(conn: &Connection) -> Result<()> {
    #[cfg(feature = "md5")]
    register_md5_functions(conn)?;
    #[cfg(feature = "sha1")]
    register_sha1_functions(conn)?;
    #[cfg(feature = "sha224")]
    register_sha224_functions(conn)?;
    #[cfg(feature = "sha256")]
    register_sha256_functions(conn)?;
    #[cfg(feature = "sha384")]
    register_sha384_functions(conn)?;
    #[cfg(feature = "sha512")]
    register_sha512_functions(conn)?;
    #[cfg(feature = "fnv")]
    register_fnv_functions(conn)?;
    #[cfg(feature = "xxhash")]
    register_xxhash_functions(conn)?;

    Ok(())
}