dyna_model 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.
@@ -0,0 +1,28 @@
1
+ class User
2
+
3
+ include DynaModel::Document
4
+
5
+ string_attr :hashy
6
+ integer_attr :ranger, default_value: 2
7
+ string_attr :name, default_value: lambda { "dude" }
8
+ integer_attr :intous
9
+ boolean_attr :is_dude
10
+ datetime_attr :born
11
+ serialized_attr :cereal
12
+ timestamps
13
+
14
+ hash_key :hashy
15
+ range_key :ranger
16
+
17
+ set_shard_name "usery"
18
+
19
+ local_secondary_index :name
20
+ global_secondary_index(:name_index, { hash_key: :name, projection: [:name] })
21
+
22
+ read_provision 4
23
+ write_provision 4
24
+ guid_delimiter "!"
25
+
26
+ validates_presence_of :name
27
+
28
+ end
@@ -0,0 +1,33 @@
1
+ class Validez
2
+
3
+ include DynaModel::Document
4
+
5
+ string_attr :key
6
+ string_attr :ranger
7
+
8
+ string_attr :body
9
+ validates_presence_of :body
10
+
11
+ boolean_attr :bool_party, default_value: false
12
+ validates :bool_party, inclusion: { in: [true, false] }
13
+
14
+ integer_attr :inteater
15
+ validates :inteater, numericality: { greater_than: 1, less_than: 4 }
16
+
17
+ string_attr :superhero
18
+
19
+ validate :check_superhero, if: lambda { |v| v.inteater == 3 }
20
+
21
+ hash_key :key
22
+ range_key :ranger
23
+
24
+ read_provision 4
25
+ write_provision 4
26
+
27
+ def check_superhero
28
+ unless self.superhero == "batman"
29
+ self.errors.add(:superhero, 'should be batman')
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,54 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "DynaModel::Attributes" do
4
+
5
+ before do
6
+ User.create_table
7
+ @user = User.new
8
+ end
9
+
10
+ it 'should add attributes' do
11
+ @user.hashy.should be_nil
12
+ @user.is_dude.should be_nil
13
+ @user.born.should be_nil
14
+ end
15
+
16
+ it 'should read default attribute' do
17
+ @user.ranger.should == 2
18
+ @user.name.should == "dude"
19
+ end
20
+
21
+ it 'should read and write StringAttr' do
22
+ @user.hashy.should be_nil
23
+ @user.hashy = "hash"
24
+ @user.hashy.should == "hash"
25
+ end
26
+
27
+ it 'should read and write IntegerAttr' do
28
+ @user.intous.should be_nil
29
+ @user.intous = 1
30
+ @user.intous.should == 1
31
+ end
32
+
33
+ it 'should read and write BooleanAttr' do
34
+ @user.is_dude = true
35
+ @user.is_dude.should be_true
36
+ @user.is_dude = false
37
+ @user.is_dude.should be_false
38
+ end
39
+
40
+ it 'should read and write DateTimeAttr' do
41
+ birthday = 27.years.ago.to_date
42
+ @user.born = birthday
43
+ @user.born.should == birthday
44
+ end
45
+
46
+ it 'should read and write SerializedAttr' do
47
+ @user.cereal.should be_nil
48
+ @user.cereal = { hi: "yo" }
49
+ @user.cereal.should == { hi: "yo" }
50
+ @user.cereal = [1,2,"3"]
51
+ @user.cereal.should == [1,2,"3"]
52
+ end
53
+
54
+ end
@@ -0,0 +1,35 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "DynaModel Callbacks" do
4
+
5
+ before do
6
+ Callbacker.create_table
7
+ end
8
+
9
+ it 'should trigger create callbacks' do
10
+ callbacker = Callbacker.create(id: 123)
11
+ callbacker.persisted?.should be_true
12
+ callbacker.before_create_method_attr.should be_true
13
+ callbacker.before_create_block_attr.should be_true
14
+ callbacker.before_validation_on_create_method_attr.should be_false
15
+ end
16
+
17
+ it 'should trigger save callbacks' do
18
+ callbacker = Callbacker.create(id: 123)
19
+ callbacker.persisted?.should be_true
20
+ callbacker.before_save_counter.should == 1
21
+ callbacker.before_validation_on_create_method_attr = true
22
+ callbacker.touch!
23
+ callbacker.before_save_counter.should == 2
24
+ end
25
+
26
+ it 'should trigger update callbacks' do
27
+ callbacker = Callbacker.create(id: 123)
28
+ callbacker.persisted?.should be_true
29
+ callbacker.before_update_counter.should == 0
30
+ callbacker.before_validation_on_create_method_attr = true
31
+ callbacker.touch!
32
+ callbacker.before_update_counter.should == 1
33
+ end
34
+
35
+ end
@@ -0,0 +1,81 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "DynaModel::Persistence" do
4
+
5
+ before do
6
+ User.create_table
7
+ @user = User.new
8
+ @user_attrs = {
9
+ hashy: "hash",
10
+ ranger: 3,
11
+ name: "Kate",
12
+ intous: 100,
13
+ is_dude: false,
14
+ born: 28.year.ago.to_date,
15
+ cereal: { frosted: "mini wheats" }
16
+ }
17
+ end
18
+
19
+ it 'should save assigned attributes' do
20
+ @user_attrs.each_pair do |k,v|
21
+ @user.send("#{k}=", v)
22
+ end
23
+ @user.save.should be_true
24
+ User.read("hash", 3).attributes.each_pair do |k,v|
25
+ next if %w(created_at updated_at).include?(k)
26
+ @user_attrs[k.to_sym].should == v
27
+ end
28
+ end
29
+
30
+ it 'should save assigned attributes by mass assign' do
31
+ user = User.new(@user_attrs)
32
+ user.save.should be_true
33
+ User.read("hash", 3).attributes.each_pair do |k,v|
34
+ next if %w(created_at updated_at).include?(k)
35
+ @user_attrs[k.to_sym].should == v
36
+ end
37
+ end
38
+
39
+ it 'should update an attribute' do
40
+ user = User.new(@user_attrs)
41
+ user.save
42
+ user.intous = 101
43
+ user.save
44
+ User.read("hash", 3).intous.should == 101
45
+ user.name = "Katie"
46
+ user.save
47
+ User.read("hash", 3).name.should == "Katie"
48
+ user.cereal = @user_attrs[:cereal].merge(cheerios: "regular")
49
+ user.save
50
+ User.read("hash", 3).cereal.should == {
51
+ frosted: "mini wheats",
52
+ cheerios: "regular"
53
+ }
54
+ user.cereal_will_change!
55
+ user.cereal.merge!(cheerios: "honey nut")
56
+ user.save
57
+ User.read("hash", 3).cereal.should == {
58
+ frosted: "mini wheats",
59
+ cheerios: "honey nut"
60
+ }
61
+ end
62
+
63
+ it 'should update attributes by mass assign' do
64
+ user = User.new(@user_attrs)
65
+ user.save
66
+ user.update_attributes({name: "Katie", cereal: {granola: "with blueberries"}})
67
+ updated_user = User.read("hash", 3)
68
+ updated_user.name.should == "Katie"
69
+ updated_user.cereal.should == {granola: "with blueberries"}
70
+ end
71
+
72
+ it 'should destroy record' do
73
+ User.read("hash", 3).should be_nil
74
+ user = User.new(@user_attrs)
75
+ user.save
76
+ User.read("hash", 3).should_not be_nil
77
+ user.destroy.should be_true
78
+ User.read("hash", 3).should be_nil
79
+ end
80
+
81
+ end
@@ -0,0 +1,118 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "DynaModel::Query" do
4
+
5
+ before do
6
+ User.create_table
7
+ Cacher.create_table
8
+ @user_attrs = {
9
+ hashy: "Dunn",
10
+ ranger: 1,
11
+ name: "Kate",
12
+ born: 28.year.ago.to_date,
13
+ intous: 1
14
+ }
15
+
16
+ @user2_attrs = {
17
+ hashy: "Dunn",
18
+ ranger: 2,
19
+ name: "Cary",
20
+ born: 27.year.ago.to_date,
21
+ intous: 2
22
+ }
23
+ end
24
+
25
+ it 'should read_guid' do
26
+ User.read_guid("Dunn!1").should be_nil
27
+ @user = User.create(@user_attrs)
28
+ User.read_guid("Dunn!1").should_not be_nil
29
+ Cacher.read_guid("123").should be_nil
30
+ @cacher = Cacher.create(key: "123", body: "content")
31
+ Cacher.read_guid("123").should_not be_nil
32
+ end
33
+
34
+ it 'should read by hash and range values' do
35
+ User.read("Dunn", 1).should be_nil
36
+ @user = User.create(@user_attrs)
37
+ User.read("Dunn", 1).should_not be_nil
38
+ Cacher.read("123").should be_nil
39
+ @cacher = Cacher.create(key: "123", body: "content")
40
+ Cacher.read("123").should_not be_nil
41
+ end
42
+
43
+ it 'should read_range' do
44
+ @user = User.create(@user_attrs)
45
+ @user2 = User.create(@user2_attrs)
46
+ User.read_range("Dunn").length.should == 2
47
+ User.read_range("Dunn", order: :asc).first.name.should == "Kate"
48
+ end
49
+
50
+ it 'should read_range with :select' do
51
+ @user = User.create(@user_attrs)
52
+ @user2 = User.create(@user2_attrs)
53
+ user = User.read_range("Dunn", select: [:name]).first
54
+ user.name.should be_present
55
+ expect {
56
+ user.born
57
+ }.to raise_error
58
+ end
59
+
60
+ it 'should read_range with :limit' do
61
+ @user = User.create(@user_attrs)
62
+ @user2 = User.create(@user2_attrs)
63
+ User.read_range("Dunn").length.should == 2
64
+ User.read_range("Dunn", limit: 1).length.should == 1
65
+ end
66
+
67
+ it 'should read_range with local secondary range key' do
68
+ @user = User.create(@user_attrs)
69
+ @user2 = User.create(@user2_attrs)
70
+ users = User.read_range("Dunn", range: {:name.eq => "Cary"})
71
+ users.length.should == 1
72
+ users.first.name.should == "Cary"
73
+ end
74
+
75
+ it 'should read_range with :global_secondary_index' do
76
+ @user = User.create(@user_attrs)
77
+ @user2 = User.create(@user2_attrs)
78
+ users = User.read_range("Cary", global_secondary_index: :name_index)
79
+ users.length.should == 1
80
+ users.first.name.should == "Cary"
81
+ end
82
+
83
+ it 'should read_first' do
84
+ @user = User.create(@user_attrs)
85
+ User.read_first("Dunn", order: :asc).name.should == "Kate"
86
+ end
87
+
88
+ it 'should count_range' do
89
+ @user = User.create(@user_attrs)
90
+ @user2 = User.create(@user2_attrs)
91
+ User.count_range("Dunn").should == 2
92
+ end
93
+
94
+ it 'should read_multiple' do
95
+ @cacher1 = Cacher.create(key: "123", body: "content")
96
+ @cacher2 = Cacher.create(key: "234", body: "content1")
97
+ multi = Cacher.read_multiple([@cacher1.key, @cacher2.key])
98
+ multi[@cacher1.key].should_not be_nil
99
+ multi[@cacher2.key].should_not be_nil
100
+ @user = User.create(@user_attrs)
101
+ @user2 = User.create(@user2_attrs)
102
+ multi = User.read_multiple([{hash_value: @user.hashy, range_value: @user.ranger}, {hash_value: @user2.hashy, range_value: @user2.ranger}])
103
+ multi[@user.hashy].should_not be_nil
104
+ multi[@user.hashy][@user.ranger.to_s].should_not be_nil
105
+ multi[@user2.hashy].should_not be_nil
106
+ multi[@user2.hashy][@user2.ranger.to_s].should_not be_nil
107
+ end
108
+
109
+ it 'should scan' do
110
+ User.scan.length.should == 0
111
+ @user = User.create(@user_attrs)
112
+ @user2 = User.create(@user2_attrs)
113
+ User.scan.length.should == 2
114
+ User.scan(scan_filter: { :name.begins_with => "C" }).length.should == 1
115
+ User.scan(scan_filter: { :intous.between => 1..2 }).length.should == 2
116
+ end
117
+
118
+ end
@@ -0,0 +1,61 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "DynaModel Validations" do
4
+
5
+ before do
6
+ Validez.create_table
7
+ @valid_params = {
8
+ key: "key",
9
+ ranger: "ranger",
10
+ body: "so fine",
11
+ bool_party: true,
12
+ inteater: 2
13
+ }
14
+ end
15
+
16
+ it 'should create from valid params' do
17
+ validez = Validez.create(@valid_params)
18
+ validez.persisted?.should be_true
19
+ end
20
+
21
+ it 'should enforce hash_key presence' do
22
+ validez = Validez.create(@valid_params.merge(key: nil))
23
+ validez.persisted?.should be_false
24
+ validez.errors.messages[:key].should be_present
25
+ end
26
+
27
+ it 'should enforce range_key presence' do
28
+ validez = Validez.create(@valid_params.merge(ranger: nil))
29
+ validez.persisted?.should be_false
30
+ validez.errors.messages[:ranger].should be_present
31
+ end
32
+
33
+ it 'should enforce boolean presence' do
34
+ validez = Validez.create(@valid_params.merge(bool_party: nil))
35
+ validez.persisted?.should be_false
36
+ validez.errors.messages[:bool_party].should be_present
37
+ end
38
+
39
+ it 'should enforce integer numericality' do
40
+ validez = Validez.create(@valid_params.merge(inteater: 'asdf'))
41
+ validez.persisted?.should be_false
42
+ validez.errors.messages[:inteater].should be_present
43
+
44
+ validez = Validez.create(@valid_params.merge(inteater: 9))
45
+ validez.persisted?.should be_false
46
+ validez.errors.messages[:inteater].should be_present
47
+
48
+ validez = Validez.create(@valid_params.merge(inteater: 2))
49
+ validez.persisted?.should be_true
50
+ end
51
+
52
+ it 'should enforce validation via method' do
53
+ validez = Validez.create(@valid_params.merge(inteater: 3))
54
+ validez.persisted?.should be_false
55
+ validez.errors.messages[:superhero].should be_present
56
+
57
+ validez = Validez.create(@valid_params.merge(inteater: 3, superhero: "batman"))
58
+ validez.persisted?.should be_true
59
+ end
60
+
61
+ end
@@ -0,0 +1,58 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+
4
+ MODELS = File.join(File.dirname(__FILE__), "app/models")
5
+
6
+ require 'rspec'
7
+ require 'dyna_model'
8
+ require 'mocha'
9
+ require 'aws-sdk'
10
+
11
+ ENV['ACCESS_KEY'] ||= 'abcd'
12
+ ENV['SECRET_KEY'] ||= '1234'
13
+
14
+ aws_config = {
15
+ access_key_id: ENV['ACCESS_KEY'],
16
+ secret_access_key: ENV['SECRET_KEY'],
17
+ dynamo_db_endpoint: 'localhost',
18
+ dynamo_db_port: '4567',
19
+ use_ssl: false
20
+ }
21
+ AWS.config(aws_config)
22
+
23
+ DynaModel::configure do |config|
24
+ config.endpoint = 'localhost'
25
+ config.port = 4567
26
+ config.use_ssl = false
27
+ config.read_provision = 5
28
+ config.write_provision = 1
29
+ config.namespace = 'test-'
30
+ end
31
+
32
+ # Requires supporting files with custom matchers and macros, etc,
33
+ # in ./support/ and its subdirectories.
34
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
35
+
36
+ Dir[ File.join(MODELS, "*.rb") ].sort.each { |file| require file }
37
+
38
+ RSpec.configure do |config|
39
+ config.mock_with(:mocha)
40
+
41
+ config.before(:each) do
42
+ client = AWS::DynamoDB::Client.new(aws_config.merge(api_version: '2012-08-10'))
43
+ client.list_tables[:table_names].each do |table|
44
+ if table =~ /^#{DynaModel::Config.namespace}/
45
+ client.delete_table(table_name: table)
46
+ end
47
+ end
48
+ end
49
+
50
+ config.after(:suite) do
51
+ client = AWS::DynamoDB::Client.new(aws_config.merge(api_version: '2012-08-10'))
52
+ client.list_tables[:table_names].each do |table|
53
+ if table =~ /^#{DynaModel::Config.namespace}/
54
+ client.delete_table(table_name: table)
55
+ end
56
+ end
57
+ end
58
+ end
metadata ADDED
@@ -0,0 +1,197 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dyna_model
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Cary Dunn
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: mocha
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: activesupport
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 4.0.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 4.0.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: activemodel
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: 4.0.0
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: 4.0.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: rails
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: 4.0.0
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: 4.0.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: aws-sdk
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: 1.38.0
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: 1.38.0
125
+ description: DyanmoDB ORM on AWS::Record
126
+ email:
127
+ - cary.dunn@gmail.com
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - ".gitignore"
133
+ - Gemfile
134
+ - LICENSE.txt
135
+ - README.md
136
+ - Rakefile
137
+ - dyna_model.gemspec
138
+ - lib/dyna_model.rb
139
+ - lib/dyna_model/attributes.rb
140
+ - lib/dyna_model/aws/record/attributes/serialized_attr.rb
141
+ - lib/dyna_model/config.rb
142
+ - lib/dyna_model/config/options.rb
143
+ - lib/dyna_model/document.rb
144
+ - lib/dyna_model/extensions/symbol.rb
145
+ - lib/dyna_model/persistence.rb
146
+ - lib/dyna_model/query.rb
147
+ - lib/dyna_model/response.rb
148
+ - lib/dyna_model/schema.rb
149
+ - lib/dyna_model/table.rb
150
+ - lib/dyna_model/tasks.rb
151
+ - lib/dyna_model/validations.rb
152
+ - lib/dyna_model/version.rb
153
+ - spec/app/models/cacher.rb
154
+ - spec/app/models/callbacker.rb
155
+ - spec/app/models/user.rb
156
+ - spec/app/models/validez.rb
157
+ - spec/dyna_model/attributes_spec.rb
158
+ - spec/dyna_model/callbacks_spec.rb
159
+ - spec/dyna_model/persistence_spec.rb
160
+ - spec/dyna_model/query_spec.rb
161
+ - spec/dyna_model/validations_spec.rb
162
+ - spec/spec_helper.rb
163
+ homepage: ''
164
+ licenses:
165
+ - MIT
166
+ metadata: {}
167
+ post_install_message:
168
+ rdoc_options: []
169
+ require_paths:
170
+ - lib
171
+ required_ruby_version: !ruby/object:Gem::Requirement
172
+ requirements:
173
+ - - ">="
174
+ - !ruby/object:Gem::Version
175
+ version: '0'
176
+ required_rubygems_version: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ requirements: []
182
+ rubyforge_project:
183
+ rubygems_version: 2.2.2
184
+ signing_key:
185
+ specification_version: 4
186
+ summary: DyanmoDB ORM on AWS::Record
187
+ test_files:
188
+ - spec/app/models/cacher.rb
189
+ - spec/app/models/callbacker.rb
190
+ - spec/app/models/user.rb
191
+ - spec/app/models/validez.rb
192
+ - spec/dyna_model/attributes_spec.rb
193
+ - spec/dyna_model/callbacks_spec.rb
194
+ - spec/dyna_model/persistence_spec.rb
195
+ - spec/dyna_model/query_spec.rb
196
+ - spec/dyna_model/validations_spec.rb
197
+ - spec/spec_helper.rb