veneer 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/..gemspec +21 -0
- data/.gitignore +2 -5
- data/Gemfile +4 -0
- data/README.md +171 -0
- data/Rakefile +3 -36
- data/lib/..rb +3 -0
- data/lib/veneer/adapters/active_record.rb +1 -1
- data/lib/veneer/adapters/activerecord/class_wrapper.rb +11 -79
- data/lib/veneer/adapters/activerecord/instance_wrapper.rb +3 -11
- data/lib/veneer/adapters/activerecord/pre_3.0_class_wrapper.rb +24 -0
- data/lib/veneer/adapters/activerecord/pre_3.0_instance_wrapper.rb +15 -0
- data/lib/veneer/adapters/activerecord.rb +9 -2
- data/lib/veneer/adapters/data_mapper.rb +1 -1
- data/lib/veneer/adapters/datamapper/class_wrapper.rb +29 -50
- data/lib/veneer/adapters/datamapper/instance_wrapper.rb +3 -14
- data/lib/veneer/adapters/mongomapper/class_wrapper.rb +2 -56
- data/lib/veneer/adapters/mongomapper.rb +2 -2
- data/lib/veneer/base/class_wrapper.rb +46 -11
- data/lib/veneer/base/instance_wrapper.rb +12 -14
- data/lib/veneer/core_ext/kernel.rb +0 -1
- data/lib/veneer/errors.rb +0 -1
- data/lib/veneer/lint.rb +183 -0
- data/lib/veneer/version.rb +3 -0
- data/lib/veneer.rb +1 -4
- data/test/test_helper.rb +4 -3
- data/test/veneer/adapters/{active_record/active_record_setup.rb → test_active_record.rb} +23 -1
- data/test/veneer/adapters/test_datamapper.rb +56 -0
- data/test/veneer/adapters/test_mongomapper.rb +49 -0
- data/test/veneer/proxy_test.rb +20 -45
- data/veneer.gemspec +15 -108
- metadata +40 -60
- data/README.textile +0 -142
- data/VERSION +0 -1
- data/datamapper_setup.rb +0 -2
- data/lib/veneer/base/conditional.rb +0 -77
- data/test/macros/class_wrapper/create_macro.rb +0 -54
- data/test/macros/class_wrapper/delete_macro.rb +0 -31
- data/test/macros/class_wrapper/find_macro.rb +0 -119
- data/test/macros/class_wrapper/hooks.rb +0 -41
- data/test/macros/class_wrapper/validations.rb +0 -91
- data/test/macros/instance_wrapper/destroy_macro.rb +0 -36
- data/test/macros/instance_wrapper/new_record_macro.rb +0 -39
- data/test/macros/instance_wrapper/save_macro.rb +0 -55
- data/test/macros/veneer_constants_interface.rb +0 -26
- data/test/support/before_save_mixin.rb +0 -14
- data/test/support/valiations_method_method.rb +0 -0
- data/test/veneer/adapters/active_record/class_wrapper_test.rb +0 -23
- data/test/veneer/adapters/active_record/instance_wrapper_test.rb +0 -21
- data/test/veneer/adapters/datamapper/class_wrapper_test.rb +0 -24
- data/test/veneer/adapters/datamapper/datamapper_setup.rb +0 -34
- data/test/veneer/adapters/datamapper/instance_wrapper_test.rb +0 -21
- data/test/veneer/adapters/mongomapper/class_wrapper_test.rb +0 -24
- data/test/veneer/adapters/mongomapper/instance_wrapper_test.rb +0 -21
- data/test/veneer/adapters/mongomapper/mongomapper_setup.rb +0 -25
- data/test/veneer/base/conditonal_test.rb +0 -118
data/..gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "./version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "."
|
7
|
+
s.version = .::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["TODO: Write your name"]
|
10
|
+
s.email = ["TODO: Write your email address"]
|
11
|
+
s.homepage = ""
|
12
|
+
s.summary = %q{TODO: Write a gem summary}
|
13
|
+
s.description = %q{TODO: Write a gem description}
|
14
|
+
|
15
|
+
s.rubyforge_project = "."
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
end
|
data/.gitignore
CHANGED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
# veneer
|
2
|
+
|
3
|
+
Veneer is an interface that sits above Data Sources. A data source may be an ORM like ActiveRecord or DataMapper, or it could be a document store like MongoMapper, Mongoid, a key value storage like Moneta, or even an adapter could be setup to use for an external API.
|
4
|
+
|
5
|
+
Veneer aims to provide plugin, engine, and library authors with a consistant interface to any of these libraries so that plugins, engines, stacks and gems may be used across data store types. Reusable code FTW!
|
6
|
+
|
7
|
+
It differs from ActiveModel in that it doesn't provide any validation support, serialization, callbacks, state machine or anything like that. Veneer is intended to work _with_ ActiveModel to provide a data store independant interface to create reusable code.
|
8
|
+
|
9
|
+
Veneer instead aims to provide a simple interface for
|
10
|
+
* querying
|
11
|
+
* creating
|
12
|
+
* saving
|
13
|
+
* deleting
|
14
|
+
* basic lifecycle hooks
|
15
|
+
** before validation
|
16
|
+
** before save
|
17
|
+
** after save
|
18
|
+
** before destroy
|
19
|
+
** after destroy
|
20
|
+
|
21
|
+
There is no interface for validations, since this interface is handled as part of ActiveModel
|
22
|
+
|
23
|
+
## Creating and Saving an instance
|
24
|
+
|
25
|
+
To create an instance of an object wrap the class in a vaneer call and create or get a new instance.
|
26
|
+
|
27
|
+
<pre><code>obj = Veneer(MyModel).new(:some => "hash", :of => "attributes")
|
28
|
+
obj.save
|
29
|
+
|
30
|
+
# OR
|
31
|
+
|
32
|
+
obj = Veneer(MyModel).create(:some => "hash", :of => "attributes")
|
33
|
+
</code></pre>
|
34
|
+
|
35
|
+
There are also version that will raise an exception if it could not save
|
36
|
+
|
37
|
+
<pre><code>obj = Veneer(MyModel).new(:some => "attribute").save!
|
38
|
+
|
39
|
+
# OR
|
40
|
+
|
41
|
+
obj = Veneer(MyModel).create!(:some => "attribute")
|
42
|
+
</code></pre>
|
43
|
+
|
44
|
+
h2. Deleting
|
45
|
+
|
46
|
+
You can delete all the instances of a model or a single instance.
|
47
|
+
|
48
|
+
<pre><code>Veneer(MyModel).destroy\_all # delete all instances
|
49
|
+
|
50
|
+
@some\_veneer\_model.destroy
|
51
|
+
</code></pre>
|
52
|
+
|
53
|
+
### Updating
|
54
|
+
|
55
|
+
To update an instance:
|
56
|
+
|
57
|
+
<pre><code>@some\_veneer\_instance.update(:with => "attributes")
|
58
|
+
|
59
|
+
OR
|
60
|
+
|
61
|
+
@some\_veneer\_instance.update!(:with => "attributes") # raise on error
|
62
|
+
</code></pre>
|
63
|
+
|
64
|
+
## Queries
|
65
|
+
|
66
|
+
Veneer lets you query models with a simple interface. Only simple queries are supported.
|
67
|
+
|
68
|
+
You can query a single object, or multiple objects.
|
69
|
+
|
70
|
+
<pre><code>Veneer(MyModel).first(:conditions => {:name => "foo"})
|
71
|
+
|
72
|
+
Veneer(MyModel).all(:conditions => {:age => 18}, :limit => 5)
|
73
|
+
</code></pre>
|
74
|
+
|
75
|
+
The supported options are:
|
76
|
+
|
77
|
+
* :limit
|
78
|
+
* :offset
|
79
|
+
* :order
|
80
|
+
* :conditions
|
81
|
+
|
82
|
+
## Limit & Offset
|
83
|
+
|
84
|
+
The :limit option will limit the number of returned results.
|
85
|
+
|
86
|
+
The :offset option, when set to an integer x will begin the results at the xth result.
|
87
|
+
|
88
|
+
## Order
|
89
|
+
|
90
|
+
Ordering should be set as an array. By default, the order is decending.
|
91
|
+
|
92
|
+
The format of the array is:
|
93
|
+
|
94
|
+
<pre><code>["<field> <directon>", "<field>"]
|
95
|
+
|
96
|
+
### Example
|
97
|
+
Veneer(MyModel).all(:order => [:name, "age desc")
|
98
|
+
</code></pre>
|
99
|
+
|
100
|
+
## Conditions
|
101
|
+
|
102
|
+
Conditions are a very simple set of conditions on the fields of the model. The for of the conditions are:
|
103
|
+
|
104
|
+
<pre><code>:conditions => {:field => value}</code></pre>
|
105
|
+
|
106
|
+
<pre><code>
|
107
|
+
Veneer(MyModel).all(:conditions => {:name => ["fred", "barney"], :age => (18..18)})
|
108
|
+
Veneer(MyModel).first(:conditions => {:name => "fred"})
|
109
|
+
</code></pre>
|
110
|
+
|
111
|
+
Condition fields should be ready to accept:
|
112
|
+
|
113
|
+
* String
|
114
|
+
* Range (Between clauses)
|
115
|
+
* Array (IN clauses)
|
116
|
+
* nil
|
117
|
+
|
118
|
+
The results of a query are all wrapped as Veneer instances.
|
119
|
+
|
120
|
+
## All Together
|
121
|
+
|
122
|
+
<pre><code>Veneer(MyModel).all(:order => [:name, "age asc"], :limit => 5, :offset => 15, :conditions => {:name => "betty", :age => (0..18)})
|
123
|
+
</code></pre>
|
124
|
+
|
125
|
+
## Object methods
|
126
|
+
|
127
|
+
All methods that aren't found on the adapter, are passed through to the instance. So to access any attributes on the actual model instance, just call the method on it. This can be handy to access things that should be avaialble with an ActiveModel.
|
128
|
+
|
129
|
+
## Current Support
|
130
|
+
|
131
|
+
Veneer currently has built in support for ActiveRecord and DataMapper.
|
132
|
+
|
133
|
+
Veneer works on a VeneerInterface inner module though so you can easily impelment your adapter without requiring it to be in the veneer repo (although pull requests are welcome) (see Building Your Adapter)
|
134
|
+
|
135
|
+
To use DataMapper or ActiveRecord
|
136
|
+
|
137
|
+
<pre><code>
|
138
|
+
require 'veneer/adapters/activerecord'
|
139
|
+
require 'veneer/adapters/datamapper'
|
140
|
+
</code></pre>
|
141
|
+
|
142
|
+
## Building Your own Adapter
|
143
|
+
|
144
|
+
Veneer is made so that you don't need to have access to the main repository to create an adapter. Veneer looks for an inner constant in the klass or object. For example, in ActiveRecord, to provide the adapter, Veneer will look for the adapter in ActiveRecord::VeneerInterface. VeneerInterface should define two classes:
|
145
|
+
|
146
|
+
* ClassWrapper
|
147
|
+
* InstanceWrapper
|
148
|
+
|
149
|
+
So, you'd end up with
|
150
|
+
|
151
|
+
* ActiveRecord::Base::VeneerInterface::ClassWrapper < Veneer::Base::ClassWrapper
|
152
|
+
* ActiveRecord::Base::VeneerInterface::InstanceWrapper < Veneer::Base::InstanceWrapper
|
153
|
+
|
154
|
+
By using inner constants, no behavior of the base implementation is overwritten, or will clash with potential methods implented in the base data store.
|
155
|
+
|
156
|
+
It also means that any adapter can be created without direct access to the Veneer repository.
|
157
|
+
|
158
|
+
## Note on Patches/Pull Requests
|
159
|
+
|
160
|
+
* Fork the project.
|
161
|
+
* Make your feature addition or bug fix.
|
162
|
+
* Add tests for it. This is important so I don't break it in a
|
163
|
+
future version unintentionally.
|
164
|
+
* Commit, do not mess with rakefile, version, or history.
|
165
|
+
(if you want to have your own version, that is fine but
|
166
|
+
bump version in a commit by itself I can ignore when I pull)
|
167
|
+
* Send me a pull request. Bonus points for topic branches.
|
168
|
+
|
169
|
+
## Copyright
|
170
|
+
|
171
|
+
Copyright (c) 2009 Daniel Neighman. See LICENSE for details.
|
data/Rakefile
CHANGED
@@ -1,24 +1,5 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
|
4
|
-
begin
|
5
|
-
require 'jeweler'
|
6
|
-
Jeweler::Tasks.new do |gem|
|
7
|
-
gem.name = "veneer"
|
8
|
-
gem.summary = %Q{A thin veneer over data stores}
|
9
|
-
gem.description = %Q{Veneer provides basic querying, saving, deleteing and creating of data stores.}
|
10
|
-
gem.email = "has.sox@gmail.com"
|
11
|
-
gem.homepage = "http://github.com/hassox/veneer"
|
12
|
-
gem.authors = ["Daniel Neighman"]
|
13
|
-
gem.rubyforge_project = "veneer"
|
14
|
-
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
|
-
end
|
16
|
-
Jeweler::RubyforgeTasks.new do |rubyforge|
|
17
|
-
rubyforge.doc_task = "rdoc"
|
18
|
-
end
|
19
|
-
rescue LoadError
|
20
|
-
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
21
|
-
end
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
22
3
|
|
23
4
|
task :default => [:test_units]
|
24
5
|
require 'rake/testtask'
|
@@ -28,21 +9,7 @@ Rake::TestTask.new("test"){ |test|
|
|
28
9
|
test.verbose = true
|
29
10
|
test.warning = true
|
30
11
|
test.libs << "test"
|
31
|
-
test.test_files = FileList["test/test*.rb", "test
|
12
|
+
test.test_files = FileList["test/test*.rb", "test/**/test*.rb"]
|
32
13
|
}
|
33
14
|
|
34
|
-
task :test => :check_dependencies
|
35
|
-
|
36
|
-
require 'rake/rdoctask'
|
37
|
-
Rake::RDocTask.new do |rdoc|
|
38
|
-
if File.exist?('VERSION')
|
39
|
-
version = File.read('VERSION')
|
40
|
-
else
|
41
|
-
version = ""
|
42
|
-
end
|
43
15
|
|
44
|
-
rdoc.rdoc_dir = 'rdoc'
|
45
|
-
rdoc.title = "veneer #{version}"
|
46
|
-
rdoc.rdoc_files.include('README*')
|
47
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
48
|
-
end
|
data/lib/..rb
ADDED
@@ -1 +1 @@
|
|
1
|
-
require
|
1
|
+
require 'veneer/adapters/activerecord'
|
@@ -10,92 +10,24 @@ module ActiveRecord
|
|
10
10
|
klass.destroy_all
|
11
11
|
end
|
12
12
|
|
13
|
-
def find_first(
|
14
|
-
opts
|
15
|
-
klass.find(:first, opts)
|
13
|
+
def find_first(opts)
|
14
|
+
build_query(opts).first
|
16
15
|
end
|
17
16
|
|
18
|
-
def find_many(
|
19
|
-
opts
|
20
|
-
klass.find(:all,opts)
|
21
|
-
end
|
22
|
-
|
23
|
-
def before_save(*methods)
|
24
|
-
klass.before_save *methods
|
25
|
-
end
|
26
|
-
|
27
|
-
%w(
|
28
|
-
validates_presence_of
|
29
|
-
validates_uniqueness_of
|
30
|
-
validates_confirmation_of
|
31
|
-
).each do |meth|
|
32
|
-
class_eval <<-RUBY
|
33
|
-
def #{meth}(*args)
|
34
|
-
klass.#{meth}(*args)
|
35
|
-
end
|
36
|
-
RUBY
|
37
|
-
end
|
38
|
-
|
39
|
-
def validates_with_method(*methods)
|
40
|
-
methods.each do |meth|
|
41
|
-
@klass.validate meth
|
42
|
-
end
|
17
|
+
def find_many(opts)
|
18
|
+
build_query(opts)
|
43
19
|
end
|
44
20
|
|
45
21
|
private
|
46
|
-
def
|
47
|
-
|
48
|
-
opts
|
49
|
-
opts
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
ary << "#{cnd.field} #{cnd.direction}"
|
54
|
-
end.join(",")
|
55
|
-
end
|
56
|
-
|
57
|
-
unless c.conditions.blank?
|
58
|
-
val_array = []
|
59
|
-
cnds = c.conditions.inject([]) do |ary, cd|
|
60
|
-
case cd.operator
|
61
|
-
when :eql
|
62
|
-
if cd.value.nil?
|
63
|
-
ary << "#{cd.field} IS ?"
|
64
|
-
else
|
65
|
-
ary << "#{cd.field} = ?"
|
66
|
-
end
|
67
|
-
val_array << cd.value
|
68
|
-
when :not
|
69
|
-
if cd.value.nil?
|
70
|
-
ary << "#{cd.field} IS NOT ?"
|
71
|
-
else
|
72
|
-
ary << "#{cd.field} <> ?"
|
73
|
-
end
|
74
|
-
val_array << cd.value
|
75
|
-
when :gt
|
76
|
-
ary << "#{cd.field} > ?"
|
77
|
-
val_array << cd.value
|
78
|
-
when :gte
|
79
|
-
ary << "#{cd.field} >= ?"
|
80
|
-
val_array << cd.value
|
81
|
-
when :lt
|
82
|
-
ary << "#{cd.field} < ?"
|
83
|
-
val_array << cd.value
|
84
|
-
when :lte
|
85
|
-
ary << "#{cd.field} <= ?"
|
86
|
-
val_array << cd.value
|
87
|
-
when :in
|
88
|
-
ary << "#{cd.field} IN ( ? )"
|
89
|
-
val_array << cd.value
|
90
|
-
end
|
91
|
-
ary
|
92
|
-
end
|
93
|
-
opts[:conditions] = [cnds.join(" AND "), *val_array]
|
94
|
-
end
|
95
|
-
opts
|
22
|
+
def build_query(opts)
|
23
|
+
query = klass
|
24
|
+
query.where(opts.conditions) if opts.conditions.present?
|
25
|
+
query.limit(opts.limit) if opts.limit?
|
26
|
+
query.offset(opts.offset) if opts.offset?
|
27
|
+
query.order(opts.order) if opts.order?
|
28
|
+
query
|
96
29
|
end
|
97
30
|
end # ClassWrapper
|
98
|
-
|
99
31
|
end
|
100
32
|
end
|
101
33
|
end
|
@@ -4,20 +4,12 @@ module ActiveRecord
|
|
4
4
|
class InstanceWrapper < Veneer::Base::InstanceWrapper
|
5
5
|
def update(attributes = {})
|
6
6
|
instance.update_attributes(attributes)
|
7
|
-
rescue Veneer::Errors::BeforeSaveError => e
|
8
|
-
handle_before_save_error(e)
|
9
7
|
end
|
10
8
|
|
11
9
|
def save!
|
12
|
-
instance.save
|
13
|
-
|
14
|
-
|
15
|
-
end
|
16
|
-
|
17
|
-
def save
|
18
|
-
instance.save
|
19
|
-
rescue Veneer::Errors::BeforeSaveError => e
|
20
|
-
handle_before_save_error(e)
|
10
|
+
instance.save ?
|
11
|
+
true :
|
12
|
+
raise ::Veneer::Errors::NotSaved
|
21
13
|
end
|
22
14
|
end # InstanceWrapper
|
23
15
|
end # VeneerInterface
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
class Base
|
3
|
+
module VeneerInterface
|
4
|
+
class ClassWrapper < Veneer::Base::ClassWrapper
|
5
|
+
def new(opts = {})
|
6
|
+
::Kernel::Veneer(klass.new(opts))
|
7
|
+
end
|
8
|
+
|
9
|
+
def destroy_all
|
10
|
+
klass.destroy_all
|
11
|
+
end
|
12
|
+
|
13
|
+
def find_first(opts)
|
14
|
+
klass.find(:first, opts.to_hash.symbolize_keys)
|
15
|
+
end
|
16
|
+
|
17
|
+
def find_many(opts)
|
18
|
+
klass.find(:all,opts.to_hash.symbolize_keys)
|
19
|
+
end
|
20
|
+
end # ClassWrapper
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
class Base
|
3
|
+
module VeneerInterface
|
4
|
+
class InstanceWrapper < Veneer::Base::InstanceWrapper
|
5
|
+
def update(attributes = {})
|
6
|
+
instance.update_attributes(attributes)
|
7
|
+
end
|
8
|
+
|
9
|
+
def save!
|
10
|
+
instance.save ? true : (raise ::Veneer::Errors::NotSaved)
|
11
|
+
end
|
12
|
+
end # InstanceWrapper
|
13
|
+
end # VeneerInterface
|
14
|
+
end # Base
|
15
|
+
end # ActiveRecord
|
@@ -1,2 +1,9 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
if defined?(ActiveRecord::Base)
|
2
|
+
if ActiveRecord::VERSION::MAJOR < 3
|
3
|
+
require 'veneer/adapters/activerecord/pre_3.0_class_wrapper'
|
4
|
+
require 'veneer/adapters/activerecord/pre_3.0_instance_wrapper'
|
5
|
+
else
|
6
|
+
require 'veneer/adapters/activerecord/class_wrapper'
|
7
|
+
require 'veneer/adapters/activerecord/instance_wrapper'
|
8
|
+
end
|
9
|
+
end
|
@@ -1 +1 @@
|
|
1
|
-
require
|
1
|
+
require 'veneer/adapters/datamapper'
|
@@ -10,69 +10,48 @@ module DataMapper
|
|
10
10
|
klass.all.destroy
|
11
11
|
end
|
12
12
|
|
13
|
-
def find_first(
|
14
|
-
opts
|
15
|
-
klass.first(opts)
|
13
|
+
def find_first(opts)
|
14
|
+
klass.first(dm_conditions_from_opts(opts))
|
16
15
|
end
|
17
16
|
|
18
|
-
def find_many(
|
19
|
-
opts
|
20
|
-
klass.all(opts)
|
17
|
+
def find_many(opts)
|
18
|
+
klass.all(dm_conditions_from_opts(opts))
|
21
19
|
end
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
[
|
32
|
-
%w(validates_presence_of validates_present),
|
33
|
-
%w(validates_uniqueness_of validates_is_unique),
|
34
|
-
%w(validates_confirmation_of validates_is_confirmed),
|
35
|
-
%w(validates_with_method validates_with_method)
|
36
|
-
].each do |(meth,natural)|
|
37
|
-
class_eval <<-RUBY
|
38
|
-
def #{meth}(*args)
|
39
|
-
ensure_validations_loaded!
|
40
|
-
klass.#{natural}(*args)
|
41
|
-
end
|
42
|
-
RUBY
|
21
|
+
private
|
22
|
+
def order_from_string(str)
|
23
|
+
field, direction = str.split " "
|
24
|
+
direction ||= "asc"
|
25
|
+
field.to_sym.send(direction) if allowed_field?(field)
|
43
26
|
end
|
44
27
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
::Kernel.require 'dm-validations'
|
49
|
-
@klass.class_eval{include ::DataMapper::Validate}
|
50
|
-
end
|
28
|
+
def allowed_field?(field)
|
29
|
+
@allowed ||= klass.properties.map(&:name).map(&:to_s)
|
30
|
+
@allowed.include?(field.to_s)
|
51
31
|
end
|
52
32
|
|
53
|
-
def
|
33
|
+
def dm_conditions_from_opts(raw)
|
54
34
|
opts = {}
|
55
35
|
|
56
|
-
opts[:limit] =
|
57
|
-
opts[:offset] =
|
58
|
-
|
59
|
-
|
60
|
-
opts[:order] =
|
61
|
-
|
62
|
-
ary
|
36
|
+
opts[:limit] = raw.limit if raw.limit?
|
37
|
+
opts[:offset] = raw.offset if raw.offset?
|
38
|
+
|
39
|
+
if raw.order.present?
|
40
|
+
opts[:order] = case raw.order
|
41
|
+
when Array
|
42
|
+
raw.order.inject([]) do |ary, str|
|
43
|
+
ary << order_from_string(str)
|
44
|
+
end.compact
|
45
|
+
when String
|
46
|
+
order_from_string(raw.order)
|
47
|
+
when Symbol
|
48
|
+
raw.order
|
63
49
|
end
|
64
50
|
end
|
65
51
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
when :eql
|
70
|
-
opts[cd.field] = cd.value
|
71
|
-
when :not, :gt, :gte, :lt, :lte
|
72
|
-
opts[cd.field.send(cd.operator)] = cd.value
|
73
|
-
when :in
|
74
|
-
opts[cd.field] = ::Array.new([cd.value].flatten.compact)
|
75
|
-
end
|
52
|
+
if raw.conditions.present?
|
53
|
+
raw.conditions.each do |field, value|
|
54
|
+
opts[field] = value if allowed_field?(field)
|
76
55
|
end
|
77
56
|
end
|
78
57
|
opts
|
@@ -4,25 +4,14 @@
|
|
4
4
|
class InstanceWrapper < ::Veneer::Base::InstanceWrapper
|
5
5
|
|
6
6
|
def save
|
7
|
-
|
8
|
-
instance.class.transaction do
|
9
|
-
result = instance.save
|
10
|
-
end
|
11
|
-
result
|
12
|
-
rescue ::Veneer::Errors::BeforeSaveError => e
|
13
|
-
handle_before_save_error(e)
|
7
|
+
instance.save
|
14
8
|
end
|
15
9
|
|
16
10
|
def save!
|
17
11
|
result = false
|
18
|
-
instance.
|
19
|
-
|
20
|
-
raise ::Veneer::Errors::NotSaved unless result
|
21
|
-
result
|
22
|
-
end
|
12
|
+
result = instance.save
|
13
|
+
raise ::Veneer::Errors::NotSaved unless result
|
23
14
|
result
|
24
|
-
rescue ::Veneer::Errors::BeforeSaveError => e
|
25
|
-
raise ::Veneer::Errors::NotSaved, e.message
|
26
15
|
end
|
27
16
|
|
28
17
|
def new_record?
|
@@ -10,67 +10,13 @@ module MongoMapper
|
|
10
10
|
klass.destroy_all
|
11
11
|
end
|
12
12
|
|
13
|
-
def find_first(
|
14
|
-
opts = conditional_to_mongo_opts(conditional)
|
13
|
+
def find_first(opts)
|
15
14
|
klass.first(opts)
|
16
15
|
end
|
17
16
|
|
18
|
-
def find_many(
|
19
|
-
opts = conditional_to_mongo_opts(conditional)
|
17
|
+
def find_many(opts)
|
20
18
|
klass.all(opts)
|
21
19
|
end
|
22
|
-
|
23
|
-
def before_save(*methods)
|
24
|
-
klass.before_save *methods
|
25
|
-
end
|
26
|
-
|
27
|
-
%w(
|
28
|
-
validates_presence_of
|
29
|
-
validates_uniqueness_of
|
30
|
-
validates_confirmation_of
|
31
|
-
).each do |meth|
|
32
|
-
class_eval <<-RUBY
|
33
|
-
def #{meth}(*args)
|
34
|
-
klass.#{meth}(*args)
|
35
|
-
end
|
36
|
-
RUBY
|
37
|
-
end
|
38
|
-
|
39
|
-
def validates_with_method(*methods)
|
40
|
-
methods.each do |meth|
|
41
|
-
klass.validates_each(nil, :logic => ::Proc.new{ send(meth)})
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
private
|
46
|
-
def conditional_to_mongo_opts(c)
|
47
|
-
opts = {}
|
48
|
-
opts[:limit] = c.limit if c.limit
|
49
|
-
opts[:offset] = c.offset if c.offset
|
50
|
-
|
51
|
-
unless c.order.blank?
|
52
|
-
opts[:order] = c.order.inject([]) do |ary, cnd|
|
53
|
-
ary << "#{cnd.field} #{cnd.direction}"
|
54
|
-
end.join(",")
|
55
|
-
end
|
56
|
-
|
57
|
-
unless c.conditions.blank?
|
58
|
-
cnds = c.conditions.inject({}) do |hsh, c|
|
59
|
-
case c.operator
|
60
|
-
when :eql
|
61
|
-
hsh[c.field] = c.value
|
62
|
-
when :not
|
63
|
-
hsh[c.field] = {"$ne" => c.value}
|
64
|
-
when :gt, :gte, :lt, :lte, :in
|
65
|
-
hsh[c.field] = {"$#{c.operator}" => c.value}
|
66
|
-
end
|
67
|
-
::STDOUT.puts hsh.inspect
|
68
|
-
hsh
|
69
|
-
end
|
70
|
-
opts[:conditions] = cnds
|
71
|
-
end
|
72
|
-
opts
|
73
|
-
end
|
74
20
|
end
|
75
21
|
end
|
76
22
|
end
|
@@ -1,3 +1,3 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'veneer/adapters/mongomapper/class_wrapper'
|
2
|
+
require 'veneer/adapters/mongomapper/instance_wrapper'
|
3
3
|
|