1 | ;
|
2 |
|
3 | var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
4 |
|
5 | Object.defineProperty(exports, "__esModule", {
|
6 | value: true
|
7 | });
|
8 | exports["default"] = void 0;
|
9 |
|
10 | var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
11 |
|
12 | var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
13 |
|
14 | var _resultSummary = _interopRequireDefault(require("./result-summary"));
|
15 |
|
16 | var _connectionHolder = require("./internal/connection-holder");
|
17 |
|
18 | var _streamObservers = require("./internal/stream-observers");
|
19 |
|
20 | /**
|
21 | * Copyright (c) 2002-2019 "Neo4j,"
|
22 | * Neo4j Sweden AB [http://neo4j.com]
|
23 | *
|
24 | * This file is part of Neo4j.
|
25 | *
|
26 | * Licensed under the Apache License, Version 2.0 (the "License");
|
27 | * you may not use this file except in compliance with the License.
|
28 | * You may obtain a copy of the License at
|
29 | *
|
30 | * http://www.apache.org/licenses/LICENSE-2.0
|
31 | *
|
32 | * Unless required by applicable law or agreed to in writing, software
|
33 | * distributed under the License is distributed on an "AS IS" BASIS,
|
34 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
35 | * See the License for the specific language governing permissions and
|
36 | * limitations under the License.
|
37 | */
|
38 | var DEFAULT_ON_ERROR = function DEFAULT_ON_ERROR(error) {
|
39 | console.log('Uncaught error when processing result: ' + error);
|
40 | };
|
41 |
|
42 | var DEFAULT_ON_COMPLETED = function DEFAULT_ON_COMPLETED(summary) {};
|
43 |
|
44 | var DEFAULT_METADATA_SUPPLIER = function DEFAULT_METADATA_SUPPLIER(metadata) {};
|
45 | /**
|
46 | * A stream of {@link Record} representing the result of a query.
|
47 | * Can be consumed eagerly as {@link Promise} resolved with array of records and {@link ResultSummary}
|
48 | * summary, or rejected with error that contains {@link string} code and {@link string} message.
|
49 | * Alternatively can be consumed lazily using {@link Result#subscribe} function.
|
50 | * @access public
|
51 | */
|
52 |
|
53 |
|
54 | var Result =
|
55 | /*#__PURE__*/
|
56 | function () {
|
57 | /**
|
58 | * Inject the observer to be used.
|
59 | * @constructor
|
60 | * @access private
|
61 | * @param {Promise<ResultStreamObserver>} streamObserverPromise
|
62 | * @param {mixed} query - Cypher query to execute
|
63 | * @param {Object} parameters - Map with parameters to use in query
|
64 | * @param {ConnectionHolder} connectionHolder - to be notified when result is either fully consumed or error happened.
|
65 | */
|
66 | function Result(streamObserverPromise, query, parameters, connectionHolder) {
|
67 | (0, _classCallCheck2["default"])(this, Result);
|
68 | this._stack = captureStacktrace();
|
69 | this._streamObserverPromise = streamObserverPromise;
|
70 | this._p = null;
|
71 | this._query = query;
|
72 | this._parameters = parameters || {};
|
73 | this._connectionHolder = connectionHolder || _connectionHolder.EMPTY_CONNECTION_HOLDER;
|
74 | }
|
75 | /**
|
76 | * Returns a promise for the field keys.
|
77 | *
|
78 | * *Should not be combined with {@link Result#subscribe} function.*
|
79 | *
|
80 | * @public
|
81 | * @returns {Promise<string[]>} - Field keys, in the order they will appear in records.
|
82 | }
|
83 | */
|
84 |
|
85 |
|
86 | (0, _createClass2["default"])(Result, [{
|
87 | key: "keys",
|
88 | value: function keys() {
|
89 | var _this = this;
|
90 |
|
91 | return new Promise(function (resolve, reject) {
|
92 | _this._streamObserverPromise.then(function (observer) {
|
93 | return observer.subscribe({
|
94 | onKeys: function onKeys(keys) {
|
95 | return resolve(keys);
|
96 | },
|
97 | onError: function onError(err) {
|
98 | return reject(err);
|
99 | }
|
100 | });
|
101 | });
|
102 | });
|
103 | }
|
104 | /**
|
105 | * Returns a promise for the result summary.
|
106 | *
|
107 | * *Should not be combined with {@link Result#subscribe} function.*
|
108 | *
|
109 | * @public
|
110 | * @returns {Promise<ResultSummary>} - Result summary.
|
111 | *
|
112 | */
|
113 |
|
114 | }, {
|
115 | key: "summary",
|
116 | value: function summary() {
|
117 | var _this2 = this;
|
118 |
|
119 | return new Promise(function (resolve, reject) {
|
120 | _this2._streamObserverPromise.then(function (o) {
|
121 | o.cancel();
|
122 | o.subscribe({
|
123 | onCompleted: function onCompleted(metadata) {
|
124 | return resolve(metadata);
|
125 | },
|
126 | onError: function onError(err) {
|
127 | return reject(err);
|
128 | }
|
129 | });
|
130 | });
|
131 | });
|
132 | }
|
133 | /**
|
134 | * Create and return new Promise
|
135 | *
|
136 | * @private
|
137 | * @return {Promise} new Promise.
|
138 | */
|
139 |
|
140 | }, {
|
141 | key: "_getOrCreatePromise",
|
142 | value: function _getOrCreatePromise() {
|
143 | var _this3 = this;
|
144 |
|
145 | if (!this._p) {
|
146 | this._p = new Promise(function (resolve, reject) {
|
147 | var records = [];
|
148 | var observer = {
|
149 | onNext: function onNext(record) {
|
150 | records.push(record);
|
151 | },
|
152 | onCompleted: function onCompleted(summary) {
|
153 | resolve({
|
154 | records: records,
|
155 | summary: summary
|
156 | });
|
157 | },
|
158 | onError: function onError(error) {
|
159 | reject(error);
|
160 | }
|
161 | };
|
162 |
|
163 | _this3.subscribe(observer);
|
164 | });
|
165 | }
|
166 |
|
167 | return this._p;
|
168 | }
|
169 | /**
|
170 | * Waits for all results and calls the passed in function with the results.
|
171 | *
|
172 | * *Should not be combined with {@link Result#subscribe} function.*
|
173 | *
|
174 | * @param {function(result: {records:Array<Record>, summary: ResultSummary})} onFulfilled - function to be called
|
175 | * when finished.
|
176 | * @param {function(error: {message:string, code:string})} onRejected - function to be called upon errors.
|
177 | * @return {Promise} promise.
|
178 | */
|
179 |
|
180 | }, {
|
181 | key: "then",
|
182 | value: function then(onFulfilled, onRejected) {
|
183 | return this._getOrCreatePromise().then(onFulfilled, onRejected);
|
184 | }
|
185 | /**
|
186 | * Catch errors when using promises.
|
187 | *
|
188 | * *Should not be combined with {@link Result#subscribe} function.*
|
189 | *
|
190 | * @param {function(error: Neo4jError)} onRejected - Function to be called upon errors.
|
191 | * @return {Promise} promise.
|
192 | */
|
193 |
|
194 | }, {
|
195 | key: "catch",
|
196 | value: function _catch(onRejected) {
|
197 | return this._getOrCreatePromise()["catch"](onRejected);
|
198 | }
|
199 | /**
|
200 | * Stream records to observer as they come in, this is a more efficient method
|
201 | * of handling the results, and allows you to handle arbitrarily large results.
|
202 | *
|
203 | * @param {Object} observer - Observer object
|
204 | * @param {function(keys: string[])} observer.onKeys - handle stream head, the field keys.
|
205 | * @param {function(record: Record)} observer.onNext - handle records, one by one.
|
206 | * @param {function(summary: ResultSummary)} observer.onCompleted - handle stream tail, the result summary.
|
207 | * @param {function(error: {message:string, code:string})} observer.onError - handle errors.
|
208 | * @return
|
209 | */
|
210 |
|
211 | }, {
|
212 | key: "subscribe",
|
213 | value: function subscribe(observer) {
|
214 | var _this4 = this;
|
215 |
|
216 | var onCompletedOriginal = observer.onCompleted || DEFAULT_ON_COMPLETED;
|
217 |
|
218 | var onCompletedWrapper = function onCompletedWrapper(metadata) {
|
219 | // notify connection holder that the used connection is not needed any more because result has
|
220 | // been fully consumed; call the original onCompleted callback after that
|
221 | _this4._connectionHolder.releaseConnection().then(function () {
|
222 | onCompletedOriginal.call(observer, new _resultSummary["default"](_this4._query, _this4._parameters, metadata));
|
223 | });
|
224 | };
|
225 |
|
226 | observer.onCompleted = onCompletedWrapper;
|
227 | var onErrorOriginal = observer.onError || DEFAULT_ON_ERROR;
|
228 |
|
229 | var onErrorWrapper = function onErrorWrapper(error) {
|
230 | // notify connection holder that the used connection is not needed any more because error happened
|
231 | // and result can't bee consumed any further; call the original onError callback after that
|
232 | _this4._connectionHolder.releaseConnection().then(function () {
|
233 | replaceStacktrace(error, _this4._stack);
|
234 | onErrorOriginal.call(observer, error);
|
235 | });
|
236 | };
|
237 |
|
238 | observer.onError = onErrorWrapper;
|
239 |
|
240 | this._streamObserverPromise.then(function (o) {
|
241 | return o.subscribe(observer);
|
242 | });
|
243 | }
|
244 | /**
|
245 | * Signals the stream observer that the future records should be discarded on the server.
|
246 | *
|
247 | * @protected
|
248 | * @since 4.0.0
|
249 | */
|
250 |
|
251 | }, {
|
252 | key: "_cancel",
|
253 | value: function _cancel() {
|
254 | this._streamObserverPromise.then(function (o) {
|
255 | return o.cancel();
|
256 | });
|
257 | }
|
258 | }]);
|
259 | return Result;
|
260 | }();
|
261 |
|
262 | function captureStacktrace() {
|
263 | var error = new Error('');
|
264 |
|
265 | if (error.stack) {
|
266 | return error.stack.replace(/^Error(\n\r)*/, ''); // we don't need the 'Error\n' part, if only it exists
|
267 | }
|
268 |
|
269 | return null;
|
270 | }
|
271 |
|
272 | function replaceStacktrace(error, newStack) {
|
273 | if (newStack) {
|
274 | // Error.prototype.toString() concatenates error.name and error.message nicely
|
275 | // then we add the rest of the stack trace
|
276 | error.stack = error.toString() + '\n' + newStack;
|
277 | }
|
278 | }
|
279 |
|
280 | var _default = Result;
|
281 | exports["default"] = _default; |
\ | No newline at end of file |