Class: Parse::Schema::Migration

Inherits:
Object
  • Object
show all
Defined in:
lib/parse/schema.rb

Overview

Represents a schema migration to be applied.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model_class, diff, client: nil) ⇒ Migration

Returns a new instance of Migration.



351
352
353
354
355
# File 'lib/parse/schema.rb', line 351

def initialize(model_class, diff, client: nil)
  @model_class = model_class
  @diff = diff
  @client = client || Parse.client
end

Instance Attribute Details

#clientObject (readonly)

Returns the value of attribute client.



349
350
351
# File 'lib/parse/schema.rb', line 349

def client
  @client
end

#diffObject (readonly)

Returns the value of attribute diff.



349
350
351
# File 'lib/parse/schema.rb', line 349

def diff
  @diff
end

#model_classObject (readonly)

Returns the value of attribute model_class.



349
350
351
# File 'lib/parse/schema.rb', line 349

def model_class
  @model_class
end

Instance Method Details

#apply!(dry_run: false) ⇒ Hash

Apply the migration to the server.

Parameters:

  • dry_run (Boolean) (defaults to: false)

    if true, only preview without applying

Returns:

  • (Hash)

    results of the migration



403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
# File 'lib/parse/schema.rb', line 403

def apply!(dry_run: false)
  return { status: :skipped, message: "No migration needed" } unless needed?

  if dry_run
    return { status: :preview, operations: operations, preview: preview }
  end

  results = { status: :success, applied: [], errors: [] }

  # Create class if needed
  unless @diff.server_exists?
    schema = build_schema
    response = @client.create_schema(@model_class.parse_class, schema)
    if response.success?
      results[:applied] << { action: :create_class, class_name: @model_class.parse_class }
    else
      results[:errors] << { action: :create_class, error: response.error }
      results[:status] = :partial
    end
    return results
  end

  # Add missing fields
  @diff.missing_on_server.each do |name, type|
    field_name = name.to_s.camelize(:lower)
    field_schema = { "fields" => { field_name => field_definition(type) } }

    response = @client.update_schema(@model_class.parse_class, field_schema)
    if response.success?
      results[:applied] << { action: :add_field, field: field_name, type: type }
    else
      results[:errors] << { action: :add_field, field: field_name, error: response.error }
      results[:status] = :partial
    end
  end

  results[:status] = :failed if results[:applied].empty? && results[:errors].any?
  results
end

#needed?Boolean

Check if migration is needed.

Returns:

  • (Boolean)


359
360
361
# File 'lib/parse/schema.rb', line 359

def needed?
  !@diff.in_sync? || !@diff.server_exists?
end

#operationsArray<Hash>

Get the operations that would be performed.

Returns:



365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
# File 'lib/parse/schema.rb', line 365

def operations
  ops = []

  unless @diff.server_exists?
    ops << { action: :create_class, class_name: @model_class.parse_class }
  end

  @diff.missing_on_server.each do |name, type|
    ops << {
      action: :add_field,
      field: name.to_s.camelize(:lower),
      type: REVERSE_TYPE_MAP[type] || "String",
    }
  end

  ops
end

#previewString

Preview the migration without applying.

Returns:

  • (String)

    human-readable preview



385
386
387
388
389
390
391
392
393
394
395
396
397
398
# File 'lib/parse/schema.rb', line 385

def preview
  return "No migration needed" unless needed?

  lines = ["Migration for #{@model_class.parse_class}:"]
  operations.each do |op|
    case op[:action]
    when :create_class
      lines << "  CREATE CLASS #{op[:class_name]}"
    when :add_field
      lines << "  ADD FIELD #{op[:field]} (#{op[:type]})"
    end
  end
  lines.join("\n")
end