openlogic-couchrest_model 1.0.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.
Files changed (107) hide show
  1. data/.gitignore +11 -0
  2. data/.rspec +4 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +176 -0
  5. data/README.md +137 -0
  6. data/Rakefile +38 -0
  7. data/THANKS.md +21 -0
  8. data/VERSION +1 -0
  9. data/benchmarks/dirty.rb +118 -0
  10. data/couchrest_model.gemspec +36 -0
  11. data/history.md +309 -0
  12. data/init.rb +1 -0
  13. data/lib/couchrest/model.rb +10 -0
  14. data/lib/couchrest/model/associations.rb +231 -0
  15. data/lib/couchrest/model/base.rb +129 -0
  16. data/lib/couchrest/model/callbacks.rb +28 -0
  17. data/lib/couchrest/model/casted_array.rb +83 -0
  18. data/lib/couchrest/model/casted_by.rb +33 -0
  19. data/lib/couchrest/model/casted_hash.rb +84 -0
  20. data/lib/couchrest/model/class_proxy.rb +135 -0
  21. data/lib/couchrest/model/collection.rb +273 -0
  22. data/lib/couchrest/model/configuration.rb +67 -0
  23. data/lib/couchrest/model/connection.rb +70 -0
  24. data/lib/couchrest/model/core_extensions/hash.rb +9 -0
  25. data/lib/couchrest/model/core_extensions/time_parsing.rb +66 -0
  26. data/lib/couchrest/model/design_doc.rb +128 -0
  27. data/lib/couchrest/model/designs.rb +91 -0
  28. data/lib/couchrest/model/designs/view.rb +513 -0
  29. data/lib/couchrest/model/dirty.rb +39 -0
  30. data/lib/couchrest/model/document_queries.rb +99 -0
  31. data/lib/couchrest/model/embeddable.rb +78 -0
  32. data/lib/couchrest/model/errors.rb +25 -0
  33. data/lib/couchrest/model/extended_attachments.rb +83 -0
  34. data/lib/couchrest/model/persistence.rb +178 -0
  35. data/lib/couchrest/model/properties.rb +228 -0
  36. data/lib/couchrest/model/property.rb +114 -0
  37. data/lib/couchrest/model/property_protection.rb +71 -0
  38. data/lib/couchrest/model/proxyable.rb +183 -0
  39. data/lib/couchrest/model/support/couchrest_database.rb +13 -0
  40. data/lib/couchrest/model/support/couchrest_design.rb +33 -0
  41. data/lib/couchrest/model/typecast.rb +154 -0
  42. data/lib/couchrest/model/validations.rb +80 -0
  43. data/lib/couchrest/model/validations/casted_model.rb +16 -0
  44. data/lib/couchrest/model/validations/locale/en.yml +5 -0
  45. data/lib/couchrest/model/validations/uniqueness.rb +69 -0
  46. data/lib/couchrest/model/views.rb +151 -0
  47. data/lib/couchrest/railtie.rb +24 -0
  48. data/lib/couchrest_model.rb +66 -0
  49. data/lib/rails/generators/couchrest_model.rb +16 -0
  50. data/lib/rails/generators/couchrest_model/config/config_generator.rb +18 -0
  51. data/lib/rails/generators/couchrest_model/config/templates/couchdb.yml +21 -0
  52. data/lib/rails/generators/couchrest_model/model/model_generator.rb +27 -0
  53. data/lib/rails/generators/couchrest_model/model/templates/model.rb +2 -0
  54. data/spec/.gitignore +1 -0
  55. data/spec/fixtures/attachments/README +3 -0
  56. data/spec/fixtures/attachments/couchdb.png +0 -0
  57. data/spec/fixtures/attachments/test.html +11 -0
  58. data/spec/fixtures/config/couchdb.yml +10 -0
  59. data/spec/fixtures/models/article.rb +36 -0
  60. data/spec/fixtures/models/base.rb +164 -0
  61. data/spec/fixtures/models/card.rb +19 -0
  62. data/spec/fixtures/models/cat.rb +23 -0
  63. data/spec/fixtures/models/client.rb +6 -0
  64. data/spec/fixtures/models/course.rb +27 -0
  65. data/spec/fixtures/models/event.rb +8 -0
  66. data/spec/fixtures/models/invoice.rb +14 -0
  67. data/spec/fixtures/models/key_chain.rb +5 -0
  68. data/spec/fixtures/models/membership.rb +4 -0
  69. data/spec/fixtures/models/person.rb +11 -0
  70. data/spec/fixtures/models/project.rb +6 -0
  71. data/spec/fixtures/models/question.rb +7 -0
  72. data/spec/fixtures/models/sale_entry.rb +9 -0
  73. data/spec/fixtures/models/sale_invoice.rb +14 -0
  74. data/spec/fixtures/models/service.rb +10 -0
  75. data/spec/fixtures/models/user.rb +22 -0
  76. data/spec/fixtures/views/lib.js +3 -0
  77. data/spec/fixtures/views/test_view/lib.js +3 -0
  78. data/spec/fixtures/views/test_view/only-map.js +4 -0
  79. data/spec/fixtures/views/test_view/test-map.js +3 -0
  80. data/spec/fixtures/views/test_view/test-reduce.js +3 -0
  81. data/spec/functional/validations_spec.rb +8 -0
  82. data/spec/spec_helper.rb +60 -0
  83. data/spec/unit/active_model_lint_spec.rb +30 -0
  84. data/spec/unit/assocations_spec.rb +242 -0
  85. data/spec/unit/attachment_spec.rb +176 -0
  86. data/spec/unit/base_spec.rb +537 -0
  87. data/spec/unit/casted_spec.rb +72 -0
  88. data/spec/unit/class_proxy_spec.rb +167 -0
  89. data/spec/unit/collection_spec.rb +86 -0
  90. data/spec/unit/configuration_spec.rb +77 -0
  91. data/spec/unit/connection_spec.rb +148 -0
  92. data/spec/unit/core_extensions/time_parsing.rb +77 -0
  93. data/spec/unit/design_doc_spec.rb +241 -0
  94. data/spec/unit/designs/view_spec.rb +831 -0
  95. data/spec/unit/designs_spec.rb +134 -0
  96. data/spec/unit/dirty_spec.rb +436 -0
  97. data/spec/unit/embeddable_spec.rb +498 -0
  98. data/spec/unit/inherited_spec.rb +33 -0
  99. data/spec/unit/persistence_spec.rb +481 -0
  100. data/spec/unit/property_protection_spec.rb +192 -0
  101. data/spec/unit/property_spec.rb +481 -0
  102. data/spec/unit/proxyable_spec.rb +376 -0
  103. data/spec/unit/subclass_spec.rb +85 -0
  104. data/spec/unit/typecast_spec.rb +521 -0
  105. data/spec/unit/validations_spec.rb +140 -0
  106. data/spec/unit/view_spec.rb +367 -0
  107. 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
@@ -0,0 +1,2 @@
1
+ class <%= class_name %> < <%= parent_class_name.classify %>
2
+ end
@@ -0,0 +1 @@
1
+ tmp
@@ -0,0 +1,3 @@
1
+ This is an example README file.
2
+
3
+ More of the README, whee.
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Test</title>
5
+ </head>
6
+ <body>
7
+ <p>
8
+ Test
9
+ </p>
10
+ </body>
11
+ </html>
@@ -0,0 +1,10 @@
1
+
2
+ development:
3
+ protocol: 'https'
4
+ host: sample.cloudant.com
5
+ port: 443
6
+ prefix: project
7
+ suffix: text
8
+ username: test
9
+ password: user
10
+
@@ -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