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 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
- @cambric = Cambric.new open('./config/cambric.yml'),
10
- :environment => 'development',
11
- :design_doc => 'twitter-clone'
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
- # @cambric.create_all_databases
30
+ # Cambric.create_all_databases
15
31
 
16
32
  2) Interact with CouchRest::Database instances:
17
33
 
18
- @tweets_db = @cambric[:tweets]
19
- @tweets_db.save_doc :author => 'marbles',
20
- :message => 'Is this pork or beef, @Randy?',
21
- :followers => ['randy','zdzolton','trevorturk'],
22
- :created_at => Time.now
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
- @tweets_db.view 'by_follower_and_created_at', :limit => 1
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 'require cambric.rb' # This needs to change when gem becomes available...! :^/
30
- irb> @cambric = Cambric.new open('./config/cambric.yml'),
31
- :environment => 'production',
32
- :design_doc => 'twitter-clone'
33
- irb> @cambric.push_all_design_docs
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
- * create a ./config/cambric.yml file
50
- bar:
51
- staging:
52
-
53
- somewhere:
54
- host: some.where
78
+ # coming soon...
55
79
 
56
- baz:
57
- staging:
80
+ * create a couchdb directory within your project
58
81
 
59
- somewhere:
60
- port: 5566
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.3.1
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.3.1"
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-18}
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
- class Cambric
4
+ module Cambric
6
5
 
7
- attr_reader :config, :environment, :design_doc_name, :db_dir
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 initialize(yaml_config_io, options={})
10
- options.keys.map!{ |k| k.to_sym }
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 [](db)
21
- @databases[db.to_sym]
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 |db_name,db|
26
- name_with_env = "#{db_name}-#{@environment}"
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 push_all_design_docs
37
- @databases.keys.each{ |db| push_design_doc_for db.to_s }
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
- def validate_options_hash options
49
- %w(environment design_doc).each do |opt_key|
50
- unless options.has_key?(opt_key.to_sym)
51
- raise "Must provide :#{opt_key} option"
52
- end
53
- end
54
- end
55
-
56
- def validate_environments_exists_for_all_dbs
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
- @databases = {}
64
- @config.each_pair do |db_name,conn_by_env|
65
- conn_settings = conn_by_env[@environment] || {}
66
- host = conn_settings['host'] || 'localhost'
67
- port = conn_settings['port'] || 5984
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
- module AssumeDesignDocName
78
+ private
76
79
 
77
- attr_accessor :design_doc_name
78
-
79
- def view name, options={}, &block
80
- super "#{@design_doc_name}/#{name}", options, &block
81
- end
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
- describe Cambric do
5
-
6
- describe "when initializing without the design document name" do
7
- it "should raise an error" do
8
- lambda do
9
- Cambric.new load_fixture('tweets.yml'), :environment => 'development'
10
- end.should raise_error
11
- end
12
- end
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
- describe "when initializing for a non-specified environment" do
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
- it "should assume ./couchdb as the database path" do
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
- @cambric = Cambric.new load_fixture('twitter-clone.yml'),
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 have a value for the environment" do
44
- @cambric.environment.should_not be_nil
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 have something for config" do
48
- @cambric.config.should_not be_nil
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 match the given design document name" do
52
- @cambric.design_doc_name.should == 'twitter-clone'
30
+ it "should default to 'development' for the environment" do
31
+ Cambric.environment.should == 'development'
53
32
  end
54
33
 
55
- it "should match the given database directory" do
56
- @cambric.db_dir.should =~ /\/spec\/fixtures\/twitter-clone/
34
+ it "should not throw a fit when creating databases" do
35
+ Cambric.create_all_databases
57
36
  end
58
-
59
- it "should contain a key for each database entry" do
60
- %w(users tweets).each do |db|
61
- @cambric.config.keys.should include(db)
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 hash-style access databases, by name, as string or symbol" do
66
- %w(users tweets).each do |db_name|
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
- describe "after pushing up the databases" do
74
- before :all do
75
- @cambric.create_all_databases
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 "when creating databases" do
62
+ describe "after creating databases" do
92
63
  before :all do
93
- Cambric.new(load_fixture('foo-bar-baz.yml'),
94
- :environment => 'staging',
95
- :design_doc => 'xop',
96
- :db_dir => File.join(FIXTURES_PATH, 'foo-bar-baz')).create_all_databases
97
- @server = CouchRest.new("localhost:5984")
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 access databases, with the environment name" do
101
- %w(bar baz).each do |db|
102
- @server.database("#{db}-staging").info.should_not be_nil
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 pushed to each the specified design doc name" do
107
- %w(bar baz).each do |db|
108
- @server.database("#{db}-staging").get('_design/xop').should_not be_nil
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
- end
112
-
113
- describe "when the YAML specifies a host or port value" do
114
- before :all do
115
- @cambric = Cambric.new load_fixture('foo-bar-baz.yml'),
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 reflect the host value in the database URI" do
122
- URI.parse(@cambric[:bar].uri).host.should == 'some.where'
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 reflect the port value in the database URI" do
126
- URI.parse(@cambric[:baz].uri).port.should == 5566
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.3.1
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-18 00:00:00 -07:00
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
@@ -1,2 +0,0 @@
1
- spaz:
2
-
@@ -1,11 +0,0 @@
1
- bar:
2
- staging:
3
-
4
- somewhere:
5
- host: some.where
6
-
7
- baz:
8
- staging:
9
-
10
- somewhere:
11
- port: 5566
@@ -1,6 +0,0 @@
1
- users:
2
- development:
3
-
4
- tweets:
5
- development:
6
-