polymorpheus 2.2.0 → 3.3.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 +5 -5
- data/README.md +21 -4
- data/lib/polymorpheus.rb +8 -0
- data/lib/polymorpheus/interface/belongs_to_polymorphic.rb +4 -3
- data/lib/polymorpheus/interface_builder.rb +2 -2
- data/lib/polymorpheus/interface_builder/association.rb +4 -3
- data/lib/polymorpheus/mysql_adapter.rb +15 -25
- data/lib/polymorpheus/mysql_adapter/foreigner_constraints.rb +30 -0
- data/lib/polymorpheus/schema_dumper.rb +3 -2
- data/lib/polymorpheus/trigger.rb +21 -20
- data/lib/polymorpheus/version.rb +1 -1
- data/polymorpheus.gemspec +3 -5
- data/spec/interface/belongs_to_polymorphic_spec.rb +149 -0
- data/spec/interface/has_many_as_polymorph_spec.rb +86 -0
- data/spec/interface/validates_polymorph_spec.rb +37 -0
- data/spec/interface_spec.rb +18 -191
- data/spec/mysql2_adapter_spec.rb +271 -110
- data/spec/schema_dumper_spec.rb +16 -25
- data/spec/spec_helper.rb +34 -2
- data/spec/support/active_record/connection_adapters/abstract_mysql_adapter.rb +9 -0
- data/spec/support/class_defs.rb +32 -0
- data/spec/support/connection_helpers.rb +21 -0
- data/spec/support/custom_matchers.rb +7 -7
- data/spec/support/schema_helpers.rb +17 -0
- data/spec/{sql_logger.rb → support/sql_logger.rb} +1 -1
- data/spec/support/sql_test_helpers.rb +41 -0
- data/spec/trigger_spec.rb +32 -21
- metadata +22 -45
- data/spec/shared_examples.rb +0 -115
- data/spec/support/db_setup.rb +0 -32
data/spec/schema_dumper_spec.rb
CHANGED
@@ -1,48 +1,39 @@
|
|
1
|
-
require 'active_record'
|
2
1
|
require 'spec_helper'
|
3
|
-
require 'sql_logger'
|
4
|
-
require 'foreigner'
|
5
|
-
require 'foreigner/connection_adapters/mysql2_adapter'
|
6
|
-
require 'polymorpheus'
|
7
|
-
require 'polymorpheus/trigger'
|
8
|
-
require 'stringio'
|
9
|
-
|
10
|
-
# this is normally done via a Railtie in non-testing situations
|
11
|
-
ActiveRecord::SchemaDumper.class_eval { include Polymorpheus::SchemaDumper }
|
12
2
|
|
13
3
|
describe Polymorpheus::SchemaDumper do
|
14
|
-
|
15
4
|
let(:connection) { ActiveRecord::Base.connection }
|
16
5
|
let(:stream) { StringIO.new }
|
17
6
|
|
18
7
|
before do
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
"utf8_unicode_ci"])]
|
8
|
+
create_table :story_arcs do |t|
|
9
|
+
t.references :hero
|
10
|
+
t.references :villain
|
11
|
+
end
|
12
|
+
create_table :heros
|
13
|
+
create_table :villains
|
14
|
+
ActiveRecord::Base.connection.add_polymorphic_constraints(
|
15
|
+
'story_arcs',
|
16
|
+
{ hero_id: 'heros.id', villain_id: 'villains.id' }
|
29
17
|
)
|
30
18
|
|
31
19
|
ActiveRecord::SchemaDumper.dump(connection, stream)
|
32
20
|
end
|
33
21
|
|
22
|
+
after do
|
23
|
+
drop_table :story_arcs # drop first, due to the foreign key
|
24
|
+
end
|
25
|
+
|
34
26
|
subject { stream.string }
|
35
27
|
|
36
28
|
let(:schema_statement) do
|
37
|
-
%{ add_polymorphic_triggers(:
|
29
|
+
%{ add_polymorphic_triggers(:story_arcs, ["hero_id", "villain_id"])}
|
38
30
|
end
|
39
31
|
|
40
32
|
specify "the schema statement is part of the dump" do
|
41
|
-
subject.index(schema_statement).
|
33
|
+
expect(subject.index(schema_statement)).to be_a(Integer)
|
42
34
|
end
|
43
35
|
|
44
36
|
specify "there is exactly one instance of the schema statement" do
|
45
|
-
subject.index(schema_statement).
|
37
|
+
expect(subject.index(schema_statement)).to eq(subject.rindex(schema_statement))
|
46
38
|
end
|
47
|
-
|
48
39
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,2 +1,34 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'active_record'
|
2
|
+
require 'polymorpheus'
|
3
|
+
require 'stringio'
|
4
|
+
|
5
|
+
require 'support/active_record/connection_adapters/abstract_mysql_adapter'
|
6
|
+
|
7
|
+
ActiveRecord::Base.establish_connection({
|
8
|
+
adapter: 'mysql2',
|
9
|
+
username: 'travis',
|
10
|
+
database: 'polymorpheus_test'
|
11
|
+
})
|
12
|
+
|
13
|
+
Dir[File.dirname(__FILE__) + '/support/*.rb'].sort.each { |path| require path }
|
14
|
+
|
15
|
+
Polymorpheus::Adapter.load!
|
16
|
+
|
17
|
+
# This is normally done via a Railtie in non-testing situations.
|
18
|
+
ActiveRecord::SchemaDumper.class_eval { include Polymorpheus::SchemaDumper }
|
19
|
+
ActiveRecord::Migration.verbose = false
|
20
|
+
|
21
|
+
RSpec.configure do |config|
|
22
|
+
config.order = :random
|
23
|
+
Kernel.srand config.seed
|
24
|
+
|
25
|
+
config.include ConnectionHelpers
|
26
|
+
config.include SchemaHelpers
|
27
|
+
config.include SqlTestHelpers
|
28
|
+
|
29
|
+
config.after do
|
30
|
+
data_sources.each do |table|
|
31
|
+
ActiveRecord::Base.connection.drop_table(table)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# Patch support for MySQL 5.7+ onto ActiveRecord < 4.1.
|
2
|
+
if ActiveRecord::VERSION::MAJOR < 4 ||
|
3
|
+
(ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR < 1)
|
4
|
+
|
5
|
+
require 'active_record/connection_adapters/abstract_mysql_adapter'
|
6
|
+
class ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter
|
7
|
+
NATIVE_DATABASE_TYPES[:primary_key] = "int(11) auto_increment PRIMARY KEY"
|
8
|
+
end
|
9
|
+
end
|
data/spec/support/class_defs.rb
CHANGED
@@ -42,6 +42,11 @@ class Battle < ActiveRecord::Base
|
|
42
42
|
has_many :heros, through: :story_arcs
|
43
43
|
end
|
44
44
|
|
45
|
+
class Issue < ActiveRecord::Base
|
46
|
+
has_many :story_arcs
|
47
|
+
has_many :heros, through: :story_arcs
|
48
|
+
end
|
49
|
+
|
45
50
|
# But only super-people have superpowers
|
46
51
|
class Superpower < ActiveRecord::Base
|
47
52
|
belongs_to_polymorphic :superhero, :supervillain, as: :wielder
|
@@ -51,3 +56,30 @@ end
|
|
51
56
|
# (Unless this is LOTR, but let's ignore that for now.)
|
52
57
|
class Tree < ActiveRecord::Base
|
53
58
|
end
|
59
|
+
|
60
|
+
class Drawing < ActiveRecord::Base
|
61
|
+
belongs_to_polymorphic :book, :binder, as: :one_way_rel
|
62
|
+
end
|
63
|
+
class Book < ActiveRecord::Base
|
64
|
+
has_many_as_polymorph :drawings
|
65
|
+
end
|
66
|
+
class Binder < ActiveRecord::Base
|
67
|
+
has_many_as_polymorph :drawings
|
68
|
+
end
|
69
|
+
|
70
|
+
class Picture < ActiveRecord::Base
|
71
|
+
belongs_to_polymorphic :web_page, :printed_work, as: :inverted_rel, inverse_of: :pictures
|
72
|
+
end
|
73
|
+
class WebPage < ActiveRecord::Base
|
74
|
+
has_many_as_polymorph :pictures, inverse_of: :web_page
|
75
|
+
end
|
76
|
+
class PrintedWork < ActiveRecord::Base
|
77
|
+
has_many_as_polymorph :pictures, inverse_of: :printed_work
|
78
|
+
end
|
79
|
+
|
80
|
+
class Pet < ActiveRecord::Base
|
81
|
+
end
|
82
|
+
class Cat < ActiveRecord::Base
|
83
|
+
end
|
84
|
+
class Dog < ActiveRecord::Base
|
85
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ConnectionHelpers
|
2
|
+
def add_polymorphic_constraints(*args)
|
3
|
+
connection.add_polymorphic_constraints(*args)
|
4
|
+
end
|
5
|
+
|
6
|
+
def data_sources
|
7
|
+
if ActiveRecord::VERSION::MAJOR >= 5
|
8
|
+
ActiveRecord::Base.connection.data_sources
|
9
|
+
else
|
10
|
+
ActiveRecord::Base.connection.tables
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def remove_polymorphic_constraints(*args)
|
15
|
+
connection.remove_polymorphic_constraints(*args)
|
16
|
+
end
|
17
|
+
|
18
|
+
def triggers
|
19
|
+
connection.triggers
|
20
|
+
end
|
21
|
+
end
|
@@ -1,31 +1,31 @@
|
|
1
1
|
RSpec::Matchers.define :be_association do |association_name|
|
2
2
|
match do |actual|
|
3
|
-
actual.
|
4
|
-
actual.name.
|
3
|
+
expect(actual).to be_instance_of Polymorpheus::InterfaceBuilder::Association
|
4
|
+
expect(actual.name).to eq association_name.to_s
|
5
5
|
end
|
6
6
|
end
|
7
7
|
|
8
8
|
RSpec::Matchers.define :match_associations do |*association_names|
|
9
9
|
match do |actual|
|
10
|
-
actual.length.
|
10
|
+
expect(actual.length).to eq association_names.length
|
11
11
|
actual.each_with_index do |item, ind|
|
12
|
-
item.
|
12
|
+
expect(item).to be_association(association_names[ind])
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
RSpec::Matchers.define :match_sql do |expected|
|
18
18
|
match do |actual|
|
19
|
-
format(expected).
|
19
|
+
expect(format(expected)).to eq format(actual)
|
20
20
|
end
|
21
21
|
|
22
|
-
|
22
|
+
failure_message do |actual|
|
23
23
|
"expected the following SQL statements to match:
|
24
24
|
#{format(actual)}
|
25
25
|
#{format(expected)}"
|
26
26
|
end
|
27
27
|
|
28
28
|
def format(sql)
|
29
|
-
sql.
|
29
|
+
sql.squish
|
30
30
|
end
|
31
31
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module SchemaHelpers
|
2
|
+
def create_table(name, options = {})
|
3
|
+
options.merge!(force: true)
|
4
|
+
ActiveRecord::Schema.define do
|
5
|
+
create_table(name, options) do |t|
|
6
|
+
yield(t) if block_given?
|
7
|
+
end
|
8
|
+
end
|
9
|
+
name.to_s.classify.constantize.reset_column_information
|
10
|
+
end
|
11
|
+
|
12
|
+
def drop_table(name)
|
13
|
+
ActiveRecord::Schema.define do
|
14
|
+
drop_table(name)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module SqlTestHelpers
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
before(:all) do
|
6
|
+
class << ActiveRecord::Base.connection
|
7
|
+
include Polymorpheus::SqlLogger
|
8
|
+
alias_method :original_execute, :execute
|
9
|
+
alias_method :execute, :log_sql_statements
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
after(:all) do
|
14
|
+
class << ActiveRecord::Base.connection
|
15
|
+
alias_method :execute, :original_execute
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
let(:connection) { ActiveRecord::Base.connection }
|
20
|
+
let(:sql) { connection.sql_statements }
|
21
|
+
|
22
|
+
def clean_sql(sql_string)
|
23
|
+
sql_string
|
24
|
+
.squish
|
25
|
+
.gsub('`', '')
|
26
|
+
.gsub(/\ FOREIGN KEY/, "\nFOREIGN KEY")
|
27
|
+
.gsub(/\ REFERENCES/, "\nREFERENCES")
|
28
|
+
.gsub(/\ ON DELETE/, "\nON DELETE")
|
29
|
+
.gsub(/\ ON UPDATE/, "\nON UPDATE")
|
30
|
+
.gsub(/([[:alpha:]])\(/, '\1 (')
|
31
|
+
end
|
32
|
+
|
33
|
+
def clear_sql_history
|
34
|
+
connection.clear_sql_history
|
35
|
+
end
|
36
|
+
|
37
|
+
def should_execute_sql(expected)
|
38
|
+
expect(clean_sql(sql.join("\n"))).to include(clean_sql(expected))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/spec/trigger_spec.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
|
-
require '
|
2
|
-
require 'polymorpheus/trigger'
|
3
|
-
|
4
|
-
describe Trigger do
|
1
|
+
require 'spec_helper'
|
5
2
|
|
3
|
+
describe Polymorpheus::Trigger do
|
6
4
|
let(:name) { "pets_unique_polyfk_on_INSERT" }
|
7
5
|
let(:event) { "INSERT" }
|
8
6
|
let(:table) { "pets"}
|
@@ -21,26 +19,39 @@ describe Trigger do
|
|
21
19
|
let(:collation_connection) { "utf8_general_ci" }
|
22
20
|
let(:db_collation) { "utf8_unicode_ci" }
|
23
21
|
|
24
|
-
|
25
|
-
|
26
|
-
|
22
|
+
let(:trigger) do
|
23
|
+
described_class.new(
|
24
|
+
[
|
25
|
+
name,
|
26
|
+
event,
|
27
|
+
table,
|
28
|
+
statement,
|
29
|
+
timing,
|
30
|
+
created,
|
31
|
+
sql_mode,
|
32
|
+
definer,
|
33
|
+
charset,
|
34
|
+
collation_connection,
|
35
|
+
db_collation
|
36
|
+
]
|
37
|
+
)
|
27
38
|
end
|
28
39
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
+
specify { expect(trigger.name).to eq name }
|
41
|
+
specify { expect(trigger.event).to eq event }
|
42
|
+
specify { expect(trigger.table).to eq table }
|
43
|
+
specify { expect(trigger.statement).to eq statement }
|
44
|
+
specify { expect(trigger.timing).to eq timing }
|
45
|
+
specify { expect(trigger.created).to eq created }
|
46
|
+
specify { expect(trigger.sql_mode).to eq sql_mode }
|
47
|
+
specify { expect(trigger.definer).to eq definer }
|
48
|
+
specify { expect(trigger.charset).to eq charset }
|
49
|
+
specify { expect(trigger.collation_connection).to eq collation_connection }
|
50
|
+
specify { expect(trigger.db_collation).to eq db_collation }
|
40
51
|
|
41
|
-
|
52
|
+
specify { expect(trigger.columns).to eq %w[dog_id kitty_id] }
|
42
53
|
|
43
|
-
|
44
|
-
|
54
|
+
specify do
|
55
|
+
expect(trigger.schema_statement).to eq %{ add_polymorphic_triggers(:pets, ["dog_id", "kitty_id"])}
|
45
56
|
end
|
46
57
|
end
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: polymorpheus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Barun Singh
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-12-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: foreigner
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: activerecord
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -33,7 +19,7 @@ dependencies:
|
|
33
19
|
version: '3.2'
|
34
20
|
- - "<"
|
35
21
|
- !ruby/object:Gem::Version
|
36
|
-
version: '
|
22
|
+
version: '6.1'
|
37
23
|
type: :runtime
|
38
24
|
prerelease: false
|
39
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -43,49 +29,35 @@ dependencies:
|
|
43
29
|
version: '3.2'
|
44
30
|
- - "<"
|
45
31
|
- !ruby/object:Gem::Version
|
46
|
-
version: '
|
32
|
+
version: '6.1'
|
47
33
|
- !ruby/object:Gem::Dependency
|
48
34
|
name: rake
|
49
35
|
requirement: !ruby/object:Gem::Requirement
|
50
36
|
requirements:
|
51
37
|
- - "~>"
|
52
38
|
- !ruby/object:Gem::Version
|
53
|
-
version:
|
54
|
-
type: :development
|
55
|
-
prerelease: false
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
requirements:
|
58
|
-
- - "~>"
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
version: 10.4.2
|
61
|
-
- !ruby/object:Gem::Dependency
|
62
|
-
name: rspec-rails
|
63
|
-
requirement: !ruby/object:Gem::Requirement
|
64
|
-
requirements:
|
65
|
-
- - "~>"
|
66
|
-
- !ruby/object:Gem::Version
|
67
|
-
version: 2.14.0
|
39
|
+
version: 12.3.3
|
68
40
|
type: :development
|
69
41
|
prerelease: false
|
70
42
|
version_requirements: !ruby/object:Gem::Requirement
|
71
43
|
requirements:
|
72
44
|
- - "~>"
|
73
45
|
- !ruby/object:Gem::Version
|
74
|
-
version:
|
46
|
+
version: 12.3.3
|
75
47
|
- !ruby/object:Gem::Dependency
|
76
|
-
name:
|
48
|
+
name: rspec
|
77
49
|
requirement: !ruby/object:Gem::Requirement
|
78
50
|
requirements:
|
79
51
|
- - "~>"
|
80
52
|
- !ruby/object:Gem::Version
|
81
|
-
version:
|
53
|
+
version: 3.9.0
|
82
54
|
type: :development
|
83
55
|
prerelease: false
|
84
56
|
version_requirements: !ruby/object:Gem::Requirement
|
85
57
|
requirements:
|
86
58
|
- - "~>"
|
87
59
|
- !ruby/object:Gem::Version
|
88
|
-
version:
|
60
|
+
version: 3.9.0
|
89
61
|
description: Provides a database-friendly method for polymorphic relationships
|
90
62
|
email: bsingh@wegowise.com
|
91
63
|
executables: []
|
@@ -107,6 +79,7 @@ files:
|
|
107
79
|
- lib/polymorpheus/interface_builder.rb
|
108
80
|
- lib/polymorpheus/interface_builder/association.rb
|
109
81
|
- lib/polymorpheus/mysql_adapter.rb
|
82
|
+
- lib/polymorpheus/mysql_adapter/foreigner_constraints.rb
|
110
83
|
- lib/polymorpheus/postgresql_adapter.rb
|
111
84
|
- lib/polymorpheus/railtie.rb
|
112
85
|
- lib/polymorpheus/schema_dumper.rb
|
@@ -114,21 +87,26 @@ files:
|
|
114
87
|
- lib/polymorpheus/trigger.rb
|
115
88
|
- lib/polymorpheus/version.rb
|
116
89
|
- polymorpheus.gemspec
|
90
|
+
- spec/interface/belongs_to_polymorphic_spec.rb
|
91
|
+
- spec/interface/has_many_as_polymorph_spec.rb
|
92
|
+
- spec/interface/validates_polymorph_spec.rb
|
117
93
|
- spec/interface_spec.rb
|
118
94
|
- spec/mysql2_adapter_spec.rb
|
119
95
|
- spec/schema_dumper_spec.rb
|
120
|
-
- spec/shared_examples.rb
|
121
96
|
- spec/spec_helper.rb
|
122
|
-
- spec/
|
97
|
+
- spec/support/active_record/connection_adapters/abstract_mysql_adapter.rb
|
123
98
|
- spec/support/class_defs.rb
|
99
|
+
- spec/support/connection_helpers.rb
|
124
100
|
- spec/support/custom_matchers.rb
|
125
|
-
- spec/support/
|
101
|
+
- spec/support/schema_helpers.rb
|
102
|
+
- spec/support/sql_logger.rb
|
103
|
+
- spec/support/sql_test_helpers.rb
|
126
104
|
- spec/trigger_spec.rb
|
127
105
|
homepage: http://github.com/wegowise/polymorpheus
|
128
106
|
licenses:
|
129
107
|
- MIT
|
130
108
|
metadata: {}
|
131
|
-
post_install_message:
|
109
|
+
post_install_message:
|
132
110
|
rdoc_options: []
|
133
111
|
require_paths:
|
134
112
|
- lib
|
@@ -143,9 +121,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
143
121
|
- !ruby/object:Gem::Version
|
144
122
|
version: 1.3.6
|
145
123
|
requirements: []
|
146
|
-
|
147
|
-
|
148
|
-
signing_key:
|
124
|
+
rubygems_version: 3.1.2
|
125
|
+
signing_key:
|
149
126
|
specification_version: 4
|
150
127
|
summary: Provides a database-friendly method for polymorphic relationships
|
151
128
|
test_files: []
|