simplydb 0.0.2 → 0.0.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/.document DELETED
@@ -1,5 +0,0 @@
1
- README.rdoc
2
- lib/**/*.rb
3
- bin/*
4
- features/**/*.feature
5
- LICENSE
data/LICENSE DELETED
@@ -1,20 +0,0 @@
1
- Copyright (c) 2010 JT Archie
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc DELETED
@@ -1,37 +0,0 @@
1
- = simplydb
2
-
3
- A minimal interface to Amazon SimpleDB that has separation of interfaces. From the low level HTTP request access to high level Ruby abstraction ORM.
4
-
5
- require 'rubygems'
6
- require 'simplydb'
7
-
8
- interface = SimplyDB::Interface.new({
9
- :access_key => ENV['AWS_ACCESS_KEY'],
10
- :secret_key => ENV['AWS_SECRET_KEY']
11
- })
12
-
13
- if interface.create_domain("MyDomain")
14
- interface.put_attributes('MyDomain', 'Item123', {'color'=>['red','brick','garnet']})
15
-
16
- attributes = interface.get_attributes('MyDomain', 'Item123')
17
- puts "Item123 = #{attributes.inspect}"
18
-
19
- items = interface.select("select color from MyDomain where color = 'brick'")
20
- puts "Items = #{items.inspect}"
21
-
22
- interface.delete_domain("MyDomain")
23
- end
24
-
25
- == Note on Patches/Pull Requests
26
-
27
- * Fork the project.
28
- * Make your feature addition or bug fix.
29
- * Add tests for it. This is important so I don't break it in a
30
- future version unintentionally.
31
- * Commit, do not mess with rakefile, version, or history.
32
- (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
33
- * Send me a pull request. Bonus points for topic branches.
34
-
35
- == Copyright
36
-
37
- Copyright (c) 2010 JT Archie. See LICENSE for details.
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.0.2
@@ -1,19 +0,0 @@
1
- $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
2
- require 'simplydb'
3
-
4
- interface = SimplyDB::Interface.new({
5
- :access_key => ENV['AWS_ACCESS_KEY'],
6
- :secret_key => ENV['AWS_SECRET_KEY']
7
- })
8
-
9
- if interface.create_domain("MyDomain")
10
- interface.put_attributes('MyDomain', 'Item123', {'color'=>['red','brick','garnet']})
11
-
12
- attributes = interface.get_attributes('MyDomain', 'Item123')
13
- puts "Item123 = #{attributes.inspect}"
14
-
15
- items = interface.select("select color from MyDomain where color = 'brick'")
16
- puts "Items = #{items.inspect}"
17
-
18
- interface.delete_domain("MyDomain")
19
- end
data/examples/record.rb DELETED
@@ -1,45 +0,0 @@
1
- $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
2
-
3
- require 'simplydb'
4
- require 'simplydb/record/base'
5
-
6
- SimplyDB::Record::Base.establish_connection({
7
- 'access_key' => ENV['AWS_ACCESS_KEY'],
8
- 'secret_key' => ENV['AWS_SECRET_KEY']
9
- })
10
-
11
- class MyDomain < SimplyDB::Record::Base; end
12
-
13
-
14
- puts "=== Domain info ==="
15
- puts "create domain: #{MyDomain.create_domain}"
16
- puts "domain name: #{MyDomain.domain_name}"
17
- puts "domain_exists?: #{MyDomain.domain_exists?}"
18
-
19
-
20
- puts "\n"
21
- puts "=== Record info ==="
22
-
23
- person = MyDomain.new(
24
- :name => 'Joe Smith',
25
- :age => 27
26
- )
27
-
28
- person[:age] = 29
29
-
30
- puts "person attributes: #{person.attribute_names.inspect}"
31
- puts "person attributes hash: #{person.attributes.inspect}"
32
-
33
- person.item_name = "person1"
34
- puts "save: #{person.save}"
35
- puts "id (item_name): #{person.item_name}"
36
-
37
- sleep 2 #let SimpleDB propogate data (not supporting consistant read, yet)
38
-
39
- found_person = MyDomain.find("person1")
40
- puts "found person attributes: #{found_person.attributes.inspect}"
41
-
42
- people = MyDomain.find_by_select('SELECT * FROM my_domain')
43
- puts "people: #{people.inspect}"
44
-
45
- MyDomain.delete_domain
@@ -1,35 +0,0 @@
1
- require 'typhoeus'
2
-
3
- module SimplyDB
4
- module Clients
5
- class Typhoeus
6
-
7
- attr_accessor :hydra, :options
8
-
9
- def initialize(options = {})
10
- @options = options
11
- @hydra = ::Typhoeus::Hydra.new
12
- end
13
-
14
- def request(options={}, force = true, &block)
15
- request = ::Typhoeus::Request.new(options[:url],
16
- :method => options[:method],
17
- :params => options[:params]
18
- )
19
-
20
- @hydra.queue(request)
21
-
22
- unless force
23
- request.on_complete {|response| block.call(response)}
24
- else
25
- @hydra.run
26
- block.call(request.response)
27
- end
28
- end
29
-
30
- def run!
31
- @hydra.run
32
- end
33
- end
34
- end
35
- end
@@ -1,21 +0,0 @@
1
- module SimplyDB
2
- module Extensions
3
- def underscore(camel_cased_word)
4
- camel_cased_word.to_s.gsub(/::/, '/').
5
- gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
6
- gsub(/([a-z\d])([A-Z])/,'\1_\2').
7
- tr("-", "_").
8
- downcase
9
- end
10
-
11
- def escape_value(string)
12
- string.gsub(/([^ a-zA-Z0-9_.-]+)/n) do
13
- '%' + $1.unpack('H2' * $1.size).join('%').upcase
14
- end.gsub(' ', '%20')
15
- end
16
-
17
- def escape_hash(params = {})
18
- return params.collect{|k,v| [k.to_s, v.to_s]}.sort.collect { |key, value| [escape_value(key), escape_value(value)].join('=') }.join('&')
19
- end
20
- end
21
- end
@@ -1,2 +0,0 @@
1
- require 'simplydb/record/base'
2
- #require 'simplydb/record/model'
@@ -1,282 +0,0 @@
1
- require 'simplydb/extensions'
2
- require 'uuidtools'
3
-
4
- module SimplyDB
5
- module Record
6
- class MissingItemName < RuntimeError; end
7
- class ItemNotFound < RuntimeError; end
8
- class MissingCredentials < RuntimeError; end
9
-
10
- class Base
11
- include SimplyDB::Extensions
12
-
13
- class << self
14
- include SimplyDB::Extensions
15
-
16
- # This setups up the parameters for the connection for SimpleDB.
17
- #
18
- # NOTE: connection settings default to parent's settings if not provided
19
- # ==== Parameters
20
- # +access_key+: AWS access key.
21
- # +secret_key+: AWS secret key.
22
- # +force+: Force the creation of the domain. (Not yet implemented)
23
- def establish_connection(options = {})
24
- unless options.empty?
25
- @connection = {
26
- :access_key => options[:aws_access_key] || options[:access_key] || ENV['AWS_ACCESS_KEY'] || ENV['ACCESS_KEY'],
27
- :secret_key => options[:aws_secret_key] || options[:secret_key] || ENV['AWS_SECRET_KEY'] || ENV['SECRET_KEY'],
28
- :force => options[:force] == true ? true : false
29
- }
30
- else
31
- @connection ||= superclass.connection
32
- end
33
-
34
- raise MissingCredentials, "Require AWS access key and secret key" if @connection[:access_key].nil? || @connection[:secret_key].nil?
35
- end
36
-
37
- # Returns the connection's paramters.
38
- attr_accessor :connection
39
-
40
- # access to the logger
41
- attr_accessor :logger
42
-
43
- # Returns the interface(+SimplyDB::Interface+) the model uses to communicate with SimpleDB.
44
- def interface
45
- @interface ||= (establish_connection; SimplyDB::Interface.new(@connection))
46
- end
47
-
48
- # Set the name of the domain to associate the record with. This should be set
49
- # to the name as it appears on SimpleDB.
50
- # ====Paremeters
51
- # +name+: The domain name the model will use when saving data to SimpleDB.
52
- def set_domain_name(name)
53
- @domain_name = name
54
- @domain_name ||= domain_name
55
- end
56
- alias_method :domain_name=, :set_domain_name
57
-
58
- # Return the domain name the model has been assigned. Default is the model
59
- # name underscored.
60
- #
61
- # Person.domain_name == "person"
62
- # MyDomain.domain_name == "my_domain"
63
- def domain_name; @domain_name ||= underscore(name); end
64
-
65
- # Creates the domain associated with the model based on the +domain_name+.
66
- def create_domain
67
- return interface.create_domain(domain_name)
68
- end
69
-
70
- # Deletes the domain associated with the model based on the +domain_name+.
71
- def delete_domain
72
- return interface.delete_domain(domain_name)
73
- end
74
-
75
- # Checks to see if the domain associated with the model exists.
76
- def domain_exists?
77
- interface.domain_metadata(domain_name)
78
- return true
79
- rescue SimplyDB::Error::NoSuchDomain => e
80
- return false
81
- end
82
-
83
- # Creates an object (or multiple objects) and saves it to the database, if validations pass.
84
- # The resulting object is returned whether the object was saved successfully to the database or not.
85
- #
86
- # The +attributes+ parameter can be either be a Hash or an Array of Hashes. These Hashes describe the
87
- # attributes on the objects that are to be created.
88
- #
89
- # ==== Examples
90
- # # Create a single new object
91
- # User.create(:first_name => 'Jamie')
92
- #
93
- # # Create an Array of new objects
94
- # User.create([{ :first_name => 'Jamie' }, { :first_name => 'Jeremy' }])
95
- #
96
- # # Create a single object and pass it into a block to set other attributes.
97
- # User.create(:first_name => 'Jamie') do |u|
98
- # u.is_admin = false
99
- # end
100
- #
101
- # # Creating an Array of new objects using a block, where the block is executed for each object:
102
- # User.create([{ :first_name => 'Jamie' }, { :first_name => 'Jeremy' }]) do |u|
103
- # u.is_admin = false
104
- # end
105
- def create(attributes = {}, &block)
106
- if attributes.is_a?(Array)
107
- attributes.collect { |attr| create(attr, &block) }
108
- else
109
- object = new(attributes)
110
- yield(object) if block_given?
111
- object.item_name ||= attributes.delete(:item_name) || UUIDTools::UUID.random_create #TODO: not depend on UUID
112
- object.save
113
- return object
114
- end
115
- end
116
-
117
- # Find operates with four different retrieval approaches:
118
- # * Find by id - This can either be a specific id ("1"), a list of ids ("1", "5", "6"), or an array of ids ([5, 6, 10]). If no record can be found for all of the listed ids, then +ItemNotFound+ will be raised.
119
- #
120
- # ==== Examples
121
- # # find by id
122
- # Person.find(1) # returns the object for ID = 1
123
- # Person.find(1, 2, 6) # returns an array for objects with IDs in (1, 2, 6)
124
- # Person.find([7, 17]) # returns an array for objects with IDs in (7, 17)
125
- # Person.find([1]) # returns an array for the object with ID = 1
126
- def find(item_names)
127
- if item_names.is_a?(Array)
128
- return item_names.collect {|item_name| find(item_name)}
129
- else
130
- attributes = interface.get_attributes(domain_name, item_names)
131
- unless attributes.empty?
132
- object = new(attributes)
133
- object.item_name = item_names
134
- object.instance_variable_set('@new_record', false)
135
- return object
136
- else
137
- raise SimplyDB::Record::ItemNotFound
138
- end
139
- end
140
- end
141
-
142
- # Executes a custom SELECT query against your domain and returns all the results. The results will
143
- # be returned as an array with columns requested encapsulated as attributes of the model you call
144
- # this method from. If you call <tt>Product.find_by_sql</tt> then the results will be returned in
145
- # a Product object with the attributes you specified in the SQL query.
146
- def find_by_select(statement = nil, consistant_read = false)
147
- return [] unless statement
148
- items = interface.select(statement, consistant_read)
149
- objects = items.collect {|item_name, attributes|
150
- object = new(attributes)
151
- object.item_name = item_name
152
- object.instance_variable_set('@new_record', false)
153
- object
154
- }
155
- return objects
156
- end
157
- end
158
-
159
- # New objects can be instantiated with attributes pass as a hash with teh key being the
160
- # column name and the value being column value.
161
- #
162
- # ==== Parameters
163
- # +attributes+: A hash of the attributes columns and their values.
164
- def initialize(attributes = nil)
165
- @attributes = {}
166
- @new_record = true
167
- @destroyed = false
168
- self.attributes = attributes unless attributes.nil?
169
- end
170
-
171
- # Returns true if the record has not been created yet.
172
- def new_record?
173
- return @new_record
174
- end
175
-
176
- # Returns the value of the attribute identified by <tt>attr_name</tt>.
177
- # (Alias for the protected read_attribute method).
178
- def [](attribute_name)
179
- return read_attribute(attribute_name)
180
- end
181
-
182
- # Updates the attribute identified by <tt>attr_name</tt> with the specified +value+.
183
- # (Alias for the protected write_attribute method).
184
- def []=(attribute_name, value)
185
- write_attribute(attribute_name, value)
186
- end
187
-
188
- # Returns a hash of all the attributes with their names as keys and the values of the attributes as values.
189
- def attributes
190
- attrs = {}
191
- attribute_names.each { |name| attrs[name] = read_attribute(name) }
192
- return attrs
193
- end
194
-
195
- # Allows you to set all the attributes at once by passing in a hash with keys
196
- # matching the attribute names (which again matches the column names).
197
- def attributes=(new_attributes)
198
- return if new_attributes.nil?
199
- new_attributes.each do |name, value|
200
- if respond_to?(:"#{name}=")
201
- send(:"#{name}=", value)
202
- else
203
- write_attribute(name, value)
204
- end
205
- end
206
- end
207
-
208
- # Checks that an attribute has been assigned a value.
209
- def has_attribute?(attribute_name)
210
- return @attributes.has_key?(attribute_name)
211
- end
212
-
213
- # Returns an array of names for the attributes available on this object sorted alphabetically.
214
- def attribute_names
215
- return @attributes.keys.sort
216
- end
217
-
218
- # Save the record to SimpleDB. Requires that an <tt>item_name</tt> has been set for the record.
219
- def save(replace = false)
220
- raise SimplyDB::Record::MissingItemName if item_name.nil? || item_name.empty?
221
- if interface.put_attributes(domain_name, item_name, attributes, {}, replace)
222
- @new_record = false
223
- return true
224
- end
225
- return false
226
- end
227
-
228
- # Freeze the attributes hash such they are still accessible, even on destroyed records.
229
- def freeze
230
- @attributes.freeze
231
- return self
232
- end
233
-
234
- # Returns +true+ if the attributes hash has been frozen.
235
- def frozen?
236
- @attributes.frozen?
237
- end
238
-
239
- # Deletes the record in the SimpleDB and freezes this instance to reflect that no changes should be made (since they can’t be persisted).
240
- def destroy
241
- unless new_record?
242
- interface.delete_attributes(domain_name, item_name)
243
- end
244
-
245
- @destroyed = true
246
- return freeze
247
- end
248
-
249
- def connection; return self.class.connection; end
250
- def interface; return self.class.interface; end
251
- def domain_name; return self.class.domain_name; end
252
- def logger; self.class.logger; end
253
-
254
- def method_missing(method, *args) #:nodoc:
255
- method = method.to_s
256
- case method
257
- when /=$/
258
- return write_attribute(method.sub(/\=$/,''), args[0])
259
- else
260
- return read_attribute(method) if has_attribute?(method)
261
- end
262
- raise NoMethodError.new("Could not find method #{method}", method, *args)
263
- end
264
-
265
- # The item name associated with the record. This is the SimpleDB item name.
266
- def item_name=(value)
267
- @item_name = value.to_s
268
- end
269
-
270
- attr_reader :item_name
271
-
272
- private
273
- def read_attribute(name) #:nodoc:
274
- return @attributes[name.to_s]
275
- end
276
-
277
- def write_attribute(name, value) #:nodoc:
278
- @attributes[name.to_s] = value.to_s
279
- end
280
- end
281
- end
282
- end