elasticord 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +3 -1
  3. data/dash_overlord.gemspec +2 -2
  4. data/elasticord.gemspec +1 -1
  5. data/lib/dash_overlord/models/v1/dynamo_db/base.rb +22 -11
  6. data/lib/dash_overlord/models/v1/dynamo_db/migration.rb +13 -3
  7. data/lib/dash_overlord/models/v1/dynamo_db/paginated_result.rb +16 -0
  8. data/lib/dash_overlord/models/v1/dynamo_db/scan.rb +114 -0
  9. data/lib/dash_overlord/use_cases/v1/dummy_data/create/charts/base.rb +3 -2
  10. data/lib/dash_overlord/use_cases/v1/dummy_data/create/charts/build.rb +1 -1
  11. data/lib/dash_overlord/use_cases/v1/repositories/dynamo_db/create/batch.rb +3 -2
  12. data/lib/dash_overlord/use_cases/v1/repositories/dynamo_db/search_and_paginate/apply_filters.rb +21 -0
  13. data/lib/dash_overlord/use_cases/v1/repositories/dynamo_db/search_and_paginate/apply_pagination.rb +62 -0
  14. data/lib/dash_overlord/use_cases/v1/repositories/dynamo_db/search_and_paginate/base.rb +39 -0
  15. data/lib/dash_overlord/use_cases/v1/shared/search_and_paginate/apply_filters.rb +2 -2
  16. data/lib/dash_overlord/use_cases/v1/shared/search_and_paginate/apply_pagination.rb +4 -11
  17. data/lib/dash_overlord/use_cases/v1/shared/search_and_paginate/base.rb +2 -6
  18. data/lib/dash_overlord/use_cases/v1/shared/search_and_paginate/build_meta_data.rb +26 -0
  19. data/lib/dash_overlord/use_cases/v1/shared/search_and_paginate/execute_query.rb +21 -0
  20. data/lib/dash_overlord/use_cases/v1/videos/index/dynamodb/search_and_paginate_videos.rb +7 -2
  21. data/lib/dash_overlord/use_cases/v1/videos/index/elastic_search/search_and_paginate_videos.rb +2 -80
  22. data/lib/elasticord/base.rb +10 -11
  23. data/lib/elasticord/entities/array_with_meta_data.rb +37 -0
  24. data/lib/elasticord/orm/search_builder.rb +101 -0
  25. data/lib/elasticord/version.rb +1 -1
  26. data/lib/tasks/create_dummy_data.rake +1 -0
  27. data/spec/dash_overlord/use_cases/v1/videos/index/dynamo_db_spec.rb +71 -9
  28. data/spec/elasticord/base_spec.rb +42 -155
  29. data/spec/elasticord/orm/search_builder_spec.rb +269 -0
  30. metadata +14 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2408da665b98d05d1dde3f3fc1511074b8eaed04
4
- data.tar.gz: cf31f46f08bcda7ce6f93ab47ed62f94dd275c88
3
+ metadata.gz: d5e4119d7285ad68f49090e7b9344e88c24561c8
4
+ data.tar.gz: 9cbf209b6d0dc56674975cbe9672dcfbba414444
5
5
  SHA512:
6
- metadata.gz: 670431cec3b786c0ba816939d9b1abfd863536df2c44b7a4d4ecea6e6ea5a597b5dcc13128dcae47c561996d4de747f26bfa28ae6c8f8fe435ea8a47e24b7d81
7
- data.tar.gz: c5b7f656b196c76f0feda110371ff3caf0004c44a8e479491fcf8c67309e572acab26930c03dccabb80fc0220af29e8c23735784c1e35631500c668778da2654
6
+ metadata.gz: 1f6a9926758e9ffdafc6439208ddd82fb96480e7102f1f91914407f7c30be698572703b95d6939c49ae9625a2407403dca8f9510e4a8170ee55982d1703ea018
7
+ data.tar.gz: 845a169cd4b027b00d26cc7aa76acf5c634fb45d675e55ce6d2c08179003b5f6d1b5df798987975b480f61a6a70db3e2d838f1a246abfbf7fd0f9f40d0e7b840
@@ -6,12 +6,14 @@ PATH
6
6
  aws-sdk (>= 2.2.35)
7
7
  bcrypt (>= 2.0.0)
8
8
  dotenv (>= 2.1.1)
9
- elasticsearch (>= 5.0.3)
9
+ elasticord (>= 1.0.0)
10
10
  i18n (>= 0.7.0)
11
11
  kaminari (>= 1.0.0.rc1)
12
12
  object_attorney (>= 3.0.7)
13
13
  pg (>= 0.17)
14
14
  ransack (>= 1.7.0)
15
+ elasticord (1.0.1)
16
+ elasticsearch (~> 5.0)
15
17
 
16
18
  GEM
17
19
  remote: https://rubygems.org/
@@ -30,10 +30,10 @@ Gem::Specification.new do |gem|
30
30
  gem.add_runtime_dependency 'i18n', '>= 0.7.0'
31
31
  gem.add_runtime_dependency 'dotenv', '>= 2.1.1'
32
32
  gem.add_runtime_dependency 'bcrypt', '>= 2.0.0'
33
+ gem.add_runtime_dependency 'aws-sdk', '>= 2.2.35'
33
34
  gem.add_runtime_dependency 'ransack', '>= 1.7.0'
34
35
  gem.add_runtime_dependency 'kaminari', '>= 1.0.0.rc1'
36
+ gem.add_runtime_dependency 'elasticord', '>= 1.0.0'
35
37
  gem.add_runtime_dependency 'activerecord', '>= 3'
36
- gem.add_runtime_dependency 'elasticsearch', '>= 5.0.3'
37
38
  gem.add_runtime_dependency 'object_attorney', '>= 3.0.7'
38
- gem.add_runtime_dependency 'aws-sdk', '>= 2.2.35'
39
39
  end
@@ -12,7 +12,7 @@ Gem::Specification.new do |gem|
12
12
  gem.email = "dev@streetbees.com"
13
13
  gem.summary = "Elastic search client"
14
14
  gem.description = "Elastic search client on top of elasticsearch gem"
15
- gem.homepage = "https://github.com/streetbees/dashlord/dash_lord"
15
+ gem.homepage = "https://github.com/Streetbees/dashlord"
16
16
 
17
17
  gem.files = `git ls-files`.split($/)
18
18
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
@@ -31,19 +31,28 @@ module DashOverlord
31
31
  end
32
32
 
33
33
  def self.all
34
- collection = []
35
- params = all_params
36
-
37
- loop do
38
- result = client.scan(params)
39
- collection += result.items
34
+ DynamoDb::Scan.new \
35
+ client: client,
36
+ table_name: table_name,
37
+ resource_class: self
38
+ end
40
39
 
41
- break unless result.last_evaluated_key
40
+ def self.page(page, last_evaluated_key)
41
+ DynamoDb::Scan.new \
42
+ current_page: page,
43
+ last_evaluated_key: last_evaluated_key,
44
+ client: client,
45
+ table_name: table_name,
46
+ resource_class: self
42
47
 
43
- params[:exclusive_start_key] = result.last_evaluated_key
44
- end
48
+ end
45
49
 
46
- collection
50
+ def self.search(filters)
51
+ DynamoDb::Scan.new \
52
+ client: client,
53
+ table_name: table_name,
54
+ resource_class: self,
55
+ filters: filters
47
56
  end
48
57
 
49
58
  def self.table_name
@@ -85,9 +94,11 @@ module DashOverlord
85
94
  end
86
95
  end
87
96
 
88
- def self.all_params
97
+ def self.scan_params
89
98
  {
90
99
  table_name: table_name,
100
+ exclusive_start_key: @last_evaluated_key,
101
+ limit: @per_page
91
102
  }
92
103
  end
93
104
 
@@ -20,14 +20,24 @@ module DashOverlord
20
20
  {
21
21
  table_name: @migration_class.table_name,
22
22
  key_schema: [
23
- attribute_name: "id",
24
- key_type: "HASH"
23
+ {
24
+ attribute_name: "dashboard_id",
25
+ key_type: "HASH" #PRIMARY KEY
26
+ },
27
+ {
28
+ attribute_name: "id",
29
+ key_type: "RANGE" # SORT KEY
30
+ },
25
31
  ],
26
32
  attribute_definitions: [
27
33
  {
28
- attribute_name: "id",
34
+ attribute_name: "dashboard_id",
29
35
  attribute_type: "N"
30
36
  },
37
+ {
38
+ attribute_name: "id",
39
+ attribute_type: "N"
40
+ }
31
41
  ],
32
42
  provisioned_throughput: {
33
43
  read_capacity_units: 10,
@@ -0,0 +1,16 @@
1
+ require 'forwardable'
2
+
3
+ module DashOverlord
4
+ module Models
5
+ module V1
6
+ module DynamoDb
7
+ class PaginatedResult < OpenStruct
8
+ include Enumerable
9
+ extend Forwardable
10
+
11
+ def_delegators :items, :each, :map, :first, :last, :length, :count
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,114 @@
1
+ module DashOverlord
2
+ module Models
3
+ module V1
4
+ module DynamoDb
5
+ class Scan < DynamoDb::Base
6
+ # resource.page(page).per(per_page)
7
+ def search(filters)
8
+ self.filters = filters
9
+
10
+ self
11
+ end
12
+
13
+ def page(page, last_evaluated_key)
14
+ self.current_page = page
15
+ self.last_evaluated_key = last_evaluated_key
16
+
17
+ self
18
+ end
19
+
20
+ def per(per_page)
21
+ self.limit = per_page
22
+
23
+ self
24
+ end
25
+
26
+ def execute #choose a better name than this...
27
+ if paginated_scan
28
+ return scan_page
29
+ end
30
+
31
+ scan_all
32
+ end
33
+
34
+ protected ##################### PROTECTED ###########################
35
+
36
+ def scan_all
37
+ scan_params = params
38
+ items = []
39
+
40
+ loop do
41
+ result = client.scan(scan_params)
42
+ items += result.items
43
+
44
+ break unless result.last_evaluated_key
45
+
46
+ scan_params[:exclusive_start_key] = result.last_evaluated_key
47
+ end
48
+
49
+ items.map{ |item| resource_class.new(item) }
50
+ end
51
+
52
+ def paginated_scan
53
+ (limit && current_page)
54
+ end
55
+
56
+ def scan_page
57
+ result = client.scan(params)
58
+
59
+ DynamoDb::PaginatedResult.new \
60
+ items: result.items.map{ |item| resource_class.new(item) },
61
+ last_evaluated_key: result.last_evaluated_key,
62
+ exclusive_start_key: last_evaluated_key,
63
+ limit: limit
64
+ end
65
+
66
+ def params
67
+ {
68
+ table_name: "#{table_name}",
69
+ exclusive_start_key: last_evaluated_key,
70
+ limit: limit
71
+ }.merge(filter_params)
72
+ end
73
+
74
+ def filter_params
75
+ return {} unless filters
76
+
77
+ initial_params = {
78
+ filter_expression: [],
79
+ expression_attribute_names: {},
80
+ expression_attribute_values: {}
81
+ }
82
+
83
+ filters_mapped = \
84
+ filters.each_with_object(initial_params) do |(key, value), object|
85
+ process_filter(key, value, object)
86
+
87
+ object
88
+ end
89
+
90
+ filters_mapped[:filter_expression] = \
91
+ filters_mapped[:filter_expression].join(' and ')
92
+
93
+ filters_mapped
94
+ end
95
+
96
+ private
97
+
98
+ def process_filter(attribute_expression, value, object)
99
+ attribute = attribute_expression.to_s.gsub('_eq', '')
100
+
101
+ object[:expression_attribute_names]["##{attribute}"] = \
102
+ attribute
103
+
104
+ object[:expression_attribute_values][":#{attribute}"] = \
105
+ value
106
+
107
+ object[:filter_expression] << \
108
+ "##{attribute} = :#{attribute}"
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
@@ -6,7 +6,7 @@ module DashOverlord
6
6
  module Charts
7
7
 
8
8
  class Base < V1::Base
9
- context_reader :num_of_records, :repo
9
+ context_reader :num_of_records, :repo, :table_name
10
10
 
11
11
  def perform
12
12
  return unless num_of_records && repo
@@ -14,7 +14,8 @@ module DashOverlord
14
14
  invoke! Charts::Build
15
15
 
16
16
  repository_create.perform \
17
- items: context.items
17
+ items: context.items,
18
+ table_name: table_name
18
19
  end
19
20
 
20
21
  protected
@@ -35,7 +35,7 @@ module DashOverlord
35
35
  num_of_records.times.map do |index|
36
36
  build_record(RECORD_STRUCTURE) \
37
37
  .merge \
38
- "submission_id" => "#{index + 1}",
38
+ "id" => (index + 1),
39
39
  "dashboard_id" => 1
40
40
  end
41
41
  end
@@ -7,7 +7,8 @@ module DashOverlord
7
7
 
8
8
  class Batch < V1::Base
9
9
  context_reader :items,
10
- :client
10
+ :client,
11
+ :table_name
11
12
 
12
13
  def perform
13
14
  return unless items
@@ -23,7 +24,7 @@ module DashOverlord
23
24
  records.each_slice(25) do |batch|
24
25
  client.batch_write_item \
25
26
  request_items: {
26
- "sample_data" => batch
27
+ "#{table_name}" => batch
27
28
  }
28
29
  end
29
30
  end
@@ -0,0 +1,21 @@
1
+ module DashOverlord
2
+ module UseCases
3
+ module V1
4
+ module Repositories
5
+ module DynamoDb
6
+ module SearchAndPaginate
7
+
8
+ class ApplyFilters < V1::Base
9
+ context_reader :filter_query, :resource
10
+
11
+ def perform
12
+ context.resource = \
13
+ resource.search(filter_query.presence)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,62 @@
1
+ module DashOverlord
2
+ module UseCases
3
+ module V1
4
+ module Repositories
5
+ module DynamoDb
6
+ module SearchAndPaginate
7
+
8
+ class ApplyPagination < V1::Base
9
+ PAGE_DEFAULT = 1
10
+ PER_PAGE_DEFAULT = 10
11
+
12
+ context_reader :page,
13
+ :last_evaluated_key,
14
+ :per_page,
15
+ :resources,
16
+ :resource
17
+
18
+ def perform
19
+ context.page = fix_page(page)
20
+
21
+ if page == 0
22
+ no_pagination
23
+ else
24
+ apply_pagination
25
+ end
26
+ end
27
+
28
+ protected ###################### PROTECTED ###########################
29
+
30
+ def no_pagination
31
+ context.resources = resource.all
32
+
33
+ context.per_page = 0
34
+ end
35
+
36
+ def apply_pagination
37
+ context.per_page = fix_per_page(per_page)
38
+
39
+ context.resource = \
40
+ resource.page(page, last_evaluated_key).per(per_page)
41
+ end
42
+
43
+ def fix_page(page)
44
+ page_or_nil = page.class == String ? page.presence : page
45
+
46
+ (page_or_nil || PAGE_DEFAULT).to_i
47
+ end
48
+
49
+ def fix_per_page(per_page)
50
+ per_page_or_nil = \
51
+ per_page.class == String ? per_page.presence : per_page
52
+
53
+ (per_page_or_nil || PER_PAGE_DEFAULT).to_i
54
+ end
55
+
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,39 @@
1
+ module DashOverlord
2
+ module UseCases
3
+ module V1
4
+ module Repositories
5
+ module DynamoDb
6
+ module SearchAndPaginate
7
+
8
+ class Base < V1::Base
9
+
10
+ # EXPECTED CONTEXT
11
+ # :resource_class
12
+ # :page
13
+ # :per_page
14
+ # :filter_query
15
+ # :full_text_term
16
+
17
+ def search_and_paginate(resource)
18
+ context.resource = resource
19
+
20
+ invoke! ApplyFilters
21
+ invoke! ApplyPagination
22
+
23
+ context.resource = context.resource.execute
24
+
25
+ context.meta = Entities::V1::MetaData.new \
26
+ context.attributes.slice :page,
27
+ :per_page,
28
+ :total_pages,
29
+ :total_results
30
+
31
+ context.resource
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -10,9 +10,9 @@ module DashOverlord
10
10
  context_reader :filter_query, :resources
11
11
 
12
12
  def perform
13
- return unless resources.respond_to?(:search)
13
+ return unless resources.respond_to?(:ransack)
14
14
 
15
- context.search_builder = resources.search(filter_query.presence)
15
+ context.search_builder = resources.ransack(filter_query.presence)
16
16
 
17
17
  context.resources = context.search_builder.result(distinct: true)
18
18
  end