@@ -2,6 +2,7 @@ import 'dart:async';
2
2
3
3
import 'package:logging/logging.dart' ;
4
4
import 'package:meta/meta.dart' ;
5
+ import 'package:neon_framework/models.dart' ;
5
6
import 'package:neon_framework/src/platform/platform.dart' ;
6
7
import 'package:neon_framework/src/utils/request_manager.dart' ;
7
8
import 'package:path/path.dart' as p;
@@ -17,18 +18,18 @@ abstract interface class RequestCache {
17
18
///
18
19
/// Use [getParameters] if you only need to check whether the cache is still
19
20
/// valid.
20
- Future <String ?> get (String key);
21
+ Future <String ?> get (Account account, String key);
21
22
22
23
/// Set's the cached [value] at the given [key] .
23
24
///
24
25
/// If a value is already present it will be updated with the new one.
25
- Future <void > set (String key, String value, CacheParameters ? parameters);
26
+ Future <void > set (Account account, String key, String value, CacheParameters ? parameters);
26
27
27
28
/// Retrieves the cache parameters for the given [key] .
28
- Future <CacheParameters > getParameters (String key);
29
+ Future <CacheParameters > getParameters (Account account, String key);
29
30
30
31
/// Updates the cache [parameters] for a given [key] without modifying the `value` .
31
- Future <void > updateParameters (String key, CacheParameters ? parameters);
32
+ Future <void > updateParameters (Account account, String key, CacheParameters ? parameters);
32
33
}
33
34
34
35
/// Default implementation of the [RequestCache] .
@@ -64,30 +65,32 @@ final class DefaultRequestCache implements RequestCache {
64
65
final cacheDir = await getApplicationCacheDirectory ();
65
66
database = await openDatabase (
66
67
p.join (cacheDir.path, 'cache.db' ),
67
- version: 2 ,
68
+ version: 3 ,
68
69
onCreate: onCreate,
69
70
onUpgrade: (db, oldVersion, newVersion) async {
70
- final batch = db.batch ();
71
- if (oldVersion == 1 ) {
72
- batch
73
- ..execute ('ALTER TABLE cache ADD COLUMN etag TEXT' )
74
- ..execute ('ALTER TABLE cache ADD COLUMN expires INTEGER' );
75
- }
76
- await batch.commit ();
71
+ // We can safely drop the table as it only contains cached data.
72
+ // Non breaking migrations should not drop the cache. The next
73
+ // breaking change should remove all non breaking migrations before it.
74
+ await db.transaction ((txn) async {
75
+ if (oldVersion <= 2 ) {
76
+ await txn.execute ('DROP TABLE cache' );
77
+ await onCreate (txn);
78
+ }
79
+ });
77
80
},
78
81
);
79
82
}
80
83
81
84
@visibleForTesting
82
- static Future <void > onCreate (Database db, int version) async {
85
+ static Future <void > onCreate (DatabaseExecutor db, [ int ? version] ) async {
83
86
await db.execute ('''
84
87
CREATE TABLE "cache" (
85
- "id" INTEGER UNIQUE ,
86
- "key" TEXT UNIQUE ,
87
- "value" TEXT,
88
+ "account" TEXT NOT NULL ,
89
+ "key" TEXT NOT NULL ,
90
+ "value" TEXT NOT NULL ,
88
91
"etag" TEXT,
89
92
"expires" INTEGER,
90
- PRIMARY KEY("id ")
93
+ PRIMARY KEY("key", "account ")
91
94
);
92
95
''' );
93
96
}
@@ -104,10 +107,17 @@ CREATE TABLE "cache" (
104
107
}
105
108
106
109
@override
107
- Future <String ?> get (String key) async {
110
+ Future <String ?> get (Account account, String key) async {
108
111
List <Map <String , Object ?>>? result;
109
112
try {
110
- result = await _requireDatabase.rawQuery ('SELECT value FROM cache WHERE key = ?' , [key]);
113
+ result = await _requireDatabase.rawQuery (
114
+ '''
115
+ SELECT value
116
+ FROM cache
117
+ WHERE account = ? AND key = ?
118
+ ''' ,
119
+ [account.id, key],
120
+ );
111
121
} on DatabaseException catch (error, stackTrace) {
112
122
_log.severe (
113
123
'Error while getting `$key ` from cache.' ,
@@ -120,25 +130,36 @@ CREATE TABLE "cache" (
120
130
}
121
131
122
132
@override
123
- Future <void > set (String key, String value, CacheParameters ? parameters) async {
133
+ Future <void > set (Account account, String key, String value, CacheParameters ? parameters) async {
124
134
try {
125
135
// UPSERT is only available since SQLite 3.24.0 (June 4, 2018).
126
136
// Using a manual solution from https://stackoverflow.com/a/38463024
127
137
final batch = _requireDatabase.batch ()
128
138
..update (
129
139
'cache' ,
130
140
{
141
+ 'account' : account.id,
131
142
'key' : key,
132
143
'value' : value,
133
144
'etag' : parameters? .etag,
134
145
'expires' : parameters? .expires? .millisecondsSinceEpoch,
135
146
},
136
- where: 'key = ?' ,
137
- whereArgs: [key],
147
+ where: 'account = ? AND key = ?' ,
148
+ whereArgs: [account.id, key],
138
149
)
139
150
..rawInsert (
140
- 'INSERT INTO cache (key, value, etag, expires) SELECT ?, ?, ?, ? WHERE (SELECT changes() = 0)' ,
141
- [key, value, parameters? .etag, parameters? .expires? .millisecondsSinceEpoch],
151
+ '''
152
+ INSERT INTO cache (account, key, value, etag, expires)
153
+ SELECT ?, ?, ?, ?, ?
154
+ WHERE (SELECT changes() = 0)
155
+ ''' ,
156
+ [
157
+ account.id,
158
+ key,
159
+ value,
160
+ parameters? .etag,
161
+ parameters? .expires? .millisecondsSinceEpoch,
162
+ ],
142
163
);
143
164
await batch.commit (noResult: true );
144
165
} on DatabaseException catch (error, stackTrace) {
@@ -151,10 +172,17 @@ CREATE TABLE "cache" (
151
172
}
152
173
153
174
@override
154
- Future <CacheParameters > getParameters (String key) async {
175
+ Future <CacheParameters > getParameters (Account account, String key) async {
155
176
List <Map <String , Object ?>>? result;
156
177
try {
157
- result = await _requireDatabase.rawQuery ('SELECT etag, expires FROM cache WHERE key = ?' , [key]);
178
+ result = await _requireDatabase.rawQuery (
179
+ '''
180
+ SELECT etag, expires
181
+ FROM cache
182
+ WHERE account = ? AND key = ?
183
+ ''' ,
184
+ [account.id, key],
185
+ );
158
186
} on DatabaseException catch (error, stackTrace) {
159
187
_log.severe (
160
188
'Error getting the cache parameters for `$key ` from cache.' ,
@@ -178,16 +206,17 @@ CREATE TABLE "cache" (
178
206
}
179
207
180
208
@override
181
- Future <void > updateParameters (String key, CacheParameters ? parameters) async {
209
+ Future <void > updateParameters (Account account, String key, CacheParameters ? parameters) async {
182
210
try {
183
211
await _requireDatabase.update (
184
212
'cache' ,
185
213
{
214
+ 'account' : account.id,
186
215
'etag' : parameters? .etag,
187
216
'expires' : parameters? .expires? .millisecondsSinceEpoch,
188
217
},
189
- where: 'key = ?' ,
190
- whereArgs: [key],
218
+ where: 'account = ? AND key = ?' ,
219
+ whereArgs: [account.id, key],
191
220
);
192
221
} on DatabaseException catch (error, stackTrace) {
193
222
_log.severe (
0 commit comments