@@ -80,10 +80,18 @@ pub struct SqliteConnectOptions {
8080 pub ( crate ) serialized : bool ,
8181 pub ( crate ) thread_name : Arc < DebugFn < dyn Fn ( u64 ) -> String + Send + Sync + ' static > > ,
8282
83+ pub ( crate ) optimize_on_close : OptimizeOnClose ,
84+
8385 #[ cfg( feature = "regexp" ) ]
8486 pub ( crate ) register_regexp_function : bool ,
8587}
8688
89+ #[ derive( Clone , Debug ) ]
90+ pub enum OptimizeOnClose {
91+ Enabled { analysis_limit : Option < u32 > } ,
92+ Disabled ,
93+ }
94+
8795impl Default for SqliteConnectOptions {
8896 fn default ( ) -> Self {
8997 Self :: new ( )
@@ -170,6 +178,9 @@ impl SqliteConnectOptions {
170178
171179 pragmas. insert ( "auto_vacuum" . into ( ) , None ) ;
172180
181+ // Soft limit on the number of rows that `ANALYZE` touches per index.
182+ pragmas. insert ( "analysis_limit" . into ( ) , None ) ;
183+
173184 Self {
174185 filename : Cow :: Borrowed ( Path :: new ( ":memory:" ) ) ,
175186 in_memory : false ,
@@ -188,6 +199,7 @@ impl SqliteConnectOptions {
188199 thread_name : Arc :: new ( DebugFn ( |id| format ! ( "sqlx-sqlite-worker-{}" , id) ) ) ,
189200 command_channel_size : 50 ,
190201 row_channel_size : 50 ,
202+ optimize_on_close : OptimizeOnClose :: Disabled ,
191203 #[ cfg( feature = "regexp" ) ]
192204 register_regexp_function : false ,
193205 }
@@ -464,6 +476,54 @@ impl SqliteConnectOptions {
464476 self
465477 }
466478
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+
467527 /// Register a regexp function that allows using regular expressions in queries.
468528 ///
469529 /// ```
0 commit comments