xeme 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +286 -0
  3. data/lib/xeme.rb +613 -0
  4. metadata +45 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d484d6f5c5b9cfdf0ae85dd4a1ca69c46b2b1c7eed711eae02352b59d3c929fe
4
+ data.tar.gz: e8d0a6527bafc7dff93ba1cd584a4527114e5dc3a40b165c3c86baf9ece744a2
5
+ SHA512:
6
+ metadata.gz: 291925e898631853c7a64f49327954b0b1c309b73e330d511561dc5c017ae7b15ab51f0fc22264e5c800a80c59530733776eba813840c06e179fd7db221aa166
7
+ data.tar.gz: 13d3459ee59daf94a4bc2841ed308ec498b14f361ad8eb76abb0d919d44823ba2fdf4df19e3b93df89d54d3c0c9564fdaf408c6f7c60d352e22844a79746b4c1
data/README.md ADDED
@@ -0,0 +1,286 @@
1
+ # Xeme
2
+
3
+ Xeme provides a common format for returning the results of a process. In its
4
+ simplest use, you create a Xeme object and add errors as necessary:
5
+
6
+ require 'xeme'
7
+ xeme = Xeme.new
8
+ xeme.error 'error-1'
9
+
10
+ If there are any errors, such as in this first example, <tt>success</tt> returns false:
11
+
12
+ puts xeme.success # false
13
+
14
+ A Xeme object without any errors returns true for <tt>success</tt>:
15
+
16
+ xeme = Xeme.new
17
+ puts xeme.success # true
18
+
19
+ Xeme is a good way to report results that are more complex than just success or
20
+ failure. For example, consider the situation in which a record must have a name
21
+ field and an email field. If the record does not meet these requirements, it is
22
+ not sufficient to merely report success or failure, nor to just report that one
23
+ field or the other is missing. With Xeme you can report all of that information
24
+ in a single object:
25
+
26
+ xeme = Xeme.new
27
+ xeme.error 'name'
28
+ xeme.error 'email'
29
+
30
+ You can return the Xeme object to another Ruby process, or you can output it to
31
+ JSON for use in some other program:
32
+
33
+ puts xeme.to_json
34
+
35
+ # outputs:
36
+ {"success":false,"messages":{"errors":[{"id":"name"},{"id":"email"}]}}
37
+
38
+ You might prefer to add the <tt>pretty</tt> option for more readable output:
39
+
40
+ puts xeme.to_json('pretty'=>true)
41
+
42
+ # outputs:
43
+ {
44
+ "success": false,
45
+ "messages": {
46
+ "errors": [
47
+ {
48
+ "id": "name"
49
+ },
50
+ {
51
+ "id": "email"
52
+ }
53
+ ]
54
+ }
55
+ }
56
+
57
+ In some situations, it's useful to give details about the error. For example,
58
+ if the <tt>name</tt> field is too long, you can report not just that there is
59
+ an error in that field, but specifics about that error:
60
+
61
+ xeme.error('name') do |msg|
62
+ msg['too-long'] = true
63
+ msg['max-length'] = 45
64
+ end
65
+
66
+ That would produce a structure like this:
67
+
68
+ {
69
+ "success": false,
70
+ "messages": {
71
+ "errors": [
72
+ {
73
+ "id": "name",
74
+ "details": {
75
+ "too-long": true,
76
+ "max-length": 45
77
+ }
78
+ }
79
+ ]
80
+ }
81
+ }
82
+
83
+
84
+ You can also add warnings and notes. A warning indicates a problem but not an
85
+ actual failure. A note does not indicate any problem at all but just some
86
+ information that should be passed along.
87
+
88
+ xeme.warning 'database-reset'
89
+ xeme.note 'database ok'
90
+
91
+ It's often useful to add misc details to the results. For example, a database
92
+ query might result in some rows from a table. You might add these rows to the
93
+ <tt>misc</tt> property like this:
94
+
95
+ xeme = Xeme.new
96
+ xeme.misc['rows'] = []
97
+ xeme.misc['rows'].push 'a'
98
+ xeme.misc['rows'].push 'b'
99
+ xeme.misc['rows'].push 'c'
100
+ puts xeme.to_json('pretty'=>true)
101
+
102
+ # outputs:
103
+ {
104
+ "success": true,
105
+ "misc": {
106
+ "rows": [
107
+ "a",
108
+ "b",
109
+ "c"
110
+ ]
111
+ }
112
+ }
113
+
114
+ Xeme can input a Xeme JSON structure to make a new Xeme object:
115
+
116
+ # json
117
+ json = <<~'JSON'
118
+ {
119
+ "success": false,
120
+ "messages": {
121
+ "errors": [
122
+ { "id": "location" }
123
+ ]
124
+ }
125
+ }
126
+ JSON
127
+
128
+ # xeme
129
+ xeme = Xeme.from_json(json)
130
+
131
+ ## Xeme structure
132
+
133
+ The Xeme structure can be used by any software, Ruby or otherwise, as a standard
134
+ way to report results. A Xeme structure can be stored in any format that
135
+ recognizes hashes, arrays, strings, numbers, booleans, and null. Such formats
136
+ include JSON and YAML. Xeme would be a good way for REST applications to
137
+ provide results from a query. The Xeme#to_json method outputs such a structure.
138
+ We'll use JSON for these examples.
139
+
140
+ An empty structure indicates success:
141
+
142
+ {}
143
+
144
+ That structure indicates no messages such as errors, and no details. To make the
145
+ structure easier to use by software that doesn't have a Xeme module, it is
146
+ customary to also output an explicit indication of success or failure:
147
+
148
+ {"success":true}
149
+
150
+ A Xeme structure can report any number of messages. A message is an error,
151
+ warning, or note. An error indicates that the process failed, and gives a resaon
152
+ why. If there are any errors, the process is considered a failure. A warning
153
+ indicates a problem, but not an actual failure. A note reports useful
154
+ information that does not indicate any kind of problem at all. Neither a warning
155
+ nor a note cause failure.
156
+
157
+ Messages, if any, are stored in a messages hash, which consists of arrays for
158
+ errors, warnings, and notes.
159
+
160
+ {
161
+ "success": false,
162
+ "messages": {
163
+ "errors": [
164
+ {
165
+ "id": "missing-city"
166
+ }
167
+ ],
168
+ "warnings": [
169
+ {
170
+ "id": "database-reset"
171
+ }
172
+ ],
173
+ "notes": [
174
+ {
175
+ "id": "database-online"
176
+ }
177
+ ]
178
+ }
179
+ }
180
+
181
+ Any number of messages can be reported. So, for example, the following structure
182
+ has two errors and no warnings or notes.
183
+
184
+ {
185
+ "success": false,
186
+ "messages": {
187
+ "errors": [
188
+ {
189
+ "id": "missing-city"
190
+ }
191
+ ],
192
+ "warnings": [
193
+ {
194
+ "id": "missing-zip-code"
195
+ }
196
+ ]
197
+ }
198
+ }
199
+
200
+ A message can have associated details. For example, the following error
201
+ indicates that the problem with the name field is that it's too long, and the
202
+ maximum length is 45:
203
+
204
+ {
205
+ "success": false,
206
+ "messages": {
207
+ "errors": [
208
+ {
209
+ "id": "name",
210
+ "details": {
211
+ "too-long": true,
212
+ "max-length": 45
213
+ }
214
+ }
215
+ ]
216
+ }
217
+ }
218
+
219
+ Sometimes it is useful to add arbitrary information to the results. For example,
220
+ the results from a database query might return the rows that the query produced.
221
+ In that situation, the misc element is handy.
222
+
223
+ {
224
+ "success": true,
225
+ "misc": {
226
+ "rows": [
227
+ "Fred",
228
+ "Mary",
229
+ "Jane"
230
+ ]
231
+ }
232
+ }
233
+
234
+ Sometimes it is useful to provide information about the specific transaction,
235
+ e.g. the call to a REST server. The transaction element can be used to provide
236
+ that information. If there is a transaction element, it should always provide a
237
+ timestamp for the transaction and a unique ID for it.
238
+
239
+ {
240
+ "success": true,
241
+ "transaction": {
242
+ "response": "08214643960776591",
243
+ "timestamp": "2020-01-07T18:41:37+00:00"
244
+ }
245
+ }
246
+
247
+ If the request includes an ID for that specific request, then that ID can be
248
+ supplied as part of the transaction element:
249
+
250
+ {
251
+ "success": true,
252
+ "transaction": {
253
+ "request": "64e57c8a-bd3e-47b9-9221-e9e3e0263341",
254
+ "response": "3301315461336113",
255
+ "timestamp": "2020-01-07T18:42:01+00:00"
256
+ }
257
+ }
258
+
259
+ The general adoption of the Xeme structure could simplify implementing
260
+ interoperable applications such as REST APIs.
261
+
262
+ ## The name
263
+
264
+ The word "xeme" has no particular association with the concept of results
265
+ reporting. I got the word from a random word generator and I liked it. The xeme,
266
+ also known as Sabine's gull, is a type of gull. See
267
+ [the Wikipedia page](https://en.wikipedia.org/wiki/Sabine's_gull)
268
+ if you'd like to know more.
269
+
270
+ ## Install
271
+
272
+ ```
273
+ gem install xeme
274
+ ```
275
+
276
+ ## Author
277
+
278
+ Mike O'Sullivan
279
+ mike@idocs.com
280
+
281
+ ## History
282
+
283
+ | version | date | notes |
284
+ |---------|-------------|-----------------|
285
+ | 0.1 | Jan 7, 2020 | Initial upload. |
286
+
data/lib/xeme.rb ADDED
@@ -0,0 +1,613 @@
1
+ require 'date'
2
+ require 'json'
3
+ require 'forwardable'
4
+
5
+ #===============================================================================
6
+ # Xeme
7
+ #
8
+
9
+ ##
10
+ # Objects of this class represent a set of results. See the README file for
11
+ # more details.
12
+
13
+ class Xeme
14
+ # Version 0.1
15
+ VERSION = '0.1'
16
+
17
+ # A Xeme::Messages object, which is basically just a hash containing arrays
18
+ # for errors, warnings, and notes.
19
+ attr_reader :messages
20
+
21
+ # A hash of any miscellaneous details you want to include.
22
+ attr_reader :misc
23
+
24
+ #---------------------------------------------------------------------------
25
+ # initialize
26
+ #
27
+
28
+ ##
29
+ # new() does not take any parameters.
30
+
31
+ def initialize
32
+ # initialize errors, warnings, notes, misc
33
+ @messages = Xeme::Messages.new
34
+ @misc = {}
35
+
36
+ # prefix and auto_misc
37
+ @prefixes = []
38
+ @auto_details_val = nil
39
+
40
+ # transaction
41
+ @transaction = nil
42
+ end
43
+ #
44
+ # initialize
45
+ #---------------------------------------------------------------------------
46
+
47
+
48
+ #---------------------------------------------------------------------------
49
+ # errors, warnings, notes
50
+ #
51
+
52
+ ##
53
+ # Returns the array of errors.
54
+ def errors
55
+ return @messages['errors']
56
+ end
57
+
58
+ ##
59
+ # Returns the array of warnings.
60
+ def warnings
61
+ return @messages['warnings']
62
+ end
63
+
64
+ ##
65
+ # Returns the array of notes.
66
+ def notes
67
+ return @messages['notes']
68
+ end
69
+ #
70
+ # errors, warnings, notes
71
+ #---------------------------------------------------------------------------
72
+
73
+
74
+ #---------------------------------------------------------------------------
75
+ # transaction
76
+ #
77
+
78
+ ##
79
+ # Returns the transaction object, creating it if necessary. See
80
+ # Xeme::Transaction. If the transaction object is never created then it is
81
+ # not output with #to_json. The transaction object can be used to provide
82
+ # meta information about the request and response that produced the
83
+ # results. See Xeme::Transaction for more information.
84
+ #
85
+ # You can create the transaction object by simply calling this method:
86
+ #
87
+ # xeme.transaction
88
+ #
89
+ # If you want to assign a request ID, call this method and assign to its
90
+ # request property. For example, if there's a request object that provides
91
+ # an id, you could assign the transaction.request ID like this:
92
+ #
93
+ # xeme.transaction.request = request.id
94
+
95
+ def transaction
96
+ @transaction ||= Xeme::Transaction.new()
97
+ return @transaction
98
+ end
99
+ #
100
+ # transaction
101
+ #---------------------------------------------------------------------------
102
+
103
+
104
+ #---------------------------------------------------------------------------
105
+ # to_h
106
+ #
107
+
108
+ ##
109
+ # Returns a hash with all the results. This hash can be used to create a JSON
110
+ # object. Empty arrays, such as if there are no warnings, are not included.
111
+
112
+ def to_h
113
+ # $tm.hrm
114
+
115
+ # initialize return value
116
+ rv = {}
117
+
118
+ # success
119
+ rv['success'] = success()
120
+
121
+ # transaction
122
+ if @transaction
123
+ rv['transaction'] = @transaction.to_h
124
+ end
125
+
126
+ # if any messages
127
+ if @messages.any?
128
+ msgs = rv['messages'] = {}
129
+
130
+ @messages.each do |key, arr|
131
+ if arr.any?
132
+ msgs[key] = []
133
+
134
+ arr.each do |msg|
135
+ msgs[key].push msg.to_h
136
+ end
137
+ end
138
+ end
139
+ end
140
+
141
+ # misc
142
+ if @misc.any?
143
+ rv['misc'] = @misc
144
+ end
145
+
146
+ # return
147
+ return rv
148
+ end
149
+ #
150
+ # to_h
151
+ #---------------------------------------------------------------------------
152
+
153
+
154
+ #---------------------------------------------------------------------------
155
+ # to_json
156
+ #
157
+
158
+ ##
159
+ # Returns a JSON string containing all the result information.
160
+ def to_json(opts={})
161
+ if opts['pretty']
162
+ return JSON.pretty_generate(self.to_h)
163
+ else
164
+ return JSON.generate(self.to_h)
165
+ end
166
+ end
167
+ #
168
+ # to_json
169
+ #---------------------------------------------------------------------------
170
+
171
+
172
+ #---------------------------------------------------------------------------
173
+ # success
174
+ #
175
+
176
+ ##
177
+ # Returns false if there are any errors, true otherwise.
178
+
179
+ def success
180
+ return @messages['errors'].empty?
181
+ end
182
+
183
+ ##
184
+ # Returns the opposite of <tt>success()</tt>.
185
+ def failure
186
+ return success ? false : true
187
+ end
188
+
189
+ #
190
+ # success
191
+ #---------------------------------------------------------------------------
192
+
193
+
194
+ #---------------------------------------------------------------------------
195
+ # exception
196
+ #
197
+
198
+ ##
199
+ # Use this method to hold on to details about an exception. An error object
200
+ # will be created, along with the exception's to_s backtrace.
201
+
202
+ def exception(id, e, details={})
203
+ message = self.error(id, details)
204
+ message.details['error'] = e.to_s
205
+ message.details['backtrace'] = e.backtrace
206
+ end
207
+ #
208
+ # exception
209
+ #---------------------------------------------------------------------------
210
+
211
+
212
+ #---------------------------------------------------------------------------
213
+ # prefix
214
+ #
215
+
216
+ ##
217
+ # <tt>prefix</tt> allows you to automatically add prefixes to your message
218
+ # codes in situations where many messages will start with the same string.
219
+ # Consider the following situation.
220
+ #
221
+ # xeme.error '/virginia/slope'
222
+ # xeme.error '/virginia/angle'
223
+ # xeme.error '/virginia/departure'
224
+ #
225
+ # That works, but the redundancy can get confusing (and annoying). With
226
+ # <tt>prefix</tt> you can avoid the redundancy like this:
227
+ #
228
+ # xeme.prefix('virginia') do
229
+ # xeme.error 'slope'
230
+ # xeme.error 'angle'
231
+ # xeme.error 'departure'
232
+ # end
233
+ #
234
+ # puts xeme.errors[0].id # /virginia/slope
235
+ # puts xeme.errors[1].id # /virginia/angle
236
+ # puts xeme.errors[2].id # /virginia/departure
237
+ #
238
+ # Prefixes can also be nested, like this:
239
+ #
240
+ # xeme.prefix('virginia') do
241
+ # xeme.prefix('fairfax') do
242
+ # xeme.error 'slope'
243
+ # end
244
+ # end
245
+ #
246
+ # puts xeme.errors[0].id # /virginia/fairfax/slope
247
+
248
+ def prefix(p_prefix)
249
+ # $tm.hrm
250
+ hold_prefixes = @prefixes.clone
251
+ @prefixes = @prefixes.clone
252
+ @prefixes.push p_prefix
253
+
254
+ begin
255
+ yield
256
+ ensure
257
+ @prefixes = hold_prefixes
258
+ end
259
+ end
260
+ #
261
+ # prefix
262
+ #---------------------------------------------------------------------------
263
+
264
+
265
+ #---------------------------------------------------------------------------
266
+ # error, warning, note
267
+ #
268
+
269
+ ##
270
+ # Creates a message object and stores it in the errors array.
271
+ #
272
+ # xeme.error('error-1').
273
+ #
274
+ # A hash of arbitrary details can be given. Those details will be stored
275
+ # with the message object in its Xeme::Message#details property.
276
+ #
277
+ # xeme.error('error-0', 'choice'=>'a')
278
+ #
279
+ # This method returns the message object, which can be used as another
280
+ # way to store details.
281
+ #
282
+ # msg = xeme.error('error-1').
283
+ # msg['location'] = 1
284
+ #
285
+ # If a block is given, the block is called with the error object as the
286
+ # single param.
287
+ #
288
+ # xeme.error('error-2') do |error|
289
+ # error['location'] = 2
290
+ # end
291
+ def error(id, details={}, &block)
292
+ return add_comment(Xeme::Message, 'errors', id, details={}, &block)
293
+ end
294
+
295
+ ##
296
+ # Works just #error() except it stores the message in the warnings array.
297
+ def warning(id, details={}, &block)
298
+ return add_comment(Xeme::Message, 'warnings', id, details={}, &block)
299
+ end
300
+
301
+ ##
302
+ # Works just #error() except it stores the message in the notes array.
303
+ def note(id, details={}, &block)
304
+ return add_comment(Xeme::Message, 'notes', id, details={}, &block)
305
+ end
306
+ #
307
+ # error, warning, note
308
+ #---------------------------------------------------------------------------
309
+
310
+
311
+ #---------------------------------------------------------------------------
312
+ # from_json
313
+ #
314
+
315
+ ##
316
+ # Creates a new Xeme object from a JSON structure.
317
+
318
+ def self.from_json(raw_json)
319
+ # $tm.hrm
320
+ hsh = JSON.parse(raw_json)
321
+ rv = self.new
322
+
323
+ # explicit success or failure
324
+ if not hsh['success'].nil?
325
+ rv.success = hsh['success']
326
+ end
327
+
328
+ # messages
329
+ if messages = hsh['messages']
330
+ messages.each do |msg_type, arr|
331
+ rv.messages[msg_type] ||= []
332
+ rv.messages[msg_type] += arr
333
+ end
334
+ end
335
+
336
+ # return
337
+ return rv
338
+ end
339
+ #
340
+ # from_json
341
+ #---------------------------------------------------------------------------
342
+
343
+
344
+ # private methods
345
+ private
346
+
347
+
348
+ #---------------------------------------------------------------------------
349
+ # messages_to_h
350
+ #
351
+ def messages_to_h(arr)
352
+ rv = []
353
+
354
+ # messages
355
+ arr.each do |msg|
356
+ rv.push msg.to_h
357
+ end
358
+
359
+ # return
360
+ return rv
361
+ end
362
+ #
363
+ # messages_to_h
364
+ #---------------------------------------------------------------------------
365
+
366
+
367
+ #---------------------------------------------------------------------------
368
+ # add_comment
369
+ #
370
+ def add_comment(cls, type, id, details={}, &block)
371
+ # $tm.hrm
372
+
373
+ # build message
374
+ msg = cls.new(prefix_id(id), details)
375
+
376
+ # ensure array
377
+ @messages[type] ||= []
378
+
379
+ # add to errors array
380
+ @messages[type].push(msg)
381
+
382
+ # yield
383
+ if block_given?
384
+ yield msg
385
+ end
386
+
387
+ # return
388
+ return msg
389
+ end
390
+ #
391
+ # add_comment
392
+ #---------------------------------------------------------------------------
393
+
394
+
395
+ #---------------------------------------------------------------------------
396
+ # prefix_id
397
+ #
398
+ def prefix_id(p_id)
399
+ if @prefixes.any?
400
+ return '/' + @prefixes.join('/') + '/' + p_id
401
+ else
402
+ return p_id
403
+ end
404
+ end
405
+ #
406
+ # prefix_id
407
+ #---------------------------------------------------------------------------
408
+ end
409
+ #
410
+ # Xeme
411
+ #===============================================================================
412
+
413
+
414
+ #===============================================================================
415
+ # Xeme::Message
416
+ #
417
+
418
+ ##
419
+ # A Xeme::Message object represents a single error, warning, or note.
420
+ # It is the base class for Xeme::Message::Error,
421
+ # Xeme::Message::Warning, and
422
+ # Xeme::Message::Note. Don't instantiate Xeme::Message
423
+ # directly, use Xeme#error, Xeme#warning, or Xeme#note.
424
+ #
425
+ # Each message contains at least an id. It can also have an options details
426
+ # hash which can be used to store misc information about the message.
427
+ #
428
+ # The message itself can be treated like a hash to give details:
429
+ #
430
+ # msg = xeme.error('my-error')
431
+ # msg['location'] = 1
432
+
433
+ class Xeme::Message
434
+ # The id of the message.
435
+ attr_reader :id
436
+
437
+ # delegate to hsh
438
+ extend Forwardable
439
+ delegate %w([] []= each length clear delete) => :@details
440
+
441
+
442
+ #---------------------------------------------------------------------------
443
+ # initialize
444
+ #
445
+
446
+ # Initialize a Xeme::Message object with the id of the message. The id can
447
+ # be any string. The optional <tt>details</tt> hash will be stored with the
448
+ # message.
449
+
450
+ def initialize(id, details={})
451
+ # $tm.hr __method__
452
+
453
+ # set id
454
+ @id = id
455
+
456
+ # initialize details
457
+ @details = details.clone
458
+ end
459
+ #
460
+ # initialize
461
+ #---------------------------------------------------------------------------
462
+
463
+
464
+ #---------------------------------------------------------------------------
465
+ # to_h
466
+ #
467
+
468
+ ##
469
+ # Returns a hash structure of the message. This structure is used by
470
+ # Xeme#to_h.
471
+
472
+ def to_h
473
+ rv = {}
474
+ rv['id'] = @id
475
+
476
+ if @details.any?
477
+ rv['details'] = @details
478
+ end
479
+
480
+ return rv
481
+ end
482
+ #
483
+ # to_h
484
+ #---------------------------------------------------------------------------
485
+ end
486
+ #
487
+ # Xeme::Message
488
+ #===============================================================================
489
+
490
+
491
+ #===============================================================================
492
+ # Xeme::Messages
493
+ #
494
+
495
+ ##
496
+ # This object holds the arrays of errors, warnings, and notes. It can mostly be
497
+ # treated like a hash. The main difference between a Xeme::Messages object and
498
+ # a hash is that any? returns true or false based on if there are any messages,
499
+ # not if there are any elements in the hash.
500
+
501
+ class Xeme::Messages
502
+ # delegate to hsh
503
+ extend Forwardable
504
+ delegate %w([] []= each length keys has_key?) => :@hsh
505
+
506
+ #---------------------------------------------------------------------------
507
+ # initialize
508
+ #
509
+
510
+ ##
511
+ # new() takes no parameters.
512
+
513
+ def initialize
514
+ @hsh = {}
515
+ @hsh['errors'] = []
516
+ @hsh['warnings'] = []
517
+ @hsh['notes'] = []
518
+ end
519
+ #
520
+ # initialize
521
+ #---------------------------------------------------------------------------
522
+
523
+
524
+ #---------------------------------------------------------------------------
525
+ # any?
526
+ #
527
+
528
+ ##
529
+ # Returns if there are any messages in any of the errors, warnings, or
530
+ # notes arrays.
531
+
532
+ def any?
533
+ @hsh.values.each do |arr|
534
+ arr.any? and return true
535
+ end
536
+
537
+ return false
538
+ end
539
+ #
540
+ # any?
541
+ #---------------------------------------------------------------------------
542
+ end
543
+ #
544
+ # Xeme::Messages
545
+ #===============================================================================
546
+
547
+
548
+ #===============================================================================
549
+ # Xeme::Transaction
550
+ #
551
+
552
+ ##
553
+ # An object of this class provdes meta information about the request and
554
+ # results. It always provides a a timestamp and a unique ID for the results. It
555
+ # may also optionally include a request ID that was provided by the process
556
+ # that made the request, such as a call to a REST application. Do not directly
557
+ # instantiate this class; use Xeme#transaction.
558
+
559
+ class Xeme::Transaction
560
+
561
+ # Optional. An ID for the request that was sent by the calling process. Do
562
+ # not generate this value yourself; use the ID that was sent with the
563
+ # request (if one was sent).
564
+ attr_accessor :request
565
+
566
+ # Gives a unique ID for these results.
567
+ attr_reader :response
568
+
569
+ # Gives a timestamp for when these results were generated.
570
+ attr_reader :timestamp
571
+
572
+ #---------------------------------------------------------------------------
573
+ # initialize
574
+ #
575
+
576
+ ##
577
+ # Initialize does not take any parameters.
578
+
579
+ def initialize
580
+ @timestamp = DateTime.now()
581
+ @response = rand().to_s.sub(/\A0\./mu, '')
582
+ @request = nil
583
+ end
584
+ #
585
+ # initialize
586
+ #---------------------------------------------------------------------------
587
+
588
+
589
+ #---------------------------------------------------------------------------
590
+ # to_h
591
+ #
592
+ def to_h
593
+ rv = {}
594
+
595
+ # request
596
+ if @request
597
+ rv['request'] = @request
598
+ end
599
+
600
+ # response and timestamp
601
+ rv['response'] = @response
602
+ rv['timestamp'] = @timestamp.to_s
603
+
604
+ # return
605
+ return rv
606
+ end
607
+ #
608
+ # to_h
609
+ #---------------------------------------------------------------------------
610
+ end
611
+ #
612
+ # Xeme::Transaction
613
+ #===============================================================================
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: xeme
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Mike O'Sullivan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-01-06 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Provides a common means for reporting results between processes
14
+ email: mike@idocs.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - README.md
20
+ - lib/xeme.rb
21
+ homepage: https://rubygems.org/gems/xeme
22
+ licenses:
23
+ - MIT
24
+ metadata: {}
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubyforge_project:
41
+ rubygems_version: 2.7.6
42
+ signing_key:
43
+ specification_version: 4
44
+ summary: General purpose structure for reporting results
45
+ test_files: []