culturecode_stagehand 1.1.2 → 1.1.5

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: fc5e551f7e747ad8fb67d445f787bd47df6059fbe939f65088901445e4ccc5db
4
- data.tar.gz: d7d1a28bdac8a210119431075d48fa5cfafaadf311958926e13e10ac5c5dda9c
3
+ metadata.gz: b9684506c931ca15ad9c467e5d96fb359ede46c3d41624331b72b7efe0b7b850
4
+ data.tar.gz: 43f4509740eb53ace3293ad6bdbd718562e165adf282e1ca2114c5daebd5ee15
5
5
  SHA512:
6
- metadata.gz: d73461a90dceed0855d2779925174f1ced0b4ba9a2a9b47c0948fa1faef6666eb5ee83af52481114033a99367747baf82b1161617ff73c30721c19dfedf5e28e
7
- data.tar.gz: 3a2443903c414b6f87ccb312d77b165428e036ae80bc04a103234a7efc373d5068f9f329d8c87c987a9e1605929237053e5b276de1dedd79860028e3fb9bc5a4
6
+ metadata.gz: 5cca6f14c6f8c9194d400a5c21bb49f90758e2160a9ebac99b72621f8b64410f91429a5b6f3ba62db4faf92d7d50caf1caee66a4d5631ccf4ac196206677130c
7
+ data.tar.gz: 28f4439a34ed046edff565df691fd4d1fada3e227a52a9fc3d60fec9b245db8d0a0c4e50629ab86febc7e5d0171c270b7257ee4121b0b5517296f6fb152b4eb6
@@ -6,7 +6,7 @@ module Stagehand
6
6
  def initialize(checklist, show_all_commits: false)
7
7
  entries = checklist.affected_entries.select(&:commit_id)
8
8
 
9
- @graph = GraphViz.new( :G, :type => :graph );
9
+ @graph = GraphViz.new( :G, :type => :graph )
10
10
  @commits = Hash.new {|hash, commit_id| hash[commit_id] = Stagehand::Staging::CommitEntry.find(commit_id) }
11
11
  nodes = Hash.new
12
12
  edges = []
@@ -24,16 +24,22 @@ module Stagehand
24
24
 
25
25
  # Create Subgraph nodes for commits with connections to other subjects
26
26
  entries = edges.flatten.uniq unless show_all_commits
27
- entries.group_by {|entry| commit_subject(entry) }.each do |subject, entries|
28
- subgraph = create_subgraph(subject, @graph)
27
+ entries.group_by {|entry| commit_subject(entry) || entry.commit_id }.each do |group, entries|
28
+ subject = commit_subject(entries.first)
29
+ subgraph = create_subgraph(subject, @graph, id: group)
29
30
  entries.each do |entry|
30
31
  nodes[entry] = create_node(entry, subgraph)
31
32
  end
32
33
  end
33
34
 
35
+ # Create deduplicate edge data in case multiple entries for the same record were part of a single commit
36
+ edges = edges.map do |entry_a, entry_b|
37
+ [[nodes[entry_a], nodes[entry_b]], label: edge_label(entry_a, entry_b)]
38
+ end
39
+
34
40
  # Create edges
35
- edges.each do |entry_a, entry_b|
36
- create_edge(nodes[entry_a], nodes[entry_b], :label => edge_label(entry_a, entry_b))
41
+ edges.uniq.each do |(node_a, node_b), options|
42
+ create_edge(node_a, node_b, options)
37
43
  end
38
44
  end
39
45
 
@@ -44,8 +50,8 @@ module Stagehand
44
50
 
45
51
  private
46
52
 
47
- def create_subgraph(subject, graph)
48
- graph.add_graph("cluster_#{subject}", :label => subject, :style => :filled, :color => :lightgrey)
53
+ def create_subgraph(subject, graph, id: subject)
54
+ graph.add_graph("cluster_#{id}", :label => subject, :style => :filled, :color => :lightgrey)
49
55
  end
50
56
 
51
57
  def create_edge(node_a, node_b, options = {})
@@ -65,7 +71,7 @@ module Stagehand
65
71
  end
66
72
 
67
73
  def same_subject?(entry_a, entry_b)
68
- commit_subject(entry_a) == commit_subject(entry_b)
74
+ commit_subject(entry_a) == commit_subject(entry_b) && commit_subject(entry_a)
69
75
  end
70
76
 
71
77
  def commit_subject(entry)
@@ -77,7 +83,7 @@ module Stagehand
77
83
  end
78
84
 
79
85
  def pretty_key(entry)
80
- "#{entry.table_name.classify} #{entry.record_id}"
86
+ "#{entry.table_name.classify} #{entry.record_id}" if entry.record_id && entry.table_name
81
87
  end
82
88
  end
83
89
  end
@@ -9,7 +9,8 @@ module Stagehand
9
9
  module Configuration
10
10
  extend self
11
11
 
12
- mattr_accessor :checklist_confirmation_filter, :checklist_association_filter, :checklist_relation_filter
12
+ mattr_accessor :checklist_confirmation_filter, :checklist_association_filter, :checklist_relation_filter, :ignored_columns
13
+ self.ignored_columns = HashWithIndifferentAccess.new
13
14
 
14
15
  def staging_connection_name
15
16
  Rails.env.to_sym
@@ -33,5 +34,11 @@ module Stagehand
33
34
  def single_connection?
34
35
  staging_connection_name == production_connection_name
35
36
  end
37
+
38
+ # Columns not to copy to the production database
39
+ # e.g. table_name => [column, column, ...]
40
+ def self.ignored_columns=(hash)
41
+ super HashWithIndifferentAccess.new(hash)
42
+ end
36
43
  end
37
44
  end
@@ -1,15 +1,22 @@
1
1
  module Stagehand
2
2
  module Connection
3
- def self.with_production_writes(model, &block)
4
- model.connection.allow_writes(&block)
3
+ def self.with_production_writes(&block)
4
+ state = allow_unsynced_production_writes?
5
+ allow_unsynced_production_writes!(true)
6
+ return block.call
7
+ ensure
8
+ allow_unsynced_production_writes!(state)
5
9
  end
6
10
 
7
- module AdapterExtensions
8
- def self.prepended(base)
9
- base.set_callback :checkout, :after, :update_readonly_state
10
- base.set_callback :checkin, :before, :clear_readonly_state
11
- end
11
+ def self.allow_unsynced_production_writes!(state = true)
12
+ Thread.current[:stagehand_allow_unsynced_production_writes] = state
13
+ end
12
14
 
15
+ def self.allow_unsynced_production_writes?
16
+ !!Thread.current[:stagehand_allow_unsynced_production_writes]
17
+ end
18
+
19
+ module AdapterExtensions
13
20
  def exec_insert(*)
14
21
  handle_readonly_writes!
15
22
  super
@@ -25,34 +32,14 @@ module Stagehand
25
32
  super
26
33
  end
27
34
 
28
- def allow_writes(&block)
29
- state = readonly?
30
- readonly!(false)
31
- return block.call
32
- ensure
33
- readonly!(state)
34
- end
35
-
36
- def readonly!(state = true)
37
- @readonly = state
38
- end
39
-
40
- def readonly?
41
- !!@readonly
42
- end
43
-
44
35
  private
45
36
 
46
- def update_readonly_state
47
- readonly! unless Configuration.single_connection? || @config[:database] == Database.staging_database_name
48
- end
49
-
50
- def clear_readonly_state
51
- readonly!(false)
37
+ def write_access?
38
+ Configuration.single_connection? || @config[:database] == Database.staging_database_name || Connection.allow_unsynced_production_writes?
52
39
  end
53
40
 
54
41
  def handle_readonly_writes!
55
- if !readonly?
42
+ if write_access?
56
43
  return
57
44
  elsif Configuration.allow_unsynced_production_writes?
58
45
  Rails.logger.warn "Writing directly to #{@config[:database]} database using readonly connection"
@@ -24,7 +24,7 @@ module Stagehand
24
24
  end
25
25
 
26
26
  def write(staging_record, attributes, table_name = nil)
27
- Connection.with_production_writes(Record) do
27
+ Connection.with_production_writes do
28
28
  is_new = matching(staging_record, table_name).update_all(attributes).zero?
29
29
 
30
30
  # Ensure we always return a record, even when updating instead of creating
@@ -37,7 +37,7 @@ module Stagehand
37
37
  end
38
38
 
39
39
  def delete(staging_record, table_name = nil)
40
- Connection.with_production_writes(Record) do
40
+ Connection.with_production_writes do
41
41
  matching(staging_record, table_name).delete_all
42
42
  end
43
43
  end
@@ -78,7 +78,12 @@ module Stagehand
78
78
 
79
79
  def staging_record_attributes(staging_record, table_name = nil)
80
80
  table_name, id = Stagehand::Key.generate(staging_record, :table_name => table_name)
81
- Stagehand::Staging::CommitEntry.connection.select_one("SELECT * FROM #{table_name} WHERE id = #{id}")
81
+ hash = Stagehand::Staging::CommitEntry.connection.select_one("SELECT * FROM #{table_name} WHERE id = #{id}")
82
+ hash&.except(*ignored_columns(table_name))
83
+ end
84
+
85
+ def ignored_columns(table_name)
86
+ Array.wrap(Configuration.ignored_columns[table_name]).map(&:to_s)
82
87
  end
83
88
 
84
89
  # CLASSES
@@ -2,7 +2,7 @@ module Stagehand
2
2
  module SchemaExtensions
3
3
  def define(*)
4
4
  # Allow production writes during Schema.define to allow Rails to write to ar_internal_metadata table
5
- Stagehand::Connection.with_production_writes(ActiveRecord::Base) { super }
5
+ Stagehand::Connection.with_production_writes { super }
6
6
  end
7
7
  end
8
8
  end
@@ -89,7 +89,20 @@ module Stagehand
89
89
  private
90
90
 
91
91
  def self.associated_associations(klass)
92
- cache("#{klass.name}_associated_associations") { klass.reflect_on_all_associations(:belongs_to).collect(&:name) }
92
+ cache("#{klass.name}_associated_associations") do
93
+ reflections = klass.reflect_on_all_associations(:belongs_to)
94
+
95
+ reflections.select! do |reflection|
96
+ begin
97
+ reflection.check_preloadable!
98
+ next true
99
+ rescue ArgumentError
100
+ next false
101
+ end
102
+ end
103
+
104
+ reflections.collect(&:name)
105
+ end
93
106
  end
94
107
 
95
108
  def self.stagehand_class?(klass)
@@ -1,3 +1,3 @@
1
1
  module Stagehand
2
- VERSION = "1.1.2"
2
+ VERSION = "1.1.5"
3
3
  end
@@ -20,7 +20,7 @@ namespace :stagehand do
20
20
  def rake_both_databases(task, stagehand_task = task.gsub(':','_'))
21
21
  task(stagehand_task => :environment) do
22
22
  Stagehand::Database.each do |connection_name|
23
- Stagehand::Connection.with_production_writes(ActiveRecord::Base) do
23
+ Stagehand::Connection.with_production_writes do
24
24
  puts "#{connection_name}"
25
25
  Rake::Task[task].reenable
26
26
  Rake::Task[task].invoke
@@ -35,4 +35,5 @@ namespace :stagehand do
35
35
 
36
36
  rake_both_databases('db:migrate')
37
37
  rake_both_databases('db:rollback')
38
+ rake_both_databases('db:test:load_structure')
38
39
  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: 1.1.2
4
+ version: 1.1.5
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: 2019-08-15 00:00:00.000000000 Z
12
+ date: 2020-06-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails