Class: Rooq::Generator::Introspector

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/rooq/generator/introspector.rb

Constant Summary collapse

PG_TYPE_MAP =
T.let({
  "integer" => :integer,
  "bigint" => :bigint,
  "smallint" => :smallint,
  "serial" => :integer,
  "bigserial" => :bigint,
  "real" => :float,
  "double precision" => :double,
  "numeric" => :decimal,
  "decimal" => :decimal,
  "character varying" => :string,
  "varchar" => :string,
  "character" => :string,
  "char" => :string,
  "text" => :text,
  "boolean" => :boolean,
  "date" => :date,
  "timestamp without time zone" => :datetime,
  "timestamp with time zone" => :datetime_tz,
  "time without time zone" => :time,
  "time with time zone" => :time_tz,
  "uuid" => :uuid,
  "json" => :json,
  "jsonb" => :jsonb,
  "bytea" => :binary,
  "inet" => :inet,
  "cidr" => :cidr,
  "macaddr" => :macaddr
}.freeze, T::Hash[String, Symbol])

Instance Method Summary collapse

Constructor Details

#initialize(connection) ⇒ void

Parameters:

  • connection (T.untyped)


42
43
44
# File 'lib/rooq/generator/introspector.rb', line 42

def initialize(connection)
  @connection = connection
end

Instance Method Details

#introspect_columns(table_name, schema: "public") ⇒ Array<ColumnInfo>

Parameters:

  • table_name (String)
  • schema (String) (defaults to: "public")

Returns:



61
62
63
64
65
66
67
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/rooq/generator/introspector.rb', line 61

def introspect_columns(table_name, schema: "public")
  columns_sql = <<~SQL
    SELECT
      column_name,
      data_type,
      is_nullable,
      column_default,
      character_maximum_length,
      numeric_precision,
      numeric_scale
    FROM information_schema.columns
    WHERE table_schema = $1
      AND table_name = $2
    ORDER BY ordinal_position
  SQL

  result = @connection.exec_params(columns_sql, [schema, table_name])
  result.map do |row|
    ColumnInfo.new(
      name: row["column_name"],
      type: map_pg_type(row["data_type"]),
      pg_type: row["data_type"],
      nullable: row["is_nullable"] == "YES",
      default: row["column_default"],
      max_length: row["character_maximum_length"]&.to_i,
      precision: row["numeric_precision"]&.to_i,
      scale: row["numeric_scale"]&.to_i
    )
  end
end

#introspect_foreign_keys(table_name, schema: "public") ⇒ Array<ForeignKeyInfo>

Parameters:

  • table_name (String)
  • schema (String) (defaults to: "public")

Returns:



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/rooq/generator/introspector.rb', line 111

def introspect_foreign_keys(table_name, schema: "public")
  fk_sql = <<~SQL
    SELECT
      kcu.column_name,
      ccu.table_name AS foreign_table_name,
      ccu.column_name AS foreign_column_name
    FROM information_schema.table_constraints tc
    JOIN information_schema.key_column_usage kcu
      ON tc.constraint_name = kcu.constraint_name
      AND tc.table_schema = kcu.table_schema
    JOIN information_schema.constraint_column_usage ccu
      ON ccu.constraint_name = tc.constraint_name
      AND ccu.table_schema = tc.table_schema
    WHERE tc.constraint_type = 'FOREIGN KEY'
      AND tc.table_schema = $1
      AND tc.table_name = $2
  SQL

  result = @connection.exec_params(fk_sql, [schema, table_name])
  result.map do |row|
    ForeignKeyInfo.new(
      column_name: row["column_name"],
      foreign_table: row["foreign_table_name"],
      foreign_column: row["foreign_column_name"]
    )
  end
end

#introspect_primary_keys(table_name, schema: "public") ⇒ Array<String>

Parameters:

  • table_name (String)
  • schema (String) (defaults to: "public")

Returns:

  • (Array<String>)


93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/rooq/generator/introspector.rb', line 93

def introspect_primary_keys(table_name, schema: "public")
  pk_sql = <<~SQL
    SELECT kcu.column_name
    FROM information_schema.table_constraints tc
    JOIN information_schema.key_column_usage kcu
      ON tc.constraint_name = kcu.constraint_name
      AND tc.table_schema = kcu.table_schema
    WHERE tc.constraint_type = 'PRIMARY KEY'
      AND tc.table_schema = $1
      AND tc.table_name = $2
    ORDER BY kcu.ordinal_position
  SQL

  result = @connection.exec_params(pk_sql, [schema, table_name])
  result.map { |row| row["column_name"] }
end

#introspect_schema(schema: "public") ⇒ Array<TableInfo>

Parameters:

  • schema (String) (defaults to: "public")

Returns:



140
141
142
143
144
145
146
147
148
149
150
# File 'lib/rooq/generator/introspector.rb', line 140

def introspect_schema(schema: "public")
  tables = introspect_tables(schema: schema)
  tables.map do |table_name|
    TableInfo.new(
      name: table_name,
      columns: introspect_columns(table_name, schema: schema),
      primary_keys: introspect_primary_keys(table_name, schema: schema),
      foreign_keys: introspect_foreign_keys(table_name, schema: schema)
    )
  end
end

#introspect_tables(schema: "public") ⇒ Array<String>

Parameters:

  • schema (String) (defaults to: "public")

Returns:

  • (Array<String>)


47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/rooq/generator/introspector.rb', line 47

def introspect_tables(schema: "public")
  tables_sql = <<~SQL
    SELECT table_name
    FROM information_schema.tables
    WHERE table_schema = $1
      AND table_type = 'BASE TABLE'
    ORDER BY table_name
  SQL

  result = @connection.exec_params(tables_sql, [schema])
  result.map { |row| row["table_name"] }
end