dolly 1.1.7 → 3.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +78 -0
  3. data/lib/dolly/attachment.rb +29 -0
  4. data/lib/dolly/bulk_document.rb +27 -26
  5. data/lib/dolly/class_methods_delegation.rb +15 -0
  6. data/lib/dolly/collection.rb +32 -65
  7. data/lib/dolly/configuration.rb +35 -10
  8. data/lib/dolly/connection.rb +93 -22
  9. data/lib/dolly/depracated_database.rb +24 -0
  10. data/lib/dolly/document.rb +61 -208
  11. data/lib/dolly/document_creation.rb +27 -0
  12. data/lib/dolly/document_state.rb +66 -0
  13. data/lib/dolly/document_type.rb +47 -0
  14. data/lib/dolly/exceptions.rb +32 -0
  15. data/lib/dolly/framework_helper.rb +7 -0
  16. data/lib/dolly/identity_properties.rb +29 -0
  17. data/lib/dolly/mango.rb +156 -0
  18. data/lib/dolly/mango_index.rb +73 -0
  19. data/lib/dolly/properties.rb +36 -0
  20. data/lib/dolly/property.rb +76 -46
  21. data/lib/dolly/property_manager.rb +53 -0
  22. data/lib/dolly/property_set.rb +23 -0
  23. data/lib/dolly/query.rb +63 -75
  24. data/lib/dolly/query_arguments.rb +35 -0
  25. data/lib/dolly/request.rb +12 -107
  26. data/lib/dolly/request_header.rb +26 -0
  27. data/lib/dolly/timestamp.rb +24 -0
  28. data/lib/dolly/version.rb +1 -1
  29. data/lib/dolly/view_query.rb +21 -0
  30. data/lib/dolly.rb +2 -23
  31. data/lib/{dolly → railties}/railtie.rb +2 -1
  32. data/lib/refinements/hash_refinements.rb +27 -0
  33. data/lib/refinements/string_refinements.rb +28 -0
  34. data/lib/tasks/db.rake +27 -4
  35. data/test/bulk_document_test.rb +8 -5
  36. data/test/document_test.rb +130 -95
  37. data/test/document_type_test.rb +28 -0
  38. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  39. data/test/dummy/log/test.log +46417 -46858
  40. data/test/inheritance_test.rb +23 -0
  41. data/test/mango_index_test.rb +64 -0
  42. data/test/mango_test.rb +273 -0
  43. data/test/property_manager_test.rb +18 -0
  44. data/test/test_helper.rb +63 -18
  45. data/test/view_query_test.rb +27 -0
  46. metadata +67 -140
  47. data/Rakefile +0 -11
  48. data/lib/dolly/bulk_error.rb +0 -16
  49. data/lib/dolly/db_config.rb +0 -20
  50. data/lib/dolly/interpreter.rb +0 -5
  51. data/lib/dolly/logger.rb +0 -9
  52. data/lib/dolly/name_space.rb +0 -28
  53. data/lib/dolly/timestamps.rb +0 -21
  54. data/lib/exceptions/dolly.rb +0 -47
  55. data/test/collection_test.rb +0 -59
  56. data/test/configuration_test.rb +0 -9
  57. data/test/dummy/README.rdoc +0 -28
  58. data/test/dummy/Rakefile +0 -6
  59. data/test/dummy/app/assets/javascripts/application.js +0 -13
  60. data/test/dummy/app/assets/stylesheets/application.css +0 -13
  61. data/test/dummy/app/controllers/application_controller.rb +0 -5
  62. data/test/dummy/app/helpers/application_helper.rb +0 -2
  63. data/test/dummy/app/views/layouts/application.html.erb +0 -14
  64. data/test/dummy/bin/bundle +0 -3
  65. data/test/dummy/bin/rails +0 -4
  66. data/test/dummy/bin/rake +0 -4
  67. data/test/dummy/config/application.rb +0 -27
  68. data/test/dummy/config/boot.rb +0 -5
  69. data/test/dummy/config/couchdb.yml +0 -13
  70. data/test/dummy/config/environment.rb +0 -5
  71. data/test/dummy/config/environments/development.rb +0 -29
  72. data/test/dummy/config/environments/production.rb +0 -80
  73. data/test/dummy/config/environments/test.rb +0 -36
  74. data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
  75. data/test/dummy/config/initializers/inflections.rb +0 -16
  76. data/test/dummy/config/initializers/mime_types.rb +0 -5
  77. data/test/dummy/config/initializers/secret_token.rb +0 -12
  78. data/test/dummy/config/initializers/session_store.rb +0 -3
  79. data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
  80. data/test/dummy/config/locales/en.yml +0 -23
  81. data/test/dummy/config/routes.rb +0 -56
  82. data/test/dummy/config.ru +0 -4
  83. data/test/dummy/lib/couch_rest_adapter/railtie.rb +0 -10
  84. data/test/dummy/public/404.html +0 -58
  85. data/test/dummy/public/422.html +0 -58
  86. data/test/dummy/public/500.html +0 -57
  87. data/test/dummy/public/favicon.ico +0 -0
  88. data/test/factories/factories.rb +0 -8
  89. data/test/request_test.rb +0 -25
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 45fa7180b3da598f09d522101ae72b4d35bff7d1
4
- data.tar.gz: 3eceb48ee307b83c6b379e2bdacd7530cafbe0f5
2
+ SHA256:
3
+ metadata.gz: b4a7f73673dc9600d2451b6ae0dd1ed5ca8c792f671f1a115405b751610b9077
4
+ data.tar.gz: 7765f1a58d5515aebce77a79fdde6e0aad8e8928867e39c45a26ac5321ef7cb9
5
5
  SHA512:
6
- metadata.gz: 2e3e721bce03f02a766d159950956ac4dff0394cf437f1fc06117ad5755ee9a0e8da0baa004c2c247710c9909fe36a5be2815ea78eb5c4371700e9376ea1b9e1
7
- data.tar.gz: 3215f948add4eb9b8f7048bafcd0a98e01c91ce09c4c4601a0c58d4a9863f1d2aa96a88de65f62d70e32945493bc82c7b9d43a25726457308321a1022e3c65f5
6
+ metadata.gz: 9430a6c2bc2b951442751b3192778a7d73985d6cb3fa0864f5a9529695d20fec13cd4b451d8232f06dfc0a27cc6897acae734eb979c52b63a60d81aa7c5061c6
7
+ data.tar.gz: a46dd510d441efffe1b7998e64b5806fba6fee10470dc3c38d78a4be49bd18d48b50ad9d84b630ef0c04895934214821162a46e3bc3888a71c02171623bffdb6
data/README.md ADDED
@@ -0,0 +1,78 @@
1
+ # Dolly3
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/dolly3`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'dolly3'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install dolly3
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/dolly3.
36
+
37
+
38
+ ## Migrating from couch 1.x to 2.x
39
+
40
+ [Official docs](https://docs.couchdb.org/en/2.3.1/install/index.html)
41
+
42
+
43
+ You will need to uninstall the couchdb service with brew
44
+
45
+ `brew services stop couchdb`
46
+ `brew services uninstall couchdb`
47
+
48
+ Download the application from the following source
49
+
50
+ http://couchdb.apache.org/#download
51
+
52
+ launch fauxton and check your installation
53
+
54
+ Copy [this file](https://github.com/apache/couchdb/blob/master/rel/overlay/bin/couchup) into your filesystem
55
+
56
+
57
+ make it executable
58
+
59
+ `chmod +x couchup.py`
60
+
61
+ and run it
62
+
63
+ `./couchup.py -h`
64
+
65
+ You might need to install python 3 and pip3 and the following libs
66
+
67
+ `pip3 install requests progressbar2`
68
+
69
+ move your .couch files into the specified `database_dir` in your [fauxton config](http://127.0.0.1:5984/_utils/#_config/couchdb@localhost)
70
+
71
+
72
+ ```
73
+ $ ./couchup list # Shows your unmigrated 1.x databases
74
+ $ ./couchup replicate -a # Replicates your 1.x DBs to 2.x
75
+ $ ./couchup rebuild -a # Optional; starts rebuilding your views
76
+ $ ./couchup delete -a # Deletes your 1.x DBs (careful!)
77
+ $ ./couchup list # Should show no remaining databases!
78
+ ```
@@ -0,0 +1,29 @@
1
+ require 'base64'
2
+
3
+ module Dolly
4
+ module Attachment
5
+ def attach_file! file_name, mime_type, body, opts={}
6
+ attach_file file_name, mime_type, body, opts
7
+ save
8
+ end
9
+
10
+ def attach_file file_name, mime_type, body, opts={}
11
+ if opts[:inline]
12
+ attach_inline_file file_name, mime_type, body
13
+ else
14
+ attach_standalone_file file_name, mime_type, body
15
+ end
16
+ end
17
+
18
+ def attach_inline_file file_name, mime_type, body
19
+ attachment_data = { file_name.to_s => { 'content_type' => mime_type,
20
+ 'data' => Base64.encode64(body)} }
21
+ doc['_attachments'] ||= {}
22
+ doc['_attachments'].merge! attachment_data
23
+ end
24
+
25
+ def attach_standalone_file file_name, mime_type, body
26
+ self.class.connection.attach id_as_resource, CGI.escape(file_name), body, { 'Content-Type' => mime_type }
27
+ end
28
+ end
29
+ end
@@ -1,37 +1,34 @@
1
- require 'dolly/bulk_error'
2
-
3
1
  module Dolly
4
2
  class BulkDocument
5
- include Enumerable
6
3
  extend Forwardable
7
4
 
8
- DOC_NAME = "_bulk_docs".freeze
5
+ DOC_NAME = '_bulk_docs'
9
6
 
10
- attr_reader :payload, :database
7
+ attr_reader :payload, :connection
11
8
  attr_accessor :errors, :response
12
9
 
13
10
  def_delegators :docs, :[], :<<
14
11
 
15
- def initialize database, ary = []
16
- @database = database
12
+ def initialize(connection, ary = [])
13
+ @connection = connection
17
14
  @payload = Hash.new
18
- self.payload[:docs] = ary
15
+ payload[:docs] = ary
19
16
  end
20
17
 
21
18
  def docs
22
- self.payload[:docs]
19
+ payload[:docs]
23
20
  end
24
21
 
25
22
  def save
26
23
  return if docs.empty?
27
- self.response = JSON::parse self.database.post(DOC_NAME, json_payload)
24
+ self.response = connection.post(DOC_NAME, docs_payload)
28
25
  build_errors
29
26
  update_revs
30
27
  end
31
28
 
32
29
  def delete
33
30
  return if docs.empty?
34
- JSON::parse database.post DOC_NAME, json_payload("_deleted" => true)
31
+ connection.post DOC_NAME, json_payload(_deleted: true)
35
32
  end
36
33
 
37
34
  def clear
@@ -45,41 +42,45 @@ module Dolly
45
42
  end
46
43
 
47
44
  private
45
+
48
46
  def update_revs
49
- self.response.each do |doc|
50
- next if doc['error']
51
- item = self.payload[:docs].detect{|d| d.id == doc['id']}
47
+ response.each do |doc|
48
+ next if doc[:error]
49
+ item = payload[:docs].detect { |d| d.id == doc[:id] }
50
+
52
51
  if item.nil?
53
- self.errors << BulkError.new({"error" => "Document saved but not local rev updated.", "reason" => "Document with id #{doc['id']} on bulk doc was not found in payload.", "obj" => nil})
52
+ errors << response_error(item)
54
53
  next
55
54
  end
56
- item.doc['_rev'] = doc['rev']
57
- self.payload[:docs].delete item
55
+
56
+ item.rev = doc[:rev]
57
+ payload[:docs].delete(item)
58
58
  end
59
+
59
60
  clean_response
60
61
  end
61
62
 
62
63
  def clean_response
63
- self.response.delete_if {|doc| !doc['error'] }
64
+ response.delete_if { |d| !d[:error] }
64
65
  end
65
66
 
66
67
  def build_errors
67
68
  self.errors = response_errors.map do |err|
68
- obj = self.payload[:docs].detect{|d| d.id == err['id']} if err['id']
69
- BulkError.new err.merge!("obj" => obj)
69
+ obj = payload[:docs].detect { |d| d.id == err[:id]} if err[:id]
70
+ BulkError.new err.merge!(obj: obj)
70
71
  end
71
72
  end
72
73
 
73
- def bare_docs
74
- self.payload[:docs].map(&:doc)
74
+ def docs_payload opts = {}
75
+ { docs: docs.map {|d| d.to_h.merge(opts) } }
75
76
  end
76
77
 
77
- def json_payload opts = {}
78
- {docs: bare_docs.map{|d| d.merge(opts)} }.to_json
78
+ def response_errors
79
+ self.response.select{ |d| d[:error] }
79
80
  end
80
81
 
81
- def response_errors
82
- self.response.select{|d| d['error']}
82
+ def response_error(item)
83
+ BulkError.new(error: 'Document saved but not local rev updated.', reason: "Document with id #{item} on bulk doc was not found in payload.", obj: nil)
83
84
  end
84
85
  end
85
86
  end
@@ -0,0 +1,15 @@
1
+ module Dolly
2
+ module ClassMethodsDelegation
3
+ def connection
4
+ self.class.connection
5
+ end
6
+
7
+ def property_clean_doc(doc)
8
+ self.class.property_clean_doc(doc)
9
+ end
10
+
11
+ def database
12
+ self.class.database
13
+ end
14
+ end
15
+ end
@@ -1,88 +1,55 @@
1
1
  module Dolly
2
- class Collection < DelegateClass(Set)
3
- attr_accessor :rows
4
- attr_writer :json, :docs_class
2
+ class Collection < DelegateClass(Array)
3
+ attr_reader :options
5
4
 
6
- def initialize str, docs_class
7
- @docs_class = docs_class
8
- @json = str
9
- initial = []
10
- super(initial)
11
- load
5
+ def initialize(rows: [], options: {})
6
+ @options = options
7
+ #TODO: We should raise an exception if one of the
8
+ # requested documents is missing
9
+ super rows[:rows].map(&collect_docs).compact
12
10
  end
13
11
 
14
- def last
15
- to_a.last
12
+ def first_or_all(forced_first = false)
13
+ return self if forced_first
14
+ single? ? first : self
16
15
  end
17
16
 
18
- def update_properties! properties ={}
19
- properties.each do |key, value|
20
-
21
- regex = %r{
22
- \"#{key}\": # find key definition in json string
23
- ( # start value group
24
- \"[^\"]*\" # find anything (even empty) between \" and \"
25
- | # logical OR
26
- null #literal null value
27
- ) # end value group
28
- }x
29
-
30
- raise Dolly::MissingPropertyError unless json.match regex
31
- json.gsub! regex, "\"#{key}\":\"#{value}\""
32
- end
33
-
34
- BulkDocument.new(Dolly::Document.database, to_a).save
35
- clear
36
- load
37
- self
17
+ def single?
18
+ size <= 1
38
19
  end
39
20
 
40
- def each &block
41
- load if empty?
42
- super &block
43
- #TODO: returning nil to avoid extra time serializing set.
44
- nil
45
- end
21
+ private
46
22
 
47
- def rows= ary
48
- ary.each do |r|
49
- next unless r['doc']
50
- properties = r['doc']
51
- id = properties.delete '_id'
52
- rev = properties.delete '_rev' if properties['_rev']
53
- document = (docs_class || doc_class(id)).new properties
54
- document.doc = properties.merge({'_id' => id, '_rev' => rev})
55
- self << document
23
+ def collect_docs
24
+ lambda do |row|
25
+ next unless collectable_row?(row)
26
+ klass = Object.const_get(doc_model(row))
27
+ klass.from_doc(row[:doc])
56
28
  end
57
29
  end
58
30
 
59
- def load
60
- parsed = JSON::parse json
61
- self.rows = parsed['rows']
31
+ def doc_model(doc)
32
+ options[:doc_type] || constantize_key(doc[:doc_type]) || constantize_key(doc_type_for(doc[:id]))
62
33
  end
63
34
 
64
- def to_json options = {}
65
- load if empty?
66
- map{|r| r.doc }.to_json(options)
35
+ def doc_type_for(key)
36
+ return false if key.nil?
37
+ key.match(%r{^([^/]+)/})[1]
67
38
  end
68
39
 
69
- private
70
- def docs_class
71
- @docs_class
40
+ def constantize_key(key)
41
+ return false if key.nil?
42
+ key.split('_').collect(&:capitalize).join
72
43
  end
73
44
 
74
- def doc_class id
75
- # TODO: We need to improve and document the way we return
76
- # multiple types when querying from a class, as it might
77
- # be confusing. We *could* also get dolly to parse the result
78
- # before sending it back to the client.
79
- doc_class = id[/^[a-z_]+/].camelize.constantize
80
- docs_class == doc_class ? docs_class : doc_class
45
+ def collectable_row?(row)
46
+ !deleted_doc?(row) && row[:error].nil?
81
47
  end
82
48
 
83
- def json
84
- @json
49
+ def deleted_doc?(row)
50
+ value = row&.fetch(:value, {})
51
+ return false unless value.is_a? Hash
52
+ value.fetch(:deleted, false)
85
53
  end
86
-
87
54
  end
88
55
  end
@@ -1,18 +1,43 @@
1
- require 'dolly/logger'
1
+ # frozen_string_literal: true
2
+ require 'erb'
2
3
 
3
4
  module Dolly
4
- class Configuration
5
- attr_accessor :log_requests, :log_path, :log
5
+ module Configuration
6
+ attr_writer :config_file
6
7
 
7
- def initialize
8
- @log_requests = false
9
- @log_path = $stdout
10
- @log = :dolly
8
+ def env
9
+ @env ||= configuration[db.to_s]
11
10
  end
12
11
 
13
- def logger
14
- return Rails.logger if log.to_sym == :rails
15
- Dolly::Logger.new self
12
+ def base_uri
13
+ "#{protocol}#{host}#{port}"
14
+ end
15
+
16
+ def protocol
17
+ "#{env['protocol']}://"
18
+ end
19
+
20
+ def host
21
+ env['host']
22
+ end
23
+
24
+ def port
25
+ return unless env['port']
26
+ ":#{env['port']}"
27
+ end
28
+
29
+ def db_name
30
+ env['name']
31
+ end
32
+
33
+ def configuration
34
+ @config_data ||= File.read(config_file)
35
+ raise Dolly::InvalidConfigFileError if @config_data&.empty?
36
+ YAML::load(ERB.new(@config_data).result)[app_env.to_s]
37
+ end
38
+
39
+ def config_file
40
+ @config_file ||= File.join('config', 'couchdb.yml')
16
41
  end
17
42
  end
18
43
  end
@@ -1,42 +1,113 @@
1
- require "dolly/request"
2
- require "dolly/name_space"
3
- require "dolly/db_config"
4
- require "dolly/bulk_document"
1
+ require 'curb'
2
+ require 'oj'
3
+ require 'cgi'
4
+ require 'net/http'
5
+ require 'dolly/request_header'
6
+ require 'dolly/exceptions'
7
+ require 'dolly/configuration'
8
+ require 'refinements/string_refinements'
9
+ require 'dolly/framework_helper'
5
10
 
6
11
  module Dolly
7
- module Connection
8
- include Dolly::NameSpace
9
- include Dolly::DbConfig
12
+ class Connection
13
+ include Dolly::Configuration
14
+ include Dolly::FrameworkHelper
15
+ attr_reader :db, :app_env
10
16
 
11
- @@design_doc = nil
17
+ DEFAULT_HEADER = { 'Content-Type' => 'application/json', 'Accept' => 'application/json' }
18
+ SECURE_PROTOCOL = 'https'
19
+ DEFAULT_DATABASE = :default
12
20
 
13
- def database
14
- @database ||= Request.new(env)
21
+ using StringRefinements
22
+
23
+ def initialize db = DEFAULT_DATABASE, app_env = :development
24
+ @db = db
25
+ @app_env = app_env
26
+ end
27
+
28
+ def get(resource, data = {})
29
+ query = { query: values_to_json(data) } if data
30
+ request :get, resource, query
31
+ end
32
+
33
+ def post resource, data
34
+ request :post, resource.cgi_escape, data
15
35
  end
16
36
 
17
- def bulk_document
18
- @bulk_document ||= BulkDocument.new(database)
37
+ def put resource, data
38
+ request :put, resource.cgi_escape, data
19
39
  end
20
40
 
21
- def bulk_save
22
- bulk_document.save
41
+ def delete resource, rev = nil, escape: true
42
+ query = "?rev=#{rev}" if rev
43
+ resource = "#{escape ? resource.cgi_escape : resource}#{query}"
44
+ request :delete, resource
23
45
  end
24
46
 
25
- def database_name value
26
- @@database_name ||= value
47
+ def view resource, opts
48
+ request :get, resource, query: values_to_json({include_docs: true}.merge!(opts))
27
49
  end
28
50
 
29
- def default_doc
30
- "#{design_doc}/_view/find"
51
+ def attach resource, attachment_name, data, headers = {}
52
+ request :put, "#{resource.cgi_escape}/#{attachment_name}", { _body: data }.merge(headers: headers)
31
53
  end
32
54
 
33
- def design_doc
34
- "_design/#{env["design"]}"
55
+ def uuids opts = {}
56
+ tools("_uuids", opts)[:uuids]
35
57
  end
36
58
 
37
- def next_id
38
- namespace database.uuids.first
59
+ def stats
60
+ get("/#{db_name}")
61
+ end
62
+
63
+ def tools path, opts = nil
64
+ request(:get, "/#{path}", opts)
65
+ end
66
+
67
+ def request(method, resource, data = {})
68
+ headers = Dolly::HeaderRequest.new(data&.delete(:headers))
69
+ data&.merge!(data&.delete(:query) || {})
70
+ db_resource = (resource =~ %r{^/}) ? resource : "/#{db_name}/#{resource}"
71
+ uri = URI("#{base_uri}#{db_resource}")
72
+ conn = curl_method_call(method, uri, data) do |curl|
73
+ if env['username'].present?
74
+ curl.http_auth_types = :basic
75
+ curl.username = env['username']
76
+ curl.password = env['password'].to_s
77
+ end
78
+
79
+ headers.each { |k, v| curl.headers[k] = v } if headers.present?
80
+ end
81
+ response_format(conn, method)
39
82
  end
40
83
 
84
+ private
85
+
86
+ def curl_method_call(method, uri, data, &block)
87
+ return Curl::Easy.http_head(uri.to_s, &block) if method.to_sym == :head
88
+ return Curl.delete(uri.to_s, &block) if method.to_sym == :delete
89
+ return Curl.send(method, uri, data, &block) if method.to_sym == :get
90
+ Curl.send(method, uri.to_s, data.to_json, &block)
91
+ end
92
+
93
+ def response_format(res, method)
94
+ raise Dolly::ResourceNotFound if res.status.to_i == 404
95
+ raise Dolly::ServerError.new(res.status.to_i) if (400..600).include? res.status.to_i
96
+ return res.header_str if method == :head
97
+
98
+ data = Oj.load(res.body_str, symbol_keys: true)
99
+ return data unless rails?
100
+ data.with_indifferent_access
101
+ rescue Oj::ParseError
102
+ res.body_str
103
+ end
104
+
105
+ def values_to_json hash
106
+ hash.each_with_object({}) { |(k,v), h| h[k] = v.is_a?(Numeric) ? v : v.to_json }
107
+ end
108
+
109
+ def to_query(string)
110
+ string.map { |k, v| "#{k}=#{v}" }.sort * '&'
111
+ end
41
112
  end
42
113
  end
@@ -0,0 +1,24 @@
1
+ module Dolly
2
+ module DepracatedDatabase
3
+ Database = Struct.new(:connection) do
4
+ def request *args
5
+ connection.request *args
6
+ end
7
+
8
+ def post *args
9
+ connection.post *args
10
+ end
11
+ end
12
+
13
+ def view *args
14
+ opts = args.pop if args.last.is_a? Hash
15
+ opts ||= {}
16
+ connection.view *args, opts.merge(include_docs: true)
17
+ end
18
+
19
+ def database
20
+ warn "[DEPRECATION] `database` is deprecated. Please use `connection` instead."
21
+ Database.new(connection)
22
+ end
23
+ end
24
+ end