fides 0.0.10 → 0.0.11
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 +4 -4
- data/README.md +15 -12
- data/Rakefile +1 -1
- data/fides.gemspec +1 -0
- data/lib/fides/database_adapter.rb +15 -0
- data/lib/fides/database_adapter_error.rb +7 -0
- data/lib/fides/postgresql.rb +95 -0
- data/lib/fides/sql_writer.rb +15 -0
- data/lib/fides/sqlite3.rb +18 -0
- data/lib/fides/version.rb +1 -1
- data/lib/fides.rb +27 -87
- data/test/lib/fides/database_adapter_test.rb +4 -0
- data/test/lib/fides/postgresql_test.rb +78 -0
- data/test/lib/fides_test.rb +82 -0
- metadata +27 -4
- data/test/lib/fides/fides_test.rb +0 -42
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 92258eb65e77c3d3fd6881caa7fa5037e9a502d0
|
4
|
+
data.tar.gz: 688bada85c59802fa3d7bb442389f6c3ff47009a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 24558f5c56565abfe349078dab792678d820569b83430287f56408e159b544fd95ad423eaf71e5baa644dcd3b9885373049de7c4b31a2dc54358c460ff7f7cc8
|
7
|
+
data.tar.gz: 8d0d5c243156a0bd7a3301260097351e0c6b77c215a15fba32dc45ff3009fd43b3a7c84097d114e2f04877be6d1d3c5f09d50fce6a2bdb34afd34cf09b5a852f
|
data/README.md
CHANGED
@@ -1,15 +1,18 @@
|
|
1
1
|
# Fides
|
2
2
|
|
3
|
-
|
4
|
-
integrity of polymorphic associations at the database level.
|
3
|
+
Adds methods for use in Rails migrations to enforce polymorphic associations at the database level.
|
5
4
|
|
6
|
-
|
7
|
-
the existance of the referred-to model of the specified type in the other table. If it doesn't exist in
|
8
|
-
it throws a descriptive SQL exception.
|
5
|
+
### Longer Description
|
9
6
|
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
The methods that this gem exposes are for use in Rails migrations and create SQL Triggers to enforce
|
8
|
+
the data integrity of Polymorphic Associations.
|
9
|
+
|
10
|
+
The triggers are invoked by the database before an insert or update on the polymorphic table, and before
|
11
|
+
a delete on tables referred to by the polymorphic table.
|
12
|
+
|
13
|
+
If an insert/update is attempted on the polymorphic table with a record that refers to a non-existent
|
14
|
+
record in another table then a SQL error is raised. If a delete is attempted from a table that is
|
15
|
+
referred to by a record in the polymorphic table then a SQL error is raised.
|
13
16
|
|
14
17
|
## Installation
|
15
18
|
|
@@ -63,12 +66,12 @@ If you're using Rails < version 3.1, then use Fides in your migration like this:
|
|
63
66
|
|
64
67
|
end
|
65
68
|
|
66
|
-
Fides assumes the use of Rails conventions, so if there's something that needs overriding just open a
|
67
|
-
bug or shoot me a pull request.
|
68
|
-
|
69
69
|
## Caveats
|
70
70
|
|
71
|
-
Fides
|
71
|
+
Fides assumes the use of Rails conventions, so if you find a case for something that needs overriding,
|
72
|
+
please feel free to submit a bug or send a pull request.
|
73
|
+
|
74
|
+
Fides currently only functions with PostgreSQL. Please feel free to contribute other adapters as desired.
|
72
75
|
|
73
76
|
## Contributing
|
74
77
|
|
data/Rakefile
CHANGED
data/fides.gemspec
CHANGED
@@ -0,0 +1,15 @@
|
|
1
|
+
module Fides
|
2
|
+
module SqlWriter
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
def strip_non_essential_spaces(string_to_strip)
|
10
|
+
return string_to_strip.gsub(/\s{2,}|\\n/, " ").strip
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module Fides
|
2
|
+
|
3
|
+
class Postgresql
|
4
|
+
include SqlWriter
|
5
|
+
|
6
|
+
def self.get_create_function_sql(interface_name, models, polymorphic_model)
|
7
|
+
|
8
|
+
sql = "DROP FUNCTION IF EXISTS check_#{interface_name}_create_integrity() CASCADE;"
|
9
|
+
|
10
|
+
sql << %{
|
11
|
+
CREATE FUNCTION check_#{interface_name}_create_integrity() RETURNS TRIGGER AS '
|
12
|
+
BEGIN
|
13
|
+
IF NEW.#{interface_name}_type = ''#{models[0]}'' AND EXISTS (
|
14
|
+
SELECT id FROM #{models[0].constantize.table_name} WHERE id = NEW.#{interface_name}_id) THEN
|
15
|
+
RETURN NEW;
|
16
|
+
}
|
17
|
+
|
18
|
+
models[1..-1].each do |model|
|
19
|
+
sql << %{
|
20
|
+
ELSEIF NEW.#{interface_name}_type = ''#{model}'' AND EXISTS (
|
21
|
+
SELECT id FROM #{model.constantize.table_name} WHERE id = NEW.#{interface_name}_id) THEN
|
22
|
+
RETURN NEW;
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
sql << %{
|
27
|
+
ELSE
|
28
|
+
RAISE EXCEPTION ''No % model with id %.'', NEW.#{interface_name}_type, NEW.#{interface_name}_id;
|
29
|
+
RETURN NULL;
|
30
|
+
END IF;
|
31
|
+
END'
|
32
|
+
LANGUAGE plpgsql;
|
33
|
+
|
34
|
+
CREATE TRIGGER check_#{interface_name}_create_integrity_trigger
|
35
|
+
BEFORE INSERT OR UPDATE ON #{polymorphic_model.constantize.table_name}
|
36
|
+
FOR EACH ROW EXECUTE PROCEDURE check_#{interface_name}_create_integrity();
|
37
|
+
}
|
38
|
+
|
39
|
+
return strip_non_essential_spaces(sql)
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.get_delete_function_sql(interface_name, models, polymorphic_model)
|
43
|
+
polymorphic_model_table_name = polymorphic_model.constantize.table_name
|
44
|
+
|
45
|
+
sql = ""
|
46
|
+
sql << %{
|
47
|
+
CREATE FUNCTION check_#{interface_name}_delete_integrity() RETURNS TRIGGER AS '
|
48
|
+
BEGIN
|
49
|
+
IF TG_TABLE_NAME = ''#{models[0].constantize.table_name}'' AND EXISTS (
|
50
|
+
SELECT id FROM #{polymorphic_model_table_name}
|
51
|
+
WHERE #{interface_name}_type = ''#{models[0]}'' AND #{interface_name}_id = OLD.id) THEN
|
52
|
+
RAISE EXCEPTION ''There are records in #{polymorphic_model_table_name} that refer to %. You must delete those records first.'', OLD;
|
53
|
+
}
|
54
|
+
|
55
|
+
models[1..-1].each do |model|
|
56
|
+
sql << %{
|
57
|
+
ELSEIF TG_TABLE_NAME = ''#{model.constantize.table_name}'' AND EXISTS (
|
58
|
+
SELECT id FROM #{polymorphic_model_table_name}
|
59
|
+
WHERE #{interface_name}_type = ''#{model}'' AND #{interface_name}_id = OLD.id) THEN
|
60
|
+
RAISE EXCEPTION ''There are records in #{polymorphic_model_table_name} that refer to %. You must delete those records first.'', OLD;
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
sql << %{
|
65
|
+
ELSE
|
66
|
+
RETURN NULL;
|
67
|
+
END IF;
|
68
|
+
END'
|
69
|
+
LANGUAGE plpgsql;
|
70
|
+
}
|
71
|
+
|
72
|
+
models.each do |model|
|
73
|
+
table_name = model.constantize.table_name
|
74
|
+
|
75
|
+
sql << %{
|
76
|
+
CREATE TRIGGER check_#{table_name}_delete_integrity_trigger
|
77
|
+
BEFORE DELETE ON #{table_name}
|
78
|
+
FOR EACH ROW EXECUTE PROCEDURE check_#{interface_name}_delete_integrity();
|
79
|
+
}
|
80
|
+
end
|
81
|
+
|
82
|
+
return strip_non_essential_spaces(sql)
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.get_drop_function_sql(interface_name)
|
86
|
+
sql = %{
|
87
|
+
DROP FUNCTION IF EXISTS check_#{interface_name}_create_integrity() CASCADE;
|
88
|
+
DROP FUNCTION IF EXISTS check_#{interface_name}_delete_integrity() CASCADE;
|
89
|
+
}
|
90
|
+
return strip_non_essential_spaces(sql)
|
91
|
+
end
|
92
|
+
|
93
|
+
end #class
|
94
|
+
|
95
|
+
end #module
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Fides
|
2
|
+
module SqlWriter
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
def strip_non_essential_spaces(string_to_strip)
|
10
|
+
return string_to_strip.gsub(/\s{2,}|\\n/, " ").strip
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'fides/sql_writer'
|
2
|
+
|
3
|
+
module Fides
|
4
|
+
|
5
|
+
class Sqlite3
|
6
|
+
include SqlWriter
|
7
|
+
|
8
|
+
def self.get_create_function_sql(interface_name, models, polymorphic_model)
|
9
|
+
raise "Sqlite3 not yet implemented"
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.get_delete_function_sql(interface_name, models, polymorphic_model)
|
13
|
+
raise "Sqlite3 not yet implemented"
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
data/lib/fides/version.rb
CHANGED
data/lib/fides.rb
CHANGED
@@ -1,120 +1,60 @@
|
|
1
|
-
require
|
2
|
-
require 'active_support/concern'
|
1
|
+
require 'rails'
|
3
2
|
require 'active_record'
|
3
|
+
require 'active_support/concern'
|
4
4
|
require 'active_support/inflector'
|
5
|
+
require 'fides/version'
|
6
|
+
require 'fides/sql_writer'
|
7
|
+
require 'fides/postgresql'
|
8
|
+
require 'fides/sqlite3'
|
9
|
+
require 'fides/database_adapter_error'
|
5
10
|
|
6
11
|
module Fides
|
7
12
|
|
13
|
+
SUPPORTED_ADAPTERS = ["postgresql"]
|
14
|
+
|
8
15
|
extend ActiveSupport::Concern
|
9
16
|
|
10
17
|
def add_polymorphic_triggers(opts)
|
11
18
|
raise ArgumentError, "missing :associated_models from options hash" if !opts.has_key?(:associated_models)
|
12
19
|
raise ArgumentError, "missing :polymorphic_model from options hash" if !opts.has_key?(:polymorphic_model)
|
20
|
+
|
13
21
|
associated_models = opts[:associated_models]
|
14
22
|
polymorphic_model = opts[:polymorphic_model]
|
15
|
-
|
23
|
+
interface = opts.has_key?(:interface_name) ? opts[:interface_name] : interface_name(polymorphic_model)
|
16
24
|
|
17
|
-
|
18
|
-
|
25
|
+
fides_sql_generator = get_sql_generator_class
|
26
|
+
|
27
|
+
sql = fides_sql_generator.get_create_function_sql(interface, associated_models, polymorphic_model)
|
28
|
+
sql << fides_sql_generator.get_delete_function_sql(interface, associated_models, polymorphic_model)
|
19
29
|
|
20
30
|
execute sql
|
21
31
|
end
|
22
32
|
|
23
33
|
def remove_polymorphic_triggers(opts)
|
24
34
|
raise ArgumentError, "missing :polymorphic_model from options hash" if !opts.has_key?(:polymorphic_model)
|
35
|
+
|
25
36
|
polymorphic_model = opts[:polymorphic_model]
|
26
|
-
|
37
|
+
interface = opts.has_key?(:interface_name) ? opts[:interface_name] : interface_name(polymorphic_model)
|
27
38
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
}
|
39
|
+
sql = get_sql_generator_class.get_drop_function_sql(interface)
|
40
|
+
|
41
|
+
execute sql
|
32
42
|
end
|
33
43
|
|
34
44
|
private
|
35
45
|
|
46
|
+
def get_sql_generator_class
|
47
|
+
db_adapter = ActiveRecord::Base.configurations[Rails.env]['adapter']
|
48
|
+
raise DatabaseAdapterError.new(db_adapter) unless SUPPORTED_ADAPTERS.include?(db_adapter)
|
49
|
+
return "Fides::#{db_adapter.capitalize}".constantize
|
50
|
+
end
|
51
|
+
|
36
52
|
# TODO: Is it safe to just grab the first polymorphic association?
|
37
53
|
def interface_name(model_name)
|
38
54
|
model_name.constantize.reflect_on_all_associations.select { |r| r if r.options[:polymorphic] }.first.name
|
39
55
|
end
|
40
56
|
|
41
|
-
|
42
|
-
sql = "DROP FUNCTION IF EXISTS check_#{interface_name}_create_integrity() CASCADE;"
|
43
|
-
|
44
|
-
sql << %{
|
45
|
-
CREATE FUNCTION check_#{interface_name}_create_integrity() RETURNS TRIGGER AS '
|
46
|
-
BEGIN
|
47
|
-
IF NEW.#{interface_name}_type = ''#{models[0]}'' AND EXISTS (
|
48
|
-
SELECT id FROM #{models[0].constantize.table_name} WHERE id = NEW.#{interface_name}_id) THEN
|
49
|
-
RETURN NEW;
|
50
|
-
}
|
51
|
-
|
52
|
-
models[1..-1].each do |model|
|
53
|
-
sql << %{
|
54
|
-
ELSEIF NEW.#{interface_name}_type = ''#{model}'' AND EXISTS (
|
55
|
-
SELECT id FROM #{model.constantize.table_name} WHERE id = NEW.#{interface_name}_id) THEN
|
56
|
-
RETURN NEW;
|
57
|
-
}
|
58
|
-
end
|
59
|
-
|
60
|
-
sql << %{
|
61
|
-
ELSE
|
62
|
-
RAISE EXCEPTION ''No % model with id %.'', NEW.#{interface_name}_type, NEW.#{interface_name}_id;
|
63
|
-
RETURN NULL;
|
64
|
-
END IF;
|
65
|
-
END'
|
66
|
-
LANGUAGE plpgsql;
|
67
|
-
|
68
|
-
CREATE TRIGGER check_#{interface_name}_create_integrity_trigger
|
69
|
-
BEFORE INSERT OR UPDATE ON #{polymorphic_model.constantize.table_name}
|
70
|
-
FOR EACH ROW EXECUTE PROCEDURE check_#{interface_name}_create_integrity();
|
71
|
-
}
|
72
|
-
|
73
|
-
return sql
|
74
|
-
end
|
75
|
-
|
76
|
-
def get_delete_function_sql(interface_name, models, polymorphic_model)
|
77
|
-
polymorphic_model_table_name = polymorphic_model.constantize.table_name
|
78
|
-
|
79
|
-
sql = ""
|
80
|
-
sql << %{
|
81
|
-
CREATE FUNCTION check_#{interface_name}_delete_integrity() RETURNS TRIGGER AS '
|
82
|
-
BEGIN
|
83
|
-
IF TG_TABLE_NAME = ''#{models[0].constantize.table_name}'' AND EXISTS (
|
84
|
-
SELECT id FROM #{polymorphic_model_table_name}
|
85
|
-
WHERE #{interface_name}_type = ''#{models[0]}'' AND #{interface_name}_id = OLD.id) THEN
|
86
|
-
RAISE EXCEPTION ''There are records in #{polymorphic_model_table_name} that refer to %. You must delete those records first.'', OLD;
|
87
|
-
}
|
88
|
-
|
89
|
-
models[1..-1].each do |model|
|
90
|
-
sql << %{
|
91
|
-
ELSEIF TG_TABLE_NAME = ''#{model.constantize.table_name}'' AND EXISTS (
|
92
|
-
SELECT id FROM #{polymorphic_model_table_name}
|
93
|
-
WHERE #{interface_name}_type = ''#{model}'' AND #{interface_name}_id = OLD.id) THEN
|
94
|
-
RAISE EXCEPTION ''There are records in #{polymorphic_model_table_name} that refer to %. You must delete those records first.'', OLD;
|
95
|
-
}
|
96
|
-
end
|
97
|
-
|
98
|
-
sql << %{
|
99
|
-
ELSE
|
100
|
-
RETURN NULL;
|
101
|
-
END IF;
|
102
|
-
END'
|
103
|
-
LANGUAGE plpgsql;
|
104
|
-
}
|
105
|
-
|
106
|
-
models.each do |model|
|
107
|
-
table_name = model.constantize.table_name
|
108
|
-
|
109
|
-
sql << %{
|
110
|
-
CREATE TRIGGER check_#{table_name}_delete_integrity_trigger
|
111
|
-
BEFORE DELETE ON #{table_name}
|
112
|
-
FOR EACH ROW EXECUTE PROCEDURE check_#{interface_name}_delete_integrity();
|
113
|
-
}
|
114
|
-
end
|
115
|
-
|
116
|
-
return sql
|
117
|
-
end
|
57
|
+
|
118
58
|
end
|
119
59
|
|
120
60
|
class ActiveRecord::Migration
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require_relative '../../test_helper'
|
2
|
+
|
3
|
+
describe Fides::Postgresql do
|
4
|
+
|
5
|
+
let(:subject) { Fides::Postgresql }
|
6
|
+
|
7
|
+
it 'responds to #get_create_function_sql' do
|
8
|
+
assert_respond_to subject, :get_create_function_sql
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'responds to #get_delete_function_sql' do
|
12
|
+
assert_respond_to subject, :get_delete_function_sql
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'returns an expected SQL string' do
|
16
|
+
sql = subject.get_create_function_sql("imageable", ["Product", "Employee"], "Picture")
|
17
|
+
assert_equal subject.strip_non_essential_spaces(CREATE_SQL), sql
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'returns an expected SQL string' do
|
21
|
+
sql = subject.get_delete_function_sql("imageable", ["Product", "Employee"], "Picture")
|
22
|
+
assert_equal subject.strip_non_essential_spaces(DELETE_SQL), sql
|
23
|
+
end
|
24
|
+
|
25
|
+
CREATE_SQL = %{
|
26
|
+
|
27
|
+
DROP FUNCTION IF EXISTS check_imageable_create_integrity() CASCADE;
|
28
|
+
|
29
|
+
CREATE FUNCTION check_imageable_create_integrity() RETURNS TRIGGER AS '
|
30
|
+
BEGIN
|
31
|
+
IF NEW.imageable_type = ''Product'' AND EXISTS (
|
32
|
+
SELECT id FROM products WHERE id = NEW.imageable_id) THEN
|
33
|
+
RETURN NEW;
|
34
|
+
ELSEIF NEW.imageable_type = ''Employee'' AND EXISTS (
|
35
|
+
SELECT id FROM employees WHERE id = NEW.imageable_id) THEN
|
36
|
+
RETURN NEW;
|
37
|
+
ELSE
|
38
|
+
RAISE EXCEPTION ''No % model with id %.'', NEW.imageable_type, NEW.imageable_id;
|
39
|
+
RETURN NULL;
|
40
|
+
END IF;
|
41
|
+
END'
|
42
|
+
LANGUAGE plpgsql;
|
43
|
+
|
44
|
+
CREATE TRIGGER check_imageable_create_integrity_trigger
|
45
|
+
BEFORE INSERT OR UPDATE ON pictures
|
46
|
+
FOR EACH ROW EXECUTE PROCEDURE check_imageable_create_integrity();
|
47
|
+
|
48
|
+
}
|
49
|
+
|
50
|
+
DELETE_SQL = %{
|
51
|
+
|
52
|
+
CREATE FUNCTION check_imageable_delete_integrity() RETURNS TRIGGER AS '
|
53
|
+
BEGIN
|
54
|
+
IF TG_TABLE_NAME = ''products'' AND EXISTS (
|
55
|
+
SELECT id FROM pictures
|
56
|
+
WHERE imageable_type = ''Product'' AND imageable_id = OLD.id) THEN
|
57
|
+
RAISE EXCEPTION ''There are records in pictures that refer to %. You must delete those records first.'', OLD;
|
58
|
+
ELSEIF TG_TABLE_NAME = ''employees'' AND EXISTS (
|
59
|
+
SELECT id FROM pictures
|
60
|
+
WHERE imageable_type = ''Employee'' AND imageable_id = OLD.id) THEN
|
61
|
+
RAISE EXCEPTION ''There are records in pictures that refer to %. You must delete those records first.'', OLD;
|
62
|
+
ELSE
|
63
|
+
RETURN NULL;
|
64
|
+
END IF;
|
65
|
+
END'
|
66
|
+
LANGUAGE plpgsql;
|
67
|
+
|
68
|
+
CREATE TRIGGER check_products_delete_integrity_trigger
|
69
|
+
BEFORE DELETE ON products
|
70
|
+
FOR EACH ROW EXECUTE PROCEDURE check_imageable_delete_integrity();
|
71
|
+
|
72
|
+
CREATE TRIGGER check_employees_delete_integrity_trigger
|
73
|
+
BEFORE DELETE ON employees
|
74
|
+
FOR EACH ROW EXECUTE PROCEDURE check_imageable_delete_integrity();
|
75
|
+
|
76
|
+
}
|
77
|
+
|
78
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
describe Fides do
|
4
|
+
|
5
|
+
before do
|
6
|
+
class Picture < ActiveRecord::Base
|
7
|
+
def self.reflect_on_all_associations
|
8
|
+
[MyTestAssociaiton.new]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
class Product < ActiveRecord::Base; end
|
12
|
+
class Employee < ActiveRecord::Base; end
|
13
|
+
class MyTestMigration < ActiveRecord::Migration
|
14
|
+
def execute(blah)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
class MyTestAssociaiton
|
18
|
+
def options
|
19
|
+
{:polymorphic => true}
|
20
|
+
end
|
21
|
+
def name
|
22
|
+
@imageable
|
23
|
+
end
|
24
|
+
end
|
25
|
+
@my_test_migration = MyTestMigration.new
|
26
|
+
end
|
27
|
+
|
28
|
+
it "responds to add_polymorphic_triggers" do
|
29
|
+
assert_respond_to @my_test_migration, :add_polymorphic_triggers
|
30
|
+
end
|
31
|
+
|
32
|
+
it "responds to remove_polymorphic_triggers" do
|
33
|
+
assert_respond_to @my_test_migration, :remove_polymorphic_triggers
|
34
|
+
end
|
35
|
+
|
36
|
+
it "includes the ability to use of the constantize method" do
|
37
|
+
assert_equal "Picture".constantize, Picture
|
38
|
+
end
|
39
|
+
|
40
|
+
it "raises and exception if :associated_models isn't a parameter of #add_polymorphic_triggers" do
|
41
|
+
exception = assert_raises(ArgumentError) {
|
42
|
+
@my_test_migration.add_polymorphic_triggers(:polymorphic_model => "Picture")
|
43
|
+
}
|
44
|
+
assert_match /associated_models/, exception.message
|
45
|
+
end
|
46
|
+
|
47
|
+
it "raises and exception if :polymorphic_model isn't a parameter of #add_polymorphic_triggers" do
|
48
|
+
exception = assert_raises(ArgumentError) {
|
49
|
+
@my_test_migration.add_polymorphic_triggers(:associated_models => ["Product", "Employee"])
|
50
|
+
}
|
51
|
+
assert_match /polymorphic_model/, exception.message
|
52
|
+
end
|
53
|
+
|
54
|
+
it "raise an error if the database adapter isn't supported" do
|
55
|
+
Rails.stub :env, "development" do
|
56
|
+
ActiveRecord::Base.stub :configurations, { "development" => { "adapter" => "fakedb" } } do
|
57
|
+
exception = assert_raises(Fides::DatabaseAdapterError) {
|
58
|
+
@my_test_migration.add_polymorphic_triggers(
|
59
|
+
:polymorphic_model => "Picture",
|
60
|
+
:associated_models => ["Product", "Employee"]
|
61
|
+
)
|
62
|
+
}
|
63
|
+
assert_match /fakedb/, exception.message
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it "runs silently" do
|
69
|
+
assert_silent do
|
70
|
+
Rails.stub :env, "development" do
|
71
|
+
ActiveRecord::Base.stub :configurations, { "development" => { "adapter" => "postgresql" } } do
|
72
|
+
@my_test_migration.add_polymorphic_triggers(
|
73
|
+
:polymorphic_model => "Picture",
|
74
|
+
:associated_models => ["Product", "Employee"],
|
75
|
+
:interface_name => "imageable"
|
76
|
+
)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fides
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Kraft
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-03-
|
11
|
+
date: 2013-03-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rails
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: bundler
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,9 +122,16 @@ files:
|
|
108
122
|
- Rakefile
|
109
123
|
- fides.gemspec
|
110
124
|
- lib/fides.rb
|
125
|
+
- lib/fides/database_adapter.rb
|
126
|
+
- lib/fides/database_adapter_error.rb
|
127
|
+
- lib/fides/postgresql.rb
|
128
|
+
- lib/fides/sql_writer.rb
|
129
|
+
- lib/fides/sqlite3.rb
|
111
130
|
- lib/fides/version.rb
|
112
|
-
- test/lib/fides/
|
131
|
+
- test/lib/fides/database_adapter_test.rb
|
132
|
+
- test/lib/fides/postgresql_test.rb
|
113
133
|
- test/lib/fides/version_test.rb
|
134
|
+
- test/lib/fides_test.rb
|
114
135
|
- test/test_helper.rb
|
115
136
|
homepage: https://github.com/mkraft/fides
|
116
137
|
licenses:
|
@@ -138,6 +159,8 @@ specification_version: 4
|
|
138
159
|
summary: Creates SQL triggers from Rails migrations to enforce the integrity of polymorphic
|
139
160
|
associations at the database level.
|
140
161
|
test_files:
|
141
|
-
- test/lib/fides/
|
162
|
+
- test/lib/fides/database_adapter_test.rb
|
163
|
+
- test/lib/fides/postgresql_test.rb
|
142
164
|
- test/lib/fides/version_test.rb
|
165
|
+
- test/lib/fides_test.rb
|
143
166
|
- test/test_helper.rb
|
@@ -1,42 +0,0 @@
|
|
1
|
-
require_relative '../../test_helper'
|
2
|
-
|
3
|
-
describe Fides do
|
4
|
-
|
5
|
-
before do
|
6
|
-
class Picture < ActiveRecord::Base; end
|
7
|
-
class MyTestMigration < ActiveRecord::Migration; end
|
8
|
-
class MyTestAssociaiton; end
|
9
|
-
@my_test_association = MyTestAssociaiton.new
|
10
|
-
@my_test_migration = MyTestMigration.new
|
11
|
-
end
|
12
|
-
|
13
|
-
it "responds to add_polymorphic_triggers" do
|
14
|
-
assert_respond_to @my_test_migration, :add_polymorphic_triggers
|
15
|
-
end
|
16
|
-
|
17
|
-
it "responds to remove_polymorphic_triggers" do
|
18
|
-
assert_respond_to @my_test_migration, :remove_polymorphic_triggers
|
19
|
-
end
|
20
|
-
|
21
|
-
it "includes the ability to use of the constantize method" do
|
22
|
-
|
23
|
-
assert_equal "Picture".constantize, Picture
|
24
|
-
end
|
25
|
-
|
26
|
-
|
27
|
-
it "raises and exception if :associated_models isn't a parameter of #add_polymorphic_triggers" do
|
28
|
-
exception = assert_raises(ArgumentError) {
|
29
|
-
MyTestMigration.add_polymorphic_triggers(:polymorphic_model => "Picture")
|
30
|
-
}
|
31
|
-
assert_match /associated_models/, exception.message
|
32
|
-
end
|
33
|
-
|
34
|
-
it "raises and exception if :polymorphic_model isn't a parameter of #add_polymorphic_triggers" do
|
35
|
-
exception = assert_raises(ArgumentError) {
|
36
|
-
MyTestMigration.add_polymorphic_triggers(:associated_models => ["Product", "Employee"])
|
37
|
-
}
|
38
|
-
assert_match /polymorphic_model/, exception.message
|
39
|
-
end
|
40
|
-
|
41
|
-
|
42
|
-
end
|