mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2025-12-13 07:45:56 +00:00
Add migration to merge duplicate Locations
- having duplicate Location nodes in the production database blocks us from adding a unique constraint, so that Locations are not created which have the same id.
This commit is contained in:
parent
a86b26a756
commit
561889c530
@ -35,7 +35,7 @@ class Store {
|
||||
const session = driver.session()
|
||||
const readTxResultPromise = session.readTransaction(async txc => {
|
||||
const result = await txc.run(
|
||||
'MATCH (migration:Migration) RETURN migration {.*} ORDER BY migration.timestamp DESC',
|
||||
'MATCH (migration:Migration) RETURN migration {.*} ORDER BY migration.createdAt DESC',
|
||||
)
|
||||
return result.records.map(r => r.get('migration'))
|
||||
})
|
||||
@ -64,12 +64,19 @@ class Store {
|
||||
const { migrations } = set
|
||||
const writeTxResultPromise = session.writeTransaction(txc => {
|
||||
return Promise.all(
|
||||
migrations.map(migration => {
|
||||
const { title, description, timestamp } = migration
|
||||
const properties = { title, description, timestamp }
|
||||
return txc.run('CREATE (migration:Migration) SET migration += $properties', {
|
||||
properties,
|
||||
})
|
||||
migrations.map(async migration => {
|
||||
const { title, description } = migration
|
||||
const properties = { title, description }
|
||||
const migrationResult = await txc.run(
|
||||
`
|
||||
MERGE (migration:Migration { title: $properties.title })
|
||||
ON CREATE SET migration += $properties,
|
||||
migration.createdAt = toString(datetime())
|
||||
RETURN migration
|
||||
`,
|
||||
{ properties },
|
||||
)
|
||||
return migrationResult
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
@ -0,0 +1,77 @@
|
||||
import { throwError, concat } from 'rxjs'
|
||||
import { flatMap, mergeMap, map, catchError } from 'rxjs/operators'
|
||||
import { getDriver } from '../neo4j'
|
||||
|
||||
export const description = `
|
||||
This migration merges duplicate :Location nodes. It became
|
||||
necessary after we realized that we had not set up constraints for Location.id in production.
|
||||
`
|
||||
export function up(next) {
|
||||
const driver = getDriver()
|
||||
const rxSession = driver.rxSession()
|
||||
rxSession
|
||||
.beginTransaction()
|
||||
.pipe(
|
||||
flatMap(transaction =>
|
||||
concat(
|
||||
transaction
|
||||
.run(
|
||||
`
|
||||
MATCH (location:Location)
|
||||
RETURN location {.id}
|
||||
`,
|
||||
)
|
||||
.records()
|
||||
.pipe(
|
||||
map(record => {
|
||||
const { id: locationIds } = record.get('location')
|
||||
return { locationIds }
|
||||
}),
|
||||
mergeMap(({ locationIds }) => {
|
||||
return transaction
|
||||
.run(
|
||||
`
|
||||
MATCH(location:Location {id: $locationIds}), (location2:Location {id: $locationIds})
|
||||
WHERE location.id = location2.id AND id(location) < id(location2)
|
||||
CALL apoc.refactor.mergeNodes([location, location2], { properties: 'combine', mergeRels: true }) YIELD node as updatedLocation
|
||||
RETURN location {.*},updatedLocation {.*}
|
||||
`,
|
||||
{ locationIds },
|
||||
)
|
||||
.records()
|
||||
.pipe(
|
||||
map(record => ({
|
||||
location: record.get('location'),
|
||||
updatedLocation: record.get('updatedLocation'),
|
||||
})),
|
||||
)
|
||||
}),
|
||||
),
|
||||
transaction.commit(),
|
||||
).pipe(catchError(error => transaction.rollback().pipe(throwError(error)))),
|
||||
),
|
||||
)
|
||||
.subscribe({
|
||||
next: ({ updatedLocation, location }) =>
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`
|
||||
Merged:
|
||||
=============================
|
||||
locationId: ${location.id}
|
||||
updatedLocation: ${location.id} => ${updatedLocation.id}
|
||||
=============================
|
||||
`),
|
||||
complete: () => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Merging of duplicate locations completed')
|
||||
next()
|
||||
},
|
||||
error: error => {
|
||||
next(new Error(error), null)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export function down(next) {
|
||||
next(new Error('Irreversible migration'))
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user