jeremyboles-dm-adapter-simpledb 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
File without changes
@@ -0,0 +1,63 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+ require 'spec/rake/spectask'
4
+ require 'pathname'
5
+ require "rake/gempackagetask"
6
+
7
+ ROOT = Pathname(__FILE__).dirname.expand_path
8
+ require ROOT + 'lib/simpledb_adapter'
9
+
10
+ task :default => [ :spec ]
11
+
12
+ desc 'Run specifications'
13
+ Spec::Rake::SpecTask.new(:spec) do |t|
14
+ if File.exists?('spec/spec.opts')
15
+ t.spec_opts << '--options' << 'spec/spec.opts'
16
+ end
17
+ t.spec_files = Pathname.glob((ROOT + 'spec/**/*_spec.rb').to_s)
18
+
19
+ begin
20
+ t.rcov = ENV.has_key?('NO_RCOV') ? ENV['NO_RCOV'] != 'true' : true
21
+ t.rcov_opts << '--exclude' << 'spec'
22
+ t.rcov_opts << '--text-summary'
23
+ t.rcov_opts << '--sort' << 'coverage' << '--sort-reverse'
24
+ rescue Exception
25
+ # rcov not installed
26
+ end
27
+ end
28
+
29
+
30
+ spec = Gem::Specification.new do |s|
31
+ s.name = "dm-adapter-simpledb"
32
+ s.version = "0.9.3"
33
+ s.date = "2008-10-01"
34
+ s.summary = "A DatMapper adapter for SimpleDB"
35
+ s.email = "jeremy@jeremyboles.com"
36
+ s.homepage = "http://github.com/jeremyboles/dm-adapter-simpledb"
37
+ s.description = "A DataMapper adapter for Amazon's SimpleDB"
38
+ s.has_rdoc = true
39
+ s.authors = ["Jeremy Boles"]
40
+ s.files = ["lib/simpledb_adapter.rb",
41
+ "README",
42
+ "Rakefile",
43
+ "dm-adapter-simpledb.gemspec"]
44
+ s.test_files = ["spec/simpledb_adapter_spec.rb",
45
+ "spec.opts",
46
+ "spec_helper.rb"]
47
+ s.rdoc_options = ["--main", "README.txt"]
48
+ s.extra_rdoc_files = ["README.txt"]
49
+ s.add_dependency("rspec", ["> 0.0.0"])
50
+ s.add_dependency("dm-core", ["> 0.0.0"])
51
+ s.add_dependency("aws-sdb", ["> 0.0.0"])
52
+ end
53
+
54
+ Rake::GemPackageTask.new(spec) do |package|
55
+ package.gem_spec = spec
56
+ end
57
+
58
+ desc "Create a gemspec file"
59
+ task :gemspec do
60
+ File.open("dm-adapter-simpledb.gemspec", "w") do |file|
61
+ file.puts spec.to_ruby
62
+ end
63
+ end
@@ -0,0 +1,38 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = %q{dm-adapter-simpledb}
3
+ s.version = "0.9.3"
4
+
5
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
6
+ s.authors = ["Jeremy Boles"]
7
+ s.date = %q{2008-10-01}
8
+ s.description = %q{A DataMapper adapter for Amazon's SimpleDB}
9
+ s.email = %q{jeremy@jeremyboles.com}
10
+ s.extra_rdoc_files = ["README.txt"]
11
+ s.files = ["lib/simpledb_adapter.rb", "README", "Rakefile", "dm-adapter-simpledb.gemspec", "spec/simpledb_adapter_spec.rb", "spec.opts", "spec_helper.rb", "README.txt"]
12
+ s.has_rdoc = true
13
+ s.homepage = %q{http://github.com/jeremyboles/dm-adapter-simpledb}
14
+ s.rdoc_options = ["--main", "README.txt"]
15
+ s.require_paths = ["lib"]
16
+ s.rubygems_version = %q{1.2.0}
17
+ s.summary = %q{A DatMapper adapter for SimpleDB}
18
+ s.test_files = ["spec/simpledb_adapter_spec.rb", "spec.opts", "spec_helper.rb"]
19
+
20
+ if s.respond_to? :specification_version then
21
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
22
+ s.specification_version = 2
23
+
24
+ if current_version >= 3 then
25
+ s.add_runtime_dependency(%q<rspec>, ["> 0.0.0"])
26
+ s.add_runtime_dependency(%q<dm-core>, ["> 0.0.0"])
27
+ s.add_runtime_dependency(%q<aws-sdb>, ["> 0.0.0"])
28
+ else
29
+ s.add_dependency(%q<rspec>, ["> 0.0.0"])
30
+ s.add_dependency(%q<dm-core>, ["> 0.0.0"])
31
+ s.add_dependency(%q<aws-sdb>, ["> 0.0.0"])
32
+ end
33
+ else
34
+ s.add_dependency(%q<rspec>, ["> 0.0.0"])
35
+ s.add_dependency(%q<dm-core>, ["> 0.0.0"])
36
+ s.add_dependency(%q<aws-sdb>, ["> 0.0.0"])
37
+ end
38
+ end
@@ -0,0 +1,163 @@
1
+ require 'rubygems'
2
+ require 'dm-core'
3
+ require 'aws_sdb'
4
+ require 'digest/sha1'
5
+
6
+ module DataMapper
7
+ module Adapters
8
+ class SimpleDBAdapter < AbstractAdapter
9
+
10
+ def create(resources)
11
+ created = 0
12
+ resources.each do |resource|
13
+ simpledb_type = simpledb_type(resource.model)
14
+ attributes = resource.attributes.merge(:simpledb_type => simpledb_type)
15
+
16
+ item_name = "#{simpledb_type}+"
17
+ keys = resource.model.key(self.name).sort {|a,b| a.name.to_s <=> b.name.to_s}
18
+ item_name += keys.map do |property|
19
+ resource.instance_variable_get(property.instance_variable_name)
20
+ end.join('-')
21
+ item_name = Digest::SHA1.hexdigest(item_name)
22
+
23
+ sdb.put_attributes(domain, item_name, attributes)
24
+
25
+ created += 1
26
+ end
27
+ created
28
+ end
29
+
30
+ def delete(query)
31
+ deleted = 0
32
+ simpledb_type = simpledb_type(query.model)
33
+
34
+ item_name = "#{simpledb_type}+"
35
+ keys = query.model.key(self.name).sort {|a,b| a.name.to_s <=> b.name.to_s }
36
+ conditions = query.conditions.sort {|a,b| a[1].name.to_s <=> b[1].name.to_s }
37
+ item_name += conditions.map do |property|
38
+ property[2].to_s
39
+ end.join('-')
40
+ item_name = Digest::SHA1.hexdigest(item_name)
41
+
42
+ sdb.delete_attributes(domain, item_name)
43
+
44
+ deleted += 1
45
+
46
+ # Curosity check to make sure we are only dealing with a delete
47
+ conditions = conditions.map {|c| c[0] }.uniq
48
+ operators = [ :gt, :gte, :lt, :lte, :not, :like, :in ]
49
+ raise NotImplementedError.new('Only :eql on delete at the moment') if (operators - conditions).size != operators.size
50
+
51
+ deleted
52
+ end
53
+
54
+ def read_many(query)
55
+ simpledb_type = simpledb_type(query.model)
56
+
57
+ conditions = ["['simpledb_type' = '#{simpledb_type}']"]
58
+ if query.conditions.size > 0
59
+ conditions += query.conditions.map do |condition|
60
+ operator = case condition[0]
61
+ when :eql then '='
62
+ when :not then '!='
63
+ when :gt then '>'
64
+ when :gte then '>='
65
+ when :lt then '<'
66
+ when :lte then '<='
67
+ else raise "Invalid query operator: #{operator.inspect}"
68
+ end
69
+ "['#{condition[1].name.to_s}' #{operator} '#{condition[2].to_s}']"
70
+ end
71
+ end
72
+
73
+ results = sdb.query(domain, conditions.compact.join(' intersection '))
74
+ results = results[0].map {|d| sdb.get_attributes(domain, d) }
75
+
76
+ Collection.new(query) do |collection|
77
+ results.each do |result|
78
+ data = query.fields.map do |property|
79
+ value = result[property.field.to_s]
80
+ if value.size > 1
81
+ value.map {|v| property.typecast(v) }
82
+ else
83
+ property.typecast(value[0])
84
+ end
85
+ end
86
+ collection.load(data)
87
+ end
88
+ end
89
+ end
90
+
91
+ def read_one(query)
92
+ simpledb_type = simpledb_type(query.model)
93
+
94
+ item_name = "#{simpledb_type}+"
95
+ keys = query.model.key(self.name).sort {|a,b| a.name.to_s <=> b.name.to_s }
96
+ conditions = query.conditions.sort {|a,b| a[1].name.to_s <=> b[1].name.to_s }
97
+ item_name += conditions.map do |property|
98
+ property[2].to_s
99
+ end.join('-')
100
+ item_name = Digest::SHA1.hexdigest(item_name)
101
+
102
+ data = sdb.get_attributes(domain, item_name)
103
+ unless data.empty?
104
+ data = query.fields.map do |property|
105
+ value = data[property.field.to_s]
106
+ if value.size > 1
107
+ value.map {|v| property.typecast(v) }
108
+ else
109
+ property.typecast(value[0])
110
+ end
111
+ end
112
+
113
+ query.model.load(data, query)
114
+ end
115
+ end
116
+
117
+ def update(attributes, query)
118
+ updated = 0
119
+
120
+ simpledb_type = simpledb_type(query.model)
121
+
122
+ item_name = "#{simpledb_type}+"
123
+ keys = query.model.key(self.name).sort {|a,b| a.name.to_s <=> b.name.to_s }
124
+ conditions = query.conditions.sort {|a,b| a[1].name.to_s <=> b[1].name.to_s }
125
+ item_name += conditions.map do |property|
126
+ property[2].to_s
127
+ end.join('-')
128
+ item_name = Digest::SHA1.hexdigest(item_name)
129
+
130
+ attributes = attributes.to_a.map {|a| [a.first.name.to_s, a.last]}.to_hash
131
+ sdb.put_attributes(domain, item_name, attributes, true)
132
+
133
+ updated += 1
134
+
135
+ # Curosity check to make sure we are only dealing with a delete
136
+ conditions = conditions.map {|c| c[0] }.uniq
137
+ selectors = [ :gt, :gte, :lt, :lte, :not, :like, :in ]
138
+ raise NotImplementedError.new('Only :eql on delete at the moment') if (selectors - conditions).size != selectors.size
139
+
140
+ updated
141
+ end
142
+ private
143
+
144
+ def domain
145
+ @uri[:domain]
146
+ end
147
+
148
+ def sdb
149
+ @sdb ||= AwsSdb::Service.new(:access_key_id => @uri[:access_key], :secret_access_key => @uri [:secret_key])
150
+ @sdb
151
+ end
152
+
153
+ def simpledb_type(model)
154
+ model.storage_name(model.repository.name)
155
+ end
156
+
157
+ end # class SimpleDBAdapter
158
+
159
+ # Required naming scheme.
160
+ SimpledbAdapter = SimpleDBAdapter
161
+
162
+ end # module Adapters
163
+ end # module DataMapper
@@ -0,0 +1,131 @@
1
+ require 'pathname'
2
+ require Pathname(__FILE__).dirname.expand_path + 'spec_helper'
3
+
4
+ describe DataMapper::Adapters::SimpleDBAdapter do
5
+ before(:each) do
6
+ @person_attrs = { :id => "person-#{Time.now.to_f.to_s}", :name => 'Jeremy Boles', :age => 25,
7
+ :wealth => 25.00, :birthday => Date.today }
8
+ @person = Person.new(@person_attrs)
9
+ end
10
+
11
+ it 'should create a record' do
12
+ @person.save.should be_true
13
+ @person.id.should_not be_nil
14
+ @person.destroy
15
+ end
16
+
17
+ describe 'with a saved record' do
18
+ before(:each) { @person.save }
19
+ after(:each) { @person.destroy }
20
+
21
+ it 'should get a record' do
22
+ person = Person.get!(@person.id, @person.name)
23
+ person.should_not be_nil
24
+ person.wealth.should == @person.wealth
25
+ end
26
+
27
+ it 'should not get records of the wrong type by id' do
28
+ Company.get(@person.id, @person.name).should == nil
29
+ lambda { Company.get!(@person.id, @person.name) }.should raise_error(DataMapper::ObjectNotFoundError)
30
+ end
31
+
32
+ it 'should update a record' do
33
+ person = Person.get!(@person.id, @person.name)
34
+ person.wealth = 100.00
35
+ person.save
36
+
37
+ person = Person.get!(@person.id, @person.name)
38
+ person.wealth.should_not == @person.wealth
39
+ person.age.should == @person.age
40
+ person.id.should == @person.id
41
+ person.name.should == @person.name
42
+ end
43
+
44
+ it 'should destroy a record' do
45
+ @person.destroy.should be_true
46
+ end
47
+
48
+ end
49
+
50
+ describe 'with multiple records saved' do
51
+ before(:each) do
52
+ @jeremy = Person.create(@person_attrs.merge(:id => Time.now.to_f.to_s, :name => "Jeremy Boles", :age => 25))
53
+ @danielle = Person.create(@person_attrs.merge(:id => Time.now.to_f.to_s, :name => "Danille Boles", :age => 26))
54
+ @keegan = Person.create(@person_attrs.merge(:id => Time.now.to_f.to_s, :name => "Keegan Jones", :age => 20))
55
+ end
56
+
57
+ after(:each) do
58
+ @jeremy.destroy
59
+ @danielle.destroy
60
+ @keegan.destroy
61
+ end
62
+
63
+ it 'should get all records' do
64
+ Person.all.length.should == 3
65
+ end
66
+
67
+ it 'should get records by eql matcher' do
68
+ people = Person.all(:age => 25)
69
+ people.length.should == 1
70
+ end
71
+
72
+ it 'should get records by not matcher' do
73
+ people = Person.all(:age.not => 25)
74
+ people.length.should == 2
75
+ end
76
+
77
+ it 'should get records by gt matcher' do
78
+ people = Person.all(:age.gt => 25)
79
+ people.length.should == 1
80
+ end
81
+
82
+ it 'should get records by gte matcher' do
83
+ people = Person.all(:age.gte => 25)
84
+ people.length.should == 2
85
+ end
86
+
87
+ it 'should get records by lt matcher' do
88
+ people = Person.all(:age.lt => 25)
89
+ people.length.should == 1
90
+ end
91
+
92
+ it 'should get records by lte matcher' do
93
+ people = Person.all(:age.lte => 25)
94
+ people.length.should == 2
95
+ end
96
+
97
+ it 'should get records with multiple matchers' do
98
+ people = Person.all(:birthday => Date.today, :age.lte => 25)
99
+ people.length.should == 2
100
+ end
101
+
102
+ it 'should handle DateTime' do
103
+ pending 'Need to figure out how to coerce DateTime'
104
+ time = Time.now
105
+ @jeremy.created_at = time
106
+ @jeremy.save
107
+ person = Person.get!(@jeremy.id, @jeremy.name)
108
+ person.created_at.should == time
109
+ end
110
+
111
+ it 'should handle Date' do
112
+ person = Person.get!(@jeremy.id, @jeremy.name)
113
+ person.birthday.should == @jeremy.birthday
114
+ end
115
+
116
+ it 'should order records'
117
+ it 'should get records by the like matcher'
118
+ end
119
+
120
+
121
+ describe 'associations' do
122
+ it 'should work with belongs_to associations'
123
+ it 'should work with has n associations'
124
+ end
125
+
126
+ describe 'STI' do
127
+ it 'should override default type'
128
+ it 'should load descendents on parent.all'
129
+ it 'should raise an error if you have a column named couchdb_type'
130
+ end
131
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jeremyboles-dm-adapter-simpledb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.3
5
+ platform: ruby
6
+ authors:
7
+ - Jeremy Boles
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-10-01 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">"
21
+ - !ruby/object:Gem::Version
22
+ version: 0.0.0
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: dm-core
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">"
30
+ - !ruby/object:Gem::Version
31
+ version: 0.0.0
32
+ version:
33
+ - !ruby/object:Gem::Dependency
34
+ name: aws-sdb
35
+ version_requirement:
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.0.0
41
+ version:
42
+ description: A DataMapper adapter for Amazon's SimpleDB
43
+ email: jeremy@jeremyboles.com
44
+ executables: []
45
+
46
+ extensions: []
47
+
48
+ extra_rdoc_files:
49
+ - README.txt
50
+ files:
51
+ - lib/simpledb_adapter.rb
52
+ - README
53
+ - Rakefile
54
+ - dm-adapter-simpledb.gemspec
55
+ - spec/simpledb_adapter_spec.rb
56
+ - spec.opts
57
+ - spec_helper.rb
58
+ - README.txt
59
+ has_rdoc: true
60
+ homepage: http://github.com/jeremyboles/dm-adapter-simpledb
61
+ post_install_message:
62
+ rdoc_options:
63
+ - --main
64
+ - README.txt
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: "0"
72
+ version:
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ version:
79
+ requirements: []
80
+
81
+ rubyforge_project:
82
+ rubygems_version: 1.2.0
83
+ signing_key:
84
+ specification_version: 2
85
+ summary: A DatMapper adapter for SimpleDB
86
+ test_files:
87
+ - spec/simpledb_adapter_spec.rb
88
+ - spec.opts
89
+ - spec_helper.rb