ardm 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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,83 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
module Ardm
|
5
|
+
module ActiveRecord
|
6
|
+
module Relation
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
alias_method :destory_without_ardm, :destroy
|
11
|
+
alias_method :update_without_ardm, :update
|
12
|
+
|
13
|
+
# we need to overrite the implementation in the class
|
14
|
+
class_eval do
|
15
|
+
def update(*a)
|
16
|
+
if a.size == 1
|
17
|
+
# need to translate attributes
|
18
|
+
options = @klass.send(:dump_properties_hash, a.first)
|
19
|
+
update_all(options)
|
20
|
+
else
|
21
|
+
update_without_ardm(*a)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def destroy(id = nil)
|
26
|
+
if id
|
27
|
+
destroy_without_ardm(id)
|
28
|
+
else
|
29
|
+
destroy_all
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def first_or_create(attributes = nil, options = {}, &block)
|
34
|
+
first(attributes) || create(attributes, options, &block)
|
35
|
+
end
|
36
|
+
|
37
|
+
def first_or_create!(attributes = nil, options = {}, &block)
|
38
|
+
first(attributes) || create!(attributes, options, &block)
|
39
|
+
end
|
40
|
+
|
41
|
+
def first_or_initialize(attributes = nil, options = {}, &block)
|
42
|
+
first(attributes) || create(attributes, options, &block)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def all(options={})
|
48
|
+
apply_finder_options(options)
|
49
|
+
end
|
50
|
+
|
51
|
+
def apply_finder_options(options)
|
52
|
+
return super if options.nil? || options.empty?
|
53
|
+
options = options.dup
|
54
|
+
conditions = options.slice!(*::ActiveRecord::SpawnMethods::VALID_FIND_OPTIONS)
|
55
|
+
super(options).where(conditions)
|
56
|
+
end
|
57
|
+
|
58
|
+
def calculate(operation, column_name, options={})
|
59
|
+
if property = properties[column_name]
|
60
|
+
column_name = property.field
|
61
|
+
end
|
62
|
+
super(operation, column_name, options)
|
63
|
+
end
|
64
|
+
|
65
|
+
def method_missing(meth, *a, &b)
|
66
|
+
if a.empty? && association = reflect_on_association(meth.to_sym)
|
67
|
+
case association.macro
|
68
|
+
when :belongs_to
|
69
|
+
association.klass.where(klass.primary_key => self.select(association.foreign_key))
|
70
|
+
when :has_many, :has_one
|
71
|
+
association.klass.where(association.foreign_key => self.clone)
|
72
|
+
end
|
73
|
+
else
|
74
|
+
super
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def destroy!
|
79
|
+
delete_all
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Ardm
|
4
|
+
module ActiveRecord
|
5
|
+
module Repository
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
def repository
|
9
|
+
self.class.repository
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
def repository
|
14
|
+
if block_given?
|
15
|
+
yield
|
16
|
+
else
|
17
|
+
Ardm::ActiveRecord::Repository::Proxy.new self
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Proxy
|
23
|
+
def initialize(model)
|
24
|
+
@model = model
|
25
|
+
end
|
26
|
+
|
27
|
+
def adapter
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def select(*args)
|
32
|
+
array_of_hashes = @model.connection.select_all(@model.send(:sanitize_sql_array, args))
|
33
|
+
array_of_hashes.map { |h| Hashie::Mash.new(h) }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Ardm
|
4
|
+
module ActiveRecord
|
5
|
+
module Serialization
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
# Returns a hash of all the attributes that have been specified for
|
10
|
+
# serialization as keys and their class restriction as values.
|
11
|
+
class_attribute :serialized_attributes, instance_accessor: false
|
12
|
+
self.serialized_attributes = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
##
|
17
|
+
# :method: serialized_attributes
|
18
|
+
#
|
19
|
+
# Returns a hash of all the attributes that have been specified for
|
20
|
+
# serialization as keys and their class restriction as values.
|
21
|
+
|
22
|
+
# If you have an attribute that needs to be saved to the database as an
|
23
|
+
# object, and retrieved as the same object, then specify the name of that
|
24
|
+
# attribute using this method and it will be handled automatically. The
|
25
|
+
# serialization is done through YAML. If +class_name+ is specified, the
|
26
|
+
# serialized object must be of that class on retrieval or
|
27
|
+
# <tt>SerializationTypeMismatch</tt> will be raised.
|
28
|
+
#
|
29
|
+
# ==== Parameters
|
30
|
+
#
|
31
|
+
# * +attr_name+ - The field name that should be serialized.
|
32
|
+
# * +class_name+ - Optional, class name that the object type should be equal to.
|
33
|
+
#
|
34
|
+
# ==== Example
|
35
|
+
#
|
36
|
+
# # Serialize a preferences attribute.
|
37
|
+
# class User < ActiveRecord::Base
|
38
|
+
# serialize :preferences
|
39
|
+
# end
|
40
|
+
def serialize(attr_name, class_name = Object)
|
41
|
+
include Behavior
|
42
|
+
|
43
|
+
coder = if [:load, :dump].all? { |x| class_name.respond_to?(x) }
|
44
|
+
class_name
|
45
|
+
else
|
46
|
+
Coders::YAMLColumn.new(class_name)
|
47
|
+
end
|
48
|
+
|
49
|
+
# merge new serialized attribute and create new hash to ensure that each class in inheritance hierarchy
|
50
|
+
# has its own hash of own serialized attributes
|
51
|
+
self.serialized_attributes = serialized_attributes.merge(attr_name.to_s => coder)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# *DEPRECATED*: Use ActiveRecord::AttributeMethods::Serialization::ClassMethods#serialized_attributes class level method instead.
|
56
|
+
def serialized_attributes
|
57
|
+
message = "Instance level serialized_attributes method is deprecated, please use class level method."
|
58
|
+
ActiveSupport::Deprecation.warn message
|
59
|
+
defined?(@serialized_attributes) ? @serialized_attributes : self.class.serialized_attributes
|
60
|
+
end
|
61
|
+
|
62
|
+
class Type # :nodoc:
|
63
|
+
def initialize(column)
|
64
|
+
@column = column
|
65
|
+
end
|
66
|
+
|
67
|
+
def type_cast(value)
|
68
|
+
if value.state == :serialized
|
69
|
+
value.unserialized_value @column.type_cast value.value
|
70
|
+
else
|
71
|
+
value.unserialized_value
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def type
|
76
|
+
@column.type
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class Attribute < Struct.new(:coder, :value, :state) # :nodoc:
|
81
|
+
def unserialized_value(v = value)
|
82
|
+
state == :serialized ? unserialize(v) : value
|
83
|
+
end
|
84
|
+
|
85
|
+
def serialized_value
|
86
|
+
state == :unserialized ? serialize : value
|
87
|
+
end
|
88
|
+
|
89
|
+
def unserialize(v)
|
90
|
+
self.state = :unserialized
|
91
|
+
self.value = coder.load(v)
|
92
|
+
end
|
93
|
+
|
94
|
+
def serialize
|
95
|
+
self.state = :serialized
|
96
|
+
self.value = coder.dump(value)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# This is only added to the model when serialize is called, which
|
101
|
+
# ensures we do not make things slower when serialization is not used.
|
102
|
+
module Behavior # :nodoc:
|
103
|
+
extend ActiveSupport::Concern
|
104
|
+
|
105
|
+
module ClassMethods # :nodoc:
|
106
|
+
def initialize_attributes(attributes, options = {})
|
107
|
+
serialized = (options.delete(:serialized) { true }) ? :serialized : :unserialized
|
108
|
+
super(attributes, options)
|
109
|
+
|
110
|
+
serialized_attributes.each do |key, coder|
|
111
|
+
if attributes.key?(key)
|
112
|
+
attributes[key] = Attribute.new(coder, attributes[key], serialized)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
attributes
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def type_cast_attribute_for_write(column, value)
|
121
|
+
if column && coder = self.class.serialized_attributes[column.name]
|
122
|
+
Attribute.new(coder, value, :unserialized)
|
123
|
+
else
|
124
|
+
super
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def _field_changed?(attr, old, value)
|
129
|
+
if self.class.serialized_attributes.include?(attr)
|
130
|
+
old != value
|
131
|
+
else
|
132
|
+
super
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def read_attribute_before_type_cast(attr_name)
|
137
|
+
if self.class.serialized_attributes.include?(attr_name)
|
138
|
+
super.unserialized_value
|
139
|
+
else
|
140
|
+
super
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def attributes_before_type_cast
|
145
|
+
super.dup.tap do |attributes|
|
146
|
+
self.class.serialized_attributes.each_key do |key|
|
147
|
+
if attributes.key?(key)
|
148
|
+
attributes[key] = attributes[key].unserialized_value
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def typecasted_attribute_value(name)
|
155
|
+
if self.class.serialized_attributes.include?(name)
|
156
|
+
@attributes[name].serialized_value
|
157
|
+
else
|
158
|
+
super
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Ardm
|
4
|
+
module ActiveRecord
|
5
|
+
module StorageNames
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
def storage_names
|
10
|
+
Ardm::ActiveRecord::StorageNames::Proxy.new(self)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Proxy
|
15
|
+
def initialize(model)
|
16
|
+
@model = model
|
17
|
+
end
|
18
|
+
|
19
|
+
def []=(repo, table_name)
|
20
|
+
unless repo == :default
|
21
|
+
raise ArgumentError, "repositories other than :default not supported."
|
22
|
+
end
|
23
|
+
@model.table_name = table_name
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'active_model/validations'
|
3
|
+
|
4
|
+
module Ardm
|
5
|
+
module ActiveRecord
|
6
|
+
# Extend ActiveRecord to support DataMapper validations
|
7
|
+
module Validations
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
include ActiveModel::Validations
|
11
|
+
|
12
|
+
# Extract and convert options from DM style to AR style
|
13
|
+
def self.extract_options(fields, *keep)
|
14
|
+
keep += [:on, :message, :if, :unless]
|
15
|
+
|
16
|
+
if Hash === fields.last
|
17
|
+
ar = fields.pop.dup
|
18
|
+
ar[:on] = ar.delete(:when) if ar[:when] && [:create, :update].include?(ar[:when])
|
19
|
+
ar[:maximum] = ar.delete(:max) if ar[:max]
|
20
|
+
ar[:in] = ar.delete(:set) if ar[:set]
|
21
|
+
|
22
|
+
removed = ar.slice!(*keep)
|
23
|
+
unless removed.empty?
|
24
|
+
$stderr.puts "WARNING validation options not handled: #{removed.inspect} in:"
|
25
|
+
$stderr.puts caller[0..1]
|
26
|
+
end
|
27
|
+
else
|
28
|
+
ar = {}
|
29
|
+
end
|
30
|
+
|
31
|
+
[fields, ar]
|
32
|
+
end
|
33
|
+
|
34
|
+
module ClassMethods
|
35
|
+
|
36
|
+
def validates_belongs_to(*fields)
|
37
|
+
fields, options = Ardm::ActiveRecord::Validations.extract_options(fields)
|
38
|
+
validates *fields, presence: options
|
39
|
+
end
|
40
|
+
|
41
|
+
def validates_presence_of(*fields)
|
42
|
+
fields, options = Ardm::ActiveRecord::Validations.extract_options(fields)
|
43
|
+
validates *fields, presence: options
|
44
|
+
end
|
45
|
+
|
46
|
+
def validates_length_of(*fields)
|
47
|
+
fields, options = Ardm::ActiveRecord::Validations.extract_options(fields, :in, :within, :maximum, :minimum, :is)
|
48
|
+
validates *fields, length: options
|
49
|
+
end
|
50
|
+
|
51
|
+
def validates_uniqueness_of(*fields)
|
52
|
+
fields, options = Ardm::ActiveRecord::Validations.extract_options(fields, :scope)
|
53
|
+
fields = fields.map do |field|
|
54
|
+
if property = properties[field]
|
55
|
+
property.field
|
56
|
+
elsif assoc = reflect_on_association(field)
|
57
|
+
assoc.foreign_key
|
58
|
+
else
|
59
|
+
field
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
if options[:scope]
|
64
|
+
options[:scope] = Array(options[:scope]).map do |scope|
|
65
|
+
assoc = reflect_on_association(scope)
|
66
|
+
assoc ? assoc.foreign_key : scope
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
validates *fields, uniqueness: options
|
71
|
+
end
|
72
|
+
|
73
|
+
def validates_within(*fields)
|
74
|
+
fields, options = Ardm::ActiveRecord::Validations.extract_options(fields, :in)
|
75
|
+
validates *fields, inclusion: options
|
76
|
+
end
|
77
|
+
|
78
|
+
# Possible formats:
|
79
|
+
#
|
80
|
+
# validates_with_method :attr, :method_name
|
81
|
+
# validates_with_method :attr, method: :method_name
|
82
|
+
# validates_with_method :method_name, options: "here"
|
83
|
+
def validates_with_method(*fields)
|
84
|
+
fields, options = Ardm::ActiveRecord::Validations.extract_options(fields, :method)
|
85
|
+
|
86
|
+
# validates_with_method :attr, :method_name
|
87
|
+
att, meth = *fields
|
88
|
+
|
89
|
+
# validates_with_method :attr, method: :method_name
|
90
|
+
meth = options[:method] if options[:method]
|
91
|
+
|
92
|
+
# validates_with_method :method_name
|
93
|
+
att, meth = :base, att if !meth
|
94
|
+
|
95
|
+
validates_with_block(att) do
|
96
|
+
self.send(meth)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def validates_with_block(att=nil, &block)
|
101
|
+
validate do |record|
|
102
|
+
val, message = instance_eval(&block)
|
103
|
+
unless val
|
104
|
+
errors.add(att, message)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
puts __FILE__
|
2
|
+
require 'ardm'
|
3
|
+
|
4
|
+
# only load support libs in active record mode (dm will supply its own libs)
|
5
|
+
require 'ardm/support/ext/blank'
|
6
|
+
require 'ardm/support/ext/hash'
|
7
|
+
require 'ardm/support/ext/object'
|
8
|
+
require 'ardm/support/ext/string'
|
9
|
+
|
10
|
+
require 'ardm/support/ext/module'
|
11
|
+
require 'ardm/support/ext/array'
|
12
|
+
require 'ardm/support/ext/try_dup'
|
13
|
+
|
14
|
+
require 'ardm/support/mash'
|
15
|
+
require 'ardm/support/deprecate'
|
16
|
+
require 'ardm/support/descendant_set'
|
17
|
+
require 'ardm/support/equalizer'
|
18
|
+
require 'ardm/support/assertions'
|
19
|
+
require 'ardm/support/lazy_array'
|
20
|
+
require 'ardm/support/local_object_space'
|
21
|
+
require 'ardm/support/hook'
|
22
|
+
require 'ardm/support/subject'
|
23
|
+
require 'ardm/support/ordered_set'
|
24
|
+
require 'ardm/support/subject_set'
|
25
|
+
require 'ardm/support/descendant_set'
|
26
|
+
|
27
|
+
require 'active_record'
|
28
|
+
require 'active_record/relation'
|
29
|
+
|
30
|
+
require 'ardm/active_record/record'
|
31
|
+
require 'ardm/active_record/relation'
|
32
|
+
|
33
|
+
module Ardm
|
34
|
+
Record = Ardm::ActiveRecord::Record
|
35
|
+
end
|
36
|
+
|
37
|
+
#::ActiveRecord::Base.class_eval do
|
38
|
+
# include Ardm::ActiveRecord::Base
|
39
|
+
#end
|
40
|
+
|
41
|
+
::ActiveRecord::Relation.class_eval do
|
42
|
+
include Ardm::ActiveRecord::Relation
|
43
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'awsm/resource'
|
2
|
+
|
3
|
+
module Ardm
|
4
|
+
module DataMapper
|
5
|
+
module Record
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
NotFound = DataMapper::ObjectNotFoundError
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def inherited(base)
|
12
|
+
base.send(:include, DataMapper::Resource)
|
13
|
+
base.send(:include, Awsm::Resource)
|
14
|
+
#base.send(:extend, DataMapper::CollectionRaise)
|
15
|
+
|
16
|
+
unless %w[Alert Association Nonce Account::Cancellation::Handler].include?(base.name)
|
17
|
+
base.timestamps :at
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
extend Forwardable
|
22
|
+
def datamapper() DataMapper end
|
23
|
+
def_delegators :datamapper, :repository, :finalize, :logger, :logger=
|
24
|
+
|
25
|
+
def execute_sql(sql)
|
26
|
+
DataMapper.repository.adapter.execute(sql)
|
27
|
+
end
|
28
|
+
|
29
|
+
def alias_attribute(new, old)
|
30
|
+
alias_method new, old
|
31
|
+
end
|
32
|
+
|
33
|
+
def attr_accessible(*attrs)
|
34
|
+
end
|
35
|
+
|
36
|
+
def abstract_class=(val)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/ardm/env.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'ardm/property/string'
|
2
|
+
|
3
|
+
require 'digest/sha1'
|
4
|
+
|
5
|
+
module Ardm
|
6
|
+
class Property
|
7
|
+
class APIKey < String
|
8
|
+
|
9
|
+
# The amount of random seed data to use to generate tha API Key
|
10
|
+
PADDING = 256
|
11
|
+
|
12
|
+
length 40
|
13
|
+
unique true
|
14
|
+
default proc { APIKey.generate }
|
15
|
+
|
16
|
+
#
|
17
|
+
# Generates a new API Key.
|
18
|
+
#
|
19
|
+
# @return [String]
|
20
|
+
# The new API Key.
|
21
|
+
#
|
22
|
+
def self.generate
|
23
|
+
sha1 = Digest::SHA1.new
|
24
|
+
|
25
|
+
PADDING.times { sha1 << rand(256).chr }
|
26
|
+
return sha1.hexdigest
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'ardm/property/string'
|
2
|
+
require 'bcrypt'
|
3
|
+
|
4
|
+
module Ardm
|
5
|
+
class Property
|
6
|
+
class BCryptHash < String
|
7
|
+
load_as BCrypt::Password
|
8
|
+
|
9
|
+
length 60
|
10
|
+
|
11
|
+
def load(value)
|
12
|
+
unless value.nil?
|
13
|
+
begin
|
14
|
+
value_loaded?(value) ? value : BCrypt::Password.new(value)
|
15
|
+
rescue BCrypt::Errors::InvalidHash
|
16
|
+
BCrypt::Password.create(value, :cost => BCrypt::Engine::DEFAULT_COST)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def dump(value)
|
22
|
+
load(value)
|
23
|
+
end
|
24
|
+
|
25
|
+
def typecast(value)
|
26
|
+
load(value)
|
27
|
+
end
|
28
|
+
|
29
|
+
end # class BCryptHash
|
30
|
+
end # class Property
|
31
|
+
end # module Ardm
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'ardm/property/string'
|
2
|
+
|
3
|
+
module Ardm
|
4
|
+
class Property
|
5
|
+
class Binary < String
|
6
|
+
|
7
|
+
if RUBY_VERSION >= "1.9"
|
8
|
+
|
9
|
+
def load(value)
|
10
|
+
super.dup.force_encoding("BINARY") unless value.nil?
|
11
|
+
end
|
12
|
+
|
13
|
+
def dump(value)
|
14
|
+
value.dup.force_encoding("BINARY") unless value.nil?
|
15
|
+
rescue
|
16
|
+
value
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end # class Binary
|
22
|
+
end # class Property
|
23
|
+
end # module Ardm
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'ardm/property/object'
|
2
|
+
|
3
|
+
module Ardm
|
4
|
+
class Property
|
5
|
+
class Boolean < Object
|
6
|
+
load_as ::TrueClass
|
7
|
+
dump_as ::TrueClass
|
8
|
+
coercion_method :to_boolean
|
9
|
+
|
10
|
+
def initialize(model, name, options = {})
|
11
|
+
# validates presence in rails fails for false.
|
12
|
+
# Boolean must therefore behave like a set.
|
13
|
+
options[:set] = [true, false]
|
14
|
+
super model, name, options
|
15
|
+
end
|
16
|
+
|
17
|
+
# @api semipublic
|
18
|
+
def value_dumped?(value)
|
19
|
+
value_loaded?(value)
|
20
|
+
end
|
21
|
+
|
22
|
+
# @api semipublic
|
23
|
+
def value_loaded?(value)
|
24
|
+
value == true || value == false
|
25
|
+
end
|
26
|
+
|
27
|
+
end # class Boolean
|
28
|
+
end # class Property
|
29
|
+
end # module Ardm
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'ardm/property/object'
|
2
|
+
|
3
|
+
module Ardm
|
4
|
+
class Property
|
5
|
+
class Class < Object
|
6
|
+
load_as ::Class
|
7
|
+
dump_as ::Class
|
8
|
+
coercion_method :to_constant
|
9
|
+
|
10
|
+
# @api semipublic
|
11
|
+
def typecast(value)
|
12
|
+
Ardm::Ext::Module.find_const(model, value.to_s) unless value.nil?
|
13
|
+
rescue NameError
|
14
|
+
value
|
15
|
+
end
|
16
|
+
|
17
|
+
end # class Class
|
18
|
+
end # class Property
|
19
|
+
end # module Ardm
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'ardm/property/yaml'
|
2
|
+
|
3
|
+
module Ardm
|
4
|
+
class Property
|
5
|
+
class CommaSeparatedList < Yaml
|
6
|
+
|
7
|
+
def dump(value)
|
8
|
+
if value.nil?
|
9
|
+
nil
|
10
|
+
elsif value.kind_of?(::Array)
|
11
|
+
super(value)
|
12
|
+
elsif value.kind_of?(::String)
|
13
|
+
v = []
|
14
|
+
|
15
|
+
value.split(',').each do |element|
|
16
|
+
element.strip!
|
17
|
+
v << element unless element.empty?
|
18
|
+
end
|
19
|
+
|
20
|
+
super(v)
|
21
|
+
else
|
22
|
+
raise ArgumentError, "+value+ of CommaSeparatedList must be a string, an array or nil, but given #{value.inspect}"
|
23
|
+
end
|
24
|
+
end # dump
|
25
|
+
|
26
|
+
end # CommaSeparatedList
|
27
|
+
end # Property
|
28
|
+
end # Ardm
|