# File lib/sql-ferret.rb, line 1416 def primary_key? return (@flags & FF_PRIMARY_KEY) != 0 end
class Ferret::Field
Constants
- FF_EXPL_UNIQUE
- FF_GHOST
- FF_OPTIONAL
- FF_PRIMARY_KEY
- [Ferret::Field]
-
flags
- FF_REFERENCE
- FF_UNCONSTRAINED
Attributes
default[R]
haunt[R]
interpretation[R]
name[R]
ref[R]
table[R]
type[R]
Public Class Methods
new(table, name, spec) { |proc do |schema| raise 'assertion failed' if ref ref_table = schema ugh 'unknown-table', table: ref_table_name \ unless ref_table ugh? referring_field: name, referring_field_table: name do if ref_field_name then ref = ref_table or ugh 'unknown-field', field: ref_field_name, table: name, significance: 'referred' else ref = primary_key or ugh 'no-primary-key', table: name, significance: 'referred' end ugh 'not-a-column', field: name, table: table.name, significance: 'referred' \| ... }
click to toggle source
Note that the parser does not look up the referred and haunted columns, for at the parsing time, not all the columns are yet available so trying to look up forward references would spuriously fail. Instead, it creates ‘relocation thunks’ and [[yield]]:s them to the caller, who must arrange to have them called (in the same order as they were [[yield]]:ed) after the whole schema has been loaded and which will perform these lookups and fill in the corresponding slots in the structure.
Calls superclass method
# File lib/sql-ferret.rb, line 1451 def initialize table, name, spec, &thunk raise 'type mismatch' unless table.is_a? Ferret::Table raise 'type mismatch' unless name.is_a? String raise 'type mismatch' unless spec.is_a? String super() @table = table @name = name unless spec.strip =~ %r{\A ( | (?<primary_key> \b primary \s+ key \s* ,) | (?<unique> \b unique \b) | (?<optional> \b optional \b) | \b ghost \b \s* (?<haunt> \b \w+ \b) )\s* ( (?<type> \b \w+ \b) | (?<unconstrained> \b unconstrained \b \s*)? \b ref \b \s* (?<ref_table> \w+) ( \s* \( \s* (?<ref_field> \w+) \s* \) )? ) ( \s* = \s* (?<default> [^\s].*) )? \Z}x then ugh 'invalid-field-specification', input: spec end unless $~['haunt'] then # Do we know the type? if $~['type'] and !%w{ integer real varchar text blob iso8601 unix_time subsecond_unix_time json pretty_json yaml ruby_marshal packed_hex}.include? $~['type'] then ugh 'unknown-type', type: $~['type'] end else # The regex above is a bit too permissive. if $~['type'] or $~['unconstrained'] or $~['default'] then ugh 'invalid-field-specification', input: spec end end if $~['primary_key'] and ($~['ref_table'] or $~['default']) then ugh 'invalid-field-specification', input: spec end @flags = 0 @flags |= FF_PRIMARY_KEY if $~['primary_key'] @flags |= FF_EXPL_UNIQUE if $~['unique'] @flags |= FF_OPTIONAL if $~['optional'] # The current [[$~]] is unlikely to survive until the # relocation thunk gets called, so we'll have to copy # [[ref_table]] and [[ref_field]] out of it, into local # variables. if ref_table_name = $~['ref_table'] then @flags |= FF_REFERENCE ref_field_name = $~['ref_field'] yield(proc do |schema| raise 'assertion failed' if @ref ref_table = schema[ref_table_name] ugh 'unknown-table', table: ref_table_name \ unless ref_table ugh? referring_field: @name, referring_field_table: @table.name do if ref_field_name then @ref = ref_table[ref_field_name] or ugh 'unknown-field', field: ref_field_name, table: ref_table.name, significance: 'referred' else @ref = ref_table.primary_key or ugh 'no-primary-key', table: ref_table.name, significance: 'referred' end ugh 'not-a-column', field: @ref.name, table: ref.table.name, significance: 'referred' \ unless @ref.column? end @type = @ref.type end) else @type = $~['type'] end if haunt = $~['haunt'] then @flags |= FF_GHOST yield(proc do |schema| ugh? significance: 'relied-on-by-ghost-field', ghost_field: @name do @haunt = @table[haunt] unless @haunt then ugh 'unknown-field', field: haunt end unless @haunt.column? then ugh 'not-a-column', field: @haunt.name end @type ||= @haunt.type unless @haunt.type == @type then ugh 'ghost-field-type-mismatch', field: @name, table: @table.name, type: @type.downcase, haunted_column: @haunt.name, haunted_column_type: @haunt.type.downcase end end end) end @flags |= FF_UNCONSTRAINED if $~['unconstrained'] @default = $~['default'] if @type then # [[@type]] can be [[nil]] if it's a reference field. # Then, the type and interpretation will be later copied # from the referred column. case @type.downcase when 'iso8601', 'json' then @interpretation = @type.downcase.to_sym @type = 'varchar' when 'yaml', 'pretty_json' then @interpretation = @type.downcase.to_sym @type = 'text' when 'ruby_marshal' then @interpretation = @type.downcase.to_sym @type = 'blob' when 'unix_time' then @interpretation = @type.downcase.to_sym @type = 'integer' when 'subsecond_unix_time' then @interpretation = @type.downcase.to_sym @type = 'real' else @interpretation = nil end end return end
Public Instance Methods
column?()
click to toggle source
# File lib/sql-ferret.rb, line 1432 def column? return (@flags & FF_GHOST) == 0 end
ghost?()
click to toggle source
# File lib/sql-ferret.rb, line 1428 def ghost? return (@flags & FF_GHOST) != 0 end
inspect()
click to toggle source
# File lib/sql-ferret.rb, line 1378 def inspect result = "#<Ferret::Field #{@table.name}.#{name}: " if primary_key? then result << 'primary key ' else result << 'optional ' if optional? result << 'unique ' if unique? end if reference? then result << 'unconstrained ' if unconstrained? result << "ghost #{@haunt.name} " if ghost? result << 'ref %s(%s)' % [ref.table.name, ref.name] else result << (interpretation || type).to_s end # Note that [[default]] is an unsanitised, unprocessed # string extracted from the schema. In pathological cases, # it can potentially contain the [[>]] character. result << " = #{default}" if default result << '>' end
optional?()
click to toggle source
# File lib/sql-ferret.rb, line 1412 def optional? return (@flags & FF_OPTIONAL) != 0 end
primary_key?()
click to toggle source
reference?()
click to toggle source
# File lib/sql-ferret.rb, line 1424 def reference? return (@flags & FF_REFERENCE) != 0 end
sql_to_declare()
click to toggle source
# File lib/sql-ferret.rb, line 1603 def sql_to_declare sql = "#@name #@type" if primary_key? then sql << " primary key" else sql << " unique" if unique? sql << " not null" unless optional? sql << " default #@default" if default end if reference? and !unconstrained? then sql << "\n references %s(%s)" % [@ref.table.name, @ref.name] end return sql end
unconstrained?()
click to toggle source
# File lib/sql-ferret.rb, line 1420 def unconstrained? return (@flags & FF_UNCONSTRAINED) != 0 end
unique?()
click to toggle source
# File lib/sql-ferret.rb, line 1408 def unique? return (@flags & (FF_PRIMARY_KEY | FF_EXPL_UNIQUE)) != 0 end