Class: Pcrd::Schema::Reader

Inherits:
Object
  • Object
show all
Defined in:
lib/pcrd/schema/reader.rb

Constant Summary collapse

TYPALIGN_BYTES =
{ "c" => 1, "s" => 2, "i" => 4, "d" => 8 }.freeze

Instance Method Summary collapse

Constructor Details

#initialize(pool) ⇒ Reader

Returns a new instance of Reader.



8
9
10
# File 'lib/pcrd/schema/reader.rb', line 8

def initialize(pool)
  @pool = pool
end

Instance Method Details

#estimated_row_count(table_name, schema_name: "public") ⇒ Object

Returns the estimated live row count from pg_class statistics.



65
66
67
68
69
70
71
72
73
74
# File 'lib/pcrd/schema/reader.rb', line 65

def estimated_row_count(table_name, schema_name: "public")
  result = @pool.exec(<<~SQL, [table_name, schema_name])
    SELECT c.reltuples::bigint
    FROM   pg_class c
    JOIN   pg_namespace n ON n.oid = c.relnamespace
    WHERE  c.relname = $1
      AND  n.nspname = $2
  SQL
  result.ntuples > 0 ? result[0]["reltuples"].to_i : 0
end

#primary_key_columns(table_name, schema_name: "public") ⇒ Object

Returns an array of column names that form the primary key, in key order.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/pcrd/schema/reader.rb', line 32

def primary_key_columns(table_name, schema_name: "public")
  result = @pool.exec(<<~SQL, [table_name, schema_name])
    SELECT a.attname
    FROM   pg_index i
    JOIN   pg_attribute a ON a.attrelid = i.indrelid
                         AND a.attnum = ANY(i.indkey)
    JOIN   pg_class c     ON c.oid = i.indrelid
    JOIN   pg_namespace n ON n.oid = c.relnamespace
    WHERE  c.relname = $1
      AND  n.nspname = $2
      AND  i.indisprimary
    ORDER BY array_position(i.indkey, a.attnum)
  SQL
  result.column_values(0)
end

#read(table_name, schema_name: "public") ⇒ Object

Raises:



12
13
14
15
16
17
# File 'lib/pcrd/schema/reader.rb', line 12

def read(table_name, schema_name: "public")
  rows = @pool.exec(COLUMNS_QUERY, [table_name, schema_name])
  raise TableNotFound, "Table #{schema_name}.#{table_name} not found" if rows.ntuples.zero?

  rows.map { build_column(_1) }
end

#replica_identity(table_name, schema_name: "public") ⇒ Object

Returns the table’s replica identity setting as a single char:

'd' default (primary key)   'n' nothing
'f' full (whole row)        'i' a specific unique index

Returns nil if the table is not found. This governs whether UPDATE/DELETE WAL records carry the old-row key columns the apply engine needs.



53
54
55
56
57
58
59
60
61
62
# File 'lib/pcrd/schema/reader.rb', line 53

def replica_identity(table_name, schema_name: "public")
  result = @pool.exec(<<~SQL, [table_name, schema_name])
    SELECT c.relreplident
    FROM   pg_class c
    JOIN   pg_namespace n ON n.oid = c.relnamespace
    WHERE  c.relname = $1
      AND  n.nspname = $2
  SQL
  result.ntuples > 0 ? result[0]["relreplident"] : nil
end

#table_exists?(table_name, schema_name: "public") ⇒ Boolean

Returns:

  • (Boolean)


19
20
21
22
23
24
25
26
27
28
29
# File 'lib/pcrd/schema/reader.rb', line 19

def table_exists?(table_name, schema_name: "public")
  result = @pool.exec(<<~SQL, [table_name, schema_name])
    SELECT 1
    FROM   pg_class c
    JOIN   pg_namespace n ON n.oid = c.relnamespace
    WHERE  c.relname = $1
      AND  n.nspname = $2
      AND  c.relkind = 'r'
  SQL
  result.ntuples > 0
end