syphon 0.0.1 → 0.0.2
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.
- data/CHANGELOG +10 -0
- data/Gemfile +1 -0
- data/README.markdown +62 -1
- data/lib/syphon/index.rb +15 -7
- data/lib/syphon/railtie.rb +38 -14
- data/lib/syphon/schema.rb +8 -7
- data/lib/syphon/version.rb +1 -1
- data/lib/syphon.rb +32 -5
- data/test/syphon/test_index.rb +25 -6
- data/test/syphon/test_railtie.rb +98 -0
- data/test/syphon/test_schema.rb +32 -9
- data/test/test_helper.rb +6 -4
- data/test/test_syphon.rb +55 -5
- metadata +6 -4
data/CHANGELOG
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
== 0.0.2 2013-12-12
|
2
|
+
|
3
|
+
* Add index_settings attribute to control sharding, replication, etc.
|
4
|
+
* Allow dynamic SQL (blocks) for attributes.
|
5
|
+
* Make index_base_name overridable instead of index_name. The former is
|
6
|
+
prefixed with the configured index_namespace.
|
7
|
+
* Restructure configuration under Rails. Single file (syphon.yml) with log
|
8
|
+
settings at top-level, and database and elasticsearch settings under their
|
9
|
+
respective keys. Log file may now be relative to rails root.
|
10
|
+
|
1
11
|
== 0.0.1 2013-11-18
|
2
12
|
|
3
13
|
* Hi.
|
data/Gemfile
CHANGED
data/README.markdown
CHANGED
@@ -2,4 +2,65 @@
|
|
2
2
|
|
3
3
|
Syphon data from an Arel source into ElasticSearch.
|
4
4
|
|
5
|
-
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
gem install syphon
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
class UsersIndex
|
12
|
+
include Syphon::Index
|
13
|
+
|
14
|
+
define_source do
|
15
|
+
# Define some attributes. Options like "index: :not_analyzed" are passed
|
16
|
+
# to elasticsearch.
|
17
|
+
|
18
|
+
string :login, index: :not_analyzed
|
19
|
+
string :name
|
20
|
+
integer :age
|
21
|
+
geo_point :location
|
22
|
+
string :bio
|
23
|
+
nested_documents do
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
## Why?
|
30
|
+
|
31
|
+
In 2 words: fast indexing.
|
32
|
+
|
33
|
+
There is no shortage of ElasticSearch adapters for ruby. The issue is that they
|
34
|
+
typically work by defining fields as attributes (methods) on your model
|
35
|
+
instances, which means to index a lot of data, you need to roundtrip your data
|
36
|
+
through heavy ruby models, which can be quite slow, particularly if your models
|
37
|
+
are made of ActiveRecord.
|
38
|
+
|
39
|
+
Syphon makes no such assumption. You define your fields to index using SQL
|
40
|
+
expressions. These are assembled into a single SQL query, and the resulting rows
|
41
|
+
are used to build ElasticSearch documents in an intuitive way using minimal ruby
|
42
|
+
data structures. Those coming from ThinkingSphinx might find this notion -- and
|
43
|
+
syntax -- familiar.
|
44
|
+
|
45
|
+
Syphon is similar in concept to an ElasticSearch river, except it's completely
|
46
|
+
handled off the server. In fact it was originally implemented using the
|
47
|
+
[JDBC river][jdbc-river], but the current incarnation was found to be a little
|
48
|
+
lacking in functionality for a smooth integration (such as documents with
|
49
|
+
multiple nested fields, and synchronous updates for testing).
|
50
|
+
|
51
|
+
Syphon focuses on the indexing aspect only - you are free to choose another gem
|
52
|
+
for the query DSL.
|
53
|
+
|
54
|
+
[jdbc-river]: https://github.com/jprante/elasticsearch-river-jdbc
|
55
|
+
|
56
|
+
## Contributing
|
57
|
+
|
58
|
+
* [Bug reports](https://github.com/howaboutwe/syphon/issues)
|
59
|
+
* [Source](https://github.com/howaboutwe/syphon)
|
60
|
+
* Patches: Fork on Github, send pull request.
|
61
|
+
* Include tests where practical.
|
62
|
+
* Leave the version alone, or bump it in a separate commit.
|
63
|
+
|
64
|
+
## Copyright
|
65
|
+
|
66
|
+
Copyright (c) George Ogata. See LICENSE for details.
|
data/lib/syphon/index.rb
CHANGED
@@ -3,14 +3,16 @@ module Syphon
|
|
3
3
|
def self.included(base)
|
4
4
|
base.extend ClassMethods
|
5
5
|
base.pre_sql ||= []
|
6
|
+
base.index_settings ||= {}
|
6
7
|
super
|
7
8
|
end
|
8
9
|
|
9
10
|
module ClassMethods
|
10
|
-
attr_accessor :pre_sql
|
11
|
+
attr_accessor :pre_sql, :index_settings
|
11
12
|
|
12
13
|
def inherited(subclass)
|
13
14
|
subclass.pre_sql = pre_sql.dup
|
15
|
+
subclass.index_settings = index_settings.dup
|
14
16
|
super
|
15
17
|
end
|
16
18
|
|
@@ -25,11 +27,19 @@ module Syphon
|
|
25
27
|
def index_name
|
26
28
|
@index_name ||=
|
27
29
|
begin
|
28
|
-
|
29
|
-
|
30
|
+
namespace = Syphon.index_namespace
|
31
|
+
if namespace.to_s.empty?
|
32
|
+
index_base_name
|
33
|
+
else
|
34
|
+
"#{namespace}_#{index_base_name}"
|
35
|
+
end
|
30
36
|
end
|
31
37
|
end
|
32
38
|
|
39
|
+
def index_base_name
|
40
|
+
@index_base_name ||= name.sub(/Index\z/, '').underscore.pluralize
|
41
|
+
end
|
42
|
+
|
33
43
|
def sources
|
34
44
|
@sources ||= {}
|
35
45
|
end
|
@@ -38,7 +48,7 @@ module Syphon
|
|
38
48
|
old_internal_name = internal_index_name
|
39
49
|
new_internal_name = new_internal_index_name(index_name)
|
40
50
|
|
41
|
-
client.indices.create(index: new_internal_name)
|
51
|
+
client.indices.create(index: new_internal_name, body: {settings: index_settings})
|
42
52
|
sources.each do |name, source|
|
43
53
|
body = source.mapping
|
44
54
|
client.indices.put_mapping(index: new_internal_name, type: source.type, body: body)
|
@@ -82,9 +92,7 @@ module Syphon
|
|
82
92
|
@warmups ||= []
|
83
93
|
end
|
84
94
|
|
85
|
-
|
86
|
-
|
87
|
-
attr_writer :index_name
|
95
|
+
attr_writer :index_base_name
|
88
96
|
|
89
97
|
private
|
90
98
|
|
data/lib/syphon/railtie.rb
CHANGED
@@ -1,27 +1,51 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'yaml'
|
3
|
+
|
1
4
|
module Syphon
|
2
5
|
class Railtie < Rails::Railtie
|
6
|
+
this = self
|
7
|
+
|
3
8
|
rake_tasks do
|
4
9
|
require 'syphon/tasks'
|
5
10
|
end
|
6
11
|
|
7
12
|
initializer "syphon.initialize" do
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
+
this.set_configuration(
|
14
|
+
env: Rails.env,
|
15
|
+
root: Rails.root,
|
16
|
+
app_name: Rails.application.class.parent_name,
|
17
|
+
dbconfig: ActiveRecord::Base.configurations,
|
18
|
+
)
|
19
|
+
end
|
13
20
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
21
|
+
class << self
|
22
|
+
def set_configuration(params = {})
|
23
|
+
env, root, app_name, dbconfig =
|
24
|
+
params.values_at(:env, :root, :app_name, :dbconfig)
|
25
|
+
|
26
|
+
path = "#{root}/config/syphon.yml"
|
27
|
+
if File.exist?(path)
|
28
|
+
erb = File.read(path)
|
29
|
+
yaml = ERB.new(erb).result
|
30
|
+
config = YAML.load(yaml)[env]
|
31
|
+
end
|
32
|
+
|
33
|
+
config ||= {}
|
34
|
+
config.symbolize_keys!
|
35
|
+
config[:log] = normalize_log(env, root, config[:log])
|
36
|
+
config[:database] ||= dbconfig[env].dup
|
37
|
+
config[:index_namespace] ||= "#{app_name.underscore}_#{env}"
|
38
|
+
config[:database].try(:symbolize_keys!)
|
39
|
+
config[:elasticsearch].try(:symbolize_keys!)
|
40
|
+
Syphon.configuration = config
|
20
41
|
end
|
21
42
|
|
22
|
-
|
23
|
-
|
24
|
-
|
43
|
+
private
|
44
|
+
|
45
|
+
def normalize_log(env, root, log)
|
46
|
+
return nil if log == false
|
47
|
+
log ||= "#{root}/log/syphon.#{env}.log"
|
48
|
+
log.start_with?('/') ? log : "#{root}/#{log}"
|
25
49
|
end
|
26
50
|
end
|
27
51
|
end
|
data/lib/syphon/schema.rb
CHANGED
@@ -84,24 +84,25 @@ module Syphon
|
|
84
84
|
end
|
85
85
|
|
86
86
|
class Field
|
87
|
-
def initialize(name, type, expression, options = {})
|
87
|
+
def initialize(schema, name, type, expression, options = {})
|
88
|
+
@schema = schema
|
88
89
|
@name = name.to_sym
|
89
90
|
@type = type
|
90
91
|
@expression = expression
|
91
92
|
@properties = options.merge(type: type)
|
92
93
|
end
|
93
94
|
|
94
|
-
attr_reader :name, :type, :expression, :properties
|
95
|
+
attr_reader :schema, :name, :type, :expression, :properties
|
95
96
|
|
96
97
|
def select(outer = nil)
|
97
98
|
name = outer ? "#{outer}[#{self.name}]" : self.name
|
98
|
-
"#{expression} AS `#{name}`"
|
99
|
+
"#{schema.send(:query_fragment, expression)} AS `#{name}`"
|
99
100
|
end
|
100
101
|
end
|
101
102
|
|
102
103
|
class NestedField < Field
|
103
|
-
def initialize(name, options = {}, &block)
|
104
|
-
super(name, :nested, nil, options)
|
104
|
+
def initialize(schema, name, options = {}, &block)
|
105
|
+
super(schema, name, :nested, nil, options)
|
105
106
|
@nested_schema = Schema.new(&block)
|
106
107
|
end
|
107
108
|
|
@@ -127,7 +128,7 @@ module Syphon
|
|
127
128
|
end
|
128
129
|
|
129
130
|
def field(name, type, expression, options = {})
|
130
|
-
schema.fields[name.to_sym] = Field.new(name, type, expression, options)
|
131
|
+
schema.fields[name.to_sym] = Field.new(schema, name, type, expression, options)
|
131
132
|
end
|
132
133
|
|
133
134
|
%w[string short byte integer long float double date boolean binary geo_point].each do |type|
|
@@ -139,7 +140,7 @@ module Syphon
|
|
139
140
|
end
|
140
141
|
|
141
142
|
def nested(name, options = {}, &block)
|
142
|
-
schema.fields[name.to_sym] = NestedField.new(name, options, &block)
|
143
|
+
schema.fields[name.to_sym] = NestedField.new(schema, name, options, &block)
|
143
144
|
end
|
144
145
|
|
145
146
|
{
|
data/lib/syphon/version.rb
CHANGED
data/lib/syphon.rb
CHANGED
@@ -10,31 +10,58 @@ module Syphon
|
|
10
10
|
autoload :VERSION, 'syphon/version'
|
11
11
|
|
12
12
|
class << self
|
13
|
-
attr_writer :configuration
|
13
|
+
attr_writer :configuration
|
14
14
|
|
15
15
|
def configuration
|
16
16
|
@configuration ||= {}
|
17
17
|
end
|
18
18
|
|
19
19
|
def database_configuration
|
20
|
-
|
20
|
+
configuration[:database] || {}
|
21
|
+
end
|
22
|
+
|
23
|
+
def elasticsearch_configuration
|
24
|
+
configuration = Syphon.configuration[:elasticsearch].try(:dup) || {}
|
25
|
+
configuration[:logger] = logger
|
26
|
+
configuration
|
21
27
|
end
|
22
28
|
|
23
29
|
def index_namespace
|
24
|
-
|
30
|
+
configuration[:index_namespace]
|
25
31
|
end
|
26
32
|
|
27
33
|
def database_connection
|
28
|
-
|
34
|
+
Thread.current[:syphon_database_connection] ||= Mysql2::Client.new(database_configuration)
|
29
35
|
end
|
30
36
|
|
31
37
|
def client
|
32
|
-
Thread.current[:syphon_client] ||= Elasticsearch::Client.new(
|
38
|
+
Thread.current[:syphon_client] ||= Elasticsearch::Client.new(elasticsearch_configuration)
|
33
39
|
end
|
34
40
|
|
35
41
|
def index_classes
|
36
42
|
Syphon.configuration['index_classes'].map(&:constantize)
|
37
43
|
end
|
44
|
+
|
45
|
+
def logger
|
46
|
+
Thread.current[:syphon_logger] ||= make_logger
|
47
|
+
end
|
48
|
+
|
49
|
+
def logger=(logger)
|
50
|
+
Thread.current[:syphon_logger] = logger
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def make_logger
|
56
|
+
log = Syphon.configuration[:log] || STDOUT
|
57
|
+
Logger.new(log).tap do |logger|
|
58
|
+
logger.formatter = lambda do |level, time, progname, message|
|
59
|
+
"#{time.strftime('%Y-%m-%d: %H:%M:%S')}: #{level}: #{message}\n"
|
60
|
+
end
|
61
|
+
level = configuration[:log_level] and
|
62
|
+
logger.level = Logger.const_get(level.upcase)
|
63
|
+
end
|
64
|
+
end
|
38
65
|
end
|
39
66
|
end
|
40
67
|
|
data/test/syphon/test_index.rb
CHANGED
@@ -12,15 +12,15 @@ describe Syphon::Index do
|
|
12
12
|
|
13
13
|
describe ".index_name" do
|
14
14
|
describe "when no index namespace is set" do
|
15
|
-
use_attribute_value Syphon, :
|
15
|
+
use_attribute_value Syphon, :configuration, {index_namespace: nil}
|
16
16
|
|
17
|
-
it "it
|
17
|
+
it "it is the index base name" do
|
18
18
|
TestIndex.index_name.must_equal 'tests'
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
22
|
describe "when the index namespace is empty" do
|
23
|
-
use_attribute_value Syphon, :
|
23
|
+
use_attribute_value Syphon, :configuration, {index_namespace: ''}
|
24
24
|
|
25
25
|
it "it is treated the same as nil" do
|
26
26
|
TestIndex.index_name.must_equal 'tests'
|
@@ -32,10 +32,21 @@ describe Syphon::Index do
|
|
32
32
|
TestIndex.index_name.must_equal 'syphon_tests'
|
33
33
|
end
|
34
34
|
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe ".index_base_name" do
|
38
|
+
it "is based on the class name" do
|
39
|
+
TestIndex.index_base_name.must_equal 'tests'
|
40
|
+
end
|
41
|
+
|
42
|
+
it "can be overridden" do
|
43
|
+
TestIndex.index_base_name = 'wibble'
|
44
|
+
TestIndex.index_base_name.must_equal 'wibble'
|
45
|
+
end
|
35
46
|
|
36
|
-
it "
|
37
|
-
TestIndex.
|
38
|
-
TestIndex.index_name.must_equal '
|
47
|
+
it "contributes to the index name" do
|
48
|
+
TestIndex.index_base_name = 'wibble'
|
49
|
+
TestIndex.index_name.must_equal 'syphon_wibble'
|
39
50
|
end
|
40
51
|
end
|
41
52
|
|
@@ -95,6 +106,14 @@ describe Syphon::Index do
|
|
95
106
|
hits.map { |doc| doc['_source']['login'] }.must_equal ['bob']
|
96
107
|
end
|
97
108
|
|
109
|
+
it "passes configured index settings" do
|
110
|
+
TestIndex.index_settings = {number_of_shards: 23}
|
111
|
+
TestIndex.build
|
112
|
+
index = TestIndex.client.indices.get_alias(name: TestIndex.index_name).keys.first
|
113
|
+
num_shards = client.indices.get_settings[index]['settings']['index.number_of_shards']
|
114
|
+
num_shards.must_equal '23'
|
115
|
+
end
|
116
|
+
|
98
117
|
it "runs all warmups between building the new index and rotating it in" do
|
99
118
|
this = self
|
100
119
|
runs = []
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
describe Syphon::Railtie do
|
4
|
+
use_attribute_value Syphon, :configuration, {}
|
5
|
+
|
6
|
+
describe ".set_configuration" do
|
7
|
+
use_temporary_directory "#{ROOT}/test/tmp"
|
8
|
+
|
9
|
+
let(:params) do
|
10
|
+
{
|
11
|
+
env: 'test',
|
12
|
+
root: tmp,
|
13
|
+
app_name: 'MyApp',
|
14
|
+
dbconfig: {'test' => {'database' => 'ardb'}},
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def write_config(data)
|
19
|
+
FileUtils.mkdir_p "#{tmp}/config"
|
20
|
+
open("#{tmp}/config/syphon.yml", 'w') { |f| f.print data.to_yaml }
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "when no configuration file is present" do
|
24
|
+
it "sets all the defaults" do
|
25
|
+
Syphon::Railtie.set_configuration(params)
|
26
|
+
Syphon.configuration[:log].must_equal "#{tmp}/log/syphon.test.log"
|
27
|
+
Syphon.configuration[:database].must_equal({database: 'ardb'})
|
28
|
+
Syphon.configuration[:index_namespace].must_equal('my_app_test')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "when a configuration file is present, but no key for the environment" do
|
33
|
+
it "sets all the defaults" do
|
34
|
+
write_config('other_env' => 'blah')
|
35
|
+
Syphon::Railtie.set_configuration(params)
|
36
|
+
Syphon.configuration[:log].must_equal "#{tmp}/log/syphon.test.log"
|
37
|
+
Syphon.configuration[:database].must_equal({database: 'ardb'})
|
38
|
+
Syphon.configuration[:index_namespace].must_equal('my_app_test')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "when a valid configuration is present" do
|
43
|
+
it "sets the configuration" do
|
44
|
+
write_config('test' => {'reload_on_failure' => true})
|
45
|
+
Syphon::Railtie.set_configuration(params)
|
46
|
+
Syphon.configuration[:reload_on_failure].must_equal true
|
47
|
+
end
|
48
|
+
|
49
|
+
it "defaults the index namespace to one based on the app name and Rails env" do
|
50
|
+
Syphon::Railtie.set_configuration(params)
|
51
|
+
Syphon.index_namespace.must_equal 'my_app_test'
|
52
|
+
end
|
53
|
+
|
54
|
+
it "sets a custom index namespace if configured" do
|
55
|
+
write_config('test' => {'index_namespace' => 'my_namespace'})
|
56
|
+
Syphon::Railtie.set_configuration(params)
|
57
|
+
Syphon.index_namespace.must_equal 'my_namespace'
|
58
|
+
end
|
59
|
+
|
60
|
+
it "sets a good default log path" do
|
61
|
+
write_config('test' => {})
|
62
|
+
Syphon::Railtie.set_configuration(params)
|
63
|
+
Syphon.configuration[:log].must_equal "#{tmp}/log/syphon.test.log"
|
64
|
+
end
|
65
|
+
|
66
|
+
it "expands a given log path relative to the rails root" do
|
67
|
+
write_config('test' => {'log' => 'path/to/my.log'})
|
68
|
+
Syphon::Railtie.set_configuration(params)
|
69
|
+
Syphon.configuration[:log].must_equal "#{tmp}/path/to/my.log"
|
70
|
+
end
|
71
|
+
|
72
|
+
it "sets no log if the log option is false" do
|
73
|
+
write_config('test' => {'log' => false})
|
74
|
+
Syphon::Railtie.set_configuration(params)
|
75
|
+
Syphon.configuration[:log].must_be_nil
|
76
|
+
end
|
77
|
+
|
78
|
+
it "sets the given database configuration" do
|
79
|
+
write_config('test' => {'database' => {'database' => 'mydb'}})
|
80
|
+
Syphon::Railtie.set_configuration(params)
|
81
|
+
Syphon.database_configuration.must_equal({database: 'mydb'})
|
82
|
+
end
|
83
|
+
|
84
|
+
it "defaults to the primary ActiveRecord configuration" do
|
85
|
+
write_config('test' => {})
|
86
|
+
Syphon::Railtie.set_configuration(params)
|
87
|
+
Syphon.database_configuration.must_equal({database: 'ardb'})
|
88
|
+
end
|
89
|
+
|
90
|
+
it "sets the given elasticsearch configuration" do
|
91
|
+
FileUtils.mkdir_p "#{tmp}/log"
|
92
|
+
write_config('test' => {'elasticsearch' => {'reload_on_failure' => true}})
|
93
|
+
Syphon::Railtie.set_configuration(params)
|
94
|
+
Syphon.elasticsearch_configuration[:reload_on_failure].must_equal true
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
data/test/syphon/test_schema.rb
CHANGED
@@ -180,14 +180,38 @@ describe Syphon::Schema do
|
|
180
180
|
having 'count(*) = 1'
|
181
181
|
end
|
182
182
|
schema.query.must_equal <<-EOS.strip.gsub(/\s+/, ' ')
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
183
|
+
SELECT S AS `s`, T AS `inner[t]`
|
184
|
+
FROM things
|
185
|
+
INNER JOIN a ON 1
|
186
|
+
INNER JOIN b ON 2
|
187
|
+
WHERE a = 1
|
188
|
+
GROUP BY x
|
189
|
+
HAVING count(*) = 1
|
190
|
+
EOS
|
191
|
+
end
|
192
|
+
|
193
|
+
it "calls blocks for dynamic queries" do
|
194
|
+
schema = Syphon::Schema.new do
|
195
|
+
string :s, -> { 'S' }
|
196
|
+
nested :inner do
|
197
|
+
string :t, -> { 'T' }
|
198
|
+
end
|
199
|
+
from -> { 'things' }
|
200
|
+
join -> { 'INNER JOIN a ON 1' }
|
201
|
+
join -> { 'INNER JOIN b ON 2' }
|
202
|
+
where -> { 'a = 1' }
|
203
|
+
group_by -> { 'x' }
|
204
|
+
having -> { 'count(*) = 1' }
|
205
|
+
end
|
206
|
+
schema.query.must_equal <<-EOS.strip.gsub(/\s+/, ' ')
|
207
|
+
SELECT S AS `s`, T AS `inner[t]`
|
208
|
+
FROM things
|
209
|
+
INNER JOIN a ON 1
|
210
|
+
INNER JOIN b ON 2
|
211
|
+
WHERE a = 1
|
212
|
+
GROUP BY x
|
213
|
+
HAVING count(*) = 1
|
214
|
+
EOS
|
191
215
|
end
|
192
216
|
|
193
217
|
it "omits optional clauses when in the minimal case" do
|
@@ -268,4 +292,3 @@ describe Syphon::Schema do
|
|
268
292
|
end
|
269
293
|
end
|
270
294
|
end
|
271
|
-
|
data/test/test_helper.rb
CHANGED
@@ -3,16 +3,18 @@ ROOT = File.expand_path('..', File.dirname(__FILE__))
|
|
3
3
|
$:.unshift "#{ROOT}/lib"
|
4
4
|
require 'minitest/spec'
|
5
5
|
require 'yaml'
|
6
|
+
require 'fileutils'
|
6
7
|
require 'temporaries'
|
7
8
|
require 'debugger' if RUBY_VERSION < '2.0'
|
8
9
|
require 'looksee'
|
10
|
+
require 'rails'
|
9
11
|
|
10
12
|
require 'syphon'
|
11
13
|
|
12
|
-
config = YAML.load_file("#{ROOT}/test/config.yml")
|
13
|
-
|
14
|
-
Syphon.configuration = config
|
15
|
-
Syphon.
|
14
|
+
config = YAML.load_file("#{ROOT}/test/config.yml").symbolize_keys
|
15
|
+
config[:database].symbolize_keys!
|
16
|
+
Syphon.configuration = config.merge(index_namespace: 'syphon')
|
17
|
+
Syphon.logger = Logger.new('/dev/null')
|
16
18
|
|
17
19
|
MiniTest::Spec.class_eval do
|
18
20
|
def self.uses_users_table
|
data/test/test_syphon.rb
CHANGED
@@ -10,7 +10,7 @@ describe Syphon do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
describe ".database_configuration" do
|
13
|
-
use_instance_variable_value Syphon, :
|
13
|
+
use_instance_variable_value Syphon, :configuration, nil
|
14
14
|
|
15
15
|
it "defaults to an empty hash" do
|
16
16
|
Syphon.database_configuration.must_equal({})
|
@@ -18,11 +18,61 @@ describe Syphon do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
describe ".index_namespace" do
|
21
|
-
|
22
|
-
|
21
|
+
describe "when a namespace is configured" do
|
22
|
+
use_instance_variable_value Syphon, :configuration, {index_namespace: 'NAMESPACE'}
|
23
23
|
|
24
|
-
|
25
|
-
|
24
|
+
it "is the configured index namespace" do
|
25
|
+
Syphon.index_namespace.must_equal('NAMESPACE')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "when no namespace is configured" do
|
30
|
+
use_instance_variable_value Syphon, :configuration, {}
|
31
|
+
|
32
|
+
it "is nil" do
|
33
|
+
Syphon.index_namespace.must_be_nil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe ".database_configuration" do
|
39
|
+
use_attribute_value Syphon, :configuration, nil
|
40
|
+
|
41
|
+
it "uses the configured database configuration" do
|
42
|
+
Syphon.configuration = {database: {database: 'mydb'}}
|
43
|
+
Syphon.database_configuration.must_equal({database: 'mydb'})
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe ".elasticsearch_configuration" do
|
48
|
+
use_attribute_value Syphon, :configuration, nil
|
49
|
+
use_attribute_value Syphon, :logger, nil
|
50
|
+
use_temporary_directory "#{ROOT}/test/tmp"
|
51
|
+
|
52
|
+
it "includes all configured elasticserach settings" do
|
53
|
+
Syphon.configuration = {elasticsearch: {reload_on_failure: true}}
|
54
|
+
Syphon.elasticsearch_configuration[:reload_on_failure].must_equal true
|
55
|
+
end
|
56
|
+
|
57
|
+
it "adds the Syphon logger" do
|
58
|
+
logger = Logger.new(logger)
|
59
|
+
Syphon.logger = logger
|
60
|
+
Syphon.elasticsearch_configuration[:logger].must_equal logger
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe ".logger" do
|
65
|
+
use_attribute_value Syphon, :configuration, nil
|
66
|
+
use_attribute_value Syphon, :logger, nil
|
67
|
+
use_temporary_directory "#{ROOT}/test/tmp"
|
68
|
+
|
69
|
+
it "uses the configured log path and log level" do
|
70
|
+
Syphon.configuration[:log] = "#{tmp}/syphon.log"
|
71
|
+
Syphon.configuration[:log_level] = 'info'
|
72
|
+
Syphon.logger.debug 'DEBUG LEVEL'
|
73
|
+
Syphon.logger.info 'INFO LEVEL'
|
74
|
+
File.read("#{ROOT}/test/tmp/syphon.log").wont_include 'DEBUG LEVEL'
|
75
|
+
File.read("#{ROOT}/test/tmp/syphon.log").must_include 'INFO LEVEL'
|
26
76
|
end
|
27
77
|
end
|
28
78
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: syphon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-12-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: elasticsearch
|
@@ -100,6 +100,7 @@ files:
|
|
100
100
|
- test/config.yml.sample
|
101
101
|
- test/syphon/test_builder.rb
|
102
102
|
- test/syphon/test_index.rb
|
103
|
+
- test/syphon/test_railtie.rb
|
103
104
|
- test/syphon/test_schema.rb
|
104
105
|
- test/syphon/test_source.rb
|
105
106
|
- test/test_helper.rb
|
@@ -118,7 +119,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
118
119
|
version: '0'
|
119
120
|
segments:
|
120
121
|
- 0
|
121
|
-
hash: -
|
122
|
+
hash: -2157484304572429612
|
122
123
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
124
|
none: false
|
124
125
|
requirements:
|
@@ -127,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
128
|
version: '0'
|
128
129
|
segments:
|
129
130
|
- 0
|
130
|
-
hash: -
|
131
|
+
hash: -2157484304572429612
|
131
132
|
requirements: []
|
132
133
|
rubyforge_project:
|
133
134
|
rubygems_version: 1.8.25
|
@@ -138,6 +139,7 @@ test_files:
|
|
138
139
|
- test/config.yml.sample
|
139
140
|
- test/syphon/test_builder.rb
|
140
141
|
- test/syphon/test_index.rb
|
142
|
+
- test/syphon/test_railtie.rb
|
141
143
|
- test/syphon/test_schema.rb
|
142
144
|
- test/syphon/test_source.rb
|
143
145
|
- test/test_helper.rb
|