realm-elasticsearch 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0bdbf9e0dd47a5bf591f0336e92461449ee4e10e460a277a114f1dd457eb77c5
4
+ data.tar.gz: b2c421396d4408724ae61918b62521cb6c1bf320450b246d9cd58f10bf321edd
5
+ SHA512:
6
+ metadata.gz: 2cf0977b9f7a3962519ded00de041b7e0b8e3c9f54259a6907130bfed7ae3cfc1a825e92137477ccddf45dbbb690de8bbc291b5e4184ff5b5c7adb60cb1b250b
7
+ data.tar.gz: b7dcccfcbe26ce6cb68dee2176fd3489a05a2626ad8e77d1426a3d54879152d0329abe52f8b2128d1b17a5a51d608f0dab26665553c3427ff4ed69024ab9ad8c
@@ -0,0 +1,8 @@
1
+ # rubocop:disable Naming/FileName
2
+ # frozen_string_literal: true
3
+
4
+ Dir[File.join(File.dirname(__FILE__), 'realm', '**', '*.rb')].sort.each do |f|
5
+ require f
6
+ end
7
+
8
+ # rubocop:enable Naming/FileName
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'typhoeus'
4
+ require 'elasticsearch'
5
+ require 'realm/health_status'
6
+ require_relative 'repository'
7
+
8
+ module Realm
9
+ module Elasticsearch
10
+ class Gateway
11
+ def initialize(url:, **options)
12
+ @url = url
13
+ @client_options = options.slice(:adapter, :retry_on_failure, :request_timeout)
14
+ end
15
+
16
+ def health
17
+ issues = []
18
+ index_names = Repository.subclasses.map(&:index_name)
19
+ begin
20
+ issues << 'One or more indexes missing' unless client.indices.exists(index: index_names)
21
+ rescue StandardError => e
22
+ issues << "Elasticsearch connection error: #{e.full_message}"
23
+ end
24
+ HealthStatus.from_issues(issues)
25
+ end
26
+
27
+ def method_missing(...)
28
+ client.send(...)
29
+ end
30
+
31
+ def respond_to_missing?(...)
32
+ client.respond_to?(...)
33
+ end
34
+
35
+ private
36
+
37
+ def client
38
+ @client ||= ::Elasticsearch::Client.new(default_config.merge(@client_options))
39
+ end
40
+
41
+ def default_config
42
+ {
43
+ url: @url,
44
+ adapter: :typhoeus,
45
+ retry_on_failure: 3,
46
+ request_timeout: 30,
47
+ }
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'realm/plugin'
4
+ require_relative 'gateway'
5
+
6
+ module Realm
7
+ module Elasticsearch
8
+ class Plugin < Realm::Plugin
9
+ def self.setup(config, container)
10
+ return unless config.persistence_gateway[:type] == :elasticsearch
11
+
12
+ container.register_factory(Gateway, **config.persistence_gateway, as: 'persistence.gateway')
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+
5
+ module Realm
6
+ module Elasticsearch
7
+ module RakeTasks
8
+ class << self
9
+ def setup(engine_name, engine_root: nil, url: ENV['ELASTICSEARCH_URL'])
10
+ return unless url
11
+
12
+ client = ::Elasticsearch::Client.new(url: url)
13
+
14
+ Rake.application.in_namespace(:es) do
15
+ Rake::Task.define_task(:create_indexes) do
16
+ with_definitions(engine_name, engine_root) do |index, config|
17
+ client.indices.create(index: index, body: config) unless client.indices.exists(index: index)
18
+ end
19
+ end
20
+
21
+ Rake::Task.define_task(:drop_indexes) do
22
+ with_definitions(engine_name, engine_root) do |index, _config|
23
+ client.indices.delete(index: index) if client.indices.exists(index: index)
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def with_definitions(engine_name, engine_root)
32
+ engine_root ||= Rails.root.join('engines', engine_name.to_s)
33
+ Dir.glob(File.join(engine_root, 'elasticsearch/indexes/*.yaml')).each do |path|
34
+ yield File.basename(path, '.yaml'), YAML.safe_load(File.read(path))
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require 'active_support/core_ext/string'
5
+
6
+ module Realm
7
+ module Elasticsearch
8
+ class Repository
9
+ def self.repo_name(value = :not_provided)
10
+ @repo_name = value.to_sym unless value == :not_provided
11
+ @repo_name = name.demodulize.underscore unless defined?(@repo_name)
12
+ @repo_name
13
+ end
14
+
15
+ def self.index_name(value = :not_provided)
16
+ @index_name = value.to_sym unless value == :not_provided
17
+ @index_name = repo_name.pluralize unless defined?(@index_name)
18
+ @index_name
19
+ end
20
+
21
+ def initialize(client)
22
+ @client = client
23
+ end
24
+
25
+ def find(id:)
26
+ single(client.get(index: index_name, id: id))
27
+ rescue ::Elasticsearch::Transport::Transport::Errors::NotFound
28
+ nil
29
+ end
30
+
31
+ def all
32
+ multiple(raw_search(query: { match_all: {} }))
33
+ end
34
+
35
+ def create(id: nil, **attrs)
36
+ client.index(index: index_name, type: '_doc', id: id, body: attrs, refresh: refresh?)
37
+ rescue ::Elasticsearch::Transport::Transport::Errors::Conflict
38
+ raise Realm::Persistence::Conflict
39
+ end
40
+
41
+ def update(id:, **attrs)
42
+ raw_update(id, doc: attrs)
43
+ end
44
+
45
+ def upsert(id:, **attrs)
46
+ raw_update(id, doc: attrs, doc_as_upsert: true)
47
+ end
48
+
49
+ def delete(id:)
50
+ client.delete(index: index_name, type: '_doc', id: id, refresh: refresh?)
51
+ true
52
+ rescue ::Elasticsearch::Transport::Transport::Errors::NotFound
53
+ false
54
+ end
55
+
56
+ def search_by(params)
57
+ multiple(raw_search(query: { bool: { must: match_params(params) } }))
58
+ end
59
+
60
+ def delete_by(params)
61
+ client.delete_by_query(
62
+ index: index_name,
63
+ refresh: refresh?,
64
+ body: { query: {
65
+ bool: {
66
+ must: match_params(params),
67
+ },
68
+ } },
69
+ )
70
+ end
71
+
72
+ def raw_update(id, body = {})
73
+ client.update(index: index_name, type: '_doc', id: id, body: body, refresh: refresh?)
74
+ end
75
+
76
+ def raw_search(yaml: nil, options: {}, **body)
77
+ client.search(index: index_name, body: yaml ? YAML.safe_load(yaml) : body, **options)
78
+ end
79
+
80
+ def truncate!
81
+ client.delete_by_query(
82
+ index: index_name,
83
+ body: { query: { match_all: {} } },
84
+ conflicts: 'proceed',
85
+ refresh: refresh?,
86
+ )
87
+ end
88
+
89
+ private
90
+
91
+ attr_reader :client
92
+
93
+ def refresh?
94
+ # impacts performance so should be used only in TEST env
95
+ # TODO: remove dependency on Rails
96
+ defined?(::Rails) && ::Rails.env.test?
97
+ end
98
+
99
+ def single(result)
100
+ id = result['_id'].then { |i| i.to_i.positive? ? i.to_i : i }
101
+ result['_source'].merge(id: id).deep_symbolize_keys
102
+ end
103
+
104
+ def multiple(results)
105
+ docs = results.dig('hits', 'hits').map { |doc| single(doc) }
106
+ { docs: docs }
107
+ end
108
+
109
+ def match_params(params)
110
+ params.map { |(key, value)| { match: { key => value } } }
111
+ end
112
+
113
+ def index_name
114
+ self.class.index_name
115
+ end
116
+ end
117
+ end
118
+ end
metadata ADDED
@@ -0,0 +1,131 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: realm-elasticsearch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.7.0
5
+ platform: ruby
6
+ authors:
7
+ - developers@reevoo.com
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-06-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: elasticsearch
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '7.11'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '7.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: realm-core
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: typhoeus
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.4'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.4'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry-byebug
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description:
98
+ email:
99
+ executables: []
100
+ extensions: []
101
+ extra_rdoc_files: []
102
+ files:
103
+ - lib/realm-elasticsearch.rb
104
+ - lib/realm/elasticsearch/gateway.rb
105
+ - lib/realm/elasticsearch/plugin.rb
106
+ - lib/realm/elasticsearch/rake_tasks.rb
107
+ - lib/realm/elasticsearch/repository.rb
108
+ homepage:
109
+ licenses:
110
+ - MIT
111
+ metadata: {}
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: 2.7.0
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements: []
127
+ rubygems_version: 3.1.6
128
+ signing_key:
129
+ specification_version: 4
130
+ summary: Elasticsearch plugin for Realm
131
+ test_files: []