marklogic 0.0.1 → 0.0.3
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.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/Rakefile +20 -0
- data/lib/marklogic.rb +2 -0
- data/lib/marklogic/app_server.rb +25 -0
- data/lib/marklogic/application.rb +76 -6
- data/lib/marklogic/collection.rb +13 -1
- data/lib/marklogic/connection.rb +83 -61
- data/lib/marklogic/cursor.rb +3 -3
- data/lib/marklogic/database.rb +31 -3
- data/lib/marklogic/exceptions.rb +1 -0
- data/lib/marklogic/forest.rb +16 -0
- data/lib/marklogic/persistence.rb +19 -0
- data/lib/marklogic/version.rb +1 -1
- data/marklogic.gemspec +2 -0
- data/spec/marklogic/app_server_spec.rb +10 -0
- data/spec/marklogic/application_spec.rb +14 -0
- data/spec/marklogic/connection_spec.rb +8 -0
- metadata +43 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a18a7c658e56f1ad3d394de8120246955b35c90d
|
4
|
+
data.tar.gz: 5380d8f65f962dec8c958be996194ece2724e35e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 465d4b95d2cb7b89f62b29e9462d4f44f029fc45d2a73132b117aa1bbf326d9e05bb11094cc7701c073a22fa6ff05628655c0dec7fa6751c08fcd654837b9424
|
7
|
+
data.tar.gz: 01c5b4435cc0f35ed3d6c1a0e93f159b4b7c41f3ecac97d75f5db111783c0363025ddb6f0bddf48a6be0b3c6afb5ad51ffcd25fcdf3c583e79a69f49ebf5e9ec
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.2.
|
1
|
+
2.2.2
|
data/Rakefile
CHANGED
@@ -1,6 +1,26 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
|
3
3
|
require 'rspec/core/rake_task'
|
4
|
+
require File.expand_path('../lib/marklogic/version', __FILE__)
|
5
|
+
|
4
6
|
RSpec::Core::RakeTask.new
|
5
7
|
|
6
8
|
task :default => :spec
|
9
|
+
|
10
|
+
desc 'Builds the gem'
|
11
|
+
task :build do
|
12
|
+
sh "gem build marklogic.gemspec"
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Builds and installs the gem'
|
16
|
+
task :install => :build do
|
17
|
+
sh "gem install marklogic-#{MarkLogic::Version}"
|
18
|
+
end
|
19
|
+
|
20
|
+
desc 'Tags version, pushes to remote, and pushes gem'
|
21
|
+
task :release => :build do
|
22
|
+
sh "git tag v#{MarkMapper::Version}"
|
23
|
+
sh "git push origin master"
|
24
|
+
sh "git push origin v#{MarkLogic::Version}"
|
25
|
+
sh "gem push marklogic-#{MarkLogic::Version}.gem"
|
26
|
+
end
|
data/lib/marklogic.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'oj'
|
1
2
|
require 'active_support'
|
2
3
|
require 'active_support/core_ext/object'
|
3
4
|
require 'active_support/core_ext/string/inflections'
|
@@ -6,6 +7,7 @@ require "marklogic/consts"
|
|
6
7
|
require 'marklogic/queries'
|
7
8
|
require 'marklogic/exceptions'
|
8
9
|
require 'marklogic/object_id'
|
10
|
+
require 'marklogic/multipart_parser'
|
9
11
|
|
10
12
|
module MarkLogic
|
11
13
|
autoload :Application, 'marklogic/application'
|
data/lib/marklogic/app_server.rb
CHANGED
@@ -26,6 +26,31 @@ module MarkLogic
|
|
26
26
|
}
|
27
27
|
end
|
28
28
|
|
29
|
+
def self.load(server_name, group_name = "Default")
|
30
|
+
app_server = AppServer.new(server_name, 0, 'http', group_name)
|
31
|
+
app_server.load
|
32
|
+
app_server
|
33
|
+
end
|
34
|
+
|
35
|
+
def load
|
36
|
+
resp = manage_connection.get(%Q{/manage/v2/servers/#{server_name}/properties?group-id=#{group_name}&format=json})
|
37
|
+
if resp.code.to_i == 200
|
38
|
+
options = Oj.load(resp.body)
|
39
|
+
options.each do |key, value|
|
40
|
+
self[key] = value
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def inspect
|
46
|
+
as_nice_string = [
|
47
|
+
"server_name: #{server_name}",
|
48
|
+
"server_type: #{server_type}",
|
49
|
+
"port: #{self['port']}"
|
50
|
+
].join(",")
|
51
|
+
"#<#{self.class}#{as_nice_string}>"
|
52
|
+
end
|
53
|
+
|
29
54
|
def []=(key, value)
|
30
55
|
@options[key] = value
|
31
56
|
end
|
@@ -2,7 +2,7 @@ module MarkLogic
|
|
2
2
|
class Application
|
3
3
|
include MarkLogic::Persistence
|
4
4
|
|
5
|
-
attr_accessor :app_name
|
5
|
+
attr_accessor :app_name, :port
|
6
6
|
|
7
7
|
def initialize(app_name, options = {})
|
8
8
|
@app_name = app_name
|
@@ -157,10 +157,16 @@ module MarkLogic
|
|
157
157
|
end
|
158
158
|
end
|
159
159
|
|
160
|
+
def modules_databases
|
161
|
+
app_servers.values.map do |app_server|
|
162
|
+
databases[app_server['modules-database']]
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
160
166
|
def database(name)
|
161
|
-
database = MarkLogic::Database.new(name)
|
167
|
+
database = MarkLogic::Database.new(name, self.connection)
|
162
168
|
yield(database) if block_given?
|
163
|
-
|
169
|
+
database.application = self
|
164
170
|
databases[name] = database
|
165
171
|
end
|
166
172
|
|
@@ -170,8 +176,73 @@ module MarkLogic
|
|
170
176
|
app_servers[name] = app_server
|
171
177
|
end
|
172
178
|
|
179
|
+
def inspect
|
180
|
+
as_nice_string = [
|
181
|
+
" app_name: #{app_name.inspect}",
|
182
|
+
" port: #{port.inspect}",
|
183
|
+
" app_servers: #{app_servers.values.each { |app_server| app_server.inspect }}"
|
184
|
+
].join(",")
|
185
|
+
"#<#{self.class}#{as_nice_string}>"
|
186
|
+
end
|
187
|
+
|
188
|
+
def self.load(app_name, options = {})
|
189
|
+
app = Application.new(app_name, options)
|
190
|
+
app.load
|
191
|
+
app
|
192
|
+
end
|
193
|
+
|
194
|
+
def load
|
195
|
+
app_servers[app_name] = MarkLogic::AppServer.load(app_name)
|
196
|
+
@port = app_servers[app_name]['port']
|
197
|
+
load_databases
|
198
|
+
build_indexes
|
199
|
+
end
|
200
|
+
|
173
201
|
private
|
174
202
|
|
203
|
+
def load_database(db_name)
|
204
|
+
db = MarkLogic::Database.load(db_name, self.connection)
|
205
|
+
db.application = self
|
206
|
+
databases[db_name] = db
|
207
|
+
|
208
|
+
db['forest'].each do |forest_name|
|
209
|
+
forests[forest_name] = MarkLogic::Forest.load(forest_name, nil, self.connection) unless forests.has_key?(forest_name)
|
210
|
+
forests[forest_name].database = db
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def load_databases
|
215
|
+
app_servers.each_value do |app_server|
|
216
|
+
db_name = app_server['content-database']
|
217
|
+
load_database(db_name) unless databases.has_key?(db_name)
|
218
|
+
|
219
|
+
modules_db_name = app_server['modules-database']
|
220
|
+
load_database(modules_db_name) unless databases.has_key?(modules_db_name)
|
221
|
+
end
|
222
|
+
|
223
|
+
triggers_database = nil
|
224
|
+
schema_database = nil
|
225
|
+
databases.each_value do |database|
|
226
|
+
if database.has_key?('triggers-database')
|
227
|
+
triggers_database = database['triggers-database']
|
228
|
+
end
|
229
|
+
|
230
|
+
if database.has_key?('schema-database')
|
231
|
+
schema_database = database['schema-database']
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
if triggers_database && !databases.has_key?(triggers_database)
|
236
|
+
load_database(triggers_database)
|
237
|
+
# databases[triggers_database] = MarkLogic::Database.new(triggers_database, self.connection)
|
238
|
+
end
|
239
|
+
|
240
|
+
if schema_database && !databases.has_key?(schema_database)
|
241
|
+
load_database(schema_database)
|
242
|
+
# databases[schema_database] = MarkLogic::Database.new(schema_database, self.connection)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
175
246
|
def indexes
|
176
247
|
@indexes ||= {}
|
177
248
|
end
|
@@ -213,7 +284,6 @@ module MarkLogic
|
|
213
284
|
schema_database = nil
|
214
285
|
databases.each_value do |database|
|
215
286
|
if database.has_key?('triggers-database')
|
216
|
-
logger.info "has triggers: [#{database['triggers-database']}]"
|
217
287
|
triggers_database = database['triggers-database']
|
218
288
|
end
|
219
289
|
|
@@ -222,11 +292,11 @@ module MarkLogic
|
|
222
292
|
end
|
223
293
|
end
|
224
294
|
|
225
|
-
if triggers_database
|
295
|
+
if triggers_database && !databases.has_key?(triggers_database)
|
226
296
|
databases[triggers_database] = MarkLogic::Database.new(triggers_database, self.connection)
|
227
297
|
end
|
228
298
|
|
229
|
-
if schema_database
|
299
|
+
if schema_database && !databases.has_key?(schema_database)
|
230
300
|
databases[schema_database] = MarkLogic::Database.new(schema_database, self.connection)
|
231
301
|
end
|
232
302
|
end
|
data/lib/marklogic/collection.rb
CHANGED
@@ -21,7 +21,7 @@ module MarkLogic
|
|
21
21
|
url = "/v1/documents?uri=#{gen_uri(id)}&format=json"
|
22
22
|
response = @database.connection.get(url)
|
23
23
|
raise Exception.new("Invalid response: #{response.code.to_i}, #{response.body}") unless response.code.to_i == 200
|
24
|
-
|
24
|
+
Oj.load(response.body)
|
25
25
|
end
|
26
26
|
|
27
27
|
def save(doc)
|
@@ -217,6 +217,18 @@ module MarkLogic
|
|
217
217
|
end
|
218
218
|
end
|
219
219
|
|
220
|
+
def to_s
|
221
|
+
%Q{collection: #{collection}}
|
222
|
+
end
|
223
|
+
|
224
|
+
def inspect
|
225
|
+
as_nice_string = [
|
226
|
+
" collection: #{collection.inspect}",
|
227
|
+
" database: #{database.database_name.inspect}"
|
228
|
+
].join(",")
|
229
|
+
"#<#{self.class}#{as_nice_string}>"
|
230
|
+
end
|
231
|
+
|
220
232
|
private
|
221
233
|
|
222
234
|
def doc_uri(doc)
|
data/lib/marklogic/connection.rb
CHANGED
@@ -2,6 +2,7 @@ require 'net/http'
|
|
2
2
|
require 'date'
|
3
3
|
require 'json'
|
4
4
|
require 'digest'
|
5
|
+
require 'net/http/persistent'
|
5
6
|
|
6
7
|
module Net
|
7
8
|
module HTTPHeader
|
@@ -54,6 +55,11 @@ module Net
|
|
54
55
|
|
55
56
|
@header['Authorization'] = ["Basic #{encoded}"]
|
56
57
|
end
|
58
|
+
|
59
|
+
# diable header capitalization for a performance gain
|
60
|
+
def capitalize(name)
|
61
|
+
name
|
62
|
+
end
|
57
63
|
end
|
58
64
|
end
|
59
65
|
|
@@ -61,6 +67,14 @@ module MarkLogic
|
|
61
67
|
class Connection
|
62
68
|
include MarkLogic::Loggable
|
63
69
|
|
70
|
+
NEWLINE_SPLITTER = Regexp.new("\r\n", Regexp::MULTILINE)
|
71
|
+
DOUBLE_NEWLINE_SPLITTER = Regexp.new("\r\n\r\n", Regexp::MULTILINE)
|
72
|
+
START_BOUNDARY_REGEX = Regexp.new("^[\r\n]+--[^-].+?[\r\n]+", Regexp::MULTILINE)
|
73
|
+
END_BOUNDARY_REGEX = Regexp.new("[\r\n]+--[^-]+--[\r\n]+$", Regexp::MULTILINE)
|
74
|
+
BOUNDARY_SPLITTER_REGEX = Regexp.new(%Q{[\r\n]+--[^-]+[\r\n]+}, Regexp::MULTILINE)
|
75
|
+
CONTENT_TYPE_REGEX = /Content-Type:\s+(.*)$/
|
76
|
+
PRIMITIVE_REGEX = /X-Primitive:\s+(.*)$/
|
77
|
+
|
64
78
|
attr_accessor :admin, :manage, :app_services, :username, :password, :host, :port, :request_retries
|
65
79
|
|
66
80
|
def self.configure(options = {})
|
@@ -118,15 +132,19 @@ module MarkLogic
|
|
118
132
|
@username = username || self.class.default_user
|
119
133
|
@password = password || self.class.default_password
|
120
134
|
@request_retries = options[:request_retries] || 3
|
121
|
-
@http = Net::HTTP.new
|
135
|
+
@http = Net::HTTP::Persistent.new 'marklogic'
|
122
136
|
end
|
123
137
|
|
124
138
|
def run_query(query, type = "javascript", options = {})
|
125
|
-
params
|
126
|
-
|
139
|
+
# manually building the params yielded a performance improvement
|
140
|
+
params = %Q{#{type}=#{URI.encode_www_form_component(query)}}
|
141
|
+
params += %Q{&dbname=#{options[:db]}} if options[:db]
|
142
|
+
|
143
|
+
headers = {
|
144
|
+
'content-type' => 'application/x-www-form-urlencoded'
|
127
145
|
}
|
128
|
-
|
129
|
-
|
146
|
+
response = request('/eval', 'post', headers, params)
|
147
|
+
|
130
148
|
# :xquery => options[:query],
|
131
149
|
# :locale => LOCALE,
|
132
150
|
# :tzoffset => "-18000",
|
@@ -164,14 +182,14 @@ module MarkLogic
|
|
164
182
|
end
|
165
183
|
|
166
184
|
def wait_for_restart(body)
|
167
|
-
json =
|
185
|
+
json = Oj.load(body)
|
168
186
|
ts_value = json["restart"]["last-startup"][0]["value"]
|
169
187
|
timestamp = DateTime.iso8601(ts_value).to_time
|
170
188
|
new_timestamp = timestamp
|
171
189
|
|
172
190
|
code = nil
|
173
191
|
logger.debug "Waiting for restart"
|
174
|
-
until code == 200
|
192
|
+
until code == 200 && new_timestamp > timestamp
|
175
193
|
begin
|
176
194
|
rr = get(%Q{/admin/v1/timestamp})
|
177
195
|
code = rr.code.to_i
|
@@ -202,65 +220,61 @@ module MarkLogic
|
|
202
220
|
end
|
203
221
|
|
204
222
|
def split_multipart(response)
|
205
|
-
|
206
|
-
body = response.body
|
223
|
+
body = response.body
|
207
224
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
225
|
+
if body.nil? || body.length == 0
|
226
|
+
response.body = nil
|
227
|
+
return
|
228
|
+
end
|
229
|
+
|
230
|
+
content_type = response['Content-Type']
|
231
|
+
if (content_type && content_type.match(/multipart\/mixed.*/))
|
232
|
+
boundary = $1 if content_type =~ /^.*boundary=(.*)$/
|
212
233
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
if meta.match(/^Content-Type:.*/m)
|
230
|
-
value_content_type = $1 if meta =~ /Content-Type:\s+(.*)$/
|
231
|
-
elsif meta.match(/^X-Primitive:.*/)
|
232
|
-
type = $1 if meta =~ /X-Primitive:\s+(.*)$/
|
233
|
-
elsif meta.match(/^X-Path:.*/)
|
234
|
-
xpath = $1 if meta =~ /X-Path:\s+(.*)$/
|
235
|
-
end
|
234
|
+
body.sub!(END_BOUNDARY_REGEX, "")
|
235
|
+
body.sub!(START_BOUNDARY_REGEX, "")
|
236
|
+
|
237
|
+
values = []
|
238
|
+
body.split(BOUNDARY_SPLITTER_REGEX).each do |item|
|
239
|
+
splits = item.split(DOUBLE_NEWLINE_SPLITTER)
|
240
|
+
metas = splits[0]
|
241
|
+
raw_value = splits[1]
|
242
|
+
|
243
|
+
value_content_type = type = nil
|
244
|
+
|
245
|
+
metas.split(NEWLINE_SPLITTER).each do |meta|
|
246
|
+
if meta =~ CONTENT_TYPE_REGEX
|
247
|
+
value_content_type = $1
|
248
|
+
elsif meta =~ PRIMITIVE_REGEX
|
249
|
+
type = $1
|
236
250
|
end
|
251
|
+
end
|
237
252
|
|
238
|
-
|
239
|
-
|
253
|
+
if (value_content_type == "application/json") then
|
254
|
+
value = Oj.load(raw_value)
|
255
|
+
else
|
256
|
+
case type
|
257
|
+
when "integer"
|
258
|
+
value = raw_value.to_i
|
259
|
+
when "boolean"
|
260
|
+
value = raw_value == "true"
|
261
|
+
when "decimal"
|
262
|
+
value = raw_value.to_f
|
240
263
|
else
|
241
|
-
|
242
|
-
when "integer"
|
243
|
-
value = raw_value.to_i
|
244
|
-
when "boolean"
|
245
|
-
value = raw_value == "true"
|
246
|
-
when "decimal"
|
247
|
-
value = raw_value.to_f
|
248
|
-
else
|
249
|
-
value = raw_value
|
250
|
-
end
|
264
|
+
value = raw_value
|
251
265
|
end
|
252
|
-
values.push(value)
|
253
266
|
end
|
267
|
+
values.push(value)
|
268
|
+
end
|
254
269
|
|
255
|
-
|
256
|
-
|
257
|
-
end
|
258
|
-
output = values
|
259
|
-
else
|
260
|
-
output = body
|
270
|
+
if (values.length == 1)
|
271
|
+
values = values[0]
|
261
272
|
end
|
262
|
-
|
273
|
+
output = values
|
274
|
+
else
|
275
|
+
output = body
|
263
276
|
end
|
277
|
+
response.body = output
|
264
278
|
end
|
265
279
|
|
266
280
|
def request(url, verb = 'get', headers = {}, body = nil, params = nil)
|
@@ -281,12 +295,20 @@ module MarkLogic
|
|
281
295
|
request.digest_auth(@username, @password, @auth)
|
282
296
|
end
|
283
297
|
|
284
|
-
|
285
|
-
|
298
|
+
if params
|
299
|
+
# query = URI.encode_www_form(params)
|
300
|
+
# query.gsub!(/&/, sep) if sep != '&'
|
301
|
+
# self.body = query
|
302
|
+
# request['content-type'] = 'application/x-www-form-urlencoded'
|
303
|
+
request.set_form_data(params) if (params)
|
304
|
+
elsif body
|
305
|
+
request.body = body if (body)
|
306
|
+
end
|
286
307
|
|
287
|
-
|
308
|
+
full_url = URI("http://#{@host}:#{@port}#{url}")
|
309
|
+
response = @http.request full_url, request
|
288
310
|
|
289
|
-
if (response.code.to_i == 401
|
311
|
+
if (response.code.to_i == 401 && @username && @password)
|
290
312
|
auth_method = $1.downcase if response['www-authenticate'] =~ /^(\w+) (.*)/
|
291
313
|
if (auth_method == "basic")
|
292
314
|
request.basic_auth(@username, @password)
|
@@ -294,7 +316,7 @@ module MarkLogic
|
|
294
316
|
@auth = request.create_digest_auth(@username, @password, response)
|
295
317
|
end
|
296
318
|
|
297
|
-
response = @http.request request
|
319
|
+
response = @http.request full_url, request
|
298
320
|
end
|
299
321
|
|
300
322
|
# puts("#{response.code} : #{verb.upcase} => ://#{@host}:#{@port}#{url} :: #{body} #{params}")
|
data/lib/marklogic/cursor.rb
CHANGED
@@ -155,7 +155,7 @@ module MarkLogic
|
|
155
155
|
end
|
156
156
|
|
157
157
|
def has_sort?
|
158
|
-
@options.has_key?(:sort)
|
158
|
+
@options.has_key?(:sort) || @options.has_key?(:order)
|
159
159
|
end
|
160
160
|
|
161
161
|
def query
|
@@ -170,7 +170,7 @@ module MarkLogic
|
|
170
170
|
|
171
171
|
sorters.map do |sorter|
|
172
172
|
name = sorter[0].to_s
|
173
|
-
direction = (sorter[1]
|
173
|
+
direction = (sorter[1] && (sorter[1] == -1)) ? "descending" : "ascending"
|
174
174
|
|
175
175
|
|
176
176
|
if @collection.database.has_range_index?(name)
|
@@ -197,7 +197,7 @@ module MarkLogic
|
|
197
197
|
|
198
198
|
sorters.map do |sorter|
|
199
199
|
name = sorter[0].to_s
|
200
|
-
direction = (sorter[1]
|
200
|
+
direction = (sorter[1] && (sorter[1] == -1)) ? "descending" : "ascending"
|
201
201
|
|
202
202
|
unless @collection.database.has_range_index?(name)
|
203
203
|
raise MissingIndexError.new("Missing index on #{name}")
|
data/lib/marklogic/database.rb
CHANGED
@@ -31,6 +31,29 @@ module MarkLogic
|
|
31
31
|
reset_indexes
|
32
32
|
end
|
33
33
|
|
34
|
+
def self.load(database_name, conn = nil)
|
35
|
+
db = Database.new(database_name, conn)
|
36
|
+
db.load
|
37
|
+
db
|
38
|
+
end
|
39
|
+
|
40
|
+
def load
|
41
|
+
resp = manage_connection.get(%Q{/manage/v2/databases/#{database_name}/properties?format=json})
|
42
|
+
if resp.code.to_i == 200
|
43
|
+
options = Oj.load(resp.body)
|
44
|
+
options.each do |key, value|
|
45
|
+
self[key] = value
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def inspect
|
51
|
+
as_nice_string = @options.collect do |key, value|
|
52
|
+
" #{key}: #{value.inspect}"
|
53
|
+
end.sort.join(",")
|
54
|
+
"#<#{self.class}#{as_nice_string}>"
|
55
|
+
end
|
56
|
+
|
34
57
|
def []=(key, value)
|
35
58
|
@options[key] = value
|
36
59
|
end
|
@@ -121,7 +144,7 @@ module MarkLogic
|
|
121
144
|
response = manage_connection.get(%Q{/manage/v2/databases/#{database_name}/properties?format=json})
|
122
145
|
raise Exception.new("Invalid response: #{response.code.to_i}: #{response.body}") if (response.code.to_i != 200)
|
123
146
|
|
124
|
-
props =
|
147
|
+
props = Oj.load(response.body)
|
125
148
|
|
126
149
|
INDEX_KEYS.each do |key|
|
127
150
|
if props[key]
|
@@ -131,7 +154,7 @@ module MarkLogic
|
|
131
154
|
logger.debug "#{database_name}: #{local} != #{remote}"
|
132
155
|
return true
|
133
156
|
end
|
134
|
-
elsif @options.has_key?(key)
|
157
|
+
elsif @options.has_key?(key) && @options[key] != []
|
135
158
|
logger.debug "#{database_name}: #{key} is not on the remote end"
|
136
159
|
return true
|
137
160
|
end
|
@@ -199,7 +222,12 @@ module MarkLogic
|
|
199
222
|
end
|
200
223
|
|
201
224
|
def collections()
|
202
|
-
|
225
|
+
res = connection.run_query('cts:collections()', "xquery")
|
226
|
+
if res.code.to_i == 200
|
227
|
+
return res.body || []
|
228
|
+
else
|
229
|
+
raise MissingCollectionLexiconError.new if res.body =~ /XDMP-COLLXCNNOTFOUND/
|
230
|
+
end
|
203
231
|
end
|
204
232
|
end
|
205
233
|
end
|
data/lib/marklogic/exceptions.rb
CHANGED
data/lib/marklogic/forest.rb
CHANGED
@@ -13,6 +13,22 @@ module MarkLogic
|
|
13
13
|
}
|
14
14
|
end
|
15
15
|
|
16
|
+
def self.load(forest_name, host_name = nil, conn = nil)
|
17
|
+
db = Forest.new(forest_name, host_name, conn)
|
18
|
+
db.load
|
19
|
+
db
|
20
|
+
end
|
21
|
+
|
22
|
+
def load
|
23
|
+
resp = manage_connection.get(%Q{/manage/v2/forests/#{forest_name}/properties?format=json})
|
24
|
+
if resp.code.to_i == 200
|
25
|
+
options = Oj.load(resp.body)
|
26
|
+
options.each do |key, value|
|
27
|
+
self[key] = value
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
16
32
|
def []=(key, value)
|
17
33
|
@options[key] = value
|
18
34
|
end
|
@@ -1,6 +1,25 @@
|
|
1
1
|
module MarkLogic
|
2
2
|
module Persistence
|
3
3
|
include MarkLogic::Loggable
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
def manage_connection=(manage_conn)
|
8
|
+
@@manage_connection = manage_conn if manage_conn
|
9
|
+
end
|
10
|
+
|
11
|
+
def manage_connection
|
12
|
+
@@manage_connection ||= MarkLogic::Connection.manage_connection
|
13
|
+
end
|
14
|
+
|
15
|
+
def admin_connection=(admin_conn)
|
16
|
+
@@admin_connection = admin_conn if admin_conn
|
17
|
+
end
|
18
|
+
|
19
|
+
def admin_connection
|
20
|
+
@@admin_connection ||= MarkLogic::Connection.admin_connection
|
21
|
+
end
|
22
|
+
end
|
4
23
|
|
5
24
|
def connection=(conn)
|
6
25
|
@connection = conn if conn
|
data/lib/marklogic/version.rb
CHANGED
data/marklogic.gemspec
CHANGED
@@ -19,5 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
spec.has_rdoc = 'yard'
|
21
21
|
|
22
|
+
spec.add_runtime_dependency 'net-http-persistent', '~> 2.9', '>= 2.9.4'
|
23
|
+
spec.add_runtime_dependency 'oj', '~> 2.12', '>= 2.12.2'
|
22
24
|
spec.add_runtime_dependency 'activesupport', '~> 4.2', '>= 4.2.0'
|
23
25
|
end
|
@@ -18,4 +18,14 @@ describe MarkLogic::AppServer do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
end
|
21
|
+
|
22
|
+
describe "load" do
|
23
|
+
it "should load an existing config from the server" do
|
24
|
+
app = MarkLogic::AppServer.load('App-Services')
|
25
|
+
expect(app['server-name']).to eq('App-Services')
|
26
|
+
expect(app['content-database']).to eq('Documents')
|
27
|
+
expect(app['modules-database']).to eq('Modules')
|
28
|
+
expect(app['port']).to eq(8000)
|
29
|
+
end
|
30
|
+
end
|
21
31
|
end
|
@@ -102,4 +102,18 @@ describe MarkLogic::Application do
|
|
102
102
|
expect(@a).to be_stale
|
103
103
|
end
|
104
104
|
end
|
105
|
+
|
106
|
+
describe "load" do
|
107
|
+
it "should load from existing config" do
|
108
|
+
app = MarkLogic::Application.load('App-Services', connection: CONNECTION)
|
109
|
+
expect(app.port).to eq(8000)
|
110
|
+
expect(app.app_servers.count).to eq(1)
|
111
|
+
expect(app.app_servers['App-Services'].server_name).to eq('App-Services')
|
112
|
+
expect(app.content_databases.count).to eq(1)
|
113
|
+
expect(app.content_databases.first.database_name).to eq('Documents')
|
114
|
+
expect(app.content_databases.first['forest']).to eq(['Documents'])
|
115
|
+
expect(app.modules_databases.count).to eq(1)
|
116
|
+
expect(app.modules_databases.first.database_name).to eq('Modules')
|
117
|
+
end
|
118
|
+
end
|
105
119
|
end
|
@@ -104,6 +104,14 @@ describe MarkLogic::Connection do
|
|
104
104
|
it "should split properly when a crazy object is returned" do
|
105
105
|
expect(@b.run_query(%Q{x = { stuff: [1, 2, 3], junk: false}; x}).body).to eq({"stuff" => [1, 2, 3], "junk" => false})
|
106
106
|
end
|
107
|
+
|
108
|
+
it "should handle url unencoded stuff" do
|
109
|
+
expect(@b.run_query(%Q{
|
110
|
+
let $x := "Hi & stuff"
|
111
|
+
return
|
112
|
+
$x
|
113
|
+
}, 'xquery').body).to eq("Hi & stuff")
|
114
|
+
end
|
107
115
|
end
|
108
116
|
|
109
117
|
describe "#digest" do
|
metadata
CHANGED
@@ -1,15 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: marklogic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paxton Hare
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-04-
|
11
|
+
date: 2015-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: net-http-persistent
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.9'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.9.4
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.9'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 2.9.4
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: oj
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '2.12'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 2.12.2
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '2.12'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 2.12.2
|
13
53
|
- !ruby/object:Gem::Dependency
|
14
54
|
name: activesupport
|
15
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -145,7 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
145
185
|
version: '0'
|
146
186
|
requirements: []
|
147
187
|
rubyforge_project:
|
148
|
-
rubygems_version: 2.4.
|
188
|
+
rubygems_version: 2.4.6
|
149
189
|
signing_key:
|
150
190
|
specification_version: 4
|
151
191
|
summary: A Ruby Driver for MarkLogic
|