@sap/cds 1.15.1 → 1.18.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/CHANGELOG.md +25 -0
- package/{developer-license-3.1.txt → LICENSE} +37 -35
- package/_hdbext/README.md +373 -0
- package/_hdbext/index.js +4 -0
- package/_hdbext/lib/client-factory.js +62 -0
- package/_hdbext/lib/client-session.js +96 -0
- package/_hdbext/lib/conn-options.js +84 -0
- package/_hdbext/lib/constants.js +79 -0
- package/_hdbext/lib/internal-constants.js +7 -0
- package/_hdbext/lib/middleware.js +46 -0
- package/_hdbext/lib/pool.js +236 -0
- package/_hdbext/lib/safe-sql.js +17 -0
- package/_hdbext/lib/sql-injection-utils.js +149 -0
- package/cds-queries-geo.js +347 -371
- package/cds-queries.js +2692 -2229
- package/cds.js +111 -104
- package/exprs.js +118 -107
- package/manager.js +696 -614
- package/metadata.js +604 -542
- package/npm-shrinkwrap.json +268 -0
- package/package.json +40 -1
- package/transaction.js +45 -51
- package/util/Queue.js +32 -30
- package/utils.js +182 -159
- package/xsjs-cds.js +231 -221
- package/.project +0 -11
- package/SIGNATURE.SMF +0 -1747
- package/TUTORIAL.md +0 -1236
- package/dependencies +0 -56
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sap/cds",
|
|
3
|
+
"version": "1.18.2",
|
|
4
|
+
"lockfileVersion": 3,
|
|
5
|
+
"requires": true,
|
|
6
|
+
"packages": {
|
|
7
|
+
"": {
|
|
8
|
+
"name": "@sap/cds",
|
|
9
|
+
"version": "1.18.2",
|
|
10
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@sap/e2e-trace": "^3.2.0",
|
|
13
|
+
"@sap/xsenv": "^3.4.0",
|
|
14
|
+
"accept-language": "2.0.16",
|
|
15
|
+
"async": "^2.6.4",
|
|
16
|
+
"debug": "^3.1.0",
|
|
17
|
+
"generic-pool": "^2.2.0",
|
|
18
|
+
"hdb": "^0.16.0",
|
|
19
|
+
"lodash": "^4.0.0",
|
|
20
|
+
"lru-cache": "^4.0.0",
|
|
21
|
+
"winston": "^2.4.6"
|
|
22
|
+
},
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=10"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"node_modules/@sap/e2e-trace": {
|
|
28
|
+
"version": "3.2.0",
|
|
29
|
+
"resolved": "https://registry.npmjs.org/@sap/e2e-trace/-/e2e-trace-3.2.0.tgz",
|
|
30
|
+
"integrity": "sha512-tNqLk/RhX6oc2ScFCJkVtSGPWqrxRLAUfIsCN1Dn4yGHc+gHQVdmyVTDkgKdgw9m4kU+emD2PjDXpo2VwAb0Pg==",
|
|
31
|
+
"hasShrinkwrap": true,
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"request-stats": "3.0.0"
|
|
34
|
+
},
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": "^8.0.0 || ^10.0.0 || ^12.0.0 || ^14.0.0 || ^16.0.0 || ^18.0.0"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"node_modules/@sap/e2e-trace/node_modules/http-headers": {
|
|
40
|
+
"version": "3.0.2",
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"next-line": "^1.1.0"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"node_modules/@sap/e2e-trace/node_modules/next-line": {
|
|
46
|
+
"version": "1.1.0"
|
|
47
|
+
},
|
|
48
|
+
"node_modules/@sap/e2e-trace/node_modules/once": {
|
|
49
|
+
"version": "1.4.0",
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"wrappy": "1"
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"node_modules/@sap/e2e-trace/node_modules/request-stats": {
|
|
55
|
+
"version": "3.0.0",
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"http-headers": "^3.0.1",
|
|
58
|
+
"once": "^1.4.0"
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"node_modules/@sap/e2e-trace/node_modules/wrappy": {
|
|
62
|
+
"version": "1.0.2"
|
|
63
|
+
},
|
|
64
|
+
"node_modules/@sap/xsenv": {
|
|
65
|
+
"version": "3.4.0",
|
|
66
|
+
"resolved": "https://registry.npmjs.org/@sap/xsenv/-/xsenv-3.4.0.tgz",
|
|
67
|
+
"integrity": "sha512-bZ/NFhS+wZI0JlMO1OOBEThfyOTmf2x5oQ+wToJGkZ2T5+gLUE3emZiC4iHA+BuSmUtO+vYoe29Q1qiE4qaiJQ==",
|
|
68
|
+
"hasShrinkwrap": true,
|
|
69
|
+
"dependencies": {
|
|
70
|
+
"debug": "4.3.3",
|
|
71
|
+
"node-cache": "^5.1.0",
|
|
72
|
+
"verror": "1.10.0"
|
|
73
|
+
},
|
|
74
|
+
"engines": {
|
|
75
|
+
"node": "^10.0.0 || ^12.0.0 || ^14.0.0 || ^16.0.0 || ^18.0.0"
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"node_modules/@sap/xsenv/node_modules/assert-plus": {
|
|
79
|
+
"version": "1.0.0"
|
|
80
|
+
},
|
|
81
|
+
"node_modules/@sap/xsenv/node_modules/clone": {
|
|
82
|
+
"version": "2.1.2"
|
|
83
|
+
},
|
|
84
|
+
"node_modules/@sap/xsenv/node_modules/core-util-is": {
|
|
85
|
+
"version": "1.0.2"
|
|
86
|
+
},
|
|
87
|
+
"node_modules/@sap/xsenv/node_modules/debug": {
|
|
88
|
+
"version": "4.3.3",
|
|
89
|
+
"dependencies": {
|
|
90
|
+
"ms": "2.1.2"
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
"node_modules/@sap/xsenv/node_modules/extsprintf": {
|
|
94
|
+
"version": "1.4.1"
|
|
95
|
+
},
|
|
96
|
+
"node_modules/@sap/xsenv/node_modules/ms": {
|
|
97
|
+
"version": "2.1.2"
|
|
98
|
+
},
|
|
99
|
+
"node_modules/@sap/xsenv/node_modules/node-cache": {
|
|
100
|
+
"version": "5.1.2",
|
|
101
|
+
"dependencies": {
|
|
102
|
+
"clone": "2.x"
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
"node_modules/@sap/xsenv/node_modules/verror": {
|
|
106
|
+
"version": "1.10.0",
|
|
107
|
+
"dependencies": {
|
|
108
|
+
"assert-plus": "^1.0.0",
|
|
109
|
+
"core-util-is": "1.0.2",
|
|
110
|
+
"extsprintf": "^1.2.0"
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
"node_modules/accept-language": {
|
|
114
|
+
"version": "2.0.16",
|
|
115
|
+
"resolved": "https://registry.npmjs.org/accept-language/-/accept-language-2.0.16.tgz",
|
|
116
|
+
"integrity": "sha1-uefScQd0rWCfJHbzz+GkkrVgYb4=",
|
|
117
|
+
"dependencies": {
|
|
118
|
+
"bcp47": "^1.1.2"
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
"node_modules/async": {
|
|
122
|
+
"version": "2.6.4",
|
|
123
|
+
"resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
|
|
124
|
+
"integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
|
|
125
|
+
"dependencies": {
|
|
126
|
+
"lodash": "^4.17.14"
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
"node_modules/bcp47": {
|
|
130
|
+
"version": "1.1.2",
|
|
131
|
+
"resolved": "https://registry.npmjs.org/bcp47/-/bcp47-1.1.2.tgz",
|
|
132
|
+
"integrity": "sha1-NUvjMH/9CEM6ePXh4glYRfifx/4=",
|
|
133
|
+
"engines": {
|
|
134
|
+
"node": ">=0.10"
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
"node_modules/colors": {
|
|
138
|
+
"version": "1.0.3",
|
|
139
|
+
"resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
|
|
140
|
+
"integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==",
|
|
141
|
+
"engines": {
|
|
142
|
+
"node": ">=0.1.90"
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
"node_modules/cycle": {
|
|
146
|
+
"version": "1.0.3",
|
|
147
|
+
"resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz",
|
|
148
|
+
"integrity": "sha512-TVF6svNzeQCOpjCqsy0/CSy8VgObG3wXusJ73xW2GbG5rGx7lC8zxDSURicsXI2UsGdi2L0QNRCi745/wUDvsA==",
|
|
149
|
+
"engines": {
|
|
150
|
+
"node": ">=0.4.0"
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
"node_modules/debug": {
|
|
154
|
+
"version": "3.2.7",
|
|
155
|
+
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
|
|
156
|
+
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
|
|
157
|
+
"dependencies": {
|
|
158
|
+
"ms": "^2.1.1"
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
"node_modules/eyes": {
|
|
162
|
+
"version": "0.1.8",
|
|
163
|
+
"resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz",
|
|
164
|
+
"integrity": "sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==",
|
|
165
|
+
"engines": {
|
|
166
|
+
"node": "> 0.1.90"
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
"node_modules/generic-pool": {
|
|
170
|
+
"version": "2.5.4",
|
|
171
|
+
"resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-2.5.4.tgz",
|
|
172
|
+
"integrity": "sha1-OMYYhRPhQDCUjsblz2VSPZd5KZs=",
|
|
173
|
+
"engines": {
|
|
174
|
+
"node": ">= 0.8.0"
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
"node_modules/hdb": {
|
|
178
|
+
"version": "0.16.0",
|
|
179
|
+
"resolved": "https://registry.npmjs.org/hdb/-/hdb-0.16.0.tgz",
|
|
180
|
+
"integrity": "sha512-QAOPkO5zUCy3gjYCbnPnPqLjXuIVjh0NLz0V/33htWy5oVnX3CQdv0DjgOmNbh478HyzJlN2qlysXlMM6vTG1A==",
|
|
181
|
+
"dependencies": {
|
|
182
|
+
"iconv-lite": "^0.4.18"
|
|
183
|
+
},
|
|
184
|
+
"engines": {
|
|
185
|
+
"node": ">= 0.12"
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
"node_modules/iconv-lite": {
|
|
189
|
+
"version": "0.4.24",
|
|
190
|
+
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
|
191
|
+
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
|
192
|
+
"dependencies": {
|
|
193
|
+
"safer-buffer": ">= 2.1.2 < 3"
|
|
194
|
+
},
|
|
195
|
+
"engines": {
|
|
196
|
+
"node": ">=0.10.0"
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
"node_modules/isstream": {
|
|
200
|
+
"version": "0.1.2",
|
|
201
|
+
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
|
202
|
+
"integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g=="
|
|
203
|
+
},
|
|
204
|
+
"node_modules/lodash": {
|
|
205
|
+
"version": "4.17.21",
|
|
206
|
+
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
|
207
|
+
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
|
208
|
+
},
|
|
209
|
+
"node_modules/lru-cache": {
|
|
210
|
+
"version": "4.1.5",
|
|
211
|
+
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
|
|
212
|
+
"integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
|
|
213
|
+
"dependencies": {
|
|
214
|
+
"pseudomap": "^1.0.2",
|
|
215
|
+
"yallist": "^2.1.2"
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
"node_modules/ms": {
|
|
219
|
+
"version": "2.1.3",
|
|
220
|
+
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
|
221
|
+
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
|
222
|
+
},
|
|
223
|
+
"node_modules/pseudomap": {
|
|
224
|
+
"version": "1.0.2",
|
|
225
|
+
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
|
|
226
|
+
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
|
|
227
|
+
},
|
|
228
|
+
"node_modules/safer-buffer": {
|
|
229
|
+
"version": "2.1.2",
|
|
230
|
+
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
|
231
|
+
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
|
232
|
+
},
|
|
233
|
+
"node_modules/stack-trace": {
|
|
234
|
+
"version": "0.0.10",
|
|
235
|
+
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
|
|
236
|
+
"integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=",
|
|
237
|
+
"engines": {
|
|
238
|
+
"node": "*"
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
"node_modules/winston": {
|
|
242
|
+
"version": "2.4.6",
|
|
243
|
+
"resolved": "https://registry.npmjs.org/winston/-/winston-2.4.6.tgz",
|
|
244
|
+
"integrity": "sha512-J5Zu4p0tojLde8mIOyDSsmLmcP8I3Z6wtwpTDHx1+hGcdhxcJaAmG4CFtagkb+NiN1M9Ek4b42pzMWqfc9jm8w==",
|
|
245
|
+
"dependencies": {
|
|
246
|
+
"async": "^3.2.3",
|
|
247
|
+
"colors": "1.0.x",
|
|
248
|
+
"cycle": "1.0.x",
|
|
249
|
+
"eyes": "0.1.x",
|
|
250
|
+
"isstream": "0.1.x",
|
|
251
|
+
"stack-trace": "0.0.x"
|
|
252
|
+
},
|
|
253
|
+
"engines": {
|
|
254
|
+
"node": ">= 0.10.0"
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
"node_modules/winston/node_modules/async": {
|
|
258
|
+
"version": "3.2.4",
|
|
259
|
+
"resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
|
|
260
|
+
"integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ=="
|
|
261
|
+
},
|
|
262
|
+
"node_modules/yallist": {
|
|
263
|
+
"version": "2.1.2",
|
|
264
|
+
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
|
|
265
|
+
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
package/package.json
CHANGED
|
@@ -1 +1,40 @@
|
|
|
1
|
-
{"dependencies":{"@sap/hdbext":"^4.3.0","@sap/xsenv":"^1.2.6","async":"1.5.0","winston":"1.1.2"},"description":"SAP HANA Core Data Services Client for node.js","devDependencies":{"expect":"^1.4.0","mocha":"4.0.1"},"engines":{"node":"^0.12.7 || ^4.4.0 || ^6.0.0","npm":"^2.11.x"},"keywords":["sap","hana","cds"],"main":"./cds.js","maintainers":[{"name":"https-support.sap.com","email":"do-not-reply@sap.com"}],"name":"@sap/cds","optionalDependencies":{},"readme":"node-cds: Core Data Services for node.js\n========================================\n\nImportant note: \n---------------\n The node-cds library is now considered feature complete. \n It will remain fully supported but will not receive further \n enhancements in future releases.\n\nAbstract\n--------\n\nThe *Core Data Services for node.js* (node-cds) are a JavaScript\nclient library for Core Data Services that allow node.js applications\nto consume CDS artifacts natively in node.js applications.\n\nnode-cds supports major CDS features, in particular entities, types,\nassociations, and views. The library offers a *managed mode* and an\n*unmanaged mode* that differ in the way that data is retrieved from\nthe database.\n\nThe node-cds project is the successor of the XS Data Services (XSDS)\nlibrary available for the HANA XS Engine.\n\n\nAPI Overview\n------------\n\n### Library Import\n\nTo use *node-cds*, require its main file:\n\n var cds = require('cds');\n\nOn Cloud Foundry, add a depencency on the latest node-cds release to\nyour `package.json`:\n\n \"dependencies\": {\n \"cds\": \"*\",\n ...\n }\n\t\t\n\n### CDS Import\n\nCDS entities are imported by name. The import function takes a callback that\nis invoked when all imports have completed. Additional fields and overrides\nmay be supplied for each entity.\n\n cds.importEntities([\n { $entity: \"xsds.test.cds::ds_test.e1\" },\n { $entity: \"xsds.test.cds::ds_test.e2\",\n $fields: {\n a: { $association: \"xsds.test.cds::ds_test.e2\",\n $viaBacklink: \"b\" }\n }\n }\n ], callback);\n\n function callback(error, entities) {\n var E1 = entities[\"xsds.test.cds::ds_test.e1\"];\n var E2 = entities[\"xsds.test.cds::ds_test.e2\"];\n // ...\n }\n\nNote that the import is a regular asynchronous node.js function. You may\nimport entities at any point in time, and in as many calls as you want.\n\nEntities may not be imported more than once. To retrieve an imported entity\nuse `$getEntity` or `$getEntities`:\n\n cds.$getEntities([\n \"xsds.test.cds::ds_test.e1\",\n \"xsds.test.cds::ds_test.e2\"\n ], function(err, entities) {\n var E1 = entities[\"xsds.test.cds::ds_test.e1\"];\n // ...\n });\n\nBoth functions will wait until the requested entity has been imported successfully.\nThere is also a synchronous version:\n\n var E1 = $getEntitySync(\"xsds.test.cds::ds_test.e1\");\n\nNote that `$getEntitySync` will return `null` if the import has not completed yet.\n\n\n### Database Connections and Transactions\n\nOpen new connection and transaction:\n\n cds.$getTransaction(function(error, tx) {\n tx.$get(...);\n // ...\n tx.$close();\n });\n\nReuse existing database connection `dbconn`, e.g., from `express` framework:\n\n cds.$getTransaction(dbconn, function(error, tx) {\n tx.$get(...);\n // ...\n tx.$close();\n });\n\nNote: We recommend `node-hdbext` for setting up the\nconnection to your HANA instance.\n\nTransaction management\n\n tx.$setAutoCommit(<boolean>);\n tx.$commit(callback);\n tx.$rollback(callback);\n\nBy default, transactions are in auto commit mode. Note that auto commit refers\nto node-cds operations, not database operations.\n\n\n### Managed Instances\n\nRetrieve entity instances by key:\n\n tx.$get(E1, { id1: 1, id2: 2, ... }, function(error, instance) {\n console.log(JSON.stringify(instance));\n });\n\nBatch retrieval for multiple instances:\n\n var requests = [\n { $entity: E1, id11: 1, id2: 2 },\n { $entity: E2, id: \"key\" }, ...\n ];\n tx.$getAll(requests, function(error, instances) {\n console.log(\"e1 = \" + JSON.stringify(instances[0]);\n console.log(\"e2 = \" + JSON.stringify(instances[1]);\n });\n\nSyntactic sugar for above:\n\n var requests = [\n E1.$prepare({ id1: 1, id2: 2 }),\n E2.$prepare({ id: \"key\" }), ...\n ];\n tx.$getAll(requests, ...);\n\nRetrieve entity instances by condition:\n\n tx.$find(E1, { value: { $gt: 69 } }, function(error, instances) {\n console.log(\"found \" + instance.length + \" instances\");\n });\n\nBatch retrieval by condition:\n\n tx.$findAll([\n { $entity: E1, { prop: { $eq: 1 } },\n { $entity: E2, { prop: { $ne: 2 } }\n ], callback);\n\nNote that the result of `$findAll` is an array of arrays; to flatten the result\nset you may use\n\n var flattenedInstanceArray = [].concat.apply([], findAllResult));\n\nFor complex data types you need to supply a comparison function using `$using` that\ncompares their values in JavaScript:\n\n tx.$find(E1, { prop: { $lt: \"1.0e-10\", $using: function(arg1, arg2) {\n return Math.sign(parseFloat(arg1) - parseFloat(arg2));\n } }, callback);\n\nA comparison function takes two arguments and returns values `< 0`, `== 0`, or `> 0`\ndepending on their relation to each other.\n\nCreate new instance:\n\n tx.$save({ $entity: E, key: 1, value: \"hello world\" }, function(error, instance) {\n if (!error)\n console.log(\"instance created\");\n });\n\nBatch creation:\n\n var newinsts = [\n { $entity: E1, id1: 1, value: 2 },\n E2.$prepare({ id: \"new\", value: 4 }), ...\n ];\n tx.$saveAll(newinsts, function(error, instances) {\n console.log(\"\" + instances.length + \" instances created\");\n });\n\nUpdate existing instance:\n\n instance.value++;\n tx.$save(instance, function (error, savedInstance) {\n if (!error)\n console.log(\"instance updated\");\n });\n\nBatch update:\n\n tx.$saveAll([ instance1, instance2, ... ], function (error, instances) {\n console.log(\"instances updated\");\n });\n\nDiscard entity instances:\n\n tx.$discard(instance, function(error) {\n if (error)\n console.error(\"Error discarding instance: \" + error);\n });\n\nBatch discard:\n\n tx.$discardAll([ instance1, instance2, ...], function(error) {\n if (error)\n console.error(\"Error discarding instances: \" + error);\n });\n\nUnmanaged delete:\n\n tx.$delete(entity, condition, callback);\n\n*CAUTION!* Unmanaged `delete`s bypass the cache and will not cascade to\ntarget instances! The `$delete` method is merely syntactic sugar for\n`$query().$matching().$delete()`!\n\n\n### Associations\n\nAdding via backlink 1:n associations:\n\n cds.importEntities([{\n $entity: \"cds.test::parent\",\n $fields: {\n BacklinkAssoc: {\n $association: {\n $entity: \"cds.test::target\",\n $viaBacklink: \"backassoc\"\n }\n }\n }\n }], callback);\n\nAdding via entity m:n associations:\n\n cds.importEntities([{\n $entity: \"cds.test::parent\",\n $fields: {\n BacklinkAssoc: {\n\t\t\t\t$association: {\n\t\t\t\t\t$entity: \"cds.test::target\",\n\t\t\t\t\t$viaEntity: \"cds.test::link\",\n\t\t\t\t\t$source: \"sourceassoc\",\n\t\t\t\t\t$target: \"targetassoc\"\n\t\t\t\t}\n }\n }\n }], callback);\n\nDeclaring lazy associations:\n\n cds.importEntities([{\n $entity: \"cds.test::parent\",\n $fields: {\n LazyAssoc: {\n $association: {\n\t\t\t\t\t$lazy: true\n\t\t\t\t}\n }\n }\n ], callback);\n\nLazy retrieval of lazy associations:\n\n instance.lazyAssoc.$load(function (error, targets) {\n // targets == instance.lazyAssoc\n console.log(\"\" + targets.length + \" targets retrieved\");\n });\n\nRe-syncing backlinking and unmanaged associations\n\n instance.unmanagedAssoc.$reload(function (error, targets) {\n // targets == instance.unmanagedAssoc\n console.log(\"association has \" + targets.length + \" targets\");\n });\n\n\n### Unmanaged Queries\n\nBasic query:\n\n E1.$query().$matching({ key: 1 })\n .$execute({}, function(error, result) {\n console.log(\"result = \" + JSON.stringify(result);\n });\n\nMore complex query conditions:\n\n E1.$query().$matching({ value1: { $lt: 42 }, value2: { $null: true } })\n .$execute({}, function(error, result) {\n console.log(\"result = \" + JSON.stringify(result);\n });\n\nProjection and navigation:\n\n E2.$query().$matching({ key: 1 })\n .$project({ value1: true, assoc: { value2: true, value3: true })\n .$execute({}, function(error, result) { ... });\n\nStream interface:\n\n E1.$query().$execute({ $stream: true }, function(error, stream) {\n stream.on('data', function(chunk) {\n console.log(chunk);\n }).on('end', function() {\n console.log(\"done\");\n });\n });\n","readmeFilename":"README.md","scripts":{"cleanBundle":"find $PWD -name package.json -exec node .filter/filter-package.js {} \\; ; rm -rf .filter init_sign.py","prepareRelease":"rm -rf doc/ test/ .gitignore .xmake.cfg && npm prune --production","test-disabled":"node node_modules/mocha/bin/mocha --recursive"},"version":"1.15.1","warnings":[{"code":"ENOTSUP","required":{"node":"^0.12.7 || ^4.4.0 || ^6.0.0","npm":"^2.11.x"},"pkgid":"@sap/cds@1.15.1"},{"code":"ENOTSUP","required":{"node":"^0.12.7 || ^4.4.0 || ^6.0.0","npm":"^2.11.x"},"pkgid":"@sap/cds@1.15.1"}],"license":"SEE LICENSE IN developer-license-3.1.txt"}
|
|
1
|
+
{
|
|
2
|
+
"dependencies": {
|
|
3
|
+
"@sap/e2e-trace": "^3.2.0",
|
|
4
|
+
"@sap/xsenv": "^3.4.0",
|
|
5
|
+
"accept-language": "2.0.16",
|
|
6
|
+
"async": "^2.6.4",
|
|
7
|
+
"debug": "^3.1.0",
|
|
8
|
+
"generic-pool": "^2.2.0",
|
|
9
|
+
"hdb": "^0.16.0",
|
|
10
|
+
"lodash": "^4.0.0",
|
|
11
|
+
"lru-cache": "^4.0.0",
|
|
12
|
+
"winston": "^2.4.6"
|
|
13
|
+
},
|
|
14
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
15
|
+
"description": "SAP HANA Core Data Services Client for node.js",
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=10"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"package.json",
|
|
21
|
+
"util",
|
|
22
|
+
"cds.js",
|
|
23
|
+
"_hdbext",
|
|
24
|
+
"npm-shrinkwrap.json",
|
|
25
|
+
"cds-queries-geo.js",
|
|
26
|
+
"cds-queries.js",
|
|
27
|
+
"exprs.js",
|
|
28
|
+
"manager.js",
|
|
29
|
+
"metadata.js",
|
|
30
|
+
"transaction.js",
|
|
31
|
+
"utils.js",
|
|
32
|
+
"xsjs-cds.js",
|
|
33
|
+
"README.md",
|
|
34
|
+
"CHANGELOG.md",
|
|
35
|
+
"LICENSE"
|
|
36
|
+
],
|
|
37
|
+
"main": "./cds.js",
|
|
38
|
+
"name": "@sap/cds",
|
|
39
|
+
"version": "1.18.2"
|
|
40
|
+
}
|
package/transaction.js
CHANGED
|
@@ -1,82 +1,76 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var manager = require('./manager');
|
|
5
|
-
var utils = require('./utils');
|
|
6
|
-
var logger = utils.logger;
|
|
1
|
+
const xsconn = require('./_hdbext');
|
|
2
|
+
const xsenv = require('@sap/xsenv');
|
|
7
3
|
|
|
4
|
+
const manager = require('./manager');
|
|
8
5
|
|
|
9
6
|
// transaction and database connection management
|
|
10
7
|
|
|
11
8
|
// transaction id for
|
|
12
|
-
|
|
9
|
+
let txId = 0;
|
|
13
10
|
|
|
14
11
|
// find HANA service binding
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
const hanaOptions = xsenv.getServices({
|
|
13
|
+
hana: process.env.HANA_SERVICE_NAME || {tag: 'hana'},
|
|
17
14
|
}).hana;
|
|
18
15
|
|
|
19
|
-
// manually provide HANA service binding
|
|
20
|
-
// var hanaOptions = {
|
|
21
|
-
// host : ...,
|
|
22
|
-
// port : 3xx15,
|
|
23
|
-
// user : ...,
|
|
24
|
-
// password : ...,
|
|
25
|
-
// schema : ...
|
|
26
|
-
// };
|
|
27
|
-
|
|
28
16
|
// control opening of new database connections
|
|
29
|
-
|
|
17
|
+
const proxy = xsconn.getPool(hanaOptions);
|
|
30
18
|
|
|
31
19
|
|
|
32
20
|
// get transaction associated with open database connection
|
|
33
21
|
|
|
34
22
|
exports.getClient = function(dbconn, callback) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
dbconn.connect(function (err) { callback(err, dbconn); });
|
|
23
|
+
const initClient = function(cl) {
|
|
24
|
+
cl.setAutoCommit(false); // auto commit handled by node-cds
|
|
25
|
+
exports._autoCommit(cl, true);
|
|
26
|
+
cl.$_tx_id = ++txId;
|
|
27
|
+
manager.openCache(cl);
|
|
28
|
+
};
|
|
29
|
+
if (dbconn) {
|
|
30
|
+
if (!dbconn.$_tx_id) {
|
|
31
|
+
initClient(dbconn);
|
|
32
|
+
}
|
|
33
|
+
if (dbconn.readyState === 'connected') {
|
|
34
|
+
callback(null, dbconn);
|
|
48
35
|
} else {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
callback(err, client);
|
|
53
|
-
});
|
|
36
|
+
dbconn.connect(function(err) {
|
|
37
|
+
callback(err, dbconn);
|
|
38
|
+
});
|
|
54
39
|
}
|
|
40
|
+
} else {
|
|
41
|
+
proxy.acquire(null, function(err, client) {
|
|
42
|
+
if (!err) {
|
|
43
|
+
initClient(client);
|
|
44
|
+
}
|
|
45
|
+
callback(err, client);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
55
48
|
};
|
|
56
49
|
|
|
57
50
|
exports.releaseClient = function(client, dbconn) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
proxy.release(client);
|
|
51
|
+
if (dbconn) {
|
|
52
|
+
// don't touch connection, in particular keep it connected
|
|
53
|
+
// dbconn.disconnect(cb);
|
|
54
|
+
} else {
|
|
55
|
+
if (client.$_tx_id) {
|
|
56
|
+
manager.closeCache(client);
|
|
65
57
|
}
|
|
58
|
+
proxy.release(client);
|
|
59
|
+
}
|
|
66
60
|
};
|
|
67
61
|
|
|
68
62
|
|
|
69
63
|
// transaction handling
|
|
70
64
|
|
|
71
|
-
exports._autoCommit = function
|
|
72
|
-
|
|
65
|
+
exports._autoCommit = function(client, auto) {
|
|
66
|
+
client.$_autoCommit = auto;
|
|
73
67
|
};
|
|
74
68
|
|
|
75
|
-
exports._commit = function
|
|
76
|
-
|
|
69
|
+
exports._commit = function(client, callback) {
|
|
70
|
+
client.commit(callback);
|
|
77
71
|
};
|
|
78
72
|
|
|
79
|
-
exports._rollback = function
|
|
80
|
-
|
|
81
|
-
|
|
73
|
+
exports._rollback = function(client, callback) {
|
|
74
|
+
manager._clearCaches(client);
|
|
75
|
+
client.rollback(callback);
|
|
82
76
|
};
|
package/util/Queue.js
CHANGED
|
@@ -3,57 +3,59 @@
|
|
|
3
3
|
exports.Queue = Queue;
|
|
4
4
|
|
|
5
5
|
function Queue() {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
this.queue = [];
|
|
7
|
+
this.busy = false;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
Object.defineProperty(Queue.prototype, 'empty', {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
get: function isEmpty() {
|
|
12
|
+
return this.queue.length === 0;
|
|
13
|
+
},
|
|
14
14
|
});
|
|
15
15
|
|
|
16
16
|
Queue.prototype.push = function push(worker, callback, name) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
const task = new Task(worker, callback, name);
|
|
18
|
+
this.queue.push(task);
|
|
19
|
+
this.run();
|
|
20
|
+
return this;
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
Queue.prototype.run = function() {
|
|
24
|
-
|
|
24
|
+
const self = this;
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
function next(err, name) {
|
|
27
|
+
self.busy = false;
|
|
28
|
+
if (self.queue.length) {
|
|
29
|
+
run();
|
|
30
30
|
}
|
|
31
|
+
}
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
33
|
+
function run() {
|
|
34
|
+
if (!self.busy) {
|
|
35
|
+
self.busy = true;
|
|
36
|
+
const task = self.queue.shift();
|
|
37
|
+
task.run(next);
|
|
38
38
|
}
|
|
39
|
+
}
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
run();
|
|
41
42
|
};
|
|
42
43
|
|
|
43
44
|
|
|
44
45
|
function Task(worker, callback, name) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
this.worker = worker;
|
|
47
|
+
this.callback = callback;
|
|
48
|
+
this.name = name;
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
Task.prototype.run = function run(next) {
|
|
51
|
-
|
|
52
|
+
const self = this;
|
|
52
53
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
function done() {
|
|
55
|
+
// eslint-disable-next-line prefer-rest-params
|
|
56
|
+
self.callback.apply(null, arguments);
|
|
57
|
+
next(null, self.name);
|
|
58
|
+
}
|
|
57
59
|
|
|
58
|
-
|
|
60
|
+
this.worker(done); // do NOT convert exceptions into errors!
|
|
59
61
|
};
|