Module: SchemaPlus::Functions::ActiveRecord::ConnectionAdapters::PostgresqlAdapter

Defined in:
lib/schema_plus/functions/active_record/connection_adapters/postgresql_adapter.rb

Instance Method Summary collapse

Instance Method Details

#drop_function(function_name, params, options = {}) ⇒ Object



7
8
9
10
# File 'lib/schema_plus/functions/active_record/connection_adapters/postgresql_adapter.rb', line 7

def drop_function(function_name, params, options = {})
  clean_params = params.gsub(/ DEFAULT[^,]+/i, '')
  super(function_name, clean_params, options)
end

#function_definition(function_name, params, name = nil) ⇒ Object

:nodoc:



46
47
48
49
50
51
52
53
54
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
80
81
82
# File 'lib/schema_plus/functions/active_record/connection_adapters/postgresql_adapter.rb', line 46

def function_definition(function_name, params, name = nil) #:nodoc:
  data = SchemaMonkey::Middleware::Schema::FunctionDefinition.start(connection: self, function_name: function_name, params: params, query_name: name) do |env|
    result = env.connection.query(<<-SQL, env.query_name)
    SELECT prosrc,
        pg_get_function_arguments(p.oid),
        pg_catalog.pg_get_function_result(p.oid) AS funcresult,
        (SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname,
        a.aggtransfn as transfn,
        format_type(a.aggtranstype, null) as transtype
      FROM pg_proc p
      LEFT JOIN pg_aggregate a ON a.aggfnoid = p.oid
    WHERE 
        pronamespace IN (SELECT oid FROM pg_namespace WHERE nspname = ANY (current_schemas(false)))
        AND proname = '#{quote_string(function_name)}'
        AND pg_get_function_identity_arguments(P.oid) = '#{quote_string(params)}'
    SQL

    row = result.first

    function_type = nil

    unless row.nil?
      sql               = if row[4].present? || row[0] == 'aggregate_dummy'
                            # it's an aggregate function
                            function_type = :aggregate
                            "(SFUNC=#{row[4]},STYPE=#{row[5]})"
                          else
                            "RETURNS #{row[2]} LANGUAGE #{row[3]} AS $$#{row[0]}$$"
                          end
      env.params        = row[1]
      env.definition    = sql
      env.function_type = function_type
    end
  end

  return data.params, data.definition, data.function_type
end

#functions(name = nil) ⇒ Object

:nodoc:



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/schema_plus/functions/active_record/connection_adapters/postgresql_adapter.rb', line 19

def functions(name = nil) #:nodoc:
  SchemaMonkey::Middleware::Schema::Functions.start(connection: self, query_name: name, functions: []) do |env|
    is_agg_column = if postgresql_version_at_least?(env, '11.0')
                      "prokind = 'a'"
                    else
                      "proisagg"
                    end
    sql = <<-SQL
      SELECT P.proname as function_name, pg_get_function_identity_arguments(P.oid), #{is_agg_column} as is_agg
        FROM pg_proc P
      WHERE
            pronamespace IN (SELECT oid FROM pg_namespace WHERE nspname = ANY (current_schemas(false))) 
        AND NOT EXISTS (SELECT 1 FROM pg_depend WHERE classid = 'pg_proc'::regclass 
              AND objid = p.oid AND deptype = 'i')
        AND NOT EXISTS (SELECT 1 FROM pg_depend WHERE classid = 'pg_proc'::regclass
              AND objid = p.oid AND refclassid = 'pg_extension'::regclass AND deptype = 'e')
      ORDER BY 1,2
    SQL

    env.functions += env.connection.query(sql, env.query_name).map do |row|
      options                 = {}
      options[:function_type] = :aggregate if row[2]
      [row[0], row[1], options]
    end
  end.functions
end

#postgresql_version_at_least?(env, required) ⇒ Boolean

Returns:

  • (Boolean)


12
13
14
15
16
17
# File 'lib/schema_plus/functions/active_record/connection_adapters/postgresql_adapter.rb', line 12

def postgresql_version_at_least?(env, required)
  @postgresql_version ||= begin
                            env.connection.select_value("SHOW server_version").match(/(\d+\.\d+)/)[1]
                          end
  Gem::Version.new(@postgresql_version) >= Gem::Version.new(required)
end