marklogic 0.0.1

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.
Files changed (90) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +10 -0
  3. data/.gitignore +15 -0
  4. data/.rspec +2 -0
  5. data/.ruby-gemset +1 -0
  6. data/.ruby-version +1 -0
  7. data/Gemfile +17 -0
  8. data/Guardfile +45 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +31 -0
  11. data/Rakefile +6 -0
  12. data/lib/marklogic.rb +21 -0
  13. data/lib/marklogic/app_server.rb +60 -0
  14. data/lib/marklogic/application.rb +244 -0
  15. data/lib/marklogic/collection.rb +265 -0
  16. data/lib/marklogic/connection.rb +308 -0
  17. data/lib/marklogic/consts.rb +35 -0
  18. data/lib/marklogic/cursor.rb +238 -0
  19. data/lib/marklogic/database.rb +205 -0
  20. data/lib/marklogic/database_settings.rb +13 -0
  21. data/lib/marklogic/database_settings/element_word_lexicon.rb +28 -0
  22. data/lib/marklogic/database_settings/geospatial_element_child_index.rb +41 -0
  23. data/lib/marklogic/database_settings/geospatial_element_index.rb +38 -0
  24. data/lib/marklogic/database_settings/geospatial_element_pair_index.rb +42 -0
  25. data/lib/marklogic/database_settings/geospatial_path_index.rb +37 -0
  26. data/lib/marklogic/database_settings/index.rb +27 -0
  27. data/lib/marklogic/database_settings/range_element_index.rb +77 -0
  28. data/lib/marklogic/database_settings/range_field_index.rb +37 -0
  29. data/lib/marklogic/database_settings/range_path_index.rb +37 -0
  30. data/lib/marklogic/exceptions.rb +5 -0
  31. data/lib/marklogic/forest.rb +47 -0
  32. data/lib/marklogic/loggable.rb +46 -0
  33. data/lib/marklogic/object_id.rb +46 -0
  34. data/lib/marklogic/persistence.rb +29 -0
  35. data/lib/marklogic/queries.rb +18 -0
  36. data/lib/marklogic/queries/and_not_query.rb +14 -0
  37. data/lib/marklogic/queries/and_query.rb +14 -0
  38. data/lib/marklogic/queries/base_query.rb +40 -0
  39. data/lib/marklogic/queries/boost_query.rb +14 -0
  40. data/lib/marklogic/queries/collection_query.rb +14 -0
  41. data/lib/marklogic/queries/container_query.rb +15 -0
  42. data/lib/marklogic/queries/directory_query.rb +20 -0
  43. data/lib/marklogic/queries/document_fragment_query.rb +13 -0
  44. data/lib/marklogic/queries/document_query.rb +14 -0
  45. data/lib/marklogic/queries/geospatial_query.rb +44 -0
  46. data/lib/marklogic/queries/locks_fragment_query.rb +13 -0
  47. data/lib/marklogic/queries/near_query.rb +31 -0
  48. data/lib/marklogic/queries/not_in_query.rb +14 -0
  49. data/lib/marklogic/queries/not_query.rb +13 -0
  50. data/lib/marklogic/queries/or_query.rb +24 -0
  51. data/lib/marklogic/queries/properties_fragment_query.rb +13 -0
  52. data/lib/marklogic/queries/range_query.rb +67 -0
  53. data/lib/marklogic/queries/value_query.rb +44 -0
  54. data/lib/marklogic/queries/word_query.rb +38 -0
  55. data/lib/marklogic/version.rb +3 -0
  56. data/marklogic.gemspec +23 -0
  57. data/spec/marklogic/app_server_spec.rb +21 -0
  58. data/spec/marklogic/application_spec.rb +105 -0
  59. data/spec/marklogic/collection_spec.rb +154 -0
  60. data/spec/marklogic/connection_spec.rb +128 -0
  61. data/spec/marklogic/cursor_spec.rb +219 -0
  62. data/spec/marklogic/database_settings/element_word_lexicon_spec.rb +21 -0
  63. data/spec/marklogic/database_settings/geospatial_element_child_index_spec.rb +26 -0
  64. data/spec/marklogic/database_settings/geospatial_element_index_spec.rb +24 -0
  65. data/spec/marklogic/database_settings/geospatial_element_pair_index_spec.rb +27 -0
  66. data/spec/marklogic/database_settings/geospatial_path_index_spec.rb +23 -0
  67. data/spec/marklogic/database_settings/range_element_index_spec.rb +34 -0
  68. data/spec/marklogic/database_settings/range_field_index_spec.rb +23 -0
  69. data/spec/marklogic/database_settings/range_path_index_spec.rb +23 -0
  70. data/spec/marklogic/database_spec.rb +108 -0
  71. data/spec/marklogic/forest_spec.rb +30 -0
  72. data/spec/marklogic/queries/and_not_query_spec.rb +13 -0
  73. data/spec/marklogic/queries/and_query_spec.rb +31 -0
  74. data/spec/marklogic/queries/boost_query_spec.rb +13 -0
  75. data/spec/marklogic/queries/collection_query_spec.rb +16 -0
  76. data/spec/marklogic/queries/container_query_spec.rb +11 -0
  77. data/spec/marklogic/queries/directory_query_spec.rb +21 -0
  78. data/spec/marklogic/queries/document_fragment_query_spec.rb +11 -0
  79. data/spec/marklogic/queries/document_query_spec.rb +16 -0
  80. data/spec/marklogic/queries/locks_fragement_query_spec.rb +11 -0
  81. data/spec/marklogic/queries/near_query_spec.rb +62 -0
  82. data/spec/marklogic/queries/not_in_query_spec.rb +13 -0
  83. data/spec/marklogic/queries/not_query_spec.rb +11 -0
  84. data/spec/marklogic/queries/or_query_spec.rb +32 -0
  85. data/spec/marklogic/queries/properties_fragment_query_spec.rb +11 -0
  86. data/spec/marklogic/queries/range_query_spec.rb +71 -0
  87. data/spec/marklogic/queries/value_query_spec.rb +68 -0
  88. data/spec/marklogic/queries/word_query_spec.rb +53 -0
  89. data/spec/spec_helper.rb +68 -0
  90. metadata +186 -0
@@ -0,0 +1,24 @@
1
+ module MarkLogic
2
+ module Queries
3
+ class OrQuery< BaseQuery
4
+ def initialize(*args)
5
+ @queries = args.flat_map{ |i| i }
6
+ end
7
+
8
+ def to_json
9
+ {
10
+ "or-query" => {
11
+ "queries" => @queries.map do |q|
12
+ q.to_json
13
+ end
14
+ }
15
+ }
16
+ end
17
+
18
+ def to_xqy
19
+ sub_queries = @queries.map { |q| q.to_xqy }.join(', ')
20
+ %Q{cts:or-query((#{sub_queries}))}
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,13 @@
1
+ module MarkLogic
2
+ module Queries
3
+ class PropertiesFragmentQuery< BaseQuery
4
+ def initialize(query)
5
+ @query = query
6
+ end
7
+
8
+ def to_xqy
9
+ %Q{cts:properties-fragment-query(#{@query.to_xqy})}
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,67 @@
1
+ module MarkLogic
2
+ module Queries
3
+ class RangeQuery < BaseQuery
4
+
5
+ attr_accessor :name, :range_type
6
+
7
+ def initialize(name, operator, range_type, value, options = {})
8
+ @name = name.to_s
9
+ @operator = operator.to_s.upcase
10
+ @range_type = range_type
11
+ @value = value
12
+ @options = options || {}
13
+ @weight = @options.delete(:weight) || 1.0
14
+ end
15
+
16
+ def operator=(op)
17
+ @operator = op
18
+ end
19
+
20
+ def operator
21
+ case @operator
22
+ when "LT"
23
+ "<"
24
+ when "LE"
25
+ "<="
26
+ when "GT"
27
+ ">"
28
+ when "GE"
29
+ ">="
30
+ when "EQ"
31
+ "="
32
+ when "NE"
33
+ "!="
34
+ else
35
+ @operator
36
+ end
37
+ end
38
+
39
+ def options=(opts)
40
+ @options = opts
41
+ end
42
+
43
+ def options
44
+ opts = []
45
+ @options.each do |k, v|
46
+ case k.to_s
47
+ when "collation", "min_occurs", "max_occurs", "score_function", "slope_factor"
48
+ opts << %Q{"#{k.to_s.gsub(/_/, '-')}=#{v}"}
49
+ when "cached"
50
+ opts << (v == true ? %Q{"cached"} : %Q{"uncached"})
51
+ when "synonym"
52
+ opts << %Q{"#{k}"}
53
+ else
54
+ opts << %Q{"#{v}"}
55
+ end
56
+ end
57
+
58
+ opts
59
+ end
60
+
61
+ def to_xqy
62
+ value = query_value(@value, @range_type)
63
+ %Q{cts:json-property-range-query("#{@name}","#{operator}",(#{value}),(#{options.join(',')}),#{@weight})}
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,44 @@
1
+ module MarkLogic
2
+ module Queries
3
+ class ValueQuery< BaseQuery
4
+ def initialize(name, value, options = {})
5
+ @name = name.to_s
6
+ @value = value
7
+ @value = value.to_s if value.is_a?(ObjectId)
8
+ @options = options || {}
9
+ @weight = @options.delete(:weight) || 1.0
10
+ @options[:exact] = true if @options.length == 0
11
+ end
12
+
13
+ def options=(opts)
14
+ @options = opts
15
+ end
16
+
17
+ def options
18
+ opts = []
19
+ @options.each do |k, v|
20
+ dashed_key = k.to_s.gsub(/_/, '-')
21
+ case k.to_s
22
+ when "lang", "min_occurs", "max_occurs"
23
+ opts << %Q{"#{dashed_key}=#{v}"}
24
+ when /(case|diacritic|punctuation|whitespace)_sensitive/
25
+ opts << (v == true ? %Q{"#{$1}-sensitive"} : %Q{"#{$1}-insensitive"})
26
+ when "exact"
27
+ opts << %Q{"#{dashed_key}"}
28
+ when "stemmed", "wildcarded"
29
+ opts << (v == true ? %Q{"#{dashed_key}"} : %Q{"un#{dashed_key}"})
30
+ else
31
+ opts << %Q{"#{v}"}
32
+ end
33
+ end
34
+
35
+ opts
36
+ end
37
+
38
+ def to_xqy
39
+ value = query_value(@value)
40
+ %Q{cts:json-property-value-query("#{@name}",(#{value}),(#{options.join(',')}),#{@weight})}
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,38 @@
1
+ module MarkLogic
2
+ module Queries
3
+ class WordQuery< BaseQuery
4
+ def initialize(values, options = {})
5
+ @values = values
6
+ @options = options || {}
7
+ @weight = @options.delete(:weight) || 1.0
8
+ @options[:exact] = true if @options.length == 0
9
+ end
10
+
11
+ def options
12
+ opts = []
13
+ @options.each do |k, v|
14
+ dashed_key = k.to_s.gsub(/_/, '-')
15
+ case k.to_s
16
+ when "lang", "distance_weight", "min_occurs", "max_occurs", "lexicon_expand"
17
+ opts << %Q{"#{dashed_key}=#{v}"}
18
+ when /(case|diacritic|punctuation|whitespace)_sensitive/
19
+ opts << (v == true ? %Q{"#{$1}-sensitive"} : %Q{"#{$1}-insensitive"})
20
+ when "exact"
21
+ opts << %Q{"#{dashed_key}"}
22
+ when "stemmed", "wildcarded"
23
+ opts << (v == true ? %Q{"#{dashed_key}"} : %Q{"un#{dashed_key}"})
24
+ else
25
+ opts << %Q{"#{v}"}
26
+ end
27
+ end
28
+
29
+ opts
30
+ end
31
+
32
+ def to_xqy
33
+ values = query_value(@values)
34
+ %Q{cts:word-query((#{values}),(#{options.join(',')}),#{@weight})}
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,3 @@
1
+ module Marklogic
2
+ VERSION = "0.0.1"
3
+ end
data/marklogic.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'marklogic/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'marklogic'
8
+ spec.version = Marklogic::VERSION
9
+ spec.authors = ['Paxton Hare']
10
+ spec.email = ['paxton@greenllama.com']
11
+ spec.summary = %q{A Ruby Driver for MarkLogic}
12
+ spec.description = %q{A Ruby Driver for MarkLogic}
13
+ spec.homepage = ''
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+ spec.has_rdoc = 'yard'
21
+
22
+ spec.add_runtime_dependency 'activesupport', '~> 4.2', '>= 4.2.0'
23
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe MarkLogic::AppServer do
4
+
5
+ describe "instance" do
6
+ let(:s) do
7
+ MarkLogic::AppServer.new(
8
+ "marklogic-gem-test",
9
+ 8039,
10
+ "http",
11
+ "Default")
12
+ end
13
+
14
+ it "should create accessors" do
15
+ expect(s.server_name).to eq("marklogic-gem-test")
16
+ expect(s.server_type).to eq("http")
17
+ expect(s["content-database"]).to eq("marklogic-gem-test-content")
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,105 @@
1
+ require 'spec_helper'
2
+
3
+ describe MarkLogic::Application do
4
+
5
+ before do
6
+ @a = MarkLogic::Application.new("marklogic-gem-application-test2", :port => PORT + 1)
7
+ @content_db = MarkLogic::Database.new("marklogic-gem-application-test2-content")
8
+ @content_forest = MarkLogic::Forest.new("marklogic-gem-application-test2-content")
9
+ @modules_db = MarkLogic::Database.new("marklogic-gem-application-test2-modules")
10
+ @modules_forest = MarkLogic::Database.new("marklogic-gem-application-test2-modules")
11
+ @app_server = MarkLogic::AppServer.new("marklogic-gem-application-test2", PORT + 1, "http", "Default")
12
+ end
13
+
14
+ after do
15
+ @a.drop
16
+ end
17
+
18
+
19
+ describe "new" do
20
+ it "should create an instance" do
21
+ expect(@a.app_name).to eq("marklogic-gem-application-test2")
22
+ expect(@a.databases.length).to eq(0)
23
+ end
24
+ end
25
+
26
+ describe "exists?" do
27
+ it "should return if it exists or not" do
28
+ @a.drop if @a.exists?
29
+ expect(@a).to_not be_exists
30
+ @a.create
31
+ expect(@a).to be_exists
32
+ @a.drop
33
+ expect(@a).to_not be_exists
34
+ end
35
+ end
36
+
37
+ describe "create" do
38
+ it "should bootstrap" do
39
+ @a.drop if @a.exists?
40
+
41
+ expect(@content_forest).to_not be_exists
42
+ expect(@content_db).to_not be_exists
43
+ expect(@modules_db).to_not be_exists
44
+ expect(@modules_forest).to_not be_exists
45
+ expect(@app_server).to_not be_exists
46
+
47
+ @a.create
48
+ expect(@content_forest).to be_exists
49
+ expect(@content_db).to be_exists
50
+ expect(@modules_forest).to be_exists
51
+ expect(@modules_db).to be_exists
52
+ expect(@app_server).to be_exists
53
+
54
+ @a.drop
55
+ end
56
+ end
57
+
58
+ describe "drop" do
59
+ it "should drop" do
60
+ @a.drop if @a.exists?
61
+ @a.create
62
+ expect(@content_db).to be_exists
63
+ expect(@modules_db).to be_exists
64
+ expect(@app_server).to be_exists
65
+
66
+ @a.drop
67
+ expect(@content_db).to_not be_exists
68
+ expect(@modules_db).to_not be_exists
69
+ expect(@app_server).to_not be_exists
70
+ end
71
+ end
72
+
73
+ describe "stale?" do
74
+ it "should be stale when appropriate" do
75
+ @a.drop if @a.exists?
76
+
77
+ expect(@a).to be_stale
78
+
79
+ @a.create
80
+ expect(@a).to_not be_stale
81
+
82
+ @a.content_databases[0].add_range_element_index("stuff")
83
+ expect(@a).to be_stale
84
+
85
+ @a.drop
86
+ expect(@a).to be_stale
87
+ end
88
+
89
+ it "should be stale when indexes are added via the app" do
90
+ @a.drop if @a.exists?
91
+ expect(@a).to be_stale
92
+ @a.create
93
+ expect(@a).to_not be_stale
94
+
95
+ @a.add_index(MarkLogic::DatabaseSettings::RangeElementIndex.new(:_id, :type => 'string'))
96
+ @a.add_index(MarkLogic::DatabaseSettings::RangeElementIndex.new(:name, :type => 'string'))
97
+ @a.add_index(MarkLogic::DatabaseSettings::RangeElementIndex.new(:age, :type => 'int'))
98
+
99
+ expect(@a).to be_stale
100
+
101
+ @a.drop
102
+ expect(@a).to be_stale
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,154 @@
1
+ require 'spec_helper'
2
+
3
+ describe MarkLogic::Collection do
4
+ before do
5
+ @collection = @database.collection("stuff")
6
+ @collection.drop
7
+ end
8
+
9
+ def save_ten
10
+ @collection.save((1..10).map do |n|
11
+ {:_id => n, :name => "John#{n}", :age => n, :stuff => "junk"}
12
+ end)
13
+ end
14
+
15
+ describe "count" do
16
+ it "returns the correct document count" do
17
+ expect(@collection.count).to eq 0
18
+ @collection.save( {:_id => "123", :name => "John", :age => 33, :stuff => "junk"} )
19
+ expect(@collection.count).to eq 1
20
+ @collection.save( {:_id => "456", :name => "Bill", :age => 33, :stuff => "junk"} )
21
+ expect(@collection.count).to eq 2
22
+ @collection.save( {:_id => "456", :name => "Bill", :age => 33, :stuff => "junk"} )
23
+ expect(@collection.count).to eq 2
24
+ end
25
+ end
26
+
27
+ describe "load" do
28
+ it "loads a document" do
29
+ expect(@collection.count).to eq 0
30
+ @collection.save( {:_id => "123", :name => "John", :age => 33, :stuff => "junk"} )
31
+ expect(@collection.count).to eq 1
32
+ doc = @collection.load("123")
33
+ expect(doc).to be_a_kind_of(Hash)
34
+ expect(doc["_id"]).to eq "123"
35
+ expect(doc['name']).to eq "John"
36
+ end
37
+ end
38
+
39
+ describe "save" do
40
+ it "saves a document" do
41
+ expect(@collection.count).to eq 0
42
+ @collection.save( {:_id => "123", :name => "John", :age => 33, :stuff => "junk"} )
43
+ expect(@collection.count).to eq 1
44
+ end
45
+ end
46
+
47
+ describe "#save multiples" do
48
+ it "saves a bunch of documents in one transaction" do
49
+ expect(@collection.count).to eq 0
50
+ @collection.save((1..10).map do |n|
51
+ {:_id => n.to_s, :name => "John#{n}", :age => 30 + n, :stuff => "junk#{n}"}
52
+ end)
53
+ expect(@collection.count).to eq 10
54
+ end
55
+ end
56
+
57
+ describe "remove" do
58
+ it "removes all document when no params given" do
59
+ expect(@collection.count).to eq 0
60
+ save_ten
61
+ expect(@collection.count).to eq 10
62
+ @collection.remove
63
+ expect(@collection.count).to eq 0
64
+ end
65
+
66
+ it "removes all document when an empty hash is given" do
67
+ expect(@collection.count).to eq 0
68
+ save_ten
69
+ expect(@collection.count).to eq 10
70
+ @collection.remove()
71
+ expect(@collection.count).to eq 0
72
+ end
73
+
74
+ it "removes documents matching the criteria given" do
75
+ expect(@collection.count).to eq 0
76
+ save_ten
77
+ expect(@collection.count).to eq 10
78
+ @collection.remove({:_id => 1})
79
+ expect(@collection.count).to eq 9
80
+
81
+ @collection.remove(@collection.from_criteria({:_id => 2}))
82
+ expect(@collection.count).to eq 8
83
+ end
84
+
85
+ it "removes documents matching the criteria given" do
86
+ expect(@collection.count).to eq 0
87
+ save_ten
88
+ expect(@collection.count).to eq 10
89
+ @collection.remove({:_id => [1, 2, 3]})
90
+ expect(@collection.count).to eq 7
91
+
92
+ @collection.remove(@collection.from_criteria({:_id => [4, 5, 6]}))
93
+ expect(@collection.count).to eq 4
94
+ end
95
+
96
+ it "removes documents matching the criteria given" do
97
+ expect(@collection.count).to eq 0
98
+ save_ten
99
+ expect(@collection.count).to eq 10
100
+ @collection.remove({ 'age' => { '$lt' => 7} })
101
+ expect(@collection.count).to eq 4
102
+
103
+ @collection.remove(@collection.from_criteria({ 'age' => { '$lt' => 8} }))
104
+ expect(@collection.count).to eq 3
105
+ end
106
+ end
107
+
108
+ describe "drop" do
109
+ it "removes all documents" do
110
+ expect(@collection.count).to eq 0
111
+ save_ten
112
+ expect(@collection.count).to eq 10
113
+ @collection.drop
114
+ expect(@collection.count).to eq 0
115
+ end
116
+ end
117
+
118
+ describe "find" do
119
+ it "finds documents matching the criteria given" do
120
+ expect(@collection.count).to eq 0
121
+ save_ten
122
+ expect(@collection.count).to eq 10
123
+ expect(@collection.find({:_id => 1}).count).to eq 1
124
+ expect(@collection.find(@collection.from_criteria({:_id => 1})).count).to eq 1
125
+ end
126
+
127
+ it "finds documents matching the criteria given" do
128
+ expect(@collection.count).to eq 0
129
+ save_ten
130
+ expect(@collection.count).to eq 10
131
+ expect(@collection.find({:_id => [1, 2, 3]}).count).to eq 3
132
+ expect(@collection.find(@collection.from_criteria({:_id => [1, 2, 3]})).count).to eq 3
133
+ end
134
+
135
+ it "finds documents matching the criteria given" do
136
+ expect(@collection.count).to eq 0
137
+ save_ten
138
+ expect(@collection.count).to eq 10
139
+ expect(@collection.find({ 'age' => { '$lt' => 7 } }).count).to eq 6
140
+ expect(@collection.find(@collection.from_criteria({ 'age' => { '$lt' => 7 } })).count).to eq 6
141
+ end
142
+ end
143
+
144
+ describe "#find_one" do
145
+ it "finds one document" do
146
+ expect(@collection.count).to eq 0
147
+ save_ten
148
+ expect(@collection.count).to eq 10
149
+ c = @collection.find_one({:_id => 1})
150
+ c = @collection.find_one(@collection.from_criteria({:_id => 1}))
151
+ expect(c['_id']).to eq(1)
152
+ end
153
+ end
154
+ end