• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Run-Time Limits
2 
3 use crate::{ffi, Connection};
4 use std::os::raw::c_int;
5 
6 /// Run-Time limit categories, for use with [`Connection::limit`] and
7 /// [`Connection::set_limit`].
8 ///
9 /// See the official documentation for more information:
10 /// - <https://www.sqlite.org/c3ref/c_limit_attached.html>
11 /// - <https://www.sqlite.org/limits.html>
12 #[derive(Copy, Clone, Debug)]
13 #[repr(i32)]
14 #[non_exhaustive]
15 #[allow(clippy::upper_case_acronyms, non_camel_case_types)]
16 #[cfg_attr(docsrs, doc(cfg(feature = "limits")))]
17 pub enum Limit {
18     /// The maximum size of any string or BLOB or table row, in bytes.
19     SQLITE_LIMIT_LENGTH = ffi::SQLITE_LIMIT_LENGTH,
20     /// The maximum length of an SQL statement, in bytes.
21     SQLITE_LIMIT_SQL_LENGTH = ffi::SQLITE_LIMIT_SQL_LENGTH,
22     /// The maximum number of columns in a table definition or in the result set
23     /// of a SELECT or the maximum number of columns in an index or in an
24     /// ORDER BY or GROUP BY clause.
25     SQLITE_LIMIT_COLUMN = ffi::SQLITE_LIMIT_COLUMN,
26     /// The maximum depth of the parse tree on any expression.
27     SQLITE_LIMIT_EXPR_DEPTH = ffi::SQLITE_LIMIT_EXPR_DEPTH,
28     /// The maximum number of terms in a compound SELECT statement.
29     SQLITE_LIMIT_COMPOUND_SELECT = ffi::SQLITE_LIMIT_COMPOUND_SELECT,
30     /// The maximum number of instructions in a virtual machine program used to
31     /// implement an SQL statement.
32     SQLITE_LIMIT_VDBE_OP = ffi::SQLITE_LIMIT_VDBE_OP,
33     /// The maximum number of arguments on a function.
34     SQLITE_LIMIT_FUNCTION_ARG = ffi::SQLITE_LIMIT_FUNCTION_ARG,
35     /// The maximum number of attached databases.
36     SQLITE_LIMIT_ATTACHED = ffi::SQLITE_LIMIT_ATTACHED,
37     /// The maximum length of the pattern argument to the LIKE or GLOB
38     /// operators.
39     SQLITE_LIMIT_LIKE_PATTERN_LENGTH = ffi::SQLITE_LIMIT_LIKE_PATTERN_LENGTH,
40     /// The maximum index number of any parameter in an SQL statement.
41     SQLITE_LIMIT_VARIABLE_NUMBER = ffi::SQLITE_LIMIT_VARIABLE_NUMBER,
42     /// The maximum depth of recursion for triggers.
43     SQLITE_LIMIT_TRIGGER_DEPTH = ffi::SQLITE_LIMIT_TRIGGER_DEPTH,
44     /// The maximum number of auxiliary worker threads that a single prepared
45     /// statement may start.
46     SQLITE_LIMIT_WORKER_THREADS = ffi::SQLITE_LIMIT_WORKER_THREADS,
47 }
48 
49 impl Connection {
50     /// Returns the current value of a [`Limit`].
51     #[inline]
52     #[cfg_attr(docsrs, doc(cfg(feature = "limits")))]
limit(&self, limit: Limit) -> i3253     pub fn limit(&self, limit: Limit) -> i32 {
54         let c = self.db.borrow();
55         unsafe { ffi::sqlite3_limit(c.db(), limit as c_int, -1) }
56     }
57 
58     /// Changes the [`Limit`] to `new_val`, returning the prior
59     /// value of the limit.
60     #[inline]
61     #[cfg_attr(docsrs, doc(cfg(feature = "limits")))]
set_limit(&self, limit: Limit, new_val: i32) -> i3262     pub fn set_limit(&self, limit: Limit, new_val: i32) -> i32 {
63         let c = self.db.borrow_mut();
64         unsafe { ffi::sqlite3_limit(c.db(), limit as c_int, new_val) }
65     }
66 }
67 
68 #[cfg(test)]
69 mod test {
70     use super::*;
71     use crate::Result;
72 
73     #[test]
test_limit_values()74     fn test_limit_values() {
75         assert_eq!(Limit::SQLITE_LIMIT_LENGTH as i32, ffi::SQLITE_LIMIT_LENGTH,);
76         assert_eq!(
77             Limit::SQLITE_LIMIT_SQL_LENGTH as i32,
78             ffi::SQLITE_LIMIT_SQL_LENGTH,
79         );
80         assert_eq!(Limit::SQLITE_LIMIT_COLUMN as i32, ffi::SQLITE_LIMIT_COLUMN,);
81         assert_eq!(
82             Limit::SQLITE_LIMIT_EXPR_DEPTH as i32,
83             ffi::SQLITE_LIMIT_EXPR_DEPTH,
84         );
85         assert_eq!(
86             Limit::SQLITE_LIMIT_COMPOUND_SELECT as i32,
87             ffi::SQLITE_LIMIT_COMPOUND_SELECT,
88         );
89         assert_eq!(
90             Limit::SQLITE_LIMIT_VDBE_OP as i32,
91             ffi::SQLITE_LIMIT_VDBE_OP,
92         );
93         assert_eq!(
94             Limit::SQLITE_LIMIT_FUNCTION_ARG as i32,
95             ffi::SQLITE_LIMIT_FUNCTION_ARG,
96         );
97         assert_eq!(
98             Limit::SQLITE_LIMIT_ATTACHED as i32,
99             ffi::SQLITE_LIMIT_ATTACHED,
100         );
101         assert_eq!(
102             Limit::SQLITE_LIMIT_LIKE_PATTERN_LENGTH as i32,
103             ffi::SQLITE_LIMIT_LIKE_PATTERN_LENGTH,
104         );
105         assert_eq!(
106             Limit::SQLITE_LIMIT_VARIABLE_NUMBER as i32,
107             ffi::SQLITE_LIMIT_VARIABLE_NUMBER,
108         );
109         #[cfg(feature = "bundled")]
110         assert_eq!(
111             Limit::SQLITE_LIMIT_TRIGGER_DEPTH as i32,
112             ffi::SQLITE_LIMIT_TRIGGER_DEPTH,
113         );
114         #[cfg(feature = "bundled")]
115         assert_eq!(
116             Limit::SQLITE_LIMIT_WORKER_THREADS as i32,
117             ffi::SQLITE_LIMIT_WORKER_THREADS,
118         );
119     }
120 
121     #[test]
test_limit() -> Result<()>122     fn test_limit() -> Result<()> {
123         let db = Connection::open_in_memory()?;
124         db.set_limit(Limit::SQLITE_LIMIT_LENGTH, 1024);
125         assert_eq!(1024, db.limit(Limit::SQLITE_LIMIT_LENGTH));
126 
127         db.set_limit(Limit::SQLITE_LIMIT_SQL_LENGTH, 1024);
128         assert_eq!(1024, db.limit(Limit::SQLITE_LIMIT_SQL_LENGTH));
129 
130         db.set_limit(Limit::SQLITE_LIMIT_COLUMN, 64);
131         assert_eq!(64, db.limit(Limit::SQLITE_LIMIT_COLUMN));
132 
133         db.set_limit(Limit::SQLITE_LIMIT_EXPR_DEPTH, 256);
134         assert_eq!(256, db.limit(Limit::SQLITE_LIMIT_EXPR_DEPTH));
135 
136         db.set_limit(Limit::SQLITE_LIMIT_COMPOUND_SELECT, 32);
137         assert_eq!(32, db.limit(Limit::SQLITE_LIMIT_COMPOUND_SELECT));
138 
139         db.set_limit(Limit::SQLITE_LIMIT_FUNCTION_ARG, 32);
140         assert_eq!(32, db.limit(Limit::SQLITE_LIMIT_FUNCTION_ARG));
141 
142         db.set_limit(Limit::SQLITE_LIMIT_ATTACHED, 2);
143         assert_eq!(2, db.limit(Limit::SQLITE_LIMIT_ATTACHED));
144 
145         db.set_limit(Limit::SQLITE_LIMIT_LIKE_PATTERN_LENGTH, 128);
146         assert_eq!(128, db.limit(Limit::SQLITE_LIMIT_LIKE_PATTERN_LENGTH));
147 
148         db.set_limit(Limit::SQLITE_LIMIT_VARIABLE_NUMBER, 99);
149         assert_eq!(99, db.limit(Limit::SQLITE_LIMIT_VARIABLE_NUMBER));
150 
151         db.set_limit(Limit::SQLITE_LIMIT_TRIGGER_DEPTH, 32);
152         assert_eq!(32, db.limit(Limit::SQLITE_LIMIT_TRIGGER_DEPTH));
153 
154         db.set_limit(Limit::SQLITE_LIMIT_WORKER_THREADS, 2);
155         assert_eq!(2, db.limit(Limit::SQLITE_LIMIT_WORKER_THREADS));
156         Ok(())
157     }
158 }
159