Module: ActiveRecord::Temporal::SystemVersioning::SchemaStatements
- Defined in:
- lib/activerecord/temporal/system_versioning/schema_statements.rb
Instance Method Summary collapse
- #change_versioning_hook(source_table, history_table, options) ⇒ Object
- #create_versioning_hook(source_table, history_table, **options) ⇒ Object
- #drop_versioning_hook(source_table, history_table, **options) ⇒ Object
- #history_table(source_table) ⇒ Object
- #versioning_function_name(source_table, verb) ⇒ Object
- #versioning_hook(source_table) ⇒ Object
Instance Method Details
#change_versioning_hook(source_table, history_table, options) ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/activerecord/temporal/system_versioning/schema_statements.rb', line 81 def change_versioning_hook(source_table, history_table, ) .assert_valid_keys(:add_columns, :remove_columns) add_columns = ([:add_columns] || []).map(&:to_s) remove_columns = ([:remove_columns] || []).map(&:to_s) assert_table_exists!(source_table) assert_table_exists!(history_table) assert_columns_match!(source_table, history_table, add_columns) hook_definition = versioning_hook(source_table) assert_hook_has_columns!(hook_definition, remove_columns) drop_versioning_hook(source_table, history_table) new_columns = hook_definition.columns + add_columns - remove_columns create_versioning_hook source_table, history_table, columns: new_columns, primary_key: hook_definition.primary_key end |
#create_versioning_hook(source_table, history_table, **options) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/activerecord/temporal/system_versioning/schema_statements.rb', line 4 def create_versioning_hook(source_table, history_table, **) .assert_valid_keys(:columns, :primary_key) columns = .fetch(:columns, :all) primary_key = .fetch(:primary_key, :id) column_names = if columns == :all columns(source_table).map(&:name) else Array(columns).map(&:to_s) end primary_key = if primary_key.is_a?(Array) && primary_key.length == 1 primary_key.first else primary_key end assert_table_exists!(source_table) assert_table_exists!(history_table) assert_columns_match!(source_table, history_table, column_names) assert_columns_exists!(source_table, Array(primary_key)) assert_primary_key_matches!(source_table, Array(primary_key)) schema_creation = SchemaCreation.new(self) hook_definition = VersioningHookDefinition.new( source_table, history_table, columns: column_names, primary_key: primary_key, gem_version: VERSION ) execute schema_creation.accept(hook_definition) end |
#drop_versioning_hook(source_table, history_table, **options) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/activerecord/temporal/system_versioning/schema_statements.rb', line 41 def drop_versioning_hook(source_table, history_table, **) .assert_valid_keys(:columns, :primary_key, :if_exists) %i[insert update delete].each do |verb| function_name = versioning_function_name(source_table, verb) sql = "DROP FUNCTION" sql << " IF EXISTS" if [:if_exists] sql << " #{function_name}() CASCADE" execute sql end end |
#history_table(source_table) ⇒ Object
105 106 107 108 109 |
# File 'lib/activerecord/temporal/system_versioning/schema_statements.rb', line 105 def history_table(source_table) hook_definition = versioning_hook(source_table) hook_definition&.history_table end |
#versioning_function_name(source_table, verb) ⇒ Object
111 112 113 114 115 116 |
# File 'lib/activerecord/temporal/system_versioning/schema_statements.rb', line 111 def versioning_function_name(source_table, verb) identifier = "#{source_table}_#{verb}" hashed_identifier = Digest::SHA256.hexdigest(identifier).first(10) "sys_ver_func_#{hashed_identifier}" end |
#versioning_hook(source_table) ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/activerecord/temporal/system_versioning/schema_statements.rb', line 55 def versioning_hook(source_table) update_function_name = versioning_function_name(source_table, :update) row = exec_query(<<~SQL.squish, "SQL", [update_function_name]).first SELECT pg_proc.proname as function_name, obj_description(pg_proc.oid, 'pg_proc') as comment FROM pg_proc JOIN pg_namespace ON pg_proc.pronamespace = pg_namespace.oid WHERE pg_namespace.nspname NOT IN ('pg_catalog', 'information_schema') AND pg_proc.proname = $1 SQL return unless row = JSON.parse(row["comment"]) VersioningHookDefinition.new( ["source_table"], ["history_table"], columns: ["columns"], primary_key: ["primary_key"], gem_version: ["gem_version"] ) end |