jeremyboles-dm-adapter-simpledb 0.9.3

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.
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