Skip to content

Commit c861051

Browse files
committed
feat(lib/columns): add is_unique to retrieve & update
1 parent 7129f7a commit c861051

File tree

3 files changed

+47
-20
lines changed

3 files changed

+47
-20
lines changed

src/lib/PostgresMetaColumns.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ COMMIT;`
163163
is_identity,
164164
identity_generation,
165165
is_nullable,
166+
is_unique,
166167
comment,
167168
}: {
168169
name?: string
@@ -173,6 +174,7 @@ COMMIT;`
173174
is_identity?: boolean
174175
identity_generation?: 'BY DEFAULT' | 'ALWAYS'
175176
is_nullable?: boolean
177+
is_unique?: boolean
176178
comment?: string
177179
}
178180
): Promise<PostgresMetaResult<PostgresColumn>> {
@@ -245,6 +247,32 @@ COMMIT;`
245247
old!.name
246248
)} SET NOT NULL;`
247249
}
250+
let isUniqueSql = ''
251+
if (old!.is_unique === true && is_unique === false) {
252+
isUniqueSql = `
253+
DO $$
254+
DECLARE
255+
r record;
256+
BEGIN
257+
FOR r IN
258+
SELECT conname FROM pg_constraint WHERE
259+
contype = 'u'
260+
AND cardinality(conkey) = 1
261+
AND conrelid = ${literal(old!.table_id)}
262+
AND conkey[1] = ${literal(old!.ordinal_position)}
263+
LOOP
264+
EXECUTE ${literal(
265+
`ALTER TABLE ${ident(old!.schema)}.${ident(old!.table)} DROP CONSTRAINT `
266+
)} || quote_ident(r.conname);
267+
END LOOP;
268+
END
269+
$$;
270+
`
271+
} else if (old!.is_unique === false && is_unique === true) {
272+
isUniqueSql = `ALTER TABLE ${ident(old!.schema)}.${ident(old!.table)} ADD UNIQUE (${ident(
273+
old!.name
274+
)});`
275+
}
248276
const commentSql =
249277
comment === undefined
250278
? ''
@@ -262,6 +290,7 @@ BEGIN;
262290
${typeSql}
263291
${defaultValueSql}
264292
${identitySql}
293+
${isUniqueSql}
265294
${commentSql}
266295
${nameSql}
267296
COMMIT;`

src/lib/sql/columns.sql

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,32 +26,22 @@ SELECT
2626
END
2727
END AS data_type,
2828
COALESCE(bt.typname, t.typname) AS format,
29-
CASE
30-
WHEN a.attidentity IN ('a', 'd') THEN TRUE
31-
ELSE FALSE
32-
END AS is_identity,
29+
a.attidentity IN ('a', 'd') AS is_identity,
3330
CASE
3431
a.attidentity
3532
WHEN 'a' THEN 'ALWAYS'
3633
WHEN 'd' THEN 'BY DEFAULT'
3734
ELSE NULL
3835
END AS identity_generation,
39-
CASE
40-
WHEN a.attnotnull
41-
OR t.typtype = 'd'
42-
AND t.typnotnull THEN FALSE
43-
ELSE TRUE
44-
END AS is_nullable,
45-
CASE
46-
WHEN (
47-
c.relkind IN ('r', 'p')
48-
)
49-
OR (
50-
c.relkind IN ('v', 'f')
51-
)
52-
AND pg_column_is_updatable(c.oid, a.attnum, FALSE) THEN TRUE
53-
ELSE FALSE
54-
END AS is_updatable,
36+
NOT (
37+
a.attnotnull
38+
OR t.typtype = 'd' AND t.typnotnull
39+
) AS is_nullable,
40+
(
41+
c.relkind IN ('r', 'p')
42+
OR c.relkind IN ('v', 'f') AND pg_column_is_updatable(c.oid, a.attnum, FALSE)
43+
) AS is_updatable,
44+
uniques.table_id IS NOT NULL AS is_unique,
5545
array_to_json(
5646
array(
5747
SELECT
@@ -82,6 +72,13 @@ FROM
8272
JOIN pg_namespace nbt ON bt.typnamespace = nbt.oid
8373
) ON t.typtype = 'd'
8474
AND t.typbasetype = bt.oid
75+
LEFT JOIN (
76+
SELECT
77+
conrelid AS table_id,
78+
conkey[1] AS ordinal_position
79+
FROM pg_catalog.pg_constraint
80+
WHERE contype = 'u' AND cardinality(conkey) = 1
81+
) AS uniques ON uniques.table_id = c.oid AND uniques.ordinal_position = a.attnum
8582
WHERE
8683
NOT pg_is_other_temp_schema(nc.oid)
8784
AND a.attnum > 0

src/lib/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export const postgresColumnSchema = Type.Object({
3232
]),
3333
is_nullable: Type.Boolean(),
3434
is_updatable: Type.Boolean(),
35+
is_unique: Type.Boolean(),
3536
enums: Type.Array(Type.Unknown()),
3637
comment: Type.Union([Type.String(), Type.Null()]),
3738
})

0 commit comments

Comments
 (0)