Module: JadeSql::SchemaGenerator

Extended by:
SchemaGenerator
Included in:
SchemaGenerator
Defined in:
lib/jade-sql/bin/generate_schema.rb

Defined Under Namespace

Classes: Column, Table

Constant Summary collapse

TYPE_MAP =

Array variants are listed first because ‘b` would otherwise match the scalar prefix of e.g. `text[]` and map it to “String”.

{
  /\Abigint\[\]/ => "List(Int)",
  /\Ainteger\[\]/ => "List(Int)",
  /\Asmallint\[\]/ => "List(Int)",
  /\Acharacter varying\[\]/ => "List(String)",
  /\Avarchar\[\]/ => "List(String)",
  /\Atext\[\]/ => "List(String)",
  /\Aboolean\[\]/ => "List(Bool)",
  /\Abool\[\]/ => "List(Bool)",
  /\Ajsonb?\[\]/ => "List(Decode.Value)",
  /\Adate\[\]/ => "List(Calendar.Date)",
  /\Atimestamp\[\]/ => "List(Clock.Instant)",
  /\Auuid\[\]/ => "List(Uuid)",

  /\Abigint\b/ => "Int",
  /\Ainteger\b/ => "Int",
  /\Asmallint\b/ => "Int",
  /\Acharacter varying\b/ => "String",
  /\Avarchar\b/ => "String",
  /\Acharacter\b/ => "String",
  /\Achar\b/ => "String",
  /\Atext\b/ => "String",
  /\Aboolean\b/ => "Bool",
  /\Abool\b/ => "Bool",
  /\Ajsonb?\b/ => "Decode.Value",
  /\Adate\b/ => "Calendar.Date",
  /\Atimestamp\b/ => "Clock.Instant",
  /\Auuid\b/ => "Uuid",
}.freeze
EXTRA_IMPORTS =
{
  "Calendar.Date" => "import Calendar",
  "Clock.Instant" => "import Clock",
  "Decode.Value"  => "import Decode",
  "Uuid"          => "import Sql.Uuid exposing(Uuid)",
}.freeze

Instance Method Summary collapse

Instance Method Details

#format(text) ⇒ Object

Run jade-fmt over the emitted source so the written schema.jd matches what the formatter would produce — keeps the generator output stable across formatter improvements and avoids spurious diffs when users re-format their tree.



65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/jade-sql/bin/generate_schema.rb', line 65

def format(text)
  source = ::Jade::Source.new(uri: '<schema>', text: text)
  ::Jade::Lexer.tokenize(source)
    .then { ::Jade::Parsing.parse(it, source:) }
    .map { |(ast, comments)| ::Jade::Formatter.format(ast, comments:, source:) }
    .then do
      case it
      in ::Jade::Ok(result) then result.end_with?("\n") ? result : "#{result}\n"
      in ::Jade::Err(_) then text  # parse error — return unformatted; downstream compile will surface it
      end
    end
end

#generate(sql, tables: nil, module_name: 'Schema') ⇒ Object



53
54
55
56
57
58
59
# File 'lib/jade-sql/bin/generate_schema.rb', line 53

def generate(sql, tables: nil, module_name: 'Schema')
  parsed = parse_tables(sql)
  pks = parse_pks(sql)
  parsed = parsed.map { |t| t.with(pk_columns: pks[t.name] || []) }
  parsed = filter_tables(parsed, tables) if tables
  format(emit(parsed, module_name))
end