zdzolton-cambric 0.3.1 → 0.4.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.
- data/README.rdoc +56 -34
- data/VERSION +1 -1
- data/cambric.gemspec +2 -5
- data/lib/cambric.rb +62 -49
- data/spec/cambric_spec.rb +98 -92
- metadata +2 -5
- data/spec/fixtures/degenerate.yml +0 -2
- data/spec/fixtures/foo-bar-baz.yml +0 -11
- data/spec/fixtures/twitter-clone.yml +0 -6
data/README.rdoc
CHANGED
@@ -2,35 +2,69 @@
|
|
2
2
|
|
3
3
|
Opinionated management and usage of CouchDB from your Ruby apps.
|
4
4
|
|
5
|
+
(BTW, there's nothing specific to Rails in how this works.)
|
6
|
+
|
5
7
|
== Usage
|
6
8
|
|
7
9
|
1) Configure the Cambric instances:
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
11
|
+
Cambric.configure do |config|
|
12
|
+
config.design_doc_name = 'twitter-clone'
|
13
|
+
config.environment = ENV['RAILS_ENV']
|
14
|
+
|
15
|
+
config.databases = {
|
16
|
+
:users => {
|
17
|
+
:development => 'http://127.0.0.1:5984/users-development',
|
18
|
+
:test => 'http://127.0.0.1:5984/users-test',
|
19
|
+
:production => 'http://prod.server:5984/users'
|
20
|
+
},
|
21
|
+
:tweets => {
|
22
|
+
:development => 'http://127.0.0.1:5984/tweets-development',
|
23
|
+
:test => 'http://127.0.0.1:5984/tweets-test',
|
24
|
+
:production => 'http://prod.server:5984/tweets'
|
25
|
+
}
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
13
29
|
# Optionally:
|
14
|
-
#
|
30
|
+
# Cambric.create_all_databases
|
15
31
|
|
16
32
|
2) Interact with CouchRest::Database instances:
|
17
33
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
34
|
+
# Just like normal...
|
35
|
+
Cambric[:tweets].save_doc :author => 'marbles',
|
36
|
+
:message => 'Is this pork or beef, @Randy?',
|
37
|
+
:followers => ['randy','zdzolton','trevorturk'],
|
38
|
+
:created_at => Time.now
|
23
39
|
|
24
|
-
|
40
|
+
# Except, you do NOT need to re-specify the design doc name when
|
41
|
+
# calling CouchRest::Database#view —hooray!
|
42
|
+
Cambric[:tweets].view 'by_follower_and_created_at', :limit => 1
|
25
43
|
|
26
|
-
3) Push view changes to CouchDB:
|
44
|
+
3) Push view/design doc changes to CouchDB:
|
27
45
|
|
28
46
|
$ ./script/console
|
29
|
-
irb> require '
|
30
|
-
irb>
|
31
|
-
|
32
|
-
|
33
|
-
|
47
|
+
irb> require 'rubygems'
|
48
|
+
irb> gem 'zdzolton-cambric'
|
49
|
+
irb> require 'cambric'
|
50
|
+
irb> Cambric.configure do |config|
|
51
|
+
config.design_doc_name = 'twitter-clone'
|
52
|
+
config.environment = ENV['RAILS_ENV']
|
53
|
+
|
54
|
+
config.databases = {
|
55
|
+
:users => {
|
56
|
+
:development => 'http://127.0.0.1:5984/users-development',
|
57
|
+
:test => 'http://127.0.0.1:5984/users-test',
|
58
|
+
:production => 'http://prod.server:5984/users'
|
59
|
+
},
|
60
|
+
:tweets => {
|
61
|
+
:development => 'http://127.0.0.1:5984/tweets-development',
|
62
|
+
:test => 'http://127.0.0.1:5984/tweets-test',
|
63
|
+
:production => 'http://prod.server:5984/tweets'
|
64
|
+
}
|
65
|
+
}
|
66
|
+
end
|
67
|
+
irb> Cambric.push_all_design_docs
|
34
68
|
|
35
69
|
== Installation
|
36
70
|
|
@@ -39,27 +73,15 @@ Opinionated management and usage of CouchDB from your Ruby apps.
|
|
39
73
|
$ sudo gem install jchris-couchapp jchris-couchrest zdzolton-cambric
|
40
74
|
|
41
75
|
* Configure Rails:
|
42
|
-
|
43
|
-
Coming soon...
|
44
|
-
|
45
|
-
* create a couchdb directory within your project
|
46
|
-
$ cd /your/app/root
|
47
|
-
$ mkdir -p ./couchdb/your_db/views/some_view_name
|
76
|
+
* create a config/initializers/cambric.rb file as follows:
|
48
77
|
|
49
|
-
|
50
|
-
bar:
|
51
|
-
staging:
|
52
|
-
|
53
|
-
somewhere:
|
54
|
-
host: some.where
|
78
|
+
# coming soon...
|
55
79
|
|
56
|
-
|
57
|
-
staging:
|
80
|
+
* create a couchdb directory within your project
|
58
81
|
|
59
|
-
|
60
|
-
|
82
|
+
$ cd /your/app/root
|
83
|
+
$ mkdir -p ./couchdb/your_db/views/some_view_name
|
61
84
|
|
62
|
-
|
63
85
|
== Copyright
|
64
86
|
|
65
87
|
Copyright (c) 2009 Zachary Zolton. See LICENSE for details.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.1
|
data/cambric.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{cambric}
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.4.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Zachary Zolton", "Geoff Buesing"]
|
9
|
-
s.date = %q{2009-05-
|
9
|
+
s.date = %q{2009-05-20}
|
10
10
|
s.email = %q{zachary.zolton@gmail.com}
|
11
11
|
s.extra_rdoc_files = [
|
12
12
|
"LICENSE",
|
@@ -22,9 +22,6 @@ Gem::Specification.new do |s|
|
|
22
22
|
"cambric.gemspec",
|
23
23
|
"lib/cambric.rb",
|
24
24
|
"spec/cambric_spec.rb",
|
25
|
-
"spec/fixtures/degenerate.yml",
|
26
|
-
"spec/fixtures/foo-bar-baz.yml",
|
27
|
-
"spec/fixtures/twitter-clone.yml",
|
28
25
|
"spec/fixtures/twitter-clone/tweets/views/by_follower_and_created_at/map.js",
|
29
26
|
"spec/spec_helper.rb"
|
30
27
|
]
|
data/lib/cambric.rb
CHANGED
@@ -1,29 +1,32 @@
|
|
1
|
-
require 'erb'
|
2
|
-
require 'yaml'
|
3
1
|
require 'couchrest'
|
2
|
+
require 'uri'
|
4
3
|
|
5
|
-
|
4
|
+
module Cambric
|
6
5
|
|
7
|
-
|
6
|
+
def self.design_doc_name
|
7
|
+
@design_doc_name
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.db_dir
|
11
|
+
@db_dir
|
12
|
+
end
|
8
13
|
|
9
|
-
def
|
10
|
-
|
11
|
-
@config = YAML::load(ERB.new(yaml_config_io.read).result)
|
12
|
-
validate_options_hash options
|
13
|
-
@environment = options[:environment]
|
14
|
-
@design_doc_name = options[:design_doc]
|
15
|
-
@db_dir = options[:db_dir] || './couchdb'
|
16
|
-
validate_environments_exists_for_all_dbs
|
17
|
-
initialize_databases
|
14
|
+
def self.environment
|
15
|
+
@environment
|
18
16
|
end
|
19
17
|
|
20
|
-
def
|
21
|
-
|
18
|
+
def self.configure
|
19
|
+
config = Configurator.new
|
20
|
+
yield config if block_given?
|
21
|
+
@databases = config.initialize_databases
|
22
|
+
@design_doc_name = config.design_doc_name
|
23
|
+
@db_dir = config.db_dir
|
24
|
+
@environment = config.environment
|
22
25
|
end
|
23
26
|
|
24
|
-
def create_all_databases
|
25
|
-
@databases.each_pair do |
|
26
|
-
name_with_env = "#{
|
27
|
+
def self.create_all_databases
|
28
|
+
@databases.each_pair do |name,db|
|
29
|
+
name_with_env = "#{name}-#{@environment}"
|
27
30
|
begin
|
28
31
|
db.server.create_db name_with_env
|
29
32
|
rescue
|
@@ -33,53 +36,63 @@ class Cambric
|
|
33
36
|
push_all_design_docs
|
34
37
|
end
|
35
38
|
|
36
|
-
def
|
37
|
-
@databases.
|
39
|
+
def self.[](database)
|
40
|
+
@databases[database.to_sym]
|
38
41
|
end
|
39
42
|
|
43
|
+
def self.push_all_design_docs
|
44
|
+
@databases.keys.each{ |db| push_design_doc_for db.to_s }
|
45
|
+
end
|
46
|
+
|
40
47
|
private
|
41
48
|
|
42
|
-
def push_design_doc_for database
|
49
|
+
def self.push_design_doc_for database
|
43
50
|
design_doc_path = File.join @db_dir, database
|
44
51
|
raise "Database directory #{design_doc_path} does not exist!" unless File.exist?(design_doc_path)
|
45
52
|
`couchapp push #{design_doc_path} #{@design_doc_name} #{self[database].uri}`
|
46
53
|
end
|
54
|
+
|
55
|
+
end
|
47
56
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
@config.each_pair do |db,env_hash|
|
58
|
-
raise "No Cambric config for DB '#{db}' ENV '#{@environment}'" unless env_hash.has_key?(@environment)
|
59
|
-
end
|
57
|
+
class Cambric::Configurator
|
58
|
+
|
59
|
+
attr_accessor :design_doc_name, :db_dir, :environment, :databases
|
60
|
+
|
61
|
+
def initialize
|
62
|
+
@design_doc_name = 'cambric'
|
63
|
+
@db_dir = './couchdb'
|
64
|
+
@environment = 'development'
|
65
|
+
@databases = {}
|
60
66
|
end
|
61
67
|
|
62
68
|
def initialize_databases
|
63
|
-
|
64
|
-
@
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
database = CouchRest.new("http://#{host}:#{port}").database("#{db_name}-#{@environment}")
|
69
|
-
database.extend AssumeDesignDocName
|
70
|
-
database.design_doc_name = @design_doc_name
|
71
|
-
@databases[db_name.to_sym] = database
|
69
|
+
dbs_by_name = {}
|
70
|
+
@databases.each_pair do |db,urls_by_env|
|
71
|
+
urls_by_env.keys.map!{ |env| env.to_sym }
|
72
|
+
uri = URI.parse urls_by_env[@environment.to_sym]
|
73
|
+
dbs_by_name[db.to_sym] = initialize_database uri
|
72
74
|
end
|
75
|
+
dbs_by_name
|
73
76
|
end
|
74
77
|
|
75
|
-
|
78
|
+
private
|
76
79
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
80
|
+
def initialize_database uri
|
81
|
+
server = CouchRest.new("#{uri.scheme}://#{uri.host}:#{uri.port}")
|
82
|
+
database = server.database uri.path.gsub(/^\//, '')
|
83
|
+
database.extend ::Cambric::AssumeDesignDocName
|
84
|
+
database.cambric_design_doc_name = @design_doc_name
|
85
|
+
database
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
module Cambric::AssumeDesignDocName
|
91
|
+
|
92
|
+
attr_accessor :cambric_design_doc_name
|
93
|
+
|
94
|
+
def view name, options={}, &block
|
95
|
+
super "#{@cambric_design_doc_name}/#{name}", options, &block
|
83
96
|
end
|
84
97
|
|
85
98
|
end
|
data/spec/cambric_spec.rb
CHANGED
@@ -1,130 +1,136 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
require 'uri'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
4
|
+
TWITTER_CLONE_DATABASES = {
|
5
|
+
:users => {
|
6
|
+
:development => 'http://127.0.0.1:5984/users-development',
|
7
|
+
:test => 'http://127.0.0.1:5984/users-test'
|
8
|
+
},
|
9
|
+
:tweets => {
|
10
|
+
:development => 'http://127.0.0.1:5984/tweets-development',
|
11
|
+
:test => 'http://127.0.0.1:5984/tweets-test'
|
12
|
+
}
|
13
|
+
}
|
13
14
|
|
14
|
-
|
15
|
-
it "should raise an error" do
|
16
|
-
lambda do
|
17
|
-
Cambric.new load_fixture('degenerate.yml'),
|
18
|
-
:environment => 'staging',
|
19
|
-
:design_doc => 'blarg'
|
20
|
-
end.should raise_error
|
21
|
-
end
|
22
|
-
end
|
15
|
+
describe Cambric do
|
23
16
|
|
24
|
-
|
25
|
-
lambda do
|
26
|
-
@cambric = Cambric.new load_fixture('foo-bar-baz.yml'),
|
27
|
-
:environment => 'staging',
|
28
|
-
:design_doc => 'xop'
|
29
|
-
|
30
|
-
@cambric.push_all_design_docs
|
31
|
-
end.should raise_error
|
32
|
-
end
|
33
|
-
|
34
|
-
describe "after initializing with required information" do
|
35
|
-
|
17
|
+
describe "after configuring without a block" do
|
36
18
|
before :all do
|
37
|
-
|
38
|
-
:environment => 'development',
|
39
|
-
:design_doc => 'twitter-clone',
|
40
|
-
:db_dir => File.join(FIXTURES_PATH, 'twitter-clone')
|
19
|
+
Cambric.configure
|
41
20
|
end
|
42
|
-
|
43
|
-
it "should
|
44
|
-
|
21
|
+
|
22
|
+
it "should default its design doc name to 'cambric'" do
|
23
|
+
Cambric.design_doc_name.should == 'cambric'
|
45
24
|
end
|
46
25
|
|
47
|
-
it "should
|
48
|
-
|
26
|
+
it "should default to './couchdb' for the database directory" do
|
27
|
+
Cambric.db_dir.should == './couchdb'
|
49
28
|
end
|
50
29
|
|
51
|
-
it "should
|
52
|
-
|
30
|
+
it "should default to 'development' for the environment" do
|
31
|
+
Cambric.environment.should == 'development'
|
53
32
|
end
|
54
33
|
|
55
|
-
it "should
|
56
|
-
|
34
|
+
it "should not throw a fit when creating databases" do
|
35
|
+
Cambric.create_all_databases
|
57
36
|
end
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "after instantiating with a block" do
|
40
|
+
before :all do
|
41
|
+
Cambric.configure do |config|
|
42
|
+
config.design_doc_name = 'twitter-clone'
|
43
|
+
config.db_dir = '../to/some/path'
|
44
|
+
config.environment = 'test'
|
45
|
+
config.databases = TWITTER_CLONE_DATABASES
|
62
46
|
end
|
63
47
|
end
|
64
48
|
|
65
|
-
it "should
|
66
|
-
|
67
|
-
[db_name, db_name.to_sym].each do |db|
|
68
|
-
@cambric[db].uri.should =~ /localhost:5984\/#{db}-development$/
|
69
|
-
end
|
70
|
-
end
|
49
|
+
it "should have the config object's value for the design doc name" do
|
50
|
+
Cambric.design_doc_name.should == 'twitter-clone'
|
71
51
|
end
|
72
52
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
@tweets_db = @cambric[:tweets]
|
77
|
-
end
|
78
|
-
|
79
|
-
it "should access views with omitted design doc name" do
|
80
|
-
@tweets_db.save_doc :author => 'marbles',
|
81
|
-
:message => 'Is this pork or beef, @Randy?',
|
82
|
-
:followers => ['randy','zdzolton','trevorturk'],
|
83
|
-
:created_at => Time.now
|
84
|
-
|
85
|
-
@tweets_db.view 'by_follower_and_created_at', :limit => 1
|
86
|
-
end
|
87
|
-
end
|
53
|
+
it "should have the config object's value for the database directory" do
|
54
|
+
Cambric.db_dir.should == '../to/some/path'
|
55
|
+
end
|
88
56
|
|
57
|
+
it "should have the config object's value for the environment" do
|
58
|
+
Cambric.environment.should == 'test'
|
59
|
+
end
|
89
60
|
end
|
90
61
|
|
91
|
-
describe "
|
62
|
+
describe "after creating databases" do
|
92
63
|
before :all do
|
93
|
-
Cambric.
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
64
|
+
Cambric.configure do |config|
|
65
|
+
config.design_doc_name = 'twitter-clone'
|
66
|
+
config.db_dir = './spec/fixtures/twitter-clone'
|
67
|
+
config.environment = 'test'
|
68
|
+
config.databases = TWITTER_CLONE_DATABASES
|
69
|
+
end
|
70
|
+
Cambric.create_all_databases
|
71
|
+
end
|
72
|
+
|
73
|
+
after :all do
|
74
|
+
%w(users tweets).each{ |db| Cambric[db].delete! }
|
98
75
|
end
|
99
76
|
|
100
|
-
it "should be able to
|
101
|
-
%w(
|
102
|
-
|
77
|
+
it "should be able to query database info" do
|
78
|
+
%w(users tweets).each do |db|
|
79
|
+
Cambric[db].info.should_not be_nil
|
103
80
|
end
|
104
81
|
end
|
105
82
|
|
106
|
-
it "should have
|
107
|
-
%w(
|
108
|
-
|
83
|
+
it "should have the expected URLs" do
|
84
|
+
%w(users tweets).each do |db|
|
85
|
+
Cambric[db].uri.should == "http://127.0.0.1:5984/#{db}-test"
|
109
86
|
end
|
110
87
|
end
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
:environment => 'somewhere',
|
117
|
-
:design_doc => 'xop',
|
118
|
-
:db_dir => File.join(FIXTURES_PATH, 'foo-bar-baz')
|
88
|
+
|
89
|
+
it "should have the expected design doc" do
|
90
|
+
%w(users tweets).each do |db|
|
91
|
+
Cambric[db].get("_design/twitter-clone").should_not be_nil
|
92
|
+
end
|
119
93
|
end
|
120
94
|
|
121
|
-
it "should
|
122
|
-
|
95
|
+
it "should have defined views for design doc" do
|
96
|
+
design_doc = Cambric[:tweets].get("_design/twitter-clone")
|
97
|
+
design_doc['views']['by_follower_and_created_at'].should_not be_nil
|
123
98
|
end
|
124
99
|
|
125
|
-
it "should
|
126
|
-
|
100
|
+
it "should be able to query view without re-specifying design doc name" do
|
101
|
+
Cambric[:tweets].view 'by_follower_and_created_at'
|
127
102
|
end
|
128
103
|
end
|
129
104
|
|
130
105
|
end
|
106
|
+
|
107
|
+
describe Cambric::Configurator do
|
108
|
+
before :all do
|
109
|
+
@config = Cambric::Configurator.new
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should default its design doc name to 'cambric'" do
|
113
|
+
@config.design_doc_name.should == 'cambric'
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should default to './couchdb' for the database directory" do
|
117
|
+
@config.db_dir.should == './couchdb'
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should default to 'development' for the environment" do
|
121
|
+
@config.environment.should == 'development'
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "when retrieving the configured CouchRest::Database instances" do
|
125
|
+
before :all do
|
126
|
+
@config.databases = TWITTER_CLONE_DATABASES
|
127
|
+
@dbs = @config.initialize_databases
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should have the expected URLs for development environment" do
|
131
|
+
%w(users tweets).each do |db|
|
132
|
+
@dbs[db.to_sym].uri.should == "http://127.0.0.1:5984/#{db}-development"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zdzolton-cambric
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zachary Zolton
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2009-05-
|
13
|
+
date: 2009-05-20 00:00:00 -07:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -42,9 +42,6 @@ files:
|
|
42
42
|
- cambric.gemspec
|
43
43
|
- lib/cambric.rb
|
44
44
|
- spec/cambric_spec.rb
|
45
|
-
- spec/fixtures/degenerate.yml
|
46
|
-
- spec/fixtures/foo-bar-baz.yml
|
47
|
-
- spec/fixtures/twitter-clone.yml
|
48
45
|
- spec/fixtures/twitter-clone/tweets/views/by_follower_and_created_at/map.js
|
49
46
|
- spec/spec_helper.rb
|
50
47
|
has_rdoc: true
|