1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
<?php
namespace Wikimedia\Rdbms;
class PostgresField implements Field {
private string $name;
private string $tablename;
private string $type;
private bool $nullable;
/** @var int */
private $max_length;
private bool $deferred;
private bool $deferrable;
private ?string $conname;
private bool $has_default;
/** @var mixed */
private $default;
/**
* @param DatabasePostgres $db
* @param string $table
* @param string $field
* @return null|PostgresField
*/
public static function fromText( DatabasePostgres $db, $table, $field ) {
$q = <<<SQL
SELECT
attnotnull, attlen, conname AS conname,
atthasdef,
pg_get_expr(adbin, adrelid) AS adsrc,
COALESCE(condeferred, FALSE) AS deferred,
COALESCE(condeferrable, FALSE) AS deferrable,
CASE WHEN typname = 'int2' THEN 'smallint'
WHEN typname = 'int4' THEN 'integer'
WHEN typname = 'int8' THEN 'bigint'
WHEN typname = 'bpchar' THEN 'char'
ELSE typname END AS typname
FROM pg_class c
JOIN pg_namespace n ON (n.oid = c.relnamespace)
JOIN pg_attribute a ON (a.attrelid = c.oid)
JOIN pg_type t ON (t.oid = a.atttypid)
LEFT JOIN pg_constraint o ON (o.conrelid = c.oid AND a.attnum = ANY(o.conkey) AND o.contype = 'f')
LEFT JOIN pg_attrdef d on c.oid=d.adrelid and a.attnum=d.adnum
WHERE relkind = 'r'
AND nspname=%s
AND relname=%s
AND attname=%s;
SQL;
foreach ( $db->getCoreSchemas() as $schema ) {
$res = $db->query(
sprintf( $q,
$db->addQuotes( $schema ),
$db->addQuotes( $db->tableName( $table, 'raw' ) ),
$db->addQuotes( $field )
),
__METHOD__
);
$row = $res->fetchObject();
if ( !$row ) {
continue;
}
$n = new PostgresField;
$n->type = $row->typname;
$n->nullable = !$row->attnotnull;
$n->name = $field;
$n->tablename = $table;
$n->max_length = $row->attlen;
$n->deferrable = (bool)$row->deferrable;
$n->deferred = (bool)$row->deferred;
$n->conname = $row->conname;
$n->has_default = (bool)$row->atthasdef;
$n->default = $row->adsrc;
return $n;
}
return null;
}
public function name() {
return $this->name;
}
public function tableName() {
return $this->tablename;
}
public function type() {
return $this->type;
}
public function isNullable() {
return $this->nullable;
}
public function maxLength() {
return $this->max_length;
}
public function is_deferrable() {
return $this->deferrable;
}
public function is_deferred() {
return $this->deferred;
}
public function conname() {
return $this->conname;
}
/**
* @since 1.19
* @return mixed|false
*/
public function defaultValue() {
if ( $this->has_default ) {
return $this->default;
} else {
return false;
}
}
}
|