active_record-mti 0.0.7 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +1 -1
- data/active_record-mti.gemspec +3 -2
- data/lib/active_record/mti.rb +7 -5
- data/lib/active_record/mti/calculations.rb +2 -2
- data/lib/active_record/mti/connection_adapters/postgresql/adapter.rb +30 -0
- data/lib/active_record/mti/inheritance.rb +21 -4
- data/lib/active_record/mti/model_schema.rb +37 -2
- data/lib/active_record/mti/query_methods.rb +1 -1
- data/lib/active_record/mti/version.rb +1 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 184ec1c49f5ccb8a375f7780684e265bb4132b13
|
4
|
+
data.tar.gz: 74679030c66bf141020f7e58c4aed0597cc83dd6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9e9d8a6e8f9b116529d648bed2893e8cf85f5c479791362d5dcd903fd502d012557dc8f1f46c4953e4fe0a2c6a982197efa3bf3bc52f46c8661adf788026bbb3
|
7
|
+
data.tar.gz: b78dac12e338c6cb5d236efb59486b34dae3280902097b5daa03eb297513ab9eaff8e61619cec283c97acc56b818ad6e411460bd5fd42d4ade2f6e0b59c705e4
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/active_record-mti.gemspec
CHANGED
@@ -37,7 +37,8 @@ Gem::Specification.new do |spec|
|
|
37
37
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
38
38
|
spec.add_development_dependency 'rake', '~> 10.0'
|
39
39
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
40
|
-
spec.add_development_dependency
|
41
|
-
spec.add_development_dependency
|
40
|
+
spec.add_development_dependency 'simplecov', ['>= 0.9.0', '<1.0.0']
|
41
|
+
spec.add_development_dependency 'codeclimate-test-reporter', '~> 1.0'
|
42
|
+
spec.add_development_dependency 'database_cleaner', '~> 1.6'
|
42
43
|
|
43
44
|
end
|
data/lib/active_record/mti.rb
CHANGED
@@ -7,6 +7,7 @@ require 'active_record/mti/model_schema'
|
|
7
7
|
require 'active_record/mti/query_methods'
|
8
8
|
require 'active_record/mti/calculations'
|
9
9
|
require 'active_record/mti/connection_adapters/postgresql/schema_statements'
|
10
|
+
require 'active_record/mti/connection_adapters/postgresql/adapter'
|
10
11
|
|
11
12
|
require 'active_record/mti/railtie' if defined?(Rails::Railtie)
|
12
13
|
|
@@ -18,12 +19,13 @@ module ActiveRecord
|
|
18
19
|
end
|
19
20
|
|
20
21
|
def self.load
|
21
|
-
::ActiveRecord::Base.send
|
22
|
-
::ActiveRecord::Base.send
|
23
|
-
::ActiveRecord::Relation.send
|
24
|
-
::ActiveRecord::Relation.send
|
22
|
+
::ActiveRecord::Base.send :include, Inheritance
|
23
|
+
::ActiveRecord::Base.send :include, ModelSchema
|
24
|
+
::ActiveRecord::Relation.send :include, QueryMethods
|
25
|
+
::ActiveRecord::Relation.send :include, Calculations
|
26
|
+
::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send :prepend, ConnectionAdapters::PostgreSQL::Adapter
|
25
27
|
::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send :include, ConnectionAdapters::PostgreSQL::SchemaStatements
|
26
|
-
::ActiveRecord::SchemaDumper.send
|
28
|
+
::ActiveRecord::SchemaDumper.send :include, SchemaDumper
|
27
29
|
end
|
28
30
|
end
|
29
31
|
end
|
@@ -52,7 +52,7 @@ module ActiveRecord
|
|
52
52
|
relation.select_values = select_values
|
53
53
|
|
54
54
|
# Remove our cast otherwise PSQL will insist that it be included in the GROUP
|
55
|
-
relation.arel.projections.select!{ |p| p.to_s !=
|
55
|
+
relation.arel.projections.select!{ |p| p.to_s != tableoid_cast(klass) } if @klass.using_multi_table_inheritance?
|
56
56
|
|
57
57
|
calculated_data = @klass.connection.select_all(relation, nil, relation.arel.bind_values + bind_values)
|
58
58
|
|
@@ -102,7 +102,7 @@ module ActiveRecord
|
|
102
102
|
|
103
103
|
# Remove our cast otherwise PSQL will insist that it be included in the GROUP
|
104
104
|
# Somewhere between line 82 and 101 relation.arel.projections gets reset :/
|
105
|
-
relation.arel.projections.select!{ |p| p.to_s !=
|
105
|
+
relation.arel.projections.select!{ |p| p.to_s != tableoid_cast(klass) } if @klass.using_multi_table_inheritance?
|
106
106
|
|
107
107
|
query_builder = relation.arel
|
108
108
|
bind_values = query_builder.bind_values + relation.bind_values
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module MTI
|
3
|
+
module ConnectionAdapters
|
4
|
+
module PostgreSQL
|
5
|
+
module Adapter
|
6
|
+
|
7
|
+
def version
|
8
|
+
Gem::Version.new exec_query(<<-SQL, 'SCHEMA').rows.first.first
|
9
|
+
SHOW server_version;
|
10
|
+
SQL
|
11
|
+
end
|
12
|
+
|
13
|
+
def column_definitions(table_name) # :nodoc:
|
14
|
+
exec_query(<<-SQL, 'SCHEMA').rows
|
15
|
+
SELECT a.attname, format_type(a.atttypid, a.atttypmod),
|
16
|
+
pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod
|
17
|
+
FROM pg_attribute a LEFT JOIN pg_attrdef d
|
18
|
+
ON a.attrelid = d.adrelid AND a.attnum = d.adnum
|
19
|
+
WHERE a.attrelid = '#{quote_table_name(table_name)}'::regclass
|
20
|
+
AND a.attnum > 0 AND NOT a.attisdropped
|
21
|
+
AND a.attname != 'tableoid'
|
22
|
+
ORDER BY a.attnum
|
23
|
+
SQL
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -34,12 +34,13 @@ module ActiveRecord
|
|
34
34
|
module ClassMethods
|
35
35
|
|
36
36
|
def inherited(child)
|
37
|
-
child.uses_mti if self.uses_mti?
|
38
37
|
super
|
39
38
|
end
|
40
39
|
|
41
|
-
def uses_mti
|
42
|
-
self.
|
40
|
+
def uses_mti(table_name = nil, inheritance_column = nil)
|
41
|
+
# self.table_name ||= table_name
|
42
|
+
self.inheritance_column = inheritance_column
|
43
|
+
|
43
44
|
@uses_mti = true
|
44
45
|
end
|
45
46
|
|
@@ -48,11 +49,27 @@ module ActiveRecord
|
|
48
49
|
end
|
49
50
|
|
50
51
|
def uses_mti?
|
51
|
-
@uses_mti ||=
|
52
|
+
@uses_mti ||= check_inheritence_of(@table_name)
|
52
53
|
end
|
53
54
|
|
54
55
|
private
|
55
56
|
|
57
|
+
def check_inheritence_of(table_name)
|
58
|
+
return nil unless table_name
|
59
|
+
|
60
|
+
result = connection.execute <<-SQL
|
61
|
+
SELECT EXISTS ( SELECT 1
|
62
|
+
FROM pg_catalog.pg_inherits
|
63
|
+
WHERE inhrelid = 'public.#{table_name}'::regclass::oid
|
64
|
+
OR inhparent = 'public.#{table_name}'::regclass::oid);
|
65
|
+
SQL
|
66
|
+
|
67
|
+
# Some versions of PSQL return {"?column?"=>"t"}
|
68
|
+
# instead of {"first"=>"t"}, so we're saying screw it,
|
69
|
+
# just give me the first value of whatever is returned
|
70
|
+
result.try(:first).try(:values).try(:first) == 't'
|
71
|
+
end
|
72
|
+
|
56
73
|
# Called by +instantiate+ to decide which class to use for a new
|
57
74
|
# record instance. For single-table inheritance, we check the record
|
58
75
|
# for a +type+ column and return the corresponding class.
|
@@ -8,16 +8,51 @@ module ActiveRecord
|
|
8
8
|
|
9
9
|
# Computes the table name, (re)sets it internally, and returns it.
|
10
10
|
def reset_table_name #:nodoc:
|
11
|
-
# binding.pry
|
12
11
|
self.table_name = if abstract_class?
|
13
12
|
superclass == Base ? nil : superclass.table_name
|
14
|
-
elsif superclass.abstract_class
|
13
|
+
elsif superclass.abstract_class?# || superclass.using_multi_table_inheritance?
|
15
14
|
superclass.table_name || compute_table_name
|
16
15
|
else
|
17
16
|
compute_table_name
|
18
17
|
end
|
19
18
|
end
|
20
19
|
|
20
|
+
# Computes and returns a table name according to default conventions.
|
21
|
+
def compute_table_name
|
22
|
+
base = base_class
|
23
|
+
if self == base
|
24
|
+
# Nested classes are prefixed with singular parent table name.
|
25
|
+
if parent < Base && !parent.abstract_class?
|
26
|
+
contained = parent.table_name
|
27
|
+
contained = contained.singularize if parent.pluralize_table_names
|
28
|
+
contained += '_'
|
29
|
+
end
|
30
|
+
|
31
|
+
"#{full_table_name_prefix}#{contained}#{undecorated_table_name(name)}#{full_table_name_suffix}"
|
32
|
+
elsif uses_mti?
|
33
|
+
|
34
|
+
# Nested classes are prefixed with singular parent table name.
|
35
|
+
if superclass < Base && !superclass.abstract_class?
|
36
|
+
contained = superclass.table_name
|
37
|
+
contained = contained.singularize if superclass.pluralize_table_names
|
38
|
+
contained += '/'
|
39
|
+
end
|
40
|
+
|
41
|
+
"#{full_table_name_prefix}#{contained}#{decorated_table_name(name)}#{full_table_name_suffix}"
|
42
|
+
else
|
43
|
+
# STI subclasses always use their superclass' table.
|
44
|
+
superclass.table_name
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
# Guesses the table name, but does not decorate it with prefix and suffix information.
|
51
|
+
def decorated_table_name(class_name = base_class.name)
|
52
|
+
table_name = class_name.to_s.underscore
|
53
|
+
pluralize_table_names ? table_name.pluralize : table_name
|
54
|
+
end
|
55
|
+
|
21
56
|
end
|
22
57
|
end
|
23
58
|
end
|
@@ -18,7 +18,7 @@ module ActiveRecord
|
|
18
18
|
def tableoid_cast(klass)
|
19
19
|
# Arel::Nodes::NamedFunction.new('CAST', [klass.arel_table[:tableoid].as('regclass')])
|
20
20
|
# Arel::Nodes::NamedFunction.new('CAST', [@klass.arel_table['tableoid::regclass'].as('regclass')])
|
21
|
-
"CAST(\"#{klass.table_name}\".\"tableoid\"::regclass AS text)"
|
21
|
+
"TRIM(BOTH '\"' FROM CAST(\"#{klass.table_name}\".\"tableoid\"::regclass AS text)) AS tableoid"
|
22
22
|
end
|
23
23
|
|
24
24
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_record-mti
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dale Stevens
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-05-
|
11
|
+
date: 2017-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pg
|
@@ -134,6 +134,20 @@ dependencies:
|
|
134
134
|
- - "~>"
|
135
135
|
- !ruby/object:Gem::Version
|
136
136
|
version: '1.0'
|
137
|
+
- !ruby/object:Gem::Dependency
|
138
|
+
name: database_cleaner
|
139
|
+
requirement: !ruby/object:Gem::Requirement
|
140
|
+
requirements:
|
141
|
+
- - "~>"
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: '1.6'
|
144
|
+
type: :development
|
145
|
+
prerelease: false
|
146
|
+
version_requirements: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - "~>"
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '1.6'
|
137
151
|
description: Allows use of native inherited tables in PostgreSQL
|
138
152
|
email:
|
139
153
|
- dale@twilightcoders.net
|
@@ -151,6 +165,7 @@ files:
|
|
151
165
|
- active_record-mti.gemspec
|
152
166
|
- lib/active_record/mti.rb
|
153
167
|
- lib/active_record/mti/calculations.rb
|
168
|
+
- lib/active_record/mti/connection_adapters/postgresql/adapter.rb
|
154
169
|
- lib/active_record/mti/connection_adapters/postgresql/schema_statements.rb
|
155
170
|
- lib/active_record/mti/inheritance.rb
|
156
171
|
- lib/active_record/mti/model_schema.rb
|