elasticord 1.0.0 → 1.0.1

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.
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