chef-solr 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +201 -0
- data/README.rdoc +7 -0
- data/Rakefile +67 -0
- data/VERSION +1 -0
- data/bin/chef-solr +27 -0
- data/bin/chef-solr-indexer +27 -0
- data/bin/chef-solr-rebuild +27 -0
- data/lib/chef/solr.rb +212 -0
- data/lib/chef/solr/application/indexer.rb +133 -0
- data/lib/chef/solr/application/rebuild.rb +93 -0
- data/lib/chef/solr/application/solr.rb +165 -0
- data/lib/chef/solr/index.rb +153 -0
- data/lib/chef/solr/index_queue_consumer.rb +78 -0
- data/lib/chef/solr/query.rb +87 -0
- data/solr/solr-home.tar.gz +0 -0
- data/solr/solr-jetty.tar.gz +0 -0
- data/spec/chef/solr/index_spec.rb +168 -0
- data/spec/chef/solr/query_spec.rb +14 -0
- data/spec/chef/solr_spec.rb +174 -0
- data/spec/spec_helper.rb +14 -0
- metadata +125 -0
@@ -0,0 +1,133 @@
|
|
1
|
+
#
|
2
|
+
# Author:: AJ Christensen (<aj@opscode.com)
|
3
|
+
# Copyright:: Copyright (c) 2008 Opscode, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
|
18
|
+
require 'chef'
|
19
|
+
require 'chef/log'
|
20
|
+
require 'chef/config'
|
21
|
+
require 'chef/application'
|
22
|
+
require 'chef/solr'
|
23
|
+
require 'chef/solr/index'
|
24
|
+
require 'chef/solr/index_queue_consumer'
|
25
|
+
require 'chef/daemon'
|
26
|
+
require 'chef/webui_user'
|
27
|
+
|
28
|
+
class Chef
|
29
|
+
class Solr
|
30
|
+
class Application
|
31
|
+
class Indexer < Chef::Application
|
32
|
+
|
33
|
+
option :config_file,
|
34
|
+
:short => "-c CONFIG",
|
35
|
+
:long => "--config CONFIG",
|
36
|
+
:default => "/etc/chef/solr.rb",
|
37
|
+
:description => "The configuration file to use"
|
38
|
+
|
39
|
+
option :log_level,
|
40
|
+
:short => "-l LEVEL",
|
41
|
+
:long => "--log_level LEVEL",
|
42
|
+
:description => "Set the log level (debug, info, warn, error, fatal)",
|
43
|
+
:proc => lambda { |l| l.to_sym }
|
44
|
+
|
45
|
+
option :log_location,
|
46
|
+
:short => "-L LOGLOCATION",
|
47
|
+
:long => "--logfile LOGLOCATION",
|
48
|
+
:description => "Set the log file location, defaults to STDOUT - recommended for daemonizing",
|
49
|
+
:proc => nil
|
50
|
+
|
51
|
+
option :help,
|
52
|
+
:short => "-h",
|
53
|
+
:long => "--help",
|
54
|
+
:description => "Show this message",
|
55
|
+
:on => :tail,
|
56
|
+
:boolean => true,
|
57
|
+
:show_options => true,
|
58
|
+
:exit => 0
|
59
|
+
|
60
|
+
option :user,
|
61
|
+
:short => "-u USER",
|
62
|
+
:long => "--user USER",
|
63
|
+
:description => "User to set privilege to",
|
64
|
+
:proc => nil
|
65
|
+
|
66
|
+
option :group,
|
67
|
+
:short => "-g GROUP",
|
68
|
+
:long => "--group GROUP",
|
69
|
+
:description => "Group to set privilege to",
|
70
|
+
:proc => nil
|
71
|
+
|
72
|
+
option :daemonize,
|
73
|
+
:short => "-d",
|
74
|
+
:long => "--daemonize",
|
75
|
+
:description => "Daemonize the process",
|
76
|
+
:proc => lambda { |p| true }
|
77
|
+
|
78
|
+
option :amqp_host,
|
79
|
+
:long => "--amqp-host HOST",
|
80
|
+
:description => "The amqp host"
|
81
|
+
|
82
|
+
option :amqp_port,
|
83
|
+
:long => "--amqp-port PORT",
|
84
|
+
:description => "The amqp port"
|
85
|
+
|
86
|
+
option :amqp_user,
|
87
|
+
:long => "--amqp-user USER",
|
88
|
+
:description => "The amqp user"
|
89
|
+
|
90
|
+
option :amqp_pass,
|
91
|
+
:long => "--amqp-pass PASS",
|
92
|
+
:description => "The amqp password"
|
93
|
+
|
94
|
+
option :amqp_vhost,
|
95
|
+
:long => "--amqp-vhost VHOST",
|
96
|
+
:description => "The amqp vhost"
|
97
|
+
|
98
|
+
Signal.trap("INT") do
|
99
|
+
begin
|
100
|
+
AmqpClient.instance.stop
|
101
|
+
rescue Bunny::ProtocolError, Bunny::ConnectionError, Bunny::UnsubscribeError
|
102
|
+
end
|
103
|
+
fatal!("SIGINT received, stopping", 2)
|
104
|
+
end
|
105
|
+
|
106
|
+
Kernel.trap("TERM") do
|
107
|
+
begin
|
108
|
+
AmqpClient.instance.stop
|
109
|
+
rescue Bunny::ProtocolError, Bunny::ConnectionError, Bunny::UnsubscribeError
|
110
|
+
end
|
111
|
+
fatal!("SIGTERM received, stopping", 1)
|
112
|
+
end
|
113
|
+
|
114
|
+
def initialize
|
115
|
+
super
|
116
|
+
|
117
|
+
@index = Chef::Solr::Index.new
|
118
|
+
@consumer = Chef::Solr::IndexQueueConsumer.new
|
119
|
+
end
|
120
|
+
|
121
|
+
def setup_application
|
122
|
+
Chef::Daemon.change_privilege
|
123
|
+
Chef::Log.level = Chef::Config[:log_level]
|
124
|
+
end
|
125
|
+
|
126
|
+
def run_application
|
127
|
+
Chef::Daemon.daemonize("chef-solr-indexer") if Chef::Config[:daemonize]
|
128
|
+
@consumer.start
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
#
|
2
|
+
# Author:: AJ Christensen (<aj@opscode.com)
|
3
|
+
# Copyright:: Copyright (c) 2008 Opscode, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
|
18
|
+
require 'chef'
|
19
|
+
require 'chef/log'
|
20
|
+
require 'chef/config'
|
21
|
+
require 'chef/application'
|
22
|
+
require 'chef/solr'
|
23
|
+
require 'chef/solr/index'
|
24
|
+
|
25
|
+
class Chef
|
26
|
+
class Solr
|
27
|
+
class Application
|
28
|
+
class Rebuild < Chef::Application
|
29
|
+
|
30
|
+
option :config_file,
|
31
|
+
:short => "-c CONFIG",
|
32
|
+
:long => "--config CONFIG",
|
33
|
+
:default => "/etc/chef/solr.rb",
|
34
|
+
:description => "The configuration file to use"
|
35
|
+
|
36
|
+
option :log_level,
|
37
|
+
:short => "-l LEVEL",
|
38
|
+
:long => "--log_level LEVEL",
|
39
|
+
:description => "Set the log level (debug, info, warn, error, fatal)",
|
40
|
+
:proc => lambda { |l| l.to_sym }
|
41
|
+
|
42
|
+
option :log_location,
|
43
|
+
:short => "-L LOGLOCATION",
|
44
|
+
:long => "--logfile LOGLOCATION",
|
45
|
+
:description => "Set the log file location, defaults to STDOUT - recommended for daemonizing",
|
46
|
+
:proc => nil
|
47
|
+
|
48
|
+
option :help,
|
49
|
+
:short => "-h",
|
50
|
+
:long => "--help",
|
51
|
+
:description => "Show this message",
|
52
|
+
:on => :tail,
|
53
|
+
:boolean => true,
|
54
|
+
:show_options => true,
|
55
|
+
:exit => 0
|
56
|
+
|
57
|
+
option :couchdb_database,
|
58
|
+
:short => "-d DB",
|
59
|
+
:long => "--couchdb-database DB",
|
60
|
+
:description => "The CouchDB Database to re-index"
|
61
|
+
|
62
|
+
option :couchdb_url,
|
63
|
+
:short => "-u URL",
|
64
|
+
:long => "--couchdb-url URL",
|
65
|
+
:description => "The CouchDB URL"
|
66
|
+
|
67
|
+
def initialize
|
68
|
+
super
|
69
|
+
|
70
|
+
@index = Chef::Solr::Index.new
|
71
|
+
end
|
72
|
+
|
73
|
+
def setup_application
|
74
|
+
Chef::Log.level = Chef::Config[:log_level]
|
75
|
+
Chef::Log.warn("This operation is destructive!")
|
76
|
+
Chef::Log.warn("I'm going to count to 10, and then delete your Solr index and rebuild it.")
|
77
|
+
Chef::Log.warn("CTRL-C will, of course, stop this disaster.")
|
78
|
+
0.upto(10) do |num|
|
79
|
+
Chef::Log.warn("... #{num}")
|
80
|
+
sleep 1
|
81
|
+
end
|
82
|
+
Chef::Log.warn("... Bombs away!")
|
83
|
+
end
|
84
|
+
|
85
|
+
def run_application
|
86
|
+
s = Chef::Solr.new(Chef::Config[:solr_url])
|
87
|
+
Chef::Log.info("Destroying the index")
|
88
|
+
s.rebuild_index
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
#
|
2
|
+
# Author:: AJ Christensen (<aj@opscode.com)
|
3
|
+
# Copyright:: Copyright (c) 2008 Opscode, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
|
18
|
+
require 'chef'
|
19
|
+
require 'chef/log'
|
20
|
+
require 'chef/config'
|
21
|
+
require 'chef/application'
|
22
|
+
require 'chef/daemon'
|
23
|
+
require 'chef/client'
|
24
|
+
|
25
|
+
class Chef
|
26
|
+
class Solr
|
27
|
+
class Application
|
28
|
+
class Solr < Chef::Application
|
29
|
+
|
30
|
+
option :config_file,
|
31
|
+
:short => "-c CONFIG",
|
32
|
+
:long => "--config CONFIG",
|
33
|
+
:default => "/etc/chef/solr.rb",
|
34
|
+
:description => "The configuration file to use"
|
35
|
+
|
36
|
+
option :log_level,
|
37
|
+
:short => "-l LEVEL",
|
38
|
+
:long => "--log_level LEVEL",
|
39
|
+
:description => "Set the log level (debug, info, warn, error, fatal)",
|
40
|
+
:proc => lambda { |l| l.to_sym }
|
41
|
+
|
42
|
+
option :log_location,
|
43
|
+
:short => "-L LOGLOCATION",
|
44
|
+
:long => "--logfile LOGLOCATION",
|
45
|
+
:description => "Set the log file location, defaults to STDOUT - recommended for daemonizing",
|
46
|
+
:proc => nil
|
47
|
+
|
48
|
+
option :help,
|
49
|
+
:short => "-h",
|
50
|
+
:long => "--help",
|
51
|
+
:description => "Show this message",
|
52
|
+
:on => :tail,
|
53
|
+
:boolean => true,
|
54
|
+
:show_options => true,
|
55
|
+
:exit => 0
|
56
|
+
|
57
|
+
option :user,
|
58
|
+
:short => "-u USER",
|
59
|
+
:long => "--user USER",
|
60
|
+
:description => "User to set privilege to",
|
61
|
+
:proc => nil
|
62
|
+
|
63
|
+
option :group,
|
64
|
+
:short => "-g GROUP",
|
65
|
+
:long => "--group GROUP",
|
66
|
+
:description => "Group to set privilege to",
|
67
|
+
:proc => nil
|
68
|
+
|
69
|
+
option :daemonize,
|
70
|
+
:short => "-d",
|
71
|
+
:long => "--daemonize",
|
72
|
+
:description => "Daemonize the process",
|
73
|
+
:proc => lambda { |p| true }
|
74
|
+
|
75
|
+
option :solr_jetty_path,
|
76
|
+
:short => "-W PATH",
|
77
|
+
:long => "--solr-jetty-dir PATH",
|
78
|
+
:description => "Where to place the Solr Jetty instance"
|
79
|
+
|
80
|
+
option :solr_data_path,
|
81
|
+
:short => "-D PATH",
|
82
|
+
:long => "--solr-data-dir PATH",
|
83
|
+
:description => "Where the Solr data lives"
|
84
|
+
|
85
|
+
option :solr_home_path,
|
86
|
+
:short => "-H PATH",
|
87
|
+
:long => "--solr-home-dir PATH",
|
88
|
+
:description => "Solr home directory"
|
89
|
+
|
90
|
+
option :solr_heap_size,
|
91
|
+
:short => "-x SIZE",
|
92
|
+
:long => "--solor-heap-size SIZE",
|
93
|
+
:description => "Set the size of the Java Heap"
|
94
|
+
|
95
|
+
option :solr_java_opts,
|
96
|
+
:short => "-j OPTS",
|
97
|
+
:long => "--java-opts OPTS",
|
98
|
+
:description => "Raw options passed to Java"
|
99
|
+
|
100
|
+
def initialize
|
101
|
+
super
|
102
|
+
Chef::Log.level = Chef::Config[:log_level]
|
103
|
+
end
|
104
|
+
|
105
|
+
def setup_application
|
106
|
+
Chef::Daemon.change_privilege
|
107
|
+
|
108
|
+
# Build up a client
|
109
|
+
c = Chef::Client.new
|
110
|
+
c.build_node(nil, true)
|
111
|
+
|
112
|
+
solr_base = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "..", "solr"))
|
113
|
+
|
114
|
+
# Create the Jetty container
|
115
|
+
unless File.directory?(Chef::Config[:solr_jetty_path])
|
116
|
+
Chef::Log.warn("Initializing the Jetty container")
|
117
|
+
solr_jetty_dir = Chef::Resource::Directory.new(Chef::Config[:solr_jetty_path], nil, c.node)
|
118
|
+
solr_jetty_dir.recursive(true)
|
119
|
+
solr_jetty_dir.run_action(:create)
|
120
|
+
solr_jetty_untar = Chef::Resource::Execute.new("untar_jetty", nil, c.node)
|
121
|
+
solr_jetty_untar.command("tar zxvf #{File.join(solr_base, 'solr-jetty.tar.gz')}")
|
122
|
+
solr_jetty_untar.cwd(Chef::Config[:solr_jetty_path])
|
123
|
+
solr_jetty_untar.run_action(:run)
|
124
|
+
end
|
125
|
+
|
126
|
+
# Create the solr home
|
127
|
+
unless File.directory?(Chef::Config[:solr_home_path])
|
128
|
+
Chef::Log.warn("Initializing Solr home directory")
|
129
|
+
solr_home_dir = Chef::Resource::Directory.new(Chef::Config[:solr_home_path], nil, c.node)
|
130
|
+
solr_home_dir.recursive(true)
|
131
|
+
solr_home_dir.run_action(:create)
|
132
|
+
solr_jetty_untar = Chef::Resource::Execute.new("untar_solr_home", nil, c.node)
|
133
|
+
solr_jetty_untar.command("tar zxvf #{File.join(solr_base, 'solr-home.tar.gz')}")
|
134
|
+
solr_jetty_untar.cwd(Chef::Config[:solr_home_path])
|
135
|
+
solr_jetty_untar.run_action(:run)
|
136
|
+
end
|
137
|
+
|
138
|
+
# Create the solr data path
|
139
|
+
unless File.directory?(Chef::Config[:solr_data_path])
|
140
|
+
Chef::Log.warn("Initializing Solr data directory")
|
141
|
+
solr_data_dir = Chef::Resource::Directory.new(Chef::Config[:solr_data_path], nil, c.node)
|
142
|
+
solr_data_dir.recursive(true)
|
143
|
+
solr_data_dir.run_action(:create)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def run_application
|
148
|
+
if Chef::Config[:daemonize]
|
149
|
+
Chef::Daemon.daemonize("chef-solr")
|
150
|
+
end
|
151
|
+
Dir.chdir(Chef::Config[:solr_jetty_path]) do
|
152
|
+
command = "java -Xmx#{Chef::Config[:solr_heap_size]} -Xms#{Chef::Config[:solr_heap_size]}"
|
153
|
+
command << " -Dsolr.data.dir=#{Chef::Config[:solr_data_path]}"
|
154
|
+
command << " -Dsolr.solr.home=#{Chef::Config[:solr_home_path]}"
|
155
|
+
command << " #{Chef::Config[:solr_java_opts]}" if Chef::Config[:solr_java_opts]
|
156
|
+
command << " -jar #{File.join(Chef::Config[:solr_jetty_path], 'start.jar')}"
|
157
|
+
Chef::Log.info("Starting Solr with #{command}")
|
158
|
+
Kernel.exec(command)
|
159
|
+
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Adam Jacob (<adam@opscode.com>)
|
3
|
+
# Copyright:: Copyright (c) 2009 Opscode, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'chef/log'
|
20
|
+
require 'chef/config'
|
21
|
+
require 'chef/solr'
|
22
|
+
require 'libxml'
|
23
|
+
require 'net/http'
|
24
|
+
|
25
|
+
class Chef
|
26
|
+
class Solr
|
27
|
+
class Index < Solr
|
28
|
+
|
29
|
+
def add(id, database, type, item)
|
30
|
+
raise ArgumentError, "Object must respond to keys!" unless item.respond_to?(:keys)
|
31
|
+
to_index = flatten_and_expand(item)
|
32
|
+
to_index["X_CHEF_id_CHEF_X"] = id
|
33
|
+
to_index["X_CHEF_database_CHEF_X"] = database
|
34
|
+
to_index["X_CHEF_type_CHEF_X"] = type
|
35
|
+
solr_add(to_index)
|
36
|
+
to_index
|
37
|
+
end
|
38
|
+
|
39
|
+
def delete(id)
|
40
|
+
solr_delete_by_id(id)
|
41
|
+
end
|
42
|
+
|
43
|
+
def delete_by_query(query)
|
44
|
+
solr_delete_by_query(query)
|
45
|
+
end
|
46
|
+
|
47
|
+
def flatten_and_expand(item, fields=Hash.new, parent=nil)
|
48
|
+
item.keys.each do |key|
|
49
|
+
# If we have a parent, we want to add the current key as a value
|
50
|
+
if parent
|
51
|
+
# foo_bar = bar
|
52
|
+
set_field_value(fields, parent, key)
|
53
|
+
# foo_X = bar, etc.
|
54
|
+
make_expando_fields(parent).each do |ex_key|
|
55
|
+
set_field_value(fields, ex_key, key)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
case item[key]
|
59
|
+
when Hash
|
60
|
+
parent_key = parent ? "#{parent}_#{key}" : key
|
61
|
+
flatten_and_expand(item[key], fields, parent_key)
|
62
|
+
else
|
63
|
+
parent_key = parent ? "#{parent}_#{key}" : key
|
64
|
+
set_field_value(fields, key, item[key])
|
65
|
+
set_field_value(fields, parent_key, item[key]) if parent
|
66
|
+
make_expando_fields(parent_key).each do |ex_key|
|
67
|
+
set_field_value(fields, ex_key, item[key])
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
fields
|
72
|
+
end
|
73
|
+
|
74
|
+
def make_expando_fields(key)
|
75
|
+
key = key.to_s
|
76
|
+
fields = Array.new
|
77
|
+
parts = key.split("_")
|
78
|
+
length = parts.length
|
79
|
+
parts.each_index do |i|
|
80
|
+
beginning = nil
|
81
|
+
remainder = nil
|
82
|
+
if i == 0
|
83
|
+
beginning = "X"
|
84
|
+
else
|
85
|
+
beginning = parts[0..i-1].join("_")
|
86
|
+
end
|
87
|
+
|
88
|
+
if i == length-1
|
89
|
+
remainder = "X"
|
90
|
+
else
|
91
|
+
remainder = parts[i+1..-1].join("_")
|
92
|
+
end
|
93
|
+
|
94
|
+
if beginning == "X" || remainder == "X"
|
95
|
+
unless beginning == "X" && remainder == "X"
|
96
|
+
fields << "#{beginning}_#{remainder}"
|
97
|
+
end
|
98
|
+
else
|
99
|
+
fields << "#{beginning}_X_#{remainder}"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
fields
|
103
|
+
end
|
104
|
+
|
105
|
+
def set_field_value(fields, key, value)
|
106
|
+
key = key.to_s
|
107
|
+
if fields.has_key?(key)
|
108
|
+
convert_field_to_array(fields, key, value) unless fields[key].kind_of?(Array)
|
109
|
+
add_value_to_field_array(fields, key, value)
|
110
|
+
else
|
111
|
+
check_value(value)
|
112
|
+
if value.kind_of?(Array)
|
113
|
+
fields[key] = Array.new
|
114
|
+
value.each do |v|
|
115
|
+
fields[key] << v.to_s
|
116
|
+
end
|
117
|
+
else
|
118
|
+
fields[key] = value.to_s
|
119
|
+
end
|
120
|
+
end
|
121
|
+
fields
|
122
|
+
end
|
123
|
+
|
124
|
+
def add_value_to_field_array(fields, key, value)
|
125
|
+
check_value(value)
|
126
|
+
if value.kind_of?(Array)
|
127
|
+
value.each do |v|
|
128
|
+
check_value(v)
|
129
|
+
fields[key] << v.to_s unless fields[key].include?(v.to_s)
|
130
|
+
end
|
131
|
+
else
|
132
|
+
fields[key] << value.to_s unless fields[key].include?(value.to_s)
|
133
|
+
end
|
134
|
+
fields
|
135
|
+
end
|
136
|
+
|
137
|
+
def convert_field_to_array(fields, key, value)
|
138
|
+
if fields[key] != value
|
139
|
+
safe = fields[key]
|
140
|
+
fields[key] = [ safe ]
|
141
|
+
end
|
142
|
+
fields
|
143
|
+
end
|
144
|
+
|
145
|
+
def check_value(value)
|
146
|
+
raise ArgumentError, "Value must not be a type of hash!" if value.kind_of?(Hash)
|
147
|
+
value
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|