slonik-interceptor-query-cache 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -8
- package/dist/src/factories/createQueryCacheInterceptor.d.ts +1 -0
- package/dist/src/factories/createQueryCacheInterceptor.js +9 -0
- package/dist/src/utilities/extractCacheAttributes.d.ts +1 -0
- package/dist/src/utilities/extractCacheAttributes.js +9 -3
- package/package.json +1 -1
- package/src/factories/createQueryCacheInterceptor.ts +13 -0
- package/src/utilities/extractCacheAttributes.ts +10 -3
package/README.md
CHANGED
|
@@ -14,11 +14,17 @@ Query cache interceptor is initialised using a custom storage service. The [Exam
|
|
|
14
14
|
|
|
15
15
|
Which queries are cached is controlled using cache attributes. Cache attributes are comments starting with `-- @cache-` prefix. Only queries with cache attributes are cached (see [Cache attributes](#cache-attributes))
|
|
16
16
|
|
|
17
|
+
## Behavior
|
|
18
|
+
|
|
19
|
+
* Does not cache queries inside of a transaction.
|
|
20
|
+
* Does not take into account the query parameters.
|
|
21
|
+
|
|
17
22
|
## Cache attributes
|
|
18
23
|
|
|
19
24
|
|Cache attribute|Description|Required?|Default|
|
|
20
25
|
|---|---|---|---|
|
|
21
26
|
|`@cache-ttl`|Number (in seconds) to cache the query for.|Yes|N/A|
|
|
27
|
+
|`@cache-key`|Key (`/^[A-Za-z0-9\-_:]+$/`) that uniquely identifies the query.|Yes|N/A|
|
|
22
28
|
|
|
23
29
|
### Example usage
|
|
24
30
|
|
|
@@ -39,19 +45,16 @@ const nodeCache = new NodeCache({
|
|
|
39
45
|
useClones: false,
|
|
40
46
|
});
|
|
41
47
|
|
|
42
|
-
const hashQuery = (query: QueryType): string => {
|
|
43
|
-
return JSON.stringify(query);
|
|
44
|
-
};
|
|
45
|
-
|
|
46
48
|
const pool = await createPool('postgres://', {
|
|
47
49
|
interceptors: [
|
|
48
50
|
createQueryCacheInterceptor({
|
|
49
51
|
storage: {
|
|
50
|
-
get: (query) => {
|
|
51
|
-
|
|
52
|
+
get: (query, cacheAttributes) => {
|
|
53
|
+
// Returning null results in the query being executed.
|
|
54
|
+
return cache.get(cacheAttributes.key) || null;
|
|
52
55
|
},
|
|
53
56
|
set: (query, cacheAttributes, queryResult) => {
|
|
54
|
-
cache.set(
|
|
57
|
+
cache.set(cacheAttributes.key, queryResult, cacheAttributes.ttl);
|
|
55
58
|
},
|
|
56
59
|
},
|
|
57
60
|
}),
|
|
@@ -60,6 +63,7 @@ const pool = await createPool('postgres://', {
|
|
|
60
63
|
|
|
61
64
|
await connection.any(sql`
|
|
62
65
|
-- @cache-ttl 60
|
|
66
|
+
-- @cache-key foo
|
|
63
67
|
SELECT
|
|
64
68
|
id,
|
|
65
69
|
code_alpha_2
|
|
@@ -67,4 +71,4 @@ await connection.any(sql`
|
|
|
67
71
|
WHERE
|
|
68
72
|
code_alpha_2 = ${countryCode}
|
|
69
73
|
`);
|
|
70
|
-
```
|
|
74
|
+
```
|
|
@@ -13,6 +13,9 @@ const createQueryCacheInterceptor = (configurationInput) => {
|
|
|
13
13
|
return {
|
|
14
14
|
beforeQueryExecution: async (context, query) => {
|
|
15
15
|
var _a;
|
|
16
|
+
if (context.transactionId) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
16
19
|
const cacheAttributes = (_a = context.sandbox.cache) === null || _a === void 0 ? void 0 : _a.cacheAttributes;
|
|
17
20
|
if (!cacheAttributes) {
|
|
18
21
|
return null;
|
|
@@ -28,6 +31,9 @@ const createQueryCacheInterceptor = (configurationInput) => {
|
|
|
28
31
|
},
|
|
29
32
|
beforeQueryResult: async (context, query, result) => {
|
|
30
33
|
var _a;
|
|
34
|
+
if (context.transactionId) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
31
37
|
const cacheAttributes = (_a = context.sandbox.cache) === null || _a === void 0 ? void 0 : _a.cacheAttributes;
|
|
32
38
|
if (cacheAttributes) {
|
|
33
39
|
await configuration.storage.set(query, cacheAttributes, result);
|
|
@@ -35,6 +41,9 @@ const createQueryCacheInterceptor = (configurationInput) => {
|
|
|
35
41
|
return null;
|
|
36
42
|
},
|
|
37
43
|
beforeTransformQuery: async (context, query) => {
|
|
44
|
+
if (context.transactionId) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
38
47
|
const cacheAttributes = (0, utilities_1.extractCacheAttributes)(query.sql);
|
|
39
48
|
if (!cacheAttributes) {
|
|
40
49
|
return null;
|
|
@@ -2,10 +2,16 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.extractCacheAttributes = void 0;
|
|
4
4
|
const extractCacheAttributes = (subject) => {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
var _a, _b;
|
|
6
|
+
const ttl = (_a = /-- @cache-ttl (\d+)/u.exec(subject)) === null || _a === void 0 ? void 0 : _a[1];
|
|
7
|
+
if (ttl) {
|
|
8
|
+
const key = (_b = /-- @cache-key ([a-zA-Z0-9\-_:/]+)/ui.exec(subject)) === null || _b === void 0 ? void 0 : _b[1];
|
|
9
|
+
if (!key) {
|
|
10
|
+
throw new Error('@cache-key must be specified when @cache-ttl is specified.');
|
|
11
|
+
}
|
|
7
12
|
return {
|
|
8
|
-
|
|
13
|
+
key,
|
|
14
|
+
ttl: Number(ttl),
|
|
9
15
|
};
|
|
10
16
|
}
|
|
11
17
|
return null;
|
package/package.json
CHANGED
|
@@ -22,6 +22,7 @@ type Sandbox = {
|
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
type CacheAttributes = {
|
|
25
|
+
key: string,
|
|
25
26
|
ttl: number,
|
|
26
27
|
};
|
|
27
28
|
|
|
@@ -45,6 +46,10 @@ export const createQueryCacheInterceptor = (configurationInput: ConfigurationInp
|
|
|
45
46
|
|
|
46
47
|
return {
|
|
47
48
|
beforeQueryExecution: async (context, query) => {
|
|
49
|
+
if (context.transactionId) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
|
|
48
53
|
const cacheAttributes = (context.sandbox as Sandbox).cache?.cacheAttributes;
|
|
49
54
|
|
|
50
55
|
if (!cacheAttributes) {
|
|
@@ -64,6 +69,10 @@ export const createQueryCacheInterceptor = (configurationInput: ConfigurationInp
|
|
|
64
69
|
return null;
|
|
65
70
|
},
|
|
66
71
|
beforeQueryResult: async (context, query, result) => {
|
|
72
|
+
if (context.transactionId) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
|
|
67
76
|
const cacheAttributes = (context.sandbox as Sandbox).cache?.cacheAttributes;
|
|
68
77
|
|
|
69
78
|
if (cacheAttributes) {
|
|
@@ -73,6 +82,10 @@ export const createQueryCacheInterceptor = (configurationInput: ConfigurationInp
|
|
|
73
82
|
return null;
|
|
74
83
|
},
|
|
75
84
|
beforeTransformQuery: async (context, query) => {
|
|
85
|
+
if (context.transactionId) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
|
|
76
89
|
const cacheAttributes = extractCacheAttributes(query.sql);
|
|
77
90
|
|
|
78
91
|
if (!cacheAttributes) {
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
export const extractCacheAttributes = (subject: string) => {
|
|
2
|
-
const
|
|
2
|
+
const ttl = /-- @cache-ttl (\d+)/u.exec(subject)?.[1];
|
|
3
|
+
|
|
4
|
+
if (ttl) {
|
|
5
|
+
const key = /-- @cache-key ([a-zA-Z0-9\-_:/]+)/ui.exec(subject)?.[1];
|
|
6
|
+
|
|
7
|
+
if (!key) {
|
|
8
|
+
throw new Error('@cache-key must be specified when @cache-ttl is specified.');
|
|
9
|
+
}
|
|
3
10
|
|
|
4
|
-
if (matches) {
|
|
5
11
|
return {
|
|
6
|
-
|
|
12
|
+
key,
|
|
13
|
+
ttl: Number(ttl),
|
|
7
14
|
};
|
|
8
15
|
}
|
|
9
16
|
|