couchmodel 0.1.0.beta2
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.
- data/LICENSE +20 -0
- data/README.rdoc +156 -0
- data/Rakefile +20 -0
- data/lib/core_extension/array.rb +14 -0
- data/lib/core_extension/string.rb +12 -0
- data/lib/couch_model/active_model.rb +86 -0
- data/lib/couch_model/base/accessor.rb +39 -0
- data/lib/couch_model/base/association.rb +63 -0
- data/lib/couch_model/base/finder.rb +28 -0
- data/lib/couch_model/base/setup.rb +88 -0
- data/lib/couch_model/base.rb +117 -0
- data/lib/couch_model/collection.rb +84 -0
- data/lib/couch_model/configuration.rb +68 -0
- data/lib/couch_model/database.rb +64 -0
- data/lib/couch_model/design.rb +92 -0
- data/lib/couch_model/server.rb +44 -0
- data/lib/couch_model/transport.rb +68 -0
- data/lib/couch_model/view.rb +52 -0
- data/lib/couch_model.rb +15 -0
- data/spec/fake_transport.yml +202 -0
- data/spec/fake_transport_helper.rb +27 -0
- data/spec/integration/basic_spec.rb +125 -0
- data/spec/integration/design/membership.design +5 -0
- data/spec/integration/design/user.design +2 -0
- data/spec/lib/core_extension/array_spec.rb +24 -0
- data/spec/lib/core_extension/string_spec.rb +22 -0
- data/spec/lib/couch_model/active_model_spec.rb +228 -0
- data/spec/lib/couch_model/base_spec.rb +169 -0
- data/spec/lib/couch_model/collection_spec.rb +100 -0
- data/spec/lib/couch_model/configuration_spec.rb +117 -0
- data/spec/lib/couch_model/core/accessor_spec.rb +59 -0
- data/spec/lib/couch_model/core/association_spec.rb +114 -0
- data/spec/lib/couch_model/core/finder_spec.rb +24 -0
- data/spec/lib/couch_model/core/setup_spec.rb +88 -0
- data/spec/lib/couch_model/database_spec.rb +165 -0
- data/spec/lib/couch_model/design/association_test_model_one.design +5 -0
- data/spec/lib/couch_model/design/base_test_model.design +10 -0
- data/spec/lib/couch_model/design/setup_test_model.design +10 -0
- data/spec/lib/couch_model/design_spec.rb +144 -0
- data/spec/lib/couch_model/server_spec.rb +64 -0
- data/spec/lib/couch_model/transport_spec.rb +44 -0
- data/spec/lib/couch_model/view_spec.rb +166 -0
- data/spec/lib/couch_model_spec.rb +3 -0
- data/spec/spec_helper.rb +27 -0
- metadata +128 -0
@@ -0,0 +1,84 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "configuration")
|
2
|
+
require File.join(File.dirname(__FILE__), "transport")
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module CouchModel
|
6
|
+
|
7
|
+
class Collection
|
8
|
+
|
9
|
+
REQUEST_PARAMETER_KEYS = [
|
10
|
+
:key, :startkey, :startkey_docid, :endkey, :endkey_docid,
|
11
|
+
:limit, :stale, :descending, :skip, :group, :group_level,
|
12
|
+
:reduce, :inclusive_end
|
13
|
+
].freeze unless defined?(REQUEST_PARAMETER_KEYS)
|
14
|
+
|
15
|
+
ARRAY_METHOD_NAMES = [
|
16
|
+
:[], :at, :collect, :compact, :count, :cycle, :each, :each_index,
|
17
|
+
:empty?, :fetch, :index, :first, :flatten, :include?, :join, :last,
|
18
|
+
:length, :map, :pack, :reject, :reverse, :reverse_each, :rindex,
|
19
|
+
:sample, :shuffle, :size, :slice, :sort, :take, :to_a, :to_ary,
|
20
|
+
:values_at, :zip
|
21
|
+
].freeze unless defined?(ARRAY_METHOD_NAMES)
|
22
|
+
|
23
|
+
attr_reader :url
|
24
|
+
attr_reader :options
|
25
|
+
|
26
|
+
def initialize(url, options = { })
|
27
|
+
@url, @options = url, options
|
28
|
+
end
|
29
|
+
|
30
|
+
def total_count
|
31
|
+
fetch :meta => true unless @total_count
|
32
|
+
@total_count
|
33
|
+
end
|
34
|
+
|
35
|
+
def respond_to?(method_name)
|
36
|
+
ARRAY_METHOD_NAMES.include?(method_name) || super
|
37
|
+
end
|
38
|
+
|
39
|
+
def method_missing(method_name, *arguments, &block)
|
40
|
+
if ARRAY_METHOD_NAMES.include?(method_name)
|
41
|
+
fetch
|
42
|
+
@entries.send method_name, *arguments, &block
|
43
|
+
else
|
44
|
+
super
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def fetch(options = { })
|
51
|
+
meta = options[:meta] || false
|
52
|
+
|
53
|
+
evaluate Transport.request(
|
54
|
+
:get, url,
|
55
|
+
:parameters => request_parameters.merge(meta ? { "limit" => "0" } : { }),
|
56
|
+
:expected_status_code => 200
|
57
|
+
)
|
58
|
+
|
59
|
+
true
|
60
|
+
end
|
61
|
+
|
62
|
+
def evaluate(response)
|
63
|
+
@total_count = response["total_rows"]
|
64
|
+
@entries = response["rows"].select do |row|
|
65
|
+
row["doc"].has_key?(Configuration::CLASS_KEY) && Object.const_defined?(row["doc"][Configuration::CLASS_KEY])
|
66
|
+
end.map do |row|
|
67
|
+
model_class = Object.const_get row["doc"][Configuration::CLASS_KEY]
|
68
|
+
model = model_class.new
|
69
|
+
model.instance_variable_set :@attributes, row["doc"]
|
70
|
+
model
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def request_parameters
|
75
|
+
parameters = { "include_docs" => "true" }
|
76
|
+
REQUEST_PARAMETER_KEYS.each do |key|
|
77
|
+
parameters[ key.to_s ] = @options[key].is_a?(Array) ? JSON.dump(@options[key]) : @options[key].to_s if @options[key]
|
78
|
+
end
|
79
|
+
parameters
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
|
2
|
+
module CouchModel
|
3
|
+
|
4
|
+
class Configuration
|
5
|
+
|
6
|
+
CLASS_KEY = "model_class".freeze unless defined?(CLASS_KEY)
|
7
|
+
CLASS_VIEW_NAME = "all".freeze unless defined?(CLASS_VIEW_NAME)
|
8
|
+
|
9
|
+
class << self
|
10
|
+
|
11
|
+
@@fake_transport = false
|
12
|
+
@@databases = [ ]
|
13
|
+
@@designs = [ ]
|
14
|
+
|
15
|
+
def fake_transport=(value)
|
16
|
+
@@fake_transport = value
|
17
|
+
end
|
18
|
+
|
19
|
+
def fake_transport
|
20
|
+
@@fake_transport
|
21
|
+
end
|
22
|
+
|
23
|
+
def design_directory=(value)
|
24
|
+
@@design_directory = value
|
25
|
+
end
|
26
|
+
|
27
|
+
def design_directory
|
28
|
+
class_variable_defined?(:@@design_directory) ? @@design_directory : ""
|
29
|
+
end
|
30
|
+
|
31
|
+
def register_database(database)
|
32
|
+
result = @@databases.select{ |element| element == database }.first
|
33
|
+
unless result
|
34
|
+
@@databases << database
|
35
|
+
result = database
|
36
|
+
end
|
37
|
+
result
|
38
|
+
end
|
39
|
+
|
40
|
+
def databases
|
41
|
+
@@databases
|
42
|
+
end
|
43
|
+
|
44
|
+
def setup_databases(options = { })
|
45
|
+
@@databases.each do |database|
|
46
|
+
database.setup! options
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def register_design(design)
|
51
|
+
@@designs << design
|
52
|
+
end
|
53
|
+
|
54
|
+
def designs
|
55
|
+
@@designs
|
56
|
+
end
|
57
|
+
|
58
|
+
def setup_designs
|
59
|
+
@@designs.each do |design|
|
60
|
+
design.push
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "transport")
|
2
|
+
require File.join(File.dirname(__FILE__), "server")
|
3
|
+
require File.join(File.dirname(__FILE__), "collection")
|
4
|
+
|
5
|
+
module CouchModel
|
6
|
+
|
7
|
+
class Database
|
8
|
+
|
9
|
+
class Error < StandardError; end
|
10
|
+
|
11
|
+
attr_reader :server
|
12
|
+
attr_reader :name
|
13
|
+
|
14
|
+
def initialize(options = { })
|
15
|
+
@name = options[:name] || raise(ArgumentError, "no database was given")
|
16
|
+
@server = options[:server] || Server.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def ==(other)
|
20
|
+
other.is_a?(self.class) && @name == other.name && @server == other.server
|
21
|
+
end
|
22
|
+
|
23
|
+
def ===(other)
|
24
|
+
object_id == other.object_id
|
25
|
+
end
|
26
|
+
|
27
|
+
def create!
|
28
|
+
Transport.request :put, url, :expected_status_code => 201
|
29
|
+
end
|
30
|
+
|
31
|
+
def delete!
|
32
|
+
Transport.request :delete, url, :expected_status_code => 200
|
33
|
+
end
|
34
|
+
|
35
|
+
def setup!(options = { })
|
36
|
+
delete_if_exists = options[:delete_if_exists] || false
|
37
|
+
|
38
|
+
if delete_if_exists
|
39
|
+
delete! if exists?
|
40
|
+
create!
|
41
|
+
else
|
42
|
+
create! unless exists?
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def informations
|
47
|
+
Transport.request :get, url, :expected_status_code => 200
|
48
|
+
end
|
49
|
+
|
50
|
+
def exists?
|
51
|
+
@server.database_names.include? @name
|
52
|
+
end
|
53
|
+
|
54
|
+
def url
|
55
|
+
"#{@server.url}/#{@name}"
|
56
|
+
end
|
57
|
+
|
58
|
+
def documents(options = { })
|
59
|
+
Collection.new url + "/_all_docs", options
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "configuration")
|
2
|
+
require File.join(File.dirname(__FILE__), "transport")
|
3
|
+
require File.join(File.dirname(__FILE__), "base")
|
4
|
+
require File.join(File.dirname(__FILE__), "view")
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
module CouchModel
|
8
|
+
|
9
|
+
class Design
|
10
|
+
|
11
|
+
attr_reader :database
|
12
|
+
attr_reader :model_class
|
13
|
+
attr_accessor :id
|
14
|
+
attr_reader :rev
|
15
|
+
attr_accessor :language
|
16
|
+
attr_reader :views
|
17
|
+
|
18
|
+
def initialize(database, model_class, attributes = { })
|
19
|
+
@database = database
|
20
|
+
@model_class = model_class
|
21
|
+
@language = "javascript"
|
22
|
+
@views = [ ]
|
23
|
+
|
24
|
+
load_file
|
25
|
+
self.id = attributes[:id] if attributes[:id]
|
26
|
+
self.language = attributes[:language] if attributes[:language]
|
27
|
+
self.views = attributes[:views] if attributes[:views]
|
28
|
+
end
|
29
|
+
|
30
|
+
def filename
|
31
|
+
@filename ||= File.join(CouchModel::Configuration.design_directory, "#{model_class.to_s.underscore}.design")
|
32
|
+
end
|
33
|
+
|
34
|
+
def load_file
|
35
|
+
return false unless File.exists?(filename)
|
36
|
+
attributes = YAML::load_file filename
|
37
|
+
self.id = attributes[:id]
|
38
|
+
self.language = attributes[:language]
|
39
|
+
self.views = attributes[:views]
|
40
|
+
true
|
41
|
+
end
|
42
|
+
|
43
|
+
def views=(view_hash)
|
44
|
+
@views = [ ]
|
45
|
+
view_hash.each do |view_name, view|
|
46
|
+
@views << View.new(self, view.merge(:name => view_name)) if view.is_a?(Hash)
|
47
|
+
end if view_hash.is_a?(Hash)
|
48
|
+
end
|
49
|
+
|
50
|
+
def generate_view(name, options = { })
|
51
|
+
view = View.new self, options.merge(:name => name)
|
52
|
+
@views.insert 0, view
|
53
|
+
view
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_hash
|
57
|
+
hash = {
|
58
|
+
"_id" => "_design/#{self.id}",
|
59
|
+
"language" => self.language,
|
60
|
+
"views" => { }
|
61
|
+
}
|
62
|
+
hash.merge! "_rev" => self.rev if self.rev
|
63
|
+
@views.each { |view| hash["views"].merge! view.to_hash }
|
64
|
+
hash
|
65
|
+
end
|
66
|
+
|
67
|
+
def exists?
|
68
|
+
Transport.request :get, self.url, :expected_status_code => 200
|
69
|
+
true
|
70
|
+
rescue Transport::UnexpectedStatusCodeError
|
71
|
+
false
|
72
|
+
end
|
73
|
+
|
74
|
+
def push
|
75
|
+
response = Transport.request :get, self.url
|
76
|
+
self.rev = response["_rev"] if response["_rev"]
|
77
|
+
|
78
|
+
Transport.request :put, self.url, :json => self.to_hash, :expected_status_code => 201
|
79
|
+
true
|
80
|
+
end
|
81
|
+
|
82
|
+
def url
|
83
|
+
"#{@database.url}/_design/#{self.id}"
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
attr_writer :rev
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "transport")
|
2
|
+
|
3
|
+
module CouchModel
|
4
|
+
|
5
|
+
class Server
|
6
|
+
|
7
|
+
class Error < StandardError; end
|
8
|
+
|
9
|
+
attr_reader :host
|
10
|
+
attr_reader :port
|
11
|
+
|
12
|
+
def initialize(options = { })
|
13
|
+
@host = options[:host] || "localhost"
|
14
|
+
@port = options[:port] || "5984"
|
15
|
+
end
|
16
|
+
|
17
|
+
def ==(other)
|
18
|
+
other.is_a?(self.class) && @host == other.host && @port == other.port
|
19
|
+
end
|
20
|
+
|
21
|
+
def informations
|
22
|
+
Transport.request :get, url + "/", :expected_status_code => 200
|
23
|
+
end
|
24
|
+
|
25
|
+
def statistics
|
26
|
+
Transport.request :get, url + "/_stats", :expected_status_code => 200
|
27
|
+
end
|
28
|
+
|
29
|
+
def database_names
|
30
|
+
Transport.request :get, url + "/_all_dbs", :expected_status_code => 200
|
31
|
+
end
|
32
|
+
|
33
|
+
def uuids(count = 1)
|
34
|
+
response = Transport.request :get, url + "/_uuids", :expected_status_code => 200, :parameters => { :count => count }
|
35
|
+
response["uuids"]
|
36
|
+
end
|
37
|
+
|
38
|
+
def url
|
39
|
+
"http://#{@host}:#{@port}"
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'net/http'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module CouchModel
|
6
|
+
|
7
|
+
module Transport
|
8
|
+
|
9
|
+
class Error < StandardError; end
|
10
|
+
|
11
|
+
class UnexpectedStatusCodeError < StandardError
|
12
|
+
|
13
|
+
attr_reader :status_code
|
14
|
+
|
15
|
+
def initialize(status_code)
|
16
|
+
@status_code = status_code
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
"#{super} received status code #{self.status_code}"
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
class << self
|
26
|
+
|
27
|
+
def request(http_method, url, options = { })
|
28
|
+
expected_status_code = options[:expected_status_code]
|
29
|
+
|
30
|
+
uri = URI.parse @base_url ? @base_url + url : url
|
31
|
+
|
32
|
+
request_class = request_class http_method
|
33
|
+
request = request_object request_class, uri, options
|
34
|
+
|
35
|
+
response = Net::HTTP.start(uri.host, uri.port) { |connection| connection.request request }
|
36
|
+
|
37
|
+
raise UnexpectedStatusCodeError, response.code.to_i if expected_status_code && expected_status_code.to_s != response.code
|
38
|
+
JSON.parse response.body
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def request_class(http_method)
|
44
|
+
Net::HTTP.const_get http_method.capitalize
|
45
|
+
end
|
46
|
+
|
47
|
+
def request_object(request_class, uri, options)
|
48
|
+
parameters = options[:parameters] || { }
|
49
|
+
json = options[:json]
|
50
|
+
|
51
|
+
case request_class.to_s
|
52
|
+
when "Net::HTTP::Get"
|
53
|
+
request_class.new uri.path +
|
54
|
+
(parameters.empty? ? "" : "?" + parameters.collect{ |key, value| "#{key}=#{URI.escape(value.to_s)}" }.reverse.join("&"))
|
55
|
+
when "Net::HTTP::Post", "Net::HTTP::Put"
|
56
|
+
request = request_class.new uri.path, { "Content-Type" => "application/json" }
|
57
|
+
request.body = JSON.dump(json) if json
|
58
|
+
request
|
59
|
+
else
|
60
|
+
request_class.new uri.path
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "configuration")
|
2
|
+
require File.join(File.dirname(__FILE__), "collection")
|
3
|
+
|
4
|
+
module CouchModel
|
5
|
+
|
6
|
+
class View
|
7
|
+
|
8
|
+
attr_reader :design
|
9
|
+
attr_accessor :name
|
10
|
+
attr_accessor :map
|
11
|
+
attr_accessor :reduce
|
12
|
+
|
13
|
+
def initialize(design, attributes = { })
|
14
|
+
@design = design
|
15
|
+
@name = attributes[:name]
|
16
|
+
|
17
|
+
generate_functions attributes
|
18
|
+
@map = attributes[:map] if attributes[:map]
|
19
|
+
@reduce = attributes[:reduce] if attributes[:reduce]
|
20
|
+
end
|
21
|
+
|
22
|
+
def collection(options = { })
|
23
|
+
Collection.new url, options
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_hash
|
27
|
+
{ self.name => { "map" => self.map, "reduce" => self.reduce } }
|
28
|
+
end
|
29
|
+
|
30
|
+
def url
|
31
|
+
"#{@design.url}/_view/#{@name}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def generate_functions(options = { })
|
35
|
+
keys = [ (options[:keys] || "_id") ].flatten
|
36
|
+
|
37
|
+
emit_values = keys.map{ |key| "document['#{key}']" }
|
38
|
+
check_values = emit_values.select{ |value| value != "document['_id']" }
|
39
|
+
|
40
|
+
@map =
|
41
|
+
"""function(document) {
|
42
|
+
if (document['#{Configuration::CLASS_KEY}'] == '#{@design.model_class.to_s}'#{check_values.empty? ? "" : " && " + check_values.join(" && ")}) {
|
43
|
+
emit(#{emit_values.size == 1 ? emit_values.first : "[ " + emit_values.join(", ") + " ]"}, null);
|
44
|
+
}
|
45
|
+
}
|
46
|
+
"""
|
47
|
+
@reduce = nil
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
data/lib/couch_model.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), "couch_model", "configuration")
|
4
|
+
require File.join(File.dirname(__FILE__), "couch_model", "base")
|
5
|
+
|
6
|
+
begin
|
7
|
+
gem 'activemodel'
|
8
|
+
require 'active_model'
|
9
|
+
|
10
|
+
require File.join(File.dirname(__FILE__), "couch_model", "active_model")
|
11
|
+
|
12
|
+
# ActiveModel support is activated
|
13
|
+
rescue Gem::LoadError
|
14
|
+
# ActiveModel support is deactivated
|
15
|
+
end
|
@@ -0,0 +1,202 @@
|
|
1
|
+
-
|
2
|
+
:http_method: "get"
|
3
|
+
:url: "http://localhost:5984/"
|
4
|
+
:response:
|
5
|
+
:code: "200"
|
6
|
+
:json:
|
7
|
+
"couchdb": "Welcome"
|
8
|
+
"version": "0.10.0"
|
9
|
+
-
|
10
|
+
:http_method: "get"
|
11
|
+
:url: "http://localhost:5984/_stats"
|
12
|
+
:response:
|
13
|
+
:code: "200"
|
14
|
+
:json:
|
15
|
+
"httpd_status_codes": "..."
|
16
|
+
"httpd_request_methods": "..."
|
17
|
+
-
|
18
|
+
:http_method: "get"
|
19
|
+
:url: "http://localhost:5984/_all_dbs"
|
20
|
+
:response:
|
21
|
+
:code: "200"
|
22
|
+
:json: [ "development", "test" ]
|
23
|
+
-
|
24
|
+
:http_method: "get"
|
25
|
+
:url: "http://localhost:5984/_uuids"
|
26
|
+
:parameters:
|
27
|
+
:count: 3
|
28
|
+
:response:
|
29
|
+
:code: "200"
|
30
|
+
:json:
|
31
|
+
"uuids": [ "uuid_1", "uuid_2", "uuid_3" ]
|
32
|
+
-
|
33
|
+
:http_method: "get"
|
34
|
+
:url: "http://localhost:5984/test"
|
35
|
+
:response:
|
36
|
+
:code: "200"
|
37
|
+
:json:
|
38
|
+
"db_name": "test"
|
39
|
+
"doc_count": "0"
|
40
|
+
-
|
41
|
+
:http_method: "get"
|
42
|
+
:url: "http://localhost:5984/new_database"
|
43
|
+
:response:
|
44
|
+
:code: "404"
|
45
|
+
:json:
|
46
|
+
-
|
47
|
+
:http_method: "get"
|
48
|
+
:url: "http://localhost:5984/test/test_model_1"
|
49
|
+
:response:
|
50
|
+
:code: "200"
|
51
|
+
:json:
|
52
|
+
"_id": "test_model_1"
|
53
|
+
"_rev": "0"
|
54
|
+
"model_class": "BaseTestModel"
|
55
|
+
"name": "phil"
|
56
|
+
"related_id": "test_model_2"
|
57
|
+
-
|
58
|
+
:http_method: "get"
|
59
|
+
:url: "http://localhost:5984/test/test_model_2"
|
60
|
+
:response:
|
61
|
+
:code: "200"
|
62
|
+
:json:
|
63
|
+
"_id": "test_model_2"
|
64
|
+
"_rev": "0"
|
65
|
+
"model_class": "BaseTestModel"
|
66
|
+
"name": "keppla"
|
67
|
+
-
|
68
|
+
:http_method: "get"
|
69
|
+
:url: "http://localhost:5984/test/invalid"
|
70
|
+
:response:
|
71
|
+
:code: "404"
|
72
|
+
-
|
73
|
+
:http_method: "post"
|
74
|
+
:url: "http://localhost:5984/test"
|
75
|
+
:response:
|
76
|
+
:code: "201"
|
77
|
+
:json:
|
78
|
+
"ok": true
|
79
|
+
"id": "test_model_2"
|
80
|
+
"rev": "0"
|
81
|
+
-
|
82
|
+
:http_method: "put"
|
83
|
+
:url: "http://localhost:5984/test/test_model_1"
|
84
|
+
:response:
|
85
|
+
:code: "200"
|
86
|
+
:json:
|
87
|
+
"ok": true
|
88
|
+
"id": "test_model_1"
|
89
|
+
"rev": "1"
|
90
|
+
-
|
91
|
+
:http_method: "delete"
|
92
|
+
:url: "http://localhost:5984/test/test_model_1"
|
93
|
+
:parameters:
|
94
|
+
"rev": "0"
|
95
|
+
:response:
|
96
|
+
:code: "200"
|
97
|
+
:json:
|
98
|
+
"ok": true
|
99
|
+
"id": "test_model_1"
|
100
|
+
"rev": "1"
|
101
|
+
-
|
102
|
+
:http_method: "get"
|
103
|
+
:url: "http://localhost:5984/test/_design/test_design"
|
104
|
+
:response:
|
105
|
+
:code: "200"
|
106
|
+
:json:
|
107
|
+
"_id": "_design/test_design"
|
108
|
+
"_rev": "0"
|
109
|
+
"language": "javascript"
|
110
|
+
"views":
|
111
|
+
"test_view":
|
112
|
+
"map": "function(document) { };"
|
113
|
+
"reduce": "function(key, values, rereduce) { };"
|
114
|
+
-
|
115
|
+
:http_method: "put"
|
116
|
+
:url: "http://localhost:5984/test/_design/test_design"
|
117
|
+
:response:
|
118
|
+
:code: "201"
|
119
|
+
:json:
|
120
|
+
"ok": true
|
121
|
+
"id": "_design/test_design"
|
122
|
+
"rev": "1"
|
123
|
+
-
|
124
|
+
:http_method: "get"
|
125
|
+
:url: "http://localhost:5984/test/_all_docs"
|
126
|
+
:parameters:
|
127
|
+
"include_docs": "true"
|
128
|
+
"limit": "1"
|
129
|
+
:response:
|
130
|
+
:code: "200"
|
131
|
+
:json:
|
132
|
+
"total_rows": 1
|
133
|
+
"offset": 0
|
134
|
+
"rows":
|
135
|
+
-
|
136
|
+
"id": "test_model_1"
|
137
|
+
"key": "test_model_1"
|
138
|
+
"value":
|
139
|
+
"rev": "0"
|
140
|
+
"doc":
|
141
|
+
"_id": "test_model_1"
|
142
|
+
"_rev": "0"
|
143
|
+
"model_class": "CollectionTestModel"
|
144
|
+
"name": "phil"
|
145
|
+
-
|
146
|
+
:http_method: "get"
|
147
|
+
:url: "http://localhost:5984/test/_all_docs"
|
148
|
+
:parameters:
|
149
|
+
"include_docs": "true"
|
150
|
+
"limit": "0"
|
151
|
+
:response:
|
152
|
+
:code: "200"
|
153
|
+
:json:
|
154
|
+
"total_rows": 1
|
155
|
+
"offset": 0
|
156
|
+
"rows": [ ]
|
157
|
+
-
|
158
|
+
:http_method: "get"
|
159
|
+
:url: "http://localhost:5984/test/_design/association_test_model_one/_view/by_related_id_and_name"
|
160
|
+
:parameters:
|
161
|
+
"include_docs": "true"
|
162
|
+
"startkey": "[\"test_model_2\",null]"
|
163
|
+
"endkey": "[\"test_model_2\",{}]"
|
164
|
+
:response:
|
165
|
+
:code: "200"
|
166
|
+
:json:
|
167
|
+
"total_rows": 1
|
168
|
+
"offset": 0
|
169
|
+
"rows":
|
170
|
+
-
|
171
|
+
"id": "test_model_1"
|
172
|
+
"key": "test_model_2"
|
173
|
+
"value":
|
174
|
+
"rev": "0"
|
175
|
+
"doc":
|
176
|
+
"_id": "test_model_1"
|
177
|
+
"_rev": "0"
|
178
|
+
"model_class": "AssociationTestModelOne"
|
179
|
+
"name": "phil"
|
180
|
+
-
|
181
|
+
:http_method: "get"
|
182
|
+
:url: "http://localhost:5984/test/_design/association_test_model_one/_view/by_related_id_and_name"
|
183
|
+
:parameters:
|
184
|
+
"include_docs": "true"
|
185
|
+
"startkey": "[\"test_model_2\",\"phil\"]"
|
186
|
+
"endkey": "[\"test_model_2\",\"phil\"]"
|
187
|
+
:response:
|
188
|
+
:code: "200"
|
189
|
+
:json:
|
190
|
+
"total_rows": 1
|
191
|
+
"offset": 0
|
192
|
+
"rows":
|
193
|
+
-
|
194
|
+
"id": "test_model_1"
|
195
|
+
"key": "test_model_2"
|
196
|
+
"value":
|
197
|
+
"rev": "0"
|
198
|
+
"doc":
|
199
|
+
"_id": "test_model_1"
|
200
|
+
"_rev": "0"
|
201
|
+
"model_class": "AssociationTestModelOne"
|
202
|
+
"name": "phil"
|