hyper_record 0.2.8
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/.gitignore +3 -0
- data/CHANGELOG +83 -0
- data/LICENSE +20 -0
- data/README +49 -0
- data/Rakefile +43 -0
- data/VERSION.yml +4 -0
- data/benchmark/save.rb +58 -0
- data/hyper_record.gemspec +76 -0
- data/init.rb +1 -0
- data/lib/active_record/connection_adapters/hyper_table_definition.rb +26 -0
- data/lib/active_record/connection_adapters/hypertable_adapter.rb +680 -0
- data/lib/active_record/connection_adapters/qualified_column.rb +57 -0
- data/lib/associations/hyper_has_and_belongs_to_many_association_extension.rb +107 -0
- data/lib/associations/hyper_has_many_association_extension.rb +87 -0
- data/lib/hyper_record.rb +636 -0
- data/lib/hypertable/gen-rb/client_constants.rb +12 -0
- data/lib/hypertable/gen-rb/client_service.rb +1436 -0
- data/lib/hypertable/gen-rb/client_types.rb +253 -0
- data/lib/hypertable/gen-rb/hql_constants.rb +12 -0
- data/lib/hypertable/gen-rb/hql_service.rb +281 -0
- data/lib/hypertable/gen-rb/hql_types.rb +73 -0
- data/lib/hypertable/thrift_client.rb +94 -0
- data/lib/hypertable/thrift_transport_monkey_patch.rb +29 -0
- data/pkg/hyper_record-0.2.8.gem +0 -0
- data/spec/fixtures/pages.yml +8 -0
- data/spec/fixtures/qualified_pages.yml +1 -0
- data/spec/lib/associations_spec.rb +235 -0
- data/spec/lib/hyper_record_spec.rb +948 -0
- data/spec/lib/hypertable_adapter_spec.rb +121 -0
- data/spec/spec_helper.rb +130 -0
- data/test/test_helper.rb +10 -0
- data/test/thrift_client_test.rb +590 -0
- metadata +99 -0
@@ -0,0 +1,121 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../spec_helper.rb')
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module ConnectionAdapters
|
5
|
+
describe HypertableAdapter do
|
6
|
+
before do
|
7
|
+
@h = HypertableAdapter.new(nil, nil, {})
|
8
|
+
end
|
9
|
+
|
10
|
+
describe HypertableAdapter, '.describe_table' do
|
11
|
+
before do
|
12
|
+
@describe_table_text = '<Schema generation="1">\n <AccessGroup name="default">\n <ColumnFamily id="1">\n <Name>message</Name> </ColumnFamily>\n <ColumnFamily id="2">\n <Name>date-time</Name>\n </ColumnFamily>\n </AccessGroup>\n </Schema>\n'
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should return a string describing a table" do
|
16
|
+
@h.should_receive(:describe_table).with('name').and_return(@describe_table_text)
|
17
|
+
@h.describe_table('name').should == @describe_table_text
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe HypertableAdapter, '.column' do
|
22
|
+
before do
|
23
|
+
@describe_table_text = '<Schema generation="1">\n <AccessGroup name="default">\n <ColumnFamily id="1">\n <Name>message</Name> </ColumnFamily>\n <ColumnFamily id="2">\n <Name>date-time</Name>\n </ColumnFamily>\n </AccessGroup>\n </Schema>\n'
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should return an array of columns representing the table schema" do
|
27
|
+
@h.stub!(:describe_table).with('name').and_return(@describe_table_text)
|
28
|
+
columns = @h.columns('name')
|
29
|
+
columns.should be_is_a(Array)
|
30
|
+
columns.should have_exactly(3).columns
|
31
|
+
# The first column within a Hypertable is always the row key.
|
32
|
+
columns[0].name.should == "ROW"
|
33
|
+
columns[1].name.should == "message"
|
34
|
+
# notice that the original column name "date-time" is converted
|
35
|
+
# to a Ruby-friendly column name "date_time"
|
36
|
+
columns[2].name.should == "date_time"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should set up the name mappings between ruby and hypertable" do
|
40
|
+
@h.stub!(:describe_table).with('name').and_return(@describe_table_text)
|
41
|
+
columns = @h.columns('name')
|
42
|
+
@h.hypertable_column_name('date_time', 'name').should == 'date-time'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe HypertableAdapter, '.quote_column_name' do
|
47
|
+
it "should surround column name in single quotes" do
|
48
|
+
@h.quote_column_name("date_time").should == "'date_time'"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe HypertableAdapter, '.rubify_column_name' do
|
53
|
+
it "should change dashes to underscores in column names" do
|
54
|
+
@h.rubify_column_name("date-time").should == "date_time"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe HypertableAdapter, '.tables' do
|
59
|
+
before do
|
60
|
+
@tables = ["table1", "table2"]
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should return an array of table names" do
|
64
|
+
@h.should_receive(:tables).and_return(@tables)
|
65
|
+
@h.tables.should == @tables
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe HypertableAdapter, '.quote' do
|
70
|
+
it "should return empty string for nil values" do
|
71
|
+
@h.quote(nil).should == ''
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe HypertableAdapter, '.quote' do
|
76
|
+
it "should return a quoted string for all non-nil values" do
|
77
|
+
@h.quote(1).should == "1"
|
78
|
+
@h.quote('happy').should == "happy"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe HypertableAdapter, '.is_qualified_column_name?' do
|
83
|
+
it "should return false for regular columns" do
|
84
|
+
status, family, qualifier = @h.is_qualified_column_name?("col1")
|
85
|
+
status.should be_false
|
86
|
+
family.should == 'col1'
|
87
|
+
qualifier.should be_nil
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should return true for qualified columns" do
|
91
|
+
status, family, qualifier = @h.is_qualified_column_name?("col1:red")
|
92
|
+
status.should be_true
|
93
|
+
family.should == 'col1'
|
94
|
+
qualifier.should == 'red'
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe HypertableAdapter, '.create_table_sql' do
|
99
|
+
it "should assemble correct hql for creating a table" do
|
100
|
+
hql = @h.create_table_hql :new_table do |t|
|
101
|
+
t.column :name, :string
|
102
|
+
t.column :value, :string, :max_versions => 1
|
103
|
+
end
|
104
|
+
|
105
|
+
hql.should == "CREATE TABLE 'new_table' ( 'name' , 'value' MAX_VERSIONS=1 )"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe HypertableAdapter, '.create_table_with_block' do
|
110
|
+
it "should assemble correct hql for creating a table" do
|
111
|
+
@h.should_receive(:execute).with("CREATE TABLE 'new_table_with_block' ( 'name' , 'value' MAX_VERSIONS=1 )").and_return(nil)
|
112
|
+
|
113
|
+
@h.create_table :new_table_with_block do |t|
|
114
|
+
t.column :name, :string
|
115
|
+
t.column :value, :string, :max_versions => 1
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
ENV["RAILS_ENV"] = "test"
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "../../../../config/environment"))
|
3
|
+
require 'spec'
|
4
|
+
require 'spec/autorun' # required rspec 1.2.8?
|
5
|
+
require 'spec/rails'
|
6
|
+
|
7
|
+
ActiveRecord::Base.configurations['hypertable'] = {
|
8
|
+
'adapter' => 'hypertable',
|
9
|
+
'host' => 'localhost',
|
10
|
+
'port' => '38080'
|
11
|
+
}
|
12
|
+
ActiveRecord::Base.establish_connection(:hypertable)
|
13
|
+
|
14
|
+
class Dummy < ActiveRecord::HyperBase
|
15
|
+
end
|
16
|
+
|
17
|
+
class Page < ActiveRecord::HyperBase
|
18
|
+
self.establish_connection(:hypertable)
|
19
|
+
|
20
|
+
# mutator_options :persistent => true, :flush_interval => 100
|
21
|
+
|
22
|
+
def self.create_table
|
23
|
+
hql = "CREATE TABLE #{table_name} (
|
24
|
+
'name',
|
25
|
+
'url'
|
26
|
+
)"
|
27
|
+
connection.execute(hql)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class QualifiedPage < ActiveRecord::HyperBase
|
32
|
+
self.establish_connection(:hypertable)
|
33
|
+
qualified_column :misc, :qualifiers => [:name, :url]
|
34
|
+
qualified_column :misc2, :qualifiers => [:foo, :bar]
|
35
|
+
|
36
|
+
def self.create_table
|
37
|
+
hql = "CREATE TABLE #{table_name} (
|
38
|
+
'misc',
|
39
|
+
'misc2'
|
40
|
+
)"
|
41
|
+
connection.execute(hql)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class QualifiedPageWithoutExplicitQualifiers < ActiveRecord::HyperBase
|
46
|
+
QualifiedPageWithoutExplicitQualifiers.set_table_name "qualified_pages"
|
47
|
+
self.establish_connection(:hypertable)
|
48
|
+
qualified_column :misc
|
49
|
+
|
50
|
+
def self.create_table
|
51
|
+
QualifiedPage.create_table
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
Spec::Runner.configure do |config|
|
56
|
+
# If you're not using ActiveRecord you should remove these
|
57
|
+
# lines, delete config/database.yml and disable :active_record
|
58
|
+
# in your config/boot.rb
|
59
|
+
config.use_transactional_fixtures = false
|
60
|
+
config.use_instantiated_fixtures = false
|
61
|
+
config.fixture_path = File.expand_path(File.join(File.dirname(__FILE__), 'fixtures'))
|
62
|
+
|
63
|
+
# == Fixtures
|
64
|
+
#
|
65
|
+
# You can declare fixtures for each example_group like this:
|
66
|
+
# describe "...." do
|
67
|
+
# fixtures :table_a, :table_b
|
68
|
+
#
|
69
|
+
# Alternatively, if you prefer to declare them only once, you can
|
70
|
+
# do so right here. Just uncomment the next line and replace the fixture
|
71
|
+
# names with your fixtures.
|
72
|
+
#
|
73
|
+
config.global_fixtures = []
|
74
|
+
|
75
|
+
#
|
76
|
+
# If you declare global fixtures, be aware that they will be declared
|
77
|
+
# for all of your examples, even those that don't use them.
|
78
|
+
#
|
79
|
+
# == Mock Framework
|
80
|
+
#
|
81
|
+
# RSpec uses it's own mocking framework by default. If you prefer to
|
82
|
+
# use mocha, flexmock or RR, uncomment the appropriate line:
|
83
|
+
#
|
84
|
+
# config.mock_with :mocha
|
85
|
+
# config.mock_with :flexmock
|
86
|
+
# config.mock_with :rr
|
87
|
+
end
|
88
|
+
|
89
|
+
class Fixtures
|
90
|
+
def self.create_fixtures(fixtures_directory, table_names, class_names = {})
|
91
|
+
Page.drop_table
|
92
|
+
Page.create_table
|
93
|
+
QualifiedPage.drop_table
|
94
|
+
QualifiedPage.create_table
|
95
|
+
|
96
|
+
table_names = [table_names].flatten.map { |n| n.to_s }
|
97
|
+
connection = block_given? ? yield : ActiveRecord::Base.connection
|
98
|
+
|
99
|
+
table_names_to_fetch = table_names.reject { |table_name| fixture_is_cached?(connection, table_name) }
|
100
|
+
|
101
|
+
unless table_names_to_fetch.empty?
|
102
|
+
ActiveRecord::Base.silence do
|
103
|
+
connection.disable_referential_integrity do
|
104
|
+
fixtures_map = {}
|
105
|
+
|
106
|
+
fixtures = table_names_to_fetch.map do |table_name|
|
107
|
+
fixtures_map[table_name] = Fixtures.new(connection, File.split(table_name.to_s).last, class_names[table_name.to_sym], File.join(fixtures_directory, table_name.to_s))
|
108
|
+
end
|
109
|
+
|
110
|
+
all_loaded_fixtures.update(fixtures_map)
|
111
|
+
|
112
|
+
connection.transaction(:requires_new => true) do
|
113
|
+
#fixtures.reverse.each {|fixture| fixture.delete_existing_fixtures}
|
114
|
+
fixtures.each {|fixture| fixture.insert_fixtures}
|
115
|
+
|
116
|
+
# Cap primary key sequences to max(pk).
|
117
|
+
if connection.respond_to?(:reset_pk_sequence!)
|
118
|
+
table_names.each do |table_name|
|
119
|
+
connection.reset_pk_sequence!(table_name)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
cache_fixtures(connection, fixtures_map)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
cached_fixtures(connection, table_names)
|
129
|
+
end
|
130
|
+
end
|