Skip to content
This repository was archived by the owner on Apr 4, 2023. It is now read-only.

Commit b2ac41a

Browse files
authored
fix: mongodb connectionURL parse options (typeorm#7560)
1 parent acc7994 commit b2ac41a

File tree

3 files changed

+68
-6
lines changed

3 files changed

+68
-6
lines changed

src/driver/DriverUtils.ts

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,27 @@ export class DriverUtils {
149149
let port = undefined;
150150
let hostReplicaSet = undefined;
151151
let replicaSet = undefined;
152-
// remove mongodb query params
152+
153+
let optionsObject: any = {};
154+
153155
if (afterBase && afterBase.indexOf("?") !== -1) {
154-
// split params to get replica set
156+
157+
// split params
155158
afterQuestionMark = afterBase.substr((afterBase.indexOf("?") + 1), afterBase.length);
156-
replicaSet = afterQuestionMark.split("=")[1];
157159

160+
const optionsList = afterQuestionMark.split("&");
161+
let optionKey: string;
162+
let optionValue: string;
163+
164+
// create optionsObject for merge with connectionUrl object before return
165+
optionsList.forEach(optionItem => {
166+
optionKey = optionItem.split("=")[0];
167+
optionValue = optionItem.split("=")[1];
168+
optionsObject[optionKey] = optionValue;
169+
});
170+
171+
// specific replicaSet value to set options about hostReplicaSet
172+
replicaSet = optionsObject["replicaSet"];
158173
afterBase = afterBase.substr(0, afterBase.indexOf("?"));
159174
}
160175

@@ -170,21 +185,28 @@ export class DriverUtils {
170185
password = usernameAndPassword.substr(firstColon + 1);
171186
}
172187

188+
// If replicaSet have value set It as hostlist, If not set like standalone host
173189
if (replicaSet) {
174190
hostReplicaSet = hostAndPort;
175191
} else {
176192
[host, port] = hostAndPort.split(":");
177193
}
178194

179-
return {
195+
let connectionUrl: any = {
180196
type: type,
181197
host: host,
182198
hostReplicaSet: hostReplicaSet,
183199
username: decodeURIComponent(username),
184200
password: decodeURIComponent(password),
185201
port: port ? parseInt(port) : undefined,
186-
database: afterBase || undefined,
187-
replicaSet: replicaSet || undefined
202+
database: afterBase || undefined
188203
};
204+
205+
// Loop to set every options in connectionUrl to object
206+
for (const [key, value] of Object.entries(optionsObject)) {
207+
connectionUrl[key] = value;
208+
}
209+
210+
return connectionUrl;
189211
}
190212
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import "reflect-metadata";
2+
import { DriverUtils } from "../../../src/driver/DriverUtils"
3+
import { expect } from "chai";
4+
5+
describe("github issues > #7401 MongoDB replica set connection string not support with method \"parseConnectionUrl\" & \"buildConnectionUrl\"", () => {
6+
7+
it("should parse replicaSet and host list in ConnectionUrl", () => {
8+
9+
var options = DriverUtils.buildMongoDBDriverOptions({url: "mongodb://testuser:[email protected]:27017,test-secondary-1.example.com:27017,test-secondary-2.example.com:27017/testdb?replicaSet=testreplicaset"})
10+
11+
expect((options.hostReplicaSet ? options.hostReplicaSet as string : '')).to.equal('test-primary.example.com:27017,test-secondary-1.example.com:27017,test-secondary-2.example.com:27017');
12+
expect((options.username ? options.username as string : '')).to.equal('testuser');
13+
expect((options.password ? options.password as string : '')).to.equal('testpwd');
14+
expect((options.database ? options.database as string : '')).to.equal('testdb');
15+
expect((options.replicaSet ? options.replicaSet as string : '')).to.equal('testreplicaset');
16+
});
17+
18+
});
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import "reflect-metadata";
2+
import { DriverUtils } from "../../../src/driver/DriverUtils"
3+
import { expect } from "chai";
4+
5+
describe("github issues > #7437 MongoDB options never parse in connectionUrl and after my fix was parse incorrect", () => {
6+
7+
it("should parse options in ConnectionUrl", () => {
8+
9+
var options = DriverUtils.buildMongoDBDriverOptions({url: "mongodb://testuser:[email protected]:27017/testdb?retryWrites=true&w=majority&useUnifiedTopology=true"})
10+
11+
expect((options.host ? options.host as string : '')).to.equal('test-primary.example.com');
12+
expect((options.username ? options.username as string : '')).to.equal('testuser');
13+
expect((options.password ? options.password as string : '')).to.equal('testpwd');
14+
expect((options.port ? options.port as number : 0)).to.equal(27017);
15+
expect((options.database ? options.database as string : '')).to.equal('testdb');
16+
17+
expect((options.retryWrites ? options.retryWrites as string : '')).to.equal('true');
18+
expect((options.w ? options.w as string : '')).to.equal('majority');
19+
expect((options.useUnifiedTopology ? options.useUnifiedTopology as string : '')).to.equal('true');
20+
});
21+
22+
});

0 commit comments

Comments
 (0)