dyna_model 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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