ardm 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/.gitignore +35 -0
- data/Gemfile +13 -0
- data/LICENSE +21 -0
- data/README.md +70 -0
- data/Rakefile +4 -0
- data/ardm.gemspec +29 -0
- data/db/.gitignore +1 -0
- data/lib/ardm/active_record/associations.rb +80 -0
- data/lib/ardm/active_record/base.rb +49 -0
- data/lib/ardm/active_record/dirty.rb +25 -0
- data/lib/ardm/active_record/hooks.rb +31 -0
- data/lib/ardm/active_record/inheritance.rb +37 -0
- data/lib/ardm/active_record/is/state_machine.rb +21 -0
- data/lib/ardm/active_record/is.rb +22 -0
- data/lib/ardm/active_record/not_found.rb +7 -0
- data/lib/ardm/active_record/predicate_builder/array_handler.rb +31 -0
- data/lib/ardm/active_record/predicate_builder/rails3.rb +147 -0
- data/lib/ardm/active_record/predicate_builder/rails4.rb +139 -0
- data/lib/ardm/active_record/predicate_builder/relation_handler.rb +15 -0
- data/lib/ardm/active_record/predicate_builder.rb +19 -0
- data/lib/ardm/active_record/property.rb +357 -0
- data/lib/ardm/active_record/query.rb +108 -0
- data/lib/ardm/active_record/record.rb +70 -0
- data/lib/ardm/active_record/relation.rb +83 -0
- data/lib/ardm/active_record/repository.rb +38 -0
- data/lib/ardm/active_record/serialization.rb +164 -0
- data/lib/ardm/active_record/storage_names.rb +28 -0
- data/lib/ardm/active_record/validations.rb +111 -0
- data/lib/ardm/active_record.rb +43 -0
- data/lib/ardm/data_mapper/not_found.rb +5 -0
- data/lib/ardm/data_mapper/record.rb +41 -0
- data/lib/ardm/data_mapper.rb +5 -0
- data/lib/ardm/env.rb +5 -0
- data/lib/ardm/property/api_key.rb +30 -0
- data/lib/ardm/property/bcrypt_hash.rb +31 -0
- data/lib/ardm/property/binary.rb +23 -0
- data/lib/ardm/property/boolean.rb +29 -0
- data/lib/ardm/property/class.rb +19 -0
- data/lib/ardm/property/comma_separated_list.rb +28 -0
- data/lib/ardm/property/csv.rb +35 -0
- data/lib/ardm/property/date.rb +12 -0
- data/lib/ardm/property/datetime.rb +12 -0
- data/lib/ardm/property/decimal.rb +38 -0
- data/lib/ardm/property/discriminator.rb +65 -0
- data/lib/ardm/property/enum.rb +51 -0
- data/lib/ardm/property/epoch_time.rb +38 -0
- data/lib/ardm/property/file_path.rb +25 -0
- data/lib/ardm/property/flag.rb +65 -0
- data/lib/ardm/property/float.rb +18 -0
- data/lib/ardm/property/integer.rb +24 -0
- data/lib/ardm/property/invalid_value_error.rb +22 -0
- data/lib/ardm/property/ip_address.rb +35 -0
- data/lib/ardm/property/json.rb +49 -0
- data/lib/ardm/property/lookup.rb +29 -0
- data/lib/ardm/property/numeric.rb +40 -0
- data/lib/ardm/property/object.rb +36 -0
- data/lib/ardm/property/paranoid_boolean.rb +18 -0
- data/lib/ardm/property/paranoid_datetime.rb +17 -0
- data/lib/ardm/property/regexp.rb +22 -0
- data/lib/ardm/property/serial.rb +16 -0
- data/lib/ardm/property/slug.rb +29 -0
- data/lib/ardm/property/string.rb +40 -0
- data/lib/ardm/property/support/dirty_minder.rb +169 -0
- data/lib/ardm/property/support/flags.rb +41 -0
- data/lib/ardm/property/support/paranoid_base.rb +78 -0
- data/lib/ardm/property/text.rb +11 -0
- data/lib/ardm/property/time.rb +12 -0
- data/lib/ardm/property/uri.rb +27 -0
- data/lib/ardm/property/uuid.rb +65 -0
- data/lib/ardm/property/validation.rb +208 -0
- data/lib/ardm/property/yaml.rb +38 -0
- data/lib/ardm/property.rb +891 -0
- data/lib/ardm/property_set.rb +152 -0
- data/lib/ardm/query/expression.rb +85 -0
- data/lib/ardm/query/ext/symbol.rb +37 -0
- data/lib/ardm/query/operator.rb +64 -0
- data/lib/ardm/record.rb +1 -0
- data/lib/ardm/support/assertions.rb +8 -0
- data/lib/ardm/support/deprecate.rb +12 -0
- data/lib/ardm/support/descendant_set.rb +89 -0
- data/lib/ardm/support/equalizer.rb +48 -0
- data/lib/ardm/support/ext/array.rb +22 -0
- data/lib/ardm/support/ext/blank.rb +25 -0
- data/lib/ardm/support/ext/hash.rb +67 -0
- data/lib/ardm/support/ext/module.rb +47 -0
- data/lib/ardm/support/ext/object.rb +57 -0
- data/lib/ardm/support/ext/string.rb +24 -0
- data/lib/ardm/support/ext/try_dup.rb +12 -0
- data/lib/ardm/support/hook.rb +405 -0
- data/lib/ardm/support/lazy_array.rb +451 -0
- data/lib/ardm/support/local_object_space.rb +13 -0
- data/lib/ardm/support/logger.rb +201 -0
- data/lib/ardm/support/mash.rb +176 -0
- data/lib/ardm/support/naming_conventions.rb +90 -0
- data/lib/ardm/support/ordered_set.rb +380 -0
- data/lib/ardm/support/subject.rb +33 -0
- data/lib/ardm/support/subject_set.rb +250 -0
- data/lib/ardm/version.rb +3 -0
- data/lib/ardm.rb +56 -0
- data/spec/fixtures/api_user.rb +11 -0
- data/spec/fixtures/article.rb +22 -0
- data/spec/fixtures/bookmark.rb +14 -0
- data/spec/fixtures/invention.rb +5 -0
- data/spec/fixtures/network_node.rb +23 -0
- data/spec/fixtures/person.rb +17 -0
- data/spec/fixtures/software_package.rb +22 -0
- data/spec/fixtures/ticket.rb +12 -0
- data/spec/fixtures/tshirt.rb +15 -0
- data/spec/integration/api_key_spec.rb +25 -0
- data/spec/integration/bcrypt_hash_spec.rb +45 -0
- data/spec/integration/comma_separated_list_spec.rb +85 -0
- data/spec/integration/dirty_minder_spec.rb +197 -0
- data/spec/integration/enum_spec.rb +79 -0
- data/spec/integration/epoch_time_spec.rb +59 -0
- data/spec/integration/file_path_spec.rb +158 -0
- data/spec/integration/flag_spec.rb +72 -0
- data/spec/integration/ip_address_spec.rb +151 -0
- data/spec/integration/json_spec.rb +70 -0
- data/spec/integration/slug_spec.rb +65 -0
- data/spec/integration/uri_spec.rb +136 -0
- data/spec/integration/uuid_spec.rb +102 -0
- data/spec/integration/yaml_spec.rb +85 -0
- data/spec/public/property/binary_spec.rb +41 -0
- data/spec/public/property/boolean_spec.rb +30 -0
- data/spec/public/property/class_spec.rb +28 -0
- data/spec/public/property/date_spec.rb +22 -0
- data/spec/public/property/date_time_spec.rb +22 -0
- data/spec/public/property/decimal_spec.rb +23 -0
- data/spec/public/property/discriminator_spec.rb +133 -0
- data/spec/public/property/float_spec.rb +22 -0
- data/spec/public/property/integer_spec.rb +22 -0
- data/spec/public/property/object_spec.rb +103 -0
- data/spec/public/property/serial_spec.rb +22 -0
- data/spec/public/property/string_spec.rb +22 -0
- data/spec/public/property/text_spec.rb +23 -0
- data/spec/public/property/time_spec.rb +22 -0
- data/spec/public/property_spec.rb +316 -0
- data/spec/rcov.opts +6 -0
- data/spec/schema.rb +86 -0
- data/spec/semipublic/property/binary_spec.rb +14 -0
- data/spec/semipublic/property/boolean_spec.rb +48 -0
- data/spec/semipublic/property/class_spec.rb +36 -0
- data/spec/semipublic/property/date_spec.rb +44 -0
- data/spec/semipublic/property/date_time_spec.rb +47 -0
- data/spec/semipublic/property/decimal_spec.rb +83 -0
- data/spec/semipublic/property/discriminator_spec.rb +22 -0
- data/spec/semipublic/property/float_spec.rb +83 -0
- data/spec/semipublic/property/integer_spec.rb +83 -0
- data/spec/semipublic/property/lookup_spec.rb +27 -0
- data/spec/semipublic/property/serial_spec.rb +14 -0
- data/spec/semipublic/property/string_spec.rb +14 -0
- data/spec/semipublic/property/text_spec.rb +30 -0
- data/spec/semipublic/property/time_spec.rb +49 -0
- data/spec/semipublic/property_spec.rb +51 -0
- data/spec/shared/flags_shared_spec.rb +36 -0
- data/spec/shared/identity_function_group.rb +5 -0
- data/spec/shared/public_property_spec.rb +229 -0
- data/spec/shared/semipublic_property_spec.rb +159 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +58 -0
- data/spec/unit/bcrypt_hash_spec.rb +154 -0
- data/spec/unit/csv_spec.rb +139 -0
- data/spec/unit/dirty_minder_spec.rb +64 -0
- data/spec/unit/enum_spec.rb +125 -0
- data/spec/unit/epoch_time_spec.rb +72 -0
- data/spec/unit/file_path_spec.rb +75 -0
- data/spec/unit/flag_spec.rb +114 -0
- data/spec/unit/ip_address_spec.rb +109 -0
- data/spec/unit/json_spec.rb +127 -0
- data/spec/unit/paranoid_boolean_spec.rb +142 -0
- data/spec/unit/paranoid_datetime_spec.rb +149 -0
- data/spec/unit/regexp_spec.rb +62 -0
- data/spec/unit/uri_spec.rb +64 -0
- data/spec/unit/yaml_spec.rb +111 -0
- data/tasks/spec.rake +40 -0
- data/tasks/yard.rake +9 -0
- data/tasks/yardstick.rake +19 -0
- metadata +350 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'ardm/property/string'
|
|
2
|
+
require 'ardm/property/support/dirty_minder'
|
|
3
|
+
|
|
4
|
+
if RUBY_VERSION >= '1.9.0'
|
|
5
|
+
require 'csv'
|
|
6
|
+
else
|
|
7
|
+
require 'fastercsv' # must be ~>1.5
|
|
8
|
+
CSV = FasterCSV unless defined?(CSV)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
module Ardm
|
|
12
|
+
class Property
|
|
13
|
+
class Csv < String
|
|
14
|
+
load_as ::Array
|
|
15
|
+
|
|
16
|
+
def load(value)
|
|
17
|
+
case value
|
|
18
|
+
when ::String then CSV.parse(value)
|
|
19
|
+
when ::Array then value
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def dump(value)
|
|
24
|
+
case value
|
|
25
|
+
when ::Array
|
|
26
|
+
CSV.generate { |csv| value.each { |row| csv << row } }
|
|
27
|
+
when ::String then value
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
include ::Ardm::Property::DirtyMinder
|
|
32
|
+
|
|
33
|
+
end # class Csv
|
|
34
|
+
end # class Property
|
|
35
|
+
end # module Ardm
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'bigdecimal'
|
|
2
|
+
|
|
3
|
+
module Ardm
|
|
4
|
+
class Property
|
|
5
|
+
class Decimal < Numeric
|
|
6
|
+
load_as BigDecimal
|
|
7
|
+
dump_as BigDecimal
|
|
8
|
+
coercion_method :to_decimal
|
|
9
|
+
|
|
10
|
+
DEFAULT_PRECISION = 10
|
|
11
|
+
DEFAULT_SCALE = 0
|
|
12
|
+
|
|
13
|
+
precision(DEFAULT_PRECISION)
|
|
14
|
+
scale(DEFAULT_SCALE)
|
|
15
|
+
|
|
16
|
+
protected
|
|
17
|
+
|
|
18
|
+
def initialize(model, name, options = {})
|
|
19
|
+
super
|
|
20
|
+
|
|
21
|
+
[ :scale, :precision ].each do |key|
|
|
22
|
+
unless @options.key?(key)
|
|
23
|
+
warn "options[#{key.inspect}] should be set for #{self.class}, defaulting to #{send(key).inspect} (#{caller.first})"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
unless @scale >= 0
|
|
28
|
+
raise ArgumentError, "scale must be equal to or greater than 0, but was #{@scale.inspect}"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
unless @precision >= @scale
|
|
32
|
+
raise ArgumentError, "precision must be equal to or greater than scale, but was #{@precision.inspect} and scale was #{@scale.inspect}"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end # class Decimal
|
|
37
|
+
end # class Property
|
|
38
|
+
end # module Ardm
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'ardm/property/class'
|
|
2
|
+
|
|
3
|
+
module Ardm
|
|
4
|
+
class Property
|
|
5
|
+
class Discriminator < Class
|
|
6
|
+
load_as ::Class
|
|
7
|
+
dump_as ::String
|
|
8
|
+
default lambda { |resource, property| resource.class }
|
|
9
|
+
required true
|
|
10
|
+
|
|
11
|
+
# ActiveRecord just stores the string name of the class.
|
|
12
|
+
# We dump false for a bad value because it results in a
|
|
13
|
+
# class that isn't in the "dump_as".
|
|
14
|
+
#
|
|
15
|
+
# Expects the class name to be a valid class name that is
|
|
16
|
+
# loaded and available.
|
|
17
|
+
def dump(value)
|
|
18
|
+
dumped = typecast(value)
|
|
19
|
+
dumped.name if dumped.is_a?(::Class)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def load(value)
|
|
23
|
+
typecast(value)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @api private
|
|
27
|
+
def bind
|
|
28
|
+
model.inheritance_column = field
|
|
29
|
+
model.extend Model unless model < Model
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
module Model
|
|
33
|
+
def inherited(model)
|
|
34
|
+
super # setup self.descendants
|
|
35
|
+
#set_discriminator_scope_for(model)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def new(*args, &block)
|
|
39
|
+
if args.size == 1 && args.first.kind_of?(Hash)
|
|
40
|
+
discriminator = properties.discriminator
|
|
41
|
+
|
|
42
|
+
if discriminator_value = args.first[discriminator.name]
|
|
43
|
+
model = discriminator.typecast(discriminator_value)
|
|
44
|
+
|
|
45
|
+
if model.kind_of?(Model) && !model.equal?(self)
|
|
46
|
+
return model.new(*args, &block)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
super
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
def set_discriminator_scope_for(model)
|
|
57
|
+
discriminator = self.properties.discriminator
|
|
58
|
+
model.scoped.with_default_scope.update_all(discriminator.field => model.descendants.dup << model)
|
|
59
|
+
rescue ::ActiveRecord::ConnectionNotEstablished => e
|
|
60
|
+
puts "Error was raised but it seems to be an ActiveRecord 3.2 error, fixed in 4:\n#{e}"
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end # class Discriminator
|
|
64
|
+
end # class Property
|
|
65
|
+
end # module Ardm
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'ardm/property/object'
|
|
2
|
+
require 'ardm/property/support/flags'
|
|
3
|
+
|
|
4
|
+
module Ardm
|
|
5
|
+
class Property
|
|
6
|
+
class Enum < Object
|
|
7
|
+
include Flags
|
|
8
|
+
|
|
9
|
+
load_as ::Object
|
|
10
|
+
dump_as ::Integer
|
|
11
|
+
|
|
12
|
+
def initialize(model, name, options = {})
|
|
13
|
+
@flag_map = {}
|
|
14
|
+
|
|
15
|
+
flags = options.fetch(:flags, self.class.flags)
|
|
16
|
+
flags.each_with_index do |flag, i|
|
|
17
|
+
@flag_map[i + 1] = flag
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
if self.class.accepted_options.include?(:set) && !options.include?(:set)
|
|
21
|
+
options[:set] = @flag_map.values_at(*@flag_map.keys.sort)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
super
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def load(value)
|
|
28
|
+
flag_map[value.to_i]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def dump(value)
|
|
32
|
+
case value
|
|
33
|
+
when ::Array then value.collect { |v| dump(v) }
|
|
34
|
+
else flag_map.invert[typecast(value)]
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def typecast(value)
|
|
39
|
+
return if value.nil?
|
|
40
|
+
# Attempt to typecast using the class of the first item in the map.
|
|
41
|
+
case flag_map[1]
|
|
42
|
+
when ::Symbol then value.to_sym
|
|
43
|
+
when ::String then value.to_s
|
|
44
|
+
when ::Fixnum then value.to_i
|
|
45
|
+
else value
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end # class Enum
|
|
50
|
+
end # class Property
|
|
51
|
+
end # module Ardm
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'ardm/property/time'
|
|
2
|
+
|
|
3
|
+
module Ardm
|
|
4
|
+
class Property
|
|
5
|
+
class EpochTime < Time
|
|
6
|
+
dump_as ::Integer
|
|
7
|
+
|
|
8
|
+
def load(value)
|
|
9
|
+
if value.kind_of?(::Numeric)
|
|
10
|
+
::Time.at(value.to_i)
|
|
11
|
+
else
|
|
12
|
+
value
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def dump(value)
|
|
17
|
+
value.to_i if value
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def typecast(value)
|
|
21
|
+
case value
|
|
22
|
+
when ::Time then value
|
|
23
|
+
when ::Numeric, /\A\d+\z/ then ::Time.at(value.to_i)
|
|
24
|
+
when ::DateTime then datetime_to_time(value)
|
|
25
|
+
when ::String then ::Time.parse(value)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def datetime_to_time(datetime)
|
|
32
|
+
utc = datetime.new_offset(0)
|
|
33
|
+
::Time.utc(utc.year, utc.month, utc.day, utc.hour, utc.min, utc.sec)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end # class EpochTime
|
|
37
|
+
end # class Property
|
|
38
|
+
end # module Ardm
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'pathname'
|
|
2
|
+
require 'ardm/property/string'
|
|
3
|
+
|
|
4
|
+
module Ardm
|
|
5
|
+
class Property
|
|
6
|
+
class FilePath < String
|
|
7
|
+
load_as Pathname
|
|
8
|
+
|
|
9
|
+
length 255
|
|
10
|
+
|
|
11
|
+
def load(value)
|
|
12
|
+
Pathname.new(value) unless Ardm::Ext.blank?(value)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def dump(value)
|
|
16
|
+
value.to_s unless Ardm::Ext.blank?(value)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def typecast(value)
|
|
20
|
+
load(value)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end # class FilePath
|
|
24
|
+
end # class Property
|
|
25
|
+
end # module Ardm
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'ardm/property/object'
|
|
2
|
+
require 'ardm/property/support/flags'
|
|
3
|
+
|
|
4
|
+
module Ardm
|
|
5
|
+
class Property
|
|
6
|
+
class Flag < Object
|
|
7
|
+
include Flags
|
|
8
|
+
|
|
9
|
+
load_as ::Object
|
|
10
|
+
dump_as ::Integer
|
|
11
|
+
|
|
12
|
+
def initialize(model, name, options = {})
|
|
13
|
+
super
|
|
14
|
+
|
|
15
|
+
@flag_map = {}
|
|
16
|
+
|
|
17
|
+
flags = options.fetch(:flags, self.class.flags)
|
|
18
|
+
flags.each_with_index do |flag, i|
|
|
19
|
+
flag_map[i] = flag
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def load(value)
|
|
24
|
+
return [] if value.nil? || value <= 0
|
|
25
|
+
|
|
26
|
+
begin
|
|
27
|
+
matches = []
|
|
28
|
+
|
|
29
|
+
0.upto(flag_map.size - 1) do |i|
|
|
30
|
+
matches << flag_map[i] if value[i] == 1
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
matches.compact
|
|
34
|
+
rescue TypeError, Errno::EDOM
|
|
35
|
+
[]
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def dump(value)
|
|
40
|
+
unless value.nil?
|
|
41
|
+
flags = Array(value).map { |flag| flag.to_sym }
|
|
42
|
+
flags.uniq!
|
|
43
|
+
|
|
44
|
+
flag = 0
|
|
45
|
+
|
|
46
|
+
flag_map.invert.values_at(*flags).each do |i|
|
|
47
|
+
next if i.nil?
|
|
48
|
+
flag += (1 << i)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
flag
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def typecast(value)
|
|
56
|
+
case value
|
|
57
|
+
when nil then nil
|
|
58
|
+
when ::Array then value.map { |v| v.to_sym }
|
|
59
|
+
else [value.to_sym]
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
end # class Flag
|
|
64
|
+
end # class Property
|
|
65
|
+
end # module Ardm
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'ardm/property/numeric'
|
|
2
|
+
|
|
3
|
+
module Ardm
|
|
4
|
+
class Property
|
|
5
|
+
class Float < Numeric
|
|
6
|
+
load_as ::Float
|
|
7
|
+
dump_as ::Float
|
|
8
|
+
coercion_method :to_float
|
|
9
|
+
|
|
10
|
+
DEFAULT_PRECISION = 10
|
|
11
|
+
DEFAULT_SCALE = nil
|
|
12
|
+
|
|
13
|
+
precision(DEFAULT_PRECISION)
|
|
14
|
+
scale(DEFAULT_SCALE)
|
|
15
|
+
|
|
16
|
+
end # class Float
|
|
17
|
+
end # class Property
|
|
18
|
+
end # module Ardm
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'ardm/property/numeric'
|
|
2
|
+
|
|
3
|
+
module Ardm
|
|
4
|
+
class Property
|
|
5
|
+
class Integer < Numeric
|
|
6
|
+
load_as ::Integer
|
|
7
|
+
dump_as ::Integer
|
|
8
|
+
coercion_method :to_integer
|
|
9
|
+
|
|
10
|
+
accept_options :serial
|
|
11
|
+
|
|
12
|
+
protected
|
|
13
|
+
|
|
14
|
+
# @api semipublic
|
|
15
|
+
def initialize(model, name, options = {})
|
|
16
|
+
if options.key?(:serial) && !kind_of?(Serial)
|
|
17
|
+
raise "Integer #{name} with explicit :serial option is deprecated, use Serial instead (#{caller[2]})"
|
|
18
|
+
end
|
|
19
|
+
super
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end # class Integer
|
|
23
|
+
end # class Property
|
|
24
|
+
end # module Ardm
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Ardm
|
|
2
|
+
class Property
|
|
3
|
+
# Exception raised when Ardm is about to work with
|
|
4
|
+
# invalid property values.
|
|
5
|
+
class InvalidValueError < StandardError
|
|
6
|
+
attr_reader :property, :value
|
|
7
|
+
|
|
8
|
+
def initialize(property, value)
|
|
9
|
+
msg = "Invalid value %s for property %s (%s) on model %s" %
|
|
10
|
+
[ value.inspect,
|
|
11
|
+
property.name.inspect,
|
|
12
|
+
property.class.name,
|
|
13
|
+
property.model.name
|
|
14
|
+
]
|
|
15
|
+
super(msg)
|
|
16
|
+
@property = property
|
|
17
|
+
@value = value
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end # class InvalidValueError
|
|
21
|
+
end # class Property
|
|
22
|
+
end # module Ardm
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'ipaddr'
|
|
2
|
+
require 'ardm/property/string'
|
|
3
|
+
|
|
4
|
+
module Ardm
|
|
5
|
+
class Property
|
|
6
|
+
class IPAddress < String
|
|
7
|
+
load_as IPAddr
|
|
8
|
+
|
|
9
|
+
length 39
|
|
10
|
+
|
|
11
|
+
def load(value)
|
|
12
|
+
if value.nil? || value_loaded?(value)
|
|
13
|
+
value
|
|
14
|
+
elsif value.is_a?(::String)
|
|
15
|
+
unless value.empty?
|
|
16
|
+
IPAddr.new(value)
|
|
17
|
+
else
|
|
18
|
+
IPAddr.new("0.0.0.0")
|
|
19
|
+
end
|
|
20
|
+
else
|
|
21
|
+
raise ArgumentError.new("+value+ must be nil or a String")
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def dump(value)
|
|
26
|
+
value.to_s unless value.nil?
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def typecast(value)
|
|
30
|
+
load(value) unless value.nil?
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end # class IPAddress
|
|
34
|
+
end # class Property
|
|
35
|
+
end # module Ardm
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'ardm/property/text'
|
|
2
|
+
require 'ardm/property/support/dirty_minder'
|
|
3
|
+
require 'multi_json'
|
|
4
|
+
|
|
5
|
+
module Ardm
|
|
6
|
+
class Property
|
|
7
|
+
class Json < Text
|
|
8
|
+
load_as ::Object
|
|
9
|
+
|
|
10
|
+
def load(value)
|
|
11
|
+
if value.nil? || value_loaded?(value)
|
|
12
|
+
value
|
|
13
|
+
elsif value.is_a?(::String)
|
|
14
|
+
typecast(value)
|
|
15
|
+
else
|
|
16
|
+
raise ArgumentError.new("+value+ of a property of JSON type must be nil or a String")
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def dump(value)
|
|
21
|
+
if value.nil? || value.is_a?(::String)
|
|
22
|
+
value
|
|
23
|
+
else
|
|
24
|
+
MultiJson.dump(value)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def typecast(value)
|
|
29
|
+
return if value.nil?
|
|
30
|
+
|
|
31
|
+
if value_loaded?(value)
|
|
32
|
+
value
|
|
33
|
+
else
|
|
34
|
+
MultiJson.load(value.to_s)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def value_loaded?(value)
|
|
39
|
+
value.kind_of?(::Array) || value.kind_of?(::Hash)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
include ::Ardm::Property::DirtyMinder
|
|
43
|
+
|
|
44
|
+
end # class Json
|
|
45
|
+
|
|
46
|
+
JSON = Json
|
|
47
|
+
|
|
48
|
+
end # class Property
|
|
49
|
+
end # module Ardm
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'ardm/property'
|
|
2
|
+
|
|
3
|
+
module Ardm
|
|
4
|
+
class Property
|
|
5
|
+
module Lookup
|
|
6
|
+
|
|
7
|
+
# Provides transparent access to the Properties defined in
|
|
8
|
+
# {Property}.
|
|
9
|
+
#
|
|
10
|
+
# @param [Symbol] name
|
|
11
|
+
# The name of the property to lookup.
|
|
12
|
+
#
|
|
13
|
+
# @return [Property]
|
|
14
|
+
# The property with the given name.
|
|
15
|
+
#
|
|
16
|
+
# @raise [NameError]
|
|
17
|
+
# The property could not be found.
|
|
18
|
+
#
|
|
19
|
+
# @api private
|
|
20
|
+
#
|
|
21
|
+
# @since 1.0.1
|
|
22
|
+
#
|
|
23
|
+
def const_missing(name)
|
|
24
|
+
Property.find_class(name.to_s) || super
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end # module Lookup
|
|
28
|
+
end # class Property
|
|
29
|
+
end # module Ardm
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'ardm/property/object'
|
|
2
|
+
|
|
3
|
+
module Ardm
|
|
4
|
+
class Property
|
|
5
|
+
class Numeric < Object
|
|
6
|
+
accept_options :precision, :scale, :min, :max
|
|
7
|
+
|
|
8
|
+
attr_reader :precision, :scale, :min, :max
|
|
9
|
+
|
|
10
|
+
DEFAULT_NUMERIC_MIN = 0
|
|
11
|
+
DEFAULT_NUMERIC_MAX = 2**31-1
|
|
12
|
+
|
|
13
|
+
protected
|
|
14
|
+
|
|
15
|
+
def initialize(model, name, options = {})
|
|
16
|
+
super
|
|
17
|
+
|
|
18
|
+
if kind_of?(Decimal) || kind_of?(Float)
|
|
19
|
+
@precision = @options.fetch(:precision)
|
|
20
|
+
@scale = @options.fetch(:scale)
|
|
21
|
+
|
|
22
|
+
unless @precision > 0
|
|
23
|
+
raise ArgumentError, "precision must be greater than 0, but was #{@precision.inspect}"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
if @options.key?(:min) || @options.key?(:max)
|
|
28
|
+
@min = @options.fetch(:min, self.class::DEFAULT_NUMERIC_MIN)
|
|
29
|
+
@max = @options.fetch(:max, self.class::DEFAULT_NUMERIC_MAX)
|
|
30
|
+
|
|
31
|
+
if @max < DEFAULT_NUMERIC_MIN && !@options.key?(:min)
|
|
32
|
+
raise ArgumentError, "min should be specified when the max is less than #{DEFAULT_NUMERIC_MIN}"
|
|
33
|
+
elsif @max < @min
|
|
34
|
+
raise ArgumentError, "max must be less than the min, but was #{@max} while the min was #{@min}"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end # class Numeric
|
|
39
|
+
end # class Property
|
|
40
|
+
end # module Ardm
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'ardm/property'
|
|
2
|
+
|
|
3
|
+
module Ardm
|
|
4
|
+
class Property
|
|
5
|
+
class Object < Property
|
|
6
|
+
load_as ::Object
|
|
7
|
+
dump_as ::Object
|
|
8
|
+
coercion_method :to_object
|
|
9
|
+
|
|
10
|
+
# @api semipublic
|
|
11
|
+
def dump(value)
|
|
12
|
+
instance_of?(Object) ? marshal(value) : value
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @api semipublic
|
|
16
|
+
def load(value)
|
|
17
|
+
typecast(instance_of?(Object) ? unmarshal(value) : value)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# @api semipublic
|
|
21
|
+
def marshal(value)
|
|
22
|
+
[ Marshal.dump(value) ].pack('m') unless value.nil?
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @api semipublic
|
|
26
|
+
def unmarshal(value)
|
|
27
|
+
Marshal.load(value.unpack('m').first) unless value.nil?
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @api private
|
|
31
|
+
def to_child_key
|
|
32
|
+
self.class
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'ardm/property/boolean'
|
|
2
|
+
require 'ardm/property/support/paranoid_base'
|
|
3
|
+
|
|
4
|
+
module Ardm
|
|
5
|
+
class Property
|
|
6
|
+
class ParanoidBoolean < Boolean
|
|
7
|
+
default false
|
|
8
|
+
lazy true
|
|
9
|
+
|
|
10
|
+
# @api private
|
|
11
|
+
def bind
|
|
12
|
+
model.send(:include, Ardm::Property::ParanoidBase)
|
|
13
|
+
model.set_paranoid_property(name) { true }
|
|
14
|
+
model.set_paranoid_scope(model.arel_table[name].eq(false))
|
|
15
|
+
end
|
|
16
|
+
end # class ParanoidBoolean
|
|
17
|
+
end # class Property
|
|
18
|
+
end # module Ardm
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'ardm/property/datetime'
|
|
2
|
+
require 'ardm/property/support/paranoid_base'
|
|
3
|
+
|
|
4
|
+
module Ardm
|
|
5
|
+
class Property
|
|
6
|
+
class ParanoidDateTime < DateTime
|
|
7
|
+
lazy true
|
|
8
|
+
|
|
9
|
+
# @api private
|
|
10
|
+
def bind
|
|
11
|
+
model.send(:include, Ardm::Property::ParanoidBase)
|
|
12
|
+
model.set_paranoid_property(name) { ::DateTime.now }
|
|
13
|
+
model.set_paranoid_scope(model.arel_table[name].eq(nil))
|
|
14
|
+
end
|
|
15
|
+
end # class ParanoidDateTime
|
|
16
|
+
end # class Property
|
|
17
|
+
end # module Ardm
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'ardm/property/string'
|
|
2
|
+
|
|
3
|
+
module Ardm
|
|
4
|
+
class Property
|
|
5
|
+
class Regexp < String
|
|
6
|
+
load_as ::Regexp
|
|
7
|
+
|
|
8
|
+
def load(value)
|
|
9
|
+
::Regexp.new(value) unless value.nil?
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def dump(value)
|
|
13
|
+
value.source unless value.nil?
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def typecast(value)
|
|
17
|
+
load(value)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|