summaryrefslogtreecommitdiff
path: root/www/wiki/includes/libs/rdbms/field/PostgresField.php
blob: 53c3d335b1d5e8e18cebd69dc134003b66a08a82 (plain)
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
<?php

namespace Wikimedia\Rdbms;

class PostgresField implements Field {
	private $name, $tablename, $type, $nullable, $max_length, $deferred, $deferrable, $conname,
		$has_default, $default;

	/**
	 * @param DatabasePostgres $db
	 * @param string $table
	 * @param string $field
	 * @return null|PostgresField
	 */
	static function fromText( DatabasePostgres $db, $table, $field ) {
		$q = <<<SQL
SELECT
 attnotnull, attlen, conname AS conname,
 atthasdef,
 adsrc,
 COALESCE(condeferred, 'f') AS deferred,
 COALESCE(condeferrable, 'f') 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;

		$table = $db->remappedTableName( $table );
		foreach ( $db->getCoreSchemas() as $schema ) {
			$res = $db->query(
				sprintf( $q,
					$db->addQuotes( $schema ),
					$db->addQuotes( $table ),
					$db->addQuotes( $field )
				)
			);
			$row = $db->fetchObject( $res );
			if ( !$row ) {
				continue;
			}
			$n = new PostgresField;
			$n->type = $row->typname;
			$n->nullable = ( $row->attnotnull == 'f' );
			$n->name = $field;
			$n->tablename = $table;
			$n->max_length = $row->attlen;
			$n->deferrable = ( $row->deferrable == 't' );
			$n->deferred = ( $row->deferred == 't' );
			$n->conname = $row->conname;
			$n->has_default = ( $row->atthasdef === 't' );
			$n->default = $row->adsrc;

			return $n;
		}

		return null;
	}

	function name() {
		return $this->name;
	}

	function tableName() {
		return $this->tablename;
	}

	function type() {
		return $this->type;
	}

	function isNullable() {
		return $this->nullable;
	}

	function maxLength() {
		return $this->max_length;
	}

	function is_deferrable() {
		return $this->deferrable;
	}

	function is_deferred() {
		return $this->deferred;
	}

	function conname() {
		return $this->conname;
	}

	/**
	 * @since 1.19
	 * @return bool|mixed
	 */
	function defaultValue() {
		if ( $this->has_default ) {
			return $this->default;
		} else {
			return false;
		}
	}
}