@toa.io/storages.mongodb 1.0.0-alpha.0 → 1.0.0-alpha.3
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/package.json +8 -7
- package/src/connection.js +18 -10
- package/src/storage.js +2 -2
- package/test/connection.test.js +58 -0
- package/types/connection.d.ts +16 -14
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toa.io/storages.mongodb",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.3",
|
|
4
4
|
"description": "Toa MongoDB Storage Connector",
|
|
5
5
|
"author": "temich <tema.gurtovoy@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/toa-io/toa#readme",
|
|
@@ -19,12 +19,13 @@
|
|
|
19
19
|
"test": "echo \"Error: run tests from root\" && exit 1"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@toa.io/console": "1.0.0-alpha.
|
|
23
|
-
"@toa.io/
|
|
24
|
-
"@toa.io/
|
|
25
|
-
"@toa.io/
|
|
26
|
-
"
|
|
22
|
+
"@toa.io/console": "1.0.0-alpha.3",
|
|
23
|
+
"@toa.io/conveyor": "1.0.0-alpha.3",
|
|
24
|
+
"@toa.io/core": "1.0.0-alpha.3",
|
|
25
|
+
"@toa.io/generic": "1.0.0-alpha.3",
|
|
26
|
+
"@toa.io/pointer": "1.0.0-alpha.3",
|
|
27
|
+
"mongodb": "6.3.0",
|
|
27
28
|
"saslprep": "1.0.3"
|
|
28
29
|
},
|
|
29
|
-
"gitHead": "
|
|
30
|
+
"gitHead": "e36ac7871fc14d15863aaf8f9bbdeace8bdfa9f0"
|
|
30
31
|
}
|
package/src/connection.js
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
const { MongoClient } = require('mongodb')
|
|
6
6
|
const { Connector } = require('@toa.io/core')
|
|
7
|
-
const { console } = require('@toa.io/console')
|
|
8
7
|
const { resolve } = require('@toa.io/pointer')
|
|
8
|
+
const { Conveyor } = require('@toa.io/conveyor')
|
|
9
9
|
const { ID } = require('./deployment')
|
|
10
10
|
|
|
11
11
|
class Connection extends Connector {
|
|
@@ -14,6 +14,8 @@ class Connection extends Connector {
|
|
|
14
14
|
#client
|
|
15
15
|
/** @type {import('mongodb').Collection<toa.mongodb.Record>} */
|
|
16
16
|
#collection
|
|
17
|
+
/** @type {toa.conveyor.Conveyor<toa.core.storages.Record, boolean>} */
|
|
18
|
+
#conveyor
|
|
17
19
|
|
|
18
20
|
constructor (locator) {
|
|
19
21
|
super()
|
|
@@ -31,14 +33,15 @@ class Connection extends Connector {
|
|
|
31
33
|
await this.#client.connect()
|
|
32
34
|
|
|
33
35
|
this.#collection = this.#client.db(db).collection(collection)
|
|
36
|
+
this.#conveyor = new Conveyor((objects) => this.addMany(objects))
|
|
34
37
|
|
|
35
|
-
console.info(
|
|
38
|
+
console.info(`Storage Mongo '${this.#locator.id}' connected`)
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
async close () {
|
|
39
42
|
await this.#client?.close()
|
|
40
43
|
|
|
41
|
-
console.info(
|
|
44
|
+
console.info(`Storage Mongo '${this.#locator.id}' disconnected`)
|
|
42
45
|
}
|
|
43
46
|
|
|
44
47
|
/** @hot */
|
|
@@ -48,22 +51,25 @@ class Connection extends Connector {
|
|
|
48
51
|
|
|
49
52
|
/** @hot */
|
|
50
53
|
async find (query, options) {
|
|
51
|
-
const cursor =
|
|
54
|
+
const cursor = this.#collection.find(query, options)
|
|
52
55
|
|
|
53
56
|
return cursor.toArray()
|
|
54
57
|
}
|
|
55
58
|
|
|
56
59
|
/** @hot */
|
|
57
60
|
async add (record) {
|
|
58
|
-
|
|
61
|
+
return this.#conveyor.process(record)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async addMany (records) {
|
|
59
65
|
let result
|
|
60
66
|
|
|
61
67
|
try {
|
|
62
|
-
const response = await this.#collection.
|
|
68
|
+
const response = await this.#collection.insertMany(records, { ordered: false })
|
|
63
69
|
|
|
64
70
|
result = response.acknowledged
|
|
65
71
|
} catch (e) {
|
|
66
|
-
if (e.code ===
|
|
72
|
+
if (e.code === ERR_DUPLICATE_KEY) result = false
|
|
67
73
|
else throw e
|
|
68
74
|
}
|
|
69
75
|
|
|
@@ -87,9 +93,11 @@ class Connection extends Connector {
|
|
|
87
93
|
}
|
|
88
94
|
|
|
89
95
|
const OPTIONS = {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
96
|
+
ignoreUndefined: true,
|
|
97
|
+
connectTimeoutMS: 0,
|
|
98
|
+
serverSelectionTimeoutMS: 0
|
|
93
99
|
}
|
|
94
100
|
|
|
101
|
+
const ERR_DUPLICATE_KEY = 11000
|
|
102
|
+
|
|
95
103
|
exports.Connection = Connection
|
package/src/storage.js
CHANGED
|
@@ -48,7 +48,7 @@ class Storage extends Connector {
|
|
|
48
48
|
const criteria = { _id: entity.id, _version: entity._version }
|
|
49
49
|
const result = await this.#connection.replace(criteria, to(entity))
|
|
50
50
|
|
|
51
|
-
return result
|
|
51
|
+
return result !== null
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
async store (entity) {
|
|
@@ -75,7 +75,7 @@ class Storage extends Connector {
|
|
|
75
75
|
|
|
76
76
|
const result = await this.#connection.update(criteria, update, options)
|
|
77
77
|
|
|
78
|
-
return from(result
|
|
78
|
+
return from(result)
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const insertManyMock = jest.fn(() => ({ acknowledged: true }))
|
|
4
|
+
jest.mock('mongodb', () => ({
|
|
5
|
+
__esModule: true,
|
|
6
|
+
MongoClient: function () {
|
|
7
|
+
this.connect = () => {},
|
|
8
|
+
this.db = () => ({
|
|
9
|
+
collection: () => ({
|
|
10
|
+
insertMany: insertManyMock
|
|
11
|
+
})
|
|
12
|
+
})
|
|
13
|
+
return this
|
|
14
|
+
},
|
|
15
|
+
}))
|
|
16
|
+
jest.mock('@toa.io/pointer', () => ({
|
|
17
|
+
__esModule: true,
|
|
18
|
+
resolve: () => ['url'],
|
|
19
|
+
}))
|
|
20
|
+
const { generate } = require('randomstring')
|
|
21
|
+
const { Connection } = require('../src/connection')
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
let connection
|
|
25
|
+
|
|
26
|
+
beforeEach(async () => {
|
|
27
|
+
jest.clearAllMocks()
|
|
28
|
+
connection = new Connection({ id: 1 })
|
|
29
|
+
await connection.open()
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('should be', () => {
|
|
33
|
+
expect(Connection).toBeDefined()
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it('should insert', async () => {
|
|
37
|
+
const object = generate()
|
|
38
|
+
|
|
39
|
+
await connection.add(object)
|
|
40
|
+
|
|
41
|
+
expect(insertManyMock).toHaveBeenCalledWith([object], { ordered: false })
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
it('should batch insert', async () => {
|
|
45
|
+
const a = generate()
|
|
46
|
+
const b = generate()
|
|
47
|
+
const c = generate()
|
|
48
|
+
|
|
49
|
+
await Promise.all([
|
|
50
|
+
connection.add(a),
|
|
51
|
+
connection.add(b),
|
|
52
|
+
connection.add(c)
|
|
53
|
+
])
|
|
54
|
+
|
|
55
|
+
expect(insertManyMock).toHaveBeenCalledTimes(2)
|
|
56
|
+
expect(insertManyMock).toHaveBeenNthCalledWith(1, [a], { ordered: false })
|
|
57
|
+
expect(insertManyMock).toHaveBeenNthCalledWith(2, [b, c], { ordered: false })
|
|
58
|
+
})
|
package/types/connection.d.ts
CHANGED
|
@@ -1,29 +1,31 @@
|
|
|
1
1
|
// noinspection ES6UnusedImports
|
|
2
2
|
|
|
3
3
|
import type {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
Document,
|
|
5
|
+
Filter,
|
|
6
|
+
FindOneAndReplaceOptions,
|
|
7
|
+
FindOneAndUpdateOptions,
|
|
8
|
+
FindOptions,
|
|
9
|
+
UpdateFilter,
|
|
10
10
|
} from 'mongodb'
|
|
11
11
|
|
|
12
12
|
import type { Connector } from '@toa.io/core'
|
|
13
13
|
import type { Record } from './record'
|
|
14
14
|
|
|
15
|
-
declare namespace toa.mongodb
|
|
15
|
+
declare namespace toa.mongodb{
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
interface Connection extends Connector{
|
|
18
|
+
get (query: Filter<Record>, options?: FindOptions<Record>): Promise<Record>
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
find (query: Filter<Record>, options?: FindOptions<Record>): Promise<Record[]>
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
add (record: Record): Promise<boolean>
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
addMany (records: Record[]): Promise<boolean>
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
replace (query: Filter<Record>, record: UpdateFilter<Record>, options?: FindOneAndReplaceOptions): Promise<any>
|
|
27
|
+
|
|
28
|
+
update (query: Filter<Record>, update: UpdateFilter<Record>, options?: FindOneAndUpdateOptions): Promise<any>
|
|
29
|
+
}
|
|
28
30
|
|
|
29
31
|
}
|