@@ -67,6 +67,42 @@ var CONSISTENCY_PROTO_CODE = {
6767 */
6868function DatastoreRequest ( ) { }
6969
70+ /**
71+ * Format a user's input to mutation methods. This will create a deep clone of
72+ * the input, as well as allow users to pass an object in the format of an
73+ * entity.
74+ *
75+ * Both of the following formats can be supplied supported:
76+ *
77+ * datastore.save({
78+ * key: datastore.key('Kind'),
79+ * data: { foo: 'bar' }
80+ * }, function(err) {})
81+ *
82+ * var entity = { foo: 'bar' }
83+ * entity[datastore.KEY] = datastore.key('Kind')
84+ * datastore.save(entity, function(err) {})
85+ *
86+ * @private
87+ *
88+ * @resource [#1803]{@link https://github.com/GoogleCloudPlatform/google-cloud-node/issues/1803}
89+ *
90+ * @param {object } obj - The user's input object.
91+ */
92+ DatastoreRequest . prepareEntityObject_ = function ( obj ) {
93+ var entityObject = extend ( true , { } , obj ) ;
94+
95+ // Entity objects are also supported.
96+ if ( obj [ entity . KEY_SYMBOL ] ) {
97+ return {
98+ key : obj [ entity . KEY_SYMBOL ] ,
99+ data : entityObject
100+ } ;
101+ }
102+
103+ return entityObject ;
104+ } ;
105+
70106/**
71107 * Generate IDs without creating entities.
72108 *
@@ -426,7 +462,10 @@ DatastoreRequest.prototype.get = function(keys, options, callback) {
426462 * Maps to {module:datastore#save}, forcing the method to be `insert`.
427463 */
428464DatastoreRequest . prototype . insert = function ( entities , callback ) {
429- entities = arrify ( entities ) . map ( propAssign ( 'method' , 'insert' ) ) ;
465+ entities = arrify ( entities )
466+ . map ( DatastoreRequest . prepareEntityObject_ )
467+ . map ( propAssign ( 'method' , 'insert' ) ) ;
468+
430469 this . save ( entities , callback ) ;
431470} ;
432471
@@ -863,53 +902,53 @@ DatastoreRequest.prototype.save = function(entities, callback) {
863902
864903 // Iterate over the entity objects, build a proto from all keys and values,
865904 // then place in the correct mutation array (insert, update, etc).
866- entities . forEach ( function ( entityObject , index ) {
867- entityObject = extend ( true , { } , entityObject ) ;
868-
869- var mutation = { } ;
870- var entityProto = { } ;
871- var method = 'upsert' ;
872-
873- if ( entityObject . method ) {
874- if ( methods [ entityObject . method ] ) {
875- method = entityObject . method ;
876- } else {
877- throw new Error ( 'Method ' + entityObject . method + ' not recognized.' ) ;
905+ entities
906+ . map ( DatastoreRequest . prepareEntityObject_ )
907+ . forEach ( function ( entityObject , index ) {
908+ var mutation = { } ;
909+ var entityProto = { } ;
910+ var method = 'upsert' ;
911+
912+ if ( entityObject . method ) {
913+ if ( methods [ entityObject . method ] ) {
914+ method = entityObject . method ;
915+ } else {
916+ throw new Error ( 'Method ' + entityObject . method + ' not recognized.' ) ;
917+ }
878918 }
879- }
880919
881- if ( ! entity . isKeyComplete ( entityObject . key ) ) {
882- insertIndexes [ index ] = true ;
883- }
920+ if ( ! entity . isKeyComplete ( entityObject . key ) ) {
921+ insertIndexes [ index ] = true ;
922+ }
884923
885- if ( is . array ( entityObject . data ) ) {
886- entityProto . properties = entityObject . data . reduce ( function ( acc , data ) {
887- var value = entity . encodeValue ( data . value ) ;
924+ if ( is . array ( entityObject . data ) ) {
925+ entityProto . properties = entityObject . data . reduce ( function ( acc , data ) {
926+ var value = entity . encodeValue ( data . value ) ;
888927
889- if ( is . boolean ( data . excludeFromIndexes ) ) {
890- var excluded = data . excludeFromIndexes ;
891- var values = value . arrayValue && value . arrayValue . values ;
928+ if ( is . boolean ( data . excludeFromIndexes ) ) {
929+ var excluded = data . excludeFromIndexes ;
930+ var values = value . arrayValue && value . arrayValue . values ;
892931
893- if ( values ) {
894- values = values . map ( propAssign ( 'excludeFromIndexes' , excluded ) ) ;
895- } else {
896- value . excludeFromIndexes = data . excludeFromIndexes ;
932+ if ( values ) {
933+ values = values . map ( propAssign ( 'excludeFromIndexes' , excluded ) ) ;
934+ } else {
935+ value . excludeFromIndexes = data . excludeFromIndexes ;
936+ }
897937 }
898- }
899938
900- acc [ data . name ] = value ;
939+ acc [ data . name ] = value ;
901940
902- return acc ;
903- } , { } ) ;
904- } else {
905- entityProto = entity . entityToEntityProto ( entityObject . data ) ;
906- }
941+ return acc ;
942+ } , { } ) ;
943+ } else {
944+ entityProto = entity . entityToEntityProto ( entityObject . data ) ;
945+ }
907946
908- entityProto . key = entity . keyToKeyProto ( entityObject . key ) ;
947+ entityProto . key = entity . keyToKeyProto ( entityObject . key ) ;
909948
910- mutation [ method ] = entityProto ;
911- mutations . push ( mutation ) ;
912- } ) ;
949+ mutation [ method ] = entityProto ;
950+ mutations . push ( mutation ) ;
951+ } ) ;
913952
914953 var protoOpts = {
915954 service : 'Datastore' ,
@@ -953,15 +992,21 @@ DatastoreRequest.prototype.save = function(entities, callback) {
953992 * Maps to {module:datastore#save}, forcing the method to be `update`.
954993 */
955994DatastoreRequest . prototype . update = function ( entities , callback ) {
956- entities = arrify ( entities ) . map ( propAssign ( 'method' , 'update' ) ) ;
995+ entities = arrify ( entities )
996+ . map ( DatastoreRequest . prepareEntityObject_ )
997+ . map ( propAssign ( 'method' , 'update' ) ) ;
998+
957999 this . save ( entities , callback ) ;
9581000} ;
9591001
9601002/**
9611003 * Maps to {module:datastore#save}, forcing the method to be `upsert`.
9621004 */
9631005DatastoreRequest . prototype . upsert = function ( entities , callback ) {
964- entities = arrify ( entities ) . map ( propAssign ( 'method' , 'upsert' ) ) ;
1006+ entities = arrify ( entities )
1007+ . map ( DatastoreRequest . prepareEntityObject_ )
1008+ . map ( propAssign ( 'method' , 'upsert' ) ) ;
1009+
9651010 this . save ( entities , callback ) ;
9661011} ;
9671012
0 commit comments