Module: DynamicMigrations::ActiveRecord::Migrators::Function

Included in:
DynamicMigrations::ActiveRecord::Migrators
Defined in:
lib/dynamic_migrations/active_record/migrators/function.rb

Defined Under Namespace

Classes: FunctionDoesNotExistError, MissingFunctionBlockError

Instance Method Summary collapse

Instance Method Details

#create_function(function_name, comment: nil, &block) ⇒ Object

create a postgres function



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/dynamic_migrations/active_record/migrators/function.rb', line 12

def create_function function_name, comment: nil, &block
  unless block
    raise MissingFunctionBlockError, "create_function requires a block"
  end
  # todo - remove this once steep/rbs can better handle blocks
  unless block.is_a? NilClass
    fn_sql = block.call.strip
  end

  # schema_name was not provided to this method, it comes from the migration class
  execute <<~SQL
    CREATE FUNCTION #{schema_name}.#{function_name}() returns trigger language plpgsql AS
    $$#{fn_sql}$$;
  SQL

  if comment.is_a? String
    set_function_comment function_name, comment
  end
end

#drop_function(function_name) ⇒ Object

remove a function from the schema



72
73
74
75
76
# File 'lib/dynamic_migrations/active_record/migrators/function.rb', line 72

def drop_function function_name
  execute <<~SQL
    DROP FUNCTION #{schema_name}.#{function_name}();
  SQL
end

#remove_function_comment(function_name) ⇒ Object

remove the comment from a function



86
87
88
89
90
# File 'lib/dynamic_migrations/active_record/migrators/function.rb', line 86

def remove_function_comment function_name
  execute <<~SQL
    COMMENT ON FUNCTION #{schema_name}.#{function_name} IS null;
  SQL
end

#set_function_comment(function_name, comment) ⇒ Object

add a comment to a function



79
80
81
82
83
# File 'lib/dynamic_migrations/active_record/migrators/function.rb', line 79

def set_function_comment function_name, comment
  execute <<~SQL
    COMMENT ON FUNCTION #{schema_name}.#{function_name} IS #{quote comment};
  SQL
end

#update_function(function_name, comment: nil, &block) ⇒ Object

update a postgres function



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/dynamic_migrations/active_record/migrators/function.rb', line 33

def update_function function_name, comment: nil, &block
  unless block
    raise MissingFunctionBlockError, "create_function requires a block"
  end
  # todo - remove this once steep/rbs can better handle blocks
  unless block.is_a? NilClass
    fn_sql = block.call.strip
  end

  # schema_name was not provided to this method, it comes from the migration class
  # assert it already exists
  exists_result = execute <<~SQL
    SELECT TRUE as exists
    FROM pg_proc p
    INNER JOIN pg_namespace p_n
      ON p_n.oid = p.pronamespace
    WHERE
      p.proname = #{function_name}
      AND p_n.nspname = #{schema_name}
      -- arguments (defaulting to none for now)
      AND pg_get_function_identity_arguments(p.oid) = ''
  SQL

  unless exists_result.to_a.first["exists"]
    raise FunctionDoesNotExistError, "Can not update Function. Function #{schema_name}.#{function_name} does not exist."
  end

  # create or replace will update the function
  execute <<~SQL
    CREATE OR REPLACE FUNCTION #{schema_name}.#{function_name}() returns trigger language plpgsql AS
    $$#{fn_sql}$$;
  SQL

  if comment.is_a? String
    set_function_comment function_name, comment
  end
end