Class: SimpleRecord::ActiveSdb::Base

Inherits:
Object
  • Object
show all
Extended by:
ActiveSdbConnect
Defined in:
lib/simple_record/active_sdb.rb

Direct Known Subclasses

Base

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ActiveSdbConnect

close_connection, establish_connection

Constructor Details

#initialize(attrs = {}) ⇒ Base

Create new Item instance. attrs is a hash: { attribute1 => values1, …, attributeN => valuesN }.

item = Client.new('name' => 'Jon', 'toys' => ['girls', 'beer', 'pub'])
puts item.inspect   #=> #<Client:0xb77a2698 @new_record=true, @attributes={"name"=>["Jon"], "toys"=>["girls", "beer", "pub"]}>
item.save           #=> {"name"=>["Jon"], "id"=>"c03edb7e-e45c-11dc-bede-001bfc466dd7", "toys"=>["girls", "beer", "pub"]}
puts item.inspect   #=> #<Client:0xb77a2698 @new_record=false, @attributes={"name"=>["Jon"], "id"=>"c03edb7e-e45c-11dc-bede-001bfc466dd7", "toys"=>["girls", "beer", "pub"]}>


678
679
680
681
# File 'lib/simple_record/active_sdb.rb', line 678

def initialize(attrs={})
  @attributes = uniq_values(attrs)
  @new_record = true
end

Class Attribute Details

.next_tokenObject

next_token value returned by last find: is useful to continue finding



168
169
170
# File 'lib/simple_record/active_sdb.rb', line 168

def next_token
  @next_token
end

Instance Attribute Details

#attributesObject

Returns a hash of all the attributes.

puts item.attributes.inspect #=> {"name"=>["Cat"], "id"=>"2937601a-e45d-11dc-a75f-001bfc466dd7", "toys"=>["Jons socks", "clew", "mice"]}


665
666
667
# File 'lib/simple_record/active_sdb.rb', line 665

def attributes
  @attributes
end

#idObject

Returns an item id. Same as: item or item.attributes



668
669
670
# File 'lib/simple_record/active_sdb.rb', line 668

def id
  @id
end

Class Method Details

.connectionObject

Returns a Aws::SdbInterface object

class A < Aws::ActiveSdb::Base
end

class B < Aws::ActiveSdb::Base
end

class C < Aws::ActiveSdb::Base
end

Aws::ActiveSdb.establish_connection 'key_id_1', 'secret_key_1'

C.establish_connection 'key_id_2', 'secret_key_2'

# A and B uses the default connection, C - uses its own
puts A.connection  #=> #<Aws::SdbInterface:0xb76d6d7c>
puts B.connection  #=> #<Aws::SdbInterface:0xb76d6d7c>
puts C.connection  #=> #<Aws::SdbInterface:0xb76d6ca0>


190
191
192
# File 'lib/simple_record/active_sdb.rb', line 190

def connection
  @connection || ActiveSdb::connection
end

.create(attributes = {}) ⇒ Object

Create and save new Item instance. Attributes is a hash: { attribute1 => values1, …, attributeN => valuesN }.

item = Client.create('name' => 'Cat', 'toys' => ['Jons socks', 'mice', 'clew'])
puts item.inspect   #=> #<Client:0xb77a0a78 @new_record=false, @attributes={"name"=>["Cat"], "id"=>"2937601a-e45d-11dc-a75f-001bfc466dd7", "toys"=>["Jons socks", "mice", "clew"]}>


694
695
696
697
698
# File 'lib/simple_record/active_sdb.rb', line 694

def self.create(attributes={})
  item = self.new(attributes)
  item.save
  item
end

.create_domain(dom = nil) ⇒ Object

Create domain at SDB. Raises no errors if the domain already exists.

class Client < Aws::ActiveSdb::Base
end
Client.create_domain  #=> {:request_id=>"6fc652a0-0000-41d5-91f4-3ed390a3d3b2", :box_usage=>"0.0055590278"}


243
244
245
246
247
# File 'lib/simple_record/active_sdb.rb', line 243

def create_domain(dom=nil)
  dom = domain if dom.nil?
  puts "Creating new SimpleDB Domain: " + dom
  connection.create_domain(dom)
end

.delete_domain(dom = nil) ⇒ Object

Remove domain from SDB. Raises no errors if the domain does not exist.

class Client < Aws::ActiveSdb::Base
end
Client.delete_domain  #=> {:request_id=>"e14d90d3-0000-4898-9995-0de28cdda270", :box_usage=>"0.0055590278"}


256
257
258
259
260
# File 'lib/simple_record/active_sdb.rb', line 256

def delete_domain(dom=nil)
  dom = domain if dom.nil?
  puts "!!! DELETING SimpleDB Domain: " + dom
  connection.delete_domain(dom)
end

.domainObject

Current domain name.

# if 'ActiveSupport' is not loaded then class name converted to downcase
class Client < Aws::ActiveSdb::Base
end
puts Client.domain  #=> 'client'

# if 'ActiveSupport' is loaded then class name being tableized
require 'activesupport'
class Client < Aws::ActiveSdb::Base
end
puts Client.domain  #=> 'clients'

# Explicit domain name definition
class Client < Aws::ActiveSdb::Base
  set_domain_name :foreign_clients
end
puts Client.domain  #=> 'foreign_clients'


215
216
217
218
219
220
221
222
223
224
# File 'lib/simple_record/active_sdb.rb', line 215

def domain
  unless @domain
    if defined? ActiveSupport::CoreExtensions::String::Inflections
      @domain = name.tableize
    else
      @domain = name.downcase
    end
  end
  @domain
end

.find(*args) ⇒ Object

See select(), original find with QUERY syntax is deprecated so now find and select are synonyms.



265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
# File 'lib/simple_record/active_sdb.rb', line 265

def find(*args)
  options = args.last.is_a?(Hash) ? args.pop : {}
  case args.first
    when nil then
      raise "Invalid parameters passed to find: nil."
    when :all then
      sql_select(options)[:items]
    when :first then
      sql_select(options.merge(:limit => 1))[:items].first
    when :count then
      res = sql_select(options.merge(:count => true))[:count]
      res
    else
      res = select_from_ids(args, options)
      return res[:single] if res[:single]
      return res[:items]
  end
end

.find_with_metadata(*args) ⇒ Object

Same as find, but will return SimpleDB metadata like :request_id and :box_usage



287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/simple_record/active_sdb.rb', line 287

def (*args)
  options = args.last.is_a?(Hash) ? args.pop : {}
  case args.first
    when nil then
      raise "Invalid parameters passed to find: nil."
    when :all then
      sql_select(options)
    when :first then
      sql_select(options.merge(:limit => 1))
    when :count then
      res = sql_select(options.merge(:count => true))
      res
    else
      select_from_ids args, options
  end
end

.generate_idObject

:nodoc:



357
358
359
# File 'lib/simple_record/active_sdb.rb', line 357

def generate_id # :nodoc:
  UUIDTools::UUID.timestamp_create().to_s
end

.select(*args) ⇒ Object

Perform a SQL-like select request.

Single record:

Client.select(:first)
Client.select(:first, :conditions=> [ "name=? AND wife=?", "Jon", "Sandy"])
Client.select(:first, :conditions=> { :name=>"Jon", :wife=>"Sandy" }, :select => :girfriends)

Bunch of records:

Client.select(:all)
Client.select(:all, :limit => 10)
Client.select(:all, :conditions=> [ "name=? AND 'girlfriend'=?", "Jon", "Judy"])
Client.select(:all, :conditions=> { :name=>"Sandy" }, :limit => 3)

Records by ids:

Client.select('1')
Client.select('1234987b4583475347523948')
Client.select('1','2','3','4', :conditions=> ["toys=?", "beer"])

Find helpers: Aws::ActiveSdb::Base.select_by_… and Aws::ActiveSdb::Base.select_all_by_…

Client.select_by_name('Matias Rust')
Client.select_by_name_and_city('Putin','Moscow')
Client.select_by_name_and_city_and_post('Medvedev','Moscow','president')

Client.select_all_by_author('G.Bush jr')
Client.select_all_by_age_and_gender_and_ethnicity('34','male','russian')
Client.select_all_by_gender_and_country('male', 'Russia', :order => 'name')

Continue listing:

# initial listing
Client.select(:all, :limit => 10)
# continue listing
begin
  Client.select(:all, :limit => 10, :next_token => Client.next_token)
end while Client.next_token

Sort oder:
If :order=>'attribute' option is specified then result response (ordered by 'attribute') will contain only items where attribute is defined (is not null).

  Client.select(:all)                         # returns all records
  Client.select(:all, :order => 'gender')     # returns all records ordered by gender where gender attribute exists
  Client.select(:all, :order => 'name desc')  # returns all records ordered by name in desc order where name attribute exists

see docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/index.html?UsingSelect.html



353
354
355
# File 'lib/simple_record/active_sdb.rb', line 353

def select(*args)
  find(*args)
end

.set_domain_name(domain) ⇒ Object

Change the default domain name to user defined.

class Client < Aws::ActiveSdb::Base
  set_domain_name :foreign_clients
end


232
233
234
# File 'lib/simple_record/active_sdb.rb', line 232

def set_domain_name(domain)
  @domain = domain.to_s
end

Instance Method Details

#[](attribute) ⇒ Object

Returns the values of the attribute identified by attribute.

puts item['Cat'].inspect  #=> ["Jons socks", "clew", "mice"]


749
750
751
# File 'lib/simple_record/active_sdb.rb', line 749

def [](attribute)
  @attributes[attribute.to_s]
end

#[]=(attribute, values) ⇒ Object

Updates the attribute identified by attribute with the specified values.

puts item['Cat'].inspect  #=> ["Jons socks", "clew", "mice"]
item['Cat'] = ["Whiskas", "chicken"]
puts item['Cat'].inspect  #=> ["Whiskas", "chicken"]


759
760
761
762
763
# File 'lib/simple_record/active_sdb.rb', line 759

def []=(attribute, values)
  attribute = attribute.to_s
  @attributes[attribute] = attribute == 'id' ? values.to_s : values.is_a?(Array) ? values.uniq : [values]

end

#apres_save2Object



907
908
909
# File 'lib/simple_record/active_sdb.rb', line 907

def apres_save2
  mark_as_old
end

#connectionObject



736
737
738
# File 'lib/simple_record/active_sdb.rb', line 736

def connection
  self.class.connection
end

#delete(options = {}) ⇒ Object

Delete the Item entirely from SDB.

sandy = Client.find_by_name 'Sandy'
sandy.reload
sandy.inspect       #=> #<Client:0xb7761d28 @new_record=false, @attributes={"name"=>["Sandy"], "id"=>"b2832ce2-e461-11dc-b13c-001bfc466dd7", "toys"=>["boys", "kids", "patchwork"}>
puts sandy.delete
sandy.reload
puts sandy.inspect  #=> #<Client:0xb7761d28 @attributes={}, @new_record=false>


990
991
992
993
# File 'lib/simple_record/active_sdb.rb', line 990

def delete(options={})
  raise_on_id_absence
  connection.delete_attributes(options[:domain] || domain, id)
end

#delete_attributes(*attrs_list) ⇒ Object

Removes specified attributes from the item. attrs_list is an array or comma separated list of attributes names. Returns the list of deleted attributes.

sandy = Client.find_by_name 'Sandy'
sandy.reload
puts sandy.inspect                   #=> #<Client:0xb7761d28 @new_record=false, @attributes={"name"=>["Sandy"], "id"=>"b2832ce2-e461-11dc-b13c-001bfc466dd7", "toys"=>["boys", "kids", "patchwork"}>
puts sandy.delete_attributes('toys') #=> ['toys']
puts sandy.inspect                   #=> #<Client:0xb7761d28 @new_record=false, @attributes={"name"=>["Sandy"], "id"=>"b2832ce2-e461-11dc-b13c-001bfc466dd7"}>


970
971
972
973
974
975
976
977
978
979
# File 'lib/simple_record/active_sdb.rb', line 970

def delete_attributes(*attrs_list)
  raise_on_id_absence
  attrs_list = attrs_list.flatten.map { |attribute| attribute.to_s }
  attrs_list.delete('id')
  unless attrs_list.blank?
    connection.delete_attributes(domain, id, attrs_list)
    attrs_list.each { |attribute| @attributes.delete(attribute) }
  end
  attrs_list
end

#delete_values(attrs) ⇒ Object

Remove specified values from corresponding attributes. attrs is a hash: { attribute1 => values1, …, attributeN => valuesN }.

sandy = Client.find_by_name 'Sandy'
sandy.reload
puts sandy.inspect                                #=> #<Client:0xb77b48fc @new_record=false, @attributes={"name"=>["Sandy"], "id"=>"b2832ce2-e461-11dc-b13c-001bfc466dd7", "toys"=>["boys", "kids", "patchwork"]}>
puts sandy.delete_values('toys' => 'patchwork')   #=> { 'toys' => ['patchwork'] }
puts sandy.inspect                                #=> #<Client:0xb77b48fc @new_record=false, @attributes={"name"=>["Sandy"], "id"=>"b2832ce2-e461-11dc-b13c-001bfc466dd7", "toys"=>["boys", "kids"]}>


941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
# File 'lib/simple_record/active_sdb.rb', line 941

def delete_values(attrs)
  raise_on_id_absence
  attrs = uniq_values(attrs)
  attrs.delete('id')
  unless attrs.blank?
    connection.delete_attributes(domain, id, attrs)
    attrs.each do |attribute, values|
      # remove the values from the attribute
      if @attributes[attribute]
        @attributes[attribute] -= values
      else
        # if the attribute is unknown remove it from a resulting list of fixed attributes
        attrs.delete(attribute)
      end
    end
  end
  attrs
end

#domainObject

Item domain name.



741
742
743
# File 'lib/simple_record/active_sdb.rb', line 741

def domain
  self.class.domain
end

#initialize_from_db(attrs = {}) ⇒ Object

This is to separate initialization from user vs coming from db (ie: find())



684
685
686
# File 'lib/simple_record/active_sdb.rb', line 684

def initialize_from_db(attrs={})
  initialize(attrs)
end

#mark_as_oldObject

:nodoc:



1000
1001
1002
# File 'lib/simple_record/active_sdb.rb', line 1000

def mark_as_old # :nodoc:
  @new_record = false
end

#new_record?Boolean

Returns true if this object hasn�t been saved yet.

Returns:

  • (Boolean)


996
997
998
# File 'lib/simple_record/active_sdb.rb', line 996

def new_record?
  @new_record
end

#pre_save2Object



902
903
904
905
# File 'lib/simple_record/active_sdb.rb', line 902

def pre_save2
  @attributes = uniq_values(@attributes)
  prepare_for_update
end

#putObject

Stores in-memory attributes to SDB. Adds the attributes values to already stored at SDB. Returns a hash of stored attributes.

sandy = Client.new(:name => 'Sandy') #=> #<Client:0xb775a7a8 @attributes={"name"=>["Sandy"]}, @new_record=true>
sandy['toys'] = 'boys'
sandy.put
sandy['toys'] = 'patchwork'
sandy.put
sandy['toys'] = 'kids'
sandy.put
puts sandy.attributes.inspect        #=> {"name"=>["Sandy"], "id"=>"b2832ce2-e461-11dc-b13c-001bfc466dd7", "toys"=>["kids"]}
sandy.reload                         #=> {"name"=>["Sandy"], "id"=>"b2832ce2-e461-11dc-b13c-001bfc466dd7", "toys"=>["boys", "kids", "patchwork"]}

compare to save method



826
827
828
829
830
831
832
833
834
835
# File 'lib/simple_record/active_sdb.rb', line 826

def put
  @attributes = uniq_values(@attributes)
  prepare_for_update
  attrs = @attributes.dup
  attrs.delete('id')
  connection.put_attributes(domain, id, attrs) unless attrs.blank?
  connection.put_attributes(domain, id, {'id' => id}, :replace)
  mark_as_old
  @attributes
end

#put_attributes(attrs) ⇒ Object

Stores specified attributes. attrs is a hash: { attribute1 => values1, …, attributeN => valuesN }. Returns a hash of saved attributes.

see to put method



842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
# File 'lib/simple_record/active_sdb.rb', line 842

def put_attributes(attrs)
  attrs = uniq_values(attrs)
  prepare_for_update
    # if 'id' is present in attrs hash:
    # replace internal 'id' attribute and remove it from the attributes to be sent
  @attributes['id'] = attrs['id'] unless attrs['id'].blank?
  attrs.delete('id')
    # add new values to all attributes from list
  connection.put_attributes(domain, id, attrs) unless attrs.blank?
  connection.put_attributes(domain, id, {'id' => id}, :replace)
  attrs.each do |attribute, values|
    @attributes[attribute] ||= []
    @attributes[attribute] += values
    @attributes[attribute].uniq!
  end
  mark_as_old
  attributes
end

#reloadObject

Reload attributes from SDB. Replaces in-memory attributes.

item = Client.find_by_name('Cat')  #=> #<Client:0xb77d0d40 @attributes={"id"=>"2937601a-e45d-11dc-a75f-001bfc466dd7"}, @new_record=false>
item.reload                        #=> #<Client:0xb77d0d40 @attributes={"id"=>"2937601a-e45d-11dc-a75f-001bfc466dd7", "name"=>["Cat"], "toys"=>["Jons socks", "clew", "mice"]}, @new_record=false>


770
771
772
773
774
775
776
777
778
779
780
781
# File 'lib/simple_record/active_sdb.rb', line 770

def reload
  raise_on_id_absence
  old_id = id
  attrs = connection.get_attributes(domain, id)[:attributes]
  @attributes = {}
  unless attrs.blank?
    attrs.each { |attribute, values| @attributes[attribute] = values }
    @attributes['id'] = old_id
  end
  mark_as_old
  @attributes
end

#reload_attributes(*attrs_list) ⇒ Object

Reload a set of attributes from SDB. Adds the loaded list to in-memory data. attrs_list is an array or comma separated list of attributes names. Returns a hash of loaded attributes.

This is not the best method to get a bunch of attributes because a web service call is being performed for every attribute.

item = Client.find_by_name('Cat')
item.reload_attributes('toys', 'name')   #=> {"name"=>["Cat"], "toys"=>["Jons socks", "clew", "mice"]}


793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
# File 'lib/simple_record/active_sdb.rb', line 793

def reload_attributes(*attrs_list)
  raise_on_id_absence
  attrs_list = attrs_list.flatten.map { |attribute| attribute.to_s }
  attrs_list.delete('id')
  result = {}
  attrs_list.flatten.uniq.each do |attribute|
    attribute = attribute.to_s
    values = connection.get_attributes(domain, id, attribute)[:attributes][attribute]
    unless values.blank?
      @attributes[attribute] = result[attribute] = values
    else
      @attributes.delete(attribute)
    end
  end
  mark_as_old
  result
end

#save2(options = {}) ⇒ Object

Store in-memory attributes to SDB. Replaces the attributes values already stored at SDB by in-memory data. Returns a hash of stored attributes.

sandy = Client.new(:name => 'Sandy')  #=> #<Client:0xb775a7a8 @attributes={"name"=>["Sandy"]}, @new_record=true>
sandy['toys'] = 'boys'
sandy.save
sandy['toys'] = 'patchwork'
sandy.save
sandy['toys'] = 'kids'
sandy.save
puts sandy.attributes.inspect         #=> {"name"=>["Sandy"], "id"=>"b2832ce2-e461-11dc-b13c-001bfc466dd7", "toys"=>["kids"]}
sandy.reload                          #=> {"name"=>["Sandy"], "id"=>"b2832ce2-e461-11dc-b13c-001bfc466dd7", "toys"=>["kids"]}

Options:

- :except => Array of attributes to NOT save

compare to put method



879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
# File 'lib/simple_record/active_sdb.rb', line 879

def save2(options={})
  options[:create_domain] = true if options[:create_domain].nil?
  pre_save2
  atts_to_save = @attributes.dup
    #puts 'atts_to_save=' + atts_to_save.inspect
    #options = params.first.is_a?(Hash) ? params.pop : {}
  if options[:except]
    options[:except].each do |e|
      atts_to_save.delete(e).inspect
    end
  end
  if options[:dirty] # Only used in simple_record right now
                     # only save if the attribute is dirty
    dirty_atts = options[:dirty_atts]
    atts_to_save.delete_if { |key, value| !dirty_atts.has_key?(key) }
  end
  dom = options[:domain] || domain
    #puts 'atts_to_save2=' + atts_to_save.inspect
  connection.put_attributes(dom, id, atts_to_save, :replace, options)
  apres_save2
  @attributes
end

#save_attributes(attrs) ⇒ Object

Replaces the attributes at SDB by the given values. Attrs is a hash: { attribute1 => values1, …, attributeN => valuesN }. The other in-memory attributes are not being saved. Returns a hash of stored attributes.

see save method



917
918
919
920
921
922
923
924
925
926
927
928
929
930
# File 'lib/simple_record/active_sdb.rb', line 917

def save_attributes(attrs)
  prepare_for_update
  attrs = uniq_values(attrs)
    # if 'id' is present in attrs hash then replace internal 'id' attribute
  unless attrs['id'].blank?
    @attributes['id'] = attrs['id']
  else
    attrs['id'] = id
  end
  connection.put_attributes(domain, id, attrs, :replace) unless attrs.blank?
  attrs.each { |attribute, values| attrs[attribute] = values }
  mark_as_old
  attrs
end