diff --git a/lib/iron_trail/db_functions.rb b/lib/iron_trail/db_functions.rb index 14ea4f0..2169401 100644 --- a/lib/iron_trail/db_functions.rb +++ b/lib/iron_trail/db_functions.rb @@ -36,14 +36,27 @@ def collect_tracked_table_names connection.execute(stmt).map { |row| row['table'] } end - def collect_all_tables(table_schema: 'public') + def function_present?(function: 'irontrail_log_row', schema: 'public') + stmt = <<~SQL + SELECT 1 FROM "pg_proc" p + INNER JOIN "pg_namespace" ns + ON (ns.oid = p.pronamespace) + WHERE p."proname"=#{connection.quote(function)} + AND ns."nspname"=#{connection.quote(schema)} + LIMIT 1; + SQL + + connection.execute(stmt).to_a.count > 0 + end + + def collect_all_tables(schema: 'public') # query pg_class rather than information schema because this way # we can get only regular tables and ignore partitions. stmt = <<~SQL SELECT c.relname AS "table" FROM "pg_class" c INNER JOIN "pg_namespace" ns ON (ns.oid = c.relnamespace) - WHERE ns.nspname=#{connection.quote(table_schema)} + WHERE ns.nspname=#{connection.quote(schema)} AND c.relkind IN ('r', 'p') AND NOT c.relispartition ORDER BY "table" ASC; diff --git a/lib/iron_trail/migration.rb b/lib/iron_trail/migration.rb index 55d7fac..57e2b30 100644 --- a/lib/iron_trail/migration.rb +++ b/lib/iron_trail/migration.rb @@ -25,7 +25,12 @@ def method_missing(method, *args) return result end - IronTrail::DbFunctions.new(connection).enable_tracking_for_table(table_name) + db_fun = IronTrail::DbFunctions.new(connection) + if db_fun.function_present? + db_fun.enable_tracking_for_table(table_name) + else + Rails.logger.warn("IronTrail will not create trigger for table #{table_name} because the trigger function does not exist in the database.") + end result end diff --git a/spec/dummy_app/db/migrate/20241112090542_setup_test_db.rb b/spec/dummy_app/db/migrate/20241112090542_setup_test_db.rb index 53fa045..c2023af 100644 --- a/spec/dummy_app/db/migrate/20241112090542_setup_test_db.rb +++ b/spec/dummy_app/db/migrate/20241112090542_setup_test_db.rb @@ -2,8 +2,6 @@ class SetupTestDb < ::ActiveRecord::Migration::Current def up - IronTrail::DbFunctions.new(connection).install_functions - create_table :people, id: :bigserial, force: true do |t| t.string :first_name, null: false t.string :last_name, null: false