@@ -81,9 +81,12 @@ func Run(ctx app.Context) {
81
81
if cmdLine .Options .Update {
82
82
writeOptions ++
83
83
}
84
+ if cmdLine .Options .Insert {
85
+ writeOptions ++
86
+ }
84
87
if writeOptions > 1 {
85
88
config .Help ()
86
- fmt .Fprintf (os .Stderr , "--update, --delete, and --delete-label are mutually exclusive\n " )
89
+ fmt .Fprintf (os .Stderr , "--insert, -- update, --delete, and --delete-label are mutually exclusive\n " )
87
90
os .Exit (1 )
88
91
}
89
92
@@ -117,6 +120,12 @@ func Run(ctx app.Context) {
117
120
fmt .Fprintf (os .Stderr , "Not enough arguments for --update: entity, id, and patches are required\n " )
118
121
os .Exit (1 )
119
122
}
123
+ } else if cmdLine .Options .Insert { // --insert
124
+ if len (cmdLine .Args ) < 2 {
125
+ config .Help ()
126
+ fmt .Fprintf (os .Stderr , "Not enough arguments for --insert: entity and patches are required\n " )
127
+ os .Exit (1 )
128
+ }
120
129
} else if cmdLine .Options .Watch { // --watch
121
130
} else { // query
122
131
if len (cmdLine .Args ) < 2 {
@@ -265,6 +274,39 @@ func Run(ctx app.Context) {
265
274
etre .Debug ("trace: %s" , trace )
266
275
ec = ec .WithTrace (trace )
267
276
277
+ // //////////////////////////////////////////////////////////////////////
278
+ // Insert and exit, if --insert
279
+ // //////////////////////////////////////////////////////////////////////
280
+
281
+ if o .Insert {
282
+ // cmdLine.Args validated above
283
+ ctx .Patches = cmdLine .Args [1 :]
284
+
285
+ if ctx .Hooks .BeforeInsert != nil {
286
+ etre .Debug ("calling hook BeforeInsert" )
287
+ err = ctx .Hooks .BeforeInsert (& ctx )
288
+ if err != nil {
289
+ printAndExit (fmt .Errorf ("BeforeInsert hook failed: %s" , err ), ctx )
290
+ }
291
+ }
292
+
293
+ patch , err := parsePatches (ctx )
294
+ if err != nil {
295
+ printAndExit (err , ctx )
296
+ }
297
+
298
+ wr , err := ec .Insert ([]etre.Entity {patch })
299
+ _ , err = writeResult (ctx , set , wr , err , "insert" )
300
+ if err != nil {
301
+ printAndExit (err , ctx )
302
+ }
303
+ if len (wr .Writes ) != 1 {
304
+ printAndExit (fmt .Errorf ("Etre reports no error but reported %d inserts, expected 1 insert" , len (wr .Writes )), ctx )
305
+ }
306
+ fmt .Printf ("OK, inserted %s %s\n " , ctx .EntityType , wr .Writes [0 ].EntityId )
307
+ return
308
+ }
309
+
268
310
// //////////////////////////////////////////////////////////////////////
269
311
// Update and exit, if --update
270
312
// //////////////////////////////////////////////////////////////////////
@@ -276,37 +318,16 @@ func Run(ctx app.Context) {
276
318
277
319
if ctx .Hooks .BeforeUpdate != nil {
278
320
etre .Debug ("calling hook BeforeUpdate" )
279
- ctx .Hooks .BeforeUpdate (& ctx )
321
+ err = ctx .Hooks .BeforeUpdate (& ctx )
322
+ if err != nil {
323
+ printAndExit (fmt .Errorf ("BeforeUpdate hook failed: %s" , err ), ctx )
324
+ }
280
325
}
281
326
282
- patch := etre.Entity {}
283
- for i , kv := range ctx .Patches {
284
- p := strings .SplitN (kv , "=" , 2 )
285
- etre .Debug ("patch %d: '%s': %#v" , i , kv , p )
286
- if len (p ) > 0 {
287
- if ctx .Options .Strict {
288
- if strings .IndexAny (p [0 ], " \t " ) != - 1 {
289
- printAndExit (fmt .Errorf ("Invalid patch: %s: label has whitespace" , kv ), ctx )
290
- }
291
- } else {
292
- p [0 ] = strings .TrimSpace (p [0 ])
293
- }
294
- if p [0 ] == "" {
295
- printAndExit (fmt .Errorf ("Invalid patch: %s: empty label" , kv ), ctx )
296
- }
297
- }
298
- switch len (p ) {
299
- case 0 :
300
- printAndExit (fmt .Errorf ("Invalid patch: %s: split on = yielded 0 parts, expected 1 or 2" , kv ), ctx )
301
- case 1 :
302
- patch [p [0 ]] = nil
303
- case 2 :
304
- patch [p [0 ]] = p [1 ]
305
- default :
306
- printAndExit (fmt .Errorf ("Invalid patch: %s: split on = yielded %d parts, expected 2" , kv , len (p )), ctx )
307
- }
327
+ patch , err := parsePatches (ctx )
328
+ if err != nil {
329
+ printAndExit (err , ctx )
308
330
}
309
- etre .Debug ("patch: %#v" , patch )
310
331
311
332
wr , err := ec .UpdateOne (ctx .EntityId , patch )
312
333
found , err := writeResult (ctx , set , wr , err , "update" )
@@ -331,7 +352,10 @@ func Run(ctx app.Context) {
331
352
332
353
if ctx .Hooks .BeforeDelete != nil {
333
354
etre .Debug ("calling hook BeforeDelete" )
334
- ctx .Hooks .BeforeDelete (& ctx )
355
+ err = ctx .Hooks .BeforeDelete (& ctx )
356
+ if err != nil {
357
+ printAndExit (fmt .Errorf ("BeforeDelete hook failed: %s" , err ), ctx )
358
+ }
335
359
}
336
360
337
361
wr , err := ec .DeleteOne (ctx .EntityId )
@@ -527,3 +551,37 @@ func printAndExit(err error, ctx app.Context) {
527
551
}
528
552
os .Exit (1 )
529
553
}
554
+
555
+ func parsePatches (ctx app.Context ) (etre.Entity , error ) {
556
+ patch := etre.Entity {}
557
+
558
+ for i , kv := range ctx .Patches {
559
+ p := strings .SplitN (kv , "=" , 2 )
560
+ etre .Debug ("patch %d: '%s': %#v" , i , kv , p )
561
+ if len (p ) > 0 {
562
+ if ctx .Options .Strict {
563
+ if strings .IndexAny (p [0 ], " \t " ) != - 1 {
564
+ return patch , fmt .Errorf ("Invalid patch: %s: label has whitespace" , kv )
565
+ }
566
+ } else {
567
+ p [0 ] = strings .TrimSpace (p [0 ])
568
+ }
569
+ if p [0 ] == "" {
570
+ return patch , fmt .Errorf ("Invalid patch: %s: empty label" , kv )
571
+ }
572
+ }
573
+ switch len (p ) {
574
+ case 0 :
575
+ return patch , fmt .Errorf ("Invalid patch: %s: split on = yielded 0 parts, expected 1 or 2" , kv )
576
+ case 1 :
577
+ patch [p [0 ]] = nil
578
+ case 2 :
579
+ patch [p [0 ]] = strings .TrimSpace (p [1 ])
580
+ default :
581
+ return patch , fmt .Errorf ("Invalid patch: %s: split on = yielded %d parts, expected 2" , kv , len (p ))
582
+ }
583
+ }
584
+ etre .Debug ("patch: %#v" , patch )
585
+
586
+ return patch , nil
587
+ }
0 commit comments