Class: DataMetaDom::Record
- Inherits:
-
VerDoccable
- Object
- Documentable
- VerDoccable
- DataMetaDom::Record
- Defined in:
- lib/dataMetaDom/record.rb
Overview
A data structure comprised of fields with the notion of identity, indexes, unique and not.
Instance Attribute Summary collapse
-
#baseName ⇒ String
readonly
Part of the #name, the suffix after last dot.
-
#fields ⇒ Object
readonly
The fields as a map keying a field name to the matching instance of a Field.
-
#identity ⇒ Object
An instance of RecIdentity.
-
#indexes ⇒ Object
readonly
A hash mapping to RecIndex from its key.
-
#key ⇒ Object
readonly
The unique key for the record, unique across the Model.
-
#name ⇒ Object
Full Record datatype name, including namespace if any.
-
#namespace ⇒ String
readonly
Part of the #name, the prefix before last dot, “package” in Java and Scala, “namespace” in C.
-
#refs ⇒ Object
readonly
An array of Reference.
-
#uniques ⇒ Object
readonly
A hash mapping to RecUnique from its key.
Attributes inherited from VerDoccable
Attributes inherited from Documentable
Class Method Summary collapse
-
.consumed?(model, src) ⇒ Boolean
Attempts to consume the instance from the given source, returns it if successful, returns nil otherwise.
Instance Method Summary collapse
-
#[](fieldKey) ⇒ Object
Fetches the field by the field key, i.e.
-
#addField(newField, model, source = nil) ⇒ Object
Add another field to this Record’s definition along with the source reference if any.
-
#addFields(fields, model, source = nil) ⇒ Object
Add several Field definitions to this Record.
-
#addIndex(newIx) ⇒ Object
Add another non-unique index to the record.
-
#addIndexes(ixs) ⇒ Object
Add several non-unique indexes to the record.
-
#addUnique(newUq) ⇒ Object
Add another unique index to the record.
-
#addUniques(uqs) ⇒ Object
Add several unique indexes to the record.
-
#assertIds(ids) ⇒ Object
Verifies that the list of ids is valid, meaning that there is a field with the given name on this record.
-
#initialize(name) ⇒ Record
constructor
Creates an instance for the given full data type name, including namespace.
-
#parse(model, source) ⇒ Object
Parse the Record from the given source into this instance.
-
#to_s ⇒ Object
Textual representation of this instance, with all the fields, attributes and references if any.
Methods inherited from VerDoccable
Methods inherited from Documentable
#addDoc, #all, #clear, #docConsumed?, #getDoc, #has?, #ids
Constructor Details
#initialize(name) ⇒ Record
Creates an instance for the given full data type name, including namespace. Namespace is required.
235 236 237 238 239 240 241 242 243 244 |
# File 'lib/dataMetaDom/record.rb', line 235 def initialize(name) #noinspection RubyArgCount super() @namespace, @baseName = DataMetaDom.splitNameSpace(name) raise %Q<Record "#{@baseName}": no namespace; namespaces are required!> unless @namespace @name = name.to_sym @key = @name @fields={}; @uniques={}; @identity=nil; @indexes = {}; @refs=[] end |
Instance Attribute Details
#baseName ⇒ String (readonly)
Returns part of the #name, the suffix after last dot.
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 |
# File 'lib/dataMetaDom/record.rb', line 172 class Record < VerDoccable Full Record datatype name, including namespace if any. Should be unique in the model. attr_accessor :name The fields as a map keying a field name to the matching instance of a Field attr_reader :fields An instance of RecIdentity. attr_reader :identity A hash mapping to RecUnique from its key. Meaning, RecUnique.key to the matching RecUnique attr_reader :uniques A hash mapping to RecIndex from its key. Meaning, RecIndex.key to the matching RecIndex attr_reader :indexes An array of Reference attr_reader :refs The unique key for the record, unique across the Model. attr_reader :key attr_reader :namespace attr_reader :baseName Attempts to consume the instance from the given source, returns it if successful, returns nil otherwise. * Parameters * +model+ - an instance of a Model * +src+ - an instance of SourceFile def self.consumed?(model, src) if src.line =~ /^\s*#{RECORD}\s+(\w+)$/ newRecord = Record.new(DataMetaDom.combineNsBase(DataMetaDom.nsAdjustment(src.namespace, model., src).to_sym, $1)).parse(model, src) $stderr.puts %<WARN: Record redefinition: "#{newRecord.key}"> if model.records[newRecord.key] model.addRecord(newRecord) else nil end end Creates an instance for the given full data type name, including namespace. Namespace is required. def initialize(name) #noinspection RubyArgCount super() @namespace, @baseName = DataMetaDom.splitNameSpace(name) raise %Q<Record "#{@baseName}": no namespace; namespaces are required!> unless @namespace @name = name.to_sym @key = @name @fields={}; @uniques={}; @identity=nil; @indexes = {}; @refs=[] end Fetches the field by the field key, i.e. Field.name def [](fieldKey); @fields[fieldKey] end Verifies that the list of ids is valid, meaning that there is a field with the given name on this record. * Parameter * +ids+ - an array of strings, each should be a valid field name already defined on this Record. def assertIds(ids) ids.each { |id| k = id.to_sym raise "Undeclared field '#{id}'" unless @fields.has_key?(k) } end Set the identity on the Record. * Parameter: * +newIdy+ - an instance of RecIdentity def identity=(newIdy) raise 'There can be only one identity statement in a record' if @identity @identity = newIdy assertIds(@identity.args) @identity.args.each { |id| f = @fields[id.to_sym] raise ArgumentError, %|Field "#{ id}" is made identity; no aggregate types or maps can be identity| if f.aggr? || f.map? raise ArgumentError, %|Optional field "#{ id}" is made identity; only required fields may be identity| unless f.isRequired } end Add another unique index to the record. * Parameter: * +newUq+ - an instance of RecUnique to add ot this record. def addUnique(newUq) assertIds(newUq.args) raise "Duplicate unique set declaration #{newUq}" if @uniques.has_key?(newUq.key) @uniques[newUq.key] = newUq end Add another non-unique index to the record. * Parameter: * +newIx+ - an instance of RecIndex to add to this Record def addIndex(newIx) assertIds(newIx.args) raise "Duplicate index declaration #{newIx}" if @indexes.has_key?(newIx.key) @indexes[newIx.key] = newIx end Add another field to this Record's definition along with the source reference if any. * Parameters: * +newField+ - an instance of Field to add to this Record * +source+ - a reference to the SourceFile where this field has been defined, pass +nil+ if built from the code. def addField(newField, model, source=nil) fieldKey = newField.name raise "Duplicate field name '#{fieldKey}' in the Record '#{@name}'" if (@fields.key?(fieldKey)) @fields[fieldKey] = newField unless STANDARD_TYPES.member?(newField.dataType.type) ns, base = DataMetaDom.splitNameSpace(newField.dataType.type) newNs = DataMetaDom.nsAdjustment(ns, model., source) reRefName = "#{newNs}.#{base}".to_sym newField.dataType.type = reRefName # adjust the type for finding the reference again @refs << Reference.new(self, newField, reRefName, source ? source.snapshot : nil) end end Add several Field definitions to this Record. * Parameters: * +fields+ - an array of the instances of Field to add to this Record def addFields(fields, model, source=nil); fields.each { |f| addField f, model, source } end Add several non-unique indexes to the record. * Parameter: * +ixs+ - an array of the instances of RecIndex to add to this Record def addIndexes(ixs); ixs.each { |ix| addIndex ix } end Add several unique indexes to the record. * Parameter: * +uqs+ - an array of instances of RecUnique to add ot this record. def addUniques(uqs); uqs.each { |uq| addUnique uq } end Parse the Record from the given source into this instance. * Parameter: * +source+ - an instance of SourceFile to parse from def parse(model, source) while (line = source.nextLine) next if docConsumed?(source) case line when /^\s*#{END_KW}\s*$/ if source.docs self.docs = source.docs.clone source.docs.clear end self.ver = source.ver unless self.ver raise "Version missing for the Record #{name}" unless self.ver return self when '' next else isTokenConsumed = false RECORD_LEVEL_TOKENS.each { |t| isTokenConsumed = t.consumed? source, self break if isTokenConsumed } unless isTokenConsumed raise ArgumentError, "Record #{@name}: all field declarations must precede identity" if @identity Field.consume(model, source, self) end resetEntity end # case line end # while line self # for call chaining end Textual representation of this instance, with all the fields, attributes and references if any. def to_s "Record{#{@name}(#{@fields.values.join(';')},uq=[#{@uniques.map { |u| '[' + u.join(',') + ']' }.join('; ')}]"\ ";idy=[#{@identity ? @identity.args.join(',') : ''}]; refs=[#{@refs.join(',')}]}, #{self.ver}" end end |
#fields ⇒ Object (readonly)
The fields as a map keying a field name to the matching instance of a Field
182 183 184 |
# File 'lib/dataMetaDom/record.rb', line 182 def fields @fields end |
#identity ⇒ Object
An instance of RecIdentity.
187 188 189 |
# File 'lib/dataMetaDom/record.rb', line 187 def identity @identity end |
#indexes ⇒ Object (readonly)
A hash mapping to RecIndex from its key. Meaning, RecIndex.key to the matching RecIndex
197 198 199 |
# File 'lib/dataMetaDom/record.rb', line 197 def indexes @indexes end |
#key ⇒ Object (readonly)
The unique key for the record, unique across the Model.
207 208 209 |
# File 'lib/dataMetaDom/record.rb', line 207 def key @key end |
#name ⇒ Object
Full Record datatype name, including namespace if any. Should be unique in the model.
177 178 179 |
# File 'lib/dataMetaDom/record.rb', line 177 def name @name end |
#namespace ⇒ String (readonly)
Returns part of the #name, the prefix before last dot, “package” in Java and Scala, “namespace” in C.
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 |
# File 'lib/dataMetaDom/record.rb', line 172 class Record < VerDoccable Full Record datatype name, including namespace if any. Should be unique in the model. attr_accessor :name The fields as a map keying a field name to the matching instance of a Field attr_reader :fields An instance of RecIdentity. attr_reader :identity A hash mapping to RecUnique from its key. Meaning, RecUnique.key to the matching RecUnique attr_reader :uniques A hash mapping to RecIndex from its key. Meaning, RecIndex.key to the matching RecIndex attr_reader :indexes An array of Reference attr_reader :refs The unique key for the record, unique across the Model. attr_reader :key attr_reader :namespace attr_reader :baseName Attempts to consume the instance from the given source, returns it if successful, returns nil otherwise. * Parameters * +model+ - an instance of a Model * +src+ - an instance of SourceFile def self.consumed?(model, src) if src.line =~ /^\s*#{RECORD}\s+(\w+)$/ newRecord = Record.new(DataMetaDom.combineNsBase(DataMetaDom.nsAdjustment(src.namespace, model., src).to_sym, $1)).parse(model, src) $stderr.puts %<WARN: Record redefinition: "#{newRecord.key}"> if model.records[newRecord.key] model.addRecord(newRecord) else nil end end Creates an instance for the given full data type name, including namespace. Namespace is required. def initialize(name) #noinspection RubyArgCount super() @namespace, @baseName = DataMetaDom.splitNameSpace(name) raise %Q<Record "#{@baseName}": no namespace; namespaces are required!> unless @namespace @name = name.to_sym @key = @name @fields={}; @uniques={}; @identity=nil; @indexes = {}; @refs=[] end Fetches the field by the field key, i.e. Field.name def [](fieldKey); @fields[fieldKey] end Verifies that the list of ids is valid, meaning that there is a field with the given name on this record. * Parameter * +ids+ - an array of strings, each should be a valid field name already defined on this Record. def assertIds(ids) ids.each { |id| k = id.to_sym raise "Undeclared field '#{id}'" unless @fields.has_key?(k) } end Set the identity on the Record. * Parameter: * +newIdy+ - an instance of RecIdentity def identity=(newIdy) raise 'There can be only one identity statement in a record' if @identity @identity = newIdy assertIds(@identity.args) @identity.args.each { |id| f = @fields[id.to_sym] raise ArgumentError, %|Field "#{ id}" is made identity; no aggregate types or maps can be identity| if f.aggr? || f.map? raise ArgumentError, %|Optional field "#{ id}" is made identity; only required fields may be identity| unless f.isRequired } end Add another unique index to the record. * Parameter: * +newUq+ - an instance of RecUnique to add ot this record. def addUnique(newUq) assertIds(newUq.args) raise "Duplicate unique set declaration #{newUq}" if @uniques.has_key?(newUq.key) @uniques[newUq.key] = newUq end Add another non-unique index to the record. * Parameter: * +newIx+ - an instance of RecIndex to add to this Record def addIndex(newIx) assertIds(newIx.args) raise "Duplicate index declaration #{newIx}" if @indexes.has_key?(newIx.key) @indexes[newIx.key] = newIx end Add another field to this Record's definition along with the source reference if any. * Parameters: * +newField+ - an instance of Field to add to this Record * +source+ - a reference to the SourceFile where this field has been defined, pass +nil+ if built from the code. def addField(newField, model, source=nil) fieldKey = newField.name raise "Duplicate field name '#{fieldKey}' in the Record '#{@name}'" if (@fields.key?(fieldKey)) @fields[fieldKey] = newField unless STANDARD_TYPES.member?(newField.dataType.type) ns, base = DataMetaDom.splitNameSpace(newField.dataType.type) newNs = DataMetaDom.nsAdjustment(ns, model., source) reRefName = "#{newNs}.#{base}".to_sym newField.dataType.type = reRefName # adjust the type for finding the reference again @refs << Reference.new(self, newField, reRefName, source ? source.snapshot : nil) end end Add several Field definitions to this Record. * Parameters: * +fields+ - an array of the instances of Field to add to this Record def addFields(fields, model, source=nil); fields.each { |f| addField f, model, source } end Add several non-unique indexes to the record. * Parameter: * +ixs+ - an array of the instances of RecIndex to add to this Record def addIndexes(ixs); ixs.each { |ix| addIndex ix } end Add several unique indexes to the record. * Parameter: * +uqs+ - an array of instances of RecUnique to add ot this record. def addUniques(uqs); uqs.each { |uq| addUnique uq } end Parse the Record from the given source into this instance. * Parameter: * +source+ - an instance of SourceFile to parse from def parse(model, source) while (line = source.nextLine) next if docConsumed?(source) case line when /^\s*#{END_KW}\s*$/ if source.docs self.docs = source.docs.clone source.docs.clear end self.ver = source.ver unless self.ver raise "Version missing for the Record #{name}" unless self.ver return self when '' next else isTokenConsumed = false RECORD_LEVEL_TOKENS.each { |t| isTokenConsumed = t.consumed? source, self break if isTokenConsumed } unless isTokenConsumed raise ArgumentError, "Record #{@name}: all field declarations must precede identity" if @identity Field.consume(model, source, self) end resetEntity end # case line end # while line self # for call chaining end Textual representation of this instance, with all the fields, attributes and references if any. def to_s "Record{#{@name}(#{@fields.values.join(';')},uq=[#{@uniques.map { |u| '[' + u.join(',') + ']' }.join('; ')}]"\ ";idy=[#{@identity ? @identity.args.join(',') : ''}]; refs=[#{@refs.join(',')}]}, #{self.ver}" end end |
#refs ⇒ Object (readonly)
An array of Reference
202 203 204 |
# File 'lib/dataMetaDom/record.rb', line 202 def refs @refs end |
#uniques ⇒ Object (readonly)
A hash mapping to RecUnique from its key. Meaning, RecUnique.key to the matching RecUnique
192 193 194 |
# File 'lib/dataMetaDom/record.rb', line 192 def uniques @uniques end |
Class Method Details
.consumed?(model, src) ⇒ Boolean
Attempts to consume the instance from the given source, returns it if successful, returns nil otherwise.
-
Parameters
-
model
- an instance of a Model -
src
- an instance of SourceFile
-
219 220 221 222 223 224 225 226 227 |
# File 'lib/dataMetaDom/record.rb', line 219 def self.consumed?(model, src) if src.line =~ /^\s*#{RECORD}\s+(\w+)$/ newRecord = Record.new(DataMetaDom.combineNsBase(DataMetaDom.nsAdjustment(src.namespace, model., src).to_sym, $1)).parse(model, src) $stderr.puts %<WARN: Record redefinition: "#{newRecord.key}"> if model.records[newRecord.key] model.addRecord(newRecord) else nil end end |
Instance Method Details
#[](fieldKey) ⇒ Object
Fetches the field by the field key, i.e. Field.name
249 |
# File 'lib/dataMetaDom/record.rb', line 249 def [](fieldKey); @fields[fieldKey] end |
#addField(newField, model, source = nil) ⇒ Object
Add another field to this Record’s definition along with the source reference if any.
-
Parameters:
-
newField
- an instance of Field to add to this Record -
source
- a reference to the SourceFile where this field has been defined, passnil
if
built from the code.
-
312 313 314 315 316 317 318 319 320 321 322 323 |
# File 'lib/dataMetaDom/record.rb', line 312 def addField(newField, model, source=nil) fieldKey = newField.name raise "Duplicate field name '#{fieldKey}' in the Record '#{@name}'" if (@fields.key?(fieldKey)) @fields[fieldKey] = newField unless STANDARD_TYPES.member?(newField.dataType.type) ns, base = DataMetaDom.splitNameSpace(newField.dataType.type) newNs = DataMetaDom.nsAdjustment(ns, model., source) reRefName = "#{newNs}.#{base}".to_sym newField.dataType.type = reRefName # adjust the type for finding the reference again @refs << Reference.new(self, newField, reRefName, source ? source.snapshot : nil) end end |
#addFields(fields, model, source = nil) ⇒ Object
Add several Field definitions to this Record.
-
Parameters:
-
fields
- an array of the instances of Field to add to this Record
-
330 |
# File 'lib/dataMetaDom/record.rb', line 330 def addFields(fields, model, source=nil); fields.each { |f| addField f, model, source } end |
#addIndex(newIx) ⇒ Object
Add another non-unique index to the record.
-
Parameter:
-
newIx
- an instance of RecIndex to add to this Record
-
299 300 301 302 303 |
# File 'lib/dataMetaDom/record.rb', line 299 def addIndex(newIx) assertIds(newIx.args) raise "Duplicate index declaration #{newIx}" if @indexes.has_key?(newIx.key) @indexes[newIx.key] = newIx end |
#addIndexes(ixs) ⇒ Object
Add several non-unique indexes to the record.
-
Parameter:
-
ixs
- an array of the instances of RecIndex to add to this Record
-
337 |
# File 'lib/dataMetaDom/record.rb', line 337 def addIndexes(ixs); ixs.each { |ix| addIndex ix } end |
#addUnique(newUq) ⇒ Object
Add another unique index to the record.
-
Parameter:
-
newUq
- an instance of RecUnique to add ot this record.
-
288 289 290 291 292 |
# File 'lib/dataMetaDom/record.rb', line 288 def addUnique(newUq) assertIds(newUq.args) raise "Duplicate unique set declaration #{newUq}" if @uniques.has_key?(newUq.key) @uniques[newUq.key] = newUq end |
#addUniques(uqs) ⇒ Object
Add several unique indexes to the record.
-
Parameter:
-
uqs
- an array of instances of RecUnique to add ot this record.
-
344 |
# File 'lib/dataMetaDom/record.rb', line 344 def addUniques(uqs); uqs.each { |uq| addUnique uq } end |
#assertIds(ids) ⇒ Object
Verifies that the list of ids is valid, meaning that there is a field with the given name on this record.
-
Parameter
-
ids
- an array of strings, each should be a valid field name already defined on this Record.
-
256 257 258 259 260 261 |
# File 'lib/dataMetaDom/record.rb', line 256 def assertIds(ids) ids.each { |id| k = id.to_sym raise "Undeclared field '#{id}'" unless @fields.has_key?(k) } end |
#parse(model, source) ⇒ Object
Parse the Record from the given source into this instance.
-
Parameter:
-
source
- an instance of SourceFile to parse from
-
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 |
# File 'lib/dataMetaDom/record.rb', line 351 def parse(model, source) while (line = source.nextLine) next if docConsumed?(source) case line when /^\s*#{END_KW}\s*$/ if source.docs self.docs = source.docs.clone source.docs.clear end self.ver = source.ver unless self.ver raise "Version missing for the Record #{name}" unless self.ver return self when '' next else isTokenConsumed = false RECORD_LEVEL_TOKENS.each { |t| isTokenConsumed = t.consumed? source, self break if isTokenConsumed } unless isTokenConsumed raise ArgumentError, "Record #{@name}: all field declarations must precede identity" if @identity Field.consume(model, source, self) end resetEntity end # case line end # while line self # for call chaining end |
#to_s ⇒ Object
Textual representation of this instance, with all the fields, attributes and references if any.
384 385 386 387 |
# File 'lib/dataMetaDom/record.rb', line 384 def to_s "Record{#{@name}(#{@fields.values.join(';')},uq=[#{@uniques.map { |u| '[' + u.join(',') + ']' }.join('; ')}]"\ ";idy=[#{@identity ? @identity.args.join(',') : ''}]; refs=[#{@refs.join(',')}]}, #{self.ver}" end |