Skip to main content

drizzle_sqlite/
pragma.rs

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