File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -59,6 +59,15 @@ service Model {
5959 rpc DeleteRelationship (DeleteRelationshipRequest )
6060 returns (google.protobuf.Empty ) {}
6161
62+ // Upsert (create-or-replace) every nmts.Entity and nmts.Relationship in a
63+ // Fragment in a single atomic transaction that is validated exactly once.
64+ //
65+ // Existing entities are fully replaced (an entity's kind may not change).
66+ // A relationship that already exists (same a/kind/z) is a no-op. The whole
67+ // fragment is applied atomically: on any validation or write error, nothing
68+ // is committed.
69+ rpc UpsertFragment (UpsertFragmentRequest ) returns (UpsertFragmentResponse ) {}
70+
6271 // Retrieve an nmts.Entity
6372 //
6473 // Returns a gRPC NotFound error if an Entity with the supplied Id
@@ -121,3 +130,13 @@ message ListRelationshipsRequest {
121130message ListRelationshipsResponse {
122131 repeated nmts.v1.Relationship relationships = 1 ;
123132}
133+
134+ message UpsertFragmentRequest {
135+ nmts.v1.Fragment fragment = 1 ;
136+ }
137+
138+ message UpsertFragmentResponse {
139+ int32 entities_created = 1 ;
140+ int32 entities_updated = 2 ;
141+ int32 relationships_created = 3 ;
142+ }
Original file line number Diff line number Diff line change @@ -158,6 +158,7 @@ func TestGrpcurl_list(t *testing.T) {
158158 "aalyria.spacetime.api.model.v1.Model.ListEntities" ,
159159 "aalyria.spacetime.api.model.v1.Model.ListRelationships" ,
160160 "aalyria.spacetime.api.model.v1.Model.UpdateEntity" ,
161+ "aalyria.spacetime.api.model.v1.Model.UpsertFragment" ,
161162 ))
162163}
163164
Original file line number Diff line number Diff line change @@ -219,7 +219,6 @@ func ModelDeleteRelationship(appCtx *cli.Context) error {
219219 return err
220220}
221221
222- // TODO: turn these into one atomic RPC call in the modelfe.
223222func ModelUpsertFragment (appCtx * cli.Context ) error {
224223 marshaller , err := marshallerForFormat (appCtx .String ("format" ))
225224 if err != nil {
@@ -241,26 +240,11 @@ func ModelUpsertFragment(appCtx *cli.Context) error {
241240 defer conn .Close ()
242241 modelClient := modelpb .NewModelClient (conn )
243242
244- for _ , nmtsEntity := range nmtsFragment .GetEntity () {
245- _ , err = modelClient .CreateEntity (
246- appCtx .Context ,
247- & modelpb.CreateEntityRequest {
248- Entity : nmtsEntity ,
249- })
250- if err != nil {
251- return err
252- }
253- }
254-
255- for _ , nmtsRelationship := range nmtsFragment .GetRelationship () {
256- _ , err = modelClient .CreateRelationship (
257- appCtx .Context ,
258- & modelpb.CreateRelationshipRequest {
259- Relationship : nmtsRelationship ,
260- })
261- if err != nil {
262- return err
263- }
243+ if _ , err := modelClient .UpsertFragment (
244+ appCtx .Context ,
245+ & modelpb.UpsertFragmentRequest {Fragment : nmtsFragment },
246+ ); err != nil {
247+ return err
264248 }
265249
266250 fmt .Fprintln (appCtx .App .ErrWriter , "# OK" )
You can’t perform that action at this time.
0 commit comments