Class: Woods::Extractors::DatabaseViewExtractor

Inherits:
Object
  • Object
show all
Includes:
SharedDependencyScanner, SharedUtilityMethods
Defined in:
lib/woods/extractors/database_view_extractor.rb

Overview

DatabaseViewExtractor handles SQL view file extraction.

Scans ‘db/views/` for Scenic gem convention SQL files (e.g., `db/views/active_users_v01.sql`). Extracts one unit per view name using the latest version only, parsing basic SQL metadata (materialized flag, referenced tables, selected columns) via regex.

Examples:

extractor = DatabaseViewExtractor.new
units = extractor.extract_all
view = units.find { |u| u.identifier == "active_users" }
view.[:is_materialized] # => false
view.[:tables_referenced] # => ["users", "orders"]

Constant Summary collapse

INTERNAL_TABLES =

Rails internal tables that should not generate model dependencies

%w[
  schema_migrations
  ar_internal_metadata
  active_storage_blobs
  active_storage_attachments
  active_storage_variant_records
  action_text_rich_texts
  action_mailbox_inbound_emails
].freeze
SQL_KEYWORDS =

SQL keywords that are not table names

%w[
  select from where join inner outer left right full cross
  on and or not in is null true false as with having group by
  order limit offset union intersect except distinct all case when
  then else end between like ilike similar to cast values lateral
  returning exists any some
].freeze

Constants included from SharedDependencyScanner

SharedDependencyScanner::FORM_ACTION_HELPER, SharedDependencyScanner::ROUTE_HELPER_PATTERN

Instance Method Summary collapse

Methods included from SharedDependencyScanner

#extract_constantize_targets, #scan_common_dependencies, #scan_form_dependencies, #scan_job_dependencies, #scan_mailer_dependencies, #scan_model_dependencies, #scan_navigation_dependencies, #scan_service_dependencies

Methods included from SharedUtilityMethods

#app_source?, #condition_label, #count_loc, #detect_entry_points, #extract_action_filter_actions, #extract_callback_conditions, #extract_class_methods, #extract_class_name, #extract_custom_errors, #extract_initialize_params, #extract_namespace, #extract_parent_class, #extract_public_methods, #resolve_source_location, #skip_file?

Constructor Details

#initializeDatabaseViewExtractor

Returns a new instance of DatabaseViewExtractor.



46
47
48
49
# File 'lib/woods/extractors/database_view_extractor.rb', line 46

def initialize
  @views_dir = Rails.root.join('db/views')
  @has_directory = @views_dir.directory?
end

Instance Method Details

#extract_allArray<ExtractedUnit>

Extract all database view units from db/views/.

Only the latest version of each view is extracted.

Returns:



56
57
58
59
60
61
62
# File 'lib/woods/extractors/database_view_extractor.rb', line 56

def extract_all
  return [] unless @has_directory

  latest_view_files.filter_map do |file|
    extract_view_file(file)
  end
end

#extract_view_file(file_path) ⇒ ExtractedUnit?

Extract a single SQL view file.

Parameters:

  • file_path (String)

    Absolute path to the SQL file

Returns:



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/woods/extractors/database_view_extractor.rb', line 68

def extract_view_file(file_path)
  source = File.read(file_path)
  view_name = extract_view_name(file_path)
  version   = extract_version(file_path)

  return nil unless view_name

  unit = ExtractedUnit.new(
    type: :database_view,
    identifier: view_name,
    file_path: file_path
  )

  unit.namespace = nil
  unit.source_code = annotate_source(source, view_name, version)
  unit. = (source, view_name, version)
  unit.dependencies = extract_dependencies(source, unit.)

  unit
rescue StandardError => e
  Rails.logger.error("Failed to extract database view #{file_path}: #{e.message}")
  nil
end