orm_adapter-couchbase 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d55904c8d5e90c57b61d5561d1c1ffe63e0e8eb5
4
+ data.tar.gz: f49d20652726d695708a784ee3372c9e147d0ce5
5
+ SHA512:
6
+ metadata.gz: 63119511c0b60c945bff3f403d26cf96fc2c0ed52e1471b8d0f4f66305cba60b9cddaea694e24449edffa343d2c46b12672c7682583b45c4448dc8e7b4643ec8
7
+ data.tar.gz: 8e430a5629d43526a6201d60a97aa6de349a222cdfb6bcc37dd563f6cbcc4c055d16d2aa4730a8df7e3ce3896445f3ab351ab72ced591bbf48e47004f1f37132
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in orm_adapter-couchbase.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Philipp Fehre
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,64 @@
1
+ # OrmAdapterCouchbase
2
+
3
+ WARNING: This is not finished, and very early stage to see if this can work
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'orm_adapter-couchbase'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install orm_adapter-couchbase
18
+
19
+ ## Usage
20
+
21
+ See the [specs for
22
+ details](https://github.com/sideshowcoder/orm_adapter-couchbase/blob/master/spec/couchbase_spec.rb).
23
+ The Couchbase ORM adapter relies on at least the `all` view to be present which
24
+ should simple return all the object for a given type. This doesn't have great
25
+ performance of course, like any full scan, so it's recommended to create
26
+ additional views to query by other attributes. If you want to for example query
27
+ a user by name, create a view for it.
28
+
29
+ ```ruby
30
+ class User < Couchbase::Model
31
+ attribute :name
32
+ view :by_name
33
+ end
34
+ ```
35
+
36
+ Currently only single attributes are supported, but the idea is to support
37
+ others via `by_name_and_rating` in the future.
38
+
39
+ ## ORM Adapter
40
+
41
+ > "Provides a single point of entry for popular ruby ORMs. Its target audience
42
+ > is gem authors who want to support more than one ORM."
43
+
44
+ For more information see the [orm_adapter
45
+ project](http://github.com/ianwhite/orm_adapter).
46
+
47
+ ## Development / Testing
48
+
49
+ This project is tested against `orm_adapter` to make sure it works as
50
+ advertised.
51
+
52
+ To run the tests:
53
+
54
+ ```
55
+ $ rake spec
56
+ ```
57
+
58
+ ## Contributing
59
+
60
+ 1. Fork it
61
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
62
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
63
+ 4. Push to the branch (`git push origin my-new-feature`)
64
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,4 @@
1
+ require "orm_adapter"
2
+ require "orm_adapter-couchbase/version"
3
+ require "orm_adapter-couchbase/couchbase" if defined?(Couchbase::Model)
4
+
@@ -0,0 +1,168 @@
1
+ require "couchbase/model"
2
+ require "orm_adapter-couchbase/ext/couchbase_model_equality"
3
+ require "orm_adapter-couchbase/ext/couchbase_model_patches"
4
+ require "orm_adapter-couchbase/ext/couchbase_model_has_many"
5
+
6
+ module Couchbase
7
+ class Model
8
+ extend OrmAdapter::ToAdapter
9
+
10
+ class OrmAdapter < OrmAdapter::Base
11
+
12
+ class MissingViewException < StandardError
13
+ def initialize view_name
14
+ message = "view named #{view_name} is not defined"
15
+ super message
16
+ end
17
+ end
18
+
19
+ def create! attrs
20
+ # make sure our views produce consistent data
21
+ klass.create! attrs
22
+ end
23
+
24
+ def destroy model
25
+ return nil unless model.is_a? klass
26
+
27
+ # Hack to get around delete removing the id from the model
28
+ id = model.id
29
+ model.delete
30
+ model.id = id
31
+ end
32
+
33
+ def get! id
34
+ klass.find wrap_key(id)
35
+ end
36
+
37
+ def get id
38
+ klass.find_by_id wrap_key(id)
39
+ end
40
+
41
+ def find_all options = {}
42
+
43
+ view_name, view_options, options = view_for_options(options)
44
+
45
+ conditions, order, limit, offset = extract_conditions!(options)
46
+
47
+ stream = klass.send(view_name, view_options)
48
+
49
+ # deal with everything which wasn't handled via the view
50
+ stream = apply_conditions(stream, conditions)
51
+ stream = apply_order(stream, order)
52
+ stream = stream.drop(offset) if offset
53
+ stream = stream.take(limit) if limit
54
+
55
+ stream.to_a # make sure to return an array
56
+ end
57
+
58
+ def find_first options = {}
59
+ id = options.delete(:id)
60
+ conditions, _ = extract_conditions!(options.dup)
61
+
62
+ if id
63
+ apply_conditions([get(id)], conditions).first
64
+ else
65
+ find_all(options).first
66
+ end
67
+ end
68
+
69
+ private
70
+ def apply_conditions stream, conditions
71
+ return stream if conditions.empty?
72
+ stream.select { |item| satisfies_conditions? item, conditions }
73
+ end
74
+
75
+ def satisfies_conditions? item, conditions
76
+ conditions.all? { |field, value| item.send(field) == value }
77
+ end
78
+
79
+ def apply_order stream, order
80
+ return stream if order.empty?
81
+
82
+ stream.to_a.sort_by do |item|
83
+ sort = []
84
+ order = order.to_enum
85
+ o = order.next
86
+ loop do
87
+ case o
88
+ when Array
89
+ value = item.send(o[0])
90
+ value = invert_value(value) if o[1] == :desc
91
+ sort.push(value)
92
+ else
93
+ value = item.send(o[0])
94
+ case order.peek
95
+ when :asc
96
+ begin
97
+ order.next
98
+ rescue StopIteration
99
+ break
100
+ end
101
+ when :desc
102
+ value = invert_value(value)
103
+ begin
104
+ order.next
105
+ rescue StopIteration
106
+ break
107
+ end
108
+ end
109
+ sort.push(value)
110
+ end
111
+ begin
112
+ o = order.next
113
+ rescue StopIteration
114
+ break
115
+ end
116
+ end
117
+ sort
118
+ end
119
+ end
120
+
121
+ def invert_value value
122
+ case value
123
+ when String
124
+ inverse = []
125
+ value.each_codepoint { |c| inverse.push(-c) }
126
+ inverse
127
+ else
128
+ -value
129
+ end
130
+ end
131
+
132
+ def view_for_options options
133
+ view_name = :all
134
+ view_options = { :stale => false }
135
+ conditions, order, limit, offset = extract_conditions!(options.dup)
136
+
137
+ # TODO would be nice to merge multiple conditions into one view name
138
+ # for example users have a rating, and the comprised key is [user,
139
+ # rating] if the view is named "by_user_and_rating" we could then merge
140
+ # this into one and even apply the ordering in one go
141
+ remaining_conditions = conditions.reject { |condition, value|
142
+ if klass.respond_to?("by_#{condition}")
143
+ view_name = "by_#{condition}".to_sym
144
+ view_options[:key] = value
145
+ end
146
+ }
147
+
148
+ options = { :conditions => remaining_conditions, :order => order }
149
+
150
+ if remaining_conditions.empty?
151
+ # merge limit, and offset conditions into view query
152
+ view_options[:limit] = limit if limit
153
+ view_options[:skip] = offset if offset
154
+ else
155
+ options[:limit] = limit if limit
156
+ options[:offset] = offset if offset
157
+ end
158
+
159
+ raise MissingViewException.new(view_name) unless klass.respond_to?(view_name)
160
+
161
+ [view_name, view_options, options]
162
+ end
163
+
164
+ end
165
+ end
166
+ end
167
+
168
+
@@ -0,0 +1,14 @@
1
+ module Couchbase
2
+ class Model
3
+
4
+ # define the equality as id equality this should be the default
5
+ # but it isn't ...
6
+ #
7
+ # TODO file a bug about this!
8
+ #
9
+ def == other
10
+ id == other.id
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,24 @@
1
+ require 'active_support/inflector'
2
+
3
+ module Couchbase
4
+ class Model
5
+
6
+ # define a has_many relationship, this is comprise of a view and and array
7
+ # with referential keys
8
+ def self.has_many(name, options = {})
9
+ assoc_name = name.to_s.singularize
10
+ ref = "#{assoc_name}_ids"
11
+ attribute(ref, :default => [])
12
+ assoc = (options[:wrapper_class] || assoc_name).to_s.camelize.constantize
13
+
14
+ define_method("#{name}=") do |others|
15
+ raise TypeError unless others.all? { |o| o.is_a? assoc }
16
+ self.send("#{ref}=", others.map(&:id))
17
+ end
18
+ define_method(name) do
19
+ assoc.find(self.send(ref))
20
+ end
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,40 @@
1
+ module Couchbase
2
+ class Model
3
+
4
+ attr_accessor :type
5
+
6
+ # Current master (072262e) version of belongs to
7
+ #
8
+ # support passing a class which is not supported in the current 0.5.3 but
9
+ # already in master
10
+ #
11
+ # - added suppport for assigning to belongs_to
12
+ #
13
+ def self.belongs_to(name, options = {})
14
+ ref = "#{name}_id"
15
+ attribute(ref)
16
+ assoc = (options[:class_name] || name).to_s.camelize.constantize
17
+ define_method(name) do
18
+ assoc.find(self.send(ref))
19
+ end
20
+ define_method("#{name}=") do |other|
21
+ raise TypeError unless other.is_a? assoc
22
+ self.send("#{ref}=", other.id)
23
+ end
24
+ end
25
+
26
+ #
27
+ # updating attributes should fail for invalid attributes, not simply ignore
28
+ # them
29
+ #
30
+ def update_attributes(attrs)
31
+ if id = attrs.delete(:id)
32
+ @id = id
33
+ end
34
+ attrs.each do |key, value|
35
+ setter = :"#{key}="
36
+ send(setter, value)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,3 @@
1
+ module OrmAdapterCouchbase
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'orm_adapter-couchbase/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "orm_adapter-couchbase"
8
+ spec.version = OrmAdapterCouchbase::VERSION
9
+ spec.authors = ["Philipp Fehre"]
10
+ spec.email = ["philipp.fehre@googlemail.com"]
11
+ spec.description = %q{Adds Couchbase support to ORM Adapter}
12
+ spec.summary = %q{Use Couchbase Model to add support for Couchbase ORM Adapter}
13
+ spec.homepage = "https://github.com/sideshowcoder/orm_adapter-couchbase"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "couchbase-model", "~> 0.5.3"
22
+ spec.add_dependency "orm_adapter", "~> 0.5.0"
23
+
24
+ spec.add_development_dependency "rspec", ">= 2.4.0"
25
+ spec.add_development_dependency "bundler", "~> 1.3"
26
+ spec.add_development_dependency "rake"
27
+ end
@@ -0,0 +1,48 @@
1
+ require "spec_helper"
2
+ require "example_app_shared"
3
+
4
+
5
+ if !defined?(Couchbase::Model) || !(Couchbase.connect(:bucket => "orm_adapter") rescue nil)
6
+ puts "** require 'couchbase-model' and start couchbase with a bucket 'orm_adapter' created to run the specs in #{__FILE__}"
7
+ else
8
+
9
+ # this is needed to get around the circular dependency since we need to
10
+ # constantize Note as well as User to have has_many and belongs_to of damn
11
+ # circular dependency
12
+ class Note < Couchbase::Model
13
+ end
14
+
15
+ class User < Couchbase::Model
16
+ attribute :name
17
+ attribute :rating
18
+ has_many :notes
19
+ view :all, :by_name
20
+ end
21
+
22
+ class Note < Couchbase::Model
23
+ attribute :body, :default => "made by orm"
24
+ belongs_to :owner, :class_name => "User"
25
+ view :all
26
+ end
27
+
28
+ module OrmAdapterCouchbaseSpec
29
+
30
+ Couchbase.connection_options = { :bucket => "orm_adapter" }
31
+ Couchbase::Model::Configuration.design_documents_paths = [File.dirname(__FILE__) + "/design_documents/"]
32
+
33
+
34
+ # here be the specs!
35
+ describe Couchbase::Model::OrmAdapter do
36
+ before do
37
+ Couchbase.bucket.flush
38
+ User.ensure_design_document!
39
+ Note.ensure_design_document!
40
+ end
41
+
42
+ it_should_behave_like "example app with orm_adapter" do
43
+ let(:user_class) { User }
44
+ let(:note_class) { Note }
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,6 @@
1
+ /*jshint -W025:false */
2
+ function (doc, meta) {
3
+ if (doc.type === "note") {
4
+ emit(meta.id, null);
5
+ }
6
+ }
@@ -0,0 +1,6 @@
1
+ /*jshint -W025:false */
2
+ function (doc, meta) {
3
+ if (doc.type === "user") {
4
+ emit(meta.id, null);
5
+ }
6
+ }
@@ -0,0 +1,6 @@
1
+ /*jshint -W025:false */
2
+ function (doc, meta) {
3
+ if (doc.type === "user") {
4
+ emit(doc.name, null);
5
+ }
6
+ }
@@ -0,0 +1,6 @@
1
+ /*jshint -W025:false */
2
+ function (doc, meta) {
3
+ if (doc.type === "note") {
4
+ emit(doc.user_id, null);
5
+ }
6
+ }
@@ -0,0 +1,242 @@
1
+ # Copied from orm_adapter and fixed some Specs
2
+
3
+ # to test your new orm_adapter, make an example app that matches the functionality
4
+ # found in the existing specs for example, look at spec/orm_adapter/adapters/active_record_spec.rb
5
+ #
6
+ # Then you can execute this shared spec as follows:
7
+ #
8
+ # it_should_behave_like "execute app with orm_adapter" do
9
+ # let(:user_class) { User }
10
+ # let(:note_class) { Note }
11
+ #
12
+ # # optionaly define the following functions if the ORM does not support
13
+ # # this syntax - this should NOT use the orm_adapter, because we're testing that
14
+ # def create_model(klass, attrs = {})
15
+ # klass.create!(attrs)
16
+ # end
17
+ #
18
+ # def reload_model(model)
19
+ # model.class.find(model.id)
20
+ # end
21
+ # end
22
+ #
23
+ shared_examples_for "example app with orm_adapter" do
24
+
25
+ def create_model(klass, attrs = {})
26
+ klass.create!(attrs)
27
+ end
28
+
29
+ def reload_model(model)
30
+ model.class.find(model.id)
31
+ end
32
+
33
+ describe "an ORM class" do
34
+ subject { note_class }
35
+
36
+ it "#to_adapter should return an adapter instance" do
37
+ subject.to_adapter.should be_a(OrmAdapter::Base)
38
+ end
39
+
40
+ it "#to_adapter should return an adapter for the receiver" do
41
+ subject.to_adapter.klass.should == subject
42
+ end
43
+
44
+ it "#to_adapter should be cached" do
45
+ subject.to_adapter.object_id.should == subject.to_adapter.object_id
46
+ end
47
+ end
48
+
49
+ describe "adapter instance" do
50
+ let(:note_adapter) { note_class.to_adapter }
51
+ let(:user_adapter) { user_class.to_adapter }
52
+
53
+ describe "#get!(id)" do
54
+ it "should return the instance with id if it exists" do
55
+ user = create_model(user_class)
56
+ user_adapter.get!(user.id).should == user
57
+ end
58
+
59
+ it "should allow to_key like arguments" do
60
+ user = create_model(user_class)
61
+ user_adapter.get!(user.to_key).should == user
62
+ end
63
+
64
+ it "should raise an error if there is no instance with that id" do
65
+ lambda { user_adapter.get!("nonexistent id") }.should raise_error
66
+ end
67
+ end
68
+
69
+ describe "#get(id)" do
70
+ it "should return the instance with id if it exists" do
71
+ user = create_model(user_class)
72
+ user_adapter.get(user.id).should == user
73
+ end
74
+
75
+ it "should allow to_key like arguments" do
76
+ user = create_model(user_class)
77
+ user_adapter.get(user.to_key).should == user
78
+ end
79
+
80
+ it "should return nil if there is no instance with that id" do
81
+ user_adapter.get("nonexistent id").should be_nil
82
+ end
83
+ end
84
+
85
+ describe "#find_first" do
86
+ describe "(conditions)" do
87
+ it "should return first model matching conditions, if it exists" do
88
+ user = create_model(user_class, :name => "Fred")
89
+ user_adapter.find_first(:name => "Fred").should == user
90
+ end
91
+
92
+ it "should return nil if no conditions match" do
93
+ user_adapter.find_first(:name => "Betty").should == nil
94
+ end
95
+
96
+ it 'should return the first model if no conditions passed' do
97
+ user = create_model(user_class)
98
+ create_model(user_class)
99
+ user_adapter.find_first.should == user
100
+ end
101
+
102
+ it "when conditions contain associated object, should return first model if it exists" do
103
+ user = create_model(user_class)
104
+ note = create_model(note_class, :owner => user)
105
+ note_adapter.find_first(:owner => user).should == note
106
+ end
107
+
108
+ it "understands :id as a primary key condition (allowing scoped finding)" do
109
+ create_model(user_class, :name => "Fred")
110
+ user = create_model(user_class, :name => "Fred")
111
+ user_adapter.find_first(:id => user.id, :name => "Fred").should == user
112
+ user_adapter.find_first(:id => user.id, :name => "Not Fred").should be_nil
113
+ end
114
+ end
115
+
116
+ describe "(:order => <order array>)" do
117
+ it "should return first model in specified order" do
118
+ user1 = create_model(user_class, :name => "Fred", :rating => 1)
119
+ user2 = create_model(user_class, :name => "Fred", :rating => 2)
120
+ user_adapter.find_first(:order => [:name, [:rating, :desc]]).should == user2
121
+ end
122
+ end
123
+
124
+ describe "(:conditions => <conditions hash>, :order => <order array>)" do
125
+ it "should return first model matching conditions, in specified order" do
126
+ user1 = create_model(user_class, :name => "Fred", :rating => 1)
127
+ user2 = create_model(user_class, :name => "Fred", :rating => 2)
128
+ user_adapter.find_first(:conditions => {:name => "Fred"}, :order => [:rating, :desc]).should == user2
129
+ end
130
+ end
131
+ end
132
+
133
+ describe "#find_all" do
134
+ describe "(conditions)" do
135
+ it "should return only models matching conditions" do
136
+ user1 = create_model(user_class, :name => "Fred")
137
+ user2 = create_model(user_class, :name => "Fred")
138
+ user3 = create_model(user_class, :name => "Betty")
139
+ user_adapter.find_all(:name => "Fred").to_a.should =~ [user1, user2]
140
+ end
141
+
142
+ it "should return all models if no conditions passed" do
143
+ user1 = create_model(user_class, :name => "Fred")
144
+ user2 = create_model(user_class, :name => "Fred")
145
+ user3 = create_model(user_class, :name => "Betty")
146
+ user_adapter.find_all.to_a.should =~ [user1, user2, user3]
147
+ end
148
+
149
+ it "should return empty array if no conditions match" do
150
+ user_adapter.find_all(:name => "Fred").should == []
151
+ end
152
+
153
+ it "when conditions contain associated object, should return first model if it exists" do
154
+ user1, user2 = create_model(user_class), create_model(user_class)
155
+ note1 = create_model(note_class, :owner => user1)
156
+ note2 = create_model(note_class, :owner => user2)
157
+ note_adapter.find_all(:owner => user2).should == [note2]
158
+ end
159
+ end
160
+
161
+ describe "(:order => <order array>)" do
162
+ it "should return all models in specified order" do
163
+ user1 = create_model(user_class, :name => "Fred", :rating => 1)
164
+ user2 = create_model(user_class, :name => "Fred", :rating => 2)
165
+ user3 = create_model(user_class, :name => "Betty", :rating => 1)
166
+ user_adapter.find_all(:order => [:name, [:rating, :desc]]).should == [user3, user2, user1]
167
+ end
168
+ end
169
+
170
+ describe "(:conditions => <conditions hash>, :order => <order array>)" do
171
+ it "should return only models matching conditions, in specified order" do
172
+ user1 = create_model(user_class, :name => "Fred", :rating => 1)
173
+ user2 = create_model(user_class, :name => "Fred", :rating => 2)
174
+ user3 = create_model(user_class, :name => "Betty", :rating => 1)
175
+ user_adapter.find_all(:conditions => {:name => "Fred"}, :order => [:rating, :desc]).should == [user2, user1]
176
+ end
177
+ end
178
+
179
+ describe "(:limit => <number of items>)" do
180
+ it "should return a limited set of matching models" do
181
+ user1 = create_model(user_class, :name => "Fred", :rating => 1)
182
+ user2 = create_model(user_class, :name => "Fred", :rating => 2)
183
+ user3 = create_model(user_class, :name => "Betty", :rating => 3)
184
+ user_adapter.find_all(:limit => 1, :order => [:rating, :asc]).should == [user1]
185
+ user_adapter.find_all(:limit => 2, :order => [:rating, :asc]).should == [user1, user2]
186
+ end
187
+ end
188
+
189
+ describe "(:offset => <offset number>) with limit (as DataMapper doesn't allow offset on its own)" do
190
+ it "should return an offset set of matching models" do
191
+ user1 = create_model(user_class, :name => "Fred", :rating => 1)
192
+ user2 = create_model(user_class, :name => "Fred", :rating => 2)
193
+ user3 = create_model(user_class, :name => "Betty", :rating => 3)
194
+ user_adapter.find_all(:limit => 3, :offset => 0, :order => [:rating, :asc]).should == [user1, user2, user3]
195
+ user_adapter.find_all(:limit => 3, :offset => 1, :order => [:rating, :asc]).should == [user2, user3]
196
+ user_adapter.find_all(:limit => 1, :offset => 1, :order => [:rating, :asc]).should == [user2]
197
+ end
198
+ end
199
+ end
200
+
201
+ describe "#create!(attributes)" do
202
+ it "should create a model with the passed attributes" do
203
+ user = user_adapter.create!(:name => "Fred")
204
+ reload_model(user).name.should == "Fred"
205
+ end
206
+
207
+ it "should raise error when create fails" do
208
+ lambda { user_adapter.create!(:user => create_model(note_class)) }.should raise_error
209
+ end
210
+
211
+ it "when attributes contain an associated object, should create a model with the attributes" do
212
+ user = create_model(user_class)
213
+ note = note_adapter.create!(:owner => user)
214
+ reload_model(note).owner.should == user
215
+ end
216
+
217
+ it "when attributes contain an has_many assoc, should create a model with the attributes" do
218
+ notes = [create_model(note_class), create_model(note_class)]
219
+ user = user_adapter.create!(:notes => notes)
220
+ reload_model(user).notes.should == notes
221
+ end
222
+ end
223
+
224
+ describe "#destroy(instance)" do
225
+ it "should destroy the instance if it exists" do
226
+ user = create_model(user_class)
227
+ (!!user_adapter.destroy(user)).should == true # make it work with both RSpec 2.x and 3.x
228
+ user_adapter.get(user.id).should be_nil
229
+ end
230
+
231
+ it "should return nil if passed with an invalid instance" do
232
+ user_adapter.destroy("nonexistent instance").should be_nil
233
+ end
234
+
235
+ it "should not destroy the instance if it doesn't match the model class" do
236
+ user = create_model(user_class)
237
+ note_adapter.destroy(user).should be_nil
238
+ user_adapter.get(user.id).should == user
239
+ end
240
+ end
241
+ end
242
+ end
@@ -0,0 +1,6 @@
1
+ $:.unshift(File.dirname(__FILE__) + "/../lib")
2
+
3
+ require "rspec"
4
+ require "couchbase/model"
5
+ require "orm_adapter"
6
+ require "orm_adapter-couchbase"
metadata ADDED
@@ -0,0 +1,140 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: orm_adapter-couchbase
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Philipp Fehre
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: couchbase-model
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.5.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.5.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: orm_adapter
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.5.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.5.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 2.4.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 2.4.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Adds Couchbase support to ORM Adapter
84
+ email:
85
+ - philipp.fehre@googlemail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - Gemfile
92
+ - LICENSE.txt
93
+ - README.md
94
+ - Rakefile
95
+ - lib/orm_adapter-couchbase.rb
96
+ - lib/orm_adapter-couchbase/couchbase.rb
97
+ - lib/orm_adapter-couchbase/ext/couchbase_model_equality.rb
98
+ - lib/orm_adapter-couchbase/ext/couchbase_model_has_many.rb
99
+ - lib/orm_adapter-couchbase/ext/couchbase_model_patches.rb
100
+ - lib/orm_adapter-couchbase/version.rb
101
+ - orm_adapter-couchbase.gemspec
102
+ - spec/couchbase_spec.rb
103
+ - spec/design_documents/note/all/map.js
104
+ - spec/design_documents/user/all/map.js
105
+ - spec/design_documents/user/by_name/map.js
106
+ - spec/design_documents/user/notes/map.js
107
+ - spec/example_app_shared.rb
108
+ - spec/spec_helper.rb
109
+ homepage: https://github.com/sideshowcoder/orm_adapter-couchbase
110
+ licenses:
111
+ - MIT
112
+ metadata: {}
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ requirements: []
128
+ rubyforge_project:
129
+ rubygems_version: 2.2.2
130
+ signing_key:
131
+ specification_version: 4
132
+ summary: Use Couchbase Model to add support for Couchbase ORM Adapter
133
+ test_files:
134
+ - spec/couchbase_spec.rb
135
+ - spec/design_documents/note/all/map.js
136
+ - spec/design_documents/user/all/map.js
137
+ - spec/design_documents/user/by_name/map.js
138
+ - spec/design_documents/user/notes/map.js
139
+ - spec/example_app_shared.rb
140
+ - spec/spec_helper.rb