Exception: ViewModel::DeserializationError::UniqueViolation

Inherits:
ViewModel::DeserializationError show all
Defined in:
lib/view_model/deserialization_error.rb

Constant Summary collapse

PG_ERROR_FIELD_CONSTRAINT_NAME =

Not exposed in pg gem

'n'.ord
DETAIL_PREFIX =
'Key ('
DETAIL_SUFFIX =
') already exists.'
DETAIL_INFIX =
')=('

Instance Attribute Summary collapse

Attributes inherited from AbstractErrorWithBlame

#nodes

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from ViewModel::DeserializationError

#code

Methods inherited from AbstractError

#aggregation?, #causes, #code, #exception, #status, #title, #to_s, #view

Constructor Details

#initialize(detail, constraint, columns, values, nodes = []) ⇒ UniqueViolation

Returns a new instance of UniqueViolation.



427
428
429
430
431
432
433
# File 'lib/view_model/deserialization_error.rb', line 427

def initialize(detail, constraint, columns, values, nodes = [])
  @detail     = detail
  @constraint = constraint
  @columns    = columns
  @values     = values
  super(nodes)
end

Instance Attribute Details

#columnsObject (readonly)

Returns the value of attribute columns.



360
361
362
# File 'lib/view_model/deserialization_error.rb', line 360

def columns
  @columns
end

#constraintObject (readonly)

Returns the value of attribute constraint.



360
361
362
# File 'lib/view_model/deserialization_error.rb', line 360

def constraint
  @constraint
end

#detailObject (readonly)

Returns the value of attribute detail.



360
361
362
# File 'lib/view_model/deserialization_error.rb', line 360

def detail
  @detail
end

#valuesObject (readonly)

Returns the value of attribute values.



360
361
362
# File 'lib/view_model/deserialization_error.rb', line 360

def values
  @values
end

Class Method Details

.from_postgres_error(err, nodes) ⇒ Object



363
364
365
366
367
368
369
370
371
372
373
374
375
376
# File 'lib/view_model/deserialization_error.rb', line 363

def self.from_postgres_error(err, nodes)
  result         = err.result
  constraint     = result.error_field(PG_ERROR_FIELD_CONSTRAINT_NAME)
  message_detail = result.error_field(PG::Result::PG_DIAG_MESSAGE_DETAIL)

  columns, values = parse_message_detail(message_detail)

  unless columns
    # Couldn't parse the detail message, fall back on an unparsed error
    return DatabaseConstraint.new(err.message, nodes)
  end

  self.new(err.message, constraint, columns, values, nodes)
end

.parse_message_detail(detail) ⇒ Object



382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
# File 'lib/view_model/deserialization_error.rb', line 382

def parse_message_detail(detail)
  stream = detail.dup

  return nil unless stream.delete_prefix!(DETAIL_PREFIX)
  return nil unless stream.delete_suffix!(DETAIL_SUFFIX)

  # The message should start with an identifier list: pop off identifier
  # tokens while we can.
  identifiers = []

  identifier = parse_identifier(stream)
  return nil unless identifier

  identifiers << identifier

  while stream.delete_prefix!(', ')
    identifier = parse_identifier(stream)
    return nil unless identifier

    identifiers << identifier
  end

  # The message should now contain ")=(" followed by the (unparseable)
  # value list.
  return nil unless stream.delete_prefix!(DETAIL_INFIX)

  [identifiers, stream]
end

Instance Method Details

#metaObject



435
436
437
# File 'lib/view_model/deserialization_error.rb', line 435

def meta
  super.merge(constraint: @constraint, columns: @columns, values: @values)
end