orm_adapter-couchbase 0.1.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.
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