couchrest_model 1.0.0.beta7

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 (69) hide show
  1. data/LICENSE +176 -0
  2. data/README.md +320 -0
  3. data/Rakefile +71 -0
  4. data/THANKS.md +19 -0
  5. data/examples/model/example.rb +144 -0
  6. data/history.txt +180 -0
  7. data/lib/couchrest/model.rb +10 -0
  8. data/lib/couchrest/model/associations.rb +207 -0
  9. data/lib/couchrest/model/attribute_protection.rb +74 -0
  10. data/lib/couchrest/model/attributes.rb +75 -0
  11. data/lib/couchrest/model/base.rb +111 -0
  12. data/lib/couchrest/model/callbacks.rb +27 -0
  13. data/lib/couchrest/model/casted_array.rb +39 -0
  14. data/lib/couchrest/model/casted_model.rb +68 -0
  15. data/lib/couchrest/model/class_proxy.rb +122 -0
  16. data/lib/couchrest/model/collection.rb +260 -0
  17. data/lib/couchrest/model/design_doc.rb +126 -0
  18. data/lib/couchrest/model/document_queries.rb +82 -0
  19. data/lib/couchrest/model/errors.rb +23 -0
  20. data/lib/couchrest/model/extended_attachments.rb +73 -0
  21. data/lib/couchrest/model/persistence.rb +141 -0
  22. data/lib/couchrest/model/properties.rb +144 -0
  23. data/lib/couchrest/model/property.rb +96 -0
  24. data/lib/couchrest/model/support/couchrest.rb +19 -0
  25. data/lib/couchrest/model/support/hash.rb +9 -0
  26. data/lib/couchrest/model/typecast.rb +170 -0
  27. data/lib/couchrest/model/validations.rb +68 -0
  28. data/lib/couchrest/model/validations/casted_model.rb +14 -0
  29. data/lib/couchrest/model/validations/locale/en.yml +5 -0
  30. data/lib/couchrest/model/validations/uniqueness.rb +45 -0
  31. data/lib/couchrest/model/views.rb +167 -0
  32. data/lib/couchrest_model.rb +56 -0
  33. data/spec/couchrest/assocations_spec.rb +213 -0
  34. data/spec/couchrest/attachment_spec.rb +148 -0
  35. data/spec/couchrest/attribute_protection_spec.rb +153 -0
  36. data/spec/couchrest/base_spec.rb +463 -0
  37. data/spec/couchrest/casted_model_spec.rb +424 -0
  38. data/spec/couchrest/casted_spec.rb +75 -0
  39. data/spec/couchrest/class_proxy_spec.rb +132 -0
  40. data/spec/couchrest/inherited_spec.rb +40 -0
  41. data/spec/couchrest/persistence_spec.rb +409 -0
  42. data/spec/couchrest/property_spec.rb +804 -0
  43. data/spec/couchrest/subclass_spec.rb +99 -0
  44. data/spec/couchrest/validations.rb +73 -0
  45. data/spec/couchrest/view_spec.rb +463 -0
  46. data/spec/fixtures/attachments/README +3 -0
  47. data/spec/fixtures/attachments/couchdb.png +0 -0
  48. data/spec/fixtures/attachments/test.html +11 -0
  49. data/spec/fixtures/base.rb +139 -0
  50. data/spec/fixtures/more/article.rb +35 -0
  51. data/spec/fixtures/more/card.rb +17 -0
  52. data/spec/fixtures/more/cat.rb +19 -0
  53. data/spec/fixtures/more/course.rb +25 -0
  54. data/spec/fixtures/more/event.rb +8 -0
  55. data/spec/fixtures/more/invoice.rb +14 -0
  56. data/spec/fixtures/more/person.rb +9 -0
  57. data/spec/fixtures/more/question.rb +7 -0
  58. data/spec/fixtures/more/service.rb +10 -0
  59. data/spec/fixtures/more/user.rb +22 -0
  60. data/spec/fixtures/views/lib.js +3 -0
  61. data/spec/fixtures/views/test_view/lib.js +3 -0
  62. data/spec/fixtures/views/test_view/only-map.js +4 -0
  63. data/spec/fixtures/views/test_view/test-map.js +3 -0
  64. data/spec/fixtures/views/test_view/test-reduce.js +3 -0
  65. data/spec/spec.opts +5 -0
  66. data/spec/spec_helper.rb +48 -0
  67. data/utils/remap.rb +27 -0
  68. data/utils/subset.rb +30 -0
  69. metadata +232 -0
@@ -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,139 @@
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_validate
24
+ property :run_after_validate
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
+ before_validate do |object|
33
+ object.run_before_validate = true
34
+ end
35
+ after_validate do |object|
36
+ object.run_after_validate = true
37
+ end
38
+ before_save do |object|
39
+ object.run_before_save = true
40
+ end
41
+ after_save do |object|
42
+ object.run_after_save = true
43
+ end
44
+ before_create do |object|
45
+ object.run_before_create = true
46
+ end
47
+ after_create do |object|
48
+ object.run_after_create = true
49
+ end
50
+ before_update do |object|
51
+ object.run_before_update = true
52
+ end
53
+ after_update do |object|
54
+ object.run_after_update = true
55
+ end
56
+
57
+ property :run_one
58
+ property :run_two
59
+ property :run_three
60
+
61
+ before_save :run_one_method, :run_two_method do |object|
62
+ object.run_three = true
63
+ end
64
+ def run_one_method
65
+ self.run_one = true
66
+ end
67
+ def run_two_method
68
+ self.run_two = true
69
+ end
70
+
71
+ attr_accessor :run_it
72
+ property :conditional_one
73
+ property :conditional_two
74
+
75
+ before_save :conditional_one_method, :conditional_two_method, :if => proc { self.run_it }
76
+ def conditional_one_method
77
+ self.conditional_one = true
78
+ end
79
+ def conditional_two_method
80
+ self.conditional_two = true
81
+ end
82
+ end
83
+
84
+ class WithTemplateAndUniqueID < CouchRest::Model::Base
85
+ use_database TEST_SERVER.default_database
86
+ unique_id do |model|
87
+ model['important-field']
88
+ end
89
+ property :preset, :default => 'value'
90
+ property :has_no_default
91
+ end
92
+
93
+ class WithGetterAndSetterMethods < CouchRest::Model::Base
94
+ use_database TEST_SERVER.default_database
95
+
96
+ property :other_arg
97
+ def arg
98
+ other_arg
99
+ end
100
+
101
+ def arg=(value)
102
+ self.other_arg = "foo-#{value}"
103
+ end
104
+ end
105
+
106
+ class WithAfterInitializeMethod < CouchRest::Model::Base
107
+ use_database TEST_SERVER.default_database
108
+
109
+ property :some_value
110
+
111
+ def after_initialize
112
+ self.some_value ||= "value"
113
+ end
114
+
115
+ end
116
+
117
+ class WithUniqueValidation < CouchRest::Model::Base
118
+ use_database DB
119
+ property :title
120
+ validates_uniqueness_of :title
121
+ end
122
+ class WithUniqueValidationProxy < CouchRest::Model::Base
123
+ use_database DB
124
+ property :title
125
+ validates_uniqueness_of :title, :proxy => 'proxy'
126
+ end
127
+ class WithUniqueValidationView < CouchRest::Model::Base
128
+ use_database DB
129
+ attr_accessor :code
130
+ unique_id :code
131
+ def code
132
+ self["_id"] ||= @code
133
+ end
134
+ property :title
135
+
136
+ validates_uniqueness_of :code, :view => 'all'
137
+ end
138
+
139
+
@@ -0,0 +1,35 @@
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['couchrest-type'] == '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 :title
26
+ property :tags, [String]
27
+
28
+ timestamps!
29
+
30
+ before_save :generate_slug_from_title
31
+
32
+ def generate_slug_from_title
33
+ self['slug'] = title.downcase.gsub(/[^a-z0-9]/,'-').squeeze('-').gsub(/^\-|\-$/,'') if new?
34
+ end
35
+ end
@@ -0,0 +1,17 @@
1
+ class Card < CouchRest::Model::Base
2
+ # Set the default database to use
3
+ use_database DB
4
+
5
+ # Official Schema
6
+ property :first_name
7
+ property :last_name, :alias => :family_name
8
+ property :read_only_value, :read_only => true
9
+ property :cast_alias, Person, :alias => :calias
10
+
11
+
12
+ timestamps!
13
+
14
+ # Validation
15
+ validates_presence_of :first_name
16
+
17
+ end
@@ -0,0 +1,19 @@
1
+
2
+ class CatToy < Hash
3
+ include ::CouchRest::Model::CastedModel
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
+
@@ -0,0 +1,25 @@
1
+ require File.join(FIXTURE_PATH, 'more', 'question')
2
+ require File.join(FIXTURE_PATH, 'more', 'person')
3
+
4
+ class Course < CouchRest::Model::Base
5
+ use_database TEST_SERVER.default_database
6
+
7
+ property :title, String
8
+ property :questions, [Question]
9
+ property :professor, Person
10
+ property :participants, [Object]
11
+ property :ends_at, Time
12
+ property :estimate, Float
13
+ property :hours, Integer
14
+ property :profit, BigDecimal
15
+ property :started_on, :type => Date
16
+ property :updated_at, :type => DateTime
17
+ property :active, :type => TrueClass
18
+ property :very_active, :type => TrueClass
19
+ property :klass, :type => Class
20
+
21
+ view_by :title
22
+ view_by :title, :active
23
+ view_by :dept, :ducktype => true
24
+
25
+ end
@@ -0,0 +1,8 @@
1
+ class Event < CouchRest::Model::Base
2
+ use_database DB
3
+
4
+ property :subject
5
+ property :occurs_at, Time, :init_method => 'parse'
6
+ property :end_date, Date, :init_method => 'parse'
7
+
8
+ end
@@ -0,0 +1,14 @@
1
+ class Invoice < CouchRest::Model::Base
2
+ # Set the default database to use
3
+ use_database DB
4
+
5
+ # Official Schema
6
+ property :client_name
7
+ property :employee_name
8
+ property :location
9
+
10
+ # Validation
11
+ validates_presence_of :client_name, :employee_name
12
+ validates_presence_of :location, :message => "Hey stupid!, you forgot the location"
13
+
14
+ end
@@ -0,0 +1,9 @@
1
+ class Person < Hash
2
+ include ::CouchRest::Model::CastedModel
3
+ property :pet, Cat
4
+ property :name, [String]
5
+
6
+ def last_name
7
+ name.last
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ class Question < Hash
2
+ include ::CouchRest::Model::CastedModel
3
+
4
+ property :q
5
+ property :a
6
+
7
+ end
@@ -0,0 +1,10 @@
1
+ class Service < CouchRest::Model::Base
2
+ # Set the default database to use
3
+ use_database DB
4
+
5
+ # Official Schema
6
+ property :name
7
+ property :price, Integer
8
+
9
+ validates_length_of :name, :minimum => 4, :maximum => 20
10
+ end
@@ -0,0 +1,22 @@
1
+ class User < CouchRest::Model::Base
2
+ # Set the default database to use
3
+ use_database DB
4
+ property :name, :accessible => true
5
+ property :admin # this will be automatically protected
6
+ end
7
+
8
+ class SpecialUser < CouchRest::Model::Base
9
+ # Set the default database to use
10
+ use_database DB
11
+ property :name # this will not be protected
12
+ property :admin, :protected => true
13
+ end
14
+
15
+ # There are two modes of protection
16
+ # 1) Declare accessible poperties, assume all the rest are protected
17
+ # property :name, :accessible => true
18
+ # property :admin # this will be automatically protected
19
+ #
20
+ # 2) Declare protected properties, assume all the rest are accessible
21
+ # property :name # this will not be protected
22
+ # property :admin, :protected => true
@@ -0,0 +1,3 @@
1
+ function globalLib() {
2
+ return "fixture";
3
+ };
@@ -0,0 +1,3 @@
1
+ function justThisView() {
2
+ return "fixture";
3
+ };
@@ -0,0 +1,4 @@
1
+ function(doc) {
2
+ //include-lib
3
+ emit(null, null);
4
+ };
@@ -0,0 +1,3 @@
1
+ function(doc) {
2
+ emit(null, null);
3
+ };
@@ -0,0 +1,3 @@
1
+ function(ks,vs,co) {
2
+ return vs.length;
3
+ };
data/spec/spec.opts ADDED
@@ -0,0 +1,5 @@
1
+ --colour
2
+ --format
3
+ progress
4
+ --loadby
5
+ mtime
@@ -0,0 +1,48 @@
1
+ require "rubygems"
2
+ require "spec" # Satisfies Autotest and anyone else not using the Rake tasks
3
+
4
+ require File.join(File.dirname(__FILE__), '..','lib','couchrest_model')
5
+ # check the following file to see how to use the spec'd features.
6
+
7
+ unless defined?(FIXTURE_PATH)
8
+ FIXTURE_PATH = File.join(File.dirname(__FILE__), '/fixtures')
9
+ SCRATCH_PATH = File.join(File.dirname(__FILE__), '/tmp')
10
+
11
+ COUCHHOST = "http://127.0.0.1:5984"
12
+ TESTDB = 'couchrest-model-test'
13
+ TEST_SERVER = CouchRest.new
14
+ TEST_SERVER.default_database = TESTDB
15
+ DB = TEST_SERVER.database(TESTDB)
16
+ end
17
+
18
+ class Basic < CouchRest::Model::Base
19
+ use_database TEST_SERVER.default_database
20
+ end
21
+
22
+ def reset_test_db!
23
+ DB.recreate! rescue nil
24
+ DB
25
+ end
26
+
27
+ Spec::Runner.configure do |config|
28
+ config.before(:all) { reset_test_db! }
29
+
30
+ config.after(:all) do
31
+ cr = TEST_SERVER
32
+ test_dbs = cr.databases.select { |db| db =~ /^#{TESTDB}/ }
33
+ test_dbs.each do |db|
34
+ cr.database(db).delete! rescue nil
35
+ end
36
+ end
37
+ end
38
+
39
+ def couchdb_lucene_available?
40
+ lucene_path = "http://localhost:5985/"
41
+ url = URI.parse(lucene_path)
42
+ req = Net::HTTP::Get.new(url.path)
43
+ res = Net::HTTP.new(url.host, url.port).start { |http| http.request(req) }
44
+ true
45
+ rescue Exception => e
46
+ false
47
+ end
48
+
data/utils/remap.rb ADDED
@@ -0,0 +1,27 @@
1
+ require 'rubygems'
2
+ require 'couchrest'
3
+
4
+ # set the source db and map view
5
+ source = CouchRest.new("http://127.0.0.1:5984").database('source-db')
6
+ source_view = 'mydesign/view-map'
7
+
8
+ # set the target db
9
+ target = CouchRest.new("http://127.0.0.1:5984").database('target-db')
10
+
11
+
12
+ pager = CouchRest::Pager.new(source)
13
+
14
+ # pager will yield once per uniq key in the source view
15
+
16
+ pager.key_reduce(source_view, 10000) do |key, values|
17
+ # create a doc from the key and the values
18
+ example_doc = {
19
+ :key => key,
20
+ :values => values.uniq
21
+ }
22
+
23
+ target.save(example_doc)
24
+
25
+ # keep us up to date with progress
26
+ puts k if (rand > 0.9)
27
+ end