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