Skip to content

Commit 1435f53

Browse files
authored
Merge pull request #14 from supabase/feature/#11-add-foreign-keys
Feature/#11 add foreign keys
2 parents cc4c392 + f3a9876 commit 1435f53

File tree

6 files changed

+234
-33
lines changed

6 files changed

+234
-33
lines changed

dist/lib/sql/tables/list.sql

+38-3
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,24 @@ WHERE
8787
AND pg_class.relnamespace = pg_namespace.oid
8888
AND pg_attribute.attrelid = pg_class.oid
8989
AND pg_attribute.attnum = any(pg_index.indkey)
90+
),
91+
relationships as (
92+
select
93+
(tc.table_schema || '.' || (tc.table_name)) as source_table_id,
94+
tc.table_schema as source_schema,
95+
tc.table_name as source_table_name,
96+
kcu.column_name as source_column_name,
97+
(ccu.table_schema || '.' || (ccu.table_name)) as target_table_id,
98+
ccu.table_schema AS target_table_schema,
99+
ccu.table_name AS target_table_name,
100+
ccu.column_name AS target_column_name,
101+
tc.constraint_name
102+
FROM
103+
information_schema.table_constraints AS tc
104+
JOIN information_schema.key_column_usage AS kcu USING (constraint_schema, constraint_name)
105+
JOIN information_schema.constraint_column_usage AS ccu USING (constraint_schema, constraint_name)
106+
where
107+
tc.constraint_type = 'FOREIGN KEY'
90108
)
91109
SELECT
92110
*,
@@ -135,7 +153,24 @@ SELECT
135153
WHERE
136154
pk_list.table_id = tables.table_id
137155
) primary_keys
138-
),
139-
'[]'
140-
) AS primary_keys
156+
),
157+
'[]'
158+
) AS primary_keys,
159+
COALESCE(
160+
(
161+
SELECT
162+
array_to_json(array_agg(row_to_json(relationships)))
163+
FROM
164+
(
165+
SELECT
166+
*
167+
FROM
168+
relationships
169+
WHERE
170+
relationships.source_table_id = tables.table_id
171+
OR relationships.target_table_id = tables.table_id
172+
) relationships
173+
),
174+
'[]'
175+
) AS relationships
141176
FROM tables

docs/index.html

+73-13
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,30 @@
191191

192192
</ul>
193193

194+
</li>
195+
196+
<li>
197+
<a href="#api-type-definitions" class="toc-h1 toc-link" data-title="API Type Definitions">API Type Definitions</a>
198+
199+
<ul class="toc-list-h2">
200+
201+
<li>
202+
<a href="#schemas-schema" class="toc-h2 toc-link" data-title="">Schemas.Schema</a>
203+
204+
</li>
205+
206+
<li>
207+
<a href="#tables-table" class="toc-h2 toc-link" data-title="">Tables.Table</a>
208+
209+
</li>
210+
211+
<li>
212+
<a href="#tables-relationship" class="toc-h2 toc-link" data-title="">Tables.Relationship</a>
213+
214+
</li>
215+
216+
</ul>
217+
194218
</li>
195219

196220
</ul>
@@ -313,26 +337,15 @@ <h2 id="getschemas">getSchemas</h2>
313337
</code></pre>
314338
<p><code>GET /schemas</code></p>
315339
<p><em>Get all schemas</em></p>
340+
<h3 id="returns">Returns</h3>
341+
<p><code>{Array}</code> <a href="#schemas-schema">Schemas.Schema</a></p>
316342
<blockquote>
317343
<p>Parameters:</p>
318344
</blockquote>
319345
<pre class="highlight tab tab-javascript"><code><span class="hljs-comment">/**
320346
* <span class="hljs-doctag">@param <span class="hljs-type">{boolean}</span> </span>[includeSystemSchemas=false] - Return system schemas as well as user schemas
321347
*/</span>
322348
</code></pre>
323-
<blockquote>
324-
<p>Returns: Schemas.Schema[]</p>
325-
</blockquote>
326-
<pre class="highlight tab tab-javascript"><code>{
327-
<span class="hljs-attr">catalog_name</span>: string
328-
<span class="hljs-attr">name</span>: string
329-
<span class="hljs-attr">owner</span>: string
330-
<span class="hljs-attr">default_character_set_catalog</span>: string
331-
<span class="hljs-attr">default_character_set_schema</span>: string
332-
<span class="hljs-attr">default_character_set_name</span>: string
333-
<span class="hljs-attr">sql_path</span>: string
334-
}
335-
</code></pre>
336349
<h1 id="pg-api-tables">Tables</h1>
337350
<p>View and manage your Postgres tables.</p>
338351
<h2 id="gettables">getTables</h2>
@@ -353,6 +366,15 @@ <h2 id="gettables">getTables</h2>
353366
</code></pre>
354367
<p><code>GET /tables</code></p>
355368
<p><em>Get all tables</em></p>
369+
<h3 id="returns-2">Returns</h3>
370+
<p><code>{Array}</code> <a href="#tables-table">Tables.Table</a></p>
371+
<blockquote>
372+
<p>Parameters:</p>
373+
</blockquote>
374+
<pre class="highlight tab tab-javascript"><code><span class="hljs-comment">/**
375+
* <span class="hljs-doctag">@param <span class="hljs-type">{boolean}</span> </span>[includeSystemSchemas=false] - Return system schemas as well as user schemas
376+
*/</span>
377+
</code></pre>
356378
<h1 id="pg-api-schemas">Types</h1>
357379
<p>View and manage your Postgres types.</p>
358380
<h2 id="gettypes">getTypes</h2>
@@ -450,6 +472,44 @@ <h2 id="getversion">getVersion</h2>
450472
</code></pre>
451473
<p><code>GET /config/version</code></p>
452474
<p>Get your Postgres version information.</p>
475+
<h1 id="api-type-definitions">API Type Definitions</h1>
476+
<h2 id="schemas-schema">Schemas.Schema</h2>
477+
<pre class="highlight tab tab-typescript"><code>{
478+
catalog_name: <span class="hljs-built_in">string</span>
479+
name: <span class="hljs-built_in">string</span>
480+
owner: <span class="hljs-built_in">string</span>
481+
default_character_set_catalog: <span class="hljs-built_in">string</span>
482+
default_character_set_schema: <span class="hljs-built_in">string</span>
483+
default_character_set_name: <span class="hljs-built_in">string</span>
484+
sql_path: <span class="hljs-built_in">string</span>
485+
}
486+
</code></pre>
487+
<h2 id="tables-table">Tables.Table</h2>
488+
<pre class="highlight tab tab-typescript"><code>{
489+
table_id: <span class="hljs-built_in">string</span>
490+
catalog: <span class="hljs-built_in">string</span>
491+
schema: <span class="hljs-built_in">string</span>
492+
name: <span class="hljs-built_in">string</span>
493+
is_insertable_into: <span class="hljs-built_in">boolean</span>
494+
is_typed: <span class="hljs-built_in">boolean</span>
495+
bytes: <span class="hljs-built_in">number</span>
496+
size: <span class="hljs-built_in">string</span>
497+
relationships: Tables.Relationship[]
498+
}
499+
</code></pre>
500+
<h2 id="tables-relationship">Tables.Relationship</h2>
501+
<pre class="highlight tab tab-typescript"><code>{
502+
source_table_id: <span class="hljs-built_in">string</span>
503+
source_schema: <span class="hljs-built_in">string</span>
504+
source_table_name: <span class="hljs-built_in">string</span>
505+
source_column_name: <span class="hljs-built_in">string</span>
506+
target_table_id: <span class="hljs-built_in">string</span>
507+
target_table_schema: <span class="hljs-built_in">string</span>
508+
target_table_name: <span class="hljs-built_in">string</span>
509+
target_column_name: <span class="hljs-built_in">string</span>
510+
constraint_name: <span class="hljs-built_in">string</span>
511+
}
512+
</code></pre>
453513
<!-- Renderer: Shins v2.5.0 -->
454514
<!-- Generator: Widdershins v4.0.1 -->
455515
</div>

docs/source/index.html.md

+64-14
Original file line numberDiff line numberDiff line change
@@ -149,26 +149,17 @@ const data = await fetch('http://localhost:1337/schemas', {
149149

150150
*Get all schemas*
151151

152+
### Returns
153+
154+
`{Array}` [Schemas.Schema](#schemas-schema)
155+
152156
> Parameters:
153157
```javascript
154158
/**
155159
* @param {boolean} [includeSystemSchemas=false] - Return system schemas as well as user schemas
156160
*/
157161
```
158-
> Returns: Schemas.Schema[]
159-
```javascript
160-
{
161-
catalog_name: string
162-
name: string
163-
owner: string
164-
default_character_set_catalog: string
165-
default_character_set_schema: string
166-
default_character_set_name: string
167-
sql_path: string
168-
}
169-
```
170-
171-
162+
172163

173164

174165

@@ -202,7 +193,16 @@ const data = await fetch('http://localhost:1337/tables', {
202193

203194
*Get all tables*
204195

196+
### Returns
197+
198+
`{Array}` [Tables.Table](#tables-table)
205199

200+
> Parameters:
201+
```javascript
202+
/**
203+
* @param {boolean} [includeSystemSchemas=false] - Return system schemas as well as user schemas
204+
*/
205+
```
206206

207207

208208

@@ -350,3 +350,53 @@ Get your Postgres version information.
350350

351351

352352

353+
354+
# API Type Definitions
355+
356+
357+
## Schemas.Schema
358+
359+
```typescript
360+
{
361+
catalog_name: string
362+
name: string
363+
owner: string
364+
default_character_set_catalog: string
365+
default_character_set_schema: string
366+
default_character_set_name: string
367+
sql_path: string
368+
}
369+
```
370+
371+
## Tables.Table
372+
373+
```typescript
374+
{
375+
table_id: string
376+
catalog: string
377+
schema: string
378+
name: string
379+
is_insertable_into: boolean
380+
is_typed: boolean
381+
bytes: number
382+
size: string
383+
relationships: Tables.Relationship[]
384+
}
385+
```
386+
387+
## Tables.Relationship
388+
389+
```typescript
390+
{
391+
source_table_id: string
392+
source_schema: string
393+
source_table_name: string
394+
source_column_name: string
395+
target_table_id: string
396+
target_table_schema: string
397+
target_table_name: string
398+
target_column_name: string
399+
constraint_name: string
400+
}
401+
```
402+

src/lib/interfaces/tables.ts

+13
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,19 @@ export namespace Tables {
99
is_typed: boolean
1010
bytes: number
1111
size: string
12+
relationships: Tables.Relationship[]
13+
}
14+
15+
export interface Relationship {
16+
source_table_id: string
17+
source_schema: string
18+
source_table_name: string
19+
source_column_name: string
20+
target_table_id: string
21+
target_table_schema: string
22+
target_table_name: string
23+
target_column_name: string
24+
constraint_name: string
1225
}
1326

1427
}

src/lib/sql/tables/list.sql

+38-3
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,24 @@ WHERE
8787
AND pg_class.relnamespace = pg_namespace.oid
8888
AND pg_attribute.attrelid = pg_class.oid
8989
AND pg_attribute.attnum = any(pg_index.indkey)
90+
),
91+
relationships as (
92+
select
93+
(tc.table_schema || '.' || (tc.table_name)) as source_table_id,
94+
tc.table_schema as source_schema,
95+
tc.table_name as source_table_name,
96+
kcu.column_name as source_column_name,
97+
(ccu.table_schema || '.' || (ccu.table_name)) as target_table_id,
98+
ccu.table_schema AS target_table_schema,
99+
ccu.table_name AS target_table_name,
100+
ccu.column_name AS target_column_name,
101+
tc.constraint_name
102+
FROM
103+
information_schema.table_constraints AS tc
104+
JOIN information_schema.key_column_usage AS kcu USING (constraint_schema, constraint_name)
105+
JOIN information_schema.constraint_column_usage AS ccu USING (constraint_schema, constraint_name)
106+
where
107+
tc.constraint_type = 'FOREIGN KEY'
90108
)
91109
SELECT
92110
*,
@@ -135,7 +153,24 @@ SELECT
135153
WHERE
136154
pk_list.table_id = tables.table_id
137155
) primary_keys
138-
),
139-
'[]'
140-
) AS primary_keys
156+
),
157+
'[]'
158+
) AS primary_keys,
159+
COALESCE(
160+
(
161+
SELECT
162+
array_to_json(array_agg(row_to_json(relationships)))
163+
FROM
164+
(
165+
SELECT
166+
*
167+
FROM
168+
relationships
169+
WHERE
170+
relationships.source_table_id = tables.table_id
171+
OR relationships.target_table_id = tables.table_id
172+
) relationships
173+
),
174+
'[]'
175+
) AS relationships
141176
FROM tables

test/integration/index.spec.js

+8
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,14 @@ describe('/tables', async () => {
145145
const datum = tables.data.find((x) => x.table_id == 'public.users')
146146
assert.equal(datum.grants.length > 0, true)
147147
})
148+
it('should return the relationships', async () => {
149+
const tables = await axios.get(`${URL}/tables`)
150+
const datum = tables.data.find((x) => x.table_id == 'public.users')
151+
const relationships = datum.relationships
152+
const relationship = relationships.find(x => x.source_table_id == 'public.todos')
153+
assert.equal(relationships.length > 0, true)
154+
assert.equal(true, relationship.target_table_id == 'public.users')
155+
})
148156

149157
it('GET with system tables', async () => {
150158
const res = await axios.get(`${URL}/tables?includeSystemSchemas=true`)

0 commit comments

Comments
 (0)