1
1
use crate :: { adapters:: FileAdapter , preproc:: ActiveAdapters } ;
2
2
use anyhow:: { Context , Result } ;
3
+ use log:: warn;
3
4
use path_clean:: PathClean ;
4
5
use rusqlite:: { named_params, OptionalExtension } ;
5
6
use std:: { path:: Path , time:: UNIX_EPOCH } ;
6
7
use tokio_rusqlite:: Connection ;
7
8
9
+ static SCHEMA_VERSION : i32 = 3 ;
8
10
#[ derive( Clone ) ]
9
11
pub struct CacheKey {
12
+ config_hash : String ,
10
13
adapter : String ,
11
14
adapter_version : i32 ,
12
15
active_adapters : String ,
@@ -15,6 +18,7 @@ pub struct CacheKey {
15
18
}
16
19
impl CacheKey {
17
20
pub fn new (
21
+ postprocess : bool ,
18
22
filepath_hint : & Path ,
19
23
adapter : & dyn FileAdapter ,
20
24
active_adapters : & ActiveAdapters ,
@@ -34,6 +38,11 @@ impl CacheKey {
34
38
"null" . to_string ( )
35
39
} ;
36
40
Ok ( CacheKey {
41
+ config_hash : if postprocess {
42
+ "a41e2e9" . to_string ( )
43
+ } else {
44
+ "f1502a3" . to_string ( )
45
+ } , // todo: when we add more config options that affect caching, create a struct and actually hash it
37
46
adapter : adapter. metadata ( ) . name . clone ( ) ,
38
47
adapter_version : adapter. metadata ( ) . version ,
39
48
file_path : filepath_hint. clean ( ) . to_string_lossy ( ) . to_string ( ) ,
@@ -63,6 +72,7 @@ async fn connect_pragmas(db: &Connection) -> Result<()> {
63
72
db. pragma_update ( None , "mmap_size" , "2000000000" ) ?;
64
73
db. execute ( "
65
74
create table if not exists preproc_cache (
75
+ config_hash text not null,
66
76
adapter text not null,
67
77
adapter_version integer not null,
68
78
created_unix_ms integer not null default (unixepoch() * 1000),
@@ -73,7 +83,7 @@ async fn connect_pragmas(db: &Connection) -> Result<()> {
73
83
) strict" , [ ]
74
84
) ?;
75
85
76
- db. execute ( "create unique index if not exists preproc_cache_idx on preproc_cache (adapter, adapter_version, file_path, active_adapters)" , [ ] ) ?;
86
+ db. execute ( "create unique index if not exists preproc_cache_idx on preproc_cache (config_hash, adapter, adapter_version, file_path, active_adapters)" , [ ] ) ?;
77
87
78
88
Ok ( ( ) )
79
89
} )
@@ -83,26 +93,29 @@ async fn connect_pragmas(db: &Connection) -> Result<()> {
83
93
. await ?;
84
94
if jm != 924716026 {
85
95
// (probably) newly created db
86
- create_pragmas ( db) . await . context ( "create_pragmas" ) ?;
96
+ db. call ( |db| Ok ( db. pragma_update ( None , "application_id" , "924716026" ) ?) )
97
+ . await ?;
87
98
}
88
99
Ok ( ( ) )
89
100
}
90
101
91
- async fn create_pragmas ( db : & Connection ) -> Result < ( ) > {
92
- db. call ( |db| {
93
- db. pragma_update ( None , "application_id" , "924716026" ) ?;
94
- db. pragma_update ( None , "user_version" , "2" ) ?; // todo: on upgrade clear db if version is unexpected
95
- Ok ( ( ) )
96
- } )
97
- . await ?;
98
- Ok ( ( ) )
99
- }
100
102
struct SqliteCache {
101
103
db : Connection ,
102
104
}
103
105
impl SqliteCache {
104
106
async fn new ( path : & Path ) -> Result < SqliteCache > {
105
107
let db = Connection :: open ( path. join ( "cache.sqlite3" ) ) . await ?;
108
+ db. call ( |db| {
109
+ let schema_version: i32 = db. pragma_query_value ( None , "user_version" , |r| r. get ( 0 ) ) ?;
110
+ if schema_version != SCHEMA_VERSION {
111
+ warn ! ( "Cache schema version mismatch, clearing cache" ) ;
112
+ db. execute ( "drop table if exists preproc_cache" , [ ] ) ?;
113
+ db. pragma_update ( None , "user_version" , format ! ( "{SCHEMA_VERSION}" ) ) ?;
114
+ }
115
+ Ok ( ( ) )
116
+ } )
117
+ . await ?;
118
+
106
119
connect_pragmas ( & db) . await ?;
107
120
108
121
Ok ( SqliteCache { db } )
@@ -120,12 +133,14 @@ impl PreprocCache for SqliteCache {
120
133
. query_row (
121
134
"select text_content_zstd from preproc_cache where
122
135
adapter = :adapter
136
+ and config_hash = :config_hash
123
137
and adapter_version = :adapter_version
124
138
and active_adapters = :active_adapters
125
139
and file_path = :file_path
126
140
and file_mtime_unix_ms = :file_mtime_unix_ms
127
141
" ,
128
142
named_params ! {
143
+ ":config_hash" : & key. config_hash,
129
144
":adapter" : & key. adapter,
130
145
":adapter_version" : & key. adapter_version,
131
146
":active_adapters" : & key. active_adapters,
@@ -152,13 +167,14 @@ impl PreprocCache for SqliteCache {
152
167
. db
153
168
. call ( move |db| {
154
169
db. execute (
155
- "insert into preproc_cache (adapter, adapter_version, active_adapters, file_path, file_mtime_unix_ms, text_content_zstd) values
156
- (:adapter, :adapter_version, :active_adapters, :file_path, :file_mtime_unix_ms, :text_content_zstd)
157
- on conflict (adapter, adapter_version, active_adapters, file_path) do update set
170
+ "insert into preproc_cache (config_hash, adapter, adapter_version, active_adapters, file_path, file_mtime_unix_ms, text_content_zstd) values
171
+ (:config_hash, : adapter, :adapter_version, :active_adapters, :file_path, :file_mtime_unix_ms, :text_content_zstd)
172
+ on conflict (config_hash, adapter, adapter_version, active_adapters, file_path) do update set
158
173
file_mtime_unix_ms = :file_mtime_unix_ms,
159
174
created_unix_ms = unixepoch() * 1000,
160
175
text_content_zstd = :text_content_zstd" ,
161
176
named_params ! {
177
+ ":config_hash" : & key. config_hash,
162
178
":adapter" : & key. adapter,
163
179
":adapter_version" : & key. adapter_version,
164
180
":active_adapters" : & key. active_adapters,
0 commit comments