1
1
import { Injectable } from '@nestjs/common' ;
2
2
import { inArray , node , or , Query , relation } from 'cypher-query-builder' ;
3
- import { Except , RequireAtLeastOne } from 'type-fest' ;
4
- import { ID , ServerException } from '~/common' ;
3
+ import { RequireAtLeastOne } from 'type-fest' ;
4
+ import { EnhancedResource , generateId , ID , ServerException } from '~/common' ;
5
5
import { CommonRepository } from '~/core' ;
6
- import {
7
- ACTIVE ,
8
- apoc ,
9
- createNode ,
10
- createRelationships ,
11
- merge ,
12
- variable ,
13
- } from '~/core/database/query' ;
14
- import { AnyMedia , Media , MediaUserMetadata , resolveMedia } from './media.dto' ;
6
+ import { ACTIVE , apoc , merge } from '~/core/database/query' ;
7
+ import { AnyMedia , MediaUserMetadata , resolveMedia } from './media.dto' ;
15
8
16
9
@Injectable ( )
17
10
export class MediaRepository extends CommonRepository {
@@ -50,19 +43,33 @@ export class MediaRepository extends CommonRepository {
50
43
) ;
51
44
}
52
45
53
- async create ( input : Except < AnyMedia , 'id' > ) {
46
+ async save (
47
+ input : RequireAtLeastOne < Pick < AnyMedia , 'id' | 'file' > > & Partial < AnyMedia > ,
48
+ ) {
49
+ const res = input . __typename
50
+ ? EnhancedResource . of ( resolveMedia ( input as AnyMedia ) )
51
+ : undefined ;
54
52
const query = this . db
55
53
. query ( )
56
- . matchNode ( 'fv' , 'FileVersion' , { id : input . file } )
57
- . apply (
58
- await createNode ( resolveMedia ( input ) , {
59
- baseNodeProps : toDbShape ( input ) ,
60
- } ) ,
61
- )
62
- . apply (
63
- createRelationships ( Media , 'in' , {
64
- media : variable ( 'fv' ) ,
65
- } ) ,
54
+ . merge ( [
55
+ node ( 'fv' , 'FileVersion' , input . file ? { id : input . file } : { } ) ,
56
+ relation ( 'out' , '' , 'media' ) ,
57
+ node ( 'node' , 'Media' , input . id ? { id : input . id } : { } ) ,
58
+ ] )
59
+ . onCreate . set ( {
60
+ values : { 'node.id' : await generateId ( ) } ,
61
+ variables : { 'node.createdAt' : 'datetime()' } ,
62
+ } )
63
+ . setValues ( { node : toDbShape ( input ) } , true )
64
+ . with ( 'node, fv' )
65
+ // Update the labels if typename is given, and maybe changed.
66
+ . apply ( ( q ) =>
67
+ res
68
+ ? q . raw (
69
+ 'CALL apoc.create.setLabels(node, $newLabels) yield node as labelsAdded' ,
70
+ { newLabels : res . dbLabels } ,
71
+ )
72
+ : q ,
66
73
)
67
74
// Grab the previous media node or null
68
75
. subQuery ( 'fv' , ( sub ) =>
@@ -81,7 +88,7 @@ export class MediaRepository extends CommonRepository {
81
88
] )
82
89
. return ( 'prevMedia' )
83
90
. orderBy ( 'fvs.createdAt' , 'DESC' )
84
- . limit ( 1 ) ,
91
+ . raw ( 'LIMIT 1' ) ,
85
92
)
86
93
// Use previous user metadata as defaults for new media
87
94
. with ( 'node, fv, prevMedia' )
@@ -100,26 +107,6 @@ export class MediaRepository extends CommonRepository {
100
107
)
101
108
. apply ( this . hydrate ( ) ) ;
102
109
103
- const result = await query . first ( ) ;
104
- if ( ! result ) {
105
- throw new ServerException ( 'Failed to create media info' ) ;
106
- }
107
- return result . dto ;
108
- }
109
-
110
- async update (
111
- input : RequireAtLeastOne < Pick < AnyMedia , 'id' | 'file' > > & Partial < AnyMedia > ,
112
- ) {
113
- const query = this . db
114
- . query ( )
115
- . match ( [
116
- node ( 'fv' , 'FileVersion' , input . file ? { id : input . file } : { } ) ,
117
- relation ( 'out' , '' , 'media' ) ,
118
- node ( 'node' , 'Media' , input . id ? { id : input . id } : { } ) ,
119
- ] )
120
- . setValues ( { node : toDbShape ( input ) } , true )
121
- . apply ( this . hydrate ( ) ) ;
122
-
123
110
const result = await query . first ( ) ;
124
111
if ( ! result ) {
125
112
throw new ServerException ( 'Failed to save media info' ) ;
0 commit comments