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,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