Skip to content

Commit 7d0181f

Browse files
authored
Merge pull request #242 from ml054/v4.2
sync with latest changes
2 parents 0dc7348 + 4a40eff commit 7d0181f

File tree

73 files changed

+1353
-470
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1353
-470
lines changed

package-lock.json

+123-318
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+13-14
Original file line numberDiff line numberDiff line change
@@ -54,25 +54,25 @@
5454
"author": "Hibernating Rhinos",
5555
"license": "MIT",
5656
"devDependencies": {
57-
"@types/bluebird": "^3.5.32",
58-
"@types/md5": "^2.2.0",
59-
"@types/mocha": "^8.0.3",
57+
"@types/bluebird": "^3.5.33",
58+
"@types/md5": "^2.2.1",
59+
"@types/mocha": "^8.0.4",
6060
"@types/pluralize": "0.0.27",
6161
"@types/rimraf": "^3.0.0",
62-
"@types/sinon": "^9.0.6",
62+
"@types/sinon": "^9.0.8",
6363
"@types/unzipper": "^0.10.3",
64-
"@types/ws": "^7.2.6",
64+
"@types/ws": "^7.4.0",
6565
"cross-os": "^1.3.0",
6666
"glob": "^7.1.6",
6767
"http-proxy-agent": "^4.0.1",
6868
"lodash.orderby": "^4.6.0",
69-
"mocha": "^8.1.3",
69+
"mocha": "^8.2.1",
7070
"nyc": "^15.1.0",
71-
"open": "^7.2.1",
71+
"open": "^7.3.0",
7272
"rimraf": "^3.0.2",
73-
"sinon": "^9.0.3",
73+
"sinon": "^9.2.1",
7474
"source-map-support": "^0.5.19",
75-
"ts-node": "^8.10.2",
75+
"ts-node": "^9.0.0",
7676
"tslint": "^6.1.3",
7777
"tslint-eslint-rules": "^5.4.0",
7878
"tslint-microsoft-contrib": "^6.2.0",
@@ -90,7 +90,7 @@
9090
"change-case": "^3.1.0",
9191
"deprecate": "^1.1.1",
9292
"md5": "^2.3.0",
93-
"moment": "^2.29.0",
93+
"moment": "^2.29.1",
9494
"node-fetch": "^2.6.1",
9595
"object.entries": "^1.1.2",
9696
"object.values": "^1.1.1",
@@ -100,11 +100,10 @@
100100
"safe-memory-cache": "^2.0.0",
101101
"semaphore": "^1.1.0",
102102
"stream-json": "^1.7.1",
103-
"string-builder": "^0.1.6",
104103
"util.promisify": "^1.0.1",
105-
"uuid": "^8.3.0",
104+
"uuid": "^8.3.1",
106105
"verror": "^1.10.0",
107-
"ws": "^7.3.1",
108-
"xregexp": "^4.3.0"
106+
"ws": "^7.4.0",
107+
"xregexp": "^4.4.0"
109108
}
110109
}

src/Documents/BulkInsertOperation.ts

+29-8
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export class BulkInsertOperation {
3131

3232
private _first: boolean = true;
3333
private _operationId = -1;
34+
private _nodeTag: string;
3435

3536
private _useCompression: boolean = false;
3637

@@ -45,6 +46,9 @@ export class BulkInsertOperation {
4546

4647
public constructor(database: string, store: IDocumentStore) {
4748
this._conventions = store.conventions;
49+
if (StringUtil.isNullOrEmpty(database)) {
50+
this._throwNoDatabase();
51+
}
4852
this._requestExecutor = store.getRequestExecutor(database);
4953

5054
this._generateEntityIdOnTheClient = new GenerateEntityIdOnTheClient(this._requestExecutor.conventions,
@@ -65,8 +69,23 @@ export class BulkInsertOperation {
6569
}
6670

6771
private async _throwBulkInsertAborted(e: Error) {
68-
const error = await this._getExceptionFromOperation();
69-
throwError("BulkInsertAbortedException", "Failed to execute bulk insert", error || e);
72+
let errorFromServer: Error;
73+
try {
74+
errorFromServer = await this._getExceptionFromOperation();
75+
} catch (ee) {
76+
// server is probably down, will propagate the original exception
77+
}
78+
79+
if (errorFromServer) {
80+
throw errorFromServer;
81+
}
82+
83+
throwError("BulkInsertAbortedException", "Failed to execute bulk insert", e);
84+
}
85+
86+
private _throwNoDatabase(): void {
87+
throwError("InvalidOperationException", "Cannot start bulk insert operation without specifying a name of a database to operate on."
88+
+ "Database name can be passed as an argument when bulk insert is being created or default database can be defined using 'DocumentStore.setDatabase' method.");
7089
}
7190

7291
private async _waitForId(): Promise<void> {
@@ -77,6 +96,7 @@ export class BulkInsertOperation {
7796
const bulkInsertGetIdRequest = new GetNextOperationIdCommand();
7897
await this._requestExecutor.execute(bulkInsertGetIdRequest);
7998
this._operationId = bulkInsertGetIdRequest.result;
99+
this._nodeTag = bulkInsertGetIdRequest.nodeTag;
80100
}
81101

82102
private static _typeCheckStoreArgs(
@@ -242,7 +262,7 @@ export class BulkInsertOperation {
242262
}
243263

244264
private async _getExceptionFromOperation(): Promise<Error> {
245-
const stateRequest = new GetOperationStateCommand(this._conventions, this._operationId);
265+
const stateRequest = new GetOperationStateCommand(this._conventions, this._operationId, this._nodeTag);
246266
await this._requestExecutor.execute(stateRequest);
247267
if (!stateRequest.result) {
248268
return null;
@@ -263,7 +283,8 @@ export class BulkInsertOperation {
263283

264284
this._requestBodyStream = new stream.PassThrough();
265285
const bulkCommand =
266-
new BulkInsertCommand(this._operationId, this._requestBodyStream, this._useCompression);
286+
new BulkInsertCommand(this._operationId, this._requestBodyStream, this._nodeTag);
287+
bulkCommand.useCompression = this._useCompression;
267288

268289
const bulkCommandPromise = this._requestExecutor.execute(bulkCommand);
269290

@@ -298,7 +319,7 @@ export class BulkInsertOperation {
298319
await this._waitForId();
299320

300321
try {
301-
await this._requestExecutor.execute(new KillOperationCommand(this._operationId));
322+
await this._requestExecutor.execute(new KillOperationCommand(this._operationId, this._nodeTag));
302323
} catch (err) {
303324
const bulkInsertError = getError("BulkInsertAbortedException",
304325
"Unable to kill bulk insert operation, because it was not found on the server.", err);
@@ -365,14 +386,14 @@ export class BulkInsertCommand extends RavenCommand<void> {
365386

366387
private readonly _stream: stream.Readable;
367388
private readonly _id: number;
368-
private _useCompression: boolean;
389+
public useCompression: boolean;
369390

370-
public constructor(id: number, stream: stream.Readable, useCompression: boolean) {
391+
public constructor(id: number, stream: stream.Readable, nodeTag: string) {
371392
super();
372393

373394
this._stream = stream;
374395
this._id = id;
375-
this._useCompression = useCompression;
396+
this._selectedNodeTag = nodeTag;
376397
}
377398

378399
public createRequest(node: ServerNode): HttpRequestParameters {

src/Documents/Commands/CreateSubscriptionCommand.ts

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { DocumentConventions } from "../Conventions/DocumentConventions";
77
import { ServerNode } from "../../Http/ServerNode";
88
import { IRaftCommand } from "../../Http/IRaftCommand";
99
import { RaftIdGenerator } from "../../Utility/RaftIdGenerator";
10+
import { throwError } from "../../Exceptions";
1011

1112
export class CreateSubscriptionCommand extends RavenCommand<CreateSubscriptionResult> implements IRaftCommand {
1213
private readonly _conventions: DocumentConventions;
@@ -16,6 +17,9 @@ export class CreateSubscriptionCommand extends RavenCommand<CreateSubscriptionRe
1617
public constructor(conventions: DocumentConventions, options: SubscriptionCreationOptions, id?: string) {
1718
super();
1819
this._conventions = conventions;
20+
if (!options) {
21+
throwError("InvalidArgumentException", "Options cannot be null");
22+
}
1923
this._options = options;
2024
this._id = id;
2125
}

src/Documents/Commands/DropSubscriptionConnectionCommand.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { RavenCommand } from "../../Http/RavenCommand";
22
import { HttpRequestParameters } from "../../Primitives/Http";
33
import { ServerNode } from "../../Http/ServerNode";
4+
import { StringUtil } from "../../Utility/StringUtil";
45

56
export class DropSubscriptionConnectionCommand extends RavenCommand<void> {
67

@@ -12,7 +13,11 @@ export class DropSubscriptionConnectionCommand extends RavenCommand<void> {
1213
}
1314

1415
public createRequest(node: ServerNode): HttpRequestParameters {
15-
const uri = node.url + "/databases/" + node.database + "/subscriptions/drop?name=" + this._name;
16+
let uri = node.url + "/databases/" + node.database + "/subscriptions/drop";
17+
18+
if (!StringUtil.isNullOrEmpty(this._name)) {
19+
uri += "?name=" + encodeURIComponent(this._name);
20+
}
1621

1722
return {
1823
method: "POST",

src/Documents/Commands/GetDocumentsCommand.ts

+1
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ export class GetDocumentsCommand extends RavenCommand<GetDocumentsResult> {
194194
// if it is too big, we fallback to POST (note that means that we can't use the HTTP cache any longer)
195195
// we are fine with that, requests to load > 1024 items are going to be rare
196196
const isGet: boolean = Array.from(uniqueIds)
197+
.filter(x => x)
197198
.map(x => x.length)
198199
.reduce((result, next) => result + next, 0) < 1024;
199200

src/Documents/Commands/GetNextOperationIdCommand.ts

+11
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ import * as stream from "readable-stream";
55

66
export class GetNextOperationIdCommand extends RavenCommand<number> {
77

8+
private _nodeTag: string;
9+
10+
public get nodeTag(): string {
11+
return this._nodeTag;
12+
}
13+
814
public get isReadRequest(): boolean {
915
return false; // disable caching
1016
}
@@ -22,6 +28,11 @@ export class GetNextOperationIdCommand extends RavenCommand<number> {
2228
if (typeof id !== "undefined") {
2329
this.result = id;
2430
}
31+
32+
const nodeTag = results["nodeTag"];
33+
if (nodeTag) {
34+
this._nodeTag = nodeTag;
35+
}
2536
});
2637
return body;
2738
}

src/Documents/Commands/KillOperationCommand.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,19 @@ export class KillOperationCommand extends RavenCommand<void> {
77

88
private readonly _id: number;
99

10-
public constructor(id: number) {
10+
public constructor(id: number)
11+
public constructor(id: number, nodeTag: string)
12+
public constructor(id: number, nodeTag?: string) {
1113
super();
1214

1315
if (!id) {
1416
throwError("InvalidArgumentException", "Id cannot be null.");
1517
}
1618
this._id = id;
19+
20+
if (nodeTag) {
21+
this._selectedNodeTag = nodeTag;
22+
}
1723
}
1824

1925
public get isReadRequest(): boolean {

src/Documents/Commands/MultiGet/MultiGetCommand.ts

+10
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { ServerNode } from "../../../Http/ServerNode";
88
import { StatusCodes } from "../../../Http/StatusCode";
99
import { getEtagHeader } from "../../../Utility/HttpUtil";
1010
import { DocumentConventions } from "../../Conventions/DocumentConventions";
11+
import { throwError } from "../../../Exceptions";
1112

1213
export class MultiGetCommand extends RavenCommand<GetResponse[]> {
1314
private _cache: HttpCache;
@@ -17,6 +18,15 @@ export class MultiGetCommand extends RavenCommand<GetResponse[]> {
1718

1819
public constructor(cache: HttpCache, conventions: DocumentConventions, commands: GetRequest[]) {
1920
super();
21+
22+
if (!cache) {
23+
throwError("InvalidArgumentException", "Cache cannot be null");
24+
}
25+
26+
if (!commands) {
27+
throwError("InvalidArgumentException", "Commands cannot be null");
28+
}
29+
2030
this._cache = cache;
2131
this._commands = commands;
2232
this._conventions = conventions;

src/Documents/Commands/QueryCommand.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import { DocumentConventions } from "../Conventions/DocumentConventions";
55
import { IndexQuery, writeIndexQuery } from "../Queries/IndexQuery";
66
import { throwError } from "../../Exceptions";
77
import { ServerNode } from "../../Http/ServerNode";
8-
import * as StringBuilder from "string-builder";
98
import { JsonSerializer } from "../../Mapping/Json/Serializer";
109
import * as stream from "readable-stream";
1110
import { RavenCommandResponsePipeline } from "../../Http/RavenCommandResponsePipeline";
11+
import { StringBuilder } from "../../Utility/StringBuilder";
1212

1313
export interface QueryCommandOptions {
1414
metadataOnly?: boolean;

src/Documents/Indexes/IndexDefinitionHelper.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { throwError } from "../../Exceptions/index";
33
import { StringUtil } from "../../Utility/StringUtil";
44
import * as XRegExp from "xregexp";
55

6-
const COMMENT_REGEX = new XRegExp("(?:/\\*(?:[^*]|(?:\\*+[^*/]))*\\*+/)|(?://.*)", "gm");
6+
const COMMENT_REGEX = XRegExp("(?:/\\*(?:[^*]|(?:\\*+[^*/]))*\\*+/)|(?://.*)", "gm");
77

88
export class IndexDefinitionHelper {
99
public static detectStaticIndexType(map: string, reduce: string): IndexType {

src/Documents/Operations/Backups/RestoreBackupOperation.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { DocumentConventions } from "../../Conventions/DocumentConventions";
55
import { RavenCommand } from "../../../Http/RavenCommand";
66
import { ServerNode } from "../../../Http/ServerNode";
77
import { RestoreBackupConfigurationBase } from "./RestoreBackupConfigurationBase";
8+
import { throwError } from "../../../Exceptions";
89

910
export class RestoreBackupOperation implements IServerOperation<OperationIdResult> {
1011
private readonly _restoreConfiguration: RestoreBackupConfigurationBase;
@@ -16,7 +17,7 @@ export class RestoreBackupOperation implements IServerOperation<OperationIdResul
1617
}
1718

1819
public getCommand(conventions: DocumentConventions): RavenCommand<OperationIdResult> {
19-
return new RestoreBackupCommand(conventions, this._restoreConfiguration, this._nodeTag);
20+
return new RestoreBackupCommand(this._restoreConfiguration, this._nodeTag);
2021
}
2122

2223
public get resultType(): OperationResultType {
@@ -31,9 +32,13 @@ export class RestoreBackupOperation implements IServerOperation<OperationIdResul
3132
class RestoreBackupCommand extends RavenCommand<OperationIdResult> {
3233
private readonly _restoreConfiguration: RestoreBackupConfigurationBase;
3334

34-
public constructor(conventions: DocumentConventions, restoreConfiguration: RestoreBackupConfigurationBase, nodeTag: string) {
35+
public constructor(restoreConfiguration: RestoreBackupConfigurationBase, nodeTag: string) {
3536
super();
3637

38+
if (!restoreConfiguration) {
39+
throwError("InvalidArgumentException", "RestoreConfiguration cannot be null");
40+
}
41+
3742
this._restoreConfiguration = restoreConfiguration;
3843
this._selectedNodeTag = nodeTag;
3944
}

src/Documents/Operations/Backups/UpdatePeriodicBackupOperation.ts

+2-4
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,16 @@ export class UpdatePeriodicBackupOperation implements IMaintenanceOperation<Upda
2121
}
2222

2323
public getCommand(conventions: DocumentConventions): RavenCommand<UpdatePeriodicBackupOperationResult> {
24-
return new UpdatePeriodicBackupCommand(conventions, this._configuration);
24+
return new UpdatePeriodicBackupCommand(this._configuration);
2525
}
2626
}
2727

2828
class UpdatePeriodicBackupCommand extends RavenCommand<UpdatePeriodicBackupOperationResult> implements IRaftCommand {
29-
private readonly _conventions: DocumentConventions;
3029
private readonly _configuration: PeriodicBackupConfiguration;
3130

32-
public constructor(conventions: DocumentConventions, configuration: PeriodicBackupConfiguration) {
31+
public constructor(configuration: PeriodicBackupConfiguration) {
3332
super();
3433

35-
this._conventions = conventions;
3634
this._configuration = configuration;
3735
}
3836

src/Documents/Operations/CompareExchange/GetCompareExchangeValuesOperation.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import * as StringBuilder from "string-builder";
21
import { HttpRequestParameters } from "../../../Primitives/Http";
32
import { IOperation, OperationResultType } from "../OperationAbstractions";
43
import { CompareExchangeValue } from "./CompareExchangeValue";
@@ -11,6 +10,7 @@ import { RavenCommand } from "../../../Http/RavenCommand";
1110
import { ServerNode } from "../../../Http/ServerNode";
1211
import { CompareExchangeValueResultParser, GetCompareExchangeValuesResponse } from "./CompareExchangeValueResultParser";
1312
import * as stream from "readable-stream";
13+
import { StringBuilder } from "../../../Utility/StringBuilder";
1414

1515
export interface GetCompareExchangeValuesParameters<T> {
1616
keys?: string[];

0 commit comments

Comments
 (0)