Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

Cleanup seeder.ts #7809

Merged
merged 2 commits into from
Mar 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@
"request": "launch",
"type": "node-terminal",
},
{
"command": "npm run prepare-database",
"name": "npm run prepare-database",
"request": "launch",
"type": "node-terminal",
},
{
"command": "npm run dev-taskserver",
"name": "npm run dev-taskserver",
Expand Down
121 changes: 52 additions & 69 deletions packages/server-core/src/seeder.ts
Original file line number Diff line number Diff line change
@@ -1,92 +1,75 @@
import { FeathersService } from '@feathersjs/feathers/lib'
import { Paginated } from '@feathersjs/feathers/lib'
import appRootPath from 'app-root-path'
import { Service } from 'feathers-sequelize'
import fs from 'fs'
import { isEqual } from 'lodash'
import path from 'path'
import { Model, ModelStatic, Op } from 'sequelize'

import { ServicesSeedConfig } from '@etherealengine/common/src/interfaces/ServicesSeedConfig'

import { Application } from '../declarations'
import config from './appconfig'
import { copyDefaultProject, uploadLocalProjectToProvider } from './projects/project/project.class'
import seederConfig from './seeder-config'

async function insertOneByOne(app: Application, config: ServicesSeedConfig) {
const service = app.service(config.path as any) as FeathersService
const templates = config.templates as any[]

const Model = (service as any).Model as ModelStatic<Model>

const templateInsertionPromises = templates.map(
(template) =>
new Promise(async (resolve) => {
const searchTemplate = {}

const uniqueField = Object.values(Model.rawAttributes).find((value: any) => value.unique) as any

if (uniqueField) {
searchTemplate[uniqueField.fieldName] = template[uniqueField.fieldName]
} else {
for (const key of Object.keys(template)) {
if (typeof template[key] !== 'object' && template[key]) {
searchTemplate[key] = template[key]
}
}
}

const result = await service.find({
query: searchTemplate
})
const isSeeded = result.total > 0

let insertionResult: any
if (!isSeeded) insertionResult = await service.create(template)

resolve(insertionResult)
})
)

return Promise.all(templateInsertionPromises)
function matchesTemplateValues(template: any, row: any) {
for (const key of Object.keys(template)) {
if (typeof template[key] !== 'object' && template[key] !== row[key]) return false
}
return true
}

export async function seeder(app: Application, forceRefresh: boolean, prepareDb: boolean) {
if (!forceRefresh && !prepareDb) return

const insertionPromises = seederConfig
.filter((config) => config.path && config.templates)
.map(
(config) =>
new Promise(async (resolve) => {
if (config.insertSingle) {
resolve(await insertOneByOne(app, config))
return
}

const templates = config.templates as any[]

const Model = app.service(config.path as any).Model as ModelStatic<Model>
const insertionPromises = seederConfig.map(async (config) => {
if (!config.path || !config.templates) return

const rows = await Model.findAll({
where: {
[Op.or]: templates
},
attributes: Object.keys(templates.at(0)),
raw: true
})
const service = app.service(config.path as any) as Service

const templatesToBeInserted = templates.filter(
(template) => rows.findIndex((row) => isEqual(row, template)) === -1
)

const service = app.service(config.path as any) as FeathersService
// setting tables only need to be seeded once
if (config.path?.endsWith('setting')) {
const result = (await service.find()) as Paginated<any>
const isSeeded = result.total > 0
if (isSeeded) return
}

resolve(await service.create(templatesToBeInserted))
})
)
const searchTemplates = config.templates?.map((template) => {
if (template.id) return { id: template.id }
else return template
})

const results = (await service.find({
query: { $or: searchTemplates },
paginate: {
// @ts-ignore - https://github.com/feathersjs/feathers/issues/3129
default: 1000,
max: 1000
}
})) as Paginated<unknown>

const templatesToBeInserted = config.templates.filter((template) => {
return (
results.data.findIndex((row) => {
return matchesTemplateValues(template, row)
}) === -1
)
})

if (!templatesToBeInserted.length) return

console.log('inerserting templates', templatesToBeInserted)

if (config.insertSingle) {
// NOTE: some of our services do not follow standard feathers service conventions,
// and break when passed an array of objects to the create method
return Promise.all(templatesToBeInserted.map((template) => service.create(template)))
} else {
return service.create(templatesToBeInserted)
}
})

await Promise.all(insertionPromises)

console.log('seeder done')

if (forceRefresh) {
// for local dev clear the storage provider
if (!config.kubernetes.enabled && !config.testEnabled) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const clientSeed = {
shortTitle: process.env.APP_TITLE,
startPath: '/',
releaseName: process.env.RELEASE_NAME || 'local',
siteDescription: process.env.SITE_DESC,
siteDescription: process.env.SITE_DESC || 'Ethereal Engine',
url:
process.env.APP_URL ||
(process.env.VITE_LOCAL_BUILD
Expand Down