Skip to content

Commit

Permalink
Remove media files if a media library is removed
Browse files Browse the repository at this point in the history
  • Loading branch information
benmerckx committed Feb 21, 2024
1 parent c52cd9b commit 9a360d1
Show file tree
Hide file tree
Showing 12 changed files with 140 additions and 239 deletions.
22 changes: 21 additions & 1 deletion src/backend/Database.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ test('remove child entries', async () => {
assert.ok(res1)
assert.is(res1.parent, sub.entryId)
await example.commit(Edit.remove(parent.entryId))
const res2 = await example.get(Query.whereId(entry.entryId))
const res2 = await example.maybeGet(Query.whereId(entry.entryId))
assert.not.ok(res2)
})

Expand Down Expand Up @@ -155,4 +155,24 @@ test('field creators', async () => {
})
})

test('remove media library and files', async () => {
const example = createExample()
const {MediaLibrary, MediaFile} = example.schema
const library = Edit.create(MediaLibrary)
.setWorkspace('main')
.setRoot('media')
await example.commit(library)
const upload = Edit.upload([
'test.txt',
new TextEncoder().encode('Hello, World!')
]).setParent(library.entryId)
await example.commit(upload)
const result = await example.get(Query.whereId(upload.entryId))
assert.is(result.parent, library.entryId)
assert.is(result.root, 'media')
await example.commit(Edit.remove(library.entryId))
const result2 = await example.maybeGet(Query.whereId(upload.entryId))
assert.not.ok(result2)
})

test.run()
19 changes: 8 additions & 11 deletions src/backend/Database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {Media} from './Media.js'
import {Source} from './Source.js'
import {Store} from './Store.js'
import {Target} from './Target.js'
import {ChangeSetCreator} from './data/ChangeSet.js'
import {Change, ChangeType} from './data/ChangeSet.js'
import {AlineaMeta} from './db/AlineaMeta.js'
import {createEntrySearch} from './db/CreateEntrySearch.js'
import {JsonLoader} from './loader/JsonLoader.js'
Expand Down Expand Up @@ -711,24 +711,21 @@ export class Database implements Syncable {
})

if (target && publishSeed.length > 0) {
const changeSetCreator = new ChangeSetCreator(this.config)
const mutations = publishSeed.map((seed): Mutation => {
const changes = publishSeed.map((seed): Change => {
const workspace = this.config.workspaces[seed.workspace]
const file = paths.join(
Workspace.data(workspace).source,
seed.root,
seed.filePath
)
return {
type: MutationType.Create,
entryId: seed.entryId,
file: file,
entry: seed
}
const record = createRecord(seed)
const contents = new TextDecoder().decode(
JsonLoader.format(this.config.schema, record)
)
return {type: ChangeType.Write, file, contents}
})
const changes = changeSetCreator.create(mutations)
await target.mutate(
{commitHash: '', mutations: changes},
{commitHash: '', mutations: [{changes, meta: undefined!}]},
{logger: new Logger('seed')}
)
}
Expand Down
8 changes: 6 additions & 2 deletions src/backend/Handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {Draft} from 'alinea/core/Draft'
import {Entry} from 'alinea/core/Entry'
import {EntryRecord} from 'alinea/core/EntryRecord'
import {EntryPhase, EntryRow} from 'alinea/core/EntryRow'
import {Graph} from 'alinea/core/Graph'
import {EditMutation, Mutation, MutationType} from 'alinea/core/Mutation'
import {PreviewUpdate, ResolveRequest, Resolver} from 'alinea/core/Resolver'
import {createSelection} from 'alinea/core/pages/CreateSelection'
Expand Down Expand Up @@ -60,7 +61,10 @@ export class Handler implements Resolver {
options.config.schema,
this.parsePreview.bind(this)
)
this.changes = new ChangeSetCreator(options.config)
this.changes = new ChangeSetCreator(
options.config,
new Graph(options.config, this)
)
const auth = options.auth ?? Auth.anonymous()
this.connect = ctx => new HandlerConnection(this, ctx)
this.router = createRouter(auth, this.connect)
Expand Down Expand Up @@ -153,7 +157,7 @@ class HandlerConnection implements Connection {
): Promise<{commitHash: string}> {
const {target, db} = this.handler.options
if (!target) throw new Error('Target not available')
const changeSet = this.handler.changes.create(mutations)
const changeSet = await this.handler.changes.create(mutations)
const {commitHash: fromCommitHash} = await this.handler.syncPending()
let toCommitHash: string
try {
Expand Down
57 changes: 34 additions & 23 deletions src/backend/data/ChangeSet.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {Config} from 'alinea/core/Config'
import {META_KEY, createRecord} from 'alinea/core/EntryRecord'
import {EntryPhase} from 'alinea/core/EntryRow'
import {Graph} from 'alinea/core/Graph'
import {
ArchiveMutation,
CreateMutation,
Expand All @@ -16,8 +17,10 @@ import {
RemoveEntryMutation,
UploadMutation
} from 'alinea/core/Mutation'
import {EntryUrlMeta, Type} from 'alinea/core/Type'
import {Query} from 'alinea/core/Query'
import {Type} from 'alinea/core/Type'
import {Workspace} from 'alinea/core/Workspace'
import {MediaFile} from 'alinea/core/media/MediaTypes'
import {join} from 'alinea/core/util/Paths'
import {JsonLoader} from '../loader/JsonLoader.js'

Expand Down Expand Up @@ -68,22 +71,7 @@ const decoder = new TextDecoder()
const loader = JsonLoader

export class ChangeSetCreator {
constructor(public config: Config) {}

entryLocation(
{locale, parentPaths, path, phase}: EntryUrlMeta,
extension: string
) {
const segments = (locale ? [locale] : [])
.concat(
parentPaths
.concat(path)
.map(segment => (segment === '' ? 'index' : segment))
)
.join('/')
const phaseSegment = phase === EntryPhase.Published ? '' : `.${phase}`
return (segments + phaseSegment + extension).toLowerCase()
}
constructor(protected config: Config, protected graph: Graph) {}

editChanges({previousFile, file, entry}: EditMutation): Array<Change> {
const type = this.config.schema[entry.type]
Expand Down Expand Up @@ -160,10 +148,32 @@ export class ChangeSetCreator {
]
}

removeChanges({file}: RemoveEntryMutation): Array<Change> {
async removeChanges({
entryId,
file
}: RemoveEntryMutation): Promise<Array<Change>> {
if (!file.endsWith(`.${EntryPhase.Archived}.json`)) return []
const {workspace, files} = await this.graph.preferPublished.get(
Query.whereId(entryId).select({
workspace: Query.workspace,
files: Query.children(MediaFile, 999)
})
)
const mediaDir =
Workspace.data(this.config.workspaces[workspace])?.mediaDir ?? ''
const removeFiles: Array<Change> = files.map(file => {
const binaryLocation = join(mediaDir, file.location)
return {
type: ChangeType.Delete,
file: binaryLocation
}
})
return [
// Remove any media files in this location
...removeFiles,
// Remove entry
{type: ChangeType.Delete, file},
// Remove children
{
type: ChangeType.Delete,
file: file.slice(0, -`.${EntryPhase.Archived}.json`.length)
Expand Down Expand Up @@ -224,7 +234,7 @@ export class ChangeSetCreator {
return [{type: ChangeType.Delete, file: mutation.file}, removeBinary]
}

mutationChanges(mutation: Mutation): Array<Change> {
async mutationChanges(mutation: Mutation): Promise<Array<Change>> {
switch (mutation.type) {
case MutationType.Edit:
return this.editChanges(mutation)
Expand All @@ -251,9 +261,10 @@ export class ChangeSetCreator {
}
}

create(mutations: Array<Mutation>): ChangeSet {
return mutations.map(meta => {
return {changes: this.mutationChanges(meta), meta}
})
async create(mutations: Array<Mutation>): Promise<ChangeSet> {
const res = []
for (const meta of mutations)
res.push({changes: await this.mutationChanges(meta), meta})
return res
}
}
187 changes: 0 additions & 187 deletions src/backend/data/ChangeSet.ts_

This file was deleted.

Loading

0 comments on commit 9a360d1

Please sign in to comment.