culturecode_stagehand 0.9.2 → 0.10.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: 0f0f8f7ad6db23b1f57b4489d7b835421c55f4e9
4
- data.tar.gz: ddf42219103d4f9db984f15381d59fd797ce6834
3
+ metadata.gz: 8e8e470e10c36d55ed09a55577353f992f4dce33
4
+ data.tar.gz: 8ff3559aa8264aba97054676c4829cd8930bad1d
5
5
  SHA512:
6
- metadata.gz: 268b7cb9e19ce1e64cb726e7e9c0fbf573910ede523c9b8aa20dbabf37f6c77f42322349408ccec4db507a6be0a50b84e157ab56f4550dc4c0509bb4123c5565
7
- data.tar.gz: 7d15177fd390976858af7cd8cb0c35efbf2cea8c3018ded4e7b38df24a2e70395bb9d7dcbfdfac255201fe27e7be00699bc49a72f689e5c2d8364567415f5c31
6
+ metadata.gz: 72c42cf30acae539d585e1d8c07abcc8a1bb48c2ac6d0d540e324aa92407bcff9f86acfb86d433abf5fadf7e672472c7ff1694c5e764116d63cfbdaab1111514
7
+ data.tar.gz: c2da536ed22c74a74db0ba20f41e0891898d02f779cfc870e2d5f46d9aaf7f2e3dd34ed08b0e5917a07e2a36571293dac382ee17f9b4e2d9db83efab1fbb0b93
@@ -20,6 +20,11 @@ module Stagehand
20
20
  !!Rails.configuration.x.stagehand.ghost_mode
21
21
  end
22
22
 
23
+ # Allow unsynchronized writes directly to the production database? A warning will be logged if set to true.
24
+ def allow_unsynced_production_writes?
25
+ !!Rails.configuration.x.stagehand.allow_unsynced_production_writes
26
+ end
27
+
23
28
  # Returns true if the production and staging connections are the same.
24
29
  # Use case: Front-end devs may not have a second database set up as they are only concerned with the front end
25
30
  def single_connection?
@@ -0,0 +1,76 @@
1
+ module Stagehand
2
+ module Connection
3
+ def self.with_production_writes(model, &block)
4
+ state = model.connection.readonly?
5
+ model.connection.readonly!(false)
6
+ return block.call
7
+ ensure
8
+ model.connection.readonly!(state)
9
+ end
10
+
11
+ module AdapterExtensions
12
+ def self.prepended(base)
13
+ base.set_callback :checkout, :after, :update_readonly_state
14
+ base.set_callback :checkin, :before, :clear_readonly_state
15
+ end
16
+
17
+ def exec_insert(*)
18
+ handle_readonly_writes!
19
+ super
20
+ end
21
+
22
+ def exec_update(*)
23
+ handle_readonly_writes!
24
+ super
25
+ end
26
+
27
+ def exec_delete(*)
28
+ handle_readonly_writes!
29
+ super
30
+ end
31
+
32
+ def allow_writes(&block)
33
+ state = readonly?
34
+ readonly!(true)
35
+ return block.call
36
+ ensure
37
+ readonly!(state)
38
+ end
39
+
40
+ def readonly!(state = true)
41
+ @readonly = state
42
+ end
43
+
44
+ def readonly?
45
+ !!@readonly
46
+ end
47
+
48
+ private
49
+
50
+ def update_readonly_state
51
+ readonly! unless Configuration.single_connection? || @config[:database] != Database.production_database_name
52
+ end
53
+
54
+ def clear_readonly_state
55
+ readonly!(false)
56
+ end
57
+
58
+ def handle_readonly_writes!
59
+ if !readonly?
60
+ return
61
+ elsif Configuration.allow_unsynced_production_writes?
62
+ Rails.logger.warn "Writing directly to production database"
63
+ else
64
+ raise(UnsyncedProductionWrite, "Attempted to write directly to production database")
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+
71
+ # EXCEPTIONS
72
+
73
+ class UnsyncedProductionWrite < StandardError; end
74
+ end
75
+
76
+ ActiveRecord::Base.connection.class.prepend(Stagehand::Connection::AdapterExtensions)
@@ -12,6 +12,7 @@ module Stagehand
12
12
  require "stagehand/cache"
13
13
  require "stagehand/key"
14
14
  require "stagehand/database"
15
+ require "stagehand/connection_adapter_extensions"
15
16
  require "stagehand/controller_extensions"
16
17
  require "stagehand/active_record_extensions"
17
18
  require "stagehand/staging"
@@ -20,17 +20,21 @@ module Stagehand
20
20
 
21
21
  return unless attributes.present?
22
22
 
23
- is_new = matching(staging_record, table_name).update_all(attributes).zero?
24
-
25
- # Ensure we always return a record, even when updating instead of creating
26
- Record.new.tap do |record|
27
- record.assign_attributes(attributes)
28
- record.save if is_new
23
+ Connection.with_production_writes(Record) do
24
+ is_new = matching(staging_record, table_name).update_all(attributes).zero?
25
+
26
+ # Ensure we always return a record, even when updating instead of creating
27
+ Record.new.tap do |record|
28
+ record.assign_attributes(attributes)
29
+ record.save if is_new
30
+ end
29
31
  end
30
32
  end
31
33
 
32
34
  def delete(staging_record, table_name = nil)
33
- matching(staging_record, table_name).delete_all
35
+ Connection.with_production_writes(Record) do
36
+ matching(staging_record, table_name).delete_all
37
+ end
34
38
  end
35
39
 
36
40
  def exists?(staging_record, table_name = nil)
@@ -1,3 +1,3 @@
1
1
  module Stagehand
2
- VERSION = "0.9.2"
2
+ VERSION = "0.10.0"
3
3
  end
@@ -19,9 +19,11 @@ namespace :stagehand do
19
19
  def rake_both_databases(task, stagehand_task = task.gsub(':','_'))
20
20
  task(stagehand_task => :environment) do
21
21
  Stagehand::Database.each do |connection_name|
22
- puts "#{connection_name}"
23
- Rake::Task[task].reenable
24
- Rake::Task[task].invoke
22
+ Stagehand::Connection.with_production_writes(ActiveRecord::Base) do
23
+ puts "#{connection_name}"
24
+ Rake::Task[task].reenable
25
+ Rake::Task[task].invoke
26
+ end
25
27
  end
26
28
  Rake::Task[task].clear
27
29
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: culturecode_stagehand
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nicholas Jakobsen
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-09-12 00:00:00.000000000 Z
12
+ date: 2016-09-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -71,6 +71,7 @@ files:
71
71
  - lib/stagehand/auditor.rb
72
72
  - lib/stagehand/cache.rb
73
73
  - lib/stagehand/configuration.rb
74
+ - lib/stagehand/connection_adapter_extensions.rb
74
75
  - lib/stagehand/controller_extensions.rb
75
76
  - lib/stagehand/database.rb
76
77
  - lib/stagehand/engine.rb