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/.gitignore +5 -21
- data/Gemfile +4 -0
- data/README.md +37 -0
- data/Rakefile +10 -50
- data/lib/simplydb.rb +2 -3
- data/lib/simplydb/client.rb +71 -58
- data/lib/simplydb/error.rb +62 -57
- data/lib/simplydb/interface.rb +36 -54
- data/lib/simplydb/server.rb +74 -0
- data/lib/simplydb/version.rb +3 -0
- data/simplydb.gemspec +25 -77
- data/spec/client_spec.rb +17 -5
- data/spec/error_spec.rb +15 -5
- data/spec/fixtures/vcr/create_env.yml +313 -0
- data/spec/fixtures/vcr/delete_domains.yml +119 -0
- data/spec/fixtures/vcr/delete_items.yml +81 -0
- data/spec/fixtures/vcr/delete_items_all.yml +79 -0
- data/spec/fixtures/vcr/destroy_env.yml +197 -0
- data/spec/fixtures/vcr/get_all_items.yml +43 -0
- data/spec/fixtures/vcr/get_domains.yml +41 -0
- data/spec/fixtures/vcr/get_items.yml +42 -0
- data/spec/fixtures/vcr/put_domains.yml +119 -0
- data/spec/fixtures/vcr/put_items.yml +81 -0
- data/spec/fixtures/vcr/show_domains.yml +42 -0
- data/spec/interface_spec.rb +75 -92
- data/spec/server_spec.rb +236 -0
- data/spec/spec_helper.rb +19 -11
- data/spec/support/vcr.rb +7 -0
- metadata +131 -56
- data/.document +0 -5
- data/LICENSE +0 -20
- data/README.rdoc +0 -37
- data/VERSION +0 -1
- data/examples/interface.rb +0 -19
- data/examples/record.rb +0 -45
- data/lib/simplydb/clients/typhoeus.rb +0 -35
- data/lib/simplydb/extensions.rb +0 -21
- data/lib/simplydb/record.rb +0 -2
- data/lib/simplydb/record/base.rb +0 -282
- data/spec/extensions_spec.rb +0 -15
- data/spec/record/base_spec.rb +0 -214
- data/spec/spec.opts +0 -2
data/.document
DELETED
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
|
data/examples/interface.rb
DELETED
@@ -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
|
data/lib/simplydb/extensions.rb
DELETED
@@ -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
|
data/lib/simplydb/record.rb
DELETED
data/lib/simplydb/record/base.rb
DELETED
@@ -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
|