Class: DbAgile::Core::Schema::Builder

Inherits:
Object
  • Object
show all
Includes:
Coercion, ConceptFactory
Defined in:
lib/dbagile/core/schema/builder.rb,
lib/dbagile/core/schema/builder/coercion.rb,
lib/dbagile/core/schema/builder/concept_factory.rb

Defined Under Namespace

Modules: Coercion, ConceptFactory

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from ConceptFactory

#build_attribute, #build_constraint, #build_constraints, #build_heading, #build_index, #build_indexes, #build_logical, #build_physical, #build_relvar, #build_relview, #build_schema

Methods included from Coercion

#coerce_array, #coerce_attribute_definition, #coerce_attribute_names, #coerce_constraint_definition, #coerce_default_value, #coerce_domain, #coerce_index_definition, #coerce_mandatory, #coerce_name, #coerce_symbolized_hash, #coercion_error!, #has_exactly_hash_keys!, #invalid!, #not_empty!, #not_nil!, #not_nil_hash!, unsymbolize_array, unsymbolize_hash, #valid_name!

Constructor Details

#initialize(schema = Schema.new) ⇒ Builder

Creates a builder instance



14
15
16
17
18
19
20
# File 'lib/dbagile/core/schema/builder.rb', line 14

def initialize(schema = Schema.new)
  if schema
    @stack = [ [:schema, schema ] ]
  else
    @stack = [ [:root, {}] ]
  end
end

Instance Attribute Details

#stackObject

Call stack



11
12
13
# File 'lib/dbagile/core/schema/builder.rb', line 11

def stack
  @stack
end

Instance Method Details

#_dumpObject

Dumps as a Schema instance



27
28
29
30
31
32
33
# File 'lib/dbagile/core/schema/builder.rb', line 27

def _dump
  if stack.last[0] == :schema
    _peek(:schema)
  else
    _peek(:root)[:schema]
  end
end

#_natural(hash) ⇒ Object

Applies natural rules according to current section



65
66
67
68
69
70
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
97
# File 'lib/dbagile/core/schema/builder.rb', line 65

def _natural(hash)
  case section = stack.last[0]
    when :schema
      coerce_symbolized_hash(hash).each_pair{|name, defn|
        self.send(name, defn)
      }
    when :logical
      coerce_symbolized_hash(hash).each_pair{|relvar_name, relvar_def|
        relvar(relvar_name, relvar_def)
      }
    when :heading
      coerce_symbolized_hash(hash).each_pair{|attr_name, attr_def|
        attribute(attr_name, attr_def)
      }
    when :constraints
      coerce_symbolized_hash(hash).each_pair{|c_name, c_def|
        constraint(c_name, c_def)
      }
    when :physical
      coerce_symbolized_hash(hash).each_pair{|name, defn|
        self.send(name, defn)
      }
    when :indexes
      coerce_symbolized_hash(hash).each_pair{|index_name, index_def|
        index(index_name, index_def)
      }
    else
      coerce_symbolized_hash(hash).each_pair{|k, v|
        invalid!("No such section #{k}") unless self.respond_to?(k)
        self.send(k, v)
      }
  end
end

#_peek(section = nil) ⇒ Object

Returns top value of the stack



55
56
57
58
59
60
61
62
# File 'lib/dbagile/core/schema/builder.rb', line 55

def _peek(section = nil)
  unless section.nil? 
    if stack.empty? or not(stack.last[0] == section)
      invalid!("expected to be in #{section}, but was #{stack.last[0]}")
    end
  end
  stack.last[1]
end

#_popObject

Pops a hash from the stack



50
51
52
# File 'lib/dbagile/core/schema/builder.rb', line 50

def _pop
  stack.pop
end

#_push(section, object, &block) ⇒ Object

Push a hash on the stack



40
41
42
43
44
45
46
47
# File 'lib/dbagile/core/schema/builder.rb', line 40

def _push(section, object, &block)
  stack.push([section, object])
  if block
    DbAgile::RubyTools::optional_args_block_call(block, [ object ])
    _pop
  end
  object
end

#attribute(name, definition) ⇒ Object

Adds an attribute to current heading



149
150
151
152
# File 'lib/dbagile/core/schema/builder.rb', line 149

def attribute(name, definition)
  name, defn = coerce_attribute_name(name), coerce_attribute_definition(definition)
  _peek(:heading)[name] = build_attribute(name, defn)
end

#constraint(name, definition) ⇒ Object

Adds a constraint to current relvar



155
156
157
158
# File 'lib/dbagile/core/schema/builder.rb', line 155

def constraint(name, definition)
  name, defn = coerce_constraint_name(name), coerce_constraint_definition(definition)
  _peek(:constraints)[name] = build_constraint(name, defn)
end

#constraints(hash = nil, &block) ⇒ Object

Starts a constraints section



140
141
142
143
144
# File 'lib/dbagile/core/schema/builder.rb', line 140

def constraints(hash = nil, &block)
  block = lambda{ _natural(hash) } unless block
  cs = (_peek(:relvar)[:constraints] ||= build_constraints)
  _push(:constraints, cs, &block)
end

#database_schema(identifier = nil, hash = nil, &block) ⇒ Object Also known as: schema

Starts the logical section and yields



104
105
106
107
108
# File 'lib/dbagile/core/schema/builder.rb', line 104

def database_schema(identifier = nil, hash = nil, &block)
  block = lambda{ _natural(hash) } unless block
  schema = (_peek(:root)[:schema] ||= build_schema(identifier))
  _push(:schema, schema, &block)
end

#heading(hash = nil, &block) ⇒ Object

Starts a heading section



133
134
135
136
137
# File 'lib/dbagile/core/schema/builder.rb', line 133

def heading(hash = nil, &block)
  block = lambda{ _natural(hash) } unless block
  heading = (_peek(:relvar)[:heading] ||= build_heading)
  _push(:heading, heading, &block)
end

#index(name, definition) ⇒ Object

Adds an index to indexes



181
182
183
184
185
186
# File 'lib/dbagile/core/schema/builder.rb', line 181

def index(name, definition)
  name, defn = coerce_index_name(name), coerce_index_definition(definition)
  _peek(:indexes)[name] = build_index(name, defn)
rescue SByC::TypeSystem::CoercionError => ex
  invalid!("Invalid index definition (#{name}, #{definition.inspect}): #{ex.message}")
end

#indexes(hash = nil, &block) ⇒ Object

Starts the indexes section and yields



172
173
174
175
176
# File 'lib/dbagile/core/schema/builder.rb', line 172

def indexes(hash = nil, &block)
  block = lambda{ _natural(hash) } unless block
  indexes = (_peek(:physical)[:indexes] ||= build_indexes)
  _push(:indexes, indexes, &block)
end

#logical(hash = nil, &block) ⇒ Object

Starts the logical section and yields



112
113
114
115
116
# File 'lib/dbagile/core/schema/builder.rb', line 112

def logical(hash = nil, &block)
  block = lambda{ _natural(hash) } unless block
  logical = (_peek(:schema)[:logical] ||= build_logical)
  _push(:logical, logical, &block)
end

#physical(hash = nil, &block) ⇒ Object

Starts the physical section and yields



165
166
167
168
169
# File 'lib/dbagile/core/schema/builder.rb', line 165

def physical(hash = nil, &block)
  block = lambda{ _natural(hash) } unless block
  physical = (_peek(:schema)[:physical] ||= build_physical)
  _push(:physical, physical, &block)
end

#relvar(name, hash = nil, &block) ⇒ Object

Starts a relvar section



119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/dbagile/core/schema/builder.rb', line 119

def relvar(name, hash = nil, &block)
  if String === hash
    (_peek(:logical)[name] ||= build_relview(name, hash))
  else
    block = lambda{ _natural(hash) } unless block
    name = coerce_relvar_name(name)
    relvar = (_peek(:logical)[name] ||= build_relvar(name))
    _push(:relvar, relvar, &block)
  end
rescue SByC::TypeSystem::CoercionError => ex
  invalid!("Invalid relvar definition (#{name}): #{ex.message}")
end