|
| 1 | +<?php |
| 2 | + |
| 3 | +namespace YlsIdeas\CockroachDb\Schema; |
| 4 | + |
| 5 | +use Doctrine\DBAL\Result; |
| 6 | +use Doctrine\DBAL\Schema\Identifier; |
| 7 | +use Doctrine\DBAL\Schema\PostgreSQLSchemaManager; |
| 8 | + |
| 9 | +class CockroachSchemaManager extends PostgreSQLSchemaManager |
| 10 | +{ |
| 11 | + protected function selectTableColumns(string $databaseName, ?string $tableName = null): Result |
| 12 | + { |
| 13 | + $sql = 'SELECT'; |
| 14 | + |
| 15 | + if ($tableName === null) { |
| 16 | + $sql .= ' c.relname AS table_name, n.nspname AS schema_name,'; |
| 17 | + } |
| 18 | + |
| 19 | + $sql .= <<<'SQL' |
| 20 | + a.attnum, |
| 21 | + quote_ident(a.attname) AS field, |
| 22 | + t.typname AS type, |
| 23 | + format_type(a.atttypid, a.atttypmod) AS complete_type, |
| 24 | + (SELECT tc.collcollate FROM pg_catalog.pg_collation tc WHERE tc.oid = a.attcollation) AS collation, |
| 25 | + (SELECT t1.typname FROM pg_catalog.pg_type t1 WHERE t1.oid = t.typbasetype) AS domain_type, |
| 26 | + (SELECT format_type(t2.typbasetype, t2.typtypmod) FROM |
| 27 | + pg_catalog.pg_type t2 WHERE t2.typtype = 'd' AND t2.oid = a.atttypid) AS domain_complete_type, |
| 28 | + a.attnotnull AS isnotnull, |
| 29 | + (SELECT 't' |
| 30 | + FROM pg_index |
| 31 | + WHERE c.oid = pg_index.indrelid |
| 32 | + AND pg_index.indkey[0] = a.attnum |
| 33 | + AND pg_index.indisprimary = 't' |
| 34 | + ) AS pri, |
| 35 | + (SELECT pg_get_expr(adbin, adrelid) |
| 36 | + FROM pg_attrdef |
| 37 | + WHERE c.oid = pg_attrdef.adrelid |
| 38 | + AND pg_attrdef.adnum=a.attnum |
| 39 | + ) AS default, |
| 40 | + (SELECT pg_description.description |
| 41 | + FROM pg_description WHERE pg_description.objoid = c.oid AND a.attnum = pg_description.objsubid |
| 42 | + ) AS comment |
| 43 | + FROM pg_attribute a |
| 44 | + INNER JOIN pg_class c |
| 45 | + ON c.oid = a.attrelid |
| 46 | + INNER JOIN pg_type t |
| 47 | + ON t.oid = a.atttypid |
| 48 | + INNER JOIN pg_namespace n |
| 49 | + ON n.oid = c.relnamespace |
| 50 | + LEFT JOIN pg_depend d |
| 51 | + ON d.objid = c.oid |
| 52 | + AND d.deptype = 'e' |
| 53 | + AND d.classid = (SELECT oid FROM pg_class WHERE relname = 'pg_class') |
| 54 | + SQL; |
| 55 | + |
| 56 | + $conditions = array_merge([ |
| 57 | + 'a.attnum > 0', |
| 58 | + "c.relkind = 'r'", |
| 59 | + 'd.refobjid IS NULL', |
| 60 | + 'a.attisdropped = false', |
| 61 | + ], $this->buildQueryConditions($tableName)); |
| 62 | + |
| 63 | + $sql .= ' WHERE ' . implode(' AND ', $conditions) . ' ORDER BY a.attnum'; |
| 64 | + |
| 65 | + return $this->_conn->executeQuery($sql); |
| 66 | + } |
| 67 | + |
| 68 | + /** |
| 69 | + * @param string|null $tableName |
| 70 | + * |
| 71 | + * @return list<string> |
| 72 | + */ |
| 73 | + private function buildQueryConditions($tableName): array |
| 74 | + { |
| 75 | + $conditions = []; |
| 76 | + |
| 77 | + if ($tableName !== null) { |
| 78 | + if (strpos($tableName, '.') !== false) { |
| 79 | + [$schemaName, $tableName] = explode('.', $tableName); |
| 80 | + $conditions[] = 'n.nspname = ' . $this->_platform->quoteStringLiteral($schemaName); |
| 81 | + } else { |
| 82 | + $conditions[] = 'n.nspname = ANY(current_schemas(false))'; |
| 83 | + } |
| 84 | + |
| 85 | + $identifier = new Identifier($tableName); |
| 86 | + $conditions[] = 'c.relname = ' . $this->_platform->quoteStringLiteral($identifier->getName()); |
| 87 | + } |
| 88 | + |
| 89 | + $conditions[] = "n.nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast')"; |
| 90 | + |
| 91 | + return $conditions; |
| 92 | + } |
| 93 | +} |
0 commit comments