Class: Brick::SalesforceSchema

Inherits:
Nokogiri::XML::SAX::Document
  • Object
show all
Includes:
MigrationsBuilder
Defined in:
lib/generators/brick/salesforce_schema.rb

Constant Summary

Constants included from MigrationsBuilder

MigrationsBuilder::SQL_TYPES

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from MigrationsBuilder

check_folder, generate_migrations

Constructor Details

#initialize(end_doc_proc) ⇒ SalesforceSchema

Returns a new instance of SalesforceSchema.

[View source]

9
10
11
# File 'lib/generators/brick/salesforce_schema.rb', line 9

def initialize(end_doc_proc)
  @end_document_proc = end_doc_proc
end

Instance Attribute Details

#end_document_procObject (readonly)

Returns the value of attribute end_document_proc.


7
8
9
# File 'lib/generators/brick/salesforce_schema.rb', line 7

def end_document_proc
  @end_document_proc
end

Instance Method Details

#characters(string) ⇒ Object

[View source]

98
99
100
101
102
103
# File 'lib/generators/brick/salesforce_schema.rb', line 98

def characters(string)
  # p [:characters, string]
  @text_stack.each do |text|
    text << string
  end
end

#end_documentObject

[View source]

21
22
23
24
# File 'lib/generators/brick/salesforce_schema.rb', line 21

def end_document
  puts
  end_document_proc&.call(@salesforce_tables)
end

#end_element_namespace(name, prefix = nil, uri = nil) ⇒ Object

[View source]

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/generators/brick/salesforce_schema.rb', line 71

def end_element_namespace(name, prefix = nil, uri = nil)
  # p [:end_element, name, prefix, uri]
  texts = @text_stack.pop
  case name
  when 'extension'
    @last_extension = nil
  when 'complexType'
    if @last_table && !@last_table.is_a?(String)
      # Do up any foreign keys
      @fks.each do |k, v|
        # Only a few records set up like this, going to sObject
        if 
          # (k.downcase.end_with?('recordid') &&
          #   (fk_col = @last_table[:cols].find { |t| t[:name] == "#{k[0..-9]}Id" })
          #  ) ||
           (fk_col = @last_table[:cols].find { |t| t[:name] == k })
          fk_col[:fk_reference_to] = v
          # puts "Skipping #{@last_table[:name]} / #{k}"
        end
      end
    end
    print '.'
    @last_table = nil
  end
  # p [:end_element_texts, name, texts]
end

#start_documentObject

[View source]

13
14
15
16
17
18
19
# File 'lib/generators/brick/salesforce_schema.rb', line 13

def start_document
  # p [:start_document]
  @salesforce_tables = {}
  @text_stack = []
  @all_extends = {}
  puts 'Each dot is a table:'
end

#start_element_namespace(name, attrs = [], prefix = nil, uri = nil, ns = []) ⇒ Object

[View source]

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/generators/brick/salesforce_schema.rb', line 26

def start_element_namespace(name, attrs = [], prefix = nil, uri = nil, ns = [])
  # p [:start_element, name, attrs, prefix, uri, ns]
  case name
  when 'complexType' # Table
    @last_table = attrs.find { |a| a.localname == 'name' }&.value
    @fks = {}
    # if attrs.first&.value&.end_with?('__c') # Starts as a string
  when 'extension'
    @last_extension = attrs.find { |a| a.localname == 'base' }.value
  when 'element' # Column
    # Extremely rarely this is nil!
    data_type = attrs.find { |a| a.localname == 'type' }&.value
    return if !@last_table || data_type.nil? || data_type == 'tns:QueryResult'

    # Promoted to a real SalesforceTable object
    if @last_table.is_a?(String)
      @last_table = @salesforce_tables[@last_table] = { extend: @salesforce_tables[@last_extension] }
    end

    col_name = attrs.find { |a| a.localname == 'name' }&.value

    # Foreign key reference?
    if data_type&.start_with?('ens:')
      foreign_table = data_type[4..]
      if col_name.end_with?('__r')
        @fks["#{col_name[0..-2]}c"] = foreign_table
      else # if col_name.end_with?('Id')
        @fks["#{col_name}Id"] = foreign_table
      end
      return
    end

    # Rarely this is nil
    nillable = attrs.find { |a| a.localname == 'nillable' }&.value == 'true'
    min_occurs = attrs.find { |a| a.localname == 'minOccurs' }&.value || -2
    min_occurs = -1 if min_occurs == 'unbounded'
    max_occurs = attrs.find { |a| a.localname == 'maxOccurs' }&.value || -2
    max_occurs = -1 if max_occurs == 'unbounded'
    col_options = { name: col_name, data_type: :data_type, nillable: :nillable, min_occurs: :min_occurs, max_occurs: :max_occurs }

    (@last_table[:cols] ||= []) << col_options
  end
  @text_stack.push +''
end