marklogic 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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,128 @@
1
+ require 'spec_helper'
2
+
3
+ describe MarkLogic::Connection do
4
+
5
+ class Response
6
+
7
+ def initialize(b)
8
+ @body = b
9
+ end
10
+
11
+ def body
12
+ @body
13
+ end
14
+
15
+ def body=(val)
16
+ @body = val
17
+ end
18
+
19
+ def read_body
20
+ true
21
+ end
22
+
23
+ def [](x)
24
+ "multipart/mixed; boundary=4ae338aa9d1fc38e"
25
+ end
26
+ end
27
+
28
+ before do
29
+ @b = MarkLogic::Connection.app_services_connection
30
+ end
31
+
32
+ describe "split_multipart" do
33
+ it "should split properly when multiple values are returned" do
34
+ response = Response.new(%Q{\r\n--4ae338aa9d1fc38e\r\nContent-Type: text/plain\r\nX-Primitive: integer\r\n\r\n5\r\n--4ae338aa9d1fc38e\r\nContent-Type: text/plain\r\nX-Primitive: integer\r\n\r\n6\r\n--4ae338aa9d1fc38e--\r\n})
35
+ expect(@b.send(:split_multipart, response)).to eq([5, 6])
36
+ end
37
+
38
+ it "should split properly when a single value is returned" do
39
+ response = Response.new(%Q{\r\n--4ae338aa9d1fc38e\r\nContent-Type: text/plain\r\nX-Primitive: integer\r\n\r\n5\r\n--4ae338aa9d1fc38e--\r\n})
40
+ expect(@b.send(:split_multipart, response)).to eq(5)
41
+ end
42
+
43
+ it "should split properly when an array value is returned" do
44
+ response = Response.new(%Q{\r\n--4ae338aa9d1fc38e\r\nContent-Type: application/json\r\nX-Primitive: array\r\n\r\n["5", 6]\r\n--4ae338aa9d1fc38e--\r\n})
45
+ expect(@b.send(:split_multipart, response)).to eq(["5", 6])
46
+ end
47
+
48
+ it "should split properly when an object value is returned" do
49
+ response = Response.new(%Q{\r\n--4ae338aa9d1fc38e\r\nContent-Type: application/json\r\nX-Primitive: map\r\n\r\n{"hi":"stuff"}\r\n--4ae338aa9d1fc38e--\r\n})
50
+ expect(@b.send(:split_multipart, response)).to eq({"hi" => "stuff"})
51
+ end
52
+
53
+ it "should split properly when a true boolean is returned" do
54
+ response = Response.new(%Q{\r\n--4ae338aa9d1fc38e\r\nContent-Type: text/plain\r\nX-Primitive: boolean\r\n\r\ntrue\r\n--4ae338aa9d1fc38e--\r\n})
55
+ expect(@b.send(:split_multipart, response)).to be true
56
+ end
57
+
58
+ it "should split properly when a false boolean is returned" do
59
+ response = Response.new(%Q{\r\n--4ae338aa9d1fc38e\r\nContent-Type: text/plain\r\nX-Primitive: boolean\r\n\r\nfalse\r\n--4ae338aa9d1fc38e--\r\n})
60
+ expect(@b.send(:split_multipart, response)).to be false
61
+ end
62
+
63
+ it "should split properly when a decimal is returned" do
64
+ response = Response.new(%Q{\r\n--4ae338aa9d1fc38e\r\nContent-Type: text/plain\r\nX-Primitive: decimal\r\n\r\n3.1\r\n--4ae338aa9d1fc38e--\r\n})
65
+ expect(@b.send(:split_multipart, response)).to eq(3.1)
66
+ end
67
+
68
+ it "should split properly when a crazy object is returned" do
69
+ response = Response.new(%Q{\r\n--4ae338aa9d1fc38e\r\nContent-Type: application/json\r\nX-Primitive: map\r\n\r\n{"stuff":[1, 2, 3], "junk":false}\r\n--4ae338aa9d1fc38e--\r\n})
70
+ expect(@b.send(:split_multipart, response)).to eq({"stuff" => [1, 2, 3], "junk" => false})
71
+ end
72
+
73
+ end
74
+
75
+ describe "run_query" do
76
+ it "should split properly when multiple values are returned" do
77
+ expect(@b.run_query('(5, 6)', 'xquery').body).to eq([5, 6])
78
+ end
79
+
80
+ it "should split properly when a single value is returned" do
81
+ expect(@b.run_query('5').body).to eq(5)
82
+ end
83
+
84
+ it "should split properly when an array value is returned" do
85
+ expect(@b.run_query(%Q{x = ["5", 6]; x}).body).to eq(["5", 6])
86
+ end
87
+
88
+ it "should split properly when an object value is returned" do
89
+ expect(@b.run_query('x = {hi: "stuff"}; x').body).to eq({"hi" => "stuff"})
90
+ end
91
+
92
+ it "should split properly when a true boolean is returned" do
93
+ expect(@b.run_query('true').body).to be true
94
+ end
95
+
96
+ it "should split properly when a false boolean is returned" do
97
+ expect(@b.run_query('false').body).to be false
98
+ end
99
+
100
+ it "should split properly when a decimal is returned" do
101
+ expect(@b.run_query('3.1').body).to eq(3.1)
102
+ end
103
+
104
+ it "should split properly when a crazy object is returned" do
105
+ expect(@b.run_query(%Q{x = { stuff: [1, 2, 3], junk: false}; x}).body).to eq({"stuff" => [1, 2, 3], "junk" => false})
106
+ end
107
+ end
108
+
109
+ describe "#digest" do
110
+ it "#digest should cache login creds" do
111
+ expect(@b.run_query('(5, 6)', 'xquery').body).to eq([5, 6])
112
+ expect(@b.run_query('(5, 6)', 'xquery').body).to eq([5, 6])
113
+ expect(@b.run_query('(5, 6)', 'xquery').body).to eq([5, 6])
114
+ expect(@b.run_query('(5, 6)', 'xquery').body).to eq([5, 6])
115
+ end
116
+ end
117
+
118
+ describe "run_query" do
119
+ it "should work" do
120
+ expect(@b.run_query('(5, 6)', 'xquery').body).to eq([5, 6])
121
+ expect(@b.run_query('<a/>,<a/>', 'xquery').body).to eq(['<a/>', '<a/>'])
122
+
123
+ res = @b.run_query('<a/>, try { fn:error((), "stuff") } catch($ex) { $ex }', 'xquery').body
124
+ expect(res[0]).to eq('<a/>')
125
+ expect(res[1]).to match(/<error:error.*/)
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,219 @@
1
+ require 'spec_helper'
2
+
3
+ describe MarkLogic::Cursor do
4
+ before do
5
+ @collection = @database.collection("stuff")
6
+ @collection.drop
7
+
8
+ @collection.save((1..101).map do |n|
9
+ {:_id => n, :name => "John#{n}", :age => n, :weight => n % 5, :stuff => "junk"}
10
+ end)
11
+ end
12
+
13
+ describe "#sort" do
14
+ it "should sort ascending" do
15
+ c = MarkLogic::Cursor.new(@collection, {
16
+ :sort => [['age', 1]]
17
+ })
18
+ expect(c.count).to eq 101
19
+ expect(c.first['age']).to eq(1)
20
+ end
21
+
22
+ it "should sort descending" do
23
+ c = MarkLogic::Cursor.new(@collection, {
24
+ :sort => [['age', -1]]
25
+ })
26
+ expect(c.count).to eq 101
27
+ expect(c.first['age']).to eq(101)
28
+ end
29
+
30
+ it "should do multiple sorts asc, desc" do
31
+ options = {
32
+ :sort => [['weight', 1], ['age', -1]]
33
+ }
34
+ c = MarkLogic::Cursor.new(@collection, options)
35
+ expect(c.count).to eq 101
36
+ first = c.first
37
+ expect(first['age']).to eq(100)
38
+ expect(first['weight']).to eq(0)
39
+ end
40
+
41
+ it "should do multiple sorts asc, asc" do
42
+ options = {
43
+ :sort => [['weight', 1], ['age', 1]]
44
+ }
45
+ c = MarkLogic::Cursor.new(@collection, options)
46
+ expect(c.count).to eq 101
47
+ first = c.first
48
+ expect(first['age']).to eq(5)
49
+ expect(first['weight']).to eq(0)
50
+ end
51
+
52
+ it "should do multiple sorts desc, asc" do
53
+ options = {
54
+ :sort => [['weight', -1], ['age', 1]]
55
+ }
56
+ c = MarkLogic::Cursor.new(@collection, options)
57
+ expect(c.count).to eq 101
58
+ first = c.first
59
+ expect(first['age']).to eq(4)
60
+ expect(first['weight']).to eq(4)
61
+ end
62
+
63
+ it "should do multiple sorts desc, asc" do
64
+ options = {
65
+ :sort => [['weight', -1], ['age', -1]]
66
+ }
67
+ c = MarkLogic::Cursor.new(@collection, options)
68
+ expect(c.count).to eq 101
69
+ first = c.first
70
+ expect(first['age']).to eq(99)
71
+ expect(first['weight']).to eq(4)
72
+ end
73
+ end
74
+
75
+ describe "#operators" do
76
+ it "should support EQ" do
77
+ criteria = { 'age' => { '$eq' => 3 } }
78
+ options = {
79
+ :query => @collection.from_criteria(criteria)
80
+ }
81
+ c = MarkLogic::Cursor.new(@collection, options)
82
+ expect(c.count).to eq 1
83
+ expect(c.first['age']).to eq 3
84
+
85
+ criteria = { 'age' => 3 }
86
+ options = {
87
+ :query => @collection.from_criteria(criteria)
88
+ }
89
+ c = MarkLogic::Cursor.new(@collection, options)
90
+ expect(c.count).to eq 1
91
+ expect(c.first['age']).to eq 3
92
+
93
+ criteria = { 'age' => (1..100).to_a }
94
+ c = MarkLogic::Cursor.new(@collection, {
95
+ :query => @collection.from_criteria(criteria)
96
+ })
97
+ expect(c.count).to eq 100
98
+ end
99
+
100
+ it "should support LT" do
101
+ criteria = { 'age' => { '$lt' => 3 } }
102
+ c = MarkLogic::Cursor.new(@collection, {
103
+ :query => @collection.from_criteria(criteria)
104
+ })
105
+ expect(c.count).to eq 2
106
+ expect([1, 2].include?(c.first['age'])).to be true
107
+ expect([1, 2].include?(c.next['age'])).to be true
108
+ end
109
+
110
+ it "should support GT" do
111
+ criteria = { 'age' => { '$gt' => 99 } }
112
+ c = MarkLogic::Cursor.new(@collection, {
113
+ :query => @collection.from_criteria(criteria)
114
+ })
115
+ expect(c.count).to eq 2
116
+ expect([100, 101].include?(c.first['age'])).to be true
117
+ expect([100, 101].include?(c.next['age'])).to be true
118
+ end
119
+
120
+ it "should support LE" do
121
+ criteria = { 'age' => { '$le' => 2 } }
122
+ c = MarkLogic::Cursor.new(@collection, {
123
+ :query => @collection.from_criteria(criteria)
124
+ })
125
+ expect(c.count).to eq 2
126
+ expect([1, 2].include?(c.first['age'])).to be true
127
+ expect([1, 2].include?(c.next['age'])).to be true
128
+ end
129
+
130
+ it "should support GE" do
131
+ criteria = { 'age' => { '$ge' => 100 } }
132
+ c = MarkLogic::Cursor.new(@collection, {
133
+ :query => @collection.from_criteria(criteria)
134
+ })
135
+ expect(c.count).to eq 2
136
+ expect([100, 101].include?(c.first['age'])).to be true
137
+ expect([100, 101].include?(c.next['age'])).to be true
138
+ end
139
+
140
+ it "should support NE" do
141
+ criteria = { 'age' => { '$ne' => 100 } }
142
+ c = MarkLogic::Cursor.new(@collection, {
143
+ :query => @collection.from_criteria(criteria)
144
+ })
145
+ expect(c.count).to eq 100
146
+ end
147
+ end
148
+
149
+ describe "count" do
150
+ it "should work when indexes are provided" do
151
+ criteria = { 'age' => { '$gt' => 3 } }
152
+ c = MarkLogic::Cursor.new(@collection, {
153
+ :query => @collection.from_criteria(criteria)
154
+ })
155
+ expect(c.count).to eq 98
156
+ end
157
+
158
+ it "should fail when no indexes are provided and should be" do
159
+ criteria = { 'stuff' => { '$gt' => 3 } }
160
+ expect {@collection.from_criteria(criteria) }.to raise_error(MarkLogic::MissingIndexError)
161
+ end
162
+
163
+ it "should return the correct count" do
164
+ c = MarkLogic::Cursor.new(@collection)
165
+ expect(c.count).to eq 101
166
+ end
167
+ end
168
+
169
+ describe "each" do
170
+ it "should work when indexes are provided" do
171
+ criteria = { 'age' => { '$gt' => 3 } }
172
+ c = MarkLogic::Cursor.new(@collection, {
173
+ :query => @collection.from_criteria(criteria)
174
+ })
175
+
176
+ count = 0
177
+ c.each do |doc|
178
+ count = count + 1
179
+ expect(doc.kind_of?(Hash)).to eq true
180
+ end
181
+ expect(count).to eq 98
182
+ end
183
+
184
+ it "should transform results when a transformer is provided" do
185
+ @user_class = Struct.new(:id, :name, :age, :stuff)
186
+
187
+ criteria = { 'age' => { '$gt' => 3 } }
188
+ c = MarkLogic::Cursor.new(@collection, {
189
+ :query => @collection.from_criteria(criteria),
190
+ :transformer => lambda { |doc| @user_class.new(doc['_id'], doc['name'], doc['age'], doc['stuff']) }
191
+ })
192
+
193
+ count = 0
194
+ c.each do |doc|
195
+ count = count + 1
196
+ expect(doc.kind_of?(@user_class)).to be true
197
+ expect(doc.stuff).to eq("junk")
198
+ end
199
+ expect(count).to eq 98
200
+ end
201
+
202
+ # it "should fail when no indexes are provided and should be" do
203
+ # criteria = { 'age' => { '$gt' => 3 } }
204
+ # c = MarkLogic::Cursor.new(@collection, {
205
+ # :query => @collection.from_criteria(criteria)
206
+ # })
207
+ # expect { c.each { |doc| doc } }.to raise_error(MarkLogic::MissingIndexError)
208
+ # end
209
+
210
+ it "should return the correct count" do
211
+ c = MarkLogic::Cursor.new(@collection)
212
+ count = 0
213
+ c.each do |doc|
214
+ count = count + 1
215
+ end
216
+ expect(count).to eq 101
217
+ end
218
+ end
219
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe MarkLogic::DatabaseSettings::ElementWordLexicon do
4
+ let(:index) do
5
+ MarkLogic::DatabaseSettings::ElementWordLexicon.new("element")
6
+ end
7
+
8
+ context "#new" do
9
+ it "should populate correctly" do
10
+ expect(index.to_json).to eq(
11
+ {
12
+ "element-word-lexicon" => {
13
+ "namespace-uri" => "",
14
+ "localname" => "element",
15
+ "collation" => MarkLogic::DEFAULT_COLLATION
16
+ }
17
+ }
18
+ )
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe MarkLogic::DatabaseSettings::GeospatialElementChildIndex do
4
+ let(:index) do
5
+ MarkLogic::DatabaseSettings::GeospatialElementChildIndex.new("parent", "child")
6
+ end
7
+
8
+ describe "new" do
9
+ it "should populate correctly" do
10
+ expect(index.to_json).to eq(
11
+ {
12
+ "geospatial-element-child-index" => {
13
+ "parent-namespace-uri" => "",
14
+ "parent-localname" => "parent",
15
+ "namespace-uri" => "",
16
+ "localname" => "child",
17
+ "coordinate-system" => "wgs84",
18
+ "point-format" => "point",
19
+ "range-value-positions" => false,
20
+ "invalid-values" => "reject"
21
+ }
22
+ }
23
+ )
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe MarkLogic::DatabaseSettings::GeospatialElementIndex do
4
+ let(:index) do
5
+ MarkLogic::DatabaseSettings::GeospatialElementIndex.new("element")
6
+ end
7
+
8
+ describe "new" do
9
+ it "should populate correctly" do
10
+ expect(index.to_json).to eq(
11
+ {
12
+ "geospatial-element-index" => {
13
+ "namespace-uri" => "",
14
+ "localname" => "element",
15
+ "coordinate-system" => "wgs84",
16
+ "point-format" => "point",
17
+ "range-value-positions" => false,
18
+ "invalid-values" => "reject"
19
+ }
20
+ }
21
+ )
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe MarkLogic::DatabaseSettings::GeospatialElementPairIndex do
4
+ let(:index) do
5
+ MarkLogic::DatabaseSettings::GeospatialElementPairIndex.new("parent", "lat", "lon")
6
+ end
7
+
8
+ describe "new" do
9
+ it "should populate correctly" do
10
+ expect(index.to_json).to eq(
11
+ {
12
+ "geospatial-element-pair-index" => {
13
+ "parent-namespace-uri" => "",
14
+ "parent-localname" => "parent",
15
+ "latitude-namespace-uri" => "",
16
+ "latitude-localname" => "lat",
17
+ "longitude-namespace-uri" => "",
18
+ "longitude-localname" => "lon",
19
+ "coordinate-system" => "wgs84",
20
+ "range-value-positions" => false,
21
+ "invalid-values" => "reject"
22
+ }
23
+ }
24
+ )
25
+ end
26
+ end
27
+ end