class ActiveFacts::Generators::Doc::LDM

Constants

MM

Public Class Methods

compatibility() click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 24
def self.compatibility
  [1, %i{relational}]   # one relational composition
end
new(constellation, composition, options = {}) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 28
def initialize constellation, composition, options = {}
  @constellation = constellation
  @composition = [composition].flatten[0]
  @options = options
  @underscore = options.has_key?("underscore") ? (options['underscore'] || '_') : ''

  @vocabulary = composition.constellation.Vocabulary.values[0]      # REVISIT when importing from other vocabularies
  # glossary_options = {"gen_bootstrap" => true}
  # @glossary = GLOSSARY.new(@vocabulary, glossary_options)
end
options() click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 18
def self.options
  {
    underscore: [String, "Use 'str' instead of underscore between words in table names"]
  }
end

Public Instance Methods

boolean_type() click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 466
def boolean_type
  'boolean'
end
check_clause(column_name, value_constraint) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 678
def check_clause column_name, value_constraint
  " CHECK(" +
    value_constraint.all_allowed_range_sorted.map do |ar|
      vr = ar.value_range
      min = vr.minimum_bound
      max = vr.maximum_bound
      if (min && max && max.value.literal == min.value.literal)
        "#{column_name} = #{sql_value(min.value)}"
      else
        inequalities = [
          min && "#{column_name} >#{min.is_inclusive ? "=" : ""} #{sql_value(min.value)}",
          max && "#{column_name} <#{max.is_inclusive ? "=" : ""} #{sql_value(max.value)}"
        ].compact
        inequalities.size > 1 ? "(" + inequalities*" AND " + ")" : inequalities[0]
      end
    end*" OR " +
  ")"
end
column_comment(component) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 448
def column_comment component
  return '' unless cp = component.parent
  prefix = column_comment(cp)
  name = component.name
  if component.is_a?(MM::Absorption)
    reading = component.parent_role.fact_type.reading_preferably_starting_with_role(component.parent_role).expand([], false)
    maybe = component.parent_role.is_mandatory ? '' : 'maybe '
    cpname = cp.name
    if prefix[(-cpname.size-1)..-1] == ' '+cpname && reading[0..cpname.size] == cpname+' '
      prefix+' that ' + maybe + reading[cpname.size+1..-1]
    else
      (prefix.empty? ? '' : prefix+' and ') + maybe + reading
    end
  else
    name
  end
end
column_name(component) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 79
def column_name component
  component.column_name.capcase
end
column_name_max() click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 55
def column_name_max
  40
end
component_type(component, column_name) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 474
def component_type component, column_name
  case component
  when MM::Indicator
    boolean_type
  when MM::SurrogateKey
    surrogate_type
  when MM::ValueField, MM::Absorption
    object_type = component.object_type
    while object_type.is_a?(MM::EntityType)
      rr = object_type.preferred_identifier.role_sequence.all_role_ref.single
      raise "Can't produce a column for composite #{component.inspect}" unless rr
      object_type = rr.role.object_type
    end
    raise "A column can only be produced from a ValueType" unless object_type.is_a?(MM::ValueType)

    if component.is_a?(MM::Absorption)
      value_constraint ||= component.child_role.role_value_constraint
    end

    supertype = object_type
    begin
      object_type = supertype
      length ||= object_type.length
      scale ||= object_type.scale
      unless component.parent.parent and component.parent.foreign_key
        # No need to enforce value constraints that are already enforced by a foreign key
        value_constraint ||= object_type.value_constraint
      end
    end while supertype = object_type.supertype
    type, length = normalise_type(object_type.name, length)
    sql_type = "#{type}#{
      if !length
        ''
      else
        '(' + length.to_s + (scale ? ", #{scale}" : '') + ')'
      end
    # }#{
    #   (component.path_mandatory ? '' : ' NOT') + ' NULL'
    # }#{
    #   # REVISIT: This is an SQL Server-ism. Replace with a standard SQL SEQUENCE/
    #   # Emit IDENTITY for columns auto-assigned on commit (except FKs)
    #   if a = object_type.is_auto_assigned and a != 'assert' and
    #       !component.all_foreign_key_field.detect{|fkf| fkf.foreign_key.source_composite == component.root}
    #     ' IDENTITY'
    #   else
    #     ''
    #   end
    }#{
      value_constraint ? check_clause(column_name, value_constraint) : ''
    }"
  when MM::ValidFrom
    component.object_type.name
  else
    raise "Can't make a column from #{component}"
  end
end
div(text, klass = nil) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 192
def div(text, klass = nil)
  element(text, klass ? {:class => klass} : {}, 'div')
end
dl(text, klass = nil) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 208
def dl(text, klass = nil)
  element(text, klass ? {:class => klass} : {}, 'dl')
end
element(text, attrs, tag = 'span') click to toggle source

Standard document elements

# File lib/activefacts/generator/doc/ldm.rb, line 184
def element(text, attrs, tag = 'span')
  "<#{tag}#{attrs.empty? ? '' : attrs.map{|k,v| " #{k}='#{v}'"}*''}>#{text}</#{tag}>"
end
entity_type_dump(o, level) click to toggle source

Dump functions

# File lib/activefacts/generator/doc/ldm.rb, line 235
def entity_type_dump(o, level)
  pi = o.preferred_identifier
  supers = o.supertypes
  if (supers.size > 0) # Ignore identification by a supertype:
    pi = nil if pi && pi.role_sequence.all_role_ref.detect{ |rr|
        rr.role.fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance)
       }
  end

  cn_array = o.concept.all_context_note_as_relevant_concept.map{|cn| [cn.context_note_kind, cn.discussion] }
  cn_hash = cn_array.inject({}) do |hash, value|
          hash[value.first] = value.last
          hash
        end

  informal_defn = cn_hash["because"]
  defn_term =
    "              <div class=\"row\">\n" +
    "                <div class=\"col-md-12 definition\">\n" +
    "                  A #{termdef(o.name)} #{informal_defn ? 'is ' + informal_defn : ''}\n" +
    "                </div>\n" +
    "              </div>\n"

  defn_detail =
    "              <div class=\"row\">\n" +
    "                <div class=\"col-md-12 details\">\n" +
    (supers.size > 0 ?
      "#{span('Each', 'keyword')} #{termref(o.name, nil, o)} #{span('is a kind of', 'keyword')} #{supers.map{|s| termref(s.name, nil, s)}*', '}\n" :
      ''
    ) +
    if pi
      "#{span('Each', 'keyword')} #{termref(o.name, nil, o)} #{span('is identified by', 'keyword')} " +
      pi.role_sequence.all_role_ref_in_order.map do |rr|
        termref(
          rr.role.object_type.name,
          [ rr.leading_adjective,
            rr.role.role_name || rr.role.object_type.name,
            rr.trailing_adjective
          ].compact * '-',
          rr.role.object_type
        )
      end * ", " + "\n"
    else
      ''
    end +
    fact_types_dump(o, relevant_fact_types(o)) + "\n" +
    "                </div>\n" +
    "              </div>\n"

  defn_term + defn_detail
end
escape(s, max = table_name_max) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 593
def escape s, max = table_name_max
  # Escape SQL keywords and non-identifiers
  if s.size > max
    excess = s[max..-1]
    s = s[0...max-(excess.size/8)] +
      Digest::SHA1.hexdigest(excess)[0...excess.size/8]
  end

  if s =~ /[^A-Za-z0-9_]/ || is_reserved_word(s)
    "[#{s}]"
  else
    s
  end
end
expand_fact_type(ft, wrt = nil, include_rolenames = true, wrt_qualifier = '') click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 326
def expand_fact_type(ft, wrt = nil, include_rolenames = true, wrt_qualifier = '')
  role = ft.all_role.detect{|r| r.object_type == wrt}
  preferred_reading = ft.reading_preferably_starting_with_role(role)
  alternate_readings = ft.all_reading.reject{|r| r == preferred_reading}

  div(
    expand_reading(preferred_reading, include_rolenames, wrt, wrt_qualifier),
    'glossary-reading'
  )
end
expand_reading(reading, include_rolenames = true, wrt = nil, wrt_qualifier = '') click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 347
def expand_reading(reading, include_rolenames = true, wrt = nil, wrt_qualifier = '')
  role_refs = reading.role_sequence.all_role_ref.sort_by{|role_ref| role_ref.ordinal}
  lrr = role_refs[role_refs.size - 1]
  element(
    # element(rr.role.is_unique ? "one" : "some", :class=>:keyword) +
    reading.expand([], include_rolenames) do |rr, freq_con, l_adj, name, t_adj, role_name_def, literal|
      if role_name_def
        role_name_def = role_name_def.gsub(/\(as ([^)]+)\)/) {
          span("(as #{ termref(rr.role.object_type.name, $1, rr.role.object_type) })", 'keyword')
        }
      end
      # qualify the last role of the reading
      quantifier = ''
      if rr == lrr
        uniq = true
        (0 ... role_refs.size - 2).each{|i| uniq = uniq && role_refs[i].role.is_unique }
        quantifier =  uniq ? "one" : "at least one"
      end
      role_ref(rr, quantifier, l_adj, name, t_adj, role_name_def, literal)
    end,
    {:class => 'reading'}
  )
end
fact_type_block(ft, wrt = nil, include_rolenames = true) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 322
def fact_type_block(ft, wrt = nil, include_rolenames = true)
  div(expand_fact_type(ft, wrt, include_rolenames, ''), 'glossary-facttype')
end
fact_type_dump(ft, wrt = nil) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 310
def fact_type_dump(ft, wrt = nil)
  if ft.entity_type
    div(
      div(span('Each ', 'keyword') + termref(ft.entity_type.name, nil, ft.entity_type) + span(' is where ', 'keyword')) +
      div(expand_fact_type(ft, wrt, true, 'some')),
      'glossary-objectification'
    )
  else
    fact_type_block(ft, wrt)
  end
end
fact_types_dump(o, ftm) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 303
def fact_types_dump(o, ftm)
  ftm.
      map { |r, ft| [ft, "    #{fact_type_dump(ft, o)}"] }.
      sort_by{|ft, text| [ ft.is_a?(ActiveFacts::Metamodel::TypeInheritance) ? 0 : 1, text]}.
      map{|ft, text| text} * "\n"
end
generate() click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 39
def generate
  @tables_emitted = {}

  # trace.enable 'ldm'

  generate_header +
  generate_definitions +
  generate_diagrams +
  generate_details +
  generate_footer
end
generate_column(leaf, indent) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 432
def generate_column leaf, indent
  column_name = safe_column_name(leaf)
  padding = " "*(column_name.size >= column_name_max ? 1 : column_name_max-column_name.size)
  constraints = leaf.all_leaf_constraint

  identity = ''

  "  " * indent + "<tr>\n" +
  "  " * indent + "  <td>#{column_name}\n" +
  "  " * indent + "  <td>#{component_type(leaf, column_name)}\n" +
  "  " * indent + "  <td>#{leaf.path_mandatory ? 'Yes' : 'No'}\n" +
  "  " * indent + "  <td>#{column_comment leaf}\n" +
  "  " * indent + "</tr>"
  # "-- #{column_comment leaf}\n\t#{column_name}#{padding}#{component_type leaf, column_name}#{identity}"
end
generate_definitions() click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 117
def generate_definitions
  defns =
    @composition.
      all_composite.
      reject {|c| c.mapping.object_type.is_a?(ActiveFacts::Metamodel::ValueType)}.
      reject {|c| c.mapping.object_type.is_static}.
      reject {|c| c.mapping.object_type.fact_type}.
      map {|c| c.mapping.object_type}

  @definitions = {}
  defns.each do |o|
    @definitions[o] = true
  end

  defns.each do |o|
    ftm = relevant_fact_types(o)

    trace :ldm, "expanding #{o.name}"

    ftm.each do |r, ft|
      next if ft.is_a?(ActiveFacts::Metamodel::TypeInheritance)
      ft.all_role.each do |ftr|
        next if @definitions[ftr.object_type]
        next if ftr.object_type.is_a?(ActiveFacts::Metamodel::ValueType)

        trace :ldm, "adding #{ftr.object_type.name}"

        defns = defns << ftr.object_type
        @definitions[ftr.object_type] = true
      end
    end
  end

  "            <h2>Business Definitions and Relationships</h2>\n" +
  defns.sort_by{|o| o.name.gsub(/ /, '').downcase}.map do |o|
    entity_type_dump(o, 0)
  end * "\n" + "\n"
end
generate_details() click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 160
def generate_details
  h2("Logical Data Model Details") +
  @composition.
  all_composite.
  sort_by{|composite| composite.mapping.name}.
  map{|composite| generate_table(composite)}*"\n" + "\n"
end
generate_diagrams() click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 156
def generate_diagrams
  ''
end
generate_foreign_key(fk, indent) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 567
def generate_foreign_key fk, indent
  # '-- '+fk.inspect
  "  " * indent + "FOREIGN KEY (" +
    fk.all_foreign_key_field.map{|fkf| safe_column_name fkf.component}*", " +
    ") REFERENCES <a href=\"#LDMD_#{table_name fk.composite}\">#{table_name fk.composite}</a> (" +
    fk.all_index_field.map{|ixf| safe_column_name ixf.component}*", " +
  ")"
end
generate_header() click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 83
def generate_header
  css_file = "/css/ldm.css"

  "<!DOCTYPE html>\n" +
  "<html lang=\"en\">\n" +
  "  <head>\n" +
  "    <meta charset=\"utf-8\">\n" +
  "    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n" +
  "    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n" +
  "    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->\n" +
  "    <title>Logical Data Model for " + @composition.name + "</title>\n" +
  "\n" +
  "    <!-- Bootstrap -->\n" +
  "    <link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css\" integrity=\"sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7\" crossorigin=\"anonymous\">\n" +
  "\n" +
  "    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->\n" +
  "    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n" +
  "    <!--[if lt IE 9]>\n" +
  "      <script src=\"https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js\"></script>\n" +
  "      <script src=\"https://oss.maxcdn.com/respond/1.4.2/respond.min.js\"></script>\n" +
  "    <![endif]-->\n" +
  File.open(File.dirname(__FILE__)+css_file) do |f|
    "    <style media='screen' type='text/css'>\n" +
    f.read + "\n" +
    "    </style>\n"
  end +
  "  </head>\n" +
  "  <body>\n" +
  "    <div class=\"container\">\n" +
  "      <div class=\"row\">\n" +
  "        <div class=\"col-md-12\">\n" +
  h1("Logical Data Model for " + @composition.name)
end
generate_index(index, delayed_indices, indent) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 531
def generate_index index, delayed_indices, indent
  nullable_columns =
    index.all_index_field.select do |ixf|
      !ixf.component.path_mandatory
    end
  contains_nullable_columns = nullable_columns.size > 0

  primary = index.composite_as_primary_index && !contains_nullable_columns
  column_names =
      index.all_index_field.map do |ixf|
        column_name(ixf.component)
      end
  clustering =
    (index.composite_as_primary_index ? ' CLUSTERED' : ' NONCLUSTERED')

  if contains_nullable_columns
    table_name = safe_table_name(index.composite)
    delayed_indices <<
      'CREATE UNIQUE'+clustering+' INDEX '+
      escape("#{table_name(index.composite)}By#{column_names*''}", index_name_max) +
      " ON #{table_name}("+column_names.map{|n| escape(n, column_name_max)}*', ' +
      ") WHERE #{
        nullable_columns.
        map{|ixf| safe_column_name ixf.component}.
        map{|column_name| column_name + ' IS NOT NULL'} *
        ' AND '
      }"
    nil
  else
    # '-- '+index.inspect
    "  " * indent + (primary ? 'PRIMARY KEY' : 'UNIQUE') +
    clustering +
    "(#{column_names.map{|n| escape(n, column_name_max)}*', '})"
  end
end
generate_table(composite) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 371
def generate_table(composite)
  @tables_emitted[composite] = true
  delayed_indices = []

  table_defn =
  "                <h3 id=\"LDMD_#{table_name(composite)}\">#{composite.mapping.name}</h3>\n" +
  "                  <table class=\"table table-bordered table-striped\">\n" +
  "                    <thead style=\"background-color: #aaa;\">\n" +
  "                      <tr>\n" +
  "                        <th>Attribute</th><th>Data Type</th><th>Man</th><th>Description</th>\n" +
  "                      </tr>\n" +
  "                    </thead>\n" +
  "                    <tbody>\n" +
  (
    composite.mapping.all_leaf.flat_map do |leaf|
      # Absorbed empty subtypes appear as leaves
      next if leaf.is_a?(MM::Absorption) && leaf.parent_role.fact_type.is_a?(MM::TypeInheritance)

      generate_column leaf, 11
    end
  ).compact.flat_map{|f| "#{f}" }*"\n"+"\n" +
  "                    </tbody>\n" +
  "                  </table>\n"

  table_keys =
  (
    composite.all_index.map do |index|
      generate_index index, delayed_indices, 9
    end.compact.sort +
    composite.all_foreign_key_as_source_composite.map do |fk|
      # trace :ldm, "generate foreign key for #{fk.composite.mapping.name}"
      generate_foreign_key fk, 9
    end.compact.sort
  ).compact.flat_map{|f| "#{f}" }*"<br>\n"+"\n"

  table_values =
    if composite.mapping.object_type.all_instance.size > 0 then
      table_values =
      "                  <table class=\"table table-bordered table-striped\">\n" +
      "                    <thead style=\"background-color: #aaa;\">\n" +
      "                      <tr>\n" +
      (
        composite.mapping.all_leaf.flat_map do |leaf|
          # Absorbed empty subtypes appear as leaves
          next if leaf.is_a?(MM::Absorption) && leaf.parent_role.fact_type.is_a?(MM::TypeInheritance)
          column_name = safe_column_name(leaf)
          "  " * 11 + "  <th>#{column_name}\n"
        end
      ) * "\n" + "\n" +
      "                      </tr>\n" +
      "                    </thead>\n" +
      "                    <tbody>\n" +
      "                    </tbody>\n" +
      "                  </table>\n"
    else
      ''
    end

  table_defn + table_keys + table_values
end
go(s = '') click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 589
def go s = ''
  "#{s}\nGO\n"  # REVISIT: This is an SQL-Serverism. Move it to a subclass.
end
h1(text, klass = nil) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 196
def h1(text, klass = nil)
  element(text, klass ? {:class => klass} : {}, 'h1')
end
h2(text, klass = nil) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 200
def h2(text, klass = nil)
  element(text, klass ? {:class => klass} : {}, 'h2')
end
h3(text, klass = nil) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 204
def h3(text, klass = nil)
  element(text, klass ? {:class => klass} : {}, 'h3')
end
has_another_nonstatic_role(ft, r) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 295
def has_another_nonstatic_role(ft, r)
  ft.all_role.detect do |rr|
    rr != r &&
    rr.object_type.is_a?(ActiveFacts::Metamodel::EntityType) &&
    !rr.object_type.is_static
  end
end
index_name_max() click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 59
def index_name_max
  60
end
is_reserved_word(w) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 580
def is_reserved_word w
  @reserved_word_hash ||=
    reserved_words.inject({}) do |h,w|
      h[w] = true
      h
    end
  @reserved_word_hash[w.upcase]
end
normalise_type(type, length) click to toggle source

Return SQL type and (modified?) length for the passed base type

# File lib/activefacts/generator/doc/ldm.rb, line 609
def normalise_type(type, length)
  sql_type = case type
    when /^Auto ?Counter$/
      'int'

    when /^Unsigned ?Integer$/,
      /^Signed ?Integer$/,
      /^Unsigned ?Small ?Integer$/,
      /^Signed ?Small ?Integer$/,
      /^Unsigned ?Tiny ?Integer$/
      s = case
        when length == nil
          'int'
        when length <= 8
          'tinyint'
        when length <= 16
          'smallint'
        when length <= 32
          'int'
        else
          'bigint'
        end
      length = nil
      s

    when /^Decimal$/
      'decimal'

    when /^Fixed ?Length ?Text$/, /^Char$/
      'char'
    when /^Variable ?Length ?Text$/, /^String$/
      'varchar'
    when /^Large ?Length ?Text$/, /^Text$/
      'text'

    when /^Date ?And ?Time$/, /^Date ?Time$/
      'datetime'
    when /^Date$/
      'datetime' # SQLSVR 2K5: 'date'
    when /^Time$/
      'datetime' # SQLSVR 2K5: 'time'
    when /^Auto ?Time ?Stamp$/
      'timestamp'

    when /^Guid$/
      'uniqueidentifier'
    when /^Money$/
      'decimal'
    when /^Picture ?Raw ?Data$/, /^Image$/
      'image'
    when /^Variable ?Length ?Raw ?Data$/, /^Blob$/
      'varbinary'
    when /^BIT$/
      'bit'
    when /^BOOLEAN$/
      'boolean'
    else type # raise "SQL type unknown for standard type #{type}"
    end
  [sql_type, length]
end
relevant_fact_types(o) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 287
def relevant_fact_types(o)
    o.
      all_role.
      map{|r| [r, r.fact_type]}.
      reject { |r, ft| ft.is_a?(ActiveFacts::Metamodel::LinkFactType) }.
      select { |r, ft| ft.entity_type || has_another_nonstatic_role(ft, r) }
end
reserved_words() click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 576
def reserved_words
  @reserved_words ||= %w{ }
end
role_ref(rr, freq_con, l_adj, name, t_adj, role_name_def, literal) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 337
def role_ref(rr, freq_con, l_adj, name, t_adj, role_name_def, literal)
  term_parts = [l_adj, termref(name, nil, rr.role.object_type), t_adj].compact
  [
    freq_con ? element(freq_con, :class=>:keyword) : nil,
    term_parts.size > 1 ? term([l_adj, termref(name, nil, rr.role.object_type), t_adj].compact*' ') : term_parts[0],
    role_name_def,
    literal
  ]
end
safe_column_name(component) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 71
def safe_column_name component
  escape(column_name(component), column_name_max)
end
safe_table_name(composite) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 67
def safe_table_name composite
  escape(table_name(composite), table_name_max)
end
schema_name_max() click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 63
def schema_name_max
  60
end
span(text, klass = nil) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 188
def span(text, klass = nil)
  element(text, klass ? {:class => klass} : {})
end
sql_string(str) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 674
def sql_string(str)
  "'" + str.gsub(/'/,"''") + "'"
end
sql_value(value) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 670
def sql_value(value)
  value.is_literal_string ? sql_string(value.literal) : value.literal
end
surrogate_type() click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 470
def surrogate_type
  'bigint'
end
table_name(composite) click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 75
def table_name composite
  composite.mapping.name.gsub(' ', @underscore)
end
table_name_max() click to toggle source
# File lib/activefacts/generator/doc/ldm.rb, line 51
def table_name_max
  60
end
term(name) click to toggle source

Text that should appear as part of a term (including role adjectives)

# File lib/activefacts/generator/doc/ldm.rb, line 228
def term(name)
  element(name, :class=>:object_type)
end
termdef(name) click to toggle source

A definition of a term

# File lib/activefacts/generator/doc/ldm.rb, line 213
def termdef(name)
  element(name, {:name => name, :class => 'object_type'}, 'a')
end
termref(name, role_name = nil, o = nil) click to toggle source

A reference to a defined term (excluding role adjectives)

# File lib/activefacts/generator/doc/ldm.rb, line 218
def termref(name, role_name = nil, o = nil)
  if o && !@definitions[o]
    element(name, :class=>:object_type)
  else
    role_name ||= name
    element(role_name, {:href=>'#'+name, :class=>:object_type}, 'a')
  end
end