bigrecord 0.0.5

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 (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