agnostic_backend 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +52 -0
- data/LICENSE.txt +21 -0
- data/README.md +345 -0
- data/Rakefile +6 -0
- data/agnostic_backend.gemspec +34 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/doc/indexable.md +292 -0
- data/doc/queryable.md +0 -0
- data/lib/agnostic_backend/cloudsearch/index.rb +99 -0
- data/lib/agnostic_backend/cloudsearch/index_field.rb +103 -0
- data/lib/agnostic_backend/cloudsearch/indexer.rb +84 -0
- data/lib/agnostic_backend/cloudsearch/remote_index_field.rb +32 -0
- data/lib/agnostic_backend/index.rb +24 -0
- data/lib/agnostic_backend/indexable/config.rb +24 -0
- data/lib/agnostic_backend/indexable/content_manager.rb +51 -0
- data/lib/agnostic_backend/indexable/field.rb +26 -0
- data/lib/agnostic_backend/indexable/field_type.rb +48 -0
- data/lib/agnostic_backend/indexable/indexable.rb +125 -0
- data/lib/agnostic_backend/indexer.rb +48 -0
- data/lib/agnostic_backend/queryable/attribute.rb +22 -0
- data/lib/agnostic_backend/queryable/cloudsearch/executor.rb +100 -0
- data/lib/agnostic_backend/queryable/cloudsearch/query.rb +29 -0
- data/lib/agnostic_backend/queryable/cloudsearch/query_builder.rb +13 -0
- data/lib/agnostic_backend/queryable/cloudsearch/result_set.rb +27 -0
- data/lib/agnostic_backend/queryable/cloudsearch/visitor.rb +127 -0
- data/lib/agnostic_backend/queryable/criteria/binary.rb +47 -0
- data/lib/agnostic_backend/queryable/criteria/criterion.rb +13 -0
- data/lib/agnostic_backend/queryable/criteria/ternary.rb +36 -0
- data/lib/agnostic_backend/queryable/criteria_builder.rb +83 -0
- data/lib/agnostic_backend/queryable/executor.rb +43 -0
- data/lib/agnostic_backend/queryable/expressions/expression.rb +65 -0
- data/lib/agnostic_backend/queryable/operations/n_ary.rb +18 -0
- data/lib/agnostic_backend/queryable/operations/operation.rb +13 -0
- data/lib/agnostic_backend/queryable/operations/unary.rb +35 -0
- data/lib/agnostic_backend/queryable/query.rb +27 -0
- data/lib/agnostic_backend/queryable/query_builder.rb +98 -0
- data/lib/agnostic_backend/queryable/result_set.rb +42 -0
- data/lib/agnostic_backend/queryable/tree_node.rb +48 -0
- data/lib/agnostic_backend/queryable/validator.rb +174 -0
- data/lib/agnostic_backend/queryable/value.rb +26 -0
- data/lib/agnostic_backend/queryable/visitor.rb +124 -0
- data/lib/agnostic_backend/rspec/matchers.rb +69 -0
- data/lib/agnostic_backend/utilities.rb +207 -0
- data/lib/agnostic_backend/version.rb +3 -0
- data/lib/agnostic_backend.rb +49 -0
- metadata +199 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0a440a493f9b88844868a71e1489132fd0a10b6e
|
4
|
+
data.tar.gz: fd232d6923c079f24c1990e0204ed1adf30e9a84
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 099b38168efcd57ef5f79709ac8268c63e021858b99dae704114c073950f2bf7d4087ff6cdca857461e0f1701cf4e8f47ce09a17da297da57cbf251ea3916b52
|
7
|
+
data.tar.gz: 2f0bf677241595b6059a54ad61d97f60784700f1d77f5c1cbbbcbbfd9e901fb8988361c6edc0ac52fd07e40b9c79c530f21cb445f117b14e56b91e6eddeeae93
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
coverage
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
agnostic_backend
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.1.5
|
data/.travis.yml
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Contributor Code of Conduct
|
2
|
+
|
3
|
+
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
4
|
+
|
5
|
+
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
|
6
|
+
|
7
|
+
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
|
8
|
+
|
9
|
+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
|
10
|
+
|
11
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
|
12
|
+
|
13
|
+
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
agnostic_backend (0.9.0)
|
5
|
+
activesupport (>= 3.2.22)
|
6
|
+
aws-sdk (~> 2)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
activesupport (3.2.22)
|
12
|
+
i18n (~> 0.6, >= 0.6.4)
|
13
|
+
multi_json (~> 1.0)
|
14
|
+
aws-sdk (2.2.14)
|
15
|
+
aws-sdk-resources (= 2.2.14)
|
16
|
+
aws-sdk-core (2.2.14)
|
17
|
+
jmespath (~> 1.0)
|
18
|
+
aws-sdk-resources (2.2.14)
|
19
|
+
aws-sdk-core (= 2.2.14)
|
20
|
+
diff-lcs (1.2.5)
|
21
|
+
docile (1.1.5)
|
22
|
+
i18n (0.7.0)
|
23
|
+
jmespath (1.1.3)
|
24
|
+
multi_json (1.11.2)
|
25
|
+
rake (10.4.2)
|
26
|
+
rspec (2.14.1)
|
27
|
+
rspec-core (~> 2.14.0)
|
28
|
+
rspec-expectations (~> 2.14.0)
|
29
|
+
rspec-mocks (~> 2.14.0)
|
30
|
+
rspec-core (2.14.8)
|
31
|
+
rspec-expectations (2.14.5)
|
32
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
33
|
+
rspec-mocks (2.14.6)
|
34
|
+
simplecov (0.9.1)
|
35
|
+
docile (~> 1.1.0)
|
36
|
+
multi_json (~> 1.0)
|
37
|
+
simplecov-html (~> 0.8.0)
|
38
|
+
simplecov-html (0.8.0)
|
39
|
+
|
40
|
+
PLATFORMS
|
41
|
+
ruby
|
42
|
+
|
43
|
+
DEPENDENCIES
|
44
|
+
agnostic_backend!
|
45
|
+
bundler
|
46
|
+
rake
|
47
|
+
rspec
|
48
|
+
simplecov
|
49
|
+
simplecov-html
|
50
|
+
|
51
|
+
BUNDLED WITH
|
52
|
+
1.11.2
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Iasonas Gavriilidis
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,345 @@
|
|
1
|
+
[![Travis Build Status](https://travis-ci.org/e-travel/agnostic_backend.svg?branch=master)](https://travis-ci.org/e-travel/agnostic_backend)
|
2
|
+
[![Code Climate](https://codeclimate.com/github/e-travel/agnostic_backend/badges/gpa.svg)](https://codeclimate.com/github/e-travel/agnostic_backend)
|
3
|
+
|
4
|
+
# Agnostic Backend
|
5
|
+
|
6
|
+
`agnostic_backend` is a gem that provides indexing and searching
|
7
|
+
capabililities to Ruby objects by supplying two modules: `Indexable`
|
8
|
+
and `Queryable`. `Indexable` provides indexing functionality by
|
9
|
+
specifying a way to define which attributes of an object should be
|
10
|
+
included in a document to be indexed to a remote backend
|
11
|
+
store. `Queryable` provides search and retrieval functionality by
|
12
|
+
specifying a generic query language that seamlessly maps to specific
|
13
|
+
backend languages.
|
14
|
+
|
15
|
+
In addition to these two modules, `agnostic_backend` supplies
|
16
|
+
additional classes (`Indexer` and `Index`) to support the
|
17
|
+
configuration and functionality of remote backends (such as
|
18
|
+
elasticsearch, AWS Cloudsearch etc.).
|
19
|
+
|
20
|
+
Although the motivation and use case for the gem relates to
|
21
|
+
`ActiveRecord` models, no assumption is made as to the classes to
|
22
|
+
which `Indexable` and `Queryable` can be included. The objective is to
|
23
|
+
maximize the flexibility of clients with respect to the use cases they
|
24
|
+
need to address.
|
25
|
+
|
26
|
+
## Installation
|
27
|
+
|
28
|
+
Add this line to your application's Gemfile:
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
gem 'agnostic_backend'
|
32
|
+
```
|
33
|
+
|
34
|
+
And then execute:
|
35
|
+
|
36
|
+
$ bundle install
|
37
|
+
|
38
|
+
Or install it yourself as:
|
39
|
+
|
40
|
+
$ gem install agnostic_backend
|
41
|
+
|
42
|
+
## Requirements
|
43
|
+
|
44
|
+
`agnostic_backend` requires a ruby version `>=2.1.0` due to the use of
|
45
|
+
mandatory keyword arguments in method definitions. Check the `Gemfile`
|
46
|
+
for more info on dependencies.
|
47
|
+
|
48
|
+
## Usage
|
49
|
+
|
50
|
+
For the purposes of this document, we will focus on `ActiveRecord`
|
51
|
+
examples. Let's assume we have two AR models, `Task` and `Workflow`,
|
52
|
+
connected using an one-to-many relationship (i.e. a `Workflow` has
|
53
|
+
many `Task`s) as follows:
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
class Task < ActiveRecord::Base
|
57
|
+
include AgnosticBackend::Indexable
|
58
|
+
|
59
|
+
belongs_to :workflow, class_name: 'Workflow'
|
60
|
+
end
|
61
|
+
|
62
|
+
class Workflow < ActiveRecord::Base
|
63
|
+
include AgnosticBackend::Indexable
|
64
|
+
|
65
|
+
has_many :tasks, class_name: 'Task'
|
66
|
+
end
|
67
|
+
```
|
68
|
+
|
69
|
+
Let's assume also that we have a remote store to which we would like
|
70
|
+
to index documents related to `Task`s and from which we would like to
|
71
|
+
retrieve these documents by performing queries based on the document
|
72
|
+
fields.
|
73
|
+
|
74
|
+
### Indexable
|
75
|
+
|
76
|
+
In order to index individual tasks, we need to specify three things:
|
77
|
+
|
78
|
+
- what should the document contain (we'll use
|
79
|
+
`Indexable::ClassMethods#define_index_fields`)
|
80
|
+
- who should be notified when the object needs to be indexed (we'll
|
81
|
+
use `Indexable::ClassMethods#define_index_notifier`)
|
82
|
+
- when should the above notification(s) occur (we'll use `ActiveRecord`'s
|
83
|
+
`after_commit` callback)
|
84
|
+
|
85
|
+
Let's see that in action:
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
class Task < ActiveRecord::Base
|
89
|
+
# let's make our class Indexable
|
90
|
+
include AgnosticBackend::Indexable
|
91
|
+
|
92
|
+
belongs_to :workflow, class_name: 'Workflow'
|
93
|
+
|
94
|
+
# define what should the document contain
|
95
|
+
define_index_fields do
|
96
|
+
integer :id
|
97
|
+
date :last_assigned_at, value: :assigned_at, label: 'Last Assigned At'
|
98
|
+
string :type, value: proc { task_category.name }, label: 'Task Type'
|
99
|
+
struct :workflow, from: Workflow
|
100
|
+
end
|
101
|
+
|
102
|
+
# define who should be notified when this object needs to be indexed
|
103
|
+
define_index_notifier { self }
|
104
|
+
|
105
|
+
# define when should the above notifications occur
|
106
|
+
# we'll use Indexable's trigger_index_notification instance method
|
107
|
+
after_commit :trigger_index_notification
|
108
|
+
end
|
109
|
+
|
110
|
+
class Workflow < ActiveRecord::Base
|
111
|
+
# let's make our class Indexable
|
112
|
+
include AgnosticBackend::Indexable
|
113
|
+
|
114
|
+
has_many :tasks, class_name: 'Task'
|
115
|
+
|
116
|
+
# define what should the document contain and who is the owner
|
117
|
+
# Note that the contents are part of the document
|
118
|
+
# created by a `Task` instance
|
119
|
+
define_index_fields(owner: Task) do
|
120
|
+
integer :id
|
121
|
+
date :creation_date, value: :created_at, label: 'Creation Date'
|
122
|
+
end
|
123
|
+
|
124
|
+
# define who should be notified when this object needs to be indexed
|
125
|
+
define_index_notifier(target: Task) { tasks }
|
126
|
+
|
127
|
+
# define when should the above notifications occur
|
128
|
+
# we'll use Indexable's trigger_index_notification instance method
|
129
|
+
after_commit :trigger_index_notification
|
130
|
+
end
|
131
|
+
```
|
132
|
+
|
133
|
+
The above definitions achieve the following things:
|
134
|
+
|
135
|
+
- when a task is created/updated, a document is generated and sent to
|
136
|
+
the remote backend for indexing
|
137
|
+
- this document includes a section `workflow` that contains the
|
138
|
+
associated `Worflow`'s document (see `struct` entry in `Task`'s
|
139
|
+
`define_index_fields`)
|
140
|
+
- when a workflow is created/updated, all its associated tasks are
|
141
|
+
notified in order to index themselves (see `define_index_notifiers`
|
142
|
+
in both classes)
|
143
|
+
|
144
|
+
Now that we've defined our models and configured their indexing, let's
|
145
|
+
play a bit more:
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
# First, let's configure our remote backend
|
149
|
+
# we'll use AWS Cloudsearch as an example
|
150
|
+
AgnosticBackend::Indexable::Config.configure_index(
|
151
|
+
Task,
|
152
|
+
AgnosticBackend::Cloudsearch::Index,
|
153
|
+
region: "the_region",
|
154
|
+
domain_name: "the_domain_name",
|
155
|
+
document_endpoint: "the_document_endpoint",
|
156
|
+
search_endpoint: "the_search_endpoint",
|
157
|
+
access_key_id: "the_access_key_id",
|
158
|
+
secret_access_key: "the_secret_access_key"
|
159
|
+
)
|
160
|
+
|
161
|
+
# Let's create a Workflow and persist it
|
162
|
+
> workflow = Workflow.create(...)
|
163
|
+
# Let's add a couple of tasks
|
164
|
+
> 2.times { workflow << Task.create(...) }
|
165
|
+
|
166
|
+
# at this point, our two tasks have already been indexed
|
167
|
+
# due to the after_commit callbacks
|
168
|
+
|
169
|
+
# let's grab the first task
|
170
|
+
> task = workflow.tasks.first
|
171
|
+
|
172
|
+
# let's generate and inspect a document for this task
|
173
|
+
> task.generate_document
|
174
|
+
{:id => 10,
|
175
|
+
:last_assigned_at => '2015-12-30T12:34:55',
|
176
|
+
:type => 'SomeTask',
|
177
|
+
# includes the workflow contents
|
178
|
+
# through the struct relationship in Task's define_index_fields
|
179
|
+
:workflow => {
|
180
|
+
:id => 4,
|
181
|
+
:creation_date => '2015-12-30T12:34:53'
|
182
|
+
}
|
183
|
+
}
|
184
|
+
|
185
|
+
# we can index it again (synchronously)
|
186
|
+
> task.put_to_index
|
187
|
+
|
188
|
+
# the following achieves the same thing by default
|
189
|
+
# but Indexable's method can be overriden in order
|
190
|
+
# to implement custom functionality (e.g. asynchronous indexing)
|
191
|
+
> task.index_object
|
192
|
+
|
193
|
+
# hey, we can get the document schema too!
|
194
|
+
> Task.schema
|
195
|
+
{:id => :integer,
|
196
|
+
:last_assigned_at => :date,
|
197
|
+
:type => :string,
|
198
|
+
:workflow => {
|
199
|
+
:id => :integer,
|
200
|
+
:creation_date => :date
|
201
|
+
}
|
202
|
+
}
|
203
|
+
|
204
|
+
# and any custom property that we supplied in define_index_fields
|
205
|
+
# in this case :label
|
206
|
+
> Task.schema {|field_type| field_type.get_option(:label)}
|
207
|
+
{:id => nil,
|
208
|
+
:last_assigned_at => "Last Assigned At",
|
209
|
+
:type => "Task Type",
|
210
|
+
:workflow => {
|
211
|
+
:id => nil,
|
212
|
+
:creation_date => "Creation Date"
|
213
|
+
}
|
214
|
+
}
|
215
|
+
```
|
216
|
+
|
217
|
+
More information about the use of `Indexable` can be found in
|
218
|
+
[this document](src/master/doc/indexable.md).
|
219
|
+
|
220
|
+
### Queryable
|
221
|
+
|
222
|
+
Queries are built and executed against a remote backend. Assuming the
|
223
|
+
same `Task` class as before:
|
224
|
+
|
225
|
+
```ruby
|
226
|
+
> query_builder = Task.query_builder
|
227
|
+
> criteria_builder = query_builder.criteria_builder
|
228
|
+
|
229
|
+
# Let's build the query:
|
230
|
+
# last_assigned_at < '2015-10-10' OR type = 'FirstTask'
|
231
|
+
> criteria = criteria_builder.or(
|
232
|
+
criteria_builder.lt('last_assigned_at', '2015-10-10T00:00:00Z'),
|
233
|
+
criteria_builder.eq('type', 'FirstTask'))
|
234
|
+
|
235
|
+
# Setup the where clause
|
236
|
+
> query_builder.where(criteria)
|
237
|
+
|
238
|
+
# Let's put some more constraints
|
239
|
+
> query_builder.order('id', :asc)
|
240
|
+
> query_builder.limit(10)
|
241
|
+
|
242
|
+
# compile the query
|
243
|
+
> query = query_builder.build
|
244
|
+
|
245
|
+
# and run it!
|
246
|
+
results = query.execute
|
247
|
+
|
248
|
+
# results is a Queryable::ResultSet instance that gives
|
249
|
+
# access to the backend results; these follow the document's schema
|
250
|
+
> results.map {|result| result['workflow']['creation_date'] }
|
251
|
+
```
|
252
|
+
|
253
|
+
For more information about `Queryable` check out
|
254
|
+
[this document](src/master/doc/queryable.md).
|
255
|
+
|
256
|
+
|
257
|
+
### Backends
|
258
|
+
|
259
|
+
Currently, the gem includes one concrete backend implementation that
|
260
|
+
talks to [AWS Cloudsearch](https://aws.amazon.com/cloudsearch/). New
|
261
|
+
backends can be implemented by subclassing `AgnosticBackend::Index`
|
262
|
+
and `AgnosticBackend::Indexer` (more on that later).
|
263
|
+
|
264
|
+
#### The Index
|
265
|
+
|
266
|
+
`AgnosticBackend::Index` is responsible for representing a particular
|
267
|
+
repo (aka index/table) in a remote backend for a specific model. This
|
268
|
+
implies that `Index` is responsible for any communications that occur
|
269
|
+
between the client and the backend, as well as any
|
270
|
+
initialization/configuration (credentials etc.) tasks. `Index` is also
|
271
|
+
the context in which a query is built and executed.
|
272
|
+
|
273
|
+
`AgnosticBackend::Indexable` exposes the `Config` class in order to
|
274
|
+
facilitate the initialization/configuration of an index at
|
275
|
+
runtime. For example, the initialization/configuration of the
|
276
|
+
Cloudsearch index that corresponds to the indexing of `Task`s can be
|
277
|
+
achieved by:
|
278
|
+
|
279
|
+
```ruby
|
280
|
+
AgnosticBackend::Indexable::Config.configure_index(
|
281
|
+
Task, # the class whose instances are indexed
|
282
|
+
AgnosticBackend::Cloudsearch::Index, # the concrete Index class
|
283
|
+
# and various parameters related to the specific backend (Cloudsearch)
|
284
|
+
region: 'the_region',
|
285
|
+
domain_name: 'the_domain_name',
|
286
|
+
document_endpoint: 'the_document_endpoint',
|
287
|
+
search_endpoint: 'the_search_endpoint',
|
288
|
+
access_key_id: 'the_access_key_id',
|
289
|
+
secret_access_key: 'the_secret_access_key'
|
290
|
+
)
|
291
|
+
```
|
292
|
+
|
293
|
+
The remote index's name should follow the convention used by
|
294
|
+
`Indexable` (see `Indexable::ClassMethods#index_name`) according to
|
295
|
+
which the remote index name is automatically determined given the
|
296
|
+
including class's name convention.
|
297
|
+
|
298
|
+
#### The Indexer
|
299
|
+
|
300
|
+
`AgnosticBackend::Indexer` is responsible for document handling,
|
301
|
+
i.e. publishing documents to and deleting documents from the remote
|
302
|
+
backend. These processes are broken down into discrete steps,
|
303
|
+
including pre-processing, transformations, and conversions to other
|
304
|
+
formats (xml, json). This is reflected in the default implementation
|
305
|
+
of `Indexer#put` (that sends a document to the remote backend) which
|
306
|
+
actually does (among other things):
|
307
|
+
|
308
|
+
```ruby
|
309
|
+
publish(transform(prepare(document)))
|
310
|
+
```
|
311
|
+
|
312
|
+
For example, a remote backend may not support the indexing of
|
313
|
+
documents with `nil` values. As part of the pre-processing step
|
314
|
+
(`#prepare`), the implementor of a specific backend might choose to
|
315
|
+
exclude `nil` values from the document before forwarding it down the
|
316
|
+
chain.
|
317
|
+
|
318
|
+
## Development
|
319
|
+
|
320
|
+
After checking out the repo, run `bundle exec bin/setup` or `bundle
|
321
|
+
install` to install dependencies. Then, run `bundle exec rake spec` or
|
322
|
+
`bundle exec rspec spec` to run the tests. This will also generate a
|
323
|
+
test coverage report in `coverage/index.html` for inspection. You can
|
324
|
+
also run `bin/console` for an interactive prompt that will allow you
|
325
|
+
to experiment.
|
326
|
+
|
327
|
+
To install this gem onto your local machine, run `bundle exec rake
|
328
|
+
install`. To release a new version, update the version number in
|
329
|
+
`version.rb`, and then run `bundle exec rake release`, which will
|
330
|
+
create a git tag for the version, push git commits and tags, and push
|
331
|
+
the `.gem` file to [rubygems.org](https://rubygems.org).
|
332
|
+
|
333
|
+
## Contributing
|
334
|
+
|
335
|
+
Bug reports and pull requests are welcome on GitHub at
|
336
|
+
https://github.com/e-travel/agnostic_backend. This project is intended
|
337
|
+
to be a safe, welcoming space for collaboration, and contributors are
|
338
|
+
expected to adhere to the
|
339
|
+
[Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
340
|
+
|
341
|
+
|
342
|
+
## License
|
343
|
+
|
344
|
+
The gem is available as open source under the terms of the
|
345
|
+
[MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'agnostic_backend/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "agnostic_backend"
|
8
|
+
spec.version = AgnosticBackend::VERSION
|
9
|
+
spec.authors = ["Iasonas Gavriilidis",
|
10
|
+
"Laertis Pappas",
|
11
|
+
"Kyriakos Kentzoglanakis"]
|
12
|
+
spec.email = ["i.gavriilidis@pamediakopes.gr",
|
13
|
+
"l.pappas@pamediakopes.gr",
|
14
|
+
"k.kentzoglanakis@pamediakopes.gr"]
|
15
|
+
|
16
|
+
spec.summary = %q{A gem to index/query ruby objects to/from remote backends}
|
17
|
+
spec.homepage = "https://github.com/e-travel/agnostic_backend"
|
18
|
+
spec.license = "MIT"
|
19
|
+
|
20
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
21
|
+
spec.bindir = "exe"
|
22
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
|
+
spec.require_paths = ["lib"]
|
24
|
+
spec.required_ruby_version = '>= 2.1.0' # for mandatory method keyword arguments
|
25
|
+
|
26
|
+
spec.add_runtime_dependency "activesupport", ">= 3.2.22"
|
27
|
+
spec.add_runtime_dependency "aws-sdk", "~> 2"
|
28
|
+
|
29
|
+
spec.add_development_dependency "bundler"
|
30
|
+
spec.add_development_dependency "rake"
|
31
|
+
spec.add_development_dependency "rspec"
|
32
|
+
spec.add_development_dependency "simplecov"
|
33
|
+
spec.add_development_dependency "simplecov-html"
|
34
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "agnostic_backend"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|