leanback 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +10 -0
  3. data/Gemfile +5 -6
  4. data/Gemfile.lock +65 -14
  5. data/README.md +465 -33
  6. data/Rakefile +8 -17
  7. data/VERSION +1 -1
  8. data/leanback.gemspec +26 -85
  9. data/lib/leanback.rb +129 -587
  10. data/spec/leanback_spec.rb +356 -0
  11. metadata +40 -117
  12. data/Changelog.rdoc +0 -146
  13. data/documentation/static/2011/11/20/i-moved-leanback-documentation/index.html +0 -180
  14. data/documentation/static/2011/11/20/index.html +0 -146
  15. data/documentation/static/2011/11/index.html +0 -146
  16. data/documentation/static/2011/index.html +0 -146
  17. data/documentation/static/2013/06/02/index.html +0 -146
  18. data/documentation/static/2013/06/02/released-leanback-v0-3-4/index.html +0 -180
  19. data/documentation/static/2013/06/09/index.html +0 -146
  20. data/documentation/static/2013/06/09/released-leanback-v0-4-0/index.html +0 -179
  21. data/documentation/static/2013/06/index.html +0 -158
  22. data/documentation/static/2013/index.html +0 -158
  23. data/documentation/static/author/admin/index.html +0 -175
  24. data/documentation/static/basic-couchdb-operations/index.html +0 -259
  25. data/documentation/static/category/uncategorized/index.html +0 -170
  26. data/documentation/static/couchdb-configuration/index.html +0 -189
  27. data/documentation/static/couchdb-security/index.html +0 -218
  28. data/documentation/static/count-by-multiple-documents/index.html +0 -221
  29. data/documentation/static/count-documents-by-key/index.html +0 -177
  30. data/documentation/static/css/2c-l-fixed.css +0 -1
  31. data/documentation/static/css/2c-l-fixed.dev.css +0 -62
  32. data/documentation/static/css/2c-r-fixed.css +0 -1
  33. data/documentation/static/css/2c-r-fixed.dev.css +0 -60
  34. data/documentation/static/css/3c-c-fixed.css +0 -1
  35. data/documentation/static/css/3c-c-fixed.dev.css +0 -84
  36. data/documentation/static/css/3c-l-fixed.css +0 -1
  37. data/documentation/static/css/3c-l-fixed.dev.css +0 -61
  38. data/documentation/static/css/3c-r-fixed.css +0 -1
  39. data/documentation/static/css/3c-r-fixed.dev.css +0 -62
  40. data/documentation/static/css/holy-grail-fluid.css +0 -5
  41. data/documentation/static/css/plugins.css +0 -5
  42. data/documentation/static/css/print.css +0 -5
  43. data/documentation/static/css/screen.css +0 -1
  44. data/documentation/static/design-documents-and-permanent-views/index.html +0 -454
  45. data/documentation/static/error-handling/index.html +0 -157
  46. data/documentation/static/find-document-by-multiple-keys/index.html +0 -269
  47. data/documentation/static/find-documents-by-key/index.html +0 -243
  48. data/documentation/static/index.html +0 -161
  49. data/documentation/static/leanback/index.html +0 -130
  50. data/documentation/static/leanback/installation/index.html +0 -119
  51. data/documentation/static/setting-the-bind_address-port/index.html +0 -151
  52. data/documentation/static/style.css +0 -16
  53. data/spec/admin_party/database_spec.rb +0 -400
  54. data/spec/no_admin_party/cloudant_spec.rb +0 -365
  55. data/spec/no_admin_party/database_spec.rb +0 -491
  56. data/spec/no_admin_party/non_admin_user_spec.rb +0 -67
  57. data/test/helper.rb +0 -18
  58. data/test/main.rb +0 -295
  59. data/test/my_view.json +0 -8
  60. data/test/my_views.json +0 -8
  61. data/test/start.json +0 -8
  62. data/test/test_leanback.rb +0 -319
  63. data/test/view_age.json +0 -8
data/Rakefile CHANGED
@@ -15,8 +15,8 @@ Jeweler::Tasks.new do |gem|
15
15
  gem.name = "leanback"
16
16
  gem.homepage = "http://github.com/obi-a/leanback"
17
17
  gem.license = "MIT"
18
- gem.summary = %Q{lightweight Ruby interface to CouchDB}
19
- gem.description = %Q{lightweight Ruby interface to CouchDB}
18
+ gem.summary = %Q{Simple Ruby interface to CouchDB}
19
+ gem.description = %Q{Simple Ruby interface to CouchDB}
20
20
  gem.email = "obioraakubue@yahoo.com"
21
21
  gem.authors = ["Obi Akubue"]
22
22
  # Include your dependencies below. Runtime dependencies are required when using your gem,
@@ -33,21 +33,12 @@ Rake::TestTask.new(:test) do |test|
33
33
  test.verbose = true
34
34
  end
35
35
 
36
- require 'rcov/rcovtask'
37
- Rcov::RcovTask.new do |test|
38
- test.libs << 'test'
39
- test.pattern = 'test/**/test_*.rb'
40
- test.verbose = true
36
+ task :repl do
37
+ leanback_file = File.expand_path(File.join(File.dirname(__FILE__), '..', 'leanback/lib/leanback'))
38
+ irb = "bundle exec pry -r #{leanback_file}"
39
+ sh irb
41
40
  end
42
41
 
43
- task :default => :test
44
-
45
- require 'rake/rdoctask'
46
- Rake::RDocTask.new do |rdoc|
47
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
42
+ task :r => :repl
48
43
 
49
- rdoc.rdoc_dir = 'rdoc'
50
- rdoc.title = "leanback #{version}"
51
- rdoc.rdoc_files.include('README*')
52
- rdoc.rdoc_files.include('lib/**/*.rb')
53
- end
44
+ task :default => :test
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.2
1
+ 0.5.0
data/leanback.gemspec CHANGED
@@ -2,15 +2,17 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
+ # stub: leanback 0.5.0 ruby lib
5
6
 
6
7
  Gem::Specification.new do |s|
7
8
  s.name = "leanback"
8
- s.version = "0.4.2"
9
+ s.version = "0.5.0"
9
10
 
10
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib"]
11
13
  s.authors = ["Obi Akubue"]
12
- s.date = "2013-11-16"
13
- s.description = "lightweight Ruby interface to CouchDB"
14
+ s.date = "2014-06-14"
15
+ s.description = "Simple Ruby interface to CouchDB"
14
16
  s.email = "obioraakubue@yahoo.com"
15
17
  s.extra_rdoc_files = [
16
18
  "LICENSE.txt",
@@ -18,111 +20,50 @@ Gem::Specification.new do |s|
18
20
  ]
19
21
  s.files = [
20
22
  ".document",
21
- "Changelog.rdoc",
23
+ ".travis.yml",
22
24
  "Gemfile",
23
25
  "Gemfile.lock",
24
26
  "LICENSE.txt",
25
27
  "README.md",
26
28
  "Rakefile",
27
29
  "VERSION",
28
- "documentation/static/2011/11/20/i-moved-leanback-documentation/index.html",
29
- "documentation/static/2011/11/20/index.html",
30
- "documentation/static/2011/11/index.html",
31
- "documentation/static/2011/index.html",
32
- "documentation/static/2013/06/02/index.html",
33
- "documentation/static/2013/06/02/released-leanback-v0-3-4/index.html",
34
- "documentation/static/2013/06/09/index.html",
35
- "documentation/static/2013/06/09/released-leanback-v0-4-0/index.html",
36
- "documentation/static/2013/06/index.html",
37
- "documentation/static/2013/index.html",
38
- "documentation/static/author/admin/index.html",
39
- "documentation/static/basic-couchdb-operations/index.html",
40
- "documentation/static/category/uncategorized/index.html",
41
- "documentation/static/couchdb-configuration/index.html",
42
- "documentation/static/couchdb-security/index.html",
43
- "documentation/static/count-by-multiple-documents/index.html",
44
- "documentation/static/count-documents-by-key/index.html",
45
- "documentation/static/css/2c-l-fixed.css",
46
- "documentation/static/css/2c-l-fixed.dev.css",
47
- "documentation/static/css/2c-r-fixed.css",
48
- "documentation/static/css/2c-r-fixed.dev.css",
49
- "documentation/static/css/3c-c-fixed.css",
50
- "documentation/static/css/3c-c-fixed.dev.css",
51
- "documentation/static/css/3c-l-fixed.css",
52
- "documentation/static/css/3c-l-fixed.dev.css",
53
- "documentation/static/css/3c-r-fixed.css",
54
- "documentation/static/css/3c-r-fixed.dev.css",
55
- "documentation/static/css/holy-grail-fluid.css",
56
- "documentation/static/css/plugins.css",
57
- "documentation/static/css/print.css",
58
- "documentation/static/css/screen.css",
59
- "documentation/static/design-documents-and-permanent-views/index.html",
60
- "documentation/static/error-handling/index.html",
61
- "documentation/static/find-document-by-multiple-keys/index.html",
62
- "documentation/static/find-documents-by-key/index.html",
63
- "documentation/static/index.html",
64
- "documentation/static/leanback/index.html",
65
- "documentation/static/leanback/installation/index.html",
66
- "documentation/static/setting-the-bind_address-port/index.html",
67
- "documentation/static/style.css",
68
30
  "leanback.gemspec",
69
31
  "lib/leanback.rb",
70
- "spec/admin_party/database_spec.rb",
71
- "spec/no_admin_party/cloudant_spec.rb",
72
- "spec/no_admin_party/database_spec.rb",
73
- "spec/no_admin_party/non_admin_user_spec.rb",
74
- "spec/spec_base.rb",
75
- "test/helper.rb",
76
- "test/main.rb",
77
- "test/my_view.json",
78
- "test/my_views.json",
79
- "test/start.json",
80
- "test/test_leanback.rb",
81
- "test/view_age.json"
32
+ "spec/leanback_spec.rb",
33
+ "spec/spec_base.rb"
82
34
  ]
83
35
  s.homepage = "http://github.com/obi-a/leanback"
84
36
  s.licenses = ["MIT"]
85
- s.require_paths = ["lib"]
86
- s.rubygems_version = "1.8.24"
87
- s.summary = "lightweight Ruby interface to CouchDB"
88
- s.test_files = [
89
- "spec/admin_party/database_spec.rb",
90
- "spec/no_admin_party/cloudant_spec.rb",
91
- "spec/no_admin_party/database_spec.rb",
92
- "spec/no_admin_party/non_admin_user_spec.rb",
93
- "spec/spec_base.rb",
94
- "test/helper.rb",
95
- "test/main.rb",
96
- "test/test_leanback.rb"
97
- ]
37
+ s.rubygems_version = "2.2.2"
38
+ s.summary = "Simple Ruby interface to CouchDB"
98
39
 
99
40
  if s.respond_to? :specification_version then
100
- s.specification_version = 3
41
+ s.specification_version = 4
101
42
 
102
43
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
44
+ s.add_runtime_dependency(%q<activesupport>, [">= 0"])
103
45
  s.add_runtime_dependency(%q<rest-client>, [">= 0"])
104
- s.add_runtime_dependency(%q<yajl-ruby>, [">= 0"])
105
- s.add_development_dependency(%q<shoulda>, [">= 0"])
106
- s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
107
- s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
108
- s.add_development_dependency(%q<rcov>, [">= 0"])
46
+ s.add_runtime_dependency(%q<json_pure>, [">= 0"])
47
+ s.add_development_dependency(%q<pry>, [">= 0"])
48
+ s.add_development_dependency(%q<bundler>, [">= 0"])
49
+ s.add_development_dependency(%q<jeweler>, ["~> 1.8.7"])
109
50
  s.add_development_dependency(%q<rspec>, [">= 0"])
110
51
  else
52
+ s.add_dependency(%q<activesupport>, [">= 0"])
111
53
  s.add_dependency(%q<rest-client>, [">= 0"])
112
- s.add_dependency(%q<yajl-ruby>, [">= 0"])
113
- s.add_dependency(%q<shoulda>, [">= 0"])
114
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
115
- s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
116
- s.add_dependency(%q<rcov>, [">= 0"])
54
+ s.add_dependency(%q<json_pure>, [">= 0"])
55
+ s.add_dependency(%q<pry>, [">= 0"])
56
+ s.add_dependency(%q<bundler>, [">= 0"])
57
+ s.add_dependency(%q<jeweler>, ["~> 1.8.7"])
117
58
  s.add_dependency(%q<rspec>, [">= 0"])
118
59
  end
119
60
  else
61
+ s.add_dependency(%q<activesupport>, [">= 0"])
120
62
  s.add_dependency(%q<rest-client>, [">= 0"])
121
- s.add_dependency(%q<yajl-ruby>, [">= 0"])
122
- s.add_dependency(%q<shoulda>, [">= 0"])
123
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
124
- s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
125
- s.add_dependency(%q<rcov>, [">= 0"])
63
+ s.add_dependency(%q<json_pure>, [">= 0"])
64
+ s.add_dependency(%q<pry>, [">= 0"])
65
+ s.add_dependency(%q<bundler>, [">= 0"])
66
+ s.add_dependency(%q<jeweler>, ["~> 1.8.7"])
126
67
  s.add_dependency(%q<rspec>, [">= 0"])
127
68
  end
128
69
  end
data/lib/leanback.rb CHANGED
@@ -1,614 +1,156 @@
1
1
  require 'rest_client'
2
- require 'yajl'
3
- require 'erb'
4
-
5
- class CouchdbException < RuntimeError
6
- attr :error
7
- def initialize(error)
8
- @error = error.values[0]
9
- end
10
- end
11
-
12
- module Couchdb
13
- def self.couch_error(e)
14
- raise e if e.is_a? OpenSSL::SSL::SSLError
15
- hash = Yajl::Parser.parse(e.response.to_s)
16
- raise CouchdbException.new(hash), "CouchDB: Error - #{hash.values[0]}. Reason - #{hash.values[1]}"
17
- end
18
-
19
- def self.salt
20
- o = [('a'..'z'),('A'..'Z')].map{|i| i.to_a}.flatten;
21
- salt = (0..50).map{ o[rand(o.length)] }.join;
22
- end
23
-
24
- #change non-admin user password
25
- def self.change_password(username, new_password,auth_session = "")
26
- salty = salt()
27
- password_sha = Digest::SHA1.hexdigest(new_password + salty)
28
- user_id = 'org.couchdb.user:' + username
29
- data = {"salt" => salty,"password_sha" => password_sha}
30
- doc = { :database => '_users', :doc_id => user_id, :data => data}
31
- update_doc doc,auth_session
32
- end
33
-
34
- #add a new user
35
- def self.add_user(user, auth_session="")
36
- o = [('a'..'z'),('A'..'Z')].map{|i| i.to_a}.flatten;
37
- salt = (0..50).map{ o[rand(o.length)] }.join;
38
- new_user = {:username => user[:username], :password => user[:password], :roles => user[:roles], :salt => salt}
39
- create_user(new_user,auth_session)
40
- end
41
-
42
- #create a new user
43
- def self.create_user(user,auth_session= "")
44
- password_sha = Digest::SHA1.hexdigest(user[:password] + user[:salt])
45
-
46
- user_hash = { :type => "user",
47
- :name => user[:username],
48
- :password_sha => password_sha,
49
- :salt => user[:salt],
50
- :roles => user[:roles]
51
- }
52
-
53
- str = Yajl::Encoder.encode(user_hash)
54
- set_address
55
- begin
56
- response = RestClient.put "#{@address}:#{@port}/_users/org.couchdb.user:#{URI.escape(user[:username])}", str,{:cookies => {"AuthSession" => auth_session}}
57
- hash = Yajl::Parser.parse(response.to_str)
58
- rescue => e
59
- couch_error(e)
60
- end
61
-
62
- end
63
-
64
- #add security object
65
- def self.set_security(db_name, data,auth_session="")
66
- security_data = Yajl::Encoder.encode(data)
67
- set_address
68
- begin
69
- response = RestClient.put "#{@address}:#{@port}/#{URI.escape(db_name)}/_security/",security_data, {:cookies => {"AuthSession" => auth_session}}
70
- hash = Yajl::Parser.parse(response.to_str)
71
- rescue => e
72
- couch_error(e)
73
- end
74
- end
75
-
76
- #get security object
77
- def self.get_security(db_name, auth_session="")
78
- set_address
79
- begin
80
- response = RestClient.get "#{@address}:#{@port}/#{URI.escape(db_name)}/_security/", {:cookies => {"AuthSession" => auth_session}}
81
- hash = Yajl::Parser.parse(response.to_str)
82
- rescue => e
83
- couch_error(e)
84
- end
85
- end
86
-
87
- #login to couchdb
88
- def self.login(username, password)
89
- set_address
90
- data = "name=#{username}&password=#{password}"
91
- begin
92
- response = RestClient.post "#{@address}:#{@port}/_session/", data, {:content_type => 'application/x-www-form-urlencoded'}
93
- response.cookies
94
- rescue => e
95
- couch_error(e)
2
+ require 'json/pure'
3
+ require 'active_support/all'
4
+
5
+ module Leanback
6
+ class InvalidDatabaseName < StandardError; end
7
+ class InvalidDocumentID < StandardError; end
8
+ class CouchdbException < StandardError
9
+ attr_reader :response
10
+ def initialize(response)
11
+ @response = response
12
+ end
13
+ end
14
+ class Couchdb
15
+ attr_reader :address
16
+ attr_reader :port
17
+ attr_reader :username
18
+ attr_reader :password
19
+ attr_reader :database
20
+ def initialize(args = {})
21
+ @database = args.fetch(:database, nil)
22
+ @address = args.fetch(:address, 'http://127.0.0.1')
23
+ @port = args.fetch(:port, '5984')
24
+ @username = args.fetch(:username, nil)
25
+ @password = args.fetch(:password, nil)
26
+ end
27
+ def create
28
+ api_request { RestClient.put "#{address_port}/#{db_uri}", content_type, cookies }
29
+ end
30
+ def delete
31
+ api_request { RestClient.delete "#{address_port}/#{db_uri}", cookies }
32
+ end
33
+ def create_doc(doc_id, doc)
34
+ api_request { RestClient.put "#{address_port}/#{db_uri}/#{doc_uri(doc_id)}", generate_json(doc), cookies }
35
+ end
36
+ def delete_doc(doc_id, rev)
37
+ api_request { RestClient.delete "#{address_port}/#{db_uri}/#{doc_uri(doc_id)}?rev=#{rev}", cookies }
38
+ end
39
+ def delete_doc!(doc_id)
40
+ document = get_doc(doc_id)
41
+ delete_doc(document[:_id], document[:_rev])
42
+ end
43
+ def get_doc(doc_id)
44
+ api_request { RestClient.get "#{address_port}/#{@database}/#{doc_id}", cookies }
45
+ end
46
+ def update_doc(doc_id, data)
47
+ api_request { RestClient.put "#{address_port}/#{db_uri}/#{doc_uri(doc_id)}", generate_json(data), cookies }
48
+ end
49
+ def edit_doc!(doc_id, data)
50
+ document = get_doc(doc_id)
51
+ document_with_rev = document.merge(data)
52
+ update_doc(doc_id, document_with_rev)
53
+ end
54
+ def view(design_doc_name, view_name, options = {})
55
+ api_request { RestClient.get "#{address_port}/#{db_uri}/#{URI.escape(design_doc_name)}/_view/#{URI.escape(view_name)}?#{options.to_query}", cookies }
56
+ end
57
+ def where(hash, options = {})
58
+ search_term = hash.values
59
+ index = hash.keys.join("_")
60
+ new_options = options.merge({startkey: search_term.to_s, endkey: search_term.to_s})
61
+ view!("_design/#{index}_keys_finder", "find_by_keys_#{index}", new_options)
62
+ rescue CouchdbException => e
63
+ add_multiple_finder(hash.keys)
64
+ view!("_design/#{index}_keys_finder", "find_by_keys_#{index}", new_options)
96
65
  end
97
- end
98
-
99
- #couchdb configuration api
100
- def self.set_config(data,auth_session = "")
101
- section = data[:section]
102
- key = data[:key]
103
- value = data[:value]
104
- json_data = Yajl::Encoder.encode(value)
105
- set_address
106
- begin
107
- response = RestClient.put "#{@address}:#{@port}/_config/#{URI.escape(section)}/#{URI.escape(key)}",json_data, {:cookies => {"AuthSession" => auth_session}}
108
- hash = Yajl::Parser.parse(response.to_str)
109
- rescue => e
110
- couch_error(e)
66
+ def security_object=(security_settings)
67
+ api_request { RestClient.put "#{address_port}/#{db_uri}/_security/", generate_json(security_settings), cookies }
111
68
  end
112
- end
113
-
114
- def self.delete_config(data,auth_session = "")
115
- section = data[:section]
116
- key = data[:key]
117
- set_address
118
- begin
119
- response = RestClient.delete "#{@address}:#{@port}/_config/#{URI.escape(section)}/#{URI.escape(key)}", {:cookies => {"AuthSession" => auth_session}}
120
- hash = Yajl::Parser.parse(response.to_str)
121
- rescue => e
122
- couch_error(e)
69
+ def security_object
70
+ api_request { RestClient.get "#{address_port}/#{db_uri}/_security/", cookies }
123
71
  end
124
- end
125
-
126
-
127
- def self.get_config(data,auth_session = "")
128
- section = data[:section]
129
- key = data[:key]
130
- set_address
131
- begin
132
- response = RestClient.get "#{@address}:#{@port}/_config/#{URI.escape(section)}/#{URI.escape(key)}", {:cookies => {"AuthSession" => auth_session}}
133
- hash = Yajl::Parser.parse(response.to_str)
134
- rescue => e
135
- couch_error(e)
72
+ def set_config(section, key, value)
73
+ !!(RestClient.put "#{address_port}/_config/#{URI.escape(section)}/#{URI.escape(key)}", value, cookies)
136
74
  end
137
- end
138
-
139
- #create a document
140
- def self.create_doc( doc,auth_session = "")
141
- db_name = doc[:database]
142
- doc_id = doc[:doc_id]
143
- data = doc[:data]
144
- json_data = Yajl::Encoder.encode(data)
145
- set_address
146
- begin
147
- response = RestClient.put "#{@address}:#{@port}/#{URI.escape(db_name)}/#{URI.escape(doc_id)}",json_data, {:cookies => {"AuthSession" => auth_session}}
148
- hash = Yajl::Parser.parse(response.to_str)
75
+ def get_config(section, key)
76
+ RestClient.get "#{address_port}/_config/#{URI.escape(section)}/#{URI.escape(key)}", cookies
149
77
  rescue => e
150
- couch_error(e)
78
+ raise_error(e)
151
79
  end
152
- end
153
-
154
- #edit a document
155
- def self.edit_doc(doc,auth_session = "")
156
- db_name = doc[:database]
157
- doc_id = doc[:doc_id]
158
- data = doc[:data]
159
- json_data = Yajl::Encoder.encode(data)
160
- set_address
161
- begin
162
- response = RestClient.put "#{@address}:#{@port}/#{URI.escape(db_name)}/#{URI.escape(doc_id)}", json_data, {:cookies => {"AuthSession" => auth_session}}
163
- hash = Yajl::Parser.parse(response.to_str)
80
+ def delete_config(section, key)
81
+ !!(RestClient.delete "#{address_port}/_config/#{URI.escape(section)}/#{URI.escape(key)}", cookies)
164
82
  rescue => e
165
- couch_error(e)
83
+ raise_error(e)
166
84
  end
167
- end
168
-
169
- #update a doc
170
- def self.update_doc(doc,auth_session = "")
171
- db_name = doc[:database]
172
- doc_id = doc[:doc_id]
173
- data = doc[:data]
174
- doc = {:database => db_name, :doc_id => doc_id}
175
- options = Couchdb.view doc,auth_session
176
- options = options.merge(data)
177
- doc = {:database => db_name, :doc_id => doc_id, :data => options}
178
- edit_doc doc,auth_session
179
- end
180
-
181
- #delete document
182
- def self.delete_doc(doc,auth_session = "")
183
- db_name = doc[:database]
184
- doc_id = doc[:doc_id]
185
- doc = {:database => db_name, :doc_id => doc_id}
186
- hash = Couchdb.view doc,auth_session
187
- doc = {:database => db_name, :doc_id => doc_id, :rev => hash["_rev"]}
188
- delete_rev(doc,auth_session)
189
- end
190
-
191
-
192
- #delete a doc by rev#
193
- def self.delete_rev(doc,auth_session = "")
194
- db_name = doc[:database]
195
- doc_id = doc[:doc_id]
196
- rev = doc[:rev]
197
- set_address
198
- begin
199
- response = RestClient.delete "#{@address}:#{@port}/#{URI.escape(db_name)}/#{URI.escape(doc_id)}?rev=#{rev}", {:cookies => {"AuthSession" => auth_session}}
200
- hash = Yajl::Parser.parse(response.to_str)
201
- rescue => e
202
- couch_error(e)
85
+ private
86
+ def view!(design_doc_name, view_name, options = {})
87
+ new_options = options.merge({include_docs: true})
88
+ result = view(design_doc_name, view_name, new_options)
89
+ rows = result[:rows]
90
+ rows.map { |row| row[:doc] }
203
91
  end
204
- end
205
-
206
-
207
- #create a database if one with the same name doesn't already exist
208
- def self.create(database_name,auth_session = "")
209
- set_address
210
- begin
211
- response = RestClient.put "#{@address}:#{@port}/#{URI.escape(database_name)}", {:content_type => :json},{:cookies => {"AuthSession" => auth_session}}
212
- hash = Yajl::Parser.parse(response.to_str)
213
- rescue => e
214
- couch_error(e)
92
+ def add_multiple_finder(keys)
93
+ view_name = keys.join("_")
94
+ condition = keys.join(" && doc.")
95
+ key = keys.join(",doc.")
96
+ design_doc_name = "#{view_name}_keys_finder"
97
+ design_doc = {
98
+ language: "javascript",
99
+ views: {
100
+ "find_by_keys_#{view_name}" => {
101
+ map: "function(doc){ if(doc.#{condition}) emit([doc.#{key}]);}"
102
+ }
103
+ }
104
+ }
105
+ create_doc "_design/#{design_doc_name}", design_doc
215
106
  end
216
- end
217
-
218
- #delete a database
219
- def self.delete(database_name,auth_session = "")
220
- set_address
221
- begin
222
- response = RestClient.delete "#{@address}:#{@port}/#{URI.escape(database_name)}", {:cookies => {"AuthSession" => auth_session}}
223
- hash = Yajl::Parser.parse(response.to_str)
224
- rescue => e
225
- couch_error(e)
226
- end
227
- end
228
-
229
- #return a list of all databases
230
- def self.all(auth_session = "")
231
- set_address
232
- begin
233
- response = RestClient.get "#{@address}:#{@port}/_all_dbs", {:cookies => {"AuthSession" => auth_session}}
234
- hash = Yajl::Parser.parse(response.to_str)
107
+ def api_request
108
+ response = yield
109
+ parse_json(response)
235
110
  rescue => e
236
- raise e
111
+ raise_error(e)
237
112
  end
238
- end
239
-
240
- ##view a document
241
- def self.view(doc,auth_session = "", options = {})
242
- set_address
243
- db_name = doc[:database]
244
- doc_id = doc[:doc_id]
245
- begin
246
- response = RestClient.get "#{@address}:#{@port}/#{db_name}/#{doc_id}",{:cookies => {"AuthSession" => auth_session}}
247
- hash = Yajl::Parser.parse(response.to_str, symbolize_keys(options))
248
- rescue => e
249
- couch_error(e)
250
- end
251
- end
252
-
253
- def self.get_params(options)
254
- params = ""
255
- if options.has_key?(:startkey)
256
- if options[:startkey].is_a? String
257
- params = 'startkey="' + options[:startkey] + '"'
258
- else
259
- params = 'startkey=' + options[:startkey].to_s # for complex keys
260
- end
113
+ def doc_uri(doc_id)
114
+ error_message = "Invalid Document ID: #{doc_id}"
115
+ raise(Leanback::InvalidDocumentID.new(error_message), error_message) unless doc_id.is_a?(String)
116
+ URI.escape(doc_id)
261
117
  end
262
- if options.has_key?(:endkey)
263
- if options[:endkey].is_a? String
264
- params = params + '&endkey="' + options[:endkey] + '"'
265
- else
266
- params = params + '&endkey=' + options[:endkey].to_s #for complex keys
267
- end
118
+ def db_uri
119
+ error_message = "Invalid database name: #{@database}"
120
+ raise(Leanback::InvalidDatabaseName.new(error_message), error_message) unless @database.is_a?(String)
121
+ URI.escape(@database)
268
122
  end
269
-
270
- if options.has_key?(:limit)
271
- params = params + "&" + "limit=" + options[:limit].to_s
123
+ def content_type
124
+ {content_type: :json}
272
125
  end
273
-
274
- if options.has_key?(:skip)
275
- params = params + "&" + "skip=" + options[:skip].to_s
126
+ def cookies
127
+ {cookies: {"AuthSession" => auth_session}}
276
128
  end
277
-
278
- if options.has_key?(:descending)
279
- params = params + "&" + "descending=true"
129
+ def address_port
130
+ "#{@address}:#{@port}"
280
131
  end
281
-
282
- return params
283
- end
284
-
285
-
286
- #query a permanent view
287
- def self.find(doc,auth_session = "", key=nil, options = {})
288
- set_address
289
- db_name = doc[:database]
290
- design_doc_name = doc[:design_doc]
291
- view_name = doc[:view]
292
- params = get_params(options)
293
-
294
- begin
295
- if key == nil
296
- response = RestClient.get "#{@address}:#{@port}/#{db_name}/_design/#{design_doc_name}/_view/#{view_name}?#{URI.escape(params)}",{:cookies => {"AuthSession" => auth_session}}
297
- else
298
- key = URI.escape('?key="' + key + '"')
299
- response = RestClient.get "#{@address}:#{@port}/#{db_name}/_design/#{design_doc_name}/_view/#{view_name}#{key}&#{URI.escape(params)}" ,{:cookies => {"AuthSession" => auth_session}}
300
- end
301
- hash = Yajl::Parser.parse(response.to_str, symbolize_keys(options))
302
- data = []
303
- rows = hash["rows"] unless hash["rows"].nil?
304
- rows = hash[:rows] unless hash[:rows].nil?
305
- rows.each do |row|
306
- value = row["value"] unless row["value"].nil?
307
- value = row[:value] unless row[:value].nil?
308
- data << value
309
- end
310
- return data
311
- rescue => e
312
- couch_error(e)
313
- end
314
- end
315
-
316
- #create a design document with views
317
- def self.create_design(doc,auth_session = "")
318
- set_address
319
- db_name = doc[:database]
320
- design_doc_name = doc[:design_doc]
321
- json_doc_name = doc[:json_doc]
322
-
323
- begin
324
- #bind json doc to string
325
- message_template = ERB.new File.new(json_doc_name).read
326
- str = message_template.result(binding)
327
- rescue => e
328
- raise e
132
+ def parse_json(json_doc)
133
+ JSON.parse(json_doc, symbolize_names: true)
329
134
  end
330
-
331
- begin
332
- response = RestClient.put "#{@address}:#{@port}/#{db_name}/_design/#{design_doc_name}", str, {:cookies => {"AuthSession" => auth_session}}
333
- hash = Yajl::Parser.parse(response.to_str)
334
- rescue => e
335
- couch_error(e)
135
+ def generate_json(data)
136
+ JSON.generate(data)
336
137
  end
337
- end
338
-
339
- #Query view, create view on fly if it dosen't already exist
340
- def self.find_on_fly(doc,auth_session = "",key = nil, options = {})
341
- db_name = doc[:database]
342
- design_doc = doc[:design_doc]
343
- view = doc[:view]
344
- json_doc = doc[:json_doc]
345
- query_info = {:database => db_name, :design_doc => design_doc, :view => view}
346
- begin
347
- if( key == nil)
348
- docs = find(query_info,auth_session,key=nil,options)
138
+ def raise_error(exeception)
139
+ if exeception.respond_to?('response')
140
+ response = parse_json(exeception.response)
141
+ raise(CouchdbException.new(response), response)
349
142
  else
350
- docs = find(query_info,auth_session,key,options)
143
+ raise(exeception)
351
144
  end
352
- rescue CouchdbException => e
353
- document = { :database => db_name, :design_doc => design_doc, :json_doc => json_doc}
354
- create_design document,auth_session
355
- if( key == nil)
356
- docs = find(query_info,auth_session,key=nil,options)
357
- else
358
- docs = find(query_info,auth_session,key,options)
359
- end
360
- end
361
- return docs
362
- end
363
-
364
-
365
- #add a finder method to the database
366
- #this creates a find by key method
367
- def self.add_finder(options,auth_session = "")
368
- set_address
369
- db_name = options[:database]
370
- key = options[:key]
371
- design_doc_name = key + '_finder'
372
-
373
- view ='{
374
- "language" : "javascript",
375
- "views" :{
376
- "find_by_'+key+'" : {
377
- "map" : "function(doc){ if(doc.'+key+') emit(doc.'+key+',doc);}"
378
- }
379
- }
380
- }'
381
-
382
- begin
383
- response = RestClient.put "#{@address}:#{@port}/#{db_name}/_design/#{design_doc_name}", view, {:cookies => {"AuthSession" => auth_session}}
384
- rescue => e
385
- couch_error(e)
386
- end
387
- end
388
-
389
- #add a multiple finder method to the database
390
- #this creates a find by keys method
391
- def self.add_multiple_finder(options,auth_session = "")
392
- set_address
393
- db_name = options[:database]
394
- keys = options[:keys]
395
- view_name = keys.join("_")
396
- key = keys.join(",doc.")
397
- condition = keys.join(" && doc.")
398
- design_doc_name = "#{view_name}_keys_finder"
399
-
400
- view = '{
401
- "language" : "javascript",
402
- "views" :{
403
- "find_by_keys_'+view_name+'" : {
404
- "map" : "function(doc){ if(doc.'+condition+') emit([doc.'+key+'],doc);}"
405
- }
406
- }
407
- }'
408
-
409
- begin
410
- response = RestClient.put "#{@address}:#{@port}/#{db_name}/_design/#{design_doc_name}", view, {:cookies => {"AuthSession" => auth_session}}
411
- rescue => e
412
- couch_error(e)
413
- end
414
- end
415
-
416
- #add a multiple counter method to the database
417
- #this creates a count by keys method
418
- def self.add_multiple_counter(options,auth_session = "")
419
- set_address
420
- db_name = options[:database]
421
- keys = options[:keys]
422
- view_name = keys.join("_")
423
- key = keys.join(",doc.")
424
- condition = keys.join(" && doc.")
425
- design_doc_name = "#{view_name}_keys_counter"
426
- view = '{
427
- "language" : "javascript",
428
- "views" :{
429
- "count_by_keys_'+view_name+'" : {
430
- "map" : "function(doc){ if(doc.'+condition+') emit([doc.'+key+'],null);}", "reduce": "_count"
431
- }
432
- }
433
- }'
434
-
435
- begin
436
- response = RestClient.put "#{@address}:#{@port}/#{db_name}/_design/#{design_doc_name}", view, {:cookies => {"AuthSession" => auth_session}}
437
- rescue => e
438
- couch_error(e)
439
145
  end
440
- end
441
-
442
- #add a counter method to the database
443
- #this creates a count method that counts documents by key
444
- def self.add_counter(options,auth_session = "")
445
- set_address
446
- db_name = options[:database]
447
- key = options[:key]
448
- design_doc_name = key + '_counter'
449
-
450
- view ='{
451
- "language" : "javascript",
452
- "views" :{
453
- "count_'+key+'" : {
454
- "map" : "function(doc){ if(doc.'+key+') emit(doc.'+key+',null);}", "reduce": "_count"
455
- }
456
- }
457
- }'
458
-
459
- begin
460
- response = RestClient.put "#{@address}:#{@port}/#{db_name}/_design/#{design_doc_name}", view, {:cookies => {"AuthSession" => auth_session}}
146
+ def auth_session
147
+ return "" if @username.nil? && @password.nil?
148
+ data = "name=#{@username}&password=#{@password}"
149
+ response = RestClient.post "#{@address}:#{@port}/_session/", data, {content_type: 'application/x-www-form-urlencoded'}
150
+ hash = response.cookies
151
+ hash["AuthSession"]
461
152
  rescue => e
462
- couch_error(e)
463
- end
464
- end
465
-
466
- #count by key
467
- def self.count(options,auth_session = "")
468
- set_address
469
- db_name = options[:database]
470
- index = options.keys[1].to_s
471
- search_term = options.values[1]
472
- design_doc_name = "#{index}_counter"
473
- view_name = "count_#{index}"
474
-
475
- begin
476
- view = { :database => db_name, :design_doc => design_doc_name, :view => view_name}
477
- docs = find view,auth_session,search_term
478
- rescue CouchdbException => e
479
- #add a counter index if one doesn't already exist in the database
480
- #then count_by_key
481
- add_counter({:database => db_name, :key => index},auth_session)
482
- docs = find view,auth_session,search_term
483
- end
484
- count = docs[0]
485
- return count.to_i
486
- end
487
-
488
- #count by keys
489
- #example:
490
- #hash = {:firstname =>'john', :gender => 'male' }
491
- #Couchdb.count_by_keys({:database => 'contacts', :keys => hash},auth_session)
492
- def self.count_by_keys(options,auth_session = "", params = {})
493
- set_address
494
- db_name = options[:database]
495
- keys = []
496
- search_term = []
497
- hash = options[:keys]
498
-
499
- hash.each do |k,v|
500
- keys << k
501
- search_term << v
502
- end
503
- index = keys.join("_")
504
- design_doc_name = "#{index}_keys_counter"
505
- view_name = "count_by_keys_#{index}"
506
- params[:startkey] = search_term
507
- params[:endkey] = search_term
508
-
509
- begin
510
- view = { :database => db_name, :design_doc => design_doc_name, :view => view_name}
511
- docs = find view,auth_session,key=nil,params
512
- rescue CouchdbException => e
513
- #add a finder/index if one doesn't already exist in the database
514
- #then find_by_keys
515
- add_multiple_counter({:database => db_name, :keys => keys},auth_session)
516
- docs = find view,auth_session,key=nil,params
517
- end
518
- count = docs[0]
519
- return count.to_i
520
- end
521
-
522
- #find by key
523
- def self.find_by(options,auth_session = "", params = {})
524
- set_address
525
- db_name = options[:database]
526
- index = options.keys[1].to_s
527
- search_term = options.values[1]
528
- design_doc_name = "#{index}_finder"
529
- view_name = "find_by_#{index}"
530
-
531
- begin
532
- view = { :database => db_name, :design_doc => design_doc_name, :view => view_name}
533
- docs = find view,auth_session,search_term,params
534
- rescue CouchdbException => e
535
- #add a finder/index if one doesn't already exist in the database
536
- #then find_by_key
537
- add_finder({:database => db_name, :key => index},auth_session)
538
- docs = find view,auth_session,search_term,params
539
- end
540
- return docs
541
- end
542
-
543
- #find by keys
544
- #example:
545
- #hash = {:firstname =>'john', :gender => 'male' }
546
- #Couchdb.find_by_keys({:database => 'contacts', :keys => hash},auth_session)
547
- def self.find_by_keys(options,auth_session = "", params = {})
548
- set_address
549
- db_name = options[:database]
550
- keys = []
551
- search_term = []
552
- hash = options[:keys]
553
-
554
- hash.each do |k,v|
555
- keys << k
556
- search_term << v
557
- end
558
- index = keys.join("_")
559
- design_doc_name = "#{index}_keys_finder"
560
- view_name = "find_by_keys_#{index}"
561
- params[:startkey] = search_term
562
- params[:endkey] = search_term
563
-
564
- begin
565
- view = { :database => db_name, :design_doc => design_doc_name, :view => view_name}
566
- docs = find view,auth_session,key=nil,params
567
- rescue CouchdbException => e
568
- #add a finder/index if one doesn't already exist in the database
569
- #then find_by_keys
570
- add_multiple_finder({:database => db_name, :keys => keys},auth_session)
571
- docs = find view,auth_session,key=nil,params
572
- end
573
- return docs
574
- end
575
-
576
- #return a list of all docs in the database
577
- def self.docs_from(database_name,auth_session = "")
578
- set_address
579
- begin
580
- response = RestClient.get "#{@address}:#{@port}/#{URI.escape(database_name)}/_all_docs?include_docs=true",{:cookies => {"AuthSession" => auth_session}}
581
- hash = Yajl::Parser.parse(response.to_str)
582
- rows = hash["rows"]
583
- count = 0
584
- rows.each do |row|
585
- rows[count] = row["doc"]
586
- count += 1
587
- end
588
- return rows
589
- rescue => e
590
- couch_error(e)
591
- end
592
- end
593
-
594
- def self.symbolize_keys(options)
595
- return {symbolize_keys: true} if options[:symbolize_keys]
596
- return {}
597
- end
598
-
599
- private_class_method :symbolize_keys
600
-
601
- class << self
602
- attr_accessor :address
603
- attr_accessor :port
604
-
605
- def set_address()
606
- if @address == nil
607
- @address = 'http://127.0.0.1'
608
- end
609
- if @port == nil
610
- @port = '5984'
611
- end
153
+ raise_error(e)
612
154
  end
613
155
  end
614
156
  end