zdzolton-cambric 0.2.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/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Zachary Zolton
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,17 @@
1
+ = Cambric
2
+
3
+ Opinionated management and usage of CouchDB from your Ruby apps.
4
+
5
+ == Usage
6
+
7
+ Coming soon...
8
+
9
+ == Installation
10
+
11
+ sudo gem install jchris-couchapp jchris-couchrest zdzolton-cambric
12
+
13
+ Configure Rails: Coming soon...
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2009 Zachary Zolton. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,49 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "cambric"
8
+ gem.summary = %Q{Opinionated management and usage of CouchDB from your Ruby apps.}
9
+ gem.email = "zachary.zolton@gmail.com"
10
+ gem.homepage = "http://github.com/zdzolton/cambric"
11
+ gem.authors = ["Zachary Zolton", "Geoff Buesing"]
12
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
13
+ gem.add_dependency('jchris-couchrest', '>= 1.0.5')
14
+ end
15
+
16
+ rescue LoadError
17
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
18
+ end
19
+
20
+ require 'spec/rake/spectask'
21
+ Spec::Rake::SpecTask.new(:spec) do |spec|
22
+ spec.libs << 'lib' << 'spec'
23
+ spec.spec_files = FileList['spec/**/*_spec.rb']
24
+ end
25
+
26
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
27
+ spec.libs << 'lib' << 'spec'
28
+ spec.pattern = 'spec/**/*_spec.rb'
29
+ spec.rcov = true
30
+ end
31
+
32
+
33
+ task :default => :spec
34
+
35
+ require 'rake/rdoctask'
36
+ Rake::RDocTask.new do |rdoc|
37
+ if File.exist?('VERSION.yml')
38
+ config = YAML.load(File.read('VERSION.yml'))
39
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
40
+ else
41
+ version = ""
42
+ end
43
+
44
+ rdoc.rdoc_dir = 'rdoc'
45
+ rdoc.title = "cambric #{version}"
46
+ rdoc.rdoc_files.include('README*')
47
+ rdoc.rdoc_files.include('lib/**/*.rb')
48
+ end
49
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
data/lib/cambric.rb ADDED
@@ -0,0 +1,85 @@
1
+ require 'erb'
2
+ require 'yaml'
3
+ require 'couchrest'
4
+
5
+ class Cambric
6
+
7
+ attr_reader :config, :environment, :design_doc_name, :db_dir
8
+
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
18
+ end
19
+
20
+ def [](db)
21
+ @databases[db.to_sym]
22
+ end
23
+
24
+ def create_all_databases
25
+ @databases.each_pair do |db_name,db|
26
+ name_with_env = "#{db_name}-#{@environment}"
27
+ begin
28
+ db.server.create_db name_with_env
29
+ rescue
30
+ db.server.database(name_with_env).recreate!
31
+ end
32
+ end
33
+ push_all_design_docs
34
+ end
35
+
36
+ def push_all_design_docs
37
+ @databases.keys.each{ |db| push_design_doc_for db.to_s }
38
+ end
39
+
40
+ private
41
+
42
+ def push_design_doc_for database
43
+ design_doc_path = File.join @db_dir, database
44
+ raise "Database directory #{design_doc_path} does not exist!" unless File.exist?(design_doc_path)
45
+ `couchapp push #{design_doc_path} #{@design_doc_name} #{self[database].uri}`
46
+ end
47
+
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
60
+ end
61
+
62
+ 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
72
+ end
73
+ end
74
+
75
+ module AssumeDesignDocName
76
+
77
+ attr_accessor :design_doc_name
78
+
79
+ def view name, options={}, &block
80
+ super "#{@design_doc_name}/#{name}", options, &block
81
+ end
82
+
83
+ end
84
+
85
+ end
@@ -0,0 +1,130 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'uri'
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
13
+
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
23
+
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
+
36
+ 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')
41
+ end
42
+
43
+ it "should have a value for the environment" do
44
+ @cambric.environment.should_not be_nil
45
+ end
46
+
47
+ it "should have something for config" do
48
+ @cambric.config.should_not be_nil
49
+ end
50
+
51
+ it "should match the given design document name" do
52
+ @cambric.design_doc_name.should == 'twitter-clone'
53
+ end
54
+
55
+ it "should match the given database directory" do
56
+ @cambric.db_dir.should =~ /\/spec\/fixtures\/twitter-clone/
57
+ 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)
62
+ end
63
+ end
64
+
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
71
+ end
72
+
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
88
+
89
+ end
90
+
91
+ describe "when creating databases" do
92
+ 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")
98
+ end
99
+
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
103
+ end
104
+ end
105
+
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
109
+ end
110
+ 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')
119
+ end
120
+
121
+ it "should reflect the host value in the database URI" do
122
+ URI.parse(@cambric[:bar].uri).host.should == 'some.where'
123
+ end
124
+
125
+ it "should reflect the port value in the database URI" do
126
+ URI.parse(@cambric[:baz].uri).port.should == 5566
127
+ end
128
+ end
129
+
130
+ end
@@ -0,0 +1,2 @@
1
+ spaz:
2
+
@@ -0,0 +1,11 @@
1
+ bar:
2
+ staging:
3
+
4
+ somewhere:
5
+ host: some.where
6
+
7
+ baz:
8
+ staging:
9
+
10
+ somewhere:
11
+ port: 5566
@@ -0,0 +1,7 @@
1
+ function(doc) {
2
+ var outdoc = { message: doc.message, author: doc.author };
3
+ doc.followers.push(doc.author);
4
+ doc.followers.forEach(function(f) {
5
+ emit([f, doc.created_at], outdoc);
6
+ });
7
+ };
@@ -0,0 +1,6 @@
1
+ users:
2
+ development:
3
+
4
+ tweets:
5
+ development:
6
+
@@ -0,0 +1,23 @@
1
+ require 'spec'
2
+
3
+ # Gem dependencies... Here?
4
+ require 'rubygems'
5
+ gem 'jchris-couchrest'
6
+
7
+ require 'json'
8
+ require 'couchrest'
9
+
10
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
11
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
12
+
13
+ require 'cambric'
14
+
15
+ FIXTURES_PATH = './spec/fixtures'
16
+
17
+ def load_fixture *path
18
+ open(File.expand_path(File.join %w(spec fixtures) + path))
19
+ end
20
+
21
+ Spec::Runner.configure do |config|
22
+
23
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: zdzolton-cambric
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Zachary Zolton
8
+ - Geoff Buesing
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-05-18 00:00:00 -07:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: jchris-couchrest
18
+ type: :runtime
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 1.0.5
25
+ version:
26
+ description:
27
+ email: zachary.zolton@gmail.com
28
+ executables: []
29
+
30
+ extensions: []
31
+
32
+ extra_rdoc_files:
33
+ - LICENSE
34
+ - README.rdoc
35
+ files:
36
+ - .document
37
+ - .gitignore
38
+ - LICENSE
39
+ - README.rdoc
40
+ - Rakefile
41
+ - VERSION
42
+ - lib/cambric.rb
43
+ - spec/cambric_spec.rb
44
+ - spec/fixtures/degenerate.yml
45
+ - spec/fixtures/foo-bar-baz.yml
46
+ - spec/fixtures/twitter-clone.yml
47
+ - spec/fixtures/twitter-clone/tweets/views/by_follower_and_created_at/map.js
48
+ - spec/spec_helper.rb
49
+ has_rdoc: true
50
+ homepage: http://github.com/zdzolton/cambric
51
+ post_install_message:
52
+ rdoc_options:
53
+ - --charset=UTF-8
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ version:
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ version:
68
+ requirements: []
69
+
70
+ rubyforge_project:
71
+ rubygems_version: 1.2.0
72
+ signing_key:
73
+ specification_version: 2
74
+ summary: Opinionated management and usage of CouchDB from your Ruby apps.
75
+ test_files:
76
+ - spec/cambric_spec.rb
77
+ - spec/spec_helper.rb