Skip to main content

drizzle_sqlite/
pragma.rs

1//! `SQLite` PRAGMA statements for database configuration and introspection
2//!
3//! This module provides type-safe, ergonomic access to `SQLite`'s PRAGMA statements.
4//! PRAGMA statements are SQL extension specific to `SQLite` and are used to modify
5//! the operation of the `SQLite` library or to query the `SQLite` library for internal
6//! (non-table) data.
7//!
8//! [SQLite PRAGMA Documentation](https://sqlite.org/pragma.html)
9//!
10//! ## Features
11//!
12//! - **Type Safety**: Enums for all pragma values (no string literals needed)
13//! - **Ergonomic API**: Uses `&'static str` instead of `String` - no `.to_string()` calls
14//! - **Documentation Links**: Each pragma links to official `SQLite` documentation
15//! - **`ToSQL` Integration**: Seamless integration with the query builder
16//!
17//! ## Categories
18//!
19//! - **Configuration**: `foreign_keys`, `journal_mode`, `wal_autocheckpoint`, `cache_spill`, etc.
20//! - **Introspection**: `table_info`, `index_list`, `compile_options`, etc.
21//! - **Maintenance**: `integrity_check`, `incremental_vacuum`, `wal_checkpoint`, etc.
22//!
23//! ## Examples
24//!
25//! ```
26//! use drizzle_sqlite::pragma::{Pragma, JournalMode, AutoVacuum};
27//! use drizzle_core::ToSQL;
28//!
29//! // Enable foreign key constraints
30//! let pragma = Pragma::foreign_keys(true);
31//! assert_eq!(pragma.to_sql().sql(), "PRAGMA foreign_keys = ON");
32//!
33//! // Set journal mode to WAL
34//! let pragma = Pragma::journal_mode(JournalMode::Wal);
35//! assert_eq!(pragma.to_sql().sql(), "PRAGMA journal_mode = WAL");
36//!
37//! // Get table schema information
38//! let pragma = Pragma::table_info("users");
39//! assert_eq!(pragma.to_sql().sql(), "PRAGMA table_info(users)");
40//!
41//! // Check database integrity
42//! let pragma = Pragma::integrity_check(None);
43//! assert_eq!(pragma.to_sql().sql(), "PRAGMA integrity_check");
44//! ```
45
46#[cfg(not(feature = "std"))]
47use crate::prelude::*;
48use crate::values::SQLiteValue;
49use drizzle_core::{SQL, ToSQL};
50
51/// Auto-vacuum modes for `SQLite` databases
52///
53/// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_auto_vacuum)
54#[derive(Debug, Clone, PartialEq, Eq)]
55pub enum AutoVacuum {
56    /// Disable auto-vacuum
57    ///
58    /// # Example
59    /// ```
60    /// # use drizzle_sqlite::pragma::AutoVacuum;
61    /// # use drizzle_core::ToSQL;
62    /// assert_eq!(AutoVacuum::None.to_sql().sql(), "NONE");
63    /// ```
64    None,
65
66    /// Enable full auto-vacuum
67    ///
68    /// # Example
69    /// ```
70    /// # use drizzle_sqlite::pragma::AutoVacuum;
71    /// # use drizzle_core::ToSQL;
72    /// assert_eq!(AutoVacuum::Full.to_sql().sql(), "FULL");
73    /// ```
74    Full,
75
76    /// Enable incremental auto-vacuum
77    ///
78    /// # Example
79    /// ```
80    /// # use drizzle_sqlite::pragma::AutoVacuum;
81    /// # use drizzle_core::ToSQL;
82    /// assert_eq!(AutoVacuum::Incremental.to_sql().sql(), "INCREMENTAL");
83    /// ```
84    Incremental,
85}
86
87/// Journal modes for `SQLite` databases
88///
89/// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_journal_mode)
90#[derive(Debug, Clone, PartialEq, Eq)]
91pub enum JournalMode {
92    /// Delete journal file after each transaction
93    ///
94    /// # Example
95    /// ```
96    /// # use drizzle_sqlite::pragma::JournalMode;
97    /// # use drizzle_core::ToSQL;
98    /// assert_eq!(JournalMode::Delete.to_sql().sql(), "DELETE");
99    /// ```
100    Delete,
101
102    /// Truncate journal file after each transaction
103    ///
104    /// # Example
105    /// ```
106    /// # use drizzle_sqlite::pragma::JournalMode;
107    /// # use drizzle_core::ToSQL;
108    /// assert_eq!(JournalMode::Truncate.to_sql().sql(), "TRUNCATE");
109    /// ```
110    Truncate,
111
112    /// Keep journal file persistent
113    ///
114    /// # Example
115    /// ```
116    /// # use drizzle_sqlite::pragma::JournalMode;
117    /// # use drizzle_core::ToSQL;
118    /// assert_eq!(JournalMode::Persist.to_sql().sql(), "PERSIST");
119    /// ```
120    Persist,
121
122    /// Store journal in memory
123    ///
124    /// # Example
125    /// ```
126    /// # use drizzle_sqlite::pragma::JournalMode;
127    /// # use drizzle_core::ToSQL;
128    /// assert_eq!(JournalMode::Memory.to_sql().sql(), "MEMORY");
129    /// ```
130    Memory,
131
132    /// Write-Ahead Logging mode
133    ///
134    /// # Example
135    /// ```
136    /// # use drizzle_sqlite::pragma::JournalMode;
137    /// # use drizzle_core::ToSQL;
138    /// assert_eq!(JournalMode::Wal.to_sql().sql(), "WAL");
139    /// ```
140    Wal,
141
142    /// Disable journaling
143    ///
144    /// # Example
145    /// ```
146    /// # use drizzle_sqlite::pragma::JournalMode;
147    /// # use drizzle_core::ToSQL;
148    /// assert_eq!(JournalMode::Off.to_sql().sql(), "OFF");
149    /// ```
150    Off,
151}
152
153/// Synchronous modes for `SQLite` databases
154///
155/// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_synchronous)
156#[derive(Debug, Clone, PartialEq, Eq)]
157pub enum Synchronous {
158    /// No syncing - fastest but least safe
159    ///
160    /// # Example
161    /// ```
162    /// # use drizzle_sqlite::pragma::Synchronous;
163    /// # use drizzle_core::ToSQL;
164    /// assert_eq!(Synchronous::Off.to_sql().sql(), "OFF");
165    /// ```
166    Off,
167
168    /// Sync at critical moments - good balance
169    ///
170    /// # Example
171    /// ```
172    /// # use drizzle_sqlite::pragma::Synchronous;
173    /// # use drizzle_core::ToSQL;
174    /// assert_eq!(Synchronous::Normal.to_sql().sql(), "NORMAL");
175    /// ```
176    Normal,
177
178    /// Sync frequently - safest but slower
179    ///
180    /// # Example
181    /// ```
182    /// # use drizzle_sqlite::pragma::Synchronous;
183    /// # use drizzle_core::ToSQL;
184    /// assert_eq!(Synchronous::Full.to_sql().sql(), "FULL");
185    /// ```
186    Full,
187
188    /// Like FULL with additional syncing
189    ///
190    /// # Example
191    /// ```
192    /// # use drizzle_sqlite::pragma::Synchronous;
193    /// # use drizzle_core::ToSQL;
194    /// assert_eq!(Synchronous::Extra.to_sql().sql(), "EXTRA");
195    /// ```
196    Extra,
197}
198
199/// Storage modes for temporary tables and indices
200///
201/// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_temp_store)
202#[derive(Debug, Clone, PartialEq, Eq)]
203pub enum TempStore {
204    /// Use default storage mode
205    ///
206    /// # Example
207    /// ```
208    /// # use drizzle_sqlite::pragma::TempStore;
209    /// # use drizzle_core::ToSQL;
210    /// assert_eq!(TempStore::Default.to_sql().sql(), "DEFAULT");
211    /// ```
212    Default,
213
214    /// Store temporary tables in files
215    ///
216    /// # Example
217    /// ```
218    /// # use drizzle_sqlite::pragma::TempStore;
219    /// # use drizzle_core::ToSQL;
220    /// assert_eq!(TempStore::File.to_sql().sql(), "FILE");
221    /// ```
222    File,
223
224    /// Store temporary tables in memory
225    ///
226    /// # Example
227    /// ```
228    /// # use drizzle_sqlite::pragma::TempStore;
229    /// # use drizzle_core::ToSQL;
230    /// assert_eq!(TempStore::Memory.to_sql().sql(), "MEMORY");
231    /// ```
232    Memory,
233}
234
235/// Database locking modes
236///
237/// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_locking_mode)
238#[derive(Debug, Clone, PartialEq, Eq)]
239pub enum LockingMode {
240    /// Normal locking mode - allows multiple readers
241    ///
242    /// # Example
243    /// ```
244    /// # use drizzle_sqlite::pragma::LockingMode;
245    /// # use drizzle_core::ToSQL;
246    /// assert_eq!(LockingMode::Normal.to_sql().sql(), "NORMAL");
247    /// ```
248    Normal,
249
250    /// Exclusive locking mode - single connection only
251    ///
252    /// # Example
253    /// ```
254    /// # use drizzle_sqlite::pragma::LockingMode;
255    /// # use drizzle_core::ToSQL;
256    /// assert_eq!(LockingMode::Exclusive.to_sql().sql(), "EXCLUSIVE");
257    /// ```
258    Exclusive,
259}
260
261/// Secure delete modes for `SQLite`
262///
263/// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_secure_delete)
264#[derive(Debug, Clone, PartialEq, Eq)]
265pub enum SecureDelete {
266    /// Disable secure delete
267    ///
268    /// # Example
269    /// ```
270    /// # use drizzle_sqlite::pragma::SecureDelete;
271    /// # use drizzle_core::ToSQL;
272    /// assert_eq!(SecureDelete::Off.to_sql().sql(), "OFF");
273    /// ```
274    Off,
275
276    /// Enable secure delete - overwrite deleted data
277    ///
278    /// # Example
279    /// ```
280    /// # use drizzle_sqlite::pragma::SecureDelete;
281    /// # use drizzle_core::ToSQL;
282    /// assert_eq!(SecureDelete::On.to_sql().sql(), "ON");
283    /// ```
284    On,
285
286    /// Fast secure delete - partial overwriting
287    ///
288    /// # Example
289    /// ```
290    /// # use drizzle_sqlite::pragma::SecureDelete;
291    /// # use drizzle_core::ToSQL;
292    /// assert_eq!(SecureDelete::Fast.to_sql().sql(), "FAST");
293    /// ```
294    Fast,
295}
296
297/// Encoding types for `SQLite` databases
298///
299/// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_encoding)
300#[derive(Debug, Clone, PartialEq, Eq)]
301pub enum Encoding {
302    /// UTF-8 encoding
303    ///
304    /// # Example
305    /// ```
306    /// # use drizzle_sqlite::pragma::Encoding;
307    /// # use drizzle_core::ToSQL;
308    /// assert_eq!(Encoding::Utf8.to_sql().sql(), "UTF-8");
309    /// ```
310    Utf8,
311
312    /// UTF-16 little endian encoding
313    ///
314    /// # Example
315    /// ```
316    /// # use drizzle_sqlite::pragma::Encoding;
317    /// # use drizzle_core::ToSQL;
318    /// assert_eq!(Encoding::Utf16Le.to_sql().sql(), "UTF-16LE");
319    /// ```
320    Utf16Le,
321
322    /// UTF-16 big endian encoding
323    ///
324    /// # Example
325    /// ```
326    /// # use drizzle_sqlite::pragma::Encoding;
327    /// # use drizzle_core::ToSQL;
328    /// assert_eq!(Encoding::Utf16Be.to_sql().sql(), "UTF-16BE");
329    /// ```
330    Utf16Be,
331}
332
333/// Cache spill settings for `SQLite` databases
334///
335/// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_cache_spill)
336#[derive(Debug, Clone, PartialEq, Eq)]
337pub enum CacheSpill {
338    /// Enable or disable cache spilling
339    ///
340    /// # Example
341    /// ```
342    /// # use drizzle_sqlite::pragma::CacheSpill;
343    /// # use drizzle_core::ToSQL;
344    /// let setting = CacheSpill::Enabled(true);
345    /// assert_eq!(setting.to_sql().sql(), "ON");
346    /// ```
347    Enabled(bool),
348
349    /// Set the spill threshold (pages)
350    ///
351    /// # Example
352    /// ```
353    /// # use drizzle_sqlite::pragma::CacheSpill;
354    /// # use drizzle_core::ToSQL;
355    /// let setting = CacheSpill::Pages(1000);
356    /// assert_eq!(setting.to_sql().sql(), "1000");
357    /// ```
358    Pages(i32),
359}
360
361/// WAL checkpoint modes
362///
363/// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_wal_checkpoint)
364#[derive(Debug, Clone, PartialEq, Eq)]
365pub enum WalCheckpointMode {
366    /// Passive checkpoint
367    Passive,
368    /// Full checkpoint
369    Full,
370    /// Restart checkpoint
371    Restart,
372    /// Truncate checkpoint
373    Truncate,
374    /// No-op checkpoint (query status only)
375    Noop,
376}
377
378/// Writable schema modes (test-only)
379///
380/// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_writable_schema)
381#[derive(Debug, Clone, PartialEq, Eq)]
382pub enum WritableSchema {
383    /// Enable or disable writable schema mode
384    Enabled(bool),
385    /// Reset the `writable_schema` setting
386    Reset,
387}
388
389/// `SQLite` pragma statements for database configuration and introspection
390#[derive(Debug, Clone, PartialEq, Eq)]
391pub enum Pragma {
392    // Read/Write Configuration Pragmas
393    /// Set or query the 32-bit signed big-endian application ID
394    ///
395    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_application_id)
396    ///
397    /// # Example
398    /// ```
399    /// # use drizzle_sqlite::pragma::Pragma;
400    /// # use drizzle_core::ToSQL;
401    /// let pragma = Pragma::ApplicationId(12345);
402    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA application_id = 12345");
403    /// ```
404    ApplicationId(i32),
405
406    /// Query or set the auto-vacuum status in the database
407    ///
408    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_auto_vacuum)
409    ///
410    /// # Example
411    /// ```
412    /// # use drizzle_sqlite::pragma::{Pragma, AutoVacuum};
413    /// # use drizzle_core::ToSQL;
414    /// let pragma = Pragma::AutoVacuum(AutoVacuum::Full);
415    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA auto_vacuum = FULL");
416    /// ```
417    AutoVacuum(AutoVacuum),
418
419    /// Suggest maximum number of database disk pages in memory
420    ///
421    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_cache_size)
422    ///
423    /// # Example
424    /// ```
425    /// # use drizzle_sqlite::pragma::Pragma;
426    /// # use drizzle_core::ToSQL;
427    /// let pragma = Pragma::CacheSize(-2000);
428    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA cache_size = -2000");
429    /// ```
430    CacheSize(i32),
431
432    /// Query, set, or clear the enforcement of foreign key constraints
433    ///
434    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_foreign_keys)
435    ///
436    /// # Example
437    /// ```
438    /// # use drizzle_sqlite::pragma::Pragma;
439    /// # use drizzle_core::ToSQL;
440    /// let pragma = Pragma::ForeignKeys(true);
441    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA foreign_keys = ON");
442    ///
443    /// let pragma = Pragma::ForeignKeys(false);
444    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA foreign_keys = OFF");
445    /// ```
446    ForeignKeys(bool),
447
448    /// Query or set the journal mode for databases
449    ///
450    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_journal_mode)
451    ///
452    /// # Example
453    /// ```
454    /// # use drizzle_sqlite::pragma::{Pragma, JournalMode};
455    /// # use drizzle_core::ToSQL;
456    /// let pragma = Pragma::JournalMode(JournalMode::Wal);
457    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA journal_mode = WAL");
458    /// ```
459    JournalMode(JournalMode),
460
461    /// Query or set the WAL auto-checkpoint threshold (pages)
462    ///
463    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_wal_autocheckpoint)
464    ///
465    /// # Example
466    /// ```
467    /// # use drizzle_sqlite::pragma::Pragma;
468    /// # use drizzle_core::ToSQL;
469    /// let pragma = Pragma::WalAutocheckpoint(1000);
470    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA wal_autocheckpoint = 1000");
471    /// ```
472    WalAutocheckpoint(i32),
473
474    /// Control how aggressively `SQLite` will write data
475    ///
476    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_synchronous)
477    ///
478    /// # Example
479    /// ```
480    /// # use drizzle_sqlite::pragma::{Pragma, Synchronous};
481    /// # use drizzle_core::ToSQL;
482    /// let pragma = Pragma::Synchronous(Synchronous::Normal);
483    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA synchronous = NORMAL");
484    /// ```
485    Synchronous(Synchronous),
486
487    /// Query or set the storage mode used by temporary tables and indices
488    ///
489    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_temp_store)
490    ///
491    /// # Example
492    /// ```
493    /// # use drizzle_sqlite::pragma::{Pragma, TempStore};
494    /// # use drizzle_core::ToSQL;
495    /// let pragma = Pragma::TempStore(TempStore::Memory);
496    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA temp_store = MEMORY");
497    /// ```
498    TempStore(TempStore),
499
500    /// Query or set the database connection locking-mode
501    ///
502    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_locking_mode)
503    ///
504    /// # Example
505    /// ```
506    /// # use drizzle_sqlite::pragma::{Pragma, LockingMode};
507    /// # use drizzle_core::ToSQL;
508    /// let pragma = Pragma::LockingMode(LockingMode::Exclusive);
509    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA locking_mode = EXCLUSIVE");
510    /// ```
511    LockingMode(LockingMode),
512
513    /// Query or set the secure-delete setting
514    ///
515    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_secure_delete)
516    ///
517    /// # Example
518    /// ```
519    /// # use drizzle_sqlite::pragma::{Pragma, SecureDelete};
520    /// # use drizzle_core::ToSQL;
521    /// let pragma = Pragma::SecureDelete(SecureDelete::Fast);
522    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA secure_delete = FAST");
523    /// ```
524    SecureDelete(SecureDelete),
525
526    /// Set or get the user-version integer
527    ///
528    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_user_version)
529    ///
530    /// # Example
531    /// ```
532    /// # use drizzle_sqlite::pragma::Pragma;
533    /// # use drizzle_core::ToSQL;
534    /// let pragma = Pragma::UserVersion(42);
535    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA user_version = 42");
536    /// ```
537    UserVersion(i32),
538
539    /// Query or set the text encoding used by the database
540    ///
541    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_encoding)
542    ///
543    /// # Example
544    /// ```
545    /// # use drizzle_sqlite::pragma::{Pragma, Encoding};
546    /// # use drizzle_core::ToSQL;
547    /// let pragma = Pragma::Encoding(Encoding::Utf8);
548    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA encoding = UTF-8");
549    /// ```
550    Encoding(Encoding),
551
552    /// Query or set the database page size in bytes
553    ///
554    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_page_size)
555    ///
556    /// # Example
557    /// ```
558    /// # use drizzle_sqlite::pragma::Pragma;
559    /// # use drizzle_core::ToSQL;
560    /// let pragma = Pragma::PageSize(4096);
561    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA page_size = 4096");
562    /// ```
563    PageSize(i32),
564
565    /// Query or set the maximum memory map size
566    ///
567    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_mmap_size)
568    ///
569    /// # Example
570    /// ```
571    /// # use drizzle_sqlite::pragma::Pragma;
572    /// # use drizzle_core::ToSQL;
573    /// let pragma = Pragma::MmapSize(268435456);
574    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA mmap_size = 268435456");
575    /// ```
576    MmapSize(i64),
577
578    /// Enable or disable recursive trigger firing
579    ///
580    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_recursive_triggers)
581    ///
582    /// # Example
583    /// ```
584    /// # use drizzle_sqlite::pragma::Pragma;
585    /// # use drizzle_core::ToSQL;
586    /// let pragma = Pragma::RecursiveTriggers(true);
587    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA recursive_triggers = ON");
588    /// ```
589    RecursiveTriggers(bool),
590
591    /// Query or set the ANALYZE limit
592    ///
593    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_analysis_limit)
594    AnalysisLimit(i32),
595
596    /// Query or set automatic indexing
597    ///
598    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_automatic_index)
599    AutomaticIndex(bool),
600
601    /// Query or set the busy timeout (milliseconds)
602    ///
603    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_busy_timeout)
604    BusyTimeout(i32),
605
606    /// Query or set cache spill settings
607    ///
608    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_cache_spill)
609    CacheSpill(CacheSpill),
610
611    /// Query or set `case_sensitive_like` (deprecated)
612    ///
613    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_case_sensitive_like)
614    CaseSensitiveLike(bool),
615
616    /// Enable or disable cell size checking
617    ///
618    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_cell_size_check)
619    CellSizeCheck(bool),
620
621    /// Enable or disable checkpoint fullfsync
622    ///
623    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_checkpoint_fullfsync)
624    CheckpointFullFsync(bool),
625
626    /// Query or set `count_changes` (deprecated)
627    ///
628    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_count_changes)
629    CountChanges(bool),
630
631    /// Query or set `data_store_directory` (deprecated)
632    ///
633    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_data_store_directory)
634    DataStoreDirectory(&'static str),
635
636    /// Query or set `default_cache_size` (deprecated)
637    ///
638    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_default_cache_size)
639    DefaultCacheSize(i32),
640
641    /// Query or set `defer_foreign_keys`
642    ///
643    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_defer_foreign_keys)
644    DeferForeignKeys(bool),
645
646    /// Query or set `empty_result_callbacks` (deprecated)
647    ///
648    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_empty_result_callbacks)
649    EmptyResultCallbacks(bool),
650
651    /// Query or set `full_column_names` (deprecated)
652    ///
653    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_full_column_names)
654    FullColumnNames(bool),
655
656    /// Query or set fullfsync
657    ///
658    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_fullfsync)
659    FullFsync(bool),
660
661    /// Query or set `hard_heap_limit`
662    ///
663    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_hard_heap_limit)
664    HardHeapLimit(i64),
665
666    /// Query or set `ignore_check_constraints`
667    ///
668    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_ignore_check_constraints)
669    IgnoreCheckConstraints(bool),
670
671    /// Query or set `journal_size_limit`
672    ///
673    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_journal_size_limit)
674    JournalSizeLimit(i64),
675
676    /// Query or set `legacy_alter_table`
677    ///
678    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_legacy_alter_table)
679    LegacyAlterTable(bool),
680
681    /// Query `legacy_file_format` (deprecated)
682    ///
683    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_legacy_file_format)
684    LegacyFileFormat,
685
686    /// Query or set `max_page_count`
687    ///
688    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_max_page_count)
689    MaxPageCount(i32),
690
691    /// Query or set `query_only`
692    ///
693    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_query_only)
694    QueryOnly(bool),
695
696    /// Query or set `read_uncommitted`
697    ///
698    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_read_uncommitted)
699    ReadUncommitted(bool),
700
701    /// Query or set `reverse_unordered_selects`
702    ///
703    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_reverse_unordered_selects)
704    ReverseUnorderedSelects(bool),
705
706    /// Query or set `schema_version` (test-only)
707    ///
708    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_schema_version)
709    SchemaVersion(i32),
710
711    /// Query or set `short_column_names` (deprecated)
712    ///
713    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_short_column_names)
714    ShortColumnNames(bool),
715
716    /// Query or set `soft_heap_limit`
717    ///
718    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_soft_heap_limit)
719    SoftHeapLimit(i64),
720
721    /// Query or set `temp_store_directory` (deprecated)
722    ///
723    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_temp_store_directory)
724    TempStoreDirectory(&'static str),
725
726    /// Query or set threads
727    ///
728    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_threads)
729    Threads(i32),
730
731    /// Query or set `trusted_schema`
732    ///
733    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_trusted_schema)
734    TrustedSchema(bool),
735
736    /// Query or set `writable_schema` (test-only)
737    ///
738    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_writable_schema)
739    WritableSchema(WritableSchema),
740
741    /// Query or set `parser_trace` (requires `SQLITE_DEBUG`)
742    ///
743    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_parser_trace)
744    ParserTrace(bool),
745
746    /// Query or set `vdbe_addoptrace` (requires `SQLITE_DEBUG`)
747    ///
748    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_vdbe_addoptrace)
749    VdbeAddoptrace(bool),
750
751    /// Query or set `vdbe_debug` (requires `SQLITE_DEBUG`)
752    ///
753    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_vdbe_debug)
754    VdbeDebug(bool),
755
756    /// Query or set `vdbe_listing` (requires `SQLITE_DEBUG`)
757    ///
758    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_vdbe_listing)
759    VdbeListing(bool),
760
761    /// Query or set `vdbe_trace` (requires `SQLITE_DEBUG`)
762    ///
763    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_vdbe_trace)
764    VdbeTrace(bool),
765
766    // Read-Only Query Pragmas
767    /// Return a list of collating sequences
768    ///
769    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_collation_list)
770    ///
771    /// # Example
772    /// ```
773    /// # use drizzle_sqlite::pragma::Pragma;
774    /// # use drizzle_core::ToSQL;
775    /// let pragma = Pragma::CollationList;
776    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA collation_list");
777    /// ```
778    CollationList,
779
780    /// Return compile-time options used when building `SQLite`
781    ///
782    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_compile_options)
783    ///
784    /// # Example
785    /// ```
786    /// # use drizzle_sqlite::pragma::Pragma;
787    /// # use drizzle_core::ToSQL;
788    /// let pragma = Pragma::CompileOptions;
789    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA compile_options");
790    /// ```
791    CompileOptions,
792
793    /// Return information about attached databases
794    ///
795    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_database_list)
796    ///
797    /// # Example
798    /// ```
799    /// # use drizzle_sqlite::pragma::Pragma;
800    /// # use drizzle_core::ToSQL;
801    /// let pragma = Pragma::DatabaseList;
802    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA database_list");
803    /// ```
804    DatabaseList,
805
806    /// Return a list of SQL functions
807    ///
808    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_function_list)
809    ///
810    /// # Example
811    /// ```
812    /// # use drizzle_sqlite::pragma::Pragma;
813    /// # use drizzle_core::ToSQL;
814    /// let pragma = Pragma::FunctionList;
815    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA function_list");
816    /// ```
817    FunctionList,
818
819    /// Return information about tables and views in the schema
820    ///
821    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_table_list)
822    ///
823    /// # Example
824    /// ```
825    /// # use drizzle_sqlite::pragma::Pragma;
826    /// # use drizzle_core::ToSQL;
827    /// let pragma = Pragma::TableList;
828    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA table_list");
829    /// ```
830    TableList,
831
832    /// Return extended table information including hidden columns
833    ///
834    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_table_xinfo)
835    ///
836    /// # Example
837    /// ```
838    /// # use drizzle_sqlite::pragma::Pragma;
839    /// # use drizzle_core::ToSQL;
840    /// let pragma = Pragma::TableXInfo("users");
841    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA table_xinfo(users)");
842    /// ```
843    TableXInfo(&'static str),
844
845    /// Return a list of available virtual table modules
846    ///
847    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_module_list)
848    ///
849    /// # Example
850    /// ```
851    /// # use drizzle_sqlite::pragma::Pragma;
852    /// # use drizzle_core::ToSQL;
853    /// let pragma = Pragma::ModuleList;
854    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA module_list");
855    /// ```
856    ModuleList,
857
858    /// Return the `data_version` counter
859    ///
860    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_data_version)
861    DataVersion,
862
863    /// Return the number of free pages in the database file
864    ///
865    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_freelist_count)
866    FreelistCount,
867
868    /// Return the page count for the database
869    ///
870    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_page_count)
871    PageCount,
872
873    /// Return a list of available pragmas
874    ///
875    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_pragma_list)
876    PragmaList,
877
878    /// Return statistics (test-only)
879    ///
880    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_stats)
881    Stats,
882
883    // Utility Pragmas
884    /// Perform incremental vacuuming
885    ///
886    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_incremental_vacuum)
887    IncrementalVacuum(Option<i32>),
888
889    /// Release as much memory as possible
890    ///
891    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_shrink_memory)
892    ShrinkMemory,
893
894    /// Run a WAL checkpoint
895    ///
896    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_wal_checkpoint)
897    WalCheckpoint(Option<WalCheckpointMode>),
898
899    /// Perform database integrity check
900    ///
901    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_integrity_check)
902    ///
903    /// # Example
904    /// ```
905    /// # use drizzle_sqlite::pragma::Pragma;
906    /// # use drizzle_core::ToSQL;
907    /// // Check entire database
908    /// let pragma = Pragma::IntegrityCheck(None);
909    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA integrity_check");
910    ///
911    /// // Check specific table
912    /// let pragma = Pragma::IntegrityCheck(Some("users"));
913    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA integrity_check(users)");
914    /// ```
915    IntegrityCheck(Option<&'static str>),
916
917    /// Perform faster database integrity check
918    ///
919    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_quick_check)
920    ///
921    /// # Example
922    /// ```
923    /// # use drizzle_sqlite::pragma::Pragma;
924    /// # use drizzle_core::ToSQL;
925    /// let pragma = Pragma::QuickCheck(None);
926    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA quick_check");
927    ///
928    /// let pragma = Pragma::QuickCheck(Some("users"));
929    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA quick_check(users)");
930    /// ```
931    QuickCheck(Option<&'static str>),
932
933    /// Attempt to optimize the database
934    ///
935    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_optimize)
936    ///
937    /// # Example
938    /// ```
939    /// # use drizzle_sqlite::pragma::Pragma;
940    /// # use drizzle_core::ToSQL;
941    /// let pragma = Pragma::Optimize(None);
942    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA optimize");
943    ///
944    /// let pragma = Pragma::Optimize(Some(0x10002));
945    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA optimize(65538)");
946    /// ```
947    Optimize(Option<u32>),
948
949    /// Check foreign key constraints for a table
950    ///
951    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_foreign_key_check)
952    ///
953    /// # Example
954    /// ```
955    /// # use drizzle_sqlite::pragma::Pragma;
956    /// # use drizzle_core::ToSQL;
957    /// let pragma = Pragma::ForeignKeyCheck(None);
958    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA foreign_key_check");
959    ///
960    /// let pragma = Pragma::ForeignKeyCheck(Some("orders"));
961    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA foreign_key_check(orders)");
962    /// ```
963    ForeignKeyCheck(Option<&'static str>),
964
965    // Table-specific Pragmas
966    /// Return information about table columns
967    ///
968    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_table_info)
969    ///
970    /// # Example
971    /// ```
972    /// # use drizzle_sqlite::pragma::Pragma;
973    /// # use drizzle_core::ToSQL;
974    /// let pragma = Pragma::TableInfo("users");
975    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA table_info(users)");
976    /// ```
977    TableInfo(&'static str),
978
979    /// Return information about table indexes
980    ///
981    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_index_list)
982    ///
983    /// # Example
984    /// ```
985    /// # use drizzle_sqlite::pragma::Pragma;
986    /// # use drizzle_core::ToSQL;
987    /// let pragma = Pragma::IndexList("users");
988    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA index_list(users)");
989    /// ```
990    IndexList(&'static str),
991
992    /// Return information about index columns
993    ///
994    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_index_info)
995    ///
996    /// # Example
997    /// ```
998    /// # use drizzle_sqlite::pragma::Pragma;
999    /// # use drizzle_core::ToSQL;
1000    /// let pragma = Pragma::IndexInfo("idx_users_email");
1001    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA index_info(idx_users_email)");
1002    /// ```
1003    IndexInfo(&'static str),
1004
1005    /// Return extended information about index columns
1006    ///
1007    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_index_xinfo)
1008    IndexXInfo(&'static str),
1009
1010    /// Return foreign key information for a table
1011    ///
1012    /// [SQLite Documentation](https://sqlite.org/pragma.html#pragma_foreign_key_list)
1013    ///
1014    /// # Example
1015    /// ```
1016    /// # use drizzle_sqlite::pragma::Pragma;
1017    /// # use drizzle_core::ToSQL;
1018    /// let pragma = Pragma::ForeignKeyList("orders");
1019    /// assert_eq!(pragma.to_sql().sql(), "PRAGMA foreign_key_list(orders)");
1020    /// ```
1021    ForeignKeyList(&'static str),
1022}
1023
1024impl<'a> ToSQL<'a, SQLiteValue<'a>> for AutoVacuum {
1025    fn to_sql(&self) -> SQL<'a, SQLiteValue<'a>> {
1026        match self {
1027            Self::None => SQL::raw("NONE"),
1028            Self::Full => SQL::raw("FULL"),
1029            Self::Incremental => SQL::raw("INCREMENTAL"),
1030        }
1031    }
1032}
1033
1034impl<'a> ToSQL<'a, SQLiteValue<'a>> for JournalMode {
1035    fn to_sql(&self) -> SQL<'a, SQLiteValue<'a>> {
1036        match self {
1037            Self::Delete => SQL::raw("DELETE"),
1038            Self::Truncate => SQL::raw("TRUNCATE"),
1039            Self::Persist => SQL::raw("PERSIST"),
1040            Self::Memory => SQL::raw("MEMORY"),
1041            Self::Wal => SQL::raw("WAL"),
1042            Self::Off => SQL::raw("OFF"),
1043        }
1044    }
1045}
1046
1047impl<'a> ToSQL<'a, SQLiteValue<'a>> for Synchronous {
1048    fn to_sql(&self) -> SQL<'a, SQLiteValue<'a>> {
1049        match self {
1050            Self::Off => SQL::raw("OFF"),
1051            Self::Normal => SQL::raw("NORMAL"),
1052            Self::Full => SQL::raw("FULL"),
1053            Self::Extra => SQL::raw("EXTRA"),
1054        }
1055    }
1056}
1057
1058impl<'a> ToSQL<'a, SQLiteValue<'a>> for TempStore {
1059    fn to_sql(&self) -> SQL<'a, SQLiteValue<'a>> {
1060        match self {
1061            Self::Default => SQL::raw("DEFAULT"),
1062            Self::File => SQL::raw("FILE"),
1063            Self::Memory => SQL::raw("MEMORY"),
1064        }
1065    }
1066}
1067
1068impl<'a> ToSQL<'a, SQLiteValue<'a>> for LockingMode {
1069    fn to_sql(&self) -> SQL<'a, SQLiteValue<'a>> {
1070        match self {
1071            Self::Normal => SQL::raw("NORMAL"),
1072            Self::Exclusive => SQL::raw("EXCLUSIVE"),
1073        }
1074    }
1075}
1076
1077impl<'a> ToSQL<'a, SQLiteValue<'a>> for SecureDelete {
1078    fn to_sql(&self) -> SQL<'a, SQLiteValue<'a>> {
1079        match self {
1080            Self::Off => SQL::raw("OFF"),
1081            Self::On => SQL::raw("ON"),
1082            Self::Fast => SQL::raw("FAST"),
1083        }
1084    }
1085}
1086
1087impl<'a> ToSQL<'a, SQLiteValue<'a>> for Encoding {
1088    fn to_sql(&self) -> SQL<'a, SQLiteValue<'a>> {
1089        match self {
1090            Self::Utf8 => SQL::raw("UTF-8"),
1091            Self::Utf16Le => SQL::raw("UTF-16LE"),
1092            Self::Utf16Be => SQL::raw("UTF-16BE"),
1093        }
1094    }
1095}
1096
1097impl<'a> ToSQL<'a, SQLiteValue<'a>> for CacheSpill {
1098    fn to_sql(&self) -> SQL<'a, SQLiteValue<'a>> {
1099        match self {
1100            Self::Enabled(enabled) => SQL::raw(if *enabled { "ON" } else { "OFF" }),
1101            Self::Pages(pages) => SQL::raw(format!("{pages}")),
1102        }
1103    }
1104}
1105
1106impl<'a> ToSQL<'a, SQLiteValue<'a>> for WalCheckpointMode {
1107    fn to_sql(&self) -> SQL<'a, SQLiteValue<'a>> {
1108        match self {
1109            Self::Passive => SQL::raw("PASSIVE"),
1110            Self::Full => SQL::raw("FULL"),
1111            Self::Restart => SQL::raw("RESTART"),
1112            Self::Truncate => SQL::raw("TRUNCATE"),
1113            Self::Noop => SQL::raw("NOOP"),
1114        }
1115    }
1116}
1117
1118impl<'a> ToSQL<'a, SQLiteValue<'a>> for WritableSchema {
1119    fn to_sql(&self) -> SQL<'a, SQLiteValue<'a>> {
1120        match self {
1121            Self::Enabled(enabled) => SQL::raw(if *enabled { "ON" } else { "OFF" }),
1122            Self::Reset => SQL::raw("RESET"),
1123        }
1124    }
1125}
1126
1127fn bool_pragma<'a>(name: &str, enabled: bool) -> SQL<'a, SQLiteValue<'a>> {
1128    let suffix = if enabled { "ON" } else { "OFF" };
1129    SQL::raw(format!("PRAGMA {name} = {suffix}"))
1130}
1131
1132/// Handles the utility pragmas where the argument is `Option<T>`.
1133fn utility_pragma<'a>(pragma: &Pragma) -> Option<SQL<'a, SQLiteValue<'a>>> {
1134    match pragma {
1135        Pragma::IncrementalVacuum(pages) => Some(pages.as_ref().map_or_else(
1136            || SQL::raw("PRAGMA incremental_vacuum"),
1137            |count| SQL::raw(format!("PRAGMA incremental_vacuum({count})")),
1138        )),
1139        Pragma::ShrinkMemory => Some(SQL::raw("PRAGMA shrink_memory")),
1140        Pragma::WalCheckpoint(mode) => Some(mode.as_ref().map_or_else(
1141            || SQL::raw("PRAGMA wal_checkpoint"),
1142            |m| SQL::raw("PRAGMA wal_checkpoint = ").append(m.to_sql()),
1143        )),
1144        Pragma::IntegrityCheck(table) => Some(table.as_ref().map_or_else(
1145            || SQL::raw("PRAGMA integrity_check"),
1146            |t| SQL::raw(format!("PRAGMA integrity_check({t})")),
1147        )),
1148        Pragma::QuickCheck(table) => Some(table.as_ref().map_or_else(
1149            || SQL::raw("PRAGMA quick_check"),
1150            |t| SQL::raw(format!("PRAGMA quick_check({t})")),
1151        )),
1152        Pragma::Optimize(mask) => Some(mask.as_ref().map_or_else(
1153            || SQL::raw("PRAGMA optimize"),
1154            |m| SQL::raw(format!("PRAGMA optimize({m})")),
1155        )),
1156        Pragma::ForeignKeyCheck(table) => Some(table.as_ref().map_or_else(
1157            || SQL::raw("PRAGMA foreign_key_check"),
1158            |t| SQL::raw(format!("PRAGMA foreign_key_check({t})")),
1159        )),
1160        _ => None,
1161    }
1162}
1163
1164impl<'a> ToSQL<'a, SQLiteValue<'a>> for Pragma {
1165    fn to_sql(&self) -> SQL<'a, SQLiteValue<'a>> {
1166        if let Some(sql) = utility_pragma(self) {
1167            return sql;
1168        }
1169        match self {
1170            // Read/Write Configuration Pragmas
1171            Self::ApplicationId(id) => SQL::raw(format!("PRAGMA application_id = {id}")),
1172            Self::AutoVacuum(mode) => SQL::raw("PRAGMA auto_vacuum = ").append(mode.to_sql()),
1173            Self::CacheSize(size) => SQL::raw(format!("PRAGMA cache_size = {size}")),
1174            Self::ForeignKeys(enabled) => bool_pragma("foreign_keys", *enabled),
1175            Self::JournalMode(mode) => SQL::raw("PRAGMA journal_mode = ").append(mode.to_sql()),
1176            Self::Synchronous(mode) => SQL::raw("PRAGMA synchronous = ").append(mode.to_sql()),
1177            Self::WalAutocheckpoint(pages) => {
1178                SQL::raw(format!("PRAGMA wal_autocheckpoint = {pages}"))
1179            }
1180            Self::TempStore(store) => SQL::raw("PRAGMA temp_store = ").append(store.to_sql()),
1181            Self::LockingMode(mode) => SQL::raw("PRAGMA locking_mode = ").append(mode.to_sql()),
1182            Self::SecureDelete(mode) => SQL::raw("PRAGMA secure_delete = ").append(mode.to_sql()),
1183            Self::UserVersion(version) => SQL::raw(format!("PRAGMA user_version = {version}")),
1184            Self::Encoding(encoding) => SQL::raw("PRAGMA encoding = ").append(encoding.to_sql()),
1185            Self::PageSize(size) => SQL::raw(format!("PRAGMA page_size = {size}")),
1186            Self::MmapSize(size) => SQL::raw(format!("PRAGMA mmap_size = {size}")),
1187            Self::RecursiveTriggers(enabled) => bool_pragma("recursive_triggers", *enabled),
1188            Self::AnalysisLimit(limit) => SQL::raw(format!("PRAGMA analysis_limit = {limit}")),
1189            Self::AutomaticIndex(enabled) => bool_pragma("automatic_index", *enabled),
1190            Self::BusyTimeout(timeout) => SQL::raw(format!("PRAGMA busy_timeout = {timeout}")),
1191            Self::CacheSpill(setting) => SQL::raw("PRAGMA cache_spill = ").append(setting.to_sql()),
1192            Self::CaseSensitiveLike(enabled) => bool_pragma("case_sensitive_like", *enabled),
1193            Self::CellSizeCheck(enabled) => bool_pragma("cell_size_check", *enabled),
1194            Self::CheckpointFullFsync(enabled) => bool_pragma("checkpoint_fullfsync", *enabled),
1195            Self::CountChanges(enabled) => bool_pragma("count_changes", *enabled),
1196            Self::DataStoreDirectory(directory) => {
1197                SQL::raw(format!("PRAGMA data_store_directory = '{directory}'"))
1198            }
1199            Self::DefaultCacheSize(size) => SQL::raw(format!("PRAGMA default_cache_size = {size}")),
1200            Self::DeferForeignKeys(enabled) => bool_pragma("defer_foreign_keys", *enabled),
1201            Self::EmptyResultCallbacks(enabled) => bool_pragma("empty_result_callbacks", *enabled),
1202            Self::FullColumnNames(enabled) => bool_pragma("full_column_names", *enabled),
1203            Self::FullFsync(enabled) => bool_pragma("fullfsync", *enabled),
1204            Self::HardHeapLimit(limit) => SQL::raw(format!("PRAGMA hard_heap_limit = {limit}")),
1205            Self::IgnoreCheckConstraints(enabled) => {
1206                bool_pragma("ignore_check_constraints", *enabled)
1207            }
1208            Self::JournalSizeLimit(limit) => {
1209                SQL::raw(format!("PRAGMA journal_size_limit = {limit}"))
1210            }
1211            Self::LegacyAlterTable(enabled) => bool_pragma("legacy_alter_table", *enabled),
1212            Self::LegacyFileFormat => SQL::raw("PRAGMA legacy_file_format"),
1213            Self::MaxPageCount(count) => SQL::raw(format!("PRAGMA max_page_count = {count}")),
1214            Self::QueryOnly(enabled) => bool_pragma("query_only", *enabled),
1215            Self::ReadUncommitted(enabled) => bool_pragma("read_uncommitted", *enabled),
1216            Self::ReverseUnorderedSelects(enabled) => {
1217                bool_pragma("reverse_unordered_selects", *enabled)
1218            }
1219            Self::SchemaVersion(version) => SQL::raw(format!("PRAGMA schema_version = {version}")),
1220            Self::ShortColumnNames(enabled) => bool_pragma("short_column_names", *enabled),
1221            Self::SoftHeapLimit(limit) => SQL::raw(format!("PRAGMA soft_heap_limit = {limit}")),
1222            Self::TempStoreDirectory(directory) => {
1223                SQL::raw(format!("PRAGMA temp_store_directory = '{directory}'"))
1224            }
1225            Self::Threads(threads) => SQL::raw(format!("PRAGMA threads = {threads}")),
1226            Self::TrustedSchema(enabled) => bool_pragma("trusted_schema", *enabled),
1227            Self::WritableSchema(mode) => {
1228                SQL::raw("PRAGMA writable_schema = ").append(mode.to_sql())
1229            }
1230            Self::ParserTrace(enabled) => bool_pragma("parser_trace", *enabled),
1231            Self::VdbeAddoptrace(enabled) => bool_pragma("vdbe_addoptrace", *enabled),
1232            Self::VdbeDebug(enabled) => bool_pragma("vdbe_debug", *enabled),
1233            Self::VdbeListing(enabled) => bool_pragma("vdbe_listing", *enabled),
1234            Self::VdbeTrace(enabled) => bool_pragma("vdbe_trace", *enabled),
1235
1236            // Read-Only Query Pragmas
1237            Self::CollationList => SQL::raw("PRAGMA collation_list"),
1238            Self::CompileOptions => SQL::raw("PRAGMA compile_options"),
1239            Self::DatabaseList => SQL::raw("PRAGMA database_list"),
1240            Self::FunctionList => SQL::raw("PRAGMA function_list"),
1241            Self::TableList => SQL::raw("PRAGMA table_list"),
1242            Self::TableXInfo(table) => SQL::raw(format!("PRAGMA table_xinfo({table})")),
1243            Self::ModuleList => SQL::raw("PRAGMA module_list"),
1244            Self::DataVersion => SQL::raw("PRAGMA data_version"),
1245            Self::FreelistCount => SQL::raw("PRAGMA freelist_count"),
1246            Self::PageCount => SQL::raw("PRAGMA page_count"),
1247            Self::PragmaList => SQL::raw("PRAGMA pragma_list"),
1248            Self::Stats => SQL::raw("PRAGMA stats"),
1249
1250            // Utility Pragmas are routed through `utility_pragma` above.
1251            Self::IncrementalVacuum(_)
1252            | Self::ShrinkMemory
1253            | Self::WalCheckpoint(_)
1254            | Self::IntegrityCheck(_)
1255            | Self::QuickCheck(_)
1256            | Self::Optimize(_)
1257            | Self::ForeignKeyCheck(_) => unreachable!("routed via utility_pragma"),
1258
1259            // Table-specific Pragmas
1260            Self::TableInfo(table) => SQL::raw(format!("PRAGMA table_info({table})")),
1261            Self::IndexList(table) => SQL::raw(format!("PRAGMA index_list({table})")),
1262            Self::IndexInfo(index) => SQL::raw(format!("PRAGMA index_info({index})")),
1263            Self::IndexXInfo(index) => SQL::raw(format!("PRAGMA index_xinfo({index})")),
1264            Self::ForeignKeyList(table) => SQL::raw(format!("PRAGMA foreign_key_list({table})")),
1265        }
1266    }
1267}
1268
1269impl Pragma {
1270    /// Create a PRAGMA query to get the current value (read-only operation)
1271    #[must_use]
1272    pub fn query(pragma_name: &str) -> SQL<'static, SQLiteValue<'static>> {
1273        SQL::raw(format!("PRAGMA {pragma_name}"))
1274    }
1275
1276    /// Convenience constructor for `foreign_keys` pragma
1277    #[must_use]
1278    pub const fn foreign_keys(enabled: bool) -> Self {
1279        Self::ForeignKeys(enabled)
1280    }
1281
1282    /// Convenience constructor for `journal_mode` pragma
1283    #[must_use]
1284    pub const fn journal_mode(mode: JournalMode) -> Self {
1285        Self::JournalMode(mode)
1286    }
1287
1288    /// Convenience constructor for `wal_autocheckpoint` pragma
1289    #[must_use]
1290    pub const fn wal_autocheckpoint(pages: i32) -> Self {
1291        Self::WalAutocheckpoint(pages)
1292    }
1293
1294    /// Convenience constructor for `table_info` pragma
1295    #[must_use]
1296    pub const fn table_info(table: &'static str) -> Self {
1297        Self::TableInfo(table)
1298    }
1299
1300    /// Convenience constructor for `index_list` pragma
1301    #[must_use]
1302    pub const fn index_list(table: &'static str) -> Self {
1303        Self::IndexList(table)
1304    }
1305
1306    /// Convenience constructor for `foreign_key_list` pragma
1307    #[must_use]
1308    pub const fn foreign_key_list(table: &'static str) -> Self {
1309        Self::ForeignKeyList(table)
1310    }
1311
1312    /// Convenience constructor for `integrity_check` pragma
1313    #[must_use]
1314    pub const fn integrity_check(table: Option<&'static str>) -> Self {
1315        Self::IntegrityCheck(table)
1316    }
1317
1318    /// Convenience constructor for `foreign_key_check` pragma
1319    #[must_use]
1320    pub const fn foreign_key_check(table: Option<&'static str>) -> Self {
1321        Self::ForeignKeyCheck(table)
1322    }
1323
1324    /// Convenience constructor for `table_xinfo` pragma
1325    #[must_use]
1326    pub const fn table_xinfo(table: &'static str) -> Self {
1327        Self::TableXInfo(table)
1328    }
1329
1330    /// Convenience constructor for encoding pragma
1331    #[must_use]
1332    pub const fn encoding(encoding: Encoding) -> Self {
1333        Self::Encoding(encoding)
1334    }
1335}
1336
1337#[cfg(test)]
1338mod tests {
1339    use super::*;
1340
1341    #[test]
1342    fn test_query_pragma_helper() {
1343        // Test the static query helper function - not covered in doc tests
1344        assert_eq!(Pragma::query("foreign_keys").sql(), "PRAGMA foreign_keys");
1345        assert_eq!(Pragma::query("custom_pragma").sql(), "PRAGMA custom_pragma");
1346    }
1347
1348    #[test]
1349    fn test_convenience_constructor_integration() {
1350        // Test that convenience constructors work the same as direct construction
1351        assert_eq!(
1352            Pragma::foreign_keys(true).to_sql().sql(),
1353            Pragma::ForeignKeys(true).to_sql().sql()
1354        );
1355        assert_eq!(
1356            Pragma::table_info("users").to_sql().sql(),
1357            Pragma::TableInfo("users").to_sql().sql()
1358        );
1359        assert_eq!(
1360            Pragma::encoding(Encoding::Utf8).to_sql().sql(),
1361            Pragma::Encoding(Encoding::Utf8).to_sql().sql()
1362        );
1363    }
1364}