active_table 0.0.1 → 0.0.2
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/lib/active_record/connection_adapters/abstract/connection_pool_extensions.rb +2 -0
- data/lib/active_record/connection_adapters/abstract_adapter_extensions.rb +12 -0
- data/lib/active_record/connection_adapters/sqlite_adapter_extensions.rb +15 -0
- data/lib/active_table/base.rb +16 -0
- data/lib/active_table/version.rb +1 -1
- data/lib/active_table.rb +3 -0
- data/spec/active_table_spec.rb +88 -18
- metadata +6 -4
@@ -0,0 +1,12 @@
|
|
1
|
+
ActiveRecord::ConnectionAdapters::AbstractAdapter.class_eval do
|
2
|
+
def mark_active_table_as_loaded(table_name)
|
3
|
+
@active_tables_loaded ||= []
|
4
|
+
@active_tables_loaded << table_name
|
5
|
+
end
|
6
|
+
|
7
|
+
def active_table_loaded_for?(table_name)
|
8
|
+
return false if @active_tables_loaded.blank?
|
9
|
+
@active_tables_loaded.include?(table_name)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
ActiveRecord::ConnectionAdapters::SQLiteAdapter.class_eval do
|
2
|
+
def tables(name = nil) #:nodoc:
|
3
|
+
sql = <<-SQL
|
4
|
+
SELECT name FROM sqlite_master
|
5
|
+
WHERE type = 'table' AND NOT name = 'sqlite_sequence'
|
6
|
+
UNION
|
7
|
+
SELECT name FROM sqlite_temp_master
|
8
|
+
WHERE type = 'table' AND NOT name = 'sqlite_sequence'
|
9
|
+
SQL
|
10
|
+
|
11
|
+
execute(sql, name).map do |row|
|
12
|
+
row['name']
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/active_table/base.rb
CHANGED
@@ -1,8 +1,18 @@
|
|
1
1
|
module ActiveTable
|
2
2
|
class Base < ActiveRecord::Base
|
3
3
|
@@tables = {}
|
4
|
+
def self.active_table(&block)
|
5
|
+
block.call
|
6
|
+
ActiveRecord::Base.connection_pool.connections.each do |connection|
|
7
|
+
create_tables(connection)
|
8
|
+
end
|
9
|
+
self.reset_column_information
|
10
|
+
self.define_attribute_methods
|
11
|
+
end
|
12
|
+
|
4
13
|
def self.create_table(name, options = {}, &block)
|
5
14
|
class_name = self.name
|
15
|
+
self.set_table_name name
|
6
16
|
@@tables[class_name] = {:name => name, :options => options, :block => block, :rows => []}
|
7
17
|
end
|
8
18
|
|
@@ -13,6 +23,7 @@ module ActiveTable
|
|
13
23
|
|
14
24
|
def self.create_tables(connection)
|
15
25
|
@@tables.each_value do |table|
|
26
|
+
next if connection.active_table_loaded_for?(table[:name])
|
16
27
|
connection.create_table table[:name], table[:options].merge(:temporary => true) do |t|
|
17
28
|
table[:block].call(t)
|
18
29
|
end
|
@@ -20,6 +31,7 @@ module ActiveTable
|
|
20
31
|
table[:rows].each do |row|
|
21
32
|
connection.execute generate_insert_sql_for_hash(connection, table[:name], row)
|
22
33
|
end
|
34
|
+
connection.mark_active_table_as_loaded(table[:name])
|
23
35
|
end
|
24
36
|
end
|
25
37
|
|
@@ -28,5 +40,9 @@ module ActiveTable
|
|
28
40
|
values = params.values.map {|v| connection.quote(v.to_s)}.join(", ")
|
29
41
|
"INSERT INTO #{connection.quote(table_name.to_s)} (#{keys}) VALUES (#{values})"
|
30
42
|
end
|
43
|
+
|
44
|
+
def self.reset_table_information
|
45
|
+
@@tables = {}
|
46
|
+
end
|
31
47
|
end
|
32
48
|
end
|
data/lib/active_table/version.rb
CHANGED
data/lib/active_table.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
require 'active_record'
|
2
2
|
require 'active_record/connection_adapters/abstract_adapter'
|
3
|
+
require 'active_record/connection_adapters/abstract_adapter_extensions'
|
4
|
+
require 'active_record/connection_adapters/sqlite_adapter'
|
5
|
+
require 'active_record/connection_adapters/sqlite_adapter_extensions'
|
3
6
|
require 'active_record/connection_adapters/abstract/connection_pool_extensions'
|
4
7
|
require 'active_table/base'
|
data/spec/active_table_spec.rb
CHANGED
@@ -1,23 +1,83 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe "a
|
3
|
+
describe "a model created with active_table" do
|
4
4
|
before(:each) do
|
5
5
|
@connection_pool = ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ":memory:")
|
6
6
|
end
|
7
7
|
|
8
8
|
after(:each) do
|
9
9
|
@connection_pool.disconnect!
|
10
|
+
ActiveTable::Base.reset_table_information
|
10
11
|
end
|
11
12
|
|
12
13
|
it "should inherit from ActiveRecord::Base" do
|
13
14
|
ActiveTable::Base.superclass.should == ActiveRecord::Base
|
14
15
|
end
|
15
16
|
|
17
|
+
it "should behave like an ActiveRecord model" do
|
18
|
+
class TemporaryModel < ActiveTable::Base
|
19
|
+
active_table do
|
20
|
+
create_table :temporary_models do |t|
|
21
|
+
t.string :name
|
22
|
+
end
|
23
|
+
|
24
|
+
insert :id => 1, :name => "foo"
|
25
|
+
insert :id => 4, :name => "baz"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
connection = @connection_pool.connection
|
30
|
+
|
31
|
+
TemporaryModel.count.should == 2
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should only create the table once for a given connection" do
|
35
|
+
connection = @connection_pool.checkout
|
36
|
+
|
37
|
+
connection.active_table_loaded_for?(:temporary_models).should be_false
|
38
|
+
|
39
|
+
class TemporaryModel < ActiveTable::Base
|
40
|
+
active_table do
|
41
|
+
create_table :temporary_models do |t|
|
42
|
+
t.string :name
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
ActiveTable::Base.create_tables(connection)
|
48
|
+
connection.active_table_loaded_for?(:temporary_models).should be_true
|
49
|
+
|
50
|
+
lambda {
|
51
|
+
ActiveTable::Base.create_tables(connection)
|
52
|
+
}.should_not raise_error
|
53
|
+
end
|
54
|
+
|
55
|
+
context "#active_table" do
|
56
|
+
it "should perform oprerations immediately and correctly reload attributes" do
|
57
|
+
connection = @connection_pool.checkout
|
58
|
+
|
59
|
+
lambda {
|
60
|
+
class TemporaryModel < ActiveTable::Base
|
61
|
+
active_table do
|
62
|
+
self.table_name = "temporary_models"
|
63
|
+
create_table :temporary_models do |t|
|
64
|
+
t.string :name
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
alias_method :foo, :name
|
69
|
+
end
|
70
|
+
}.should_not raise_error
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
16
74
|
context "when a connection is opened" do
|
17
75
|
it "should create a table from its model definition" do
|
18
76
|
class TemporaryModel < ActiveTable::Base
|
19
|
-
|
20
|
-
|
77
|
+
active_table do
|
78
|
+
create_table :temporary_models do |t|
|
79
|
+
t.string :name
|
80
|
+
end
|
21
81
|
end
|
22
82
|
end
|
23
83
|
|
@@ -30,14 +90,18 @@ describe "a temporary ActiveRecord model created with with_model" do
|
|
30
90
|
|
31
91
|
it "should create multiple tables at the same time" do
|
32
92
|
class TemporaryModel < ActiveTable::Base
|
33
|
-
|
34
|
-
|
93
|
+
active_table do
|
94
|
+
create_table :temporary_models do |t|
|
95
|
+
t.string :name
|
96
|
+
end
|
35
97
|
end
|
36
98
|
end
|
37
99
|
|
38
100
|
class TemporaryModelTwo < ActiveTable::Base
|
39
|
-
|
40
|
-
|
101
|
+
active_table do
|
102
|
+
create_table :temporary_models_two do |t|
|
103
|
+
t.string :name
|
104
|
+
end
|
41
105
|
end
|
42
106
|
end
|
43
107
|
|
@@ -51,12 +115,14 @@ describe "a temporary ActiveRecord model created with with_model" do
|
|
51
115
|
|
52
116
|
it "should insert rows of data specified within the model" do
|
53
117
|
class TemporaryModel < ActiveTable::Base
|
54
|
-
|
55
|
-
|
56
|
-
|
118
|
+
active_table do
|
119
|
+
create_table :temporary_models do |t|
|
120
|
+
t.string :name
|
121
|
+
end
|
57
122
|
|
58
|
-
|
59
|
-
|
123
|
+
insert :id => 1, :name => "foo"
|
124
|
+
insert :id => 4, :name => "baz"
|
125
|
+
end
|
60
126
|
end
|
61
127
|
|
62
128
|
connection = @connection_pool.connection
|
@@ -70,11 +136,13 @@ describe "a temporary ActiveRecord model created with with_model" do
|
|
70
136
|
context "when inserting data" do
|
71
137
|
it "should handle apostrophes without blowing up" do
|
72
138
|
class TemporaryModel < ActiveTable::Base
|
73
|
-
|
74
|
-
|
75
|
-
|
139
|
+
active_table do
|
140
|
+
create_table :temporary_models do |t|
|
141
|
+
t.string :name
|
142
|
+
end
|
76
143
|
|
77
|
-
|
144
|
+
insert :id => 1, :name => "foo's the boss?"
|
145
|
+
end
|
78
146
|
end
|
79
147
|
|
80
148
|
connection = @connection_pool.connection
|
@@ -86,8 +154,10 @@ describe "a temporary ActiveRecord model created with with_model" do
|
|
86
154
|
context "with multiple connections" do
|
87
155
|
it "should create a temporary table for each connection" do
|
88
156
|
class TemporaryModel < ActiveTable::Base
|
89
|
-
|
90
|
-
|
157
|
+
active_table do
|
158
|
+
create_table :temporary_models do |t|
|
159
|
+
t.string :name
|
160
|
+
end
|
91
161
|
end
|
92
162
|
end
|
93
163
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_table
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Case Commons LLC
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-06-
|
18
|
+
date: 2011-06-09 00:00:00 -04:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -60,6 +60,8 @@ files:
|
|
60
60
|
- gemfiles/rspec1/Gemfile
|
61
61
|
- gemfiles/rspec2/Gemfile
|
62
62
|
- lib/active_record/connection_adapters/abstract/connection_pool_extensions.rb
|
63
|
+
- lib/active_record/connection_adapters/abstract_adapter_extensions.rb
|
64
|
+
- lib/active_record/connection_adapters/sqlite_adapter_extensions.rb
|
63
65
|
- lib/active_table.rb
|
64
66
|
- lib/active_table/base.rb
|
65
67
|
- lib/active_table/version.rb
|