openlogic-couchrest_model 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +11 -0
- data/.rspec +4 -0
- data/Gemfile +4 -0
- data/LICENSE +176 -0
- data/README.md +137 -0
- data/Rakefile +38 -0
- data/THANKS.md +21 -0
- data/VERSION +1 -0
- data/benchmarks/dirty.rb +118 -0
- data/couchrest_model.gemspec +36 -0
- data/history.md +309 -0
- data/init.rb +1 -0
- data/lib/couchrest/model.rb +10 -0
- data/lib/couchrest/model/associations.rb +231 -0
- data/lib/couchrest/model/base.rb +129 -0
- data/lib/couchrest/model/callbacks.rb +28 -0
- data/lib/couchrest/model/casted_array.rb +83 -0
- data/lib/couchrest/model/casted_by.rb +33 -0
- data/lib/couchrest/model/casted_hash.rb +84 -0
- data/lib/couchrest/model/class_proxy.rb +135 -0
- data/lib/couchrest/model/collection.rb +273 -0
- data/lib/couchrest/model/configuration.rb +67 -0
- data/lib/couchrest/model/connection.rb +70 -0
- data/lib/couchrest/model/core_extensions/hash.rb +9 -0
- data/lib/couchrest/model/core_extensions/time_parsing.rb +66 -0
- data/lib/couchrest/model/design_doc.rb +128 -0
- data/lib/couchrest/model/designs.rb +91 -0
- data/lib/couchrest/model/designs/view.rb +513 -0
- data/lib/couchrest/model/dirty.rb +39 -0
- data/lib/couchrest/model/document_queries.rb +99 -0
- data/lib/couchrest/model/embeddable.rb +78 -0
- data/lib/couchrest/model/errors.rb +25 -0
- data/lib/couchrest/model/extended_attachments.rb +83 -0
- data/lib/couchrest/model/persistence.rb +178 -0
- data/lib/couchrest/model/properties.rb +228 -0
- data/lib/couchrest/model/property.rb +114 -0
- data/lib/couchrest/model/property_protection.rb +71 -0
- data/lib/couchrest/model/proxyable.rb +183 -0
- data/lib/couchrest/model/support/couchrest_database.rb +13 -0
- data/lib/couchrest/model/support/couchrest_design.rb +33 -0
- data/lib/couchrest/model/typecast.rb +154 -0
- data/lib/couchrest/model/validations.rb +80 -0
- data/lib/couchrest/model/validations/casted_model.rb +16 -0
- data/lib/couchrest/model/validations/locale/en.yml +5 -0
- data/lib/couchrest/model/validations/uniqueness.rb +69 -0
- data/lib/couchrest/model/views.rb +151 -0
- data/lib/couchrest/railtie.rb +24 -0
- data/lib/couchrest_model.rb +66 -0
- data/lib/rails/generators/couchrest_model.rb +16 -0
- data/lib/rails/generators/couchrest_model/config/config_generator.rb +18 -0
- data/lib/rails/generators/couchrest_model/config/templates/couchdb.yml +21 -0
- data/lib/rails/generators/couchrest_model/model/model_generator.rb +27 -0
- data/lib/rails/generators/couchrest_model/model/templates/model.rb +2 -0
- data/spec/.gitignore +1 -0
- data/spec/fixtures/attachments/README +3 -0
- data/spec/fixtures/attachments/couchdb.png +0 -0
- data/spec/fixtures/attachments/test.html +11 -0
- data/spec/fixtures/config/couchdb.yml +10 -0
- data/spec/fixtures/models/article.rb +36 -0
- data/spec/fixtures/models/base.rb +164 -0
- data/spec/fixtures/models/card.rb +19 -0
- data/spec/fixtures/models/cat.rb +23 -0
- data/spec/fixtures/models/client.rb +6 -0
- data/spec/fixtures/models/course.rb +27 -0
- data/spec/fixtures/models/event.rb +8 -0
- data/spec/fixtures/models/invoice.rb +14 -0
- data/spec/fixtures/models/key_chain.rb +5 -0
- data/spec/fixtures/models/membership.rb +4 -0
- data/spec/fixtures/models/person.rb +11 -0
- data/spec/fixtures/models/project.rb +6 -0
- data/spec/fixtures/models/question.rb +7 -0
- data/spec/fixtures/models/sale_entry.rb +9 -0
- data/spec/fixtures/models/sale_invoice.rb +14 -0
- data/spec/fixtures/models/service.rb +10 -0
- data/spec/fixtures/models/user.rb +22 -0
- data/spec/fixtures/views/lib.js +3 -0
- data/spec/fixtures/views/test_view/lib.js +3 -0
- data/spec/fixtures/views/test_view/only-map.js +4 -0
- data/spec/fixtures/views/test_view/test-map.js +3 -0
- data/spec/fixtures/views/test_view/test-reduce.js +3 -0
- data/spec/functional/validations_spec.rb +8 -0
- data/spec/spec_helper.rb +60 -0
- data/spec/unit/active_model_lint_spec.rb +30 -0
- data/spec/unit/assocations_spec.rb +242 -0
- data/spec/unit/attachment_spec.rb +176 -0
- data/spec/unit/base_spec.rb +537 -0
- data/spec/unit/casted_spec.rb +72 -0
- data/spec/unit/class_proxy_spec.rb +167 -0
- data/spec/unit/collection_spec.rb +86 -0
- data/spec/unit/configuration_spec.rb +77 -0
- data/spec/unit/connection_spec.rb +148 -0
- data/spec/unit/core_extensions/time_parsing.rb +77 -0
- data/spec/unit/design_doc_spec.rb +241 -0
- data/spec/unit/designs/view_spec.rb +831 -0
- data/spec/unit/designs_spec.rb +134 -0
- data/spec/unit/dirty_spec.rb +436 -0
- data/spec/unit/embeddable_spec.rb +498 -0
- data/spec/unit/inherited_spec.rb +33 -0
- data/spec/unit/persistence_spec.rb +481 -0
- data/spec/unit/property_protection_spec.rb +192 -0
- data/spec/unit/property_spec.rb +481 -0
- data/spec/unit/proxyable_spec.rb +376 -0
- data/spec/unit/subclass_spec.rb +85 -0
- data/spec/unit/typecast_spec.rb +521 -0
- data/spec/unit/validations_spec.rb +140 -0
- data/spec/unit/view_spec.rb +367 -0
- metadata +301 -0
@@ -0,0 +1,24 @@
|
|
1
|
+
require "rails"
|
2
|
+
require "active_model/railtie"
|
3
|
+
|
4
|
+
module CouchRest
|
5
|
+
class ModelRailtie < Rails::Railtie
|
6
|
+
def self.generator
|
7
|
+
config.respond_to?(:app_generators) ? :app_generators : :generators
|
8
|
+
end
|
9
|
+
|
10
|
+
config.send(generator).orm :couchrest_model
|
11
|
+
config.send(generator).test_framework :test_unit, :fixture => false
|
12
|
+
|
13
|
+
initializer "couchrest_model.configure_default_connection" do
|
14
|
+
CouchRest::Model::Base.configure do |conf|
|
15
|
+
conf.environment = Rails.env
|
16
|
+
conf.connection_config_file = File.join(Rails.root, 'config', 'couchdb.yml')
|
17
|
+
conf.connection[:prefix] =
|
18
|
+
Rails.application.class.to_s.underscore.gsub(/\/.*/, '')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
require "active_model/callbacks"
|
3
|
+
require "active_model/conversion"
|
4
|
+
require "active_model/errors"
|
5
|
+
require "active_model/naming"
|
6
|
+
require "active_model/serialization"
|
7
|
+
require "active_model/translation"
|
8
|
+
require "active_model/validator"
|
9
|
+
require "active_model/validations"
|
10
|
+
require "active_model/dirty"
|
11
|
+
|
12
|
+
require 'active_support/core_ext'
|
13
|
+
require 'active_support/json'
|
14
|
+
|
15
|
+
require 'mime/types'
|
16
|
+
require "enumerator"
|
17
|
+
require "time"
|
18
|
+
require 'digest/md5'
|
19
|
+
|
20
|
+
require 'bigdecimal' # used in typecast
|
21
|
+
require 'bigdecimal/util' # used in typecast
|
22
|
+
|
23
|
+
require 'couchrest'
|
24
|
+
|
25
|
+
require 'couchrest/model'
|
26
|
+
require 'couchrest/model/errors'
|
27
|
+
require "couchrest/model/persistence"
|
28
|
+
require "couchrest/model/typecast"
|
29
|
+
require "couchrest/model/casted_by"
|
30
|
+
require "couchrest/model/dirty"
|
31
|
+
require "couchrest/model/property"
|
32
|
+
require "couchrest/model/property_protection"
|
33
|
+
require "couchrest/model/properties"
|
34
|
+
require "couchrest/model/casted_array"
|
35
|
+
require "couchrest/model/casted_hash"
|
36
|
+
require "couchrest/model/validations"
|
37
|
+
require "couchrest/model/callbacks"
|
38
|
+
require "couchrest/model/document_queries"
|
39
|
+
require "couchrest/model/views"
|
40
|
+
require "couchrest/model/design_doc"
|
41
|
+
require "couchrest/model/extended_attachments"
|
42
|
+
require "couchrest/model/class_proxy"
|
43
|
+
require "couchrest/model/proxyable"
|
44
|
+
require "couchrest/model/collection"
|
45
|
+
require "couchrest/model/associations"
|
46
|
+
require "couchrest/model/configuration"
|
47
|
+
require "couchrest/model/connection"
|
48
|
+
require "couchrest/model/designs"
|
49
|
+
require "couchrest/model/designs/view"
|
50
|
+
|
51
|
+
# Monkey patches applied to couchrest
|
52
|
+
require "couchrest/model/support/couchrest_design"
|
53
|
+
require "couchrest/model/support/couchrest_database"
|
54
|
+
|
55
|
+
# Core Extensions
|
56
|
+
require "couchrest/model/core_extensions/hash"
|
57
|
+
require "couchrest/model/core_extensions/time_parsing"
|
58
|
+
|
59
|
+
# Base libraries
|
60
|
+
require "couchrest/model/embeddable"
|
61
|
+
require "couchrest/model/base"
|
62
|
+
|
63
|
+
# Add rails support *after* everything has loaded
|
64
|
+
if defined?(Rails)
|
65
|
+
require "couchrest/railtie"
|
66
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rails/generators/named_base'
|
2
|
+
require 'rails/generators/active_model'
|
3
|
+
require 'couchrest_model'
|
4
|
+
|
5
|
+
module CouchrestModel
|
6
|
+
module Generators
|
7
|
+
class Base < Rails::Generators::NamedBase #:nodoc:
|
8
|
+
|
9
|
+
# Set the current directory as base for the inherited generators.
|
10
|
+
def self.base_root
|
11
|
+
File.dirname(__FILE__)
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rails/generators/couchrest_model'
|
2
|
+
|
3
|
+
module CouchrestModel
|
4
|
+
module Generators
|
5
|
+
class ConfigGenerator < Rails::Generators::Base
|
6
|
+
source_root File.expand_path('../templates', __FILE__)
|
7
|
+
|
8
|
+
def app_name
|
9
|
+
Rails::Application.subclasses.first.parent.to_s.underscore
|
10
|
+
end
|
11
|
+
|
12
|
+
def copy_configuration_file
|
13
|
+
template 'couchdb.yml', File.join('config', "couchdb.yml")
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
development: &development
|
2
|
+
protocol: 'http'
|
3
|
+
host: localhost
|
4
|
+
port: 5984
|
5
|
+
prefix: <%= app_name %>
|
6
|
+
suffix: development
|
7
|
+
username:
|
8
|
+
password:
|
9
|
+
|
10
|
+
test:
|
11
|
+
<<: *development
|
12
|
+
suffix: test
|
13
|
+
|
14
|
+
production:
|
15
|
+
protocol: 'https'
|
16
|
+
host: localhost
|
17
|
+
port: 5984
|
18
|
+
prefix: <%= app_name %>
|
19
|
+
suffix: production
|
20
|
+
username: root
|
21
|
+
password: 123
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rails/generators/couchrest_model'
|
2
|
+
|
3
|
+
module CouchrestModel
|
4
|
+
module Generators
|
5
|
+
class ModelGenerator < Base
|
6
|
+
check_class_collision
|
7
|
+
|
8
|
+
def create_model_file
|
9
|
+
template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_module_file
|
13
|
+
return if class_path.empty?
|
14
|
+
template 'module.rb', File.join('app/models', "#{class_path.join('/')}.rb") if behavior == :invoke
|
15
|
+
end
|
16
|
+
|
17
|
+
hook_for :test_framework
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def parent_class_name
|
22
|
+
"CouchRest::Model::Base"
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/spec/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
tmp
|
Binary file
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class Article < CouchRest::Model::Base
|
2
|
+
use_database DB
|
3
|
+
unique_id :slug
|
4
|
+
|
5
|
+
provides_collection :article_details, 'Article', 'by_date', :descending => true, :include_docs => true
|
6
|
+
view_by :date, :descending => true
|
7
|
+
view_by :user_id, :date
|
8
|
+
|
9
|
+
view_by :tags,
|
10
|
+
:map =>
|
11
|
+
"function(doc) {
|
12
|
+
if (doc['#{model_type_key}'] == 'Article' && doc.tags) {
|
13
|
+
doc.tags.forEach(function(tag){
|
14
|
+
emit(tag, 1);
|
15
|
+
});
|
16
|
+
}
|
17
|
+
}",
|
18
|
+
:reduce =>
|
19
|
+
"function(keys, values, rereduce) {
|
20
|
+
return sum(values);
|
21
|
+
}"
|
22
|
+
|
23
|
+
property :date, Date
|
24
|
+
property :slug, :read_only => true
|
25
|
+
property :user_id
|
26
|
+
property :title
|
27
|
+
property :tags, [String]
|
28
|
+
|
29
|
+
timestamps!
|
30
|
+
|
31
|
+
before_save :generate_slug_from_title
|
32
|
+
|
33
|
+
def generate_slug_from_title
|
34
|
+
self['slug'] = title.downcase.gsub(/[^a-z0-9]/,'-').squeeze('-').gsub(/^\-|\-$/,'') if new?
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
class WithDefaultValues < CouchRest::Model::Base
|
2
|
+
use_database TEST_SERVER.default_database
|
3
|
+
property :preset, Object, :default => {:right => 10, :top_align => false}
|
4
|
+
property :set_by_proc, Time, :default => Proc.new{Time.now}
|
5
|
+
property :tags, [String], :default => []
|
6
|
+
property :read_only_with_default, :default => 'generic', :read_only => true
|
7
|
+
property :default_false, TrueClass, :default => false
|
8
|
+
property :name
|
9
|
+
timestamps!
|
10
|
+
end
|
11
|
+
|
12
|
+
class WithSimplePropertyType < CouchRest::Model::Base
|
13
|
+
use_database TEST_SERVER.default_database
|
14
|
+
property :name, String
|
15
|
+
property :preset, String, :default => 'none'
|
16
|
+
property :tags, [String]
|
17
|
+
timestamps!
|
18
|
+
end
|
19
|
+
|
20
|
+
class WithCallBacks < CouchRest::Model::Base
|
21
|
+
use_database TEST_SERVER.default_database
|
22
|
+
property :name
|
23
|
+
property :run_before_validation
|
24
|
+
property :run_after_validation
|
25
|
+
property :run_before_save
|
26
|
+
property :run_after_save
|
27
|
+
property :run_before_create
|
28
|
+
property :run_after_create
|
29
|
+
property :run_before_update
|
30
|
+
property :run_after_update
|
31
|
+
|
32
|
+
validates_presence_of :run_before_validation
|
33
|
+
|
34
|
+
before_validation do |object|
|
35
|
+
object.run_before_validation = true
|
36
|
+
end
|
37
|
+
after_validation do |object|
|
38
|
+
object.run_after_validation = true
|
39
|
+
end
|
40
|
+
before_save do |object|
|
41
|
+
object.run_before_save = true
|
42
|
+
end
|
43
|
+
after_save do |object|
|
44
|
+
object.run_after_save = true
|
45
|
+
end
|
46
|
+
before_create do |object|
|
47
|
+
object.run_before_create = true
|
48
|
+
end
|
49
|
+
after_create do |object|
|
50
|
+
object.run_after_create = true
|
51
|
+
end
|
52
|
+
before_update do |object|
|
53
|
+
object.run_before_update = true
|
54
|
+
end
|
55
|
+
after_update do |object|
|
56
|
+
object.run_after_update = true
|
57
|
+
end
|
58
|
+
|
59
|
+
property :run_one
|
60
|
+
property :run_two
|
61
|
+
property :run_three
|
62
|
+
|
63
|
+
before_save :run_one_method, :run_two_method do |object|
|
64
|
+
object.run_three = true
|
65
|
+
end
|
66
|
+
def run_one_method
|
67
|
+
self.run_one = true
|
68
|
+
end
|
69
|
+
def run_two_method
|
70
|
+
self.run_two = true
|
71
|
+
end
|
72
|
+
|
73
|
+
attr_accessor :run_it
|
74
|
+
property :conditional_one
|
75
|
+
property :conditional_two
|
76
|
+
|
77
|
+
before_save :conditional_one_method, :conditional_two_method, :if => proc { self.run_it }
|
78
|
+
def conditional_one_method
|
79
|
+
self.conditional_one = true
|
80
|
+
end
|
81
|
+
def conditional_two_method
|
82
|
+
self.conditional_two = true
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Following two fixture classes have __intentionally__ diffent syntax for setting the validation context
|
87
|
+
class WithContextualValidationOnCreate < CouchRest::Model::Base
|
88
|
+
use_database TEST_SERVER.default_database
|
89
|
+
property(:name, String)
|
90
|
+
validates(:name, :presence => {:on => :create})
|
91
|
+
end
|
92
|
+
|
93
|
+
class WithContextualValidationOnUpdate < CouchRest::Model::Base
|
94
|
+
use_database TEST_SERVER.default_database
|
95
|
+
property(:name, String)
|
96
|
+
validates(:name, :presence => true, :on => :update)
|
97
|
+
end
|
98
|
+
|
99
|
+
class WithTemplateAndUniqueID < CouchRest::Model::Base
|
100
|
+
use_database TEST_SERVER.default_database
|
101
|
+
unique_id do |model|
|
102
|
+
model.slug
|
103
|
+
end
|
104
|
+
property :slug
|
105
|
+
property :preset, :default => 'value'
|
106
|
+
property :has_no_default
|
107
|
+
end
|
108
|
+
|
109
|
+
class WithGetterAndSetterMethods < CouchRest::Model::Base
|
110
|
+
use_database TEST_SERVER.default_database
|
111
|
+
|
112
|
+
property :other_arg
|
113
|
+
def arg
|
114
|
+
other_arg
|
115
|
+
end
|
116
|
+
|
117
|
+
def arg=(value)
|
118
|
+
self.other_arg = "foo-#{value}"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
class WithAfterInitializeMethod < CouchRest::Model::Base
|
123
|
+
use_database TEST_SERVER.default_database
|
124
|
+
|
125
|
+
property :some_value
|
126
|
+
|
127
|
+
def after_initialize
|
128
|
+
self.some_value ||= "value"
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
|
133
|
+
class WithUniqueValidation < CouchRest::Model::Base
|
134
|
+
use_database DB
|
135
|
+
property :title
|
136
|
+
validates_uniqueness_of :title
|
137
|
+
end
|
138
|
+
class WithUniqueValidationProxy < CouchRest::Model::Base
|
139
|
+
use_database DB
|
140
|
+
property :title
|
141
|
+
validates_uniqueness_of :title, :proxy => 'proxy'
|
142
|
+
end
|
143
|
+
class WithUniqueValidationView < CouchRest::Model::Base
|
144
|
+
use_database DB
|
145
|
+
attr_accessor :code
|
146
|
+
unique_id :code
|
147
|
+
def code
|
148
|
+
@code
|
149
|
+
end
|
150
|
+
property :title
|
151
|
+
|
152
|
+
validates_uniqueness_of :code, :view => 'all'
|
153
|
+
end
|
154
|
+
|
155
|
+
class WithScopedUniqueValidation < CouchRest::Model::Base
|
156
|
+
use_database DB
|
157
|
+
|
158
|
+
property :parent_id
|
159
|
+
property :title
|
160
|
+
|
161
|
+
validates_uniqueness_of :title, :scope => :parent_id
|
162
|
+
end
|
163
|
+
|
164
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'person'
|
2
|
+
|
3
|
+
class Card < CouchRest::Model::Base
|
4
|
+
# Set the default database to use
|
5
|
+
use_database DB
|
6
|
+
|
7
|
+
# Official Schema
|
8
|
+
property :first_name
|
9
|
+
property :last_name, :alias => :family_name
|
10
|
+
property :read_only_value, :read_only => true
|
11
|
+
property :cast_alias, Person, :alias => :calias
|
12
|
+
property :fg_color, :default => '#000'
|
13
|
+
|
14
|
+
timestamps!
|
15
|
+
|
16
|
+
# Validation
|
17
|
+
validates_presence_of :first_name
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
class CatToy
|
3
|
+
include CouchRest::Model::Embeddable
|
4
|
+
|
5
|
+
property :name
|
6
|
+
|
7
|
+
validates_presence_of :name
|
8
|
+
end
|
9
|
+
|
10
|
+
class Cat < CouchRest::Model::Base
|
11
|
+
# Set the default database to use
|
12
|
+
use_database DB
|
13
|
+
|
14
|
+
property :name, :accessible => true
|
15
|
+
property :toys, [CatToy], :default => [], :accessible => true
|
16
|
+
property :favorite_toy, CatToy, :accessible => true
|
17
|
+
property :number
|
18
|
+
end
|
19
|
+
|
20
|
+
class ChildCat < Cat
|
21
|
+
property :mother, Cat
|
22
|
+
property :siblings, [Cat]
|
23
|
+
end
|