bigrecord 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +44 -0
  3. data/Rakefile +17 -0
  4. data/VERSION +1 -0
  5. data/doc/bigrecord_specs.rdoc +36 -0
  6. data/doc/getting_started.rdoc +157 -0
  7. data/examples/bigrecord.yml +25 -0
  8. data/generators/bigrecord/bigrecord_generator.rb +17 -0
  9. data/generators/bigrecord/templates/bigrecord.rake +47 -0
  10. data/generators/bigrecord_migration/bigrecord_migration_generator.rb +13 -0
  11. data/generators/bigrecord_migration/templates/migration.rb +9 -0
  12. data/generators/bigrecord_model/bigrecord_model_generator.rb +28 -0
  13. data/generators/bigrecord_model/templates/migration.rb +13 -0
  14. data/generators/bigrecord_model/templates/model.rb +7 -0
  15. data/generators/bigrecord_model/templates/model_spec.rb +12 -0
  16. data/init.rb +9 -0
  17. data/install.rb +22 -0
  18. data/lib/big_record/abstract_base.rb +1088 -0
  19. data/lib/big_record/action_view_extensions.rb +266 -0
  20. data/lib/big_record/ar_associations/association_collection.rb +194 -0
  21. data/lib/big_record/ar_associations/association_proxy.rb +158 -0
  22. data/lib/big_record/ar_associations/belongs_to_association.rb +57 -0
  23. data/lib/big_record/ar_associations/belongs_to_many_association.rb +57 -0
  24. data/lib/big_record/ar_associations/has_and_belongs_to_many_association.rb +164 -0
  25. data/lib/big_record/ar_associations/has_many_association.rb +191 -0
  26. data/lib/big_record/ar_associations/has_one_association.rb +80 -0
  27. data/lib/big_record/ar_associations.rb +1608 -0
  28. data/lib/big_record/ar_reflection.rb +223 -0
  29. data/lib/big_record/attribute_methods.rb +75 -0
  30. data/lib/big_record/base.rb +618 -0
  31. data/lib/big_record/br_associations/association_collection.rb +194 -0
  32. data/lib/big_record/br_associations/association_proxy.rb +153 -0
  33. data/lib/big_record/br_associations/belongs_to_association.rb +52 -0
  34. data/lib/big_record/br_associations/belongs_to_many_association.rb +293 -0
  35. data/lib/big_record/br_associations/cached_item_proxy.rb +194 -0
  36. data/lib/big_record/br_associations/cached_item_proxy_factory.rb +62 -0
  37. data/lib/big_record/br_associations/has_and_belongs_to_many_association.rb +168 -0
  38. data/lib/big_record/br_associations/has_one_association.rb +80 -0
  39. data/lib/big_record/br_associations.rb +978 -0
  40. data/lib/big_record/br_reflection.rb +151 -0
  41. data/lib/big_record/callbacks.rb +367 -0
  42. data/lib/big_record/connection_adapters/abstract/connection_specification.rb +279 -0
  43. data/lib/big_record/connection_adapters/abstract/database_statements.rb +175 -0
  44. data/lib/big_record/connection_adapters/abstract/quoting.rb +58 -0
  45. data/lib/big_record/connection_adapters/abstract_adapter.rb +190 -0
  46. data/lib/big_record/connection_adapters/column.rb +491 -0
  47. data/lib/big_record/connection_adapters/hbase_adapter.rb +432 -0
  48. data/lib/big_record/connection_adapters/view.rb +27 -0
  49. data/lib/big_record/connection_adapters.rb +10 -0
  50. data/lib/big_record/deletion.rb +73 -0
  51. data/lib/big_record/dynamic_schema.rb +92 -0
  52. data/lib/big_record/embedded.rb +71 -0
  53. data/lib/big_record/embedded_associations/association_proxy.rb +148 -0
  54. data/lib/big_record/family_span_columns.rb +89 -0
  55. data/lib/big_record/fixtures.rb +1025 -0
  56. data/lib/big_record/migration.rb +380 -0
  57. data/lib/big_record/routing_ext.rb +65 -0
  58. data/lib/big_record/timestamp.rb +51 -0
  59. data/lib/big_record/validations.rb +830 -0
  60. data/lib/big_record.rb +125 -0
  61. data/lib/bigrecord.rb +1 -0
  62. data/rails/init.rb +9 -0
  63. data/spec/connections/bigrecord.yml +13 -0
  64. data/spec/connections/cassandra/connection.rb +2 -0
  65. data/spec/connections/hbase/connection.rb +2 -0
  66. data/spec/debug.log +281 -0
  67. data/spec/integration/br_associations_spec.rb +80 -0
  68. data/spec/lib/animal.rb +12 -0
  69. data/spec/lib/book.rb +10 -0
  70. data/spec/lib/broken_migrations/duplicate_name/20090706182535_add_animals_table.rb +14 -0
  71. data/spec/lib/broken_migrations/duplicate_name/20090706193019_add_animals_table.rb +9 -0
  72. data/spec/lib/broken_migrations/duplicate_version/20090706190623_add_books_table.rb +9 -0
  73. data/spec/lib/broken_migrations/duplicate_version/20090706190623_add_companies_table.rb +9 -0
  74. data/spec/lib/company.rb +14 -0
  75. data/spec/lib/embedded/web_link.rb +12 -0
  76. data/spec/lib/employee.rb +33 -0
  77. data/spec/lib/migrations/20090706182535_add_animals_table.rb +13 -0
  78. data/spec/lib/migrations/20090706190623_add_books_table.rb +15 -0
  79. data/spec/lib/migrations/20090706193019_add_companies_table.rb +14 -0
  80. data/spec/lib/migrations/20090706194512_add_employees_table.rb +13 -0
  81. data/spec/lib/migrations/20090706195741_add_zoos_table.rb +13 -0
  82. data/spec/lib/novel.rb +5 -0
  83. data/spec/lib/zoo.rb +17 -0
  84. data/spec/spec.opts +4 -0
  85. data/spec/spec_helper.rb +55 -0
  86. data/spec/unit/abstract_base_spec.rb +287 -0
  87. data/spec/unit/adapters/abstract_adapter_spec.rb +56 -0
  88. data/spec/unit/adapters/adapter_shared_spec.rb +51 -0
  89. data/spec/unit/adapters/hbase_adapter_spec.rb +15 -0
  90. data/spec/unit/ar_associations_spec.rb +8 -0
  91. data/spec/unit/base_spec.rb +6 -0
  92. data/spec/unit/br_associations_spec.rb +58 -0
  93. data/spec/unit/embedded_spec.rb +43 -0
  94. data/spec/unit/find_spec.rb +34 -0
  95. data/spec/unit/hash_helper_spec.rb +44 -0
  96. data/spec/unit/migration_spec.rb +144 -0
  97. data/spec/unit/model_spec.rb +315 -0
  98. data/spec/unit/validations_spec.rb +182 -0
  99. data/tasks/bigrecord_tasks.rake +47 -0
  100. data/tasks/data_store.rb +46 -0
  101. data/tasks/gem.rb +22 -0
  102. data/tasks/rdoc.rb +8 -0
  103. data/tasks/spec.rb +34 -0
  104. metadata +189 -0
@@ -0,0 +1,9 @@
1
+ class AddCompaniesTable < BigRecord::Migration
2
+
3
+ def self.up
4
+ end
5
+
6
+ def self.down
7
+ end
8
+
9
+ end
@@ -0,0 +1,14 @@
1
+ class Company < BigRecord::Base
2
+
3
+ column 'attribute:name', 'string'
4
+ column 'attribute:address', 'string'
5
+ column 'attribute:employees', 'integer'
6
+ column 'attribute:readonly', 'string'
7
+
8
+ column 'log:change', 'string', :alias => 'change_log', :collection => true
9
+
10
+ attr_create_accessible :name
11
+ attr_protected :employees
12
+ attr_readonly :readonly
13
+
14
+ end
@@ -0,0 +1,12 @@
1
+ # This doesn't need to be in the Embedded namespace, but it's placed here for organization.
2
+
3
+ module Embedded
4
+
5
+ class WebLink < BigRecord::Embedded
6
+
7
+ column :url, :string
8
+ column :title, :string
9
+
10
+ end
11
+
12
+ end
@@ -0,0 +1,33 @@
1
+ class Employee < BigRecord::Base
2
+
3
+ column 'attribute:first_name', :string
4
+ column 'attribute:middle_name', :string
5
+ column 'attribute:last_name', :string
6
+ column 'attribute:email', :string
7
+ column 'attribute:title', :string
8
+ column 'attribute:company_id', :string
9
+ column 'attribute:password', :string
10
+ column 'attribute:gender', :string # it's not discrimination
11
+ column 'attribute:age', :integer
12
+
13
+ validates_presence_of :first_name, :last_name
14
+ validates_length_of :first_name, :last_name, :within => 2..50
15
+ validates_length_of :middle_name, :within => 1..50, :allow_nil => true
16
+ validates_format_of :first_name, :last_name, :with => /^[\w-]/
17
+ validates_format_of :middle_name, :with => /^[\w-]/, :allow_nil => true
18
+ #validates_uniqueness_of :name
19
+ validates_exclusion_of :first_name, :last_name, :in => %w( admin superuser )
20
+ validates_exclusion_of :middle_name, :in => %w( admin superuser ), :allow_nil => true
21
+
22
+ validates_presence_of :email
23
+
24
+ validates_inclusion_of :gender, :in => %w( m f )
25
+
26
+ validates_confirmation_of :password
27
+
28
+ validates_acceptance_of :contract
29
+
30
+
31
+ belongs_to_big_record :company, :foreign_key => :company_id
32
+
33
+ end
@@ -0,0 +1,13 @@
1
+ class AddAnimalsTable < BigRecord::Migration
2
+
3
+ def self.up
4
+ create_table :animals, :force => true do |t|
5
+ t.family :attribute, :versions => 100
6
+ end
7
+ end
8
+
9
+ def self.down
10
+ drop_table :animals
11
+ end
12
+
13
+ end
@@ -0,0 +1,15 @@
1
+ class AddBooksTable < BigRecord::Migration
2
+
3
+ def self.up
4
+ create_table :books, :force => true do |t|
5
+ t.family :attribute, :versions => 100
6
+ t.family :family2
7
+ t.family :log, :versions => 100
8
+ end
9
+ end
10
+
11
+ def self.down
12
+ drop_table :books
13
+ end
14
+
15
+ end
@@ -0,0 +1,14 @@
1
+ class AddCompaniesTable < BigRecord::Migration
2
+
3
+ def self.up
4
+ create_table :companies, :force => true do |t|
5
+ t.family :attribute, :versions => 100
6
+ t.family :log, :versions => 100
7
+ end
8
+ end
9
+
10
+ def self.down
11
+ drop_table :companies
12
+ end
13
+
14
+ end
@@ -0,0 +1,13 @@
1
+ class AddEmployeesTable < BigRecord::Migration
2
+
3
+ def self.up
4
+ create_table :employees, :force => true do |t|
5
+ t.family :attribute, :versions => 100
6
+ end
7
+ end
8
+
9
+ def self.down
10
+ drop_table :employees
11
+ end
12
+
13
+ end
@@ -0,0 +1,13 @@
1
+ class AddZoosTable < BigRecord::Migration
2
+
3
+ def self.up
4
+ create_table :zoos, :force => true do |t|
5
+ t.family :attr, :versions => 100
6
+ end
7
+ end
8
+
9
+ def self.down
10
+ drop_table :zoos
11
+ end
12
+
13
+ end
data/spec/lib/novel.rb ADDED
@@ -0,0 +1,5 @@
1
+ class Novel < Book
2
+
3
+ column :publisher, :string
4
+
5
+ end
data/spec/lib/zoo.rb ADDED
@@ -0,0 +1,17 @@
1
+ class Zoo < BigRecord::Base
2
+
3
+ set_default_family :attr
4
+
5
+ column 'attr:name', 'string'
6
+ column 'attr:address', 'string'
7
+ column 'attr:employees', 'integer'
8
+ column 'attr:readonly', 'string'
9
+ column :description, :string
10
+ column 'attr:weblink', 'Embedded::WebLink', :alias => "weblink"
11
+ column 'attr:animal_ids', :string, :collection => true
12
+
13
+
14
+ attr_accessible :name, :address, :description
15
+
16
+ belongs_to_many :animals, :foreign_key => 'attr:animal_ids'
17
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --loadby random
3
+ --format progress
4
+ --debugger
@@ -0,0 +1,55 @@
1
+ require 'pathname'
2
+ require 'rubygems'
3
+
4
+ gem 'rspec', '~>1.2'
5
+ require 'spec'
6
+
7
+ SPEC_ROOT = Pathname(__FILE__).dirname.expand_path
8
+ require SPEC_ROOT.parent + 'lib/big_record'
9
+
10
+ BigRecord::Base.configurations = YAML::load(File.open(File.join(File.dirname(__FILE__), "connections", "bigrecord.yml")))
11
+ BigRecord::Base.logger = Logger.new(File.join(File.dirname(__FILE__), "debug.log"))
12
+
13
+ begin
14
+ require 'connection'
15
+ rescue LoadError
16
+ BigRecord::Base.logger.info "No data store defined. Using Hbase..."
17
+ require File.join(File.dirname(__FILE__), 'connections', 'hbase', 'connection')
18
+ end
19
+
20
+ # Load the various helpers for the spec suite
21
+ Dir.glob( File.join(File.dirname(__FILE__), "lib", "**", "*.rb") ).each do |model|
22
+ require model
23
+ end
24
+
25
+
26
+ # Redefine the Hash class to include two helper methods used only in the specs.
27
+ class Hash
28
+ # Helper method to determine if a hash is completely contained within other_hash (order is not important).
29
+ # Matches each key/value pair, and returns false as soon as a mismatch occurs. The other_hash might have
30
+ # more pairs, but those aren't considered.
31
+ #
32
+ # hash1 = { :key1 => "value1", :key2 => "value2", :key3 => "value3" }
33
+ #
34
+ # hash2 = { :key1 => "value1", :key2 => "value2", :key3 => "value3", :key4 => "value4" }
35
+ #
36
+ # hash3 = { :key1 => "value4", :key2 => "value3", :key3 => "value1", :key4 => "value2" }
37
+ #
38
+ # hash1.subset_of?(hash2) # => true
39
+ # hash2.subset_of?(hash1) # => false
40
+ # hash3.subset_of?(hash1) # => false
41
+ # hash3.subset_of?(hash2) # => false
42
+ #
43
+ def subset_of?(other_hash)
44
+ self.each_pair do |key, value|
45
+ return false if !other_hash.has_key?(key) || !(other_hash[key] == value)
46
+ end
47
+
48
+ true
49
+ end
50
+
51
+ def superset_of?(other_hash)
52
+ other_hash.subset_of?(self)
53
+ end
54
+
55
+ end
@@ -0,0 +1,287 @@
1
+ # Defined as a shared spec because embedded_spec uses it as well
2
+ describe "BigRecord::AbstractBase", :shared => true do
3
+
4
+ it "should provide #primary_key" do
5
+ Book.should respond_to(:primary_key)
6
+ end
7
+
8
+ describe '#columns' do
9
+
10
+ before(:all) do
11
+ # Grab the columns from a simple BigRecord model
12
+ @columns = Book.columns
13
+ end
14
+
15
+ it 'should return a hash of Column objects describing the columns in the model' do
16
+ # Verify that each entry is a Column object
17
+ @columns.each do |column|
18
+ column.should be_a_kind_of(BigRecord::ConnectionAdapters::Column)
19
+ end
20
+
21
+ # Map the names of each of the columns
22
+ column_names = @columns.map{ |column| column.name }
23
+
24
+ # Verify that each attribute we defined in the Book model is present
25
+ expected_names = %w( attribute:title attribute:author attribute:description family2: log:change )
26
+ (column_names & expected_names).sort.should == expected_names.sort
27
+ end
28
+
29
+ it 'should save a default alias name for each column (e.g. attribute:name become alias name automatically)' do
30
+ lookup = { 'attribute:id' => 'id',
31
+ 'attribute:title' => 'title',
32
+ 'attribute:author' => 'author',
33
+ 'attribute:description' => 'description'}
34
+
35
+ # Go through each column and if an attribute name is found that matches the lookup table above,
36
+ # verify that the alias name it creates is the one we expect.
37
+ @columns.each do |column|
38
+ if lookup.has_key?(column.name)
39
+ column.alias.should == lookup[column.name]
40
+ end
41
+ end
42
+ end
43
+
44
+ end
45
+
46
+ describe 'column families' do
47
+
48
+ it 'should respond to #default_family with a default value, or with the value defined in the model' do
49
+ Book.should respond_to(:default_family)
50
+ Book.default_family.should == "attribute"
51
+
52
+ Zoo.should respond_to(:default_family)
53
+ Zoo.default_family.should == "attr"
54
+ end
55
+
56
+ it 'should automatically append the #default_family to columns without one defined' do
57
+ Zoo.columns.map{|column| column.name}.should include("attr:description")
58
+ Zoo.new.should respond_to(:description)
59
+ Zoo.new.should respond_to(:description=)
60
+ end
61
+
62
+ end
63
+
64
+ describe '.attributes' do
65
+
66
+ before(:each) do
67
+ @book = Book.new
68
+ end
69
+
70
+ it 'should have getter and setter methods for the attributes from the alias of their names' do
71
+ # Check that the getters are responding
72
+ @book.should respond_to(:title)
73
+ @book.should respond_to(:author)
74
+ @book.should respond_to(:description)
75
+
76
+ # Check that the setters are responding
77
+ @book.should respond_to(:title=)
78
+ @book.should respond_to(:author=)
79
+ @book.should respond_to(:description=)
80
+
81
+ # Now we use the setters
82
+ @book.title = "The Beach"
83
+ @book.author = "Alex Garland"
84
+ @book.description = "A furiously intelligent first novel." # this was written on the cover
85
+
86
+ # And we check that the getters are working
87
+ @book.title.should == "The Beach"
88
+ @book.author.should == "Alex Garland"
89
+ @book.description.should == "A furiously intelligent first novel."
90
+ end
91
+
92
+ it 'should provide a list of modified attributes with #modified_attributes' do
93
+ pending "This was deprecated"
94
+
95
+ book = Book.new( :title => "The Beach",
96
+ :author => "Alex Garland",
97
+ :description => "A furiously intelligent first novel.")
98
+
99
+ book.modified_attributes.each_pair do |key, value|
100
+ %w( title author description ).include?(key.to_s).should be_true
101
+ end
102
+ end
103
+
104
+ it 'should return a hash of attribute-names and values' do
105
+ # Set some attributes, and verify that they get stored in the model
106
+ @book.title = "The Beach"
107
+ @book.author = "Alex Garland"
108
+ @book.description = "A furiously intelligent first novel."
109
+
110
+ expected_hash = {"log:change"=>[], "attribute:description"=>"A furiously intelligent first novel.", "attribute:title"=>"The Beach", "attribute:links"=>[], "attribute:author"=>"Alex Garland"}
111
+
112
+ @book.attributes.superset_of?(expected_hash).should be_true
113
+ end
114
+
115
+ it "should return a hash with all nil or empty list values if the instance is new and has no default values" do
116
+ @book.attributes.superset_of?({"log:change"=>[], "attribute:description"=>nil, "attribute:title"=>nil, "attribute:links"=>[], "attribute:author"=>nil}).should be_true
117
+ end
118
+
119
+ end
120
+
121
+ describe ".attributes=" do
122
+
123
+ it 'should be able to mass assign attributes' do
124
+ # Check that the mass asssignment of attributes works with #new
125
+ @book = Book.new( :title => "The Beach",
126
+ :author => "Alex Garland",
127
+ :description => "A furiously intelligent first novel.")
128
+
129
+ @book.attributes.superset_of?({"log:change"=>[], "attribute:description"=>"A furiously intelligent first novel.", "attribute:title"=>"The Beach", "attribute:links"=>[], "attribute:author"=>"Alex Garland"}).should be_true
130
+
131
+ # Check that it works with the #attributes= method
132
+ @book.attributes = {:title => "28 Days Later"}
133
+
134
+ @book.attributes.superset_of?({"log:change"=>[], "attribute:description"=>"A furiously intelligent first novel.", "attribute:title"=>"28 Days Later", "attribute:links"=>[], "attribute:author"=>"Alex Garland"}).should be_true
135
+ end
136
+
137
+ end
138
+
139
+ describe "protected attributes" do
140
+
141
+ it 'should respond to the method #protected_attributes' do
142
+ Company.should respond_to(:protected_attributes)
143
+ end
144
+
145
+ it 'should list #protected_attributes' do
146
+ Company.protected_attributes.should be_a_kind_of(Set)
147
+ Company.protected_attributes.should include("employees")
148
+ end
149
+
150
+ it 'should be handled properly' do
151
+ # Employees is a protected attribute here, so it shouldn't be saved.
152
+ @company = Company.new(:name => "The Company", :address => "Unknown", :employees => 18000, :readonly => "secret")
153
+
154
+ @company.attributes.superset_of?({"attribute:employees"=>nil, "attribute:address"=>"Unknown", "attribute:readonly"=>"secret", "log:change"=>[], "attribute:name"=>"The Company"}).should be_true
155
+
156
+ # Check it against the attributes= method
157
+ @company.attributes = {:employees => 18000}
158
+
159
+ @company.attributes.superset_of?({"attribute:employees"=>nil, "attribute:address"=>"Unknown", "attribute:readonly"=>"secret", "log:change"=>[], "attribute:name"=>"The Company"}).should be_true
160
+
161
+ # Now check that we can access it with the employees= method
162
+ @company.employees = 18000
163
+
164
+ @company.attributes.superset_of?({"attribute:employees"=>18000, "attribute:address"=>"Unknown", "attribute:readonly"=>"secret", "log:change"=>[], "attribute:name"=>"The Company"}).should be_true
165
+ end
166
+
167
+ end
168
+
169
+ describe "accessible attributes" do
170
+
171
+ it 'should respond to the method #accessible_attributes' do
172
+ Zoo.should respond_to(:accessible_attributes)
173
+ Zoo.accessible_attributes.should_not be_empty
174
+ end
175
+
176
+ it 'should list #accessible_attributes' do
177
+ Zoo.accessible_attributes.should be_a_kind_of(Set)
178
+ Zoo.accessible_attributes.should include("address")
179
+ Zoo.accessible_attributes.should include("description")
180
+ end
181
+
182
+ it 'should be handled properly' do
183
+ # name, address, and description are accessible attributes here
184
+ attributes_hash = { :name => "San Francisco",
185
+ :address => "Some Address",
186
+ :description => "This is a pretty awesome zoo",
187
+ :employees => 10000,
188
+ :readonly => "should not work" }
189
+
190
+ zoo = Zoo.new(attributes_hash)
191
+
192
+ zoo.attributes.superset_of?({"attr:readonly"=>nil, "attr:address"=>"Some Address", "attr:description"=>"This is a pretty awesome zoo", "attr:employees"=>nil, "attr:name"=>"San Francisco"}).should be_true
193
+
194
+ zoo.attributes = {:address => "1 Zoo Rd", :description => "Awesome address", :employees => 1000}
195
+
196
+ zoo.attributes.superset_of?({"attr:readonly"=>nil, "attr:address"=>"1 Zoo Rd", "attr:description"=>"Awesome address", "attr:employees"=>nil, "attr:name"=>"San Francisco"}).should be_true
197
+
198
+ zoo.employees = 1000
199
+
200
+ zoo.attributes.superset_of?({"attr:readonly"=>nil, "attr:address"=>"1 Zoo Rd", "attr:description"=>"Awesome address", "attr:employees"=>1000, "attr:name"=>"San Francisco"})
201
+ end
202
+
203
+ end
204
+
205
+ describe "readonly attributes" do
206
+
207
+ it 'should respond to the method #readonly_attributes' do
208
+ Company.should respond_to(:readonly_attributes)
209
+ end
210
+
211
+ it 'should list #readonly_attributes' do
212
+ Company.readonly_attributes.should be_a_kind_of(Set)
213
+ Company.readonly_attributes.should include("readonly")
214
+ end
215
+
216
+ it 'should be handled properly' do
217
+ pending "this still needs to be implemented in BigRecord::AbstractBase"
218
+
219
+ # readonly is the readonly attribute here
220
+ @company = Company.new(:name => "The Company", :address => "Unknown", :readonly => "secret")
221
+
222
+ # It should've been set successfully since this is a new record
223
+ @company.attributes.superset_of?({"attribute:employees"=>nil, "attribute:address"=>"Unknown", "attribute:readonly"=>"secret", "log:change"=>[], "attribute:name"=>"The Company"}).should be_true
224
+
225
+ # It should still also be accessible with the attributes= method
226
+ @company.attributes = {:readonly => "another secret"}
227
+
228
+ @company.attributes.superset_of?({"attribute:employees"=>nil, "attribute:address"=>"Unknown", "attribute:readonly"=>"another secret", "log:change"=>[], "attribute:name"=>"The Company"}).should be_true
229
+
230
+ # Now when we save it, it should no longer be accessible with mass assignment
231
+
232
+ # Mock new_record? so it's essentially acting like it was saved.
233
+ @company.stub!(:new_record?).and_return(false)
234
+
235
+ @company.attributes = {:readonly => "compromised secret"}
236
+
237
+ @company.attributes.superset_of?({"attribute:employees"=>nil, "attribute:address"=>"Unknown", "attribute:readonly"=>"another secret", "log:change"=>[], "attribute:name"=>"The Company"}).should be_true
238
+
239
+ # And it should still not be accessible with the explicit setter
240
+ @company.readonly = "compromised secret"
241
+
242
+ @company.attributes.superset_of?({"attribute:employees"=>nil, "attribute:address"=>"Unknown", "attribute:readonly"=>"another secret", "log:change"=>[], "attribute:name"=>"Another Company"}).should be_true
243
+ end
244
+
245
+ end
246
+
247
+ describe "create_accessible attributes" do
248
+
249
+ it 'should respond to the method #create_accessible_attributes' do
250
+ Company.should respond_to(:create_accessible_attributes)
251
+ end
252
+
253
+ it 'should list #create_accessible_attributes' do
254
+ Company.create_accessible_attributes.should be_a_kind_of(Set)
255
+ Company.create_accessible_attributes.should include("name")
256
+ end
257
+
258
+ it 'should be handled properly' do
259
+ # Name is the create_accessible attribute here
260
+ @company = Company.new(:name => "Another Company", :address => "Unknown")
261
+
262
+ # It should've been set successfully since this is a new record
263
+ @company.attributes.superset_of?({"attribute:employees"=>nil, "attribute:address"=>"Unknown", "attribute:readonly"=>nil, "log:change"=>[], "attribute:name"=>"Another Company"}).should be_true
264
+
265
+ # It should still also be accessible with the attributes= method
266
+ @company.attributes = {:name => "The Company"}
267
+
268
+ @company.attributes.superset_of?({"attribute:employees"=>nil, "attribute:address"=>"Unknown", "attribute:readonly"=>nil, "log:change"=>[], "attribute:name"=>"The Company"}).should be_true
269
+
270
+ # Now when we save it, it should no longer be accessible with mass assignment
271
+
272
+ # Mock new_record? so it's essentially acting like it was saved.
273
+ @company.stub!(:new_record?).and_return(false)
274
+
275
+ @company.attributes = {:name => "Another Company"}
276
+
277
+ @company.attributes.superset_of?({"attribute:employees"=>nil, "attribute:address"=>"Unknown", "attribute:readonly"=>nil, "log:change"=>[], "attribute:name"=>"The Company"}).should be_true
278
+
279
+ # But it should still be accessible with the explicit setter
280
+ @company.name = "Another Company"
281
+
282
+ @company.attributes.superset_of?({"attribute:employees"=>nil, "attribute:address"=>"Unknown", "attribute:readonly"=>nil, "log:change"=>[], "attribute:name"=>"Another Company"}).should be_true
283
+ end
284
+
285
+ end
286
+
287
+ end
@@ -0,0 +1,56 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+ require File.expand_path(File.join(File.dirname(__FILE__), 'adapter_shared_spec'))
3
+
4
+ describe BigRecord::ConnectionAdapters::AbstractAdapter do
5
+
6
+ before do
7
+ @adapter = BigRecord::ConnectionAdapters::AbstractAdapter.new("")
8
+ end
9
+
10
+ it_should_behave_like 'a BigRecord Adapter'
11
+
12
+ it "should raise NotImplementedError when #update_raw is called" do
13
+ lambda{ @adapter.update_raw(:table_name, :row, :values, :timestamp) }.should raise_error(NotImplementedError)
14
+ end
15
+
16
+ it "should raise NotImplementedError when #update is called" do
17
+ lambda{ @adapter.update(:table_name, :row, :values, :timestamp) }.should raise_error(NotImplementedError)
18
+ end
19
+
20
+ it "should raise NotImplementedError when #get_raw is called" do
21
+ lambda{ @adapter.get_raw(:table_name, :row, :column, :options) }.should raise_error(NotImplementedError)
22
+ end
23
+
24
+ it "should raise NotImplementedError when #get is called" do
25
+ lambda{ @adapter.get(:table_name, :row, :column, :options) }.should raise_error(NotImplementedError)
26
+ end
27
+
28
+ it "should raise NotImplementedError when #get_columns_raw is called" do
29
+ lambda{ @adapter.get_columns_raw(:table_name, :row, :columns, :options) }.should raise_error(NotImplementedError)
30
+ end
31
+
32
+ it "should raise NotImplementedError when #get_columns is called" do
33
+ lambda{ @adapter.get_columns(:table_name, :row, :columns, :options) }.should raise_error(NotImplementedError)
34
+ end
35
+
36
+ it "should raise NotImplementedError when #delete is called" do
37
+ lambda{ @adapter.delete(:table_name, :row) }.should raise_error(NotImplementedError)
38
+ end
39
+
40
+ it "should raise NotImplementedError when #delete_all is called" do
41
+ lambda{ @adapter.delete_all(:table_name) }.should raise_error(NotImplementedError)
42
+ end
43
+
44
+ it "should raise NotImplementedError when #table_exists? is called" do
45
+ lambda{ @adapter.table_exists?(:table_name) }.should raise_error(NotImplementedError)
46
+ end
47
+
48
+ it "should raise NotImplementedError when #create_table is called" do
49
+ lambda{ @adapter.create_table(:table_name, :column_families) }.should raise_error(NotImplementedError)
50
+ end
51
+
52
+ it "should raise NotImplementedError when #drop_table is called" do
53
+ lambda{ @adapter.drop_table(:table_name) }.should raise_error(NotImplementedError)
54
+ end
55
+
56
+ end
@@ -0,0 +1,51 @@
1
+ describe "a BigRecord Adapter", :shared => true do
2
+
3
+ %w{adapter_name supports_migrations?}.each do |meth|
4
+ it "should have a ##{meth} method" do
5
+ @adapter.should respond_to(meth.intern)
6
+ end
7
+ end
8
+
9
+ describe "with connection management" do
10
+ %w{active? reconnect! disconnect!}.each do |meth|
11
+ it "should have a ##{meth} method" do
12
+ @adapter.should respond_to(meth.intern)
13
+ end
14
+ end
15
+ end
16
+
17
+ describe "with data store statements" do
18
+ %w{update_raw update get_raw get get_columns_raw get_columns get_consecutive_rows_raw get_consecutive_rows delete delete_all}.each do |meth|
19
+ it "should have a ##{meth} method" do
20
+ @adapter.should respond_to(meth.intern)
21
+ end
22
+ end
23
+ end
24
+
25
+ describe "with schema statements" do
26
+ %w{table_exists? create_table drop_table}.each do |meth|
27
+ it "should have a ##{meth} method" do
28
+ @adapter.should respond_to(meth.intern)
29
+ end
30
+ end
31
+
32
+ it "should have the methods needed for migrations if supports_migrations? is true" do
33
+ if @adapter.supports_migrations?
34
+ %w{initialize_schema_migrations_table get_all_schema_versions add_column_family remove_column_family modify_column_family}.each do |meth|
35
+ @adapter.should respond_to(meth.intern)
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ describe "timestamp functionality" do
42
+ it "should use the default Time.to_bigrecord_timestamp or implement it's own method" do
43
+ Time.now.should respond_to(:to_bigrecord_timestamp)
44
+ Time.should respond_to(:from_bigrecord_timestamp)
45
+
46
+ Time.now.to_bigrecord_timestamp.should_not be_nil
47
+ Time.from_bigrecord_timestamp(Time.now.to_bigrecord_timestamp).should_not be_nil
48
+ end
49
+ end
50
+
51
+ end
@@ -0,0 +1,15 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+ require File.expand_path(File.join(File.dirname(__FILE__), 'adapter_shared_spec'))
3
+
4
+ describe BigRecord::ConnectionAdapters::HbaseAdapter do
5
+
6
+ before do
7
+ # Make sure the connection is defined in spec/connections/bigrecord.yml
8
+ BigRecord::Base.establish_connection 'hbase'
9
+
10
+ @adapter = BigRecord::Base.connection
11
+ end
12
+
13
+ it_should_behave_like 'a BigRecord Adapter'
14
+
15
+ end
@@ -0,0 +1,8 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ describe BigRecord::ArAssociations do
4
+
5
+ describe '' do
6
+ end
7
+
8
+ end
@@ -0,0 +1,6 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+ require File.expand_path(File.join(File.dirname(__FILE__), 'abstract_base_spec'))
3
+
4
+ describe BigRecord::Base do
5
+ it_should_behave_like "BigRecord::AbstractBase"
6
+ end