zdzolton-cambric 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|