cds-caching 1.3.1 → 1.3.2
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 +16 -0
- package/app/dashboard/controller/App-dbg.controller.js +14 -14
- package/app/dashboard/controller/App-dbg.controller.js.map +1 -1
- package/app/dashboard/controller/App.controller.js +1 -1
- package/app/dashboard/controller/App.controller.js.map +1 -1
- package/app/dashboard/controller/App.controller.ts +14 -14
- package/app/dashboard/controller/BaseController-dbg.js +7 -0
- package/app/dashboard/controller/BaseController-dbg.js.map +1 -1
- package/app/dashboard/controller/BaseController.js +1 -1
- package/app/dashboard/controller/BaseController.js.map +1 -1
- package/app/dashboard/controller/BaseController.ts +10 -0
- package/app/dashboard/controller/Cache-dbg.controller.js +34 -25
- package/app/dashboard/controller/Cache-dbg.controller.js.map +1 -1
- package/app/dashboard/controller/Cache.controller.js +1 -1
- package/app/dashboard/controller/Cache.controller.js.map +1 -1
- package/app/dashboard/controller/Cache.controller.ts +36 -25
- package/app/dashboard/controller/SingleMetric-dbg.controller.js +56 -50
- package/app/dashboard/controller/SingleMetric-dbg.controller.js.map +1 -1
- package/app/dashboard/controller/SingleMetric.controller.js +1 -1
- package/app/dashboard/controller/SingleMetric.controller.js.map +1 -1
- package/app/dashboard/controller/SingleMetric.controller.ts +29 -22
- package/app/dashboard/i18n/i18n.properties +235 -0
- package/app/dashboard/i18n/i18n_de.properties +271 -3
- package/app/dashboard/i18n/i18n_en.properties +295 -2
- package/app/dashboard/resources/sap-ui-custom.js +11 -11
- package/app/dashboard/resources/sap-ui-custom.js.map +1 -1
- package/app/dashboard/view/Cache.view.xml +149 -149
- package/app/dashboard/view/Main.view.xml +7 -7
- package/app/dashboard/view/SingleMetric.view.xml +30 -30
- package/cds-plugin.js +31 -8
- package/lib/util.js +28 -2
- package/package.json +1 -1
|
@@ -13,30 +13,30 @@
|
|
|
13
13
|
formatter: 'cds/plugin/caching/dashboard/model/formatter'
|
|
14
14
|
}">
|
|
15
15
|
|
|
16
|
-
<f:DynamicPage title="
|
|
16
|
+
<f:DynamicPage title="{i18n>homePageTitle}" headerExpanded="true" headerPinned="true">
|
|
17
17
|
<f:title>
|
|
18
18
|
<f:DynamicPageTitle>
|
|
19
19
|
<f:heading>
|
|
20
|
-
<Title text="
|
|
20
|
+
<Title text="{i18n>homePageTitle}" />
|
|
21
21
|
</f:heading>
|
|
22
22
|
<f:actions>
|
|
23
|
-
<Button type="Transparent" icon="sap-icon://refresh" text="
|
|
23
|
+
<Button type="Transparent" icon="sap-icon://refresh" text="{i18n>refreshButton}" press="onRefresh" />
|
|
24
24
|
</f:actions>
|
|
25
25
|
</f:DynamicPageTitle>
|
|
26
26
|
</f:title>
|
|
27
27
|
|
|
28
28
|
<f:content>
|
|
29
29
|
|
|
30
|
-
<Table id="cachesList" headerText="
|
|
30
|
+
<Table id="cachesList" headerText="{i18n>cachingServicesHeader}" mode="SingleSelectMaster" items="{path: '/Caches'}" itemPress="onCacheSelect" noDataText="{i18n>noCachesAvailable}">
|
|
31
31
|
<columns>
|
|
32
32
|
<Column>
|
|
33
|
-
<Text text="
|
|
33
|
+
<Text text="{i18n>colName}" />
|
|
34
34
|
</Column>
|
|
35
35
|
<Column>
|
|
36
|
-
<Text text="
|
|
36
|
+
<Text text="{i18n>colStatisticTrackingEnabled}" />
|
|
37
37
|
</Column>
|
|
38
38
|
<Column>
|
|
39
|
-
<Text text="
|
|
39
|
+
<Text text="{i18n>colKeyTrackingEnabled}" />
|
|
40
40
|
</Column>
|
|
41
41
|
</columns>
|
|
42
42
|
<items>
|
|
@@ -14,19 +14,19 @@
|
|
|
14
14
|
formatter: 'cds/plugin/caching/dashboard/model/formatter'
|
|
15
15
|
}">
|
|
16
16
|
|
|
17
|
-
<f:DynamicPage title="
|
|
17
|
+
<f:DynamicPage title="{i18n>metricDetailsPageTitle}" showFooter="false">
|
|
18
18
|
<f:title>
|
|
19
19
|
<f:DynamicPageTitle>
|
|
20
20
|
<f:heading>
|
|
21
|
-
<Title text="
|
|
21
|
+
<Title text="{= ${i18n>metricPagePrefix} + ' ' + ${ui>/metricId} }" />
|
|
22
22
|
</f:heading>
|
|
23
23
|
<f:actions>
|
|
24
|
-
<Button icon="sap-icon://refresh" text="
|
|
24
|
+
<Button icon="sap-icon://refresh" text="{i18n>refreshButton}" type="Transparent" press="onRefresh" />
|
|
25
25
|
</f:actions>
|
|
26
26
|
<f:navigationActions>
|
|
27
|
-
<OverflowToolbarButton type="Transparent" icon="sap-icon://full-screen" press="handleFullScreen" tooltip="
|
|
28
|
-
<OverflowToolbarButton type="Transparent" icon="sap-icon://exit-full-screen" press="handleExitFullScreen" tooltip="
|
|
29
|
-
<OverflowToolbarButton type="Transparent" icon="sap-icon://decline" press="handleClose" tooltip="
|
|
27
|
+
<OverflowToolbarButton type="Transparent" icon="sap-icon://full-screen" press="handleFullScreen" tooltip="{i18n>ttFullScreenEnter}" visible="{= ${app>/layout} !== 'EndColumnFullScreen' }"/>
|
|
28
|
+
<OverflowToolbarButton type="Transparent" icon="sap-icon://exit-full-screen" press="handleExitFullScreen" tooltip="{i18n>ttFullScreenExit}" visible="{= ${app>/layout} === 'EndColumnFullScreen' }"/>
|
|
29
|
+
<OverflowToolbarButton type="Transparent" icon="sap-icon://decline" press="handleClose" tooltip="{i18n>ttCloseEndColumn}"/>
|
|
30
30
|
</f:navigationActions>
|
|
31
31
|
</f:DynamicPageTitle>
|
|
32
32
|
</f:title>
|
|
@@ -43,10 +43,10 @@
|
|
|
43
43
|
<cssgrid:ResponsiveColumnItemLayoutData columns="24"/>
|
|
44
44
|
</layoutData>
|
|
45
45
|
|
|
46
|
-
<Title text="
|
|
46
|
+
<Title text="{i18n>sectionReadThroughPerformance}" titleStyle="H5" class="sapUiMediumMarginTop sapUiTinyMarginBottom" />
|
|
47
47
|
|
|
48
48
|
<f:GridContainer id="metricCacheThroughGrid" columnsChange=".onColumnsChange">
|
|
49
|
-
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="
|
|
49
|
+
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="{i18n>hitRatio}" subheader="{i18n>tileSubCacheHitRate}">
|
|
50
50
|
<TileContent unit="%">
|
|
51
51
|
<NumericContent valueColor="{formatter: 'formatter.formatHitRatioWithColor', path: 'ui>/hitRatio'}" value="{ path: 'ui>/hitRatio', type: 'sap.ui.model.type.Float', formatOptions: {style: 'short', decimals: 2}}" />
|
|
52
52
|
</TileContent>
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
</layoutData>
|
|
56
56
|
</GenericTile>
|
|
57
57
|
|
|
58
|
-
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="
|
|
58
|
+
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="{i18n>headerCacheEfficiency}" subheader="{i18n>tileSubPerformanceFactor}">
|
|
59
59
|
<TileContent unit="x">
|
|
60
60
|
<NumericContent valueColor="{formatter: 'formatter.formatCacheEfficiencyWithColor', path: 'ui>/cacheEfficiency'}" value="{path: 'ui>/cacheEfficiency', type: 'sap.ui.model.type.Float', formatOptions: {style: 'short', decimals: 2}}" />
|
|
61
61
|
</TileContent>
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
</layoutData>
|
|
65
65
|
</GenericTile>
|
|
66
66
|
|
|
67
|
-
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="
|
|
67
|
+
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="{i18n>throughput}" subheader="{i18n>tileSubReqPerSec}">
|
|
68
68
|
<TileContent unit="req/s">
|
|
69
69
|
<NumericContent value="{ path: 'ui>/throughput', type: 'sap.ui.model.type.Float', formatOptions: {style: 'short', decimals: 2}}" withMargin="false" />
|
|
70
70
|
</TileContent>
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
</layoutData>
|
|
74
74
|
</GenericTile>
|
|
75
75
|
|
|
76
|
-
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="
|
|
76
|
+
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="{i18n>headerErrorRate}" subheader="{i18n>tileSubCacheErrors}">
|
|
77
77
|
<TileContent unit="%">
|
|
78
78
|
<NumericContent valueColor="{formatter: 'formatter.formatErrorRateWithColor', path: 'ui>/errorRate'}" value="{ path: 'ui>/errorRate', formatter: 'formatter.formatPercentageValue' }" />
|
|
79
79
|
</TileContent>
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
</layoutData>
|
|
83
83
|
</GenericTile>
|
|
84
84
|
|
|
85
|
-
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="
|
|
85
|
+
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="{i18n>totalRequests}" subheader="{i18n>tileSubCacheOperations}">
|
|
86
86
|
<TileContent unit="req">
|
|
87
87
|
<NumericContent value="{= ${ui>/hits} + ${ui>/misses}}" withMargin="false" />
|
|
88
88
|
</TileContent>
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
</layoutData>
|
|
92
92
|
</GenericTile>
|
|
93
93
|
|
|
94
|
-
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="
|
|
94
|
+
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="{i18n>headerCacheHits}" subheader="{i18n>tileSubSuccessfulRetrievals}">
|
|
95
95
|
<TileContent unit="hits">
|
|
96
96
|
<NumericContent value="{ui>/hits}" withMargin="false" />
|
|
97
97
|
</TileContent>
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
</layoutData>
|
|
101
101
|
</GenericTile>
|
|
102
102
|
|
|
103
|
-
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="
|
|
103
|
+
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="{i18n>headerCacheMisses}" subheader="{i18n>tileSubFailedRetrievals}">
|
|
104
104
|
<TileContent unit="misses">
|
|
105
105
|
<NumericContent value="{ui>/misses}" withMargin="false" />
|
|
106
106
|
</TileContent>
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
</GenericTile>
|
|
111
111
|
|
|
112
112
|
|
|
113
|
-
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="
|
|
113
|
+
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="{i18n>headerCacheErrors}" subheader="{i18n>tileSubErrorCount}">
|
|
114
114
|
<TileContent unit="errors">
|
|
115
115
|
<NumericContent value="{ui>/errors}" withMargin="false" />
|
|
116
116
|
</TileContent>
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
</GenericTile>
|
|
121
121
|
|
|
122
122
|
|
|
123
|
-
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="
|
|
123
|
+
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="{i18n>headerHitLatency}" subheader="{i18n>tileSubCacheHitResponse}">
|
|
124
124
|
<TileContent unit="ms">
|
|
125
125
|
<NumericContent valueColor="{formatter: 'formatter.formatLatencyWithColor', path: 'ui>/avgHitLatency'}" value="{ path: 'ui>/avgHitLatency', type: 'sap.ui.model.type.Float', formatOptions: {style: 'short', decimals: 2}}" />
|
|
126
126
|
</TileContent>
|
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
</layoutData>
|
|
130
130
|
</GenericTile>
|
|
131
131
|
|
|
132
|
-
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="
|
|
132
|
+
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="{i18n>headerMissLatency}" subheader="{i18n>tileSubCacheMissResponse}">
|
|
133
133
|
<TileContent unit="ms">
|
|
134
134
|
<NumericContent valueColor="{formatter: 'formatter.formatLatencyWithColor', path: 'ui>/avgMissLatency'}" value="{ path: 'ui>/avgMissLatency', type: 'sap.ui.model.type.Float', formatOptions: {style: 'short', decimals: 2}}" />
|
|
135
135
|
</TileContent>
|
|
@@ -141,7 +141,7 @@
|
|
|
141
141
|
<!-- Read-Through Distribution Chart -->
|
|
142
142
|
<f:Card class="sapUiTinyMargin">
|
|
143
143
|
<f:header>
|
|
144
|
-
<card:Header title="
|
|
144
|
+
<card:Header title="{i18n>cardReadThroughOps}" subtitle="{i18n>cardReadThroughOpsSub}" />
|
|
145
145
|
</f:header>
|
|
146
146
|
<f:content>
|
|
147
147
|
<l:VerticalLayout width="100%">
|
|
@@ -175,7 +175,7 @@
|
|
|
175
175
|
<!-- Latency Chart -->
|
|
176
176
|
<f:Card class="sapUiTinyMargin">
|
|
177
177
|
<f:header>
|
|
178
|
-
<card:Header title="
|
|
178
|
+
<card:Header title="{i18n>cardLatencyCompare}" subtitle="{i18n>cardLatencyCompareSub}" />
|
|
179
179
|
</f:header>
|
|
180
180
|
<f:content>
|
|
181
181
|
<l:VerticalLayout width="100%">
|
|
@@ -214,10 +214,10 @@
|
|
|
214
214
|
<cssgrid:ResponsiveColumnItemLayoutData columns="24"/>
|
|
215
215
|
</layoutData>
|
|
216
216
|
|
|
217
|
-
<Title text="
|
|
217
|
+
<Title text="{i18n>sectionNativeFunctionPerformance}" titleStyle="H5" class="sapUiMediumMarginTop sapUiTinyMarginBottom" />
|
|
218
218
|
|
|
219
219
|
<f:GridContainer id="metricNativeGrid" columnsChange=".onColumnsChange">
|
|
220
|
-
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="
|
|
220
|
+
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="{i18n>headerNativeThroughput}" subheader="{i18n>tileSubNativeOpsPerSec}">
|
|
221
221
|
<TileContent unit="ops/s">
|
|
222
222
|
<NumericContent value="{ path: 'ui>/nativeThroughput', formatter: 'formatter.formatNumberValue' }" withMargin="false" />
|
|
223
223
|
</TileContent>
|
|
@@ -226,7 +226,7 @@
|
|
|
226
226
|
</layoutData>
|
|
227
227
|
</GenericTile>
|
|
228
228
|
|
|
229
|
-
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="
|
|
229
|
+
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="{i18n>headerNativeErrorRate}" subheader="{i18n>tileSubCacheErrors}">
|
|
230
230
|
<TileContent unit="%">
|
|
231
231
|
<NumericContent valueColor="{formatter: 'formatter.formatErrorRateWithColor', path: 'ui>/nativeErrorRate'}" value="{ path: 'ui>/nativeErrorRate', formatter: 'formatter.formatPercentageValue' }" />
|
|
232
232
|
</TileContent>
|
|
@@ -235,7 +235,7 @@
|
|
|
235
235
|
</layoutData>
|
|
236
236
|
</GenericTile>
|
|
237
237
|
|
|
238
|
-
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="
|
|
238
|
+
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="{i18n>headerNativeSets}" subheader="{i18n>tileSubWriteOps}">
|
|
239
239
|
<TileContent unit="sets">
|
|
240
240
|
<NumericContent value="{ui>/nativeSets}" withMargin="false" />
|
|
241
241
|
</TileContent>
|
|
@@ -244,7 +244,7 @@
|
|
|
244
244
|
</layoutData>
|
|
245
245
|
</GenericTile>
|
|
246
246
|
|
|
247
|
-
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="
|
|
247
|
+
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="{i18n>headerNativeGets}" subheader="{i18n>tileSubReadOps}">
|
|
248
248
|
<TileContent unit="gets">
|
|
249
249
|
<NumericContent value="{ui>/nativeGets}" withMargin="false" />
|
|
250
250
|
</TileContent>
|
|
@@ -253,7 +253,7 @@
|
|
|
253
253
|
</layoutData>
|
|
254
254
|
</GenericTile>
|
|
255
255
|
|
|
256
|
-
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="
|
|
256
|
+
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="{i18n>headerNativeDeletes}" subheader="{i18n>tileSubDeleteOps}">
|
|
257
257
|
<TileContent unit="deletes">
|
|
258
258
|
<NumericContent value="{ui>/nativeDeletes}" withMargin="false" />
|
|
259
259
|
</TileContent>
|
|
@@ -262,7 +262,7 @@
|
|
|
262
262
|
</layoutData>
|
|
263
263
|
</GenericTile>
|
|
264
264
|
|
|
265
|
-
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="
|
|
265
|
+
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="{i18n>headerNativeClears}" subheader="{i18n>tileSubClearOps}">
|
|
266
266
|
<TileContent unit="clears">
|
|
267
267
|
<NumericContent value="{ui>/nativeClears}" withMargin="false" />
|
|
268
268
|
</TileContent>
|
|
@@ -271,7 +271,7 @@
|
|
|
271
271
|
</layoutData>
|
|
272
272
|
</GenericTile>
|
|
273
273
|
|
|
274
|
-
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="
|
|
274
|
+
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="{i18n>headerDeleteByTags}" subheader="{i18n>tileSubTagDeletes}">
|
|
275
275
|
<TileContent unit="deletes">
|
|
276
276
|
<NumericContent value="{ui>/nativeDeleteByTags}" withMargin="false" />
|
|
277
277
|
</TileContent>
|
|
@@ -280,7 +280,7 @@
|
|
|
280
280
|
</layoutData>
|
|
281
281
|
</GenericTile>
|
|
282
282
|
|
|
283
|
-
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="
|
|
283
|
+
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="{i18n>headerNativeErrors}" subheader="{i18n>tileSubErrorCount}">
|
|
284
284
|
<TileContent unit="errors">
|
|
285
285
|
<NumericContent value="{ui>/nativeErrors}" withMargin="false" />
|
|
286
286
|
</TileContent>
|
|
@@ -289,7 +289,7 @@
|
|
|
289
289
|
</layoutData>
|
|
290
290
|
</GenericTile>
|
|
291
291
|
|
|
292
|
-
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="
|
|
292
|
+
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="{i18n>headerTotalNativeOps}" subheader="{i18n>tileSubAllOperations}">
|
|
293
293
|
<TileContent unit="ops">
|
|
294
294
|
<NumericContent value="{ui>/totalNativeOperations}" withMargin="false" />
|
|
295
295
|
</TileContent>
|
|
@@ -300,7 +300,7 @@
|
|
|
300
300
|
<!-- Native Function Distribution Chart -->
|
|
301
301
|
<f:Card class="sapUiTinyMargin">
|
|
302
302
|
<f:header>
|
|
303
|
-
<card:Header title="
|
|
303
|
+
<card:Header title="{i18n>cardNativeFunctionOps}" subtitle="{i18n>cardReadThroughOpsSub}" />
|
|
304
304
|
</f:header>
|
|
305
305
|
<f:content>
|
|
306
306
|
<l:VerticalLayout width="100%">
|
package/cds-plugin.js
CHANGED
|
@@ -14,8 +14,6 @@ if (cachingConfigs.some(c => c.statistics)) {
|
|
|
14
14
|
cds.env.roots.push(path.join(__dirname, 'db', 'statistics'));
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
cds.add?.register?.('caching-dashboard', require('./lib/add'))
|
|
18
|
-
|
|
19
17
|
cds.on('served', scanCachingAnnotations)
|
|
20
18
|
const LOG = cds.log("cds-caching");
|
|
21
19
|
|
|
@@ -27,14 +25,20 @@ cds.build?.register?.('cds-caching', class CachingBuildPlugin extends cds.build.
|
|
|
27
25
|
clean() { }
|
|
28
26
|
|
|
29
27
|
static hasTask() {
|
|
28
|
+
cds.log('cds-caching').info('hasTask', cds.env.requires);
|
|
30
29
|
const requires = cds.env.requires || {};
|
|
30
|
+
const dbKind = requires.db?.kind || '';
|
|
31
|
+
const isHanaDB = dbKind === 'hana' || dbKind === 'sql';
|
|
31
32
|
return Object.values(requires).some(
|
|
32
|
-
r => r.impl === 'cds-caching' && r.store === 'hana'
|
|
33
|
+
r => r.impl === 'cds-caching' && (r.store === 'hana' || (r.store === 'cds' && isHanaDB))
|
|
33
34
|
);
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
async build() {
|
|
37
38
|
const requires = cds.env.requires || {};
|
|
39
|
+
const compileOpts = { ...this.options(), sql_mapping: cds.env.sql.names };
|
|
40
|
+
let wroteCacheStore = false;
|
|
41
|
+
|
|
38
42
|
for (const [, config] of Object.entries(requires)) {
|
|
39
43
|
if (config.impl === 'cds-caching' && config.store === 'hana') {
|
|
40
44
|
const table = config.credentials?.table || 'KEYV';
|
|
@@ -48,12 +52,31 @@ cds.build?.register?.('cds-caching', class CachingBuildPlugin extends cds.build.
|
|
|
48
52
|
await this.write(content).to(`src/gen/${table}.hdbtable`);
|
|
49
53
|
LOG.info('Building cds-caching hana table', { table, keySize });
|
|
50
54
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
+
|
|
56
|
+
if (config.store === 'cds' && !wroteCacheStore) {
|
|
57
|
+
await this._buildCacheStoreHdbtables(compileOpts);
|
|
58
|
+
wroteCacheStore = true;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* The HANA build task compiles only the app `db/` folder, so `plugin.cds_caching.CacheStore`
|
|
65
|
+
* from env.roots is not part of that CSN. Emit matching .hdbtable files here.
|
|
66
|
+
* Non-HANA DBs still get the table via normal CDS deploy / DDL.
|
|
67
|
+
*/
|
|
68
|
+
async _buildCacheStoreHdbtables(compileOpts) {
|
|
69
|
+
const modelPath = path.join(__dirname, 'db', 'cache-store');
|
|
70
|
+
const model = await cds.load(modelPath, { ...compileOpts, cwd: cds.root });
|
|
71
|
+
const artifacts = cds.compile.to.hdbtable(model, compileOpts);
|
|
72
|
+
for (const [content, key] of artifacts) {
|
|
73
|
+
const file = key.file || `${key.name}${key.suffix || ''}`;
|
|
74
|
+
await this.write(content).to(path.join('src/gen', file));
|
|
55
75
|
}
|
|
76
|
+
LOG.info('Built cds-caching CacheStore HANA artifacts from cache-store model');
|
|
56
77
|
}
|
|
57
78
|
});
|
|
58
79
|
|
|
59
|
-
|
|
80
|
+
// CAP resolves `impl: 'cds-caching'` to this file; the main export must be the service class
|
|
81
|
+
// so `cds.connect.to('<cache>')` returns CachingService (e.g. addCachableFunction).
|
|
82
|
+
module.exports = CachingService
|
package/lib/util.js
CHANGED
|
@@ -85,17 +85,42 @@ const bindFunction = async (service, action, isBound = false) => {
|
|
|
85
85
|
})
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
const ENTITY_TAG_PREFIX = 'entity:';
|
|
89
|
+
|
|
90
|
+
const getEntityTag = (entity) => `${ENTITY_TAG_PREFIX}${entity.name}`;
|
|
91
|
+
|
|
88
92
|
const bindEntity = async (service, entity) => {
|
|
93
|
+
const invalidateOnWrite = entity['@cache.invalidateOnWrite'];
|
|
94
|
+
const entityTag = invalidateOnWrite ? getEntityTag(entity) : null;
|
|
95
|
+
|
|
89
96
|
service.prepend(function () {
|
|
90
97
|
service.on('READ', entity.name, async (req, next) => {
|
|
91
98
|
const cache = await cds.connect.to(entity['@cache.service'] || "caching");
|
|
99
|
+
|
|
100
|
+
const tags = [...(entity['@cache.tags'] || [])];
|
|
101
|
+
if (entityTag) tags.push({ value: entityTag });
|
|
102
|
+
|
|
92
103
|
const { result, cacheKey } = await cache.rt.run(req, next, {
|
|
93
104
|
ttl: entity['@cache.ttl'],
|
|
94
|
-
tags
|
|
105
|
+
tags,
|
|
95
106
|
key: extractCacheProperties(entity, 'key')
|
|
96
107
|
});
|
|
97
108
|
return result;
|
|
98
109
|
})
|
|
110
|
+
|
|
111
|
+
if (invalidateOnWrite) {
|
|
112
|
+
const cudHandler = async (data, req) => {
|
|
113
|
+
try {
|
|
114
|
+
const cache = await cds.connect.to(entity['@cache.service'] || "caching");
|
|
115
|
+
await cache.deleteByTag(entityTag);
|
|
116
|
+
} catch (error) {
|
|
117
|
+
cds.log('cds-caching').warn(`Cache invalidation failed for ${entity.name}:`, error);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
service.after('CREATE', entity.name, cudHandler);
|
|
121
|
+
service.after('UPDATE', entity.name, cudHandler);
|
|
122
|
+
service.after('DELETE', entity.name, cudHandler);
|
|
123
|
+
}
|
|
99
124
|
})
|
|
100
125
|
}
|
|
101
126
|
|
|
@@ -183,7 +208,8 @@ const scanCachingAnnotations = async (srvs) => {
|
|
|
183
208
|
cacheConfig.entities[entity.name] = {
|
|
184
209
|
ttl: entity['@cache.ttl'],
|
|
185
210
|
tags: entity['@cache.tags'],
|
|
186
|
-
key: extractCacheProperties(entity, 'key')
|
|
211
|
+
key: extractCacheProperties(entity, 'key'),
|
|
212
|
+
invalidateOnWrite: entity['@cache.invalidateOnWrite'] || false
|
|
187
213
|
};
|
|
188
214
|
}
|
|
189
215
|
|