bigrecord 0.0.8 → 0.0.9
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.
- data/README.rdoc +5 -4
- data/VERSION +1 -1
- data/lib/big_record/abstract_base.rb +21 -14
- data/lib/big_record/base.rb +38 -30
- data/lib/big_record/br_associations.rb +100 -773
- data/lib/big_record/br_reflection.rb +1 -3
- data/lib/big_record/connection_adapters/abstract/database_statements.rb +1 -161
- data/lib/big_record/connection_adapters/abstract_adapter.rb +1 -17
- data/lib/big_record/connection_adapters/column.rb +1 -30
- data/lib/big_record/connection_adapters/hbase_adapter.rb +18 -16
- data/lib/big_record/connection_adapters/hbase_rest_adapter.rb +64 -61
- data/lib/big_record/dynamic_schema.rb +14 -0
- data/lib/big_record/embedded_associations/association_proxy.rb +0 -6
- data/lib/big_record/timestamp.rb +28 -2
- data/lib/big_record.rb +1 -4
- data/lib/bigrecord.rb +1 -1
- data/spec/connections/bigrecord.yml +2 -2
- data/spec/debug.log +215 -172
- data/spec/unit/ar_associations_spec.rb +0 -7
- data/spec/unit/{abstract_base_spec.rb → attributes_spec.rb} +20 -3
- data/spec/unit/callback_spec.rb +1 -0
- data/spec/unit/{base_spec.rb → columns_spec.rb} +2 -2
- data/spec/unit/embedded_spec.rb +1 -1
- data/spec/unit/find_spec.rb +10 -0
- data/spec/unit/model_spec.rb +13 -4
- data/spec/unit/scanner_spec.rb +44 -0
- data/tasks/gem.rb +0 -1
- data/tasks/rdoc.rb +1 -1
- metadata +6 -14
data/README.rdoc
CHANGED
@@ -3,10 +3,10 @@
|
|
3
3
|
A Ruby Object/Data Mapper for distributed column-oriented data stores (inspired by BigTable) such as HBase. Intended to work as a drop-in for Rails applications.
|
4
4
|
|
5
5
|
== Features
|
6
|
-
* Dynamic schemas (due to the schema-less design of BigTable).
|
6
|
+
* {BigRecord::DynamicSchema Dynamic schemas} (due to the schema-less design of BigTable).
|
7
7
|
* Support for column-oriented data stores.
|
8
8
|
* Similar usage to Active Record.
|
9
|
-
* Embedded records that store within a single table row.
|
9
|
+
* {BigRecord::Embedded Embedded records} that store within a single table row.
|
10
10
|
* Automatic versioning.
|
11
11
|
* Scalability (depending on the data store used).
|
12
12
|
|
@@ -31,11 +31,11 @@ Beyond this though, there are two basic motivations that almost immediately dema
|
|
31
31
|
|
32
32
|
== Getting Started
|
33
33
|
|
34
|
-
Check out the guides/getting_started.rdoc file for more information.
|
34
|
+
Check out the {file:guides/getting_started.rdoc guides/getting_started.rdoc} file for more information.
|
35
35
|
|
36
36
|
== Deployment
|
37
37
|
|
38
|
-
Refer to guides/deployment.rdoc for more information.
|
38
|
+
Refer to {file:guides/deployment.rdoc guides/deployment.rdoc} for more information.
|
39
39
|
|
40
40
|
== Documentation
|
41
41
|
|
@@ -48,5 +48,6 @@ Big Record is released under the MIT license.
|
|
48
48
|
== Links
|
49
49
|
|
50
50
|
* Contact Us
|
51
|
+
* Google Group - http://groups.google.com/group/bigrecord
|
51
52
|
* Website - http://www.bigrecord.org
|
52
53
|
* IRC Channel - <tt>#bigrecord</tt> on irc.freenode.net
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.9
|
@@ -367,14 +367,14 @@ module BigRecord
|
|
367
367
|
write_attribute(self.class.primary_key, value)
|
368
368
|
end
|
369
369
|
|
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.
|
370
|
+
# Returns true if this object hasn't been saved yet -- that is, a record for the object doesn't exist yet.
|
372
371
|
def new_record?
|
373
372
|
false
|
374
373
|
end
|
375
374
|
|
376
|
-
#
|
377
|
-
# *
|
375
|
+
# Method that saves the BigRecord object into the database. It will do one of two things:
|
376
|
+
# * If no record currently exists: Creates a new record with values matching those of the object attributes.
|
377
|
+
# * If a record already exist: Updates the record with values matching those of the object attributes.
|
378
378
|
def save
|
379
379
|
raise NotImplemented
|
380
380
|
end
|
@@ -435,6 +435,7 @@ module BigRecord
|
|
435
435
|
end
|
436
436
|
|
437
437
|
protected
|
438
|
+
|
438
439
|
def clone_in_persistence_format
|
439
440
|
validate_attributes_schema
|
440
441
|
|
@@ -682,6 +683,7 @@ module BigRecord
|
|
682
683
|
end
|
683
684
|
|
684
685
|
protected
|
686
|
+
|
685
687
|
# Returns the value of the attribute identified by <tt>attr_name</tt> after it has been typecast (for example,
|
686
688
|
# "2004-12-12" in a data column is cast to a date object, like Date.new(2004, 12, 12)).
|
687
689
|
def read_attribute(attr_name)
|
@@ -701,7 +703,8 @@ module BigRecord
|
|
701
703
|
@attributes[attr_name.to_s]
|
702
704
|
end
|
703
705
|
|
704
|
-
private
|
706
|
+
private
|
707
|
+
|
705
708
|
# Called on first read access to any given column and generates reader
|
706
709
|
# methods for all columns in the columns_hash if
|
707
710
|
# BigRecord::Base.generate_read_methods is set to true.
|
@@ -778,6 +781,7 @@ private
|
|
778
781
|
end
|
779
782
|
|
780
783
|
public
|
784
|
+
|
781
785
|
class << self
|
782
786
|
|
783
787
|
# Evaluate the name of the column of the primary key only once
|
@@ -884,7 +888,8 @@ private
|
|
884
888
|
# adds the new column into the model's column hash.
|
885
889
|
#
|
886
890
|
# @param type [Symbol, String] Column type as defined in the source of {ConnectionAdapters::Column#klass}
|
887
|
-
# @
|
891
|
+
# @param [Hash] options The options to define the column with.
|
892
|
+
# @option options [TrueClass,FalseClass] :collection Whether this column is a collection.
|
888
893
|
# @option options [String] :alias Define an alias for the column that cannot be inferred. By default, 'attribute:name' will be aliased to 'name'.
|
889
894
|
# @option options [String] :default Default value to set for this column.
|
890
895
|
#
|
@@ -918,7 +923,7 @@ private
|
|
918
923
|
end
|
919
924
|
|
920
925
|
# Contains the names of the generated reader methods.
|
921
|
-
def read_methods
|
926
|
+
def read_methods
|
922
927
|
@read_methods ||= Set.new
|
923
928
|
end
|
924
929
|
|
@@ -1045,7 +1050,15 @@ private
|
|
1045
1050
|
read_inheritable_attribute(:attr_create_accessible)
|
1046
1051
|
end
|
1047
1052
|
|
1053
|
+
# Guesses the table name, but does not decorate it with prefix and suffix information.
|
1054
|
+
def undecorated_table_name(class_name = base_class.name)
|
1055
|
+
table_name = Inflector.underscore(Inflector.demodulize(class_name))
|
1056
|
+
table_name = Inflector.pluralize(table_name) if pluralize_table_names
|
1057
|
+
table_name
|
1058
|
+
end
|
1059
|
+
|
1048
1060
|
protected
|
1061
|
+
|
1049
1062
|
def invalidate_views
|
1050
1063
|
@views = nil
|
1051
1064
|
@view_names = nil
|
@@ -1081,16 +1094,10 @@ private
|
|
1081
1094
|
type_name.constantize
|
1082
1095
|
end
|
1083
1096
|
|
1084
|
-
public
|
1085
|
-
# Guesses the table name, but does not decorate it with prefix and suffix information.
|
1086
|
-
def undecorated_table_name(class_name = base_class.name)
|
1087
|
-
table_name = Inflector.underscore(Inflector.demodulize(class_name))
|
1088
|
-
table_name = Inflector.pluralize(table_name) if pluralize_table_names
|
1089
|
-
table_name
|
1090
|
-
end
|
1091
1097
|
end
|
1092
1098
|
|
1093
1099
|
protected
|
1100
|
+
|
1094
1101
|
# Handle *? for method_missing.
|
1095
1102
|
def attribute?(attribute_name)
|
1096
1103
|
query_attribute(attribute_name)
|
data/lib/big_record/base.rb
CHANGED
@@ -12,8 +12,10 @@ module BigRecord
|
|
12
12
|
super
|
13
13
|
end
|
14
14
|
|
15
|
+
public
|
16
|
+
|
15
17
|
# New objects can be instantiated as either empty (pass no construction parameter) or pre-set with
|
16
|
-
# attributes but not yet saved (pass a hash with key names matching the associated
|
18
|
+
# attributes but not yet saved (pass a hash with key names matching the associated column names).
|
17
19
|
# In both instances, valid attribute keys are determined by the column names of the associated table --
|
18
20
|
# hence you can't have attributes that aren't part of the table columns.
|
19
21
|
def initialize(attrs = nil)
|
@@ -24,7 +26,6 @@ module BigRecord
|
|
24
26
|
|
25
27
|
# Returns the value of the attribute identified by <tt>attr_name</tt> after it has been typecast (for example,
|
26
28
|
# "2004-12-12" in a data column is cast to a date object, like Date.new(2004, 12, 12)).
|
27
|
-
# (Alias for the protected read_attribute method).
|
28
29
|
def [](attr_name)
|
29
30
|
if attr_name.ends_with?(":")
|
30
31
|
read_family_attributes(attr_name)
|
@@ -80,7 +81,7 @@ module BigRecord
|
|
80
81
|
end
|
81
82
|
end
|
82
83
|
|
83
|
-
# Read an attribute that defines a column family.
|
84
|
+
# Read an attribute that defines a column family, as opposed to a column qualifier.
|
84
85
|
def read_family_attributes(attr_name)
|
85
86
|
attr_name = attr_name.to_s
|
86
87
|
column = column_for_attribute(attr_name)
|
@@ -130,24 +131,14 @@ module BigRecord
|
|
130
131
|
end
|
131
132
|
end
|
132
133
|
|
133
|
-
def set_loaded(name)
|
134
|
-
@loaded_columns ||= []
|
135
|
-
@loaded_columns << name
|
136
|
-
end
|
137
|
-
|
138
|
-
def is_loaded?(name)
|
139
|
-
@loaded_columns ||= []
|
140
|
-
@loaded_columns.include?(name)
|
141
|
-
end
|
142
|
-
|
143
|
-
public
|
144
134
|
# Returns true if this object hasn't been saved yet -- that is, a record for the object doesn't exist yet.
|
145
135
|
def new_record?
|
146
136
|
@new_record
|
147
137
|
end
|
148
138
|
|
149
|
-
#
|
150
|
-
# *
|
139
|
+
# Method that saves the BigRecord object into the database. It will do one of two things:
|
140
|
+
# * If no record currently exists: Creates a new record with values matching those of the object attributes.
|
141
|
+
# * If a record already exist: Updates the record with values matching those of the object attributes.
|
151
142
|
def save
|
152
143
|
create_or_update
|
153
144
|
end
|
@@ -158,8 +149,7 @@ module BigRecord
|
|
158
149
|
create_or_update || raise(RecordNotSaved)
|
159
150
|
end
|
160
151
|
|
161
|
-
# Deletes the record in the database
|
162
|
-
# be made (since they can't be persisted).
|
152
|
+
# Deletes the record in the database.
|
163
153
|
def destroy
|
164
154
|
unless new_record?
|
165
155
|
connection.delete(self.class.table_name, self.id)
|
@@ -197,6 +187,16 @@ module BigRecord
|
|
197
187
|
|
198
188
|
protected
|
199
189
|
|
190
|
+
def set_loaded(name)
|
191
|
+
@loaded_columns ||= []
|
192
|
+
@loaded_columns << name
|
193
|
+
end
|
194
|
+
|
195
|
+
def is_loaded?(name)
|
196
|
+
@loaded_columns ||= []
|
197
|
+
@loaded_columns.include?(name)
|
198
|
+
end
|
199
|
+
|
200
200
|
# Invoke {#create} if {#new_record} returns true, otherwise it's an {#update}
|
201
201
|
def create_or_update
|
202
202
|
raise ReadOnlyRecord if readonly?
|
@@ -218,8 +218,8 @@ module BigRecord
|
|
218
218
|
update_bigrecord
|
219
219
|
end
|
220
220
|
|
221
|
-
# Update this record in
|
222
|
-
# therefore weird
|
221
|
+
# Update this record in the database. Cannot be directly in the method 'update' because it would trigger callbacks and
|
222
|
+
# therefore weird behavior.
|
223
223
|
def update_bigrecord
|
224
224
|
timestamp = self.respond_to?(:updated_at) ? self.updated_at.to_bigrecord_timestamp : Time.now.to_bigrecord_timestamp
|
225
225
|
|
@@ -229,6 +229,7 @@ module BigRecord
|
|
229
229
|
end
|
230
230
|
|
231
231
|
public
|
232
|
+
|
232
233
|
class << self
|
233
234
|
|
234
235
|
# Return the name of the primary key. Defaults to "id".
|
@@ -299,6 +300,16 @@ module BigRecord
|
|
299
300
|
end
|
300
301
|
end
|
301
302
|
|
303
|
+
# Returns all records for the model by invoking find(:all)
|
304
|
+
def all
|
305
|
+
find(:all)
|
306
|
+
end
|
307
|
+
|
308
|
+
# Returns the first record for the model by invoke find(:first)
|
309
|
+
def first
|
310
|
+
find(:first)
|
311
|
+
end
|
312
|
+
|
302
313
|
# Returns true if the given +id+ represents the primary key of a record in the database, false otherwise.
|
303
314
|
def exists?(id)
|
304
315
|
!find(id).nil?
|
@@ -387,10 +398,16 @@ module BigRecord
|
|
387
398
|
connection.truncate_table(table_name)
|
388
399
|
end
|
389
400
|
|
401
|
+
# Returns the inflected table name as it's called in your database.
|
390
402
|
def table_name
|
391
403
|
(superclass == BigRecord::Base) ? @table_name : superclass.table_name
|
392
404
|
end
|
393
405
|
|
406
|
+
# If you want to avoid the table name inflection, you can define the name
|
407
|
+
# explicitly with this method.
|
408
|
+
#
|
409
|
+
# @example
|
410
|
+
# set_table_name :table_xyz
|
394
411
|
def set_table_name(name)
|
395
412
|
@table_name = name.to_s
|
396
413
|
end
|
@@ -519,6 +536,7 @@ module BigRecord
|
|
519
536
|
end
|
520
537
|
|
521
538
|
protected
|
539
|
+
|
522
540
|
def invalidate_views
|
523
541
|
@views = nil
|
524
542
|
@view_names = nil
|
@@ -614,16 +632,6 @@ module BigRecord
|
|
614
632
|
end
|
615
633
|
end
|
616
634
|
|
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
|
-
|
627
635
|
# Add the missing cells to the raw record and set them to nil. We know that it's
|
628
636
|
# nil because else we would have received those cells. That way, when the value of
|
629
637
|
# one of these cells will be requested by the client we won't try to lazy load it.
|