bigrecord 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +0 -0
- data/README.rdoc +9 -1
- data/Rakefile +0 -0
- data/VERSION +1 -1
- data/examples/bigrecord.yml +2 -5
- data/generators/bigrecord/bigrecord_generator.rb +0 -0
- data/generators/bigrecord/templates/bigrecord.rake +0 -0
- data/generators/bigrecord_migration/bigrecord_migration_generator.rb +0 -0
- data/generators/bigrecord_migration/templates/migration.rb +0 -0
- data/generators/bigrecord_model/bigrecord_model_generator.rb +0 -0
- data/generators/bigrecord_model/templates/migration.rb +0 -0
- data/generators/bigrecord_model/templates/model.rb +0 -0
- data/generators/bigrecord_model/templates/model_spec.rb +0 -0
- data/{doc → guides}/bigrecord_specs.rdoc +0 -0
- data/guides/deployment.rdoc +21 -0
- data/{doc → guides}/getting_started.rdoc +30 -18
- data/init.rb +0 -0
- data/install.rb +0 -0
- data/lib/big_record/abstract_base.rb +50 -28
- data/lib/big_record/action_view_extensions.rb +1 -1
- data/lib/big_record/ar_associations/association_collection.rb +0 -0
- data/lib/big_record/ar_associations/association_proxy.rb +0 -0
- data/lib/big_record/ar_associations/belongs_to_association.rb +0 -0
- data/lib/big_record/ar_associations/belongs_to_many_association.rb +0 -0
- data/lib/big_record/ar_associations/has_and_belongs_to_many_association.rb +0 -0
- data/lib/big_record/ar_associations/has_many_association.rb +0 -0
- data/lib/big_record/ar_associations/has_one_association.rb +0 -0
- data/lib/big_record/ar_associations.rb +0 -0
- data/lib/big_record/ar_reflection.rb +0 -0
- data/lib/big_record/attribute_methods.rb +0 -0
- data/lib/big_record/base.rb +49 -24
- data/lib/big_record/br_associations/association_collection.rb +0 -0
- data/lib/big_record/br_associations/association_proxy.rb +0 -0
- data/lib/big_record/br_associations/belongs_to_association.rb +0 -0
- data/lib/big_record/br_associations/belongs_to_many_association.rb +0 -0
- data/lib/big_record/br_associations/cached_item_proxy.rb +0 -0
- data/lib/big_record/br_associations/cached_item_proxy_factory.rb +0 -0
- data/lib/big_record/br_associations/has_and_belongs_to_many_association.rb +0 -0
- data/lib/big_record/br_associations/has_one_association.rb +0 -0
- data/lib/big_record/br_associations.rb +0 -0
- data/lib/big_record/br_reflection.rb +0 -0
- data/lib/big_record/callbacks.rb +0 -0
- data/lib/big_record/connection_adapters/abstract/connection_specification.rb +0 -0
- data/lib/big_record/connection_adapters/abstract/database_statements.rb +0 -0
- data/lib/big_record/connection_adapters/abstract/quoting.rb +1 -1
- data/lib/big_record/connection_adapters/abstract_adapter.rb +0 -0
- data/lib/big_record/connection_adapters/column.rb +30 -0
- data/lib/big_record/connection_adapters/hbase_adapter.rb +0 -0
- data/lib/big_record/connection_adapters/hbase_rest_adapter.rb +424 -0
- data/lib/big_record/connection_adapters/view.rb +63 -0
- data/lib/big_record/connection_adapters.rb +1 -0
- data/lib/big_record/deletion.rb +0 -0
- data/lib/big_record/dynamic_schema.rb +0 -0
- data/lib/big_record/embedded.rb +128 -1
- data/lib/big_record/embedded_associations/association_proxy.rb +0 -0
- data/lib/big_record/family_span_columns.rb +0 -0
- data/lib/big_record/fixtures.rb +0 -0
- data/lib/big_record/migration.rb +30 -8
- data/lib/big_record/routing_ext.rb +6 -4
- data/lib/big_record/timestamp.rb +0 -0
- data/lib/big_record/validations.rb +0 -0
- data/lib/big_record.rb +5 -3
- data/lib/bigrecord.rb +0 -0
- data/rails/init.rb +3 -2
- data/spec/adapter_benchmark.rb +55 -0
- data/spec/connections/bigrecord.yml +4 -2
- data/spec/connections/cassandra/connection.rb +0 -0
- data/spec/connections/hbase/connection.rb +0 -0
- data/spec/debug.log +156 -40724
- data/spec/integration/br_associations_spec.rb +0 -0
- data/spec/lib/animal.rb +0 -0
- data/spec/lib/book.rb +0 -0
- data/spec/lib/broken_migrations/duplicate_name/20090706182535_add_animals_table.rb +0 -0
- data/spec/lib/broken_migrations/duplicate_name/20090706193019_add_animals_table.rb +0 -0
- data/spec/lib/broken_migrations/duplicate_version/20090706190623_add_books_table.rb +0 -0
- data/spec/lib/broken_migrations/duplicate_version/20090706190623_add_companies_table.rb +0 -0
- data/spec/lib/company.rb +0 -0
- data/spec/lib/embedded/web_link.rb +0 -0
- data/spec/lib/employee.rb +0 -0
- data/spec/lib/migrations/20090706182535_add_animals_table.rb +0 -0
- data/spec/lib/migrations/20090706190623_add_books_table.rb +0 -0
- data/spec/lib/migrations/20090706193019_add_companies_table.rb +0 -0
- data/spec/lib/migrations/20090706194512_add_employees_table.rb +0 -0
- data/spec/lib/migrations/20090706195741_add_zoos_table.rb +0 -0
- data/spec/lib/novel.rb +2 -0
- data/spec/lib/zoo.rb +0 -0
- data/spec/spec.opts +0 -0
- data/spec/spec_helper.rb +7 -1
- data/spec/unit/abstract_base_spec.rb +0 -0
- data/spec/unit/adapters/abstract_adapter_spec.rb +0 -0
- data/spec/unit/adapters/adapter_shared_spec.rb +0 -0
- data/spec/unit/adapters/hbase_adapter_spec.rb +0 -0
- data/spec/unit/ar_associations_spec.rb +0 -0
- data/spec/unit/base_spec.rb +0 -0
- data/spec/unit/br_associations_spec.rb +0 -0
- data/spec/unit/embedded_spec.rb +0 -0
- data/spec/unit/find_spec.rb +0 -0
- data/spec/unit/hash_helper_spec.rb +0 -0
- data/spec/unit/migration_spec.rb +0 -0
- data/spec/unit/model_spec.rb +0 -0
- data/spec/unit/validations_spec.rb +0 -0
- data/tasks/bigrecord_tasks.rake +0 -0
- data/tasks/data_store.rb +8 -1
- data/tasks/gem.rb +2 -2
- data/tasks/rdoc.rb +14 -8
- data/tasks/spec.rb +0 -0
- metadata +10 -6
data/LICENSE
CHANGED
File without changes
|
data/README.rdoc
CHANGED
@@ -31,7 +31,15 @@ Beyond this though, there are two basic motivations that almost immediately dema
|
|
31
31
|
|
32
32
|
== Getting Started
|
33
33
|
|
34
|
-
Check out the
|
34
|
+
Check out the guides/getting_started.rdoc file for more information.
|
35
|
+
|
36
|
+
== Deployment
|
37
|
+
|
38
|
+
Refer to guides/deployment.rdoc for more information.
|
39
|
+
|
40
|
+
== Documentation
|
41
|
+
|
42
|
+
Please refer to http://openplaces.github.com/bigrecord/
|
35
43
|
|
36
44
|
== License
|
37
45
|
|
data/Rakefile
CHANGED
File without changes
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.8
|
data/examples/bigrecord.yml
CHANGED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,21 @@
|
|
1
|
+
= Deploying Big Record
|
2
|
+
|
3
|
+
Stargate is a new implementation for HBase's web service front-end, and as such, is not currently recommended for deployment.
|
4
|
+
|
5
|
+
We here at Openplaces have developed Bigrecord Driver, which uses JRuby to interact with HBase via the native Java API and connect to Bigrecord through the DRb protocol. This method is slightly more complicated to setup, but preliminary benchmarks show that it runs faster (especially for scanner functionality).
|
6
|
+
|
7
|
+
== Instructions
|
8
|
+
* Your database should already be set up (please refer to the database's own documentation) with the required information known such as the zookeeper quorum/port, etc. in order for Bigrecord to connect to it.
|
9
|
+
* Bigrecord Driver (if your database requires it for connecting)
|
10
|
+
* JRuby 1.1.6+ is needed to run Bigrecord Driver.
|
11
|
+
|
12
|
+
Install the Bigrecord Driver gem and its dependencies, then start up a DRb server. Please refer the Bigrecord Driver documentation for more detailed instructions. (http://github.com/openplaces/bigrecord/blob/master/bigrecord-driver/README.rdoc)
|
13
|
+
|
14
|
+
Edit your bigrecord.yml config file as follows:
|
15
|
+
|
16
|
+
production:
|
17
|
+
adapter: hbase
|
18
|
+
zookeeper_quorum: localhost
|
19
|
+
zookeeper_client_port: 2181
|
20
|
+
drb_host: localhost
|
21
|
+
drb_port: 50001
|
@@ -1,18 +1,29 @@
|
|
1
1
|
= Getting Started
|
2
2
|
|
3
|
-
== Requirements
|
4
3
|
|
5
|
-
|
6
|
-
* Bigrecord Driver (if your database requires it for connecting)
|
7
|
-
* JRuby 1.1.6+ is needed to run Bigrecord Driver.
|
4
|
+
== Setting up HBase and Stargate
|
8
5
|
|
9
|
-
|
6
|
+
To quickly get started with development, you can set up HBase to run as a single server on your local computer, along with Stargate, its RESTful web service front-end.
|
10
7
|
|
11
|
-
|
8
|
+
(1) Download and unpack the most recent release of HBase from http://hadoop.apache.org/hbase/releases.html#Download
|
12
9
|
|
13
|
-
(
|
10
|
+
(2) Edit (hbase-dir)/conf/hbase-env.sh and uncomment/modify the following line to correspond to your Java home path:
|
11
|
+
export JAVA_HOME=/usr/lib/jvm/java-6-sun
|
12
|
+
|
13
|
+
(3) Copy (hbase-dir)/contrib/stargate/hbase-<version>-stargate.jar into <hbase-dir>/lib
|
14
|
+
|
15
|
+
(4) Copy all the files in the (hbase-dir)/contrib/stargate/lib folder into <hbase-dir>/lib
|
16
|
+
|
17
|
+
(5) Start up HBase:
|
18
|
+
$ (hbase-dir)/bin/start-hbase.sh
|
19
|
+
|
20
|
+
(6)Start up Stargate (append "-p 1234" at the end if you want to change the port):
|
21
|
+
$ (hbase-dir)/bin/hbase org.apache.hadoop.hbase.stargate.Main
|
14
22
|
|
15
|
-
|
23
|
+
|
24
|
+
== Setting up Bigrecord
|
25
|
+
|
26
|
+
(1) Install the Bigrecord Driver gem and its dependencies, then start up a DRb server. Please see the Bigrecord Driver documentation for more detailed instructions. (http://github.com/openplaces/bigrecord/blob/master/bigrecord-driver/README.rdoc)
|
16
27
|
|
17
28
|
(2) Add the following line into the Rails::Initializer.run do |config| block:
|
18
29
|
|
@@ -26,15 +37,14 @@ and run the following command to install all the gems listed for your Rails app:
|
|
26
37
|
|
27
38
|
script/generate bigrecord
|
28
39
|
|
29
|
-
(4) Edit the config/bigrecord.yml[.sample] file in your Rails root to the information corresponding to
|
40
|
+
(4) Edit the config/bigrecord.yml[.sample] file in your Rails root to the information corresponding to the Stargate server.
|
30
41
|
|
31
|
-
|
42
|
+
development:
|
43
|
+
adapter: hbase_rest
|
44
|
+
api_address: http://localhost:8080
|
32
45
|
|
33
|
-
|
46
|
+
Note: 8080 is the default port that Stargate starts up on. Make sure you modify this if you changed the port from the default.
|
34
47
|
|
35
|
-
script/plugin install git://github.com/openplaces/bigrecord.git
|
36
|
-
|
37
|
-
(3) Edit the config/bigrecord.yml[.sample] file in your Rails root to the information corresponding to your database install and Bigrecord Driver DRb server.
|
38
48
|
|
39
49
|
== Usage
|
40
50
|
|
@@ -50,7 +60,7 @@ This will add a model in app/models and a migration file in db/bigrecord_migrate
|
|
50
60
|
|
51
61
|
Creates a Bigrecord specific migration and adds it into db/bigrecord_migrate
|
52
62
|
|
53
|
-
=== Migration File
|
63
|
+
=== {BigRecord::Migration Migration File}
|
54
64
|
|
55
65
|
Although column-oriented databases are generally schema-less, certain ones (like Hbase) require the creation of tables and column families ahead of time. The individual columns, however, are defined in the model itself and can be modified dynamically without the need for migrations.
|
56
66
|
|
@@ -81,7 +91,7 @@ Run the following rake task to migrate your tables and column families up to the
|
|
81
91
|
|
82
92
|
rake bigrecord:migrate
|
83
93
|
|
84
|
-
=== Column and Attribute Definition
|
94
|
+
=== {BigRecord::ConnectionAdapters::Column Column and Attribute Definition}
|
85
95
|
|
86
96
|
Now that you have your tables and column families all set up, you can begin adding columns to your model. The following is an example of a model named book.rb
|
87
97
|
|
@@ -94,7 +104,7 @@ Now that you have your tables and column families all set up, you can begin addi
|
|
94
104
|
|
95
105
|
This simple model defines 4 columns of type string. An important thing to notice here is that the first column 'attribute:title' had the column family prepended to it. This is identical to just passing the symbol :title to the column method, and the default behaviour is to prepend the column family (attribute) automatically if one is not defined. Furthermore, in Hbase, there's the option of storing collections for a given column. This will return an array for the links attribute on a Book record.
|
96
106
|
|
97
|
-
=== Associations
|
107
|
+
=== {BigRecord::BrAssociations Associations}
|
98
108
|
|
99
109
|
There are also associations available in Bigrecord, as well as the ability to associate to Activerecord models. The following are a few models demonstrating this:
|
100
110
|
|
@@ -118,7 +128,7 @@ In this example, an Animal is related to Zoo and Trainer. Both Animal and Zoo ar
|
|
118
128
|
|
119
129
|
Once the association columns are defined, you define the associations themselves with either belongs_to_bigrecord or belongs_to_many and defining the :foreign_key (this is required for all associations).
|
120
130
|
|
121
|
-
=== Specifying return columns
|
131
|
+
=== {BigRecord::ConnectionAdapters::View Specifying return columns}
|
122
132
|
|
123
133
|
There are two ways to define specific columns to be returned with your models: 1) at the model level and 2) during the query.
|
124
134
|
|
@@ -158,4 +168,6 @@ Note: A Bigrecord model will return all the columns within the default column fa
|
|
158
168
|
|
159
169
|
As you may have noticed, this functionality is synonymous with the :select option in Activerecord.
|
160
170
|
|
171
|
+
=== {BigRecord::Embedded Embedded Records}
|
172
|
+
|
161
173
|
=== At this point, usage patterns for a Bigrecord model are similar to that of an Activerecord model, and much of that documentation applies as well. Please refer to those and see if they work!
|
data/init.rb
CHANGED
File without changes
|
data/install.rb
CHANGED
File without changes
|
@@ -139,6 +139,8 @@ module BigRecord
|
|
139
139
|
# attributes but not yet saved (pass a hash with key names matching the associated table column names).
|
140
140
|
# In both instances, valid attribute keys are determined by the column names of the associated table --
|
141
141
|
# hence you can't have attributes that aren't part of the table columns.
|
142
|
+
#
|
143
|
+
# @param [Hash] Optional hash argument consisting of keys that match the names of the columns, and their values.
|
142
144
|
def initialize(attrs = nil)
|
143
145
|
preinitialize(attrs)
|
144
146
|
@attributes = attributes_from_column_definition
|
@@ -157,6 +159,9 @@ module BigRecord
|
|
157
159
|
|
158
160
|
# Safe version of attributes= so that objects can be instantiated even
|
159
161
|
# if columns are removed.
|
162
|
+
#
|
163
|
+
# @param [Hash] Attribute hash consisting of the column name and their values.
|
164
|
+
# @param [true, false] Pass the attributes hash through {#remove_attributes_protected_from_mass_assignment}
|
160
165
|
def safe_attributes=(new_attributes, guard_protected_attributes = true)
|
161
166
|
return if new_attributes.nil?
|
162
167
|
attributes = new_attributes.dup
|
@@ -189,10 +194,16 @@ module BigRecord
|
|
189
194
|
read_attribute(attr_name)
|
190
195
|
end
|
191
196
|
|
197
|
+
# Default to_s method that just returns invokes the {#id} method
|
198
|
+
#
|
199
|
+
# @return [String] The row identifier/id of the record
|
192
200
|
def to_s
|
193
201
|
id
|
194
202
|
end
|
195
203
|
|
204
|
+
# Get the attributes hash of the object.
|
205
|
+
#
|
206
|
+
# @return [Hash] a duplicated attributes hash
|
196
207
|
def attributes()
|
197
208
|
@attributes.dup
|
198
209
|
end
|
@@ -201,6 +212,8 @@ module BigRecord
|
|
201
212
|
# The optional options argument is passed to find when reloading so you
|
202
213
|
# may do e.g. record.reload(:lock => true) to reload the same record with
|
203
214
|
# an exclusive row lock.
|
215
|
+
#
|
216
|
+
# @return Itself with reloaded attributes.
|
204
217
|
def reload(options = nil)
|
205
218
|
@attributes.update(self.class.find(self.id, options).instance_variable_get('@attributes'))
|
206
219
|
self
|
@@ -262,12 +275,18 @@ module BigRecord
|
|
262
275
|
|
263
276
|
# Returns true if the specified +attribute+ has been set by the user or by a database load and is neither
|
264
277
|
# nil nor empty? (the latter only applies to objects that respond to empty?, most notably Strings).
|
278
|
+
#
|
279
|
+
# @return [String, Symbol] Name of an attribute.
|
280
|
+
# @return [true,false] Whether that attribute exists.
|
265
281
|
def attribute_present?(attribute)
|
266
282
|
value = read_attribute(attribute)
|
267
283
|
!value.blank? or value == 0
|
268
284
|
end
|
269
285
|
|
270
286
|
# Returns true if the given attribute is in the attributes hash
|
287
|
+
#
|
288
|
+
# @return [String, Symbol] Name of an attribute.
|
289
|
+
# @return [true,false] Whether that attribute exists in the attributes hash.
|
271
290
|
def has_attribute?(attr_name)
|
272
291
|
@attributes.has_key?(attr_name.to_s)
|
273
292
|
end
|
@@ -332,6 +351,9 @@ module BigRecord
|
|
332
351
|
@attributes.freeze; self
|
333
352
|
end
|
334
353
|
|
354
|
+
# Checks whether the object has had its attributes hash frozen.
|
355
|
+
#
|
356
|
+
# @return [true,false]
|
335
357
|
def frozen?
|
336
358
|
@attributes.frozen?
|
337
359
|
end
|
@@ -345,7 +367,8 @@ module BigRecord
|
|
345
367
|
write_attribute(self.class.primary_key, value)
|
346
368
|
end
|
347
369
|
|
348
|
-
# Returns true if this object hasn't been saved yet -- that is, a record for the object doesn't
|
370
|
+
# Returns true if this object hasn't been saved yet -- that is, a record for the object doesn't
|
371
|
+
# yet exist in the data store.
|
349
372
|
def new_record?
|
350
373
|
false
|
351
374
|
end
|
@@ -386,6 +409,7 @@ module BigRecord
|
|
386
409
|
raise NotImplemented
|
387
410
|
end
|
388
411
|
|
412
|
+
# Returns the connection adapter of the current session.
|
389
413
|
def connection
|
390
414
|
self.class.connection
|
391
415
|
end
|
@@ -395,6 +419,7 @@ module BigRecord
|
|
395
419
|
@readonly == true
|
396
420
|
end
|
397
421
|
|
422
|
+
# Sets the record to be readonly
|
398
423
|
def readonly! #:nodoc:
|
399
424
|
@readonly = true
|
400
425
|
end
|
@@ -466,15 +491,12 @@ module BigRecord
|
|
466
491
|
end
|
467
492
|
end
|
468
493
|
|
469
|
-
# Generate a new id
|
494
|
+
# Generate a new id with the UUIDTools library.
|
495
|
+
# Override this method to use another id generator.
|
470
496
|
def generate_new_id
|
471
497
|
UUIDTools::UUID.random_create.to_s
|
472
498
|
end
|
473
499
|
|
474
|
-
def self.random_id #not necessarily unique! -- this is strictly for 'stumbling', not for assigning to new entities
|
475
|
-
[8,4,4,4,12].map{|l| "%0#{l}x" % rand(1 << l*4) }.join('-')
|
476
|
-
end
|
477
|
-
|
478
500
|
# Initializes the attributes array with keys matching the columns from the linked table and
|
479
501
|
# the values matching the corresponding default value of that column, so
|
480
502
|
# that a new instance, or one populated from a passed-in Hash, still has all the attributes
|
@@ -610,6 +632,9 @@ module BigRecord
|
|
610
632
|
end
|
611
633
|
end
|
612
634
|
|
635
|
+
# Removes any attributes from the argument hash that have been declared as protected
|
636
|
+
# from mass assignment. See the {#attr_protected} and {#attr_accessible} macros to define
|
637
|
+
# these attributes.
|
613
638
|
def remove_attributes_protected_from_mass_assignment(attributes)
|
614
639
|
safe_attributes =
|
615
640
|
if self.class.accessible_attributes.nil? && self.class.protected_attributes.nil?
|
@@ -679,7 +704,7 @@ module BigRecord
|
|
679
704
|
private
|
680
705
|
# Called on first read access to any given column and generates reader
|
681
706
|
# methods for all columns in the columns_hash if
|
682
|
-
#
|
707
|
+
# BigRecord::Base.generate_read_methods is set to true.
|
683
708
|
def define_read_methods
|
684
709
|
self.class.columns_hash.each do |name, column|
|
685
710
|
unless respond_to_without_attributes?(name)
|
@@ -692,7 +717,7 @@ private
|
|
692
717
|
end
|
693
718
|
end
|
694
719
|
|
695
|
-
# Define an attribute reader method.
|
720
|
+
# Define an attribute reader method. Cope with a nil column.
|
696
721
|
def define_read_method(symbol, attr_name, column)
|
697
722
|
cast_code = column.type_cast_code('v') if column
|
698
723
|
access_code = cast_code ? "(v=@attributes['#{attr_name}']) && #{cast_code}" : "@attributes['#{attr_name}']"
|
@@ -760,22 +785,9 @@ private
|
|
760
785
|
raise NotImplemented
|
761
786
|
end
|
762
787
|
|
763
|
-
|
764
|
-
# def inspect
|
765
|
-
# if self == Base
|
766
|
-
# super
|
767
|
-
# elsif abstract_class?
|
768
|
-
# "#{super}(abstract)"
|
769
|
-
# elsif table_exists?
|
770
|
-
# attr_list = columns.map { |c| "#{c.name}: #{c.type}" } * ', '
|
771
|
-
# "#{super}(#{attr_list})"
|
772
|
-
# else
|
773
|
-
# "#{super}(Table doesn't exist)"
|
774
|
-
# end
|
775
|
-
# end
|
776
|
-
|
777
|
-
# Log and benchmark multiple statements in a single block. Example:
|
788
|
+
# Log and benchmark multiple statements in a single block.
|
778
789
|
#
|
790
|
+
# @example
|
779
791
|
# Project.benchmark("Creating project") do
|
780
792
|
# project = Project.create("name" => "stuff")
|
781
793
|
# project.create_manager("name" => "David")
|
@@ -816,7 +828,7 @@ private
|
|
816
828
|
end
|
817
829
|
|
818
830
|
# Override this method in the subclasses to add new columns. This is different from ActiveRecord because
|
819
|
-
# the number of columns in
|
831
|
+
# the number of columns in an Hbase table is variable.
|
820
832
|
def columns
|
821
833
|
@columns = columns_hash.values
|
822
834
|
end
|
@@ -868,6 +880,15 @@ private
|
|
868
880
|
end
|
869
881
|
end
|
870
882
|
|
883
|
+
# Macro for defining a new column for a model. Invokes {create_column} and
|
884
|
+
# adds the new column into the model's column hash.
|
885
|
+
#
|
886
|
+
# @param type [Symbol, String] Column type as defined in the source of {ConnectionAdapters::Column#klass}
|
887
|
+
# @option options [true,false] :collection Whether this column is a collection.
|
888
|
+
# @option options [String] :alias Define an alias for the column that cannot be inferred. By default, 'attribute:name' will be aliased to 'name'.
|
889
|
+
# @option options [String] :default Default value to set for this column.
|
890
|
+
#
|
891
|
+
# @return [ConnectionAdapters::Column] The column object created.
|
871
892
|
def column(name, type, options={})
|
872
893
|
name = name.to_s
|
873
894
|
|
@@ -884,10 +905,6 @@ private
|
|
884
905
|
c
|
885
906
|
end
|
886
907
|
|
887
|
-
def create_column(name, type, options)
|
888
|
-
ConnectionAdapters::Column.new(name, type, options)
|
889
|
-
end
|
890
|
-
|
891
908
|
# Define aliases to the fully qualified attributes
|
892
909
|
def alias_attribute(alias_name, fully_qualified_name)
|
893
910
|
self.class_eval <<-EOF
|
@@ -1040,6 +1057,11 @@ private
|
|
1040
1057
|
@content_columns = nil
|
1041
1058
|
end
|
1042
1059
|
|
1060
|
+
# Creates a {ConnectionAdapters::Column} object.
|
1061
|
+
def create_column(name, type, options)
|
1062
|
+
ConnectionAdapters::Column.new(name, type, options)
|
1063
|
+
end
|
1064
|
+
|
1043
1065
|
def default_columns
|
1044
1066
|
raise NotImplemented
|
1045
1067
|
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/lib/big_record/base.rb
CHANGED
@@ -33,7 +33,6 @@ module BigRecord
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
# protected
|
37
36
|
# Returns the value of the attribute identified by <tt>attr_name</tt> after it has been typecast (for example,
|
38
37
|
# "2004-12-12" in a data column is cast to a date object, like Date.new(2004, 12, 12)).
|
39
38
|
def read_attribute(attr_name, options={})
|
@@ -81,6 +80,7 @@ module BigRecord
|
|
81
80
|
end
|
82
81
|
end
|
83
82
|
|
83
|
+
# Read an attribute that defines a column family.
|
84
84
|
def read_family_attributes(attr_name)
|
85
85
|
attr_name = attr_name.to_s
|
86
86
|
column = column_for_attribute(attr_name)
|
@@ -197,6 +197,7 @@ module BigRecord
|
|
197
197
|
|
198
198
|
protected
|
199
199
|
|
200
|
+
# Invoke {#create} if {#new_record} returns true, otherwise it's an {#update}
|
200
201
|
def create_or_update
|
201
202
|
raise ReadOnlyRecord if readonly?
|
202
203
|
result = new_record? ? create : update
|
@@ -230,11 +231,7 @@ module BigRecord
|
|
230
231
|
public
|
231
232
|
class << self
|
232
233
|
|
233
|
-
#
|
234
|
-
# def default_family
|
235
|
-
# "attribute"
|
236
|
-
# end
|
237
|
-
|
234
|
+
# Return the name of the primary key. Defaults to "id".
|
238
235
|
def primary_key
|
239
236
|
@primary_key ||= "id"
|
240
237
|
end
|
@@ -245,12 +242,12 @@ module BigRecord
|
|
245
242
|
end
|
246
243
|
|
247
244
|
# HBase scanner utility -- scans the table and executes code on each record
|
248
|
-
#
|
245
|
+
#
|
246
|
+
# @example
|
249
247
|
# Entity.scan(:batch_size => 200) {|e|puts "#{e.name} is a child!" if e.parent}
|
250
248
|
#
|
251
|
-
#
|
252
|
-
#
|
253
|
-
# code - the code to execute (see example above for syntax)
|
249
|
+
# @option options [Integer] :batch_size - number of records to retrieve from database with each scan iteration.
|
250
|
+
# @option options [Block] :code - the code to execute (see example above for syntax)
|
254
251
|
#
|
255
252
|
def scan(options={}, &code)
|
256
253
|
options = options.dup
|
@@ -327,10 +324,10 @@ module BigRecord
|
|
327
324
|
# The arguments may also be given as arrays in which case the update method is called for each pair of +id+ and
|
328
325
|
# +attributes+ and an array of objects is returned.
|
329
326
|
#
|
330
|
-
#
|
327
|
+
# @example of updating one record:
|
331
328
|
# Person.update(15, {:user_name => 'Samuel', :group => 'expert'})
|
332
329
|
#
|
333
|
-
#
|
330
|
+
# @example of updating multiple records:
|
334
331
|
# people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy"} }
|
335
332
|
# Person.update(people.keys, people.values)
|
336
333
|
def update(id, attributes)
|
@@ -378,7 +375,7 @@ module BigRecord
|
|
378
375
|
# calling the destroy method). Example:
|
379
376
|
# Post.delete_all "person_id = 5 AND (category = 'Something' OR category = 'Else')"
|
380
377
|
#
|
381
|
-
#
|
378
|
+
# @todo take into consideration the conditions
|
382
379
|
def delete_all(conditions = nil)
|
383
380
|
connection.get_consecutive_rows(table_name, nil, nil, ["#{default_family}:"]).each do |row|
|
384
381
|
connection.delete(table_name, row["id"])
|
@@ -398,18 +395,34 @@ module BigRecord
|
|
398
395
|
@table_name = name.to_s
|
399
396
|
end
|
400
397
|
|
398
|
+
# Get the default column family used to store attributes that have no column family set explicitly.
|
399
|
+
#
|
400
|
+
# Defaults to "attribute"
|
401
401
|
def default_family
|
402
402
|
(superclass == BigRecord::Base) ? (@default_family ||= "attribute") : superclass.default_family
|
403
403
|
end
|
404
404
|
|
405
|
+
# Set the default column family used to store attributes that have no column family set explicitly.
|
406
|
+
#
|
407
|
+
# @example
|
408
|
+
# set_default_family :attr # instead of using :attribute as the default.
|
405
409
|
def set_default_family(name)
|
406
410
|
@default_family = name.to_s
|
407
411
|
end
|
408
412
|
|
413
|
+
# @return [Class] The base class which inherits BigRecord::Base directly.
|
409
414
|
def base_class
|
410
415
|
(superclass == BigRecord::Base) ? self : superclass.base_class
|
411
416
|
end
|
412
417
|
|
418
|
+
# Macro for defining a named view to a list of columns.
|
419
|
+
#
|
420
|
+
# @param [String, Symbol] name Give it an arbitrary name.
|
421
|
+
# @param [Array<String, Symbol>] columns List of columns to associate to this view. Can use column aliases or fully qualified names.
|
422
|
+
#
|
423
|
+
# @example
|
424
|
+
# view :front_page, :name, :title, :description
|
425
|
+
# view :summary, ["attribute:name", "attribute:title"]
|
413
426
|
def view(name, *columns)
|
414
427
|
name = name.to_sym
|
415
428
|
@views_hash ||= default_views
|
@@ -420,14 +433,17 @@ module BigRecord
|
|
420
433
|
@views_hash[name] = ConnectionAdapters::View.new(name, columns.flatten, self)
|
421
434
|
end
|
422
435
|
|
436
|
+
# Get a list of all the views defined by the {view} macro for the model.
|
423
437
|
def views
|
424
438
|
@views ||= views_hash.values
|
425
439
|
end
|
426
440
|
|
441
|
+
# Get a list of view names defined by {view}.
|
427
442
|
def view_names
|
428
443
|
@view_names ||= views_hash.keys
|
429
444
|
end
|
430
445
|
|
446
|
+
# Get the full hash of views consisting of the name as keys, and the {ConnectionAdapters::View} views.
|
431
447
|
def views_hash
|
432
448
|
unless @all_views_hash
|
433
449
|
# add default hbase columns
|
@@ -445,10 +461,12 @@ module BigRecord
|
|
445
461
|
@all_views_hash
|
446
462
|
end
|
447
463
|
|
464
|
+
# Default columns to create with the model, such as primary key.
|
448
465
|
def default_columns
|
449
466
|
{primary_key => ConnectionAdapters::Column.new(primary_key, 'string')}
|
450
467
|
end
|
451
468
|
|
469
|
+
# @see BigRecord::AbstractBase.column
|
452
470
|
def column(name, type, options={})
|
453
471
|
name = name.to_s
|
454
472
|
name = "#{self.default_family}:#{name}" unless (name =~ /:/)
|
@@ -456,21 +474,18 @@ module BigRecord
|
|
456
474
|
super(name, type, options)
|
457
475
|
end
|
458
476
|
|
477
|
+
# Return the hash of default views which consist of all columns and the :default named views.
|
459
478
|
def default_views
|
460
479
|
{:all=>ConnectionAdapters::View.new('all', nil, self), :default=>ConnectionAdapters::View.new('default', nil, self)}
|
461
480
|
end
|
462
481
|
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
end
|
471
|
-
end
|
472
|
-
|
473
|
-
# return the list of columns to get from hbase
|
482
|
+
# Return the list of fully qualified column names, i.e. ["family:qualifier"].
|
483
|
+
#
|
484
|
+
# Returns the column names based on the options argument in order of
|
485
|
+
# :columns,then :view, i.e. disregards :view if :columns is defined.
|
486
|
+
#
|
487
|
+
# @option options [Array<String, Symbol>] :columns List of fully qualified column names or column aliases.
|
488
|
+
# @option options [String, Symbol] :view The name of the view as defined with {view}.
|
474
489
|
def columns_to_find(options={})
|
475
490
|
c =
|
476
491
|
if options[:columns]
|
@@ -599,6 +614,16 @@ module BigRecord
|
|
599
614
|
end
|
600
615
|
end
|
601
616
|
|
617
|
+
def find_all_by_id(ids, options={})
|
618
|
+
ids.inject([]) do |result, id|
|
619
|
+
begin
|
620
|
+
result << find_one(id, options)
|
621
|
+
rescue BigRecord::RecordNotFound => e
|
622
|
+
end
|
623
|
+
result
|
624
|
+
end
|
625
|
+
end
|
626
|
+
|
602
627
|
# Add the missing cells to the raw record and set them to nil. We know that it's
|
603
628
|
# nil because else we would have received those cells. That way, when the value of
|
604
629
|
# one of these cells will be requested by the client we won't try to lazy load it.
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/lib/big_record/callbacks.rb
CHANGED
File without changes
|
File without changes
|
File without changes
|