From accb31ade76b6a747dea856d42e870ccc8e1e105 Mon Sep 17 00:00:00 2001 From: Samir Jha Date: Tue, 24 Sep 2024 16:26:42 +0000 Subject: [PATCH] Fixes #37859 - Re-drop evr extension in katello --- config/initializers/monkeys.rb | 1 - db/migrate/20200213184848_create_evr_type.rb | 127 +++++++++++++- ...4161240_katello_recreate_evr_constructs.rb | 160 ++++++++++++++++++ lib/monkeys/fx_sqlite_skip.rb | 13 -- 4 files changed, 286 insertions(+), 15 deletions(-) create mode 100644 db/migrate/20240924161240_katello_recreate_evr_constructs.rb delete mode 100644 lib/monkeys/fx_sqlite_skip.rb diff --git a/config/initializers/monkeys.rb b/config/initializers/monkeys.rb index 8ed5b9fe7a5..1cba332c8aa 100644 --- a/config/initializers/monkeys.rb +++ b/config/initializers/monkeys.rb @@ -1,4 +1,3 @@ #place where monkey patches are required require 'monkeys/ar_postgres_evr_t' -require 'monkeys/fx_sqlite_skip' require 'monkeys/remove_hidden_distribution' diff --git a/db/migrate/20200213184848_create_evr_type.rb b/db/migrate/20200213184848_create_evr_type.rb index 8bd6bfe9148..d0122e3c52a 100644 --- a/db/migrate/20200213184848_create_evr_type.rb +++ b/db/migrate/20200213184848_create_evr_type.rb @@ -4,7 +4,132 @@ class CreateEvrType < ActiveRecord::Migration[5.2] def up unless connection.adapter_name.downcase.include?('sqlite') - enable_extension "evr" + execute <<~SQL + create type evr_array_item as ( + n NUMERIC, + s TEXT + ); + + create type evr_t as ( + epoch INT, + version evr_array_item[], + release evr_array_item[] + ); + + CREATE FUNCTION evr_trigger() RETURNS trigger AS $$ + BEGIN + NEW.evr = (select ROW(coalesce(NEW.epoch::numeric,0), + rpmver_array(coalesce(NEW.version,'empty'))::evr_array_item[], + rpmver_array(coalesce(NEW.release,'empty'))::evr_array_item[])::evr_t); + RETURN NEW; + END; + $$ language 'plpgsql'; + + create or replace FUNCTION empty(t TEXT) + RETURNS BOOLEAN as $$ + BEGIN + return t ~ '^[[:space:]]*$'; + END; + $$ language 'plpgsql'; + + create or replace FUNCTION isalpha(ch CHAR) + RETURNS BOOLEAN as $$ + BEGIN + if ascii(ch) between ascii('a') and ascii('z') or + ascii(ch) between ascii('A') and ascii('Z') + then + return TRUE; + end if; + return FALSE; + END; + $$ language 'plpgsql'; + + create or replace FUNCTION isalphanum(ch CHAR) + RETURNS BOOLEAN as $$ + BEGIN + if ascii(ch) between ascii('a') and ascii('z') or + ascii(ch) between ascii('A') and ascii('Z') or + ascii(ch) between ascii('0') and ascii('9') + then + return TRUE; + end if; + return FALSE; + END; + $$ language 'plpgsql'; + + create or replace function isdigit(ch CHAR) + RETURNS BOOLEAN as $$ + BEGIN + if ascii(ch) between ascii('0') and ascii('9') + then + return TRUE; + end if; + return FALSE; + END ; + $$ language 'plpgsql'; + + create or replace FUNCTION rpmver_array (string1 IN VARCHAR) + RETURNS evr_array_item[] as $$ + declare + str1 VARCHAR := string1; + digits VARCHAR(10) := '0123456789'; + lc_alpha VARCHAR(27) := 'abcdefghijklmnopqrstuvwxyz'; + uc_alpha VARCHAR(27) := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + alpha VARCHAR(54) := lc_alpha || uc_alpha; + one VARCHAR; + isnum BOOLEAN; + ver_array evr_array_item[] := ARRAY[]::evr_array_item[]; + BEGIN + if str1 is NULL + then + RAISE EXCEPTION 'VALUE_ERROR.'; + end if; + + one := str1; + <> + while one <> '' + loop + declare + segm1 VARCHAR; + segm1_n NUMERIC := 0; + begin + -- Throw out all non-alphanum characters + while one <> '' and not isalphanum(one) + loop + one := substr(one, 2); + end loop; + str1 := one; + if str1 <> '' and isdigit(str1) + then + str1 := ltrim(str1, digits); + isnum := true; + else + str1 := ltrim(str1, alpha); + isnum := false; + end if; + if str1 <> '' + then segm1 := substr(one, 1, length(one) - length(str1)); + else segm1 := one; + end if; + + if segm1 = '' then return ver_array; end if; /* arbitrary */ + if isnum + then + segm1 := ltrim(segm1, '0'); + if segm1 <> '' then segm1_n := segm1::numeric; end if; + segm1 := NULL; + else + end if; + ver_array := array_append(ver_array, (segm1_n, segm1)::evr_array_item); + one := str1; + end; + end loop segment_loop; + + return ver_array; + END ; + $$ language 'plpgsql'; + + SQL add_column :katello_rpms, :evr, :evr_t add_column :katello_installed_packages, :evr, :evr_t diff --git a/db/migrate/20240924161240_katello_recreate_evr_constructs.rb b/db/migrate/20240924161240_katello_recreate_evr_constructs.rb new file mode 100644 index 00000000000..1a5367e64f2 --- /dev/null +++ b/db/migrate/20240924161240_katello_recreate_evr_constructs.rb @@ -0,0 +1,160 @@ +class KatelloRecreateEvrConstructs < ActiveRecord::Migration[6.1] + def up + if !extension_enabled?('evr') + return + else + execute <<~SQL + DROP EXTENSION evr CASCADE; + SQL + + execute <<~SQL + create type evr_array_item as ( + n NUMERIC, + s TEXT + ); + + create type evr_t as ( + epoch INT, + version evr_array_item[], + release evr_array_item[] + ); + + CREATE FUNCTION evr_trigger() RETURNS trigger AS $$ + BEGIN + NEW.evr = (select ROW(coalesce(NEW.epoch::numeric,0), + rpmver_array(coalesce(NEW.version,'empty'))::evr_array_item[], + rpmver_array(coalesce(NEW.release,'empty'))::evr_array_item[])::evr_t); + RETURN NEW; + END; + $$ language 'plpgsql'; + + create or replace FUNCTION empty(t TEXT) + RETURNS BOOLEAN as $$ + BEGIN + return t ~ '^[[:space:]]*$'; + END; + $$ language 'plpgsql'; + + create or replace FUNCTION isalpha(ch CHAR) + RETURNS BOOLEAN as $$ + BEGIN + if ascii(ch) between ascii('a') and ascii('z') or + ascii(ch) between ascii('A') and ascii('Z') + then + return TRUE; + end if; + return FALSE; + END; + $$ language 'plpgsql'; + + create or replace FUNCTION isalphanum(ch CHAR) + RETURNS BOOLEAN as $$ + BEGIN + if ascii(ch) between ascii('a') and ascii('z') or + ascii(ch) between ascii('A') and ascii('Z') or + ascii(ch) between ascii('0') and ascii('9') + then + return TRUE; + end if; + return FALSE; + END; + $$ language 'plpgsql'; + + create or replace function isdigit(ch CHAR) + RETURNS BOOLEAN as $$ + BEGIN + if ascii(ch) between ascii('0') and ascii('9') + then + return TRUE; + end if; + return FALSE; + END ; + $$ language 'plpgsql'; + + create or replace FUNCTION rpmver_array (string1 IN VARCHAR) + RETURNS evr_array_item[] as $$ + declare + str1 VARCHAR := string1; + digits VARCHAR(10) := '0123456789'; + lc_alpha VARCHAR(27) := 'abcdefghijklmnopqrstuvwxyz'; + uc_alpha VARCHAR(27) := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + alpha VARCHAR(54) := lc_alpha || uc_alpha; + one VARCHAR; + isnum BOOLEAN; + ver_array evr_array_item[] := ARRAY[]::evr_array_item[]; + BEGIN + if str1 is NULL + then + RAISE EXCEPTION 'VALUE_ERROR.'; + end if; + + one := str1; + <> + while one <> '' + loop + declare + segm1 VARCHAR; + segm1_n NUMERIC := 0; + begin + -- Throw out all non-alphanum characters + while one <> '' and not isalphanum(one) + loop + one := substr(one, 2); + end loop; + str1 := one; + if str1 <> '' and isdigit(str1) + then + str1 := ltrim(str1, digits); + isnum := true; + else + str1 := ltrim(str1, alpha); + isnum := false; + end if; + if str1 <> '' + then segm1 := substr(one, 1, length(one) - length(str1)); + else segm1 := one; + end if; + + if segm1 = '' then return ver_array; end if; /* arbitrary */ + if isnum + then + segm1 := ltrim(segm1, '0'); + if segm1 <> '' then segm1_n := segm1::numeric; end if; + segm1 := NULL; + else + end if; + ver_array := array_append(ver_array, (segm1_n, segm1)::evr_array_item); + one := str1; + end; + end loop segment_loop; + + return ver_array; + END ; + $$ language 'plpgsql'; + + SQL + + add_column :katello_rpms, :evr, :evr_t + add_column :katello_installed_packages, :evr, :evr_t + + execute <<-SQL + update katello_rpms SET evr = (ROW(coalesce(epoch::numeric,0), + rpmver_array(coalesce(version,'empty'))::evr_array_item[], + rpmver_array(coalesce(release,'empty'))::evr_array_item[])::evr_t); + + update katello_installed_packages SET evr = (ROW(coalesce(epoch::numeric,0), + rpmver_array(coalesce(version,'empty'))::evr_array_item[], + rpmver_array(coalesce(release,'empty'))::evr_array_item[])::evr_t); + SQL + + create_trigger :evr_insert_trigger_katello_rpms, on: :katello_rpms + create_trigger :evr_update_trigger_katello_rpms, on: :katello_rpms + create_trigger :evr_insert_trigger_katello_installed_packages, on: :katello_installed_packages + create_trigger :evr_update_trigger_katello_installed_packages, on: :katello_installed_packages + end + end + + def down + fail ActiveRecord::IrreversibleMigration + end +end diff --git a/lib/monkeys/fx_sqlite_skip.rb b/lib/monkeys/fx_sqlite_skip.rb deleted file mode 100644 index a9a4bf0ac74..00000000000 --- a/lib/monkeys/fx_sqlite_skip.rb +++ /dev/null @@ -1,13 +0,0 @@ -module Fx - module SchemaDumper - # @api private - module Trigger - def tables(stream) - unless ActiveRecord::Migration[5.2].connection.adapter_name.downcase.include?('sqlite') - super - triggers(stream) - end - end - end - end -end