def initialize(model, name, type, options = {})
assert_kind_of 'model', model, Model
assert_kind_of 'name', name, Symbol
assert_kind_of 'type', type, Class
if Fixnum == type
warn "#{type} properties are deprecated. Please use Integer instead"
type = Integer
end
unless TYPES.include?(type) || (DataMapper::Type > type && TYPES.include?(type.primitive))
raise ArgumentError, "+type+ was #{type.inspect}, which is not a supported type: #{TYPES * ', '}", caller
end
@extra_options = {}
(options.keys - PROPERTY_OPTIONS).each do |key|
@extra_options[key] = options.delete(key)
end
@model = model
@name = name.to_s.sub(/\?$/, '').to_sym
@type = type
@custom = DataMapper::Type > @type
@options = @custom ? @type.options.merge(options) : options
@instance_variable_name = "@#{@name}"
@primitive = @options.fetch(:primitive, @type.respond_to?(:primitive) ? @type.primitive : @type)
@getter = TrueClass == @primitive ? "#{@name}?".to_sym : @name
@field = @options.fetch(:field, nil)
@serial = @options.fetch(:serial, false)
@key = @options.fetch(:key, @serial || false)
@default = @options.fetch(:default, nil)
@nullable = @options.fetch(:nullable, @key == false)
@index = @options.fetch(:index, false)
@unique_index = @options.fetch(:unique_index, false)
@lazy = @options.fetch(:lazy, @type.respond_to?(:lazy) ? @type.lazy : false) && !@key
@fields = {}
@track = @options.fetch(:track) do
if @custom && @type.respond_to?(:track) && @type.track
@type.track
else
IMMUTABLE_TYPES.include?(@primitive) ? :set : :get
end
end
if String == @primitive || Class == @primitive
@length = @options.fetch(:length, @options.fetch(:size, DEFAULT_LENGTH))
elsif BigDecimal == @primitive || Float == @primitive
@precision = @options.fetch(:precision, DEFAULT_PRECISION)
default_scale = (Float == @primitive) ? DEFAULT_SCALE_FLOAT : DEFAULT_SCALE_BIGDECIMAL
@scale = @options.fetch(:scale, default_scale)
unless @precision > 0
raise ArgumentError, "precision must be greater than 0, but was #{@precision.inspect}"
end
if (BigDecimal == @primitive) || (Float == @primitive && !@scale.nil?)
unless @scale >= 0
raise ArgumentError, "scale must be equal to or greater than 0, but was #{@scale.inspect}"
end
unless @precision >= @scale
raise ArgumentError, "precision must be equal to or greater than scale, but was #{@precision.inspect} and scale was #{@scale.inspect}"
end
end
end
determine_visibility
@model.auto_generate_validations(self) if @model.respond_to?(:auto_generate_validations)
@model.property_serialization_setup(self) if @model.respond_to?(:property_serialization_setup)
end