hairtrigger 0.2.21 → 0.2.25
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/LICENSE.txt +1 -1
- data/README.md +47 -9
- data/lib/hair_trigger/builder.rb +15 -10
- data/lib/hair_trigger/schema_dumper.rb +38 -6
- data/lib/hair_trigger/version.rb +1 -1
- data/lib/hair_trigger.rb +31 -32
- metadata +13 -24
- data/spec/adapter_spec.rb +0 -94
- data/spec/builder_spec.rb +0 -433
- data/spec/migrations/20110331212003_initial_tables.rb +0 -18
- data/spec/migrations/20110331212631_user_trigger.rb +0 -18
- data/spec/migrations/20110417185102_manual_user_trigger.rb +0 -10
- data/spec/migrations-3.2/20110331212003_initial_tables.rb +0 -18
- data/spec/migrations-3.2/20110331212631_user_trigger.rb +0 -18
- data/spec/migrations-3.2/20110417185102_manual_user_trigger.rb +0 -10
- data/spec/migrations-pre-3.1/20110331212003_initial_tables.rb +0 -18
- data/spec/migrations-pre-3.1/20110331212631_user_trigger.rb +0 -18
- data/spec/migrations-pre-3.1/20110417185102_manual_user_trigger.rb +0 -10
- data/spec/migrations_spec.rb +0 -60
- data/spec/models/user.rb +0 -6
- data/spec/models/user_group.rb +0 -3
- data/spec/schema_dumper_spec.rb +0 -124
- data/spec/spec_helper.rb +0 -104
data/spec/schema_dumper_spec.rb
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
# for this spec to work, you need to have postgres and mysql installed (in
|
|
4
|
-
# addition to the gems), and you should make sure that you have set up
|
|
5
|
-
# appropriate users and permissions. see database.yml for more info
|
|
6
|
-
|
|
7
|
-
describe "schema dumping" do
|
|
8
|
-
include_context "hairtrigger utils"
|
|
9
|
-
|
|
10
|
-
each_adapter do
|
|
11
|
-
before do
|
|
12
|
-
reset_tmp
|
|
13
|
-
initialize_db
|
|
14
|
-
migrate_db
|
|
15
|
-
db_triggers.grep(/bob_count \+ 1/).size.should eql(1)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
context "without schema.rb" do
|
|
19
|
-
it "should work" do
|
|
20
|
-
schema_rb = dump_schema
|
|
21
|
-
schema_rb.should match(/create_trigger\("users_after_insert_row_when_new_name_bob__tr", :generated => true, :compatibility => 1\)/)
|
|
22
|
-
schema_rb.should match(/create_trigger\("users_after_update_row_when_new_name_joe__tr", :compatibility => 1\)/)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
it "should create adapter-specific triggers if no migrations exist" do
|
|
26
|
-
FileUtils.rm_rf(Dir.glob('tmp/migrations/*rb'))
|
|
27
|
-
schema_rb = dump_schema
|
|
28
|
-
schema_rb.should_not match(/create_trigger\(/)
|
|
29
|
-
schema_rb.should match(/no candidate create_trigger statement could be found, creating an adapter-specific one/)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
it "should not dump triggers in migrations that haven't run" do
|
|
33
|
-
# edit our model trigger, generate a new migration
|
|
34
|
-
replace_file_contents HairTrigger.model_path + '/user.rb',
|
|
35
|
-
'"UPDATE user_groups SET bob_count = bob_count + 1"',
|
|
36
|
-
'{:default => "UPDATE user_groups SET bob_count = bob_count + 2"}'
|
|
37
|
-
reset_models
|
|
38
|
-
|
|
39
|
-
HairTrigger.should_not be_migrations_current
|
|
40
|
-
migration = HairTrigger.generate_migration
|
|
41
|
-
HairTrigger.should be_migrations_current
|
|
42
|
-
|
|
43
|
-
schema_rb = dump_schema
|
|
44
|
-
schema_rb.should match(/bob_count \+ 1/)
|
|
45
|
-
schema_rb.should_not match(/bob_count \+ 2/)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
it 'should take in consideration active record schema dumper ignore_tables option with regexp' do
|
|
49
|
-
ActiveRecord::SchemaDumper.ignore_tables = [/users/]
|
|
50
|
-
|
|
51
|
-
dump_schema.should_not match(/create_trigger/)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
it 'should take in consideration active record schema dumper ignore_tables option with string' do
|
|
55
|
-
ActiveRecord::SchemaDumper.ignore_tables = ['users']
|
|
56
|
-
|
|
57
|
-
dump_schema.should_not match(/create_trigger/)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
it 'should take in consideration active record schema dumper ignore_tables option with partial string' do
|
|
61
|
-
ActiveRecord::SchemaDumper.ignore_tables = ['user']
|
|
62
|
-
|
|
63
|
-
dump_schema.should match(/create_trigger/)
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
context "with schema.rb" do
|
|
70
|
-
before do
|
|
71
|
-
ActiveRecord::SchemaDumper.previous_schema = dump_schema
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
it "should work" do
|
|
75
|
-
schema_rb = dump_schema
|
|
76
|
-
schema_rb.should match(/create_trigger\("users_after_insert_row_when_new_name_bob__tr", :generated => true, :compatibility => 1\)/)
|
|
77
|
-
schema_rb.should match(/create_trigger\("users_after_update_row_when_new_name_joe__tr", :compatibility => 1\)/)
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
it "should still work even if migrations have been deleted" do
|
|
81
|
-
FileUtils.rm_rf(Dir.glob('tmp/migrations/*rb'))
|
|
82
|
-
schema_rb = dump_schema
|
|
83
|
-
schema_rb.should match(/create_trigger\("users_after_insert_row_when_new_name_bob__tr", :generated => true, :compatibility => 1\)/)
|
|
84
|
-
schema_rb.should match(/create_trigger\("users_after_update_row_when_new_name_joe__tr", :compatibility => 1\)/)
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
it "should evaluate all migrations even if they haven't run" do
|
|
88
|
-
# edit our model trigger, generate a new migration
|
|
89
|
-
replace_file_contents HairTrigger.model_path + '/user.rb',
|
|
90
|
-
'"UPDATE user_groups SET bob_count = bob_count + 1"',
|
|
91
|
-
'{:default => "UPDATE user_groups SET bob_count = bob_count + 2"}'
|
|
92
|
-
reset_models
|
|
93
|
-
|
|
94
|
-
HairTrigger.should_not be_migrations_current
|
|
95
|
-
migration = HairTrigger.generate_migration
|
|
96
|
-
HairTrigger.should be_migrations_current
|
|
97
|
-
|
|
98
|
-
schema_rb = dump_schema
|
|
99
|
-
schema_rb.should match(/bob_count \+ 1/)
|
|
100
|
-
schema_rb.should_not match(/bob_count \+ 2/)
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
it 'should take in consideration active record schema dumper ignore_tables option with regexp' do
|
|
104
|
-
ActiveRecord::SchemaDumper.ignore_tables = [/users/]
|
|
105
|
-
|
|
106
|
-
dump_schema.should_not match(/create_trigger/)
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
it 'should take in consideration active record schema dumper ignore_tables option with string' do
|
|
110
|
-
ActiveRecord::SchemaDumper.ignore_tables = ['users']
|
|
111
|
-
|
|
112
|
-
dump_schema.should_not match(/create_trigger/)
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
it 'should take in consideration active record schema dumper ignore_tables option with partial string' do
|
|
116
|
-
ActiveRecord::SchemaDumper.ignore_tables = ['user']
|
|
117
|
-
|
|
118
|
-
dump_schema.should match(/create_trigger/)
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
end
|
|
124
|
-
end
|
data/spec/spec_helper.rb
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
require 'rspec'
|
|
2
|
-
require 'active_record'
|
|
3
|
-
require 'logger'
|
|
4
|
-
require 'hair_trigger'
|
|
5
|
-
require 'yaml'
|
|
6
|
-
|
|
7
|
-
CONFIGS = YAML.load_file(File.expand_path(File.dirname(__FILE__) + '/../database.yml'))[ENV["DB_CONFIG"] || "test"]
|
|
8
|
-
ADAPTERS = [:mysql2, :postgresql, :sqlite3]
|
|
9
|
-
ADAPTERS.unshift :mysql if ActiveRecord::VERSION::STRING < "5"
|
|
10
|
-
|
|
11
|
-
def each_adapter
|
|
12
|
-
require 'active_record/connection_adapters/postgresql_adapter'
|
|
13
|
-
require 'active_record/connection_adapters/mysql_adapter' if ADAPTERS.include? :mysql
|
|
14
|
-
require 'active_record/connection_adapters/mysql2_adapter'
|
|
15
|
-
require 'active_record/connection_adapters/sqlite3_adapter'
|
|
16
|
-
require 'mysql2'
|
|
17
|
-
|
|
18
|
-
ADAPTERS.each do |adapter_name|
|
|
19
|
-
context "under #{adapter_name}" do
|
|
20
|
-
let(:adapter) { adapter_name }
|
|
21
|
-
instance_eval &Proc.new
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
shared_context "hairtrigger utils" do
|
|
27
|
-
|
|
28
|
-
def reset_models
|
|
29
|
-
User.send :remove_instance_variable, :@triggers if Object.const_defined?('User')
|
|
30
|
-
load './tmp/models/user.rb' # since some tests modify it
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def reset_tmp(options = {})
|
|
34
|
-
options[:migration_glob] ||= '*'
|
|
35
|
-
HairTrigger.model_path = 'tmp/models'
|
|
36
|
-
HairTrigger.migration_path = 'tmp/migrations'
|
|
37
|
-
FileUtils.rm_rf('tmp') if File.directory?('tmp')
|
|
38
|
-
FileUtils.mkdir_p(HairTrigger.model_path)
|
|
39
|
-
FileUtils.mkdir_p(HairTrigger.migration_path)
|
|
40
|
-
FileUtils.cp_r('spec/models', 'tmp')
|
|
41
|
-
reset_models
|
|
42
|
-
FileUtils.cp_r(Dir.glob("spec/migrations#{migrations_sufix}/#{options[:migration_glob]}"), HairTrigger.migration_path)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def migrations_sufix
|
|
46
|
-
if ActiveRecord::VERSION::STRING < '3.1.'
|
|
47
|
-
'-pre-3.1'
|
|
48
|
-
elsif ActiveRecord::VERSION::STRING < '5.0'
|
|
49
|
-
'-3.2'
|
|
50
|
-
else
|
|
51
|
-
''
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def initialize_db
|
|
56
|
-
ActiveRecord::Base.clear_all_connections!
|
|
57
|
-
config = CONFIGS[adapter.to_s].merge({:adapter => adapter.to_s})
|
|
58
|
-
case adapter
|
|
59
|
-
when :mysql, :mysql2
|
|
60
|
-
ret = `echo "drop database if exists #{config['database']}; create database #{config['database']};" | mysql -u #{config['username']}`
|
|
61
|
-
raise "error creating database: #{ret}" unless $?.exitstatus == 0
|
|
62
|
-
when :postgresql
|
|
63
|
-
user_arg = "-U #{config['username']}" if config['username']
|
|
64
|
-
`dropdb #{user_arg} #{config['database']} &>/dev/null`
|
|
65
|
-
ret = `createdb #{user_arg} #{config['database']} 2>&1`
|
|
66
|
-
raise "error creating database: #{ret}" unless $?.exitstatus == 0
|
|
67
|
-
end
|
|
68
|
-
# Arel has an issue in that it keeps using original connection for quoting,
|
|
69
|
-
# etc. (which breaks stuff) unless you do this:
|
|
70
|
-
Arel::Visitors::ENGINE_VISITORS.delete(ActiveRecord::Base) if defined?(Arel::Visitors::ENGINE_VISITORS)
|
|
71
|
-
ActiveRecord::Base.establish_connection(config)
|
|
72
|
-
ActiveRecord::Base.logger = Logger.new('/dev/null')
|
|
73
|
-
ActiveRecord::SchemaDumper.previous_schema = nil
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def migrate_db
|
|
77
|
-
ActiveRecord::Migration.verbose = false
|
|
78
|
-
ActiveRecord::Migrator.migrate(HairTrigger.migration_path)
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def dump_schema
|
|
82
|
-
io = StringIO.new
|
|
83
|
-
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, io)
|
|
84
|
-
io.rewind
|
|
85
|
-
io.read
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def trigger(*args)
|
|
89
|
-
HairTrigger::Builder.new(*args)
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
def conn
|
|
93
|
-
ActiveRecord::Base.connection
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
def db_triggers
|
|
97
|
-
conn.triggers.values
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def replace_file_contents(path, source, replacement)
|
|
101
|
-
contents = File.read(path)
|
|
102
|
-
File.open(path, 'w') { |f| f.write contents.sub(source, replacement) }
|
|
103
|
-
end
|
|
104
|
-
end
|