smeg2 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/FEATURES ADDED
@@ -0,0 +1,5 @@
1
+ * Ability to load views from disk
2
+ * Query these views from an object
3
+ * Map the views to a hash structure, or just an array
4
+ * At the top level retrieved, look for a RubyType field, and cast
5
+ * vague AR methods (Create, save, hooks)
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Lincoln Stoll
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.md ADDED
@@ -0,0 +1,69 @@
1
+ # smeg2
2
+
3
+ Simple library for working with CouchDB
4
+
5
+ ## Basic Usage
6
+
7
+ Create a database object to work with. Will create the DB if it doesn't exist
8
+
9
+ @db = Smeg2::Database.new('http://localhost:5984/smeg2-test')
10
+ # if you don't want to create the DB if it doesn't exist:
11
+ @db = Smeg2::Database.new('http://localhost:5984/smeg2-test', false)
12
+
13
+ Save a new document
14
+
15
+ id = @db.save({:document_title => 'New Document', :documents => 'are just a hash')
16
+ id_of_document_saved = id
17
+ revision_of_document_saved = revision
18
+
19
+ Get a document
20
+
21
+ doc = @db.get(document_id)
22
+ # with revision
23
+ doc = @db.get(document_id, revision)
24
+
25
+ Save an existing document
26
+
27
+ id = @db.save(existing_document_loaded_from_db)
28
+ new_revision = id.revision
29
+
30
+ Delete a document
31
+
32
+ @db.delete(document_id_or_document_object)
33
+
34
+ Run a design document
35
+
36
+ @db.design('DesignDoc/_view/viewname')
37
+ => An array of documents
38
+
39
+ # with parameters
40
+ @db.design('DD/_list/listname/viewname', :key => ab..fg, :xyz => 7)
41
+ => An array of documents
42
+
43
+ # Iterator Method
44
+ @db.design('DesignDoc/_view/viewname') do |doc|
45
+ #invoked for each document
46
+ p doc
47
+ end
48
+
49
+ Delete the database
50
+
51
+ @db.delete_database
52
+
53
+ Create the database
54
+
55
+ @db.create_database
56
+
57
+ ## Note on Patches/Pull Requests
58
+
59
+ * Fork the project.
60
+ * Make your feature addition or bug fix.
61
+ * Add tests for it. This is important so I don't break it in a
62
+ future version unintentionally.
63
+ * Commit, do not mess with rakefile, version, or history.
64
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
65
+ * Send me a pull request. Bonus points for topic branches.
66
+
67
+ == Copyright
68
+
69
+ Copyright (c) 2009 Lincoln Stoll. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,48 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "smeg2"
8
+ gem.summary = %Q{Simple CouchDB library}
9
+ gem.description = %Q{Simple library for working with CouchDB. Avoids magic, keeps it simple.}
10
+ gem.email = "lstoll@lstoll.net"
11
+ gem.homepage = "http://github.com/lstoll/smeg2"
12
+ gem.authors = ["Lincoln Stoll"]
13
+ gem.add_development_dependency "rspec", ">= 1.2.9"
14
+ gem.add_dependency "rest-client", ">= 0"
15
+ gem.add_dependency "hashie", ">= 0"
16
+ gem.add_dependency "json", ">= 0"
17
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
+ end
19
+ Jeweler::GemcutterTasks.new
20
+ rescue LoadError
21
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
22
+ end
23
+
24
+ require 'spec/rake/spectask'
25
+ Spec::Rake::SpecTask.new(:spec) do |spec|
26
+ spec.libs << 'lib' << 'spec'
27
+ spec.spec_files = FileList['spec/**/*_spec.rb']
28
+ end
29
+
30
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
31
+ spec.libs << 'lib' << 'spec'
32
+ spec.pattern = 'spec/**/*_spec.rb'
33
+ spec.rcov = true
34
+ end
35
+
36
+ task :spec => :check_dependencies
37
+
38
+ task :default => :spec
39
+
40
+ require 'rake/rdoctask'
41
+ Rake::RDocTask.new do |rdoc|
42
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
43
+
44
+ rdoc.rdoc_dir = 'rdoc'
45
+ rdoc.title = "smeg2 #{version}"
46
+ rdoc.rdoc_files.include('README*')
47
+ rdoc.rdoc_files.include('lib/**/*.rb')
48
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
data/lib/smeg2.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'json'
2
+ require 'rest_client'
3
+ require 'hashie'
4
+
5
+ $:.unshift File.dirname(__FILE__) unless
6
+ $:.include?(File.dirname(__FILE__)) ||
7
+ $:.include?(File.expand_path(File.dirname(__FILE__)))
8
+
9
+ module Smeg2
10
+ autoload :Document, 'smeg2/document'
11
+ autoload :Tasks, 'smeg2/tasks'
12
+ autoload :Database, 'smeg2/database'
13
+ end
@@ -0,0 +1,106 @@
1
+ require 'cgi'
2
+
3
+ # Represents a connection to the database. Can be used standalone to talk
4
+ # to a couch instance manually, otherwise is used by the mapper.
5
+ class Smeg2::Database
6
+ attr_reader :url
7
+
8
+ # Create a new instance, with the URL for the database to work with
9
+ # By default will create the database if it doesn't exist, pass false
10
+ # as the second parameter to disable this.
11
+ def initialize(url, autocreate = true)
12
+ @url = url
13
+ create_database if autocreate
14
+ end
15
+
16
+ # Creates this database, will not error if the database exists
17
+ def create_database
18
+ begin
19
+ c.put @url, {}
20
+ rescue RestClient::RequestFailed => e
21
+ unless e.message =~ /412$/
22
+ raise e
23
+ end
24
+ end
25
+ end
26
+
27
+ # deletes this database.
28
+ def delete_database
29
+ begin
30
+ c.delete @url
31
+ rescue RestClient::ResourceNotFound
32
+ end
33
+ end
34
+
35
+ # gets a document by it's ID
36
+ def get(docid, rev=nil)
37
+ revurl = rev ? "?rev=#{rev}" : ""
38
+ JSON.parse(c.get(@url + '/' + docid + revurl))
39
+ end
40
+
41
+ # creates/updates a document from a hash/array structure
42
+ def save(doc)
43
+ if id = doc['_id']
44
+ res = c.put(@url + '/' + id, doc.to_json)
45
+ else
46
+ res = c.post(@url, doc.to_json)
47
+ end
48
+ res = JSON.parse(res)
49
+ return nil unless res['ok']
50
+ Smeg2::StringWithRevision.new(res['id'], res['rev'])
51
+ end
52
+
53
+ # deletes a document. Can take an object or id
54
+ def delete(doc)
55
+ if doc.kind_of? String
56
+ rev = get(doc)['_rev']
57
+ else
58
+ rev = doc['_rev']
59
+ doc = doc['_id']
60
+ end
61
+
62
+ c.delete(@url + '/' + doc + '?rev=' + rev)
63
+ end
64
+
65
+ # runs a design by path, with optional params passed in
66
+ def design(path, params = {}, &block)
67
+ url = @url + '/_design/' + path
68
+ res = JSON.parse(c.get(paramify_url(url, params)))
69
+ if block_given?
70
+ # TODO - stream properly
71
+ res.each do |i|
72
+ yield i
73
+ end
74
+ nil
75
+ else
76
+ res
77
+ end
78
+ end
79
+
80
+
81
+
82
+ private
83
+
84
+ def paramify_url url, params = {}
85
+ if params && !params.empty?
86
+ query = params.collect do |k,v|
87
+ v = v.to_json if %w{key startkey endkey}.include?(k.to_s)
88
+ "#{k}=#{CGI.escape(v.to_s)}"
89
+ end.join("&")
90
+ url = "#{url}?#{query}"
91
+ end
92
+ url
93
+ end
94
+
95
+
96
+ def c; RestClient; end
97
+ end
98
+
99
+ class Smeg2::StringWithRevision < String
100
+ attr_reader :revision
101
+
102
+ def initialize(id, rev)
103
+ @revision = rev
104
+ super(id)
105
+ end
106
+ end
@@ -0,0 +1,4 @@
1
+ # Represents a Document. Fields are defined here, as well as callbacks and
2
+ # view access:
3
+ class Smeg2::Document
4
+ end
@@ -0,0 +1,3 @@
1
+ # Defines rake tasks for managing databases and views.
2
+ module Smeg2::Tasks
3
+ end
@@ -0,0 +1,101 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Smeg2::Database do
4
+ before :all do
5
+ @dburl = 'http://localhost:5984/smeg2_test'
6
+ begin
7
+ RestClient.delete(@dburl)
8
+ rescue
9
+ end
10
+ @db = Smeg2::Database.new(@dburl)
11
+ # some kind of fixtures loading?
12
+ end
13
+
14
+ describe "creating/deleting databases" do
15
+ it "should be able to delete a database" do
16
+ @db.create_database
17
+ @db.delete_database
18
+ lambda {RestClient.get(@dburl)}.
19
+ should raise_error(RestClient::ResourceNotFound)
20
+ end
21
+
22
+ it "should be able to create a database" do
23
+ @db.delete_database
24
+ @db.create_database
25
+ lambda {RestClient.get(@dburl)}.
26
+ should_not raise_error(RestClient::ResourceNotFound)
27
+ end
28
+
29
+ it "should not error when creating a database that exists" do
30
+ @db.delete_database
31
+ @db.create_database
32
+ lambda {@db.create_database}.
33
+ should_not raise_error(Exception)
34
+ end
35
+
36
+ it "shoudld automatically create the database" do
37
+ @db.delete_database
38
+ @db = Smeg2::Database.new(@dburl)
39
+ lambda {RestClient.get(@dburl)}.
40
+ should_not raise_error(RestClient::ResourceNotFound)
41
+ end
42
+ end
43
+
44
+ describe "working with documents" do
45
+ before :all do
46
+ @db = Smeg2::Database.new(@dburl)
47
+ end
48
+
49
+ it "should return a valid ID and rev when creating" do
50
+ id = @db.save(:testfield => 'true')
51
+ id.should_not be_empty
52
+ id.revision.should_not be_empty
53
+ lambda {RestClient.get(@dburl + '/' + id)}.
54
+ should_not raise_error(Exception)
55
+ end
56
+
57
+ it "should be able to get a doc by it's ID" do
58
+ id = @db.save(:testfield => 'true')
59
+ doc = @db.get(id)
60
+ doc.should_not be_nil
61
+ doc['testfield'].should_not be_nil
62
+ end
63
+
64
+ it "should be able to get a doc by it's ID and rev" do
65
+ id = @db.save(:testfield => 'true')
66
+ rev = id.revision
67
+ doc = @db.get(id)
68
+ doc['testfield2'] = 'bwah'
69
+ id = @db.save(doc)
70
+ doc = @db.get(id, rev)
71
+ doc['_rev'].should_not eql(id.revision)
72
+ end
73
+
74
+ it "should be able to update an existing doc" do
75
+ id = @db.save(:testfield => 'true')
76
+ doc = @db.get(id)
77
+ doc['testerfield'] = 'false'
78
+ @db.save(doc)
79
+ @db.get(id)['testerfield'].should eql('false')
80
+ end
81
+
82
+ it "should be able to delete a document when given a document" do
83
+ id = @db.save(:testfield => 'true')
84
+ doc = @db.get(id)
85
+ @db.delete(doc)
86
+ lambda {@db.get(id)}.
87
+ should raise_error(RestClient::ResourceNotFound)
88
+ end
89
+
90
+ it "should be able to delete a document when given a document id" do
91
+ id = @db.save(:testfield => 'true')
92
+ @db.delete(id)
93
+ lambda {@db.get(id)}.
94
+ should raise_error(RestClient::ResourceNotFound)
95
+ end
96
+ end
97
+
98
+ describe "Design Access" do
99
+ it "should be able to call a design with parameters"
100
+ end
101
+ end
@@ -0,0 +1,9 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Smeg2::Document do
4
+ it "should save when created called"
5
+ it "should tag its class when saved"
6
+ describe "View Access" do
7
+ it "should be able to query a view"
8
+ end
9
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,10 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'rubygems'
4
+ require 'smeg2'
5
+ require 'spec'
6
+ require 'spec/autorun'
7
+
8
+ Spec::Runner.configure do |config|
9
+
10
+ end
@@ -0,0 +1,8 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Smeg2::Tasks do
4
+ it "should be able to create a database"
5
+ it "should be able to load a view from disk"
6
+ it "should be able to load fixtures from disk"
7
+ it "should be able to delete a database"
8
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: smeg2
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Lincoln Stoll
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-13 00:00:00 +11:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.2.9
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: rest-client
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: hashie
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: json
47
+ type: :runtime
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ description: Simple library for working with CouchDB. Avoids magic, keeps it simple.
56
+ email: lstoll@lstoll.net
57
+ executables: []
58
+
59
+ extensions: []
60
+
61
+ extra_rdoc_files:
62
+ - LICENSE
63
+ - README.md
64
+ files:
65
+ - .document
66
+ - .gitignore
67
+ - FEATURES
68
+ - LICENSE
69
+ - README.md
70
+ - Rakefile
71
+ - VERSION
72
+ - lib/smeg2.rb
73
+ - lib/smeg2/database.rb
74
+ - lib/smeg2/document.rb
75
+ - lib/smeg2/tasks.rb
76
+ - spec/database_spec.rb
77
+ - spec/document_spec.rb
78
+ - spec/spec.opts
79
+ - spec/spec_helper.rb
80
+ - spec/tasks_spec.rb
81
+ has_rdoc: true
82
+ homepage: http://github.com/lstoll/smeg2
83
+ licenses: []
84
+
85
+ post_install_message:
86
+ rdoc_options:
87
+ - --charset=UTF-8
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: "0"
95
+ version:
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: "0"
101
+ version:
102
+ requirements: []
103
+
104
+ rubyforge_project:
105
+ rubygems_version: 1.3.5
106
+ signing_key:
107
+ specification_version: 3
108
+ summary: Simple CouchDB library
109
+ test_files:
110
+ - spec/database_spec.rb
111
+ - spec/document_spec.rb
112
+ - spec/spec_helper.rb
113
+ - spec/tasks_spec.rb