Module: Arfi::Commands::FunctionsHelpers

Included in:
Functions
Defined in:
lib/arfi/commands/functions_helpers.rb,
sig/lib/arfi/commands/functions_helpers.rbs

Overview

Shared helper methods for Functions.

Constant Summary collapse

ADAPTERS =

Returns:

  • (::Array[:postgresql | :mysql | :trilogy])
IDENT =

Returns:

  • (::Regexp)
DEFAULT_SCHEMA =

Returns:

  • ("public")
ROOT_DIR =

Returns:

  • ("db/functions")

Instance Method Summary collapse

Instance Method Details

#adapter_optString?

Read the --adapter option value from CLI options.

Returns:

  • (String?)

    Adapter name or nil if not provided



139
140
141
# File 'lib/arfi/commands/functions_helpers.rb', line 139

def adapter_opt
  options[:adapter]&.to_s
end

#check_schema_conflict!(parsed_schema) ⇒ void

This method returns an undefined value.

Raise if the schema is specified both inline and via the --schema option.

Parameters:

  • parsed_schema (String?)

    Schema parsed from 'schema.function' form

Raises:

  • (ArgumentError)

    If schema is specified twice



92
93
94
95
96
# File 'lib/arfi/commands/functions_helpers.rb', line 92

def check_schema_conflict!(parsed_schema)
  return unless schema_opt && parsed_schema

  raise ArgumentError, "Schema specified twice (both 'schema.fn' and --schema). Pick one."
end

#infer_adapter_from_configString??

Infer the database adapter from the Rails primary DB configuration.

Returns:

  • (String?)

    Adapter name, or nil if inference fails

  • (nil)

    if StandardError

Raises:

  • (StandardError)


149
150
151
152
153
154
155
156
# File 'lib/arfi/commands/functions_helpers.rb', line 149

def infer_adapter_from_config
  cfg = primary_db_config
  h = cfg&.configuration_hash
  adapter = h && (h[:adapter] || h['adapter'])
  adapter&.to_s
rescue StandardError
  nil
end

#parse_function_ref(ref) ⇒ [ ::String?, ::String ]

Parse a function reference into an optional schema and function name.

Accepts 'schema.function_name' or just 'function_name' form.

Parameters:

  • ref (String)

    Function reference string

Returns:

  • ([ ::String?, ::String ])

    Array of [schema, function_name]



42
43
44
45
46
47
48
49
50
51
52
# File 'lib/arfi/commands/functions_helpers.rb', line 42

def parse_function_ref(ref)
  validate_function_ref!(ref)
  parsed_schema, parsed_fn = ref.split('.', 2)
  if parsed_fn.nil?
    parsed_fn = parsed_schema
    parsed_schema = nil
  end
  check_schema_conflict!(parsed_schema)
  schema = schema_opt || parsed_schema
  [schema, parsed_fn || '']
end

#primary_db_configObject

Get the primary database configuration for the current Rails environment.

Returns:

  • (Object)

    ActiveRecord database config object



170
171
172
173
174
175
176
177
178
# File 'lib/arfi/commands/functions_helpers.rb', line 170

def primary_db_config
  cfgs =
    if ActiveRecord::Base.respond_to?(:configurations) && ActiveRecord::Base.configurations
      ActiveRecord::Base.configurations.configurations.select { _1.env_name == Rails.env }
    else
      [] # steep:ignore
    end
  cfgs.find { _1.name == 'primary' } || cfgs.first
end

#resolve_adapterString

Resolve the effective adapter from CLI option or Rails DB config.

Returns:

  • (String)

    Resolved adapter name

Raises:

  • (ArgumentError)

    If adapter cannot be inferred



113
114
115
116
117
118
# File 'lib/arfi/commands/functions_helpers.rb', line 113

def resolve_adapter
  adapter_opt || infer_adapter_from_config || raise(
    ArgumentError,
    'Could not infer adapter. Pass --adapter=[postgresql|mysql|trilogy].'
  )
end

#resolve_functions_for(adapter:) ⇒ Array<Hash<Symbol, Object>>

Resolve the effective list of function files for a given adapter.

Parameters:

  • adapter (String)

    Adapter name (postgresql, mysql, trilogy)

  • adapter: (String)

Returns:

  • (Array<Hash<Symbol, Object>>)

    Resolved function rows

Raises:



126
127
128
129
130
131
132
133
# File 'lib/arfi/commands/functions_helpers.rb', line 126

def resolve_functions_for(adapter:)
  root = Rails.root.join(ROOT_DIR)
  raise Arfi::Errors::NoFunctionsDir unless root.directory?

  candidates = collect_all_candidates(root, adapter)
  by_key = group_candidates_by_key(candidates)
  build_resolved_rows(by_key)
end

#resolve_schema_name(schema) ⇒ String?

Resolve the effective schema name, defaulting to 'public' for PostgreSQL/generic.

Parameters:

  • schema (String?)

    User-provided schema name (optional)

Returns:

  • (String?)

    Resolved schema name or nil for MySQL/Trilogy



103
104
105
106
# File 'lib/arfi/commands/functions_helpers.rb', line 103

def resolve_schema_name(schema)
  adapter = adapter_opt
  adapter.nil? || adapter == 'postgresql' ? (schema || DEFAULT_SCHEMA) : nil
end

#schema_optString?

Read the --schema option value from CLI options.

Returns:

  • (String?)

    Schema name or nil if not provided



162
163
164
# File 'lib/arfi/commands/functions_helpers.rb', line 162

def schema_opt
  options[:schema]&.to_s
end

#validate_adapter_option!void

This method returns an undefined value.

Validate that the --adapter option, if provided, is one of the supported adapters.

Raises:



29
30
31
32
33
# File 'lib/arfi/commands/functions_helpers.rb', line 29

def validate_adapter_option!
  opt = adapter_opt
  return if opt.nil?
  raise Arfi::Errors::AdapterNotSupported unless ADAPTERS.map(&:to_s).include?(opt)
end

#validate_function_ref!(ref) ⇒ void

This method returns an undefined value.

Validate that a function reference is a non-empty string without path separators.

Parameters:

  • ref (String)

    Function reference string

Raises:

  • (ArgumentError)

    If reference is invalid



78
79
80
81
82
83
84
# File 'lib/arfi/commands/functions_helpers.rb', line 78

def validate_function_ref!(ref)
  raise ArgumentError, "Invalid function name: #{ref.inspect}" unless ref.is_a?(String)

  sep = [File::SEPARATOR, File::ALT_SEPARATOR].compact
  bad = ref.empty? || ref.include?('..') || sep.any? { |s| ref.include?(s) }
  raise ArgumentError, "Invalid function name: #{ref.inspect}" if bad
end

#validate_identifiers!(schema, function_name) ⇒ void

This method returns an undefined value.

Validate that schema and function name match the allowed identifier pattern.

Schema-qualified functions are only allowed for PostgreSQL adapter.

Parameters:

  • schema (String?)

    Schema name to validate (optional)

  • function_name (String)

    Function name to validate

Raises:

  • (ArgumentError)

    If identifiers are invalid



63
64
65
66
67
68
69
70
# File 'lib/arfi/commands/functions_helpers.rb', line 63

def validate_identifiers!(schema, function_name)
  raise ArgumentError, "Invalid function name: #{function_name.inspect}" unless IDENT.match?(function_name)
  return if schema.nil?
  raise ArgumentError, "Invalid schema name: #{schema.inspect}" unless IDENT.match?(schema)
  return unless adapter_opt && adapter_opt != 'postgresql'

  raise ArgumentError, 'Schema-qualified functions are only supported for PostgreSQL (adapter=postgresql).'
end

#validate_schema_format!void

This method returns an undefined value.

Validate that the Rails schema format is set to :ruby.

Raises:



14
15
16
17
18
19
20
21
22
# File 'lib/arfi/commands/functions_helpers.rb', line 14

def validate_schema_format!
  fmt =
    if defined?(Rails) && Rails.application
      Rails.application.config.active_record.schema_format
    elsif defined?(ActiveRecord::Base) && ActiveRecord::Base.respond_to?(:schema_format)
      ActiveRecord::Base.schema_format
    end
  raise Arfi::Errors::InvalidSchemaFormat unless fmt == :ruby
end