simply_stored 0.3.9 → 0.5.0

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.
Files changed (132) hide show
  1. data/CHANGELOG.md +38 -0
  2. data/README.md +45 -24
  3. data/lib/simply_stored/couch/association_property.rb +27 -0
  4. data/lib/simply_stored/couch/belongs_to.rb +5 -7
  5. data/lib/simply_stored/couch/finders.rb +5 -1
  6. data/lib/simply_stored/couch/has_and_belongs_to_many.rb +202 -0
  7. data/lib/simply_stored/couch/has_many.rb +6 -51
  8. data/lib/simply_stored/couch/has_one.rb +4 -29
  9. data/lib/simply_stored/couch/properties.rb +11 -0
  10. data/lib/simply_stored/couch.rb +38 -2
  11. data/lib/simply_stored/instance_methods.rb +68 -29
  12. data/lib/simply_stored.rb +3 -1
  13. data/test/{couchdb/couch_active_model_compatibility_test.rb → active_model_compatibility_test.rb} +2 -2
  14. data/test/{couchdb/couch_belongs_to_test.rb → belongs_to_test.rb} +13 -3
  15. data/test/{couchdb/couch_conflict_handling_test.rb → conflict_handling_test.rb} +3 -3
  16. data/test/{couchdb/couch_finder_test.rb → finder_test.rb} +8 -3
  17. data/test/fixtures/couch.rb +55 -0
  18. data/test/has_and_belongs_to_many_test.rb +639 -0
  19. data/test/{couchdb/couch_has_many_test.rb → has_many_test.rb} +13 -3
  20. data/test/{couchdb/couch_has_one_test.rb → has_one_test.rb} +13 -3
  21. data/test/{couchdb/couch_instance_lifecycle_test.rb → instance_lifecycle_test.rb} +3 -3
  22. data/test/{couchdb/couch_mass_assignment_protection_test.rb → mass_assignment_protection_test.rb} +3 -3
  23. data/test/{couchdb/couch_s3_test.rb → s3_test.rb} +3 -3
  24. data/test/{couchdb/couch_soft_deletable_test.rb → soft_deletable_test.rb} +3 -3
  25. data/test/test_helper.rb +1 -5
  26. data/test/{couchdb/couch_validations_test.rb → validations_test.rb} +3 -3
  27. data/test/{couchdb/custom_views_test.rb → views_test.rb} +3 -3
  28. metadata +36 -234
  29. data/lib/simply_stored/simpledb/associations.rb +0 -215
  30. data/lib/simply_stored/simpledb/attributes.rb +0 -173
  31. data/lib/simply_stored/simpledb/storag.rb +0 -85
  32. data/lib/simply_stored/simpledb/validations.rb +0 -88
  33. data/lib/simply_stored/simpledb.rb +0 -216
  34. data/test/fixtures/simpledb/item.rb +0 -11
  35. data/test/fixtures/simpledb/item_daddy.rb +0 -8
  36. data/test/fixtures/simpledb/log_item.rb +0 -3
  37. data/test/fixtures/simpledb/namespace_bar.rb +0 -5
  38. data/test/fixtures/simpledb/namespace_foo.rb +0 -7
  39. data/test/fixtures/simpledb/protected_item.rb +0 -3
  40. data/test/simply_stored_simpledb_test.rb +0 -1376
  41. data/test/vendor/dhaka-2.2.1/lib/dhaka/dot/dot.rb +0 -29
  42. data/test/vendor/dhaka-2.2.1/lib/dhaka/evaluator/evaluator.rb +0 -133
  43. data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/closure_hash.rb +0 -15
  44. data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/grammar.rb +0 -240
  45. data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/grammar_symbol.rb +0 -27
  46. data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/precedence.rb +0 -19
  47. data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/production.rb +0 -36
  48. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/accept_actions.rb +0 -36
  49. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/alphabet.rb +0 -21
  50. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/compiled_lexer.rb +0 -46
  51. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/dfa.rb +0 -121
  52. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/lexeme.rb +0 -32
  53. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/lexer.rb +0 -70
  54. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/lexer_run.rb +0 -78
  55. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/regex_grammar.rb +0 -392
  56. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/regex_parser.rb +0 -2010
  57. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/regex_tokenizer.rb +0 -14
  58. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/specification.rb +0 -96
  59. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/state.rb +0 -68
  60. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/state_machine.rb +0 -37
  61. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/action.rb +0 -55
  62. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/channel.rb +0 -58
  63. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/compiled_parser.rb +0 -51
  64. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/conflict.rb +0 -54
  65. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/item.rb +0 -42
  66. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parse_result.rb +0 -50
  67. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parse_tree.rb +0 -66
  68. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parser.rb +0 -165
  69. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parser_methods.rb +0 -11
  70. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parser_run.rb +0 -39
  71. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parser_state.rb +0 -74
  72. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/token.rb +0 -22
  73. data/test/vendor/dhaka-2.2.1/lib/dhaka/runtime.rb +0 -51
  74. data/test/vendor/dhaka-2.2.1/lib/dhaka/tokenizer/tokenizer.rb +0 -190
  75. data/test/vendor/dhaka-2.2.1/lib/dhaka.rb +0 -62
  76. data/test/vendor/dhaka-2.2.1/test/all_tests.rb +0 -5
  77. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_evaluator.rb +0 -64
  78. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_evaluator_test.rb +0 -43
  79. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_grammar.rb +0 -41
  80. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_grammar_test.rb +0 -9
  81. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_test_methods.rb +0 -9
  82. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_tokenizer.rb +0 -39
  83. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_tokenizer_test.rb +0 -38
  84. data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_evaluator.rb +0 -43
  85. data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_grammar.rb +0 -24
  86. data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_grammar_test.rb +0 -30
  87. data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_lexer_specification.rb +0 -23
  88. data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_parser_test.rb +0 -33
  89. data/test/vendor/dhaka-2.2.1/test/brackets/bracket_grammar.rb +0 -23
  90. data/test/vendor/dhaka-2.2.1/test/brackets/bracket_tokenizer.rb +0 -22
  91. data/test/vendor/dhaka-2.2.1/test/brackets/brackets_test.rb +0 -28
  92. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_driver.rb +0 -46
  93. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_driver_test.rb +0 -276
  94. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_evaluator.rb +0 -284
  95. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_evaluator_test.rb +0 -38
  96. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_grammar.rb +0 -104
  97. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_lexer.rb +0 -109
  98. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_lexer_specification.rb +0 -37
  99. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_lexer_test.rb +0 -58
  100. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_parser.rb +0 -879
  101. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_parser_test.rb +0 -55
  102. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_test.rb +0 -170
  103. data/test/vendor/dhaka-2.2.1/test/core/another_lalr_but_not_slr_grammar.rb +0 -20
  104. data/test/vendor/dhaka-2.2.1/test/core/compiled_parser_test.rb +0 -44
  105. data/test/vendor/dhaka-2.2.1/test/core/dfa_test.rb +0 -170
  106. data/test/vendor/dhaka-2.2.1/test/core/evaluator_test.rb +0 -22
  107. data/test/vendor/dhaka-2.2.1/test/core/grammar_test.rb +0 -83
  108. data/test/vendor/dhaka-2.2.1/test/core/lalr_but_not_slr_grammar.rb +0 -19
  109. data/test/vendor/dhaka-2.2.1/test/core/lexer_test.rb +0 -139
  110. data/test/vendor/dhaka-2.2.1/test/core/malformed_grammar.rb +0 -7
  111. data/test/vendor/dhaka-2.2.1/test/core/malformed_grammar_test.rb +0 -8
  112. data/test/vendor/dhaka-2.2.1/test/core/nullable_grammar.rb +0 -21
  113. data/test/vendor/dhaka-2.2.1/test/core/parse_result_test.rb +0 -44
  114. data/test/vendor/dhaka-2.2.1/test/core/parser_state_test.rb +0 -24
  115. data/test/vendor/dhaka-2.2.1/test/core/parser_test.rb +0 -131
  116. data/test/vendor/dhaka-2.2.1/test/core/precedence_grammar.rb +0 -17
  117. data/test/vendor/dhaka-2.2.1/test/core/precedence_grammar_test.rb +0 -9
  118. data/test/vendor/dhaka-2.2.1/test/core/rr_conflict_grammar.rb +0 -21
  119. data/test/vendor/dhaka-2.2.1/test/core/simple_grammar.rb +0 -22
  120. data/test/vendor/dhaka-2.2.1/test/core/sr_conflict_grammar.rb +0 -16
  121. data/test/vendor/dhaka-2.2.1/test/dhaka_test_helper.rb +0 -17
  122. data/test/vendor/dhaka-2.2.1/test/fake_logger.rb +0 -17
  123. data/test/vendor/simplerdb-0.2/lib/simplerdb/client_exception.rb +0 -10
  124. data/test/vendor/simplerdb-0.2/lib/simplerdb/db.rb +0 -146
  125. data/test/vendor/simplerdb-0.2/lib/simplerdb/query_language.rb +0 -266
  126. data/test/vendor/simplerdb-0.2/lib/simplerdb/server.rb +0 -33
  127. data/test/vendor/simplerdb-0.2/lib/simplerdb/servlet.rb +0 -191
  128. data/test/vendor/simplerdb-0.2/lib/simplerdb.rb +0 -3
  129. data/test/vendor/simplerdb-0.2/test/functional_test.rb +0 -81
  130. data/test/vendor/simplerdb-0.2/test/query_evaluator_test.rb +0 -73
  131. data/test/vendor/simplerdb-0.2/test/query_parser_test.rb +0 -64
  132. data/test/vendor/simplerdb-0.2/test/simplerdb_test.rb +0 -80
@@ -1,173 +0,0 @@
1
- module SimplyStored
2
- module SimpleDB
3
- module Attributes
4
- def self.included(base)
5
- base.extend(ClassMethods)
6
- end
7
-
8
- module ClassMethods
9
- # generates an accessor for a simple attribute
10
- def simpledb_string(*attributes)
11
- attributes.each do |attr|
12
- # getter
13
- define_method attr.to_s do
14
- self[attr.to_s].try(:first) || @_partitioned_attributes.try(:[], attr.to_s)
15
- end
16
-
17
- # setter
18
- define_method "#{attr}=" do |val|
19
- self[attr.to_s] = val
20
- end
21
-
22
- add_attribute_definition_to_attribute_list(attr)
23
- add_attribute_definition_to_partition_list(attr)
24
- end
25
- end
26
-
27
- def simpledb_array(*attributes)
28
- attributes.each do |attr|
29
- # getter
30
- define_method attr.to_s do
31
- self[attr.to_s] = [] unless self[attr.to_s]
32
- self[attr.to_s]
33
- end
34
-
35
- # setter
36
- define_method "#{attr}=" do |val|
37
- self[attr.to_s] = [val].flatten
38
- end
39
-
40
- add_attribute_definition_to_attribute_list(attr)
41
- end
42
- end
43
-
44
- def simpledb_timestamp(*attributes)
45
- attributes.each do |attr|
46
- # getter
47
- define_method attr.to_s do
48
- if self[attr.to_s]
49
- cached = instance_variable_get("@#{attr}")
50
- if cached
51
- return cached
52
- else
53
- val = Time.parse(self[attr.to_s].first + "+0000").utc # UTC
54
- instance_variable_set("@#{attr}", val)
55
- return val
56
- end
57
- else
58
- nil
59
- end
60
- end
61
-
62
- # setter
63
- define_method "#{attr}=" do |val|
64
- instance_variable_set("@#{attr}", val)
65
- self[attr.to_s] = val.strftime("%Y%m%d%H%M%S")
66
- end
67
-
68
- add_attribute_definition_to_attribute_list(attr)
69
- end
70
- end
71
-
72
- def simpledb_integer(*attributes)
73
- attributes.each do |attr|
74
- # getter
75
- define_method attr.to_s do
76
- if self[attr.to_s]
77
- cached = instance_variable_get("@#{attr}")
78
- if cached
79
- return cached
80
- else
81
- val = self[attr.to_s].first.sub(/\A0+/, '').to_i
82
- instance_variable_set("@#{attr}", val)
83
- return val
84
- end
85
- else
86
- nil
87
- end
88
- end
89
-
90
- # setter
91
- define_method "#{attr}=" do |val|
92
- instance_variable_set("@#{attr}", val)
93
- self[attr.to_s] = sprintf("%016d", val.to_i)
94
- end
95
-
96
- add_attribute_definition_to_attribute_list(attr)
97
- end
98
- end
99
-
100
- def add_attribute_definition_to_attribute_list(attr)
101
- @_defined_attributes ||= []
102
- @_defined_attributes << attr.to_s
103
- end
104
-
105
- def add_attribute_definition_to_partition_list(attr)
106
- @_partitioned_attributes ||= []
107
- @_partitioned_attributes << attr.to_s
108
- end
109
-
110
- def attr_protected(*args)
111
- @_protected_attributes ||= []
112
- @_protected_attributes += args.to_a
113
- end
114
-
115
- def attr_accessible(*args)
116
- @_accessible_attributes ||= []
117
- @_accessible_attributes += args.to_a
118
- end
119
-
120
- end
121
-
122
- def attributes=(attr)
123
- attr = _remove_protected_attributes(attr)
124
- super(attr)
125
- end
126
-
127
- def _remove_protected_attributes(attrs)
128
- return {} if attrs.blank?
129
- attrs = attrs.dup.stringify_keys
130
- (self.class.instance_variable_get(:@_protected_attributes) || []).map(&:to_s).each do |protected_attribute|
131
- attrs.delete(protected_attribute)
132
- end
133
-
134
- accessible_attributes = (self.class.instance_variable_get(:@_accessible_attributes) || []).map(&:to_s)
135
-
136
- if accessible_attributes.present?
137
- attrs.each do |attr_key, attr_value|
138
- attrs.delete(attr_key) unless accessible_attributes.include?(attr_key)
139
- end
140
- end
141
-
142
- attrs
143
- end
144
-
145
- def partition_string_attributes
146
- (self.class.instance_variable_get(:@_partitioned_attributes) || []).each do |attr|
147
- next if self[attr].nil?
148
- value = self[attr].first
149
- if value.present? && value.size > 1024
150
- 0.upto(value.size / 1024) do |i|
151
- self["#{attr.to_s}_#{i}"] = value[(1024 * i)..(1024 * (i + 1) - 1)]
152
- end
153
- @_partitioned_attributes ||= {}
154
- @_partitioned_attributes[attr] = self[attr]
155
- send("#{attr}=", [])
156
- end
157
- end
158
- end
159
-
160
- def restore_partitioned_attributes
161
- (self.class.instance_variable_get(:@_partitioned_attributes) || []).each do |attr|
162
- if (partitions = attributes.select{|key, value| key.match(/^#{attr}_([0-9]+)$/)}).any?
163
- unpartitioned_value = ""
164
- partitions.sort_by{|key, value| key.match(/^#{attr}_([0-9]+)$/); $1}.each do |partition|
165
- unpartitioned_value << partition.last.first
166
- end
167
- self[attr] = unpartitioned_value
168
- end
169
- end
170
- end
171
- end
172
- end
173
- end
@@ -1,85 +0,0 @@
1
- module SimplyStore
2
- module Storage
3
- def self.included(base)
4
- base.extend(ClassMethods)
5
- base.class_eval do
6
- cattr_accessor :_s3_options
7
- end
8
- end
9
-
10
- def s3_connection
11
- @_s3_connection ||= RightAws::S3.new(AWS_CONFIG[:aws_access_key_id], AWS_CONFIG[:aws_secret_access_key], :multi_thread => true)
12
- end
13
-
14
- def s3_bucket(name)
15
- if !@_s3_bucket
16
- @_s3_bucket = s3_connection.bucket(_s3_options[name][:bucket])
17
- @_s3_bucket = s3_connection.bucket(_s3_options[name][:bucket], true, 'private') if @_s3_bucket.nil? # create it if it didn't exist, do not do it the first time as the ACL get modified
18
- end
19
- @_s3_bucket
20
- rescue Exception => e
21
- raise ArgumentError, "Could not access/create S3 bucket '#{name}': #{e} #{e.backtrace.join("\n")}"
22
- end
23
-
24
- def save
25
- if ret = super
26
- save_attachments
27
- end
28
- ret
29
- end
30
-
31
- def save_attachments
32
- if @_attachments
33
- @_attachments.each do |name, attachment|
34
- if attachment[:dirty]
35
- value = attachment[:value].is_a?(String) ? attachment[:value] : attachment[:value].to_json
36
- s3_bucket(name).put(s3_attachment_key(name), value, {}, _s3_options[name][:permissions])
37
- attachment[:dirty] = false
38
- end
39
- end
40
- end
41
- end
42
-
43
- def s3_attachment_key(name)
44
- "#{self.class.name.tableize}/#{name}/#{id}"
45
- end
46
-
47
- module ClassMethods
48
- def has_s3_attachment(name, options = {})
49
- name = name.to_sym
50
- raise ArgumentError, "No bucket name specified for attachment #{name}" if options[:bucket].blank?
51
- options.update(:permissions => 'private', :ssl => true)
52
- self._s3_options ||= {}
53
- self._s3_options[name] = options
54
-
55
- define_attachment_accessors(name)
56
- attr_reader :_attachments
57
- end
58
-
59
- def define_attachment_accessors(name)
60
- define_method(name) do
61
- unless @_attachments and @_attachments[name]
62
- @_attachments = {name => {}}
63
- @_attachments[name][:value] = s3_bucket(name).get(s3_attachment_key(name))
64
- end
65
- @_attachments[name][:value]
66
- end
67
-
68
- define_method("#{name}=") do |value|
69
- @_attachments ||= {}
70
- @_attachments[name] ||= {}
71
- @_attachments[name].update(:value => value, :dirty => true)
72
- value
73
- end
74
-
75
- define_method("#{name}_url") do
76
- if _s3_options[name][:permissions] == 'private'
77
- RightAws::S3Generator.new(AWS_CONFIG[:aws_access_key_id], AWS_CONFIG[:aws_secret_access_key], :multi_thread => true).bucket(_s3_options[name][:bucket]).get(s3_attachment_key(name), 5.minutes)
78
- else
79
- "http://#{_s3_options[name][:bucket].to_s}.s3.amazonaws.com/#{s3_attachment_key(name)}"
80
- end
81
- end
82
- end
83
- end
84
- end
85
- end
@@ -1,88 +0,0 @@
1
- module SimplyStored
2
- module SimpleDB
3
- module Validations
4
- def validate
5
- # abstract - implement in subclass and add checks that add to errors with add_error
6
- end
7
-
8
- def self.included(base)
9
- base.extend(ClassMethods)
10
- end
11
-
12
- module ClassMethods
13
- def require_attributes(*attributes)
14
- @_required_attributes ||= []
15
- attributes.each do |attr|
16
- @_required_attributes << attr.to_s
17
- end
18
- end
19
-
20
- def require_inclusion_of(attr, valid_set, options = {})
21
- options = {
22
- :allow_blank => false
23
- }.update(options)
24
- @_required_inclusions ||= {}
25
- @_required_inclusions[attr.to_s] = [valid_set, options]
26
- end
27
-
28
- def require_format_of(attr, valid_regex, options = {})
29
- options = {
30
- :allow_blank => false
31
- }.update(options)
32
- @_required_formats ||= {}
33
- @_required_formats[attr.to_s] = [valid_regex, options]
34
- end
35
- end
36
-
37
- def ensure_formats
38
- list_of_format_checks = self.class.instance_variable_get("@_required_formats") || {}
39
- list_of_format_checks.each do |attr, check_options|
40
- valid_regex, options = check_options
41
- add_error(attr, 'is of invalid format') unless valid_regex.match(self.send(attr)) || (self.send(attr).blank? && options[:allow_blank])
42
- end
43
- end
44
-
45
- def ensure_inclusions
46
- list_of_inclusion_checks = self.class.instance_variable_get("@_required_inclusions") || {}
47
- list_of_inclusion_checks.each do |attr, check_options|
48
- valid_set, options = check_options
49
- if self.send(attr) && self.send(attr).is_a?(Array)
50
- self.send(attr).all? do |item|
51
- add_error(attr, 'is not included in the valid set') unless (valid_set.include?(item) rescue false) || (self.send(attr).blank? && options[:allow_blank])
52
- end
53
- else
54
- add_error(attr, 'is not included in the valid set') unless (valid_set.include?(self.send(attr)) rescue false) || (self.send(attr).blank? && options[:allow_blank])
55
- end
56
- end
57
- end
58
-
59
- def add_error(attr, desc)
60
- errors << [attr, desc]
61
- end
62
-
63
- def clear_errors
64
- @errors = []
65
- end
66
-
67
- def ensure_no_foreign_attributes
68
- not_allowed_attributes = self.attributes.keys.sort - (self.class.instance_variable_get("@_defined_attributes") || [])
69
- not_allowed_attributes = not_allowed_attributes.delete_if{|attr| attr.to_s == 'id'} # the ID is an implicit attribute
70
- not_allowed_attributes.each do |attr|
71
- add_error(attr, 'is unknown and should not be set')
72
- end
73
- end
74
-
75
- def ensure_required_attributes_present
76
- list_of_required_attributes = self.class.instance_variable_get("@_required_attributes") || []
77
- list_of_required_attributes.all? do |attr|
78
- if self.send(attr).blank?
79
- add_error(attr, 'is missing')
80
- false
81
- else
82
- true
83
- end
84
- end
85
- end
86
- end
87
- end
88
- end
@@ -1,216 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../simply_stored')
2
-
3
- require 'sdb/right_sdb_interface'
4
- require 'sdb/active_sdb'
5
- require "simply_stored/simpledb/attributes"
6
- require "simply_stored/simpledb/associations"
7
- require "simply_stored/simpledb/validations"
8
-
9
- module SimplyStored
10
- class Simple < RightAws::ActiveSdb::Base
11
- def self.aws_access_key
12
- @_aws_access_key
13
- end
14
-
15
- def self.aws_secret_access_key
16
- @_aws_secret_access_key
17
- end
18
-
19
- def self.aws_access_key=(aws_access_key)
20
- @_aws_access_key = aws_access_key
21
- end
22
-
23
- def self.aws_secret_access_key=(aws_secret_access_key)
24
- @_aws_secret_access_key = aws_secret_access_key
25
- end
26
-
27
- include SimplyStored::SimpleDB::Associations
28
- include SimplyStored::SimpleDB::Attributes
29
- include SimplyStored::SimpleDB::Validations
30
- extend SimplyStored::Storage::ClassMethods
31
-
32
- alias :active_sdb_save :save
33
- alias :active_sdb_delete :delete
34
- alias :active_sdb_save_attributes :save_attributes
35
-
36
- def initialize(attrs={})
37
- attrs = _remove_protected_attributes(attrs) || {}
38
- super(attrs)
39
- end
40
-
41
- def save(run_validations = true)
42
- run_validations ? save_with_validations : save_without_validations
43
- end
44
-
45
- def reload
46
- super
47
- restore_partitioned_attributes
48
- self
49
- end
50
-
51
- def save_with_validations
52
- new_record = new_record? # save status as it changes during saving
53
- before_create if new_record && respond_to?(:before_create)
54
- before_save if respond_to?(:before_save)
55
- if valid?
56
- set_timestamps
57
- partition_string_attributes
58
- sdb_operation(:save)
59
- clear_errors
60
- after_create if new_record && respond_to?(:after_create)
61
- after_save if respond_to?(:after_save)
62
- true
63
- else
64
- false
65
- end
66
- end
67
-
68
- def save_without_validations
69
- new_record = new_record? # save status as it changes during saving
70
- before_create if new_record && respond_to?(:before_create)
71
- before_save if respond_to?(:before_save)
72
- set_timestamps
73
- sdb_operation(:save)
74
- clear_errors
75
- after_create if new_record && respond_to?(:after_create)
76
- after_save if respond_to?(:after_save)
77
- true
78
- end
79
-
80
- def delete
81
- before_delete if respond_to?(:before_delete)
82
- sdb_operation(:delete)
83
- after_delete if respond_to?(:after_delete)
84
- clear_dependents_after_delete
85
- nil
86
- end
87
-
88
- def valid?
89
- clear_errors
90
- before_validation if respond_to?(:before_validation)
91
- ensure_no_foreign_attributes
92
- ensure_required_attributes_present
93
- ensure_inclusions
94
- ensure_formats
95
- validate
96
- errors.empty?
97
- end
98
-
99
- def errors
100
- @errors ||= []
101
- end
102
-
103
- def self.domain
104
- unless @domain
105
- if defined? ActiveSupport::CoreExtensions::String::Inflections
106
- @domain = name.tableize.gsub('/','__').gsub('::','__')
107
- else
108
- @domain = name.downcase.gsub('/','__').gsub('::','__')
109
- end
110
- end
111
- @domain
112
- end
113
-
114
- def self.foreign_key
115
- self.name.underscore.gsub('/','__').gsub('::','__') + "_id"
116
- end
117
-
118
- def self.find(*args)
119
- retries = 0
120
- options = args.last.is_a?(Hash) ? args.pop : {}
121
- options.update(:auto_load => true)
122
- args << options
123
- begin
124
- super(*args)
125
- rescue Rightscale::AwsError => e
126
- if (Rightscale::AwsError.system_error?(e) or e.message.match(/^RequestThrottled/)) and retries < 2
127
- retries += 1
128
- sleep retries * 0.5
129
- retry
130
- else
131
- raise Error.new("Couldn't find item with #{args.inspect}: #{e}")
132
- end
133
- rescue RightAws::ActiveSdb::ActiveSdbError => e
134
- if e.message.match(/Couldn't find #{name} with ID/)
135
- if retries < 2
136
- retries += 1
137
- sleep retries * 0.5
138
- retry
139
- else
140
- raise RecordNotFound, e.message
141
- end
142
- else
143
- raise
144
- end
145
- end
146
- end
147
-
148
- def self.all(options = {})
149
- find(:all, options)
150
- end
151
-
152
- def self.first(options = {})
153
- find(:first, options)
154
- end
155
-
156
- def update_attributes(*args)
157
- # HACK in order to update attributes to nil
158
- # thank you ActiveSDB
159
- if (attrs = args.first).is_a?(Hash)
160
- attrs.each do |k,v|
161
- attrs[k] = [nil] if v.blank?
162
- end
163
- end
164
-
165
- sdb_operation(:save_attributes, *args)
166
- end
167
-
168
- def to_param
169
- id
170
- end
171
-
172
- # set several attrbiutes at once with a given hash
173
- # in contrast to ActiveSDB#attributes= it doesn't nil the other attributes
174
- def set_attributes(attrs)
175
- attrs = _remove_protected_attributes(attrs)
176
-
177
- attrs.each do |k,v|
178
- self[k] = v
179
- end
180
- end
181
-
182
- protected
183
-
184
- def self.generate_id
185
- UUIDTools::UUID.random_create().to_s
186
- end
187
-
188
- def sdb_operation(operation, *args)
189
- retries = 0
190
- begin
191
- send("active_sdb_#{operation}", *args)
192
- rescue Rightscale::AwsError => e
193
- if (Rightscale::AwsError.system_error?(e) or e.message.match(/^RequestThrottled/)) and retries < 2
194
- retries += 1
195
- sleep retries * 0.5
196
- retry
197
- else
198
- raise Error.new("Couldn't #{operation} item of type #{self.class.name}#{id.nil? ? "" : " (with id: #{id})"}: #{e} #{e.backtrace.join("\n")}")
199
- end
200
- end
201
- end
202
-
203
- def set_timestamps
204
- self.updated_at = Time.now.utc if self.respond_to?(:updated_at=)
205
- self.created_at = Time.now.utc if self.respond_to?(:created_at=) && self.new_record?
206
- end
207
-
208
- def self.get_class_from_name(klass_name)
209
- klass_name.to_s.gsub('__','/').classify.constantize
210
- end
211
-
212
- def self.formalize_class_name(name)
213
- name.to_s.gsub('__','/').gsub('__','::').classify
214
- end
215
- end
216
- end
@@ -1,11 +0,0 @@
1
- class Item < SimplyStored::Simple
2
- simpledb_string :foo_attribute, :item_daddy_id
3
- simpledb_array :bar_attribute_array
4
- simpledb_timestamp :updated_at, :created_at
5
- simpledb_integer :integer_field
6
-
7
- require_inclusion_of :foo_attribute, ['a', 'b', 'c']
8
- require_inclusion_of :bar_attribute_array, ['goog', 'boob']
9
-
10
- belongs_to :item_daddy
11
- end
@@ -1,8 +0,0 @@
1
- class ItemDaddy < SimplyStored::Simple
2
- simpledb_string :name, 'namespace__foo_id'
3
- require_attributes :name
4
-
5
- has_one :item
6
- has_many :items
7
-
8
- end
@@ -1,3 +0,0 @@
1
- class LogItem < SimplyStored::Simple
2
- has_s3_attachment :log_data, :bucket => "bucket-for-monsieur", :access_key => 'abcdef', :secret_access_key => 'secret!'
3
- end
@@ -1,5 +0,0 @@
1
- module Namespace
2
- class Bar < SimplyStored::Simple
3
- has_many :foos
4
- end
5
- end
@@ -1,7 +0,0 @@
1
- module Namespace
2
- class Foo < SimplyStored::Simple
3
- has_many :item_daddys
4
- belongs_to :namespace__bar
5
- simpledb_string :namespace__bar_id
6
- end
7
- end
@@ -1,3 +0,0 @@
1
- class ProtectedItem < SimplyStored::Simple
2
- simpledb_string :a, :b, :c
3
- end