@@ -5,7 +5,12 @@ import { GenerateAlphaNumericPassword } from 'src/utils/random'
5
5
import { MongoService } from './mongo.service'
6
6
import * as mongodb_uri from 'mongodb-uri'
7
7
import { RegionService } from 'src/region/region.service'
8
- import { TASK_LOCK_INIT_TIME } from 'src/constants'
8
+ import {
9
+ CN_PUBLISHED_CONF ,
10
+ CN_PUBLISHED_FUNCTIONS ,
11
+ CN_PUBLISHED_WEBSITE_HOSTING ,
12
+ TASK_LOCK_INIT_TIME ,
13
+ } from 'src/constants'
9
14
import { Region } from 'src/region/entities/region'
10
15
import { SystemDatabase } from '../system-database'
11
16
import {
@@ -18,6 +23,9 @@ import { exec } from 'node:child_process'
18
23
import { promisify } from 'node:util'
19
24
import { DatabaseSyncRecord } from './entities/database-sync-record'
20
25
import { MongoClient , ObjectId } from 'mongodb'
26
+ import { DedicatedDatabaseService } from './dedicated-database/dedicated-database.service'
27
+ import { CloudFunction } from 'src/function/entities/cloud-function'
28
+ import { ApplicationConfiguration } from 'src/application/entities/application-configuration'
21
29
22
30
const p_exec = promisify ( exec )
23
31
@@ -29,6 +37,7 @@ export class DatabaseService {
29
37
constructor (
30
38
private readonly mongoService : MongoService ,
31
39
private readonly regionService : RegionService ,
40
+ private readonly dedicatedDatabaseService : DedicatedDatabaseService ,
32
41
) { }
33
42
34
43
async create ( appid : string ) {
@@ -226,11 +235,31 @@ export class DatabaseService {
226
235
227
236
async exportDatabase ( appid : string , filePath : string , uid : ObjectId ) {
228
237
const region = await this . regionService . findByAppId ( appid )
229
- const database = await this . findOne ( appid )
230
- assert ( database , 'Database not found' )
238
+ const sharedDatabase = await this . findOne ( appid )
239
+ const dedicatedDatabase = await this . dedicatedDatabaseService . findOne ( appid )
231
240
232
- const connectionUri = this . getControlConnectionUri ( region , database )
233
- assert ( connectionUri , 'Database connection uri not found' )
241
+ if ( sharedDatabase && dedicatedDatabase ) {
242
+ throw new Error (
243
+ `Database ${ appid } found in both shared and dedicated databases.` ,
244
+ )
245
+ }
246
+
247
+ if ( ! sharedDatabase && ! dedicatedDatabase ) {
248
+ throw new Error (
249
+ `Database ${ appid } not found in both shared and dedicated databases.` ,
250
+ )
251
+ }
252
+ let connectionUri
253
+ if ( sharedDatabase ) {
254
+ connectionUri = this . getControlConnectionUri ( region , sharedDatabase )
255
+ } else {
256
+ connectionUri = await this . dedicatedDatabaseService . getConnectionUri (
257
+ region ,
258
+ dedicatedDatabase ,
259
+ )
260
+ }
261
+
262
+ assert ( connectionUri , `Database ${ appid } connection uri not found` )
234
263
235
264
try {
236
265
await p_exec (
@@ -252,16 +281,39 @@ export class DatabaseService {
252
281
uid : ObjectId ,
253
282
) : Promise < void > {
254
283
const region = await this . regionService . findByAppId ( appid )
255
- const database = await this . findOne ( appid )
256
- assert ( database , 'Database not found' )
257
284
258
- const connectionUri = this . getControlConnectionUri ( region , database )
259
- assert ( connectionUri , 'Database connection uri not found' )
285
+ const sharedDatabase = await this . findOne ( appid )
286
+ const dedicatedDatabase = await this . dedicatedDatabaseService . findOne ( appid )
287
+
288
+ if ( sharedDatabase && dedicatedDatabase ) {
289
+ throw new Error (
290
+ `Database ${ appid } found in both shared and dedicated databases.` ,
291
+ )
292
+ }
293
+
294
+ if ( ! sharedDatabase && ! dedicatedDatabase ) {
295
+ throw new Error (
296
+ `Database ${ appid } not found in both shared and dedicated databases.` ,
297
+ )
298
+ }
299
+ let connectionUri
300
+ if ( sharedDatabase ) {
301
+ connectionUri = this . getControlConnectionUri ( region , sharedDatabase )
302
+ } else {
303
+ connectionUri = await this . dedicatedDatabaseService . getConnectionUri (
304
+ region ,
305
+ dedicatedDatabase ,
306
+ )
307
+ }
308
+ assert ( connectionUri , `Database ${ appid } connection uri not found` )
260
309
261
310
try {
262
311
await p_exec (
263
312
`mongorestore --uri='${ connectionUri } ' --gzip --archive='${ filePath } ' --nsFrom="${ dbName } .*" --nsTo="${ appid } .*" -v --nsInclude="${ dbName } .*"` ,
264
313
)
314
+
315
+ await this . recoverFunctionsToSystemDatabase ( appid , uid )
316
+
265
317
await this . db
266
318
. collection < DatabaseSyncRecord > ( 'DatabaseSyncRecord' )
267
319
. insertOne ( { uid, createdAt : new Date ( ) } )
@@ -271,4 +323,54 @@ export class DatabaseService {
271
323
throw error
272
324
}
273
325
}
326
+
327
+ async recoverFunctionsToSystemDatabase ( appid : string , uid : ObjectId ) {
328
+ const { db, client } =
329
+ ( await this . dedicatedDatabaseService . findAndConnect ( appid ) ) ||
330
+ ( await this . findAndConnect ( appid ) )
331
+
332
+ try {
333
+ const appFunctionCollection = db . collection ( CN_PUBLISHED_FUNCTIONS )
334
+ const appConfCollection = db . collection ( CN_PUBLISHED_CONF )
335
+ const appWebsiteCollection = db . collection ( CN_PUBLISHED_WEBSITE_HOSTING )
336
+
337
+ const functionsExist = await this . db
338
+ . collection < CloudFunction > ( 'CloudFunction' )
339
+ . countDocuments ( { appid } )
340
+
341
+ if ( functionsExist ) {
342
+ this . logger . debug ( `${ appid } Functions already exist in system database` )
343
+ return
344
+ }
345
+
346
+ const funcs : CloudFunction [ ] = await appFunctionCollection
347
+ . find < CloudFunction > ( { } )
348
+ . toArray ( )
349
+
350
+ if ( funcs . length === 0 ) {
351
+ this . logger . debug ( ` ${ appid } No functions for recover.` )
352
+ return
353
+ }
354
+
355
+ funcs . forEach ( ( func ) => {
356
+ delete func . _id
357
+ func . appid = appid
358
+ func . createdBy = uid
359
+ } )
360
+
361
+ await this . db . collection < CloudFunction > ( 'CloudFunction' ) . insertMany ( funcs )
362
+
363
+ // sync conf
364
+ const conf = await this . db
365
+ . collection < ApplicationConfiguration > ( 'ApplicationConfiguration' )
366
+ . findOne ( { appid } )
367
+
368
+ await appConfCollection . deleteMany ( { } )
369
+ await appConfCollection . insertOne ( conf )
370
+
371
+ await appWebsiteCollection . deleteMany ( { } )
372
+ } finally {
373
+ await client . close ( )
374
+ }
375
+ }
274
376
}
0 commit comments