Class: Rails::Schema::Extractor::StructureSqlParser

Inherits:
Object
  • Object
show all
Defined in:
lib/rails/schema/extractor/structure_sql_parser.rb

Constant Summary collapse

SQL_TYPE_MAP =
{
  "character varying" => "string", "varchar" => "string",
  "integer" => "integer", "smallint" => "integer", "serial" => "integer",
  "bigint" => "bigint", "bigserial" => "bigint",
  "boolean" => "boolean", "text" => "text",
  "timestamp without time zone" => "datetime", "timestamp with time zone" => "datetime",
  "timestamp" => "datetime",
  "json" => "json", "jsonb" => "jsonb", "uuid" => "uuid",
  "numeric" => "decimal", "decimal" => "decimal", "money" => "decimal",
  "date" => "date",
  "float" => "float", "double precision" => "float", "real" => "float",
  "bytea" => "binary"
}.freeze
COMPOUND_TYPE_RE =
/\A(character\s+varying|bit\s+varying|double\s+precision|
timestamp(?:\(\d+\))?\s+with(?:out)?\s+time\s+zone)/ix.freeze
CONSTRAINT_RE =
/\A(CONSTRAINT|UNIQUE|CHECK|EXCLUDE|FOREIGN\s+KEY)\b/i.freeze
PK_CONSTRAINT_RE =
/PRIMARY\s+KEY\s*\(([^)]+)\)/i.freeze

Instance Method Summary collapse

Constructor Details

#initialize(structure_path = nil) ⇒ StructureSqlParser

Returns a new instance of StructureSqlParser.



26
27
28
# File 'lib/rails/schema/extractor/structure_sql_parser.rb', line 26

def initialize(structure_path = nil)
  @structure_path = structure_path
end

Instance Method Details

#parseObject



30
31
32
33
34
35
# File 'lib/rails/schema/extractor/structure_sql_parser.rb', line 30

def parse
  path = resolve_path
  return {} unless path && File.exist?(path)

  parse_content(File.read(path))
end

#parse_content(content) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/rails/schema/extractor/structure_sql_parser.rb', line 37

def parse_content(content)
  tables = {}

  content.scan(/CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?([\w."]+)\s*\((.*?)\)\s*;/mi) do |table_name, body|
    name = extract_table_name(table_name)
    columns, pk_columns = parse_table_body(body)
    pk_columns.each { |pk| columns.find { |c| c[:name] == pk }&.[]= :primary, true }
    tables[name] = columns
  end

  tables
end