active_record-mti 0.0.7 → 0.1.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b14d2c9a38a839510f0246918f467e58e592aef4
4
- data.tar.gz: bf6e66c09163a3296f93befdbaf1fe7a3b043ad8
3
+ metadata.gz: 184ec1c49f5ccb8a375f7780684e265bb4132b13
4
+ data.tar.gz: 74679030c66bf141020f7e58c4aed0597cc83dd6
5
5
  SHA512:
6
- metadata.gz: 7fb70a3c6492b2c70dd4a95198116a9a4dc3eb2e45f66ca5be70b38d5658a38fc39742d820320091b6f3411717ee23a1fca3eb71e362a95cb8dfe7f6803537ee
7
- data.tar.gz: e1066d95c0fd0ebdf83fd7d2aded8de84c665829a71929c2e35bdb70b5b9dc7754ee4b11a1f126dac0f30f96a4440ad60fde724f813f624a8c5abc5baf6b22cf
6
+ metadata.gz: 9e9d8a6e8f9b116529d648bed2893e8cf85f5c479791362d5dcd903fd502d012557dc8f1f46c4953e4fe0a2c6a982197efa3bf3bc52f46c8661adf788026bbb3
7
+ data.tar.gz: b78dac12e338c6cb5d236efb59486b34dae3280902097b5daa03eb297513ab9eaff8e61619cec283c97acc56b818ad6e411460bd5fd42d4ade2f6e0b59c705e4
data/.gitignore CHANGED
@@ -74,3 +74,4 @@ ehthumbs.db
74
74
  Thumbs.db
75
75
  /Gemfile.lock
76
76
  /coverage
77
+ /.editorconfig
@@ -14,7 +14,7 @@ after_success:
14
14
  - bundle exec codeclimate-test-reporter
15
15
 
16
16
  addons:
17
- postgresql: "9.1"
17
+ postgresql: "9.3"
18
18
 
19
19
  env:
20
20
  - RSPEC_VERSION="<2.99"
@@ -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 "simplecov", ['>= 0.9.0', '<1.0.0']
41
- spec.add_development_dependency "codeclimate-test-reporter", "~> 1.0"
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
@@ -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 :include, Inheritance
22
- ::ActiveRecord::Base.send :include, ActiveRecord::MTI::ModelSchema
23
- ::ActiveRecord::Relation.send :include, QueryMethods
24
- ::ActiveRecord::Relation.send :include, ActiveRecord::MTI::Calculations
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 :include, ActiveRecord::MTI::SchemaDumper
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 != "CAST(\"#{klass.table_name}\".\"tableoid\"::regclass AS text)" } if @klass.using_multi_table_inheritance?
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 != "CAST(\"#{klass.table_name}\".\"tableoid\"::regclass AS text)" } if @klass.using_multi_table_inheritance?
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.inheritance_column = nil
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 ||= false
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? || superclass.using_multi_table_inheritance?
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
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module MTI
3
- VERSION = '0.0.7'
3
+ VERSION = '0.1.0'
4
4
  end
5
5
  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.7
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-10 00:00:00.000000000 Z
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