Class: Pinspec::Analyzer::SchemaReader

Inherits:
Object
  • Object
show all
Includes:
Source
Defined in:
lib/pinspec/analyzer/schema_reader.rb

Constant Summary collapse

KNOWN_TYPES =
%i[
  string text citext
  integer bigint smallint tinyint float decimal numeric money
  datetime timestamp timestamptz time date
  binary blob boolean
  json jsonb hstore xml
  uuid inet cidr macaddr
  daterange numrange tsrange tstzrange int4range int8range
  interval bit bit_varying oid ltree
  primary_key serial bigserial virtual enum
].freeze
HANDLED_STATEMENTS =
%i[create_table add_index add_foreign_key enable_extension].freeze
NON_COLUMN_CALLS =
%i[index check_constraint exclusion_constraint unique_constraint].freeze
DEFAULT_ID_TYPE =
:bigint

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ SchemaReader

Returns a new instance of SchemaReader.



55
56
57
# File 'lib/pinspec/analyzer/schema_reader.rb', line 55

def initialize(path)
  @path = path
end

Class Method Details

.parse(path) ⇒ Object



43
44
45
# File 'lib/pinspec/analyzer/schema_reader.rb', line 43

def parse(path)
  new(path).parse
end

.read(app_root = ".") ⇒ Object

Raises:



29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/pinspec/analyzer/schema_reader.rb', line 29

def read(app_root = ".")
  schema = File.join(app_root, "db", "schema.rb")
  return parse(schema) if File.file?(schema)

  structure = File.join(app_root, "db", "structure.sql")
  if File.file?(structure)
    raise SchemaFormatUnsupported, structure_sql_message(structure)
  end

  raise TargetNotFound,
        "no db/schema.rb under #{app_root} (and no db/structure.sql either); " \
        "is this a Rails application root?"
end

.structure_sql_message(path) ⇒ Object



47
48
49
50
51
52
# File 'lib/pinspec/analyzer/schema_reader.rb', line 47

def structure_sql_message(path)
  "#{path} is a SQL-format schema; pinspec reads the Ruby schema DSL. " \
    "Generate one with `bin/rails db:schema:dump` after setting " \
    "`config.active_record.schema_format = :ruby`, or keep both formats " \
    "while pinspec runs. SQL-format support is spec open question 2."
end

Instance Method Details

#parseObject



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/pinspec/analyzer/schema_reader.rb', line 59

def parse
  raise SchemaFormatUnsupported, self.class.structure_sql_message(@path) if @path.end_with?(".sql")

  read_source
  collect_statements

  tables       = @raw_tables.map { |raw| build_table(raw) }
  foreign_keys = resolve_foreign_keys(tables)

  SchemaGraph.new(
    tables:             tables,
    fk_map:             foreign_keys.to_h { |fk| [fk.key, fk.to_table] },
    foreign_keys:       foreign_keys,
    skipped_statements: build_skipped(tables.map(&:name))
  )
end