@@ -80,10 +80,18 @@ pub struct SqliteConnectOptions {
80
80
pub ( crate ) serialized : bool ,
81
81
pub ( crate ) thread_name : Arc < DebugFn < dyn Fn ( u64 ) -> String + Send + Sync + ' static > > ,
82
82
83
+ pub ( crate ) optimize_on_close : OptimizeOnClose ,
84
+
83
85
#[ cfg( feature = "regexp" ) ]
84
86
pub ( crate ) register_regexp_function : bool ,
85
87
}
86
88
89
+ #[ derive( Clone , Debug ) ]
90
+ pub enum OptimizeOnClose {
91
+ Enabled { analysis_limit : Option < u32 > } ,
92
+ Disabled ,
93
+ }
94
+
87
95
impl Default for SqliteConnectOptions {
88
96
fn default ( ) -> Self {
89
97
Self :: new ( )
@@ -170,6 +178,9 @@ impl SqliteConnectOptions {
170
178
171
179
pragmas. insert ( "auto_vacuum" . into ( ) , None ) ;
172
180
181
+ // Soft limit on the number of rows that `ANALYZE` touches per index.
182
+ pragmas. insert ( "analysis_limit" . into ( ) , None ) ;
183
+
173
184
Self {
174
185
filename : Cow :: Borrowed ( Path :: new ( ":memory:" ) ) ,
175
186
in_memory : false ,
@@ -188,6 +199,7 @@ impl SqliteConnectOptions {
188
199
thread_name : Arc :: new ( DebugFn ( |id| format ! ( "sqlx-sqlite-worker-{}" , id) ) ) ,
189
200
command_channel_size : 50 ,
190
201
row_channel_size : 50 ,
202
+ optimize_on_close : OptimizeOnClose :: Disabled ,
191
203
#[ cfg( feature = "regexp" ) ]
192
204
register_regexp_function : false ,
193
205
}
@@ -464,6 +476,54 @@ impl SqliteConnectOptions {
464
476
self
465
477
}
466
478
479
+ /// Execute `PRAGMA optimize;` on the SQLite connection before closing.
480
+ ///
481
+ /// The SQLite manual recommends using this for long-lived databases.
482
+ ///
483
+ /// This will collect and store statistics about the layout of data in your tables to help the query planner make better decisions.
484
+ /// Over the connection's lifetime, the query planner will make notes about which tables could use up-to-date statistics so this
485
+ /// command doesn't have to scan the whole database every time. Thus, the best time to execute this is on connection close.
486
+ ///
487
+ /// `analysis_limit` sets a soft limit on the maximum number of rows to scan per index.
488
+ /// It is equivalent to setting [`Self::analysis_limit`] but only takes effect for the `PRAGMA optimize;` call
489
+ /// and does not affect the behavior of any `ANALYZE` statements made during the connection's lifetime.
490
+ ///
491
+ /// If not `None`, the `analysis_limit` here overrides the global `analysis_limit` setting,
492
+ /// but only for the `PRAGMA optimize;` call.
493
+ ///
494
+ /// Not enabled by default.
495
+ ///
496
+ /// See [the SQLite manual](https://www.sqlite.org/lang_analyze.html#automatically_running_analyze) for details.
497
+ pub fn optimize_on_close (
498
+ mut self ,
499
+ enabled : bool ,
500
+ analysis_limit : impl Into < Option < u32 > > ,
501
+ ) -> Self {
502
+ self . optimize_on_close = if enabled {
503
+ OptimizeOnClose :: Enabled {
504
+ analysis_limit : ( analysis_limit. into ( ) ) ,
505
+ }
506
+ } else {
507
+ OptimizeOnClose :: Disabled
508
+ } ;
509
+ self
510
+ }
511
+
512
+ /// Set a soft limit on the number of rows that `ANALYZE` touches per index.
513
+ ///
514
+ /// This also affects `PRAGMA optimize` which is set by [Self::optimize_on_close].
515
+ ///
516
+ /// The value recommended by SQLite is `400`. There is no default.
517
+ ///
518
+ /// See [the SQLite manual](https://www.sqlite.org/lang_analyze.html#approx) for details.
519
+ pub fn analysis_limit ( mut self , limit : impl Into < Option < u32 > > ) -> Self {
520
+ if let Some ( limit) = limit. into ( ) {
521
+ return self . pragma ( "analysis_limit" , limit. to_string ( ) ) ;
522
+ }
523
+ self . pragmas . insert ( "analysis_limit" . into ( ) , None ) ;
524
+ self
525
+ }
526
+
467
527
/// Register a regexp function that allows using regular expressions in queries.
468
528
///
469
529
/// ```
0 commit comments