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 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
-