@@ -240,6 +240,22 @@ function getObjectOrInterfaceFields(type) {
240
240
return keys ;
241
241
}
242
242
243
+ /**
244
+ * Transforms the doc (field_name, field_value) collection to JSON stringify, strip leading and ending '{' and '}' and insert leading ', '
245
+ * This allows docs to be appanded to already existing input parameters.
246
+ * @param doc (should already have passed through getScalarsAndEnums)
247
+ * @returns String
248
+ */
249
+ function convertToInputAppendString ( doc ) {
250
+ ret = ''
251
+ if ( doc != null && doc . size > 0 ) {
252
+ ret = JSON . stringify ( doc ) ;
253
+ ret [ 0 ] = ',' ;
254
+ ret = ret - slice ( 0 , - 1 ) ;
255
+ }
256
+ return ret ;
257
+ }
258
+
243
259
// ----------------------------------------------------------
244
260
245
261
async function getEdge ( parent , args , info ) {
@@ -301,15 +317,15 @@ async function getEdge(parent, args, info){
301
317
/*
302
318
TODO: We should probably call the createEdge function here (when we've defined it).
303
319
*/
304
- async function create ( isRoot , ctxt , data , returnType , info ) {
320
+ async function create ( isRoot , ctxt , data , returnType , info ) {
305
321
// define transaction object
306
- if ( ctxt . trans === undefined ) ctxt . trans = initTransaction ( ) ;
322
+ if ( ctxt . trans === undefined ) ctxt . trans = initTransaction ( ) ;
307
323
308
324
// is root op and mutatation is already queued
309
- if ( isRoot && ctxt . trans . queue [ info . path . key ] ) {
310
- if ( ctxt . trans . open ) await executeTransaction ( ctxt ) ;
311
- if ( ctxt . trans . error ) {
312
- if ( ctxt . trans . errorReported ) return null ;
325
+ if ( isRoot && ctxt . trans . queue [ info . path . key ] ) {
326
+ if ( ctxt . trans . open ) await executeTransaction ( ctxt ) ;
327
+ if ( ctxt . trans . error ) {
328
+ if ( ctxt . trans . errorReported ) return null ;
313
329
ctxt . trans . errorReported = true ;
314
330
throw ctxt . trans . error ;
315
331
}
@@ -338,48 +354,60 @@ async function create(isRoot, ctxt, data, returnType, info){
338
354
339
355
// for edges
340
356
let ob = getTypesAndInterfaces ( data , returnType ) ;
341
- for ( let fieldName in ob ) {
357
+ for ( let fieldName in ob ) {
342
358
let innerFieldType = graphql . getNamedType ( returnType . getFields ( ) [ fieldName ] . type ) ;
343
359
let edge = getEdgeCollectionName ( returnType . name , fieldName ) ;
344
360
ctxt . trans . write . add ( edge ) ;
345
361
let edgeCollection = asAQLVar ( `db.${ edge } ` ) ;
346
362
let values = Array . isArray ( ob [ fieldName ] ) ? ob [ fieldName ] : [ ob [ fieldName ] ] ; // treat as list even if only one value is present
347
363
348
- for ( let i in values ) {
364
+ for ( let i in values ) {
349
365
let value = values [ i ] ;
350
366
console . log ( value ) ;
351
- if ( graphql . isInterfaceType ( innerFieldType ) ) { // interface
352
- if ( value [ 'connect' ] ) {
367
+
368
+ // Prepare annotations
369
+ let annotations = null ;
370
+ if ( value [ 'annotations' ] ) {
371
+ annotations = getScalarsAndEnums ( value [ 'annotations' ] , info . schema . getType ( "_InputToAnnotate" + edge ) ) ;
372
+ annotations [ '_creationDate' ] = date . valueOf ( ) ;
373
+ }
374
+
375
+ if ( graphql . isInterfaceType ( innerFieldType ) ) { // interface
376
+ if ( value [ 'connect' ] ) {
353
377
validateType ( ctxt , value [ 'connect' ] , innerFieldType , info . schema ) ;
354
378
let typeToConnect = value [ 'connect' ] . split ( '/' ) [ 0 ] ;
355
379
// add edge
356
380
ctxt . trans . code . push ( `if(db._collection('${ typeToConnect } ').exists('${ value [ 'connect' ] } ')){` ) ;
357
- ctxt . trans . code . push ( ` db._query(aql\`INSERT {_from: ${ from } ._id, _to: "${ value [ 'connect' ] } " } IN ${ edgeCollection } RETURN NEW\`);` ) ;
381
+ ctxt . trans . code . push ( ` db._query(aql\`INSERT {_from: ${ from } ._id, _to: "${ value [ 'connect' ] } " ${ convertToInputAppendString ( annotations ) } } IN ${ edgeCollection } RETURN NEW\`);` ) ;
358
382
ctxt . trans . code . push ( `} else { ` ) ;
359
383
ctxt . trans . code . push ( ` throw "${ value [ 'connect' ] } does not exist in ${ typeToConnect } ";` ) ;
360
384
ctxt . trans . code . push ( `}` ) ;
361
385
} else {
362
386
// create
363
387
let key = Object . keys ( value ) [ 0 ] ;
388
+ if ( key == "annotations" ) {
389
+ // In case the user actually specifies the annotations before the edge
390
+ key = Object . keys ( value ) [ 1 ] ;
391
+ }
364
392
let typeToCreate = key . replace ( / ^ c r e a t e ( .+ ) $ / , '$1' ) ;
365
393
let to = asAQLVar ( getVar ( ctxt ) ) ; // reference to the object to be added
366
394
await create ( false , ctxt , value [ key ] , info . schema . getType ( typeToCreate ) , info ) ;
367
- ctxt . trans . code . push ( `db._query(aql\`INSERT {_from: ${ from } ._id, _to: ${ to } ._id } IN ${ edgeCollection } RETURN NEW\`);` ) ;
395
+ ctxt . trans . code . push ( `db._query(aql\`INSERT {_from: ${ from } ._id, _to: ${ to } ._id ${ convertToInputAppendString ( annotations ) } } IN ${ edgeCollection } RETURN NEW\`);` ) ;
368
396
}
369
397
} else { // type
370
398
if ( value [ 'connect' ] ) {
371
399
validateType ( ctxt , value [ 'connect' ] , innerFieldType , info . schema ) ;
372
400
let typeToConnect = value [ 'connect' ] . split ( '/' ) [ 0 ] ;
373
401
// add edge
374
402
ctxt . trans . code . push ( `if(db._collection('${ typeToConnect } ').exists('${ value [ 'connect' ] } ')){` ) ;
375
- ctxt . trans . code . push ( ` db._query(aql\`INSERT {_from: ${ from } ._id, _to: "${ value [ 'connect' ] } " } IN ${ edgeCollection } RETURN NEW\`);` ) ;
403
+ ctxt . trans . code . push ( ` db._query(aql\`INSERT {_from: ${ from } ._id, _to: "${ value [ 'connect' ] } " ${ convertToInputAppendString ( annotations ) } } IN ${ edgeCollection } RETURN NEW\`);` ) ;
376
404
ctxt . trans . code . push ( `} else { ` ) ;
377
405
ctxt . trans . code . push ( ` throw "${ value [ 'connect' ] } does not exist in ${ typeToConnect } ";` ) ;
378
406
ctxt . trans . code . push ( `}` ) ;
379
- } else { // create
407
+ } else { // create
380
408
let to = asAQLVar ( getVar ( ctxt ) ) ; // reference to the object to be added
381
409
await create ( false , ctxt , value [ 'create' ] , innerFieldType , info ) ;
382
- ctxt . trans . code . push ( `db._query(aql\`INSERT {_from: ${ from } ._id, _to: ${ to } ._id } IN ${ edgeCollection } RETURN NEW\`);` ) ;
410
+ ctxt . trans . code . push ( `db._query(aql\`INSERT {_from: ${ from } ._id, _to: ${ to } ._id ${ convertToInputAppendString ( annotations ) } } IN ${ edgeCollection } RETURN NEW\`);` ) ;
383
411
}
384
412
}
385
413
}
@@ -389,7 +417,7 @@ async function create(isRoot, ctxt, data, returnType, info){
389
417
addFinalDirectiveChecksForType ( ctxt , returnType , aql `${ asAQLVar ( resVar ) } ._id` , info . schema ) ;
390
418
391
419
// overwrite the current action
392
- if ( isRoot ) {
420
+ if ( isRoot ) {
393
421
ctxt . trans . code . push ( `result['${ info . path . key } '] = ${ resVar } ;` ) ; // add root result
394
422
ctxt . trans . queue [ info . path . key ] = true ; // indicate that this mutation op has been added to the transaction
395
423
getVar ( ctxt ) ; // increment varCounter
@@ -549,15 +577,15 @@ function validateType(ctxt, id, type, schema){
549
577
}
550
578
}
551
579
552
- async function update ( isRoot , ctxt , id , data , returnType , info ) {
580
+ async function update ( isRoot , ctxt , id , data , returnType , info ) {
553
581
// define transaction object
554
- if ( ctxt . trans === undefined ) ctxt . trans = initTransaction ( ) ;
582
+ if ( ctxt . trans === undefined ) ctxt . trans = initTransaction ( ) ;
555
583
556
584
// is root op and mutation is already queued
557
- if ( isRoot && ctxt . trans . queue [ info . path . key ] ) {
558
- if ( ctxt . trans . open ) await executeTransaction ( ctxt ) ;
559
- if ( ctxt . trans . error ) {
560
- if ( ctxt . trans . errorReported ) return null ;
585
+ if ( isRoot && ctxt . trans . queue [ info . path . key ] ) {
586
+ if ( ctxt . trans . open ) await executeTransaction ( ctxt ) ;
587
+ if ( ctxt . trans . error ) {
588
+ if ( ctxt . trans . errorReported ) return null ;
561
589
ctxt . trans . errorReported = true ;
562
590
throw ctxt . trans . error ;
563
591
}
@@ -569,24 +597,24 @@ async function update(isRoot, ctxt, id, data, returnType, info){
569
597
// 3) Add key check to transaction
570
598
let keyName = getKeyName ( returnType . name ) ;
571
599
let keyType = info . schema [ "_typeMap" ] [ keyName ] ;
572
- if ( keyType ) {
600
+ if ( keyType ) {
573
601
try {
574
602
let collection = db . collection ( returnType ) ;
575
603
const cursor = await db . query ( aql `FOR i IN ${ collection } FILTER(i._id == ${ id } ) RETURN i` ) ;
576
604
let doc = await cursor . next ( ) ;
577
- if ( doc == undefined ) {
605
+ if ( doc == undefined ) {
578
606
throw new ApolloError ( `ID ${ id } is not a document in the type ${ returnType } ` ) ;
579
607
}
580
608
581
609
let key = { } ;
582
- for ( let f in keyType . _fields ) {
610
+ for ( let f in keyType . _fields ) {
583
611
key [ f ] = doc [ f ] ;
584
- if ( data [ f ] !== undefined ) {
612
+ if ( data [ f ] !== undefined ) {
585
613
key [ f ] = data [ f ] ;
586
614
}
587
615
}
588
616
validateKey ( ctxt , key , returnType , info . schema , id ) ;
589
- } catch ( err ) {
617
+ } catch ( err ) {
590
618
throw new ApolloError ( err ) ;
591
619
}
592
620
}
@@ -619,6 +647,13 @@ async function update(isRoot, ctxt, id, data, returnType, info){
619
647
for ( let i in values ) {
620
648
let value = values [ i ] ;
621
649
650
+ // Prepare annotations
651
+ let annotations = null ;
652
+ if ( value [ 'annotations' ] ) {
653
+ annotations = getScalarsAndEnums ( value [ 'annotations' ] , info . schema . getType ( "_InputToAnnotate" + edge ) ) ;
654
+ annotations [ '_creationDate' ] = date . valueOf ( ) ;
655
+ }
656
+
622
657
if ( graphql . isInterfaceType ( nestedReturnType ) ) {
623
658
// interface field
624
659
if ( value [ 'connect' ] ) {
@@ -630,11 +665,11 @@ async function update(isRoot, ctxt, id, data, returnType, info){
630
665
// add edge
631
666
if ( ! disableEdgeValidation ) { // check the database
632
667
ctxt . trans . code . push ( `if(db._collection('${ typeToConnect } ').exists('${ value [ 'connect' ] } ')){` ) ;
633
- ctxt . trans . code . push ( `db._query(aql\`INSERT {_from: "${ id } ", _to: "${ value [ 'connect' ] } " } IN ${ edgeCollection } RETURN NEW\`);` ) ;
668
+ ctxt . trans . code . push ( `db._query(aql\`INSERT {_from: "${ id } ", _to: "${ value [ 'connect' ] } " ${ convertToInputAppendString ( annotations ) } } IN ${ edgeCollection } RETURN NEW\`);` ) ;
634
669
ctxt . trans . code . push ( `} else { throw "${ value [ 'connect' ] } does not exist in ${ typeToConnect } "; }` ) ;
635
670
} else {
636
671
console . warn ( `Adding connection to ${ value [ 'connect' ] } in ${ edge } without validating ID` ) ;
637
- ctxt . trans . code . push ( `db._query(aql\`INSERT {_from: "${ id } ", _to: "${ value [ 'connect' ] } " } IN ${ edgeCollection } RETURN NEW\`);` ) ;
672
+ ctxt . trans . code . push ( `db._query(aql\`INSERT {_from: "${ id } ", _to: "${ value [ 'connect' ] } " ${ convertToInputAppendString ( annotations ) } } IN ${ edgeCollection } RETURN NEW\`);` ) ;
638
673
}
639
674
} else {
640
675
// create
@@ -645,7 +680,7 @@ async function update(isRoot, ctxt, id, data, returnType, info){
645
680
}
646
681
let to = asAQLVar ( getVar ( ctxt ) ) ; // reference to the object to be added
647
682
await create ( false , ctxt , value [ key ] , info . schema . getType ( typeToCreate ) , info ) ;
648
- ctxt . trans . code . push ( `db._query(aql\`INSERT {_from: "${ id } ", _to: ${ to } ._id } IN ${ edgeCollection } RETURN NEW\`);` ) ;
683
+ ctxt . trans . code . push ( `db._query(aql\`INSERT {_from: "${ id } ", _to: ${ to } ._id ${ convertToInputAppendString ( annotations ) } } IN ${ edgeCollection } RETURN NEW\`);` ) ;
649
684
}
650
685
} else {
651
686
// type field
@@ -658,17 +693,17 @@ async function update(isRoot, ctxt, id, data, returnType, info){
658
693
// add edge
659
694
if ( ! disableEdgeValidation ) { // check the database
660
695
ctxt . trans . code . push ( `if(db._collection('${ typeToConnect } ').exists('${ value [ 'connect' ] } ')){` ) ;
661
- ctxt . trans . code . push ( `db._query(aql\`INSERT {_from: "${ id } ", _to: "${ value [ 'connect' ] } " } IN ${ edgeCollection } RETURN NEW\`);` ) ;
696
+ ctxt . trans . code . push ( `db._query(aql\`INSERT {_from: "${ id } ", _to: "${ value [ 'connect' ] } " ${ convertToInputAppendString ( annotations ) } } IN ${ edgeCollection } RETURN NEW\`);` ) ;
662
697
ctxt . trans . code . push ( `} else { throw "${ value [ 'connect' ] } does not exist in ${ typeToConnect } "; }` ) ;
663
698
} else {
664
699
console . warn ( `Adding connection to ${ value [ 'connect' ] } in ${ edge } without validating ID` ) ;
665
- ctxt . trans . code . push ( `db._query(aql\`INSERT {_from: "${ id } ", _to: "${ value [ 'connect' ] } " } IN ${ edgeCollection } RETURN NEW\`);` ) ;
700
+ ctxt . trans . code . push ( `db._query(aql\`INSERT {_from: "${ id } ", _to: "${ value [ 'connect' ] } " ${ convertToInputAppendString ( annotations ) } } IN ${ edgeCollection } RETURN NEW\`);` ) ;
666
701
}
667
702
} else {
668
703
// create
669
704
let to = asAQLVar ( getVar ( ctxt ) ) ; // reference to the object to be added
670
705
await create ( false , ctxt , value [ 'create' ] , nestedReturnType , info ) ;
671
- ctxt . trans . code . push ( `db._query(aql\`INSERT {_from: "${ id } ", _to: ${ to } ._id } IN ${ edgeCollection } RETURN NEW\`);` ) ;
706
+ ctxt . trans . code . push ( `db._query(aql\`INSERT {_from: "${ id } ", _to: ${ to } ._id ${ convertToInputAppendString ( annotations ) } } IN ${ edgeCollection } RETURN NEW\`);` ) ;
672
707
}
673
708
}
674
709
}
@@ -678,7 +713,7 @@ async function update(isRoot, ctxt, id, data, returnType, info){
678
713
addFinalDirectiveChecksForType ( ctxt , returnType , aql `${ asAQLVar ( resVar ) } ._id` , info . schema ) ;
679
714
680
715
// overwrite the current action
681
- if ( isRoot ) {
716
+ if ( isRoot ) {
682
717
ctxt . trans . code . push ( `result['${ info . path . key } '] = ${ resVar } .new;` ) ; // add root result
683
718
ctxt . trans . queue [ info . path . key ] = true ; // indicate that this mutation op has been added to the transaction
684
719
getVar ( ctxt ) ; // increment varCounter
@@ -736,11 +771,11 @@ function formatFixVariable(_type, v) {
736
771
if ( Array . isArray ( v ) ) {
737
772
let newV = [ ]
738
773
for ( date of v )
739
- newV . push ( aql `DATE_TIMESTAMP(${ date } )` ) ;
774
+ newV . push ( aql `DATE_TIMESTAMP(" ${ date } " )` ) ;
740
775
return newV ;
741
776
}
742
777
else
743
- return aql `DATE_TIMESTAMP(${ v } )` ;
778
+ return aql `DATE_TIMESTAMP(" ${ v } " )` ;
744
779
else
745
780
return v ;
746
781
}
0 commit comments