Class: DataMetaDom::Field

Inherits:
VerDoccable show all
Defined in:
lib/dataMetaDom/field.rb

Overview

A field for a Record, with the full name including namespace if any, required flag, DataType and default value if any.

For command line details either check the new method’s source or the README.rdoc file, the usage section.

Constant Summary collapse

SET =

Aggregation type: Set

'set'
LIST =

Aggregation type: List

'list'
DEQUE =

Aggregation type: Deque

'deque'
AGGRS =

Making a hash/set of 3 members is outright silly, use simple array:

[SET, LIST, DEQUE]
MAP =

Map keyword, that’s a different kind of aggregator with 2 types

'map'

Instance Attribute Summary collapse

Attributes inherited from VerDoccable

#ver

Attributes inherited from Documentable

#docs

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from VerDoccable

#resetEntity, verConsumed?

Methods inherited from Documentable

#addDoc, #all, #clear, #docConsumed?, #getDoc, #has?, #ids

Constructor Details

#initialize(name = nil) ⇒ Field

Another way ot create a Field from the code - a constructor, with the given name if any. See the class method create for more details.



105
106
107
108
109
110
111
112
113
# File 'lib/dataMetaDom/field.rb', line 105

def initialize(name=nil)
    super()
    @length = nil
    if name
        raise ArgumentError, %<Invlalid field name "#{name}", must be alphanum starting with alpha> unless name =~ /^#{ID_START}\w*$/
        @name = name.to_sym
    end
    @default = nil
end

Instance Attribute Details

#aggrObject

Aggregate indicator - one of the constants: SET, LIST, DEQUE. Note it does not include MAP.



50
51
52
# File 'lib/dataMetaDom/field.rb', line 50

def aggr
  @aggr
end

#dataTypeObject

An instance of DataType for the given field. For a Map – source type



45
46
47
# File 'lib/dataMetaDom/field.rb', line 45

def dataType
  @dataType
end

#defaultObject

Default value for this field if any.



40
41
42
# File 'lib/dataMetaDom/field.rb', line 40

def default
  @default
end

#isRequiredObject

Required flag, true for a required field, false for an optional one.



35
36
37
# File 'lib/dataMetaDom/field.rb', line 35

def isRequired
  @isRequired
end

#nameObject (readonly)

The name for this field, full name including namespace if any.



30
31
32
# File 'lib/dataMetaDom/field.rb', line 30

def name
  @name
end

#regexObject

matches Regular expression specification if any, for a string



60
61
62
# File 'lib/dataMetaDom/field.rb', line 60

def regex
  @regex
end

#trgTypeObject

Target type for a Map



55
56
57
# File 'lib/dataMetaDom/field.rb', line 55

def trgType
  @trgType
end

Class Method Details

.consume(model, source, record) ⇒ Object

Parses a new field from the given source, adds to the given record with the source info.

  • Parameters:

    • source - the instance of SourceFile to parse from

    • record - the instance of the Record to which the newly parsed Field will be added.



69
70
71
72
73
74
75
76
# File 'lib/dataMetaDom/field.rb', line 69

def consume(model, source, record)
    newField = Field.new.parse(model, source)
    if record.docs
        newField.docs = record.docs.clone
        record.docs.clear
    end
    record.addField newField, model, source.snapshot
end

.create(name, dataType, req = false) ⇒ Object

Creates a new field with the the given name, type and required flag. Use to build a Model from the code.

  • Parameters:

    • name - full name for the new field, including namespace if any.

    • dataType - an instance of DataType, can use reusable types defined on util.rb.

    • req - the required flag, true for required, see isRequired for details.

Raises:

  • (ArgumentError)


85
86
87
88
89
90
91
# File 'lib/dataMetaDom/field.rb', line 85

def create(name, dataType, req=false)
    raise ArgumentError, 'Must specify name and type when creating a field from the code' if !name || !dataType
    result = Field.new name
    result.dataType = dataType
    result.isRequired = req
    result
end

Instance Method Details

#aggr?Boolean

For readability - determine if the field is aggregated type: LIST, DEQUE, SET

Returns:

  • (Boolean)


95
# File 'lib/dataMetaDom/field.rb', line 95

def aggr?; defined?(@aggr) && @aggr != nil; end

#default_specObject

Specification of a default value per the DataMeta DOM syntax or empty string if there is no default value on this field.



166
# File 'lib/dataMetaDom/field.rb', line 166

def default_spec; @default ? "=#{@default}" : '' end

#map?Boolean

For readability - determine if the field is a map

Returns:

  • (Boolean)


97
# File 'lib/dataMetaDom/field.rb', line 97

def map?; defined?(@trgType) && @trgType != nil; end

#matches_specObject

matches specification



168
# File 'lib/dataMetaDom/field.rb', line 168

def matches_spec; @regex ? " matches #{@regex}" : '' end

#parse(model, source) ⇒ Object

Parses this field from the given source.

  • Parameter:

    • source - an instance of SourceFile



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/dataMetaDom/field.rb', line 120

def parse(model, source)
    @aggr = nil
    @trgType = nil
    src = nil

    if source.line =~ /^\s*([#{REQUIRED_PFX}#{OPTIONAL_PFX}])\s*#{MAP}\{\s*([^\s,]+)\s*,\s*([^\}]+)}(.+)/
       # is it a map{} ?
       ro, srcSpec, trgSpec, tail = $1, $2, $3, $4
       src = %|#{ro}#{srcSpec}#{tail ? tail : ''}|
       @trgType = DataType.parse(source, trgSpec)
       unless STANDARD_TYPES.member?(@trgType.type)
           ns, base = DataMetaDom.splitNameSpace(@trgType.type)
           newNs = DataMetaDom.nsAdjustment(ns, model.options, source)
           newNsVer = "#{newNs}.#{base}".to_sym
           @trgType.type = newNsVer # adjust the type for the map target type too
       end
#        elsif source.line =~ /^\s*([#{REQUIRED_PFX}#{OPTIONAL_PFX}])\s*(string)\s+(#{ID_START}\w*)\s*(.+)?$/
        # is it a string with no length?
#            req, typeSpec, name, tail = $1, $2, $3, $4
#            src = %|#{req}#{typeSpec}[0] #{name} #{tail}|
    else # is it a list, deque or set?
        AGGRS.each { |a| ## aggregates do not allow matching nor they allow defaults
           if source.line =~ /^\s*([#{REQUIRED_PFX}#{OPTIONAL_PFX}])\s*#{a}\{([^\}]+)\}(.+)/
               @aggr = a
               src = %|#{$1}#{$2}#{$3}|
               break
           end
        }
    end
    r = (src ? src : source.line).scan(/^\s*([#{REQUIRED_PFX}#{OPTIONAL_PFX}])\s*(\S+)\s+(#{ID_START}\w*)\s*(.+)?$/)
    raise "Invalid field spec '#{line}'" unless r
    req, typeSpec, name, tail = r[0]
    defaultSpec = tail =~ /(=\S.+)/ ? $1.strip : nil
    @regex  = tail =~ /#{MATCHES}\s+(.+)/ ? $1.strip : nil # regex can have any symbols, even space, but it starts with a non-space
    #puts "<#{line}> <#{req}>  <#{typeSpec}> <#{dimSpec}> <#@name>"
    raise 'Invalid field spec format' if !name || name.empty? || !req || !typeSpec
    @name = name.to_sym
    @dataType = DataType.parse(source, typeSpec)
    @default = defaultSpec[1..-1] if defaultSpec # skip the = sign
    @isRequired = req.to_sym == REQUIRED_PFX
    self
end

#req_specObject

Required flag as per the DataMeta DOM syntax, either DataMetaDom::REQUIRED_PFX or DataMetaDom::OPTIONAL_PFX, the constants defined in the util.rb



174
# File 'lib/dataMetaDom/field.rb', line 174

def req_spec; @isRequired ? REQUIRED_PFX : OPTIONAL_PFX end

#set?Boolean

Returns:

  • (Boolean)


98
# File 'lib/dataMetaDom/field.rb', line 98

def set?; defined?(@aggr) && @aggr == SET; end

#to_sObject

Textual representation of all aspects of the field.



179
# File 'lib/dataMetaDom/field.rb', line 179

def to_s; "Field #{@name}(#{req_spec}#{@dataType})#{@default ? '=<' + @default + '>' : ''}" end