dyna_model 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ca4e3bd3b871756a2b5fad4bf362c334bbf804af
4
- data.tar.gz: ac13badc8bca36d88787d6cbdb6134af19c69a93
3
+ metadata.gz: 254b9c0ebdd7a60601af697b4702fa53d9dc3f0e
4
+ data.tar.gz: 9129d092e187f9284e1853d63e744ffa56e9d84a
5
5
  SHA512:
6
- metadata.gz: 23243b46398ab0517a2f6a7c57e1fdbbe3f4f63c8d55b8c1a8a73abe8de75a297395ad8554d06101c02cb472de16a696e738a509b46002427812b4efa6279e49
7
- data.tar.gz: 32f20b9e28c107825230eb53dfd18b092f6626e91e66a4b1fd859b0523c4f5c38c1566d2e77e9417ec80b8612c4c91ba24269f47a74379eecc1611ee37b0b38a
6
+ metadata.gz: 3dd8cca0fe4249f173fceb88d4a29b706409de9a017049844493a6066ef67f2238548bddd18b9278d5ba390eeeb0910d82c103ad4db3ffe4e7171903433d164f
7
+ data.tar.gz: 9c27a58d8bb188a5a29bf49c4ab6163ae9d3f3525d85e4d6a16f6466a586c31aed0e744a36ba7de1ff31b37f4d0aefd0a50cf95ca1bbb07cce6122d5defd1ab7
data/README.md CHANGED
@@ -76,6 +76,16 @@ rake ddb:destroy CLASS=Dude
76
76
  rake ddb:destroy CLASS=all
77
77
  ```
78
78
 
79
+ ## Elasticsearch::Model compatible adapter
80
+ ```
81
+ require 'dyna_model/adapters/elasticsearch/dyna_model_adapter'
82
+ class Item
83
+ include DynaModel::Document
84
+ include Elasticsearch::Model
85
+ include Elasticsearch::Model::Callbacks
86
+ end
87
+ ```
88
+
79
89
  # AWS::Record
80
90
  * http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/Record.html
81
91
  * https://github.com/aws/aws-sdk-ruby/blob/master/lib/aws/record/abstract_base.rb
@@ -0,0 +1,86 @@
1
+ module Elasticsearch
2
+ module Model
3
+ module Adapter
4
+ module DynaModelAdapter
5
+
6
+ Adapter.register self, lambda { |klass| !!defined?(::DynaModel::Document) && klass.ancestors.include?(::DynaModel::Document) }
7
+
8
+ module Records
9
+
10
+ def records
11
+ records_arr = klass.read_multiple(ids, format: :array)
12
+ records_arr.sort_by { |e| response.response['hits']['hits'].index { |hit| hit['_id'].to_s == e.id.to_s } }
13
+ end
14
+
15
+ # Intercept call to sorting methods, so we can ignore the order from Elasticsearch
16
+ %w| asc desc order_by |.each do |name|
17
+ define_method name do |*args|
18
+ raise "TODO - not supported yet"
19
+ end
20
+ end
21
+ end
22
+
23
+ module Callbacks
24
+ def self.included(base)
25
+ base.after_create { |document| document.__elasticsearch__.index_document }
26
+ base.after_update { |document| document.__elasticsearch__.update_document }
27
+ base.after_destroy { |document| document.__elasticsearch__.delete_document }
28
+ end
29
+ end
30
+
31
+ module Importing
32
+
33
+ def __find_in_batches(options={}, &block)
34
+ items = []
35
+
36
+ # Use 1/4 or read provision
37
+ read_provision = self.dynamo_db_table.table_schema[:provisioned_throughput][:read_capacity_units]
38
+ raise "read_provision not set for class!" unless read_provision
39
+ default_batch_size = (read_provision / 2.0).floor
40
+ batch_size = options[:batch_size] || default_batch_size
41
+ puts "Indexing via scan with batch size of #{batch_size}..."
42
+
43
+ # :consumed_capacity
44
+ scan_idx = 0
45
+ results_hash = {}
46
+ while scan_idx == 0 || (results_hash && results_hash[:last_evaluated_key])
47
+ puts "Batch iteration #{scan_idx+1}..."
48
+ scan_options = {
49
+ batch: batch_size,
50
+ manual_batching: true,
51
+ return_consumed_capacity: :total
52
+ }
53
+ scan_options.merge!(exclusive_start_key: results_hash[:last_evaluated_key]) if results_hash[:last_evaluated_key]
54
+ scan_options.merge!(scan_filter: options[:scan_filter]) if options[:scan_filter]
55
+ results_hash = self.scan(scan_options)
56
+
57
+ unless results_hash[:results].blank?
58
+ puts "Indexing #{results_hash[:results].size} results..."
59
+ batch_for_bulk = results_hash[:results].map { |a| { index: {
60
+ _id: a.id,
61
+ data: a.__elasticsearch__.as_indexed_json
62
+ } } }
63
+ yield batch_for_bulk
64
+ end
65
+
66
+ # If more results to scan, sleep to throttle...
67
+ # Local Dynamo is not returning consumed_capacity 2014-01-12
68
+ if results_hash[:last_evaluated_key] && results_hash[:consumed_capacity]
69
+ # try to keep read usage under 50% of read_provision
70
+ sleep_time = results_hash[:consumed_capacity][:capacity_units].to_f / (read_provision / 2.0)
71
+ puts "Sleeping for #{sleep_time}..."
72
+ sleep(sleep_time)
73
+ end
74
+
75
+ scan_idx += 1
76
+ end
77
+
78
+ end
79
+
80
+ end
81
+
82
+ end
83
+
84
+ end
85
+ end
86
+ end
@@ -34,6 +34,17 @@ module DynaModel
34
34
  end
35
35
  super
36
36
  end
37
+
38
+ # OVERRIDE
39
+ # https://github.com/aws/aws-sdk-ruby/blob/master/lib/aws/record/abstract_base.rb#L76
40
+ # AWS::Record::AbstractBase for :select attributes
41
+ public
42
+ def attributes
43
+ attributes = AWS::Core::IndifferentHash.new
44
+ (self.instance_variable_get("@_selected_attributes") || self.class.attributes.keys).inject(attributes) do |hash,attr_name|
45
+ hash.merge(attr_name => __send__(attr_name))
46
+ end
47
+ end
37
48
  end
38
49
 
39
50
  include ActiveModel::Conversion
@@ -47,6 +58,10 @@ module DynaModel
47
58
  include DynaModel::Schema
48
59
  include DynaModel::Query
49
60
 
61
+ def id
62
+ self.dynamo_db_guid
63
+ end
64
+
50
65
  def to_param
51
66
  self.dynamo_db_guid
52
67
  end
@@ -64,7 +79,7 @@ module DynaModel
64
79
  end
65
80
 
66
81
  def all_attributes_loaded?
67
- self.instance_variable_get("@_select") == :all
82
+ self.instance_variable_get("@_select").nil? && self.instance_variable_get("@_select") == :all
68
83
  end
69
84
 
70
85
  # When only partial attributes were selected (via GSI or projected attributes on an index)
@@ -30,18 +30,26 @@ module DynaModel
30
30
  end
31
31
 
32
32
  def read_multiple(keys, options={})
33
+ options[:format] = (options[:format] && options[:format] == :array) ? :array : :hash
33
34
  results_map = {}
34
- results = self.dynamo_db_table.batch_get_item(keys, options)
35
- results[:responses][self.dynamo_db_table_name(options[:shard_name])].each do |result|
36
- attrs = Response.strip_attr_types(result)
37
- obj = self.obj_from_attrs(attrs, options)
38
- if self.dynamo_db_table.range_keys.present? && primary_range_key = self.dynamo_db_table.range_keys.find{|rk| rk[:primary_range_key] }
39
- (results_map[attrs[self.dynamo_db_table.hash_key[:attribute_name]]] ||= {})[attrs[primary_range_key[:attribute_name]]] = obj
40
- else
41
- results_map[attrs[self.dynamo_db_table.hash_key[:attribute_name]]] = obj
35
+ results_arr = []
36
+ if keys.present?
37
+ results = self.dynamo_db_table.batch_get_item(keys, options)
38
+ results[:responses][self.dynamo_db_table_name(options[:shard_name])].each do |result|
39
+ attrs = Response.strip_attr_types(result)
40
+ obj = self.obj_from_attrs(attrs, options)
41
+ if options[:format] == :array
42
+ results_arr << obj
43
+ else
44
+ if self.dynamo_db_table.range_keys.present? && primary_range_key = self.dynamo_db_table.range_keys.find{|rk| rk[:primary_range_key] }
45
+ (results_map[attrs[self.dynamo_db_table.hash_key[:attribute_name]]] ||= {})[attrs[primary_range_key[:attribute_name]]] = obj
46
+ else
47
+ results_map[attrs[self.dynamo_db_table.hash_key[:attribute_name]]] = obj
48
+ end
49
+ end
42
50
  end
43
51
  end
44
- results_map
52
+ options[:format] == :array ? results_arr : results_map
45
53
  end
46
54
 
47
55
  # Read results up to the limit
@@ -281,16 +281,13 @@ module DynaModel
281
281
  keys.each do |k|
282
282
  key_request = {}
283
283
  if @primary_range_key
284
- hash_value = k[:hash_value]
284
+ hash_value, range_value = k.split(@model.guid_delimiter)
285
285
  else
286
- raise ArgumentError, "expected keys to be in the form of ['hash key here'] for table with no range keys" if hash_value.is_a?(Hash)
287
286
  hash_value = k
288
287
  end
289
- raise ArgumentError, "every key must include a :hash_value" if hash_value.blank?
290
288
  key_request[@hash_key[:attribute_name]] = { @hash_key[:attribute_type] => hash_value.to_s }
291
289
  if @primary_range_key
292
- range_value = k[:range_value]
293
- raise ArgumentError, "every key must include a :range_value" if range_value.blank?
290
+ raise ArgumentError, "every key must include a range_value" if range_value.blank?
294
291
  key_request[@primary_range_key[:attribute_name]] = { @primary_range_key[:attribute_type] => range_value.to_s }
295
292
  end
296
293
  keys_request << key_request
@@ -1,3 +1,3 @@
1
1
  module DynaModel
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -99,7 +99,7 @@ describe "DynaModel::Query" do
99
99
  multi[@cacher2.key].should_not be_nil
100
100
  @user = User.create(@user_attrs)
101
101
  @user2 = User.create(@user2_attrs)
102
- multi = User.read_multiple([{hash_value: @user.hashy, range_value: @user.ranger}, {hash_value: @user2.hashy, range_value: @user2.ranger}])
102
+ multi = User.read_multiple([@user.dynamo_db_guid, @user2.dynamo_db_guid])
103
103
  multi[@user.hashy].should_not be_nil
104
104
  multi[@user.hashy][@user.ranger.to_s].should_not be_nil
105
105
  multi[@user2.hashy].should_not be_nil
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dyna_model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cary Dunn
@@ -136,6 +136,7 @@ files:
136
136
  - Rakefile
137
137
  - dyna_model.gemspec
138
138
  - lib/dyna_model.rb
139
+ - lib/dyna_model/adapters/elasticsearch/dyna_model_adapter.rb
139
140
  - lib/dyna_model/attributes.rb
140
141
  - lib/dyna_model/aws/record/attributes/serialized_attr.rb
141
142
  - lib/dyna_model/config.rb