dolly 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ad0bbb9be5691d6b00639f4af6d401657f7892a9
4
- data.tar.gz: 00f1dbd0c0fb0c29b3ffedbde617875fe2c737e9
3
+ metadata.gz: b43649cf960832da484ca9d972ad118313156e01
4
+ data.tar.gz: ae8cbcfa0414e80e2a7ba881737f810e3582c232
5
5
  SHA512:
6
- metadata.gz: 2e9514240a3f8e2a2e9c62d6142aa45cb534ba2d935d3c11789cbf039e0a43e500066de6b9c9db20a04bc68e76833bbd57a38d4049f86d90d3ef9448e31f33cc
7
- data.tar.gz: 4fbb5496d005ad2110ce3268f42249a3e62116ddbf41ac9c92b8b8bc30470a6ad561b82cc764a485c796d1ccf150fdbc9c0ba6f48ba0794c50fa305ee6d578cf
6
+ metadata.gz: 94107541b5742c644dcb657d35ef95a68ae79beeaf17a41ead87eb54d5371e52fa1d6ec9db65d6d6384103a2d9ed0f748df82a2d52cf4689010f45304976b354
7
+ data.tar.gz: fcc8db3b3e45d28d670e98dc851c79d7ab06f977f932795f00b443e06d750539eb6a20a5c752e6eefe666b57528a4bd5aaef1c3c7eda61b3a482a0a8d3c836f9
@@ -1,28 +1,29 @@
1
1
  require "dolly/request"
2
2
  require "dolly/name_space"
3
+ require "dolly/db_config"
3
4
 
4
5
  module Dolly
5
6
  module Connection
6
7
  include Dolly::NameSpace
8
+ include Dolly::DbConfig
9
+
10
+ @@design_doc = nil
7
11
 
8
12
  def database
9
- @database ||= Request.new(database_name: @@database_name)
13
+ @database ||= Request.new(env)
10
14
  end
11
15
 
12
16
  def database_name value
13
- @@database_name ||= value
17
+ @@database_name ||= value
14
18
  end
15
19
 
16
20
  def default_doc
17
- "#{design_doc}/_view/#{name_paramitized}"
21
+ "#{design_doc}/_view/find"
18
22
  end
19
23
 
20
24
  def design_doc
21
- "_design/#{@@design_doc || DESIGN_DOC}"
25
+ "_design/#{env["design"]}"
22
26
  end
23
27
 
24
- def set_design_doc value
25
- @@design_doc = value
26
- end
27
28
  end
28
29
  end
@@ -0,0 +1,18 @@
1
+ module Dolly
2
+ module DbConfig
3
+ attr_accessor :config_file
4
+
5
+ def parse_config
6
+ YAML::load( ERB.new( File.read(config_file) ).result)
7
+ end
8
+
9
+ def env
10
+ parse_config[Rails.env]
11
+ end
12
+
13
+ def config_file
14
+ root = Rails.root || File.expand_path("../../../test/dummy/", __FILE__)
15
+ File.join(root, 'config', 'couchdb.yml')
16
+ end
17
+ end
18
+ end
@@ -4,6 +4,11 @@ module Dolly
4
4
  model_name.param_key
5
5
  end
6
6
 
7
+ def base_id id
8
+ return id unless id =~ /^#{name_paramitized}\//
9
+ id.match("[^/]+[/](.+)")[1]
10
+ end
11
+
7
12
  def namespace id
8
13
  return id if id =~ /^#{name_paramitized}/
9
14
  "#{name_paramitized}/#{id}"
data/lib/dolly/query.rb CHANGED
@@ -17,7 +17,7 @@ module Dolly
17
17
  DESIGN_DOC = "dolly"
18
18
 
19
19
  def find *ids
20
- response = default_view(keys: ids.map{|id| namespace(id)}).parsed_response
20
+ response = default_view(keys: ids.map{ |id| [name_paramitized, base_id(id)] }).parsed_response
21
21
  ids.count > 1 ? Collection.new(response, name.constantize) : self.new.from_json(response)
22
22
  rescue NoMethodError => err
23
23
  if err.message == "undefined method `[]' for nil:NilClass"
@@ -28,7 +28,8 @@ module Dolly
28
28
  end
29
29
 
30
30
  def all
31
- Collection.new default_view.parsed_response, name.constantize
31
+ q = {startkey: [name_paramitized,nil], endkey: [name_paramitized,{}]}
32
+ Collection.new default_view(q).parsed_response, name.constantize
32
33
  end
33
34
 
34
35
  def default_view options = {}
@@ -0,0 +1,12 @@
1
+ require 'rails'
2
+
3
+ module Dolly
4
+ class Railtie < Rails::Railtie
5
+ railtie_name :dolly
6
+
7
+ rake_tasks do
8
+ load File.join File.dirname(__FILE__), '../tasks/db.rake'
9
+ end
10
+ end
11
+ end
12
+
data/lib/dolly/request.rb CHANGED
@@ -10,15 +10,19 @@ module Dolly
10
10
  attr_accessor :database_name, :host, :port
11
11
 
12
12
  def initialize options = {}
13
- @host = options[:host] || DEFAULT_HOST
14
- @port = options[:port] || DEFAULT_PORT
15
- @database_name = options[:database_name]
13
+ @host = options["host"] || DEFAULT_HOST
14
+ @port = options["port"] || DEFAULT_PORT
16
15
 
17
- self.class.base_uri "#{protocol}://#{host}:#{port}"
16
+ @database_name = options["name"]
17
+ @username = options["username"]
18
+ @password = options["password"]
19
+
20
+ self.class.base_uri "#{protocol}://#{auth_info}#{host}:#{port}"
18
21
  end
19
22
 
20
- def get resource, data
21
- request :get, resource, {query: values_to_json(data)}
23
+ def get resource, data = nil
24
+ q = {query: values_to_json(data)} if data
25
+ request :get, resource, q
22
26
  end
23
27
 
24
28
  def put resource, data
@@ -34,6 +38,11 @@ module Dolly
34
38
  end
35
39
 
36
40
  private
41
+ def auth_info
42
+ return "" unless @username.present?
43
+ "#{@username}:#{@password}@"
44
+ end
45
+
37
46
  def values_to_json hash
38
47
  hash.reduce({}){|h, v| h[v.first] = v.last.to_json; h}
39
48
  end
@@ -43,6 +52,7 @@ module Dolly
43
52
  end
44
53
 
45
54
  def request method, resource, data = nil
55
+ data ||= {}
46
56
  headers = { 'Content-Type' => 'application/json' }
47
57
  response = self.class.send method, full_path(resource), data.merge(headers: headers)
48
58
  if response.code == 404
data/lib/dolly/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Dolly
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/dolly.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require "dolly/version"
2
2
  require "dolly/document"
3
+ require 'dolly/railtie' if defined?(Rails)
3
4
 
4
5
  module Dolly; end
@@ -9,4 +9,9 @@ module Dolly
9
9
  'There has been an error on the couchdb server. Please review your couch logs.'
10
10
  end
11
11
  end
12
+ class MissingDesignError < RuntimeError
13
+ def to_s
14
+ 'Design document is missing. Add it into couchdb.yml as design:name.'
15
+ end
16
+ end
12
17
  end
data/lib/tasks/db.rake ADDED
@@ -0,0 +1,26 @@
1
+ namespace :db do
2
+ desc "Will create if missing database and add default views"
3
+ task setup: :environment do
4
+ VIEW_DOC = {
5
+ language: "coffeescript",
6
+ views: {
7
+ find: {
8
+ map: "(d)->\n if d._id\n [str, t, id] = d._id.match /([^/]+)[/](.+)/\n emit [t, id], 1 if t and id"
9
+ }
10
+ }
11
+ }.freeze
12
+
13
+ Dolly::Document.database.put "", nil
14
+
15
+ remote_doc = begin
16
+ JSON.parse Dolly::Document.database.get(Dolly::Document.design_doc).parsed_response
17
+ rescue Dolly::ResourceNotFound
18
+ {}
19
+ end
20
+
21
+ doc = VIEW_DOC.merge remote_doc
22
+
23
+ Dolly::Document.database.put Dolly::Document.design_doc, doc.to_json
24
+ puts "design document #{Dolly::Document.design_doc} was created/updated."
25
+ end
26
+ end
@@ -1,9 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class FooBar < Dolly::Document
4
- database_name 'test'
5
- set_design_doc 'test'
6
-
7
4
  property :foo, :bar
8
5
  property :with_default, default: 1
9
6
  property :boolean, class_name: TrueClass, default: true
@@ -12,19 +9,23 @@ class FooBar < Dolly::Document
12
9
  end
13
10
 
14
11
  class DocumentTest < ActiveSupport::TestCase
12
+ DB_BASE_PATH = "http://localhost:5984/test/_design/test/_view/".freeze
13
+ VIEW_DOC = "find".freeze
15
14
 
16
15
  def setup
17
16
  data = {foo: 'Foo', bar: 'Bar', type: 'foo_bar'}
17
+
18
18
  all_docs = [ {foo: 'Foo B', bar: 'Bar B', type: 'foo_bar'}, {foo: 'Foo A', bar: 'Bar A', type: 'foo_bar'}]
19
19
 
20
20
  view_resp = build_view_response [data]
21
21
  empty_resp = build_view_response []
22
22
  @multi_resp = build_view_response all_docs
23
23
 
24
- build_request ["foo_bar/1"], view_resp
25
- build_request ["foo_bar/2"], empty_resp
26
- build_request ["foo_bar/1","foo_bar/2"], @multi_resp
27
- build_request [], @multi_resp
24
+ build_request [["foo_bar","1"]], view_resp
25
+ build_request [["foo_bar","2"]], empty_resp
26
+ build_request [["foo_bar","1"],["foo_bar","2"]], @multi_resp
27
+
28
+ FakeWeb.register_uri :get, "#{view_base_path}?startkey=%5B%22foo_bar%22%2Cnull%5D&endkey=%5B%22foo_bar%22%2C%7B%7D%5D&include_docs=true", body: @multi_resp.to_json
28
29
  end
29
30
 
30
31
  test 'with timestamps!' do
@@ -44,14 +45,14 @@ class DocumentTest < ActiveSupport::TestCase
44
45
 
45
46
  test 'empty find should raise error' do
46
47
  assert_raise Dolly::ResourceNotFound do
47
- FakeWeb.register_uri :get, "http://localhost:5984/test/_design/test/_view/foo_bar?keys=%5B%5D&include_docs=true", :status => ["404", "Not Found"]
48
+ FakeWeb.register_uri :get, "#{view_base_path}?keys=%5B%5D&include_docs=true", :status => ["404", "Not Found"]
48
49
  foo = FooBar.find
49
50
  end
50
51
  end
51
52
 
52
53
  test 'error on server raises Dolly::ServerError' do
53
54
  assert_raise Dolly::ServerError do
54
- FakeWeb.register_uri :get, "http://localhost:5984/test/_design/test/_view/foo_bar?keys=%5B%5D&include_docs=true", :status => ["500", "Error"]
55
+ FakeWeb.register_uri :get, "#{view_base_path}?keys=%5B%5D&include_docs=true", :status => ["500", "Error"]
55
56
  foo = FooBar.find
56
57
  end
57
58
  end
@@ -139,9 +140,12 @@ class DocumentTest < ActiveSupport::TestCase
139
140
  end
140
141
 
141
142
  def build_request keys, body, view_name = 'foo_bar'
142
- base_url = "http://localhost:5984/test/_design/test/_view/foo_bar"
143
143
  query = "keys=#{CGI::escape keys.to_s.gsub(' ','')}&" unless keys.blank?
144
- FakeWeb.register_uri :get, "#{base_url}?#{query.to_s}include_docs=true", body: body.to_json
144
+ FakeWeb.register_uri :get, "#{view_base_path}?#{query.to_s}include_docs=true", body: body.to_json
145
+ end
146
+
147
+ def view_base_path
148
+ "#{DB_BASE_PATH}#{VIEW_DOC}"
145
149
  end
146
150
 
147
151
  end
@@ -2,7 +2,7 @@ defaults: &defaults
2
2
  host: localhost
3
3
  port: 5984
4
4
  protocol: http
5
- design_doc: 'my_app'
5
+ design: 'test'
6
6
 
7
7
  development:
8
8
  <<: *defaults
@@ -11,5 +11,3 @@ development:
11
11
  test:
12
12
  <<: *defaults
13
13
  name: test
14
-
15
-