pg_inheritance 0.1.0 → 0.1.1

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
  SHA256:
3
- metadata.gz: 3454653b6ac4bb6e19903d97a2b11152633aa1144bb0cd20057d78a4a159d450
4
- data.tar.gz: cb3b501bc727184aa24a9e6ad709393ce9176064e1b54c9b10067f1a5a63b174
3
+ metadata.gz: 78df89fa727c1c8148e62de7f68cd62551c194b8d8052e1ffbfbce7c55a2c0d8
4
+ data.tar.gz: 6da79709df0ea92f719a3728ef71c0f164d54928e17f31cf80eea762caed1bb7
5
5
  SHA512:
6
- metadata.gz: a0949d2e040c91860a5af00bae171f5882b07ef217dce52b4d33533340368abee6eacbe0075e28d665e630d7cab4786c7c75b5b5d19b5043e1eeab240cc65fff
7
- data.tar.gz: bf92d2c81ad011834e44fd14a04ce1334d2fade2205d3f2b31d714fdb87a0ad81df4772bbbf059ee2ed17bd71456537507313345d7bd6b929c46658f7ac720ca
6
+ metadata.gz: f0d417385e9a064b20f4019674963a333a570e1dd5f9376ec8a8e3bad881d14687cb0ac87a6462f27b842d6eb4468660896390c7dc420b18295cb3e18d47def6
7
+ data.tar.gz: c7b9757f36549c722977cbd8cd967f1d8ca2249374db1e1ac5e41e1f584671f8af9b1991fcc452b964f7e6fa274801f162d78415cbdb350e8c446831c9dd13cd
data/.gitignore CHANGED
@@ -9,3 +9,5 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+
13
+ *.gem
data/README.md CHANGED
@@ -1,10 +1,21 @@
1
1
  # PG Inheritance
2
- [![Build Status](https://travis-ci.com/sigmen/pg_inheritance.svg?branch=master)](https://travis-ci.com/sigmen/pg_inheritance)
2
+ [![Gem Version](https://badge.fury.io/rb/pg_inheritance.svg)](https://badge.fury.io/rb/pg_inheritance) [![Build Status](https://travis-ci.com/sigmen/pg_inheritance.svg?branch=master)](https://travis-ci.com/sigmen/pg_inheritance)
3
3
 
4
4
  # UNDER DEVELOPMENT
5
5
 
6
- ### Supported ORM
7
- * ActiveRecord 6.0+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'pg_inheritance'
11
+
12
+ And then execute:
13
+
14
+ $ bundle install
15
+
16
+ Or install with:
17
+
18
+ $ gem install pg_inheritance
8
19
 
9
20
  ### Migrations
10
21
 
@@ -17,7 +28,7 @@ class CreateMembers < ActiveRecord::Migration
17
28
  t.string :name
18
29
  end
19
30
 
20
- create_table :members, inherited_from: :users do |t|
31
+ create_table :members, inherits: :users do |t|
21
32
  t.string :logo_url
22
33
  end
23
34
  end
@@ -1,6 +1,10 @@
1
+ require 'pg_inheritance/active_record/parentable'
2
+
1
3
  module PGInheritance
2
4
  module ActiveRecord
3
5
  module Inheritable
6
+ include PGInheritance::ActiveRecord::Parentable
7
+
4
8
  def drop_inheritance(table_name, parent_name)
5
9
  unless inherited?(table_name, parent_name)
6
10
  raise PGInheritance::TableNotInheritedError, "#{table_name} not inherited from #{parent_name}"
@@ -12,26 +16,12 @@ module PGInheritance
12
16
  private
13
17
 
14
18
  def inherited?(table_name, parent_name)
15
- table_parents(table_name).any? { |x| x['relname'] == parent_name.to_s }
16
- end
17
-
18
- def table_parents(table_name)
19
- execute(select_parents_query(table_name))
19
+ parent_table(table_name) == parent_name.to_s
20
20
  end
21
21
 
22
22
  def drop_inheritance_query(table_name, parent_name)
23
23
  "ALTER TABLE #{table_name} NO INHERIT #{parent_name};"
24
24
  end
25
-
26
- def select_parents_query(table_name)
27
- <<-SQL
28
- SELECT pg_namespace.nspname, pg_class.relname
29
- FROM pg_catalog.pg_inherits
30
- INNER JOIN pg_catalog.pg_class ON (pg_inherits.inhparent = pg_class.oid)
31
- INNER JOIN pg_catalog.pg_namespace ON (pg_class.relnamespace = pg_namespace.oid)
32
- WHERE inhrelid = '#{table_name}'::regclass
33
- SQL
34
- end
35
25
  end
36
26
  end
37
27
  end
@@ -0,0 +1,26 @@
1
+ module PGInheritance
2
+ module ActiveRecord
3
+ module Parentable
4
+ def parent_table(table_name)
5
+ result = execute(select_parents_query(table_name))
6
+
7
+ return unless result.any?
8
+
9
+ result.first['relname']
10
+ end
11
+
12
+ private
13
+
14
+ def select_parents_query(table_name)
15
+ <<-SQL
16
+ SELECT pg_namespace.nspname, pg_class.relname
17
+ FROM pg_catalog.pg_inherits
18
+ INNER JOIN pg_catalog.pg_class ON (pg_inherits.inhparent = pg_class.oid)
19
+ INNER JOIN pg_catalog.pg_namespace ON (pg_class.relnamespace = pg_namespace.oid)
20
+ WHERE inhrelid = '#{table_name}'::regclass
21
+ LIMIT 1
22
+ SQL
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,72 @@
1
+ module PGInheritance
2
+ module ActiveRecord
3
+ module SchemaDumper
4
+ def table(child_table, stream)
5
+ return if dumped_tables.include?(child_table)
6
+
7
+ new_stream = StringIO.new
8
+
9
+ super(child_table, new_stream)
10
+
11
+ string = new_stream.string
12
+ parent_table = @connection.parent_table(child_table)
13
+
14
+ if parent_table
15
+ string = handle_parent(parent_table, child_table, stream, string)
16
+ end
17
+
18
+ dumped_tables << child_table
19
+
20
+ stream.tap { |s| s.write(string) }
21
+ end
22
+
23
+ private
24
+
25
+ def dumped_tables
26
+ @dumped_tables ||= []
27
+ end
28
+
29
+ def handle_parent(parent_table, child_table, stream, string)
30
+ table(parent_table, stream)
31
+
32
+ string = inject_inherits_for_create_table(string, child_table, parent_table)
33
+ string = remove_parent_table_columns(string, @connection.columns(parent_table))
34
+
35
+ parent_indexes = @connection.indexes(parent_table).map { |index| [index.name, index] }.to_h
36
+ child_indexes = @connection.indexes(child_table).map { |index| [index.name, index] }.to_h
37
+
38
+ intersected_index_names = parent_indexes.keys & child_indexes.keys
39
+
40
+ remove_parent_table_indexes(string, parent_indexes.slice(*intersected_index_names))
41
+ end
42
+
43
+ def inject_inherits_for_create_table(string, table, parent_table)
44
+ tbl_start = "create_table #{remove_prefix_and_suffix(table).inspect}"
45
+ tbl_end = ' do |t|'
46
+ tbl_inherit = ", inherits: '#{parent_table}'"
47
+
48
+ string.gsub!(/#{Regexp.escape(tbl_start)}.*#{Regexp.escape(tbl_end)}/, tbl_start + tbl_inherit + tbl_end)
49
+ end
50
+
51
+ def remove_parent_table_columns(string, columns)
52
+ columns.each do |col|
53
+ string.gsub!(/\s+t\.\w+\s+("|')#{col.name}("|').*/, '')
54
+ end
55
+
56
+ string
57
+ end
58
+
59
+ def remove_parent_table_indexes(string, indexes)
60
+ indexes.each do |index|
61
+ string.gsub!(/\s+t\.index.*("|')#{index.name}("|').*/, '')
62
+ end
63
+
64
+ string
65
+ end
66
+
67
+ def remove_prefix_and_suffix(table)
68
+ table.gsub(/^(#{::ActiveRecord::Base.table_name_prefix})(.+)(#{::ActiveRecord::Base.table_name_suffix})$/, '\\2')
69
+ end
70
+ end
71
+ end
72
+ end
@@ -5,10 +5,12 @@ module PGInheritance
5
5
  module SchemaStatements
6
6
  include PGInheritance::ActiveRecord::Inheritable
7
7
 
8
+ INDEX_OPTIONS = %i[unique using where orders name].freeze
9
+
8
10
  def create_table(table_name, options = {})
9
- inherited_table = options.delete(:inherited_from)
11
+ parent_table = options.delete(:inherits)
10
12
 
11
- prepare_options(inherited_table, options)
13
+ prepare_options(parent_table, options)
12
14
 
13
15
  table_name = prepare_table_name(table_name, options)
14
16
 
@@ -23,7 +25,7 @@ module PGInheritance
23
25
  end
24
26
 
25
27
  def remove_pk_option(options)
26
- return unless options[:inherited_from]
28
+ return unless options[:inherits]
27
29
 
28
30
  options[:id] = false
29
31
  options.delete(:primary_key)
@@ -1,4 +1,5 @@
1
1
  require 'pg_inheritance/active_record/schema_statements'
2
+ require 'pg_inheritance/active_record/schema_dumper'
2
3
 
3
4
  module PGInheritance
4
5
  class Railtie < Rails::Railtie
@@ -7,6 +8,8 @@ module PGInheritance
7
8
  adapter_klass = ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
8
9
 
9
10
  adapter_klass.prepend(PGInheritance::ActiveRecord::SchemaStatements)
11
+
12
+ ::ActiveRecord::SchemaDumper.prepend(PGInheritance::ActiveRecord::SchemaDumper)
10
13
  end
11
14
  end
12
15
  end
@@ -1,3 +1,3 @@
1
1
  module PGInheritance
2
- VERSION = '0.1.0'.freeze
2
+ VERSION = '0.1.1'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg_inheritance
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roman Kakorin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-14 00:00:00.000000000 Z
11
+ date: 2020-05-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -73,6 +73,8 @@ files:
73
73
  - bin/setup
74
74
  - lib/pg_inheritance.rb
75
75
  - lib/pg_inheritance/active_record/inheritable.rb
76
+ - lib/pg_inheritance/active_record/parentable.rb
77
+ - lib/pg_inheritance/active_record/schema_dumper.rb
76
78
  - lib/pg_inheritance/active_record/schema_statements.rb
77
79
  - lib/pg_inheritance/railtie.rb
78
80
  - lib/pg_inheritance/version.rb