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 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