Skip to content

Commit 47caa29

Browse files
kishansinghifs1kishansinghifs11ilit
authored
Add support for PostgreSQL "CREATE TABLE INHERITS" (#524)
* feat: add support for PostgreSQL table inheritance in schema export * fixed the suggested changes in the inheritance feature * Update src/components/EditorSidePanel/TablesTab/TableField.jsx Co-authored-by: 1ilit <[email protected]> * fixed all the comments * feat: finalize Postgres table inheritance support with fixes and formatting --------- Co-authored-by: kishansinghifs1 <[email protected]> Co-authored-by: 1ilit <[email protected]>
1 parent 2f23c09 commit 47caa29

File tree

6 files changed

+206
-117
lines changed

6 files changed

+206
-117
lines changed

src/components/EditorSidePanel/TablesTab/TableField.jsx

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { dbToTypes } from "../../../data/datatypes";
88
import { DragHandle } from "../../SortableList/DragHandle";
99
import FieldDetails from "./FieldDetails";
1010

11-
export default function TableField({ data, tid, index }) {
11+
export default function TableField({ data, tid, index, inherited }) {
1212
const { updateField } = useDiagram();
1313
const { types } = useTypes();
1414
const { enums } = useEnums();
@@ -21,12 +21,15 @@ export default function TableField({ data, tid, index }) {
2121
return (
2222
<div className="hover-1 my-2 flex gap-2 items-center">
2323
<DragHandle id={data.id} />
24+
2425
<div className="min-w-20 flex-1/3">
2526
<Input
2627
value={data.name}
2728
id={`scroll_table_${tid}_input_${index}`}
28-
validateStatus={data.name.trim() === "" ? "error" : "default"}
29-
placeholder="Name"
29+
validateStatus={
30+
data.name.trim() === "" || inherited ? "error" : "default"
31+
}
32+
placeholder={t("name")}
3033
onChange={(value) => updateField(tid, data.id, { name: value })}
3134
onFocus={(e) => setEditField({ name: e.target.value })}
3235
onBlur={(e) => {
@@ -51,13 +54,14 @@ export default function TableField({ data, tid, index }) {
5154
}}
5255
/>
5356
</div>
57+
5458
<div className="min-w-24 flex-1/3">
5559
<Select
5660
className="w-full"
5761
optionList={[
5862
...Object.keys(dbToTypes[database]).map((value) => ({
5963
label: value,
60-
value: value,
64+
value,
6165
})),
6266
...types.map((type) => ({
6367
label: type.name.toUpperCase(),
@@ -71,7 +75,7 @@ export default function TableField({ data, tid, index }) {
7175
filter
7276
value={data.type}
7377
validateStatus={data.type === "" ? "error" : "default"}
74-
placeholder="Type"
78+
placeholder={t("type")}
7579
onChange={(value) => {
7680
if (value === data.type) return;
7781
setUndoStack((prev) => [
@@ -135,6 +139,7 @@ export default function TableField({ data, tid, index }) {
135139
}}
136140
/>
137141
</div>
142+
138143
<div>
139144
<Button
140145
type={data.notNull ? "tertiary" : "primary"}
@@ -164,11 +169,13 @@ export default function TableField({ data, tid, index }) {
164169
?
165170
</Button>
166171
</div>
172+
167173
<div>
168174
<Button
169175
type={data.primary ? "primary" : "tertiary"}
170176
title={t("primary")}
171177
theme={data.primary ? "solid" : "light"}
178+
icon={<IconKeyStroked />}
172179
onClick={() => {
173180
setUndoStack((prev) => [
174181
...prev,
@@ -189,9 +196,9 @@ export default function TableField({ data, tid, index }) {
189196
setRedoStack([]);
190197
updateField(tid, data.id, { primary: !data.primary });
191198
}}
192-
icon={<IconKeyStroked />}
193199
/>
194200
</div>
201+
195202
<div>
196203
<Popover
197204
content={

src/components/EditorSidePanel/TablesTab/TableInfo.jsx

Lines changed: 73 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
import { useState, useRef } from "react";
2-
import { Collapse, Input, TextArea, Button, Card } from "@douyinfe/semi-ui";
2+
import {
3+
Collapse,
4+
Input,
5+
TextArea,
6+
Button,
7+
Card,
8+
Select,
9+
} from "@douyinfe/semi-ui";
310
import ColorPicker from "../ColorPicker";
411
import { IconDeleteStroked } from "@douyinfe/semi-icons";
512
import { useDiagram, useSaveState, useUndoRedo } from "../../../hooks";
6-
import { Action, ObjectType, State } from "../../../data/constants";
13+
import { Action, ObjectType, State, DB } from "../../../data/constants";
714
import TableField from "./TableField";
815
import IndexDetails from "./IndexDetails";
916
import { useTranslation } from "react-i18next";
1017
import { SortableList } from "../../SortableList/SortableList";
1118
import { nanoid } from "nanoid";
1219

1320
export default function TableInfo({ data }) {
21+
const { tables, database } = useDiagram();
1422
const { t } = useTranslation();
1523
const [indexActiveKey, setIndexActiveKey] = useState("");
1624
const { deleteTable, updateTable, setTables } = useDiagram();
@@ -56,10 +64,20 @@ export default function TableInfo({ data }) {
5664
};
5765
undefined;
5866

67+
const inheritedFieldNames =
68+
Array.isArray(data.inherits) && data.inherits.length > 0
69+
? data.inherits
70+
.map((parentName) => {
71+
const parent = tables.find((t) => t.name === parentName);
72+
return parent ? parent.fields.map((f) => f.name) : [];
73+
})
74+
.flat()
75+
: [];
76+
5977
return (
6078
<div>
6179
<div className="flex items-center mb-2.5">
62-
<div className="text-md font-semibold break-keep">{t("name")}: </div>
80+
<div className="text-md font-semibold break-keep">{t("name")}:</div>
6381
<Input
6482
value={data.name}
6583
validateStatus={data.name.trim() === "" ? "error" : "default"}
@@ -88,21 +106,64 @@ export default function TableInfo({ data }) {
88106
}}
89107
/>
90108
</div>
109+
91110
<SortableList
92111
items={data.fields}
93112
keyPrefix={`table-${data.id}`}
94-
onChange={(newFields) => {
95-
setTables((prev) => {
96-
return prev.map((t) =>
113+
onChange={(newFields) =>
114+
setTables((prev) =>
115+
prev.map((t) =>
97116
t.id === data.id ? { ...t, fields: newFields } : t,
98-
);
99-
});
100-
}}
117+
),
118+
)
119+
}
101120
afterChange={() => setSaveState(State.SAVING)}
102121
renderItem={(item, i) => (
103-
<TableField data={item} tid={data.id} index={i} />
122+
<TableField
123+
data={item}
124+
tid={data.id}
125+
index={i}
126+
inherited={inheritedFieldNames.includes(item.name)}
127+
/>
104128
)}
105129
/>
130+
131+
{database === DB.POSTGRES && (
132+
<div className="mb-2">
133+
<div className="text-md font-semibold break-keep">
134+
{t("inherits")}:
135+
</div>
136+
<Select
137+
multiple
138+
value={data.inherits || []}
139+
optionList={tables
140+
.filter((t) => t.id !== data.id)
141+
.map((t) => ({ label: t.name, value: t.name }))}
142+
onChange={(value) => {
143+
setUndoStack((prev) => [
144+
...prev,
145+
{
146+
action: Action.EDIT,
147+
element: ObjectType.TABLE,
148+
component: "self",
149+
tid: data.id,
150+
undo: { inherits: data.inherits },
151+
redo: { inherits: value },
152+
message: t("edit_table", {
153+
tableName: data.name,
154+
extra: "[inherits]",
155+
}),
156+
},
157+
]);
158+
setRedoStack([]);
159+
updateTable(data.id, { inherits: value });
160+
}}
161+
placeholder={t("inherits")}
162+
className="w-full"
163+
/>
164+
</div>
165+
)}
166+
106167
{data.indices.length > 0 && (
107168
<Card
108169
bodyStyle={{ padding: "4px" }}
@@ -133,6 +194,7 @@ export default function TableInfo({ data }) {
133194
</Collapse>
134195
</Card>
135196
)}
197+
136198
<Card
137199
bodyStyle={{ padding: "4px" }}
138200
style={{ marginTop: "12px", marginBottom: "12px" }}
@@ -173,6 +235,7 @@ export default function TableInfo({ data }) {
173235
</Collapse.Panel>
174236
</Collapse>
175237
</Card>
238+
176239
<div className="flex justify-between items-center gap-1 mb-2">
177240
<ColorPicker
178241
usePopover={true}

src/data/schemas.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ export const tableSchema = {
5656
},
5757
color: { type: "string", pattern: "^#[0-9a-fA-F]{6}$" },
5858
},
59+
inherits: {
60+
type: "array",
61+
items: { type: ["string"] },
62+
},
5963
required: ["id", "name", "x", "y", "fields", "comment", "indices", "color"],
6064
};
6165

src/i18n/locales/en.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ const en = {
88
translation: {
99
report_bug: "Report a bug",
1010
import: "Import",
11+
inherits: "Inherits",
12+
merging_column_w_inherited_definition: "Column '{{fieldName}}' in table '{{tableName}}' with inherited definition will be merged",
1113
import_from: "Import from",
1214
file: "File",
1315
new: "New",

0 commit comments

Comments
 (0)