mirror of
https://github.com/chartdb/chartdb.git
synced 2025-11-03 21:43:23 +00:00
db state
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import React, { useCallback } from 'react';
|
||||
import { DBTable } from '@/lib/domain/db-table';
|
||||
import { generateId, randomHSLA } from '@/lib/utils';
|
||||
import { chartDBContext } from './chartdb-context';
|
||||
import { ChartDBContext, chartDBContext } from './chartdb-context';
|
||||
import { DatabaseType } from '@/lib/domain/database-type';
|
||||
import { DBField } from '@/lib/domain/db-field';
|
||||
import { DBIndex } from '@/lib/domain/db-index';
|
||||
@@ -12,7 +12,7 @@ export const ChartDBProvider: React.FC<React.PropsWithChildren> = ({
|
||||
children,
|
||||
}) => {
|
||||
const [diagramId, setDiagramId] = React.useState('');
|
||||
const { getDiagram } = useData();
|
||||
const db = useData();
|
||||
const [diagramName, setDiagramName] = React.useState('New Diagram');
|
||||
const [databaseType, setDatabaseType] = React.useState<DatabaseType>(
|
||||
DatabaseType.GENERIC
|
||||
@@ -22,15 +22,35 @@ export const ChartDBProvider: React.FC<React.PropsWithChildren> = ({
|
||||
[]
|
||||
);
|
||||
|
||||
const updateDatabaseType = setDatabaseType;
|
||||
const updateDiagramId = setDiagramId;
|
||||
const updateDiagramName = setDiagramName;
|
||||
|
||||
const addTable = (table: DBTable) => {
|
||||
setTables((tables) => [...tables, table]);
|
||||
const updateDatabaseType: ChartDBContext['updateDatabaseType'] = async (
|
||||
databaseType
|
||||
) => {
|
||||
setDatabaseType(databaseType);
|
||||
await db.updateDiagram({
|
||||
id: diagramId,
|
||||
attributes: {
|
||||
databaseType,
|
||||
},
|
||||
});
|
||||
};
|
||||
const updateDiagramId: ChartDBContext['updateDiagramId'] = async (id) => {
|
||||
const prevId = diagramId;
|
||||
setDiagramId(id);
|
||||
await db.updateDiagram({ id: prevId, attributes: { id } });
|
||||
};
|
||||
const updateDiagramName: ChartDBContext['updateDiagramName'] = async (
|
||||
name
|
||||
) => {
|
||||
setDiagramName(name);
|
||||
await db.updateDiagram({ id: diagramId, attributes: { name } });
|
||||
};
|
||||
|
||||
const createTable = () => {
|
||||
const addTable: ChartDBContext['addTable'] = (table: DBTable) => {
|
||||
setTables((tables) => [...tables, table]);
|
||||
return db.addTable({ diagramId, table });
|
||||
};
|
||||
|
||||
const createTable: ChartDBContext['createTable'] = async () => {
|
||||
const table: DBTable = {
|
||||
id: generateId(),
|
||||
name: `table_${tables.length + 1}`,
|
||||
@@ -51,36 +71,51 @@ export const ChartDBProvider: React.FC<React.PropsWithChildren> = ({
|
||||
color: randomHSLA(),
|
||||
createdAt: Date.now(),
|
||||
};
|
||||
addTable(table);
|
||||
await addTable(table);
|
||||
|
||||
return table;
|
||||
};
|
||||
|
||||
const getTable = (id: string) =>
|
||||
const getTable: ChartDBContext['getTable'] = (id: string) =>
|
||||
tables.find((table) => table.id === id) ?? null;
|
||||
|
||||
const removeTable = (id: string) => {
|
||||
const removeTable: ChartDBContext['removeTable'] = async (id: string) => {
|
||||
setTables((tables) => tables.filter((table) => table.id !== id));
|
||||
await db.deleteTable({ diagramId, id });
|
||||
};
|
||||
|
||||
const updateTable = (id: string, table: Partial<DBTable>) => {
|
||||
const updateTable: ChartDBContext['updateTable'] = async (
|
||||
id: string,
|
||||
table: Partial<DBTable>
|
||||
) => {
|
||||
setTables((tables) =>
|
||||
tables.map((t) => (t.id === id ? { ...t, ...table } : t))
|
||||
);
|
||||
await db.updateTable({ id, attributes: table });
|
||||
};
|
||||
|
||||
const updateTables = (tables: PartialExcept<DBTable, 'id'>[]) => {
|
||||
const updateTables: ChartDBContext['updateTables'] = async (
|
||||
tables: PartialExcept<DBTable, 'id'>[]
|
||||
) => {
|
||||
setTables((currentTables) =>
|
||||
currentTables.map((table) => {
|
||||
const updatedTable = tables.find((t) => t.id === table.id);
|
||||
return updatedTable ? { ...table, ...updatedTable } : table;
|
||||
})
|
||||
);
|
||||
|
||||
const promises = [];
|
||||
for (const table of tables) {
|
||||
promises.push(db.updateTable({ id: table.id, attributes: table }));
|
||||
}
|
||||
|
||||
await Promise.all(promises);
|
||||
};
|
||||
|
||||
const updateTablesState = (
|
||||
const updateTablesState: ChartDBContext['updateTablesState'] = async (
|
||||
updateFn: (tables: DBTable[]) => PartialExcept<DBTable, 'id'>[]
|
||||
) => {
|
||||
const updatedTables = updateFn(tables);
|
||||
setTables((prevTables) => {
|
||||
const updatedTables = updateFn(prevTables);
|
||||
return prevTables
|
||||
@@ -96,9 +131,29 @@ export const ChartDBProvider: React.FC<React.PropsWithChildren> = ({
|
||||
updatedTables.some((t) => t.id === prevTable.id)
|
||||
);
|
||||
});
|
||||
|
||||
const promises = [];
|
||||
for (const updatedTable of updatedTables) {
|
||||
promises.push(
|
||||
db.updateTable({
|
||||
id: updatedTable.id,
|
||||
attributes: updatedTable,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
const tablesToDelete = tables.filter(
|
||||
(table) => !updatedTables.some((t) => t.id === table.id)
|
||||
);
|
||||
|
||||
for (const table of tablesToDelete) {
|
||||
promises.push(db.deleteTable({ diagramId, id: table.id }));
|
||||
}
|
||||
|
||||
await Promise.all(promises);
|
||||
};
|
||||
|
||||
const updateField = (
|
||||
const updateField: ChartDBContext['updateField'] = async (
|
||||
tableId: string,
|
||||
fieldId: string,
|
||||
field: Partial<DBField>
|
||||
@@ -115,9 +170,27 @@ export const ChartDBProvider: React.FC<React.PropsWithChildren> = ({
|
||||
: table
|
||||
)
|
||||
);
|
||||
|
||||
const table = await db.getTable({ diagramId, id: tableId });
|
||||
if (!table) {
|
||||
return;
|
||||
}
|
||||
|
||||
await db.updateTable({
|
||||
id: tableId,
|
||||
attributes: {
|
||||
...table,
|
||||
fields: table.fields.map((f) =>
|
||||
f.id === fieldId ? { ...f, ...field } : f
|
||||
),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const removeField = (tableId: string, fieldId: string) => {
|
||||
const removeField: ChartDBContext['removeField'] = async (
|
||||
tableId: string,
|
||||
fieldId: string
|
||||
) => {
|
||||
setTables((tables) =>
|
||||
tables.map((table) =>
|
||||
table.id === tableId
|
||||
@@ -128,9 +201,25 @@ export const ChartDBProvider: React.FC<React.PropsWithChildren> = ({
|
||||
: table
|
||||
)
|
||||
);
|
||||
|
||||
const table = await db.getTable({ diagramId, id: tableId });
|
||||
if (!table) {
|
||||
return;
|
||||
}
|
||||
|
||||
await db.updateTable({
|
||||
id: tableId,
|
||||
attributes: {
|
||||
...table,
|
||||
fields: table.fields.filter((f) => f.id !== fieldId),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const addField = (tableId: string, field: DBField) => {
|
||||
const addField: ChartDBContext['addField'] = async (
|
||||
tableId: string,
|
||||
field: DBField
|
||||
) => {
|
||||
setTables((tables) =>
|
||||
tables.map((table) =>
|
||||
table.id === tableId
|
||||
@@ -138,14 +227,33 @@ export const ChartDBProvider: React.FC<React.PropsWithChildren> = ({
|
||||
: table
|
||||
)
|
||||
);
|
||||
|
||||
const table = await db.getTable({ diagramId, id: tableId });
|
||||
|
||||
if (!table) {
|
||||
return;
|
||||
}
|
||||
|
||||
await db.updateTable({
|
||||
id: tableId,
|
||||
attributes: {
|
||||
...table,
|
||||
fields: [...table.fields, field],
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const getField = (tableId: string, fieldId: string) => {
|
||||
const getField: ChartDBContext['getField'] = (
|
||||
tableId: string,
|
||||
fieldId: string
|
||||
) => {
|
||||
const table = getTable(tableId);
|
||||
return table?.fields.find((f) => f.id === fieldId) ?? null;
|
||||
};
|
||||
|
||||
const createField = (tableId: string) => {
|
||||
const createField: ChartDBContext['createField'] = async (
|
||||
tableId: string
|
||||
) => {
|
||||
const table = getTable(tableId);
|
||||
const field: DBField = {
|
||||
id: generateId(),
|
||||
@@ -157,12 +265,15 @@ export const ChartDBProvider: React.FC<React.PropsWithChildren> = ({
|
||||
createdAt: Date.now(),
|
||||
};
|
||||
|
||||
addField(tableId, field);
|
||||
await addField(tableId, field);
|
||||
|
||||
return field;
|
||||
};
|
||||
|
||||
const addIndex = (tableId: string, index: DBIndex) => {
|
||||
const addIndex: ChartDBContext['addIndex'] = async (
|
||||
tableId: string,
|
||||
index: DBIndex
|
||||
) => {
|
||||
setTables((tables) =>
|
||||
tables.map((table) =>
|
||||
table.id === tableId
|
||||
@@ -170,9 +281,25 @@ export const ChartDBProvider: React.FC<React.PropsWithChildren> = ({
|
||||
: table
|
||||
)
|
||||
);
|
||||
|
||||
const dbTable = await db.getTable({ diagramId, id: tableId });
|
||||
if (!dbTable) {
|
||||
return;
|
||||
}
|
||||
|
||||
await db.updateTable({
|
||||
id: tableId,
|
||||
attributes: {
|
||||
...dbTable,
|
||||
indexes: [...dbTable.indexes, index],
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const removeIndex = (tableId: string, indexId: string) => {
|
||||
const removeIndex: ChartDBContext['removeIndex'] = async (
|
||||
tableId: string,
|
||||
indexId: string
|
||||
) => {
|
||||
setTables((tables) =>
|
||||
tables.map((table) =>
|
||||
table.id === tableId
|
||||
@@ -185,9 +312,28 @@ export const ChartDBProvider: React.FC<React.PropsWithChildren> = ({
|
||||
: table
|
||||
)
|
||||
);
|
||||
|
||||
const dbTable = await db.getTable({
|
||||
diagramId,
|
||||
id: tableId,
|
||||
});
|
||||
|
||||
if (!dbTable) {
|
||||
return;
|
||||
}
|
||||
|
||||
await db.updateTable({
|
||||
id: tableId,
|
||||
attributes: {
|
||||
...dbTable,
|
||||
indexes: dbTable.indexes.filter((i) => i.id !== indexId),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const createIndex = (tableId: string) => {
|
||||
const createIndex: ChartDBContext['createIndex'] = async (
|
||||
tableId: string
|
||||
) => {
|
||||
const table = getTable(tableId);
|
||||
const index: DBIndex = {
|
||||
id: generateId(),
|
||||
@@ -197,17 +343,20 @@ export const ChartDBProvider: React.FC<React.PropsWithChildren> = ({
|
||||
createdAt: Date.now(),
|
||||
};
|
||||
|
||||
addIndex(tableId, index);
|
||||
await addIndex(tableId, index);
|
||||
|
||||
return index;
|
||||
};
|
||||
|
||||
const getIndex = (tableId: string, indexId: string) => {
|
||||
const getIndex: ChartDBContext['getIndex'] = (
|
||||
tableId: string,
|
||||
indexId: string
|
||||
) => {
|
||||
const table = getTable(tableId);
|
||||
return table?.indexes.find((i) => i.id === indexId) ?? null;
|
||||
};
|
||||
|
||||
const updateIndex = (
|
||||
const updateIndex: ChartDBContext['updateIndex'] = async (
|
||||
tableId: string,
|
||||
indexId: string,
|
||||
index: Partial<DBIndex>
|
||||
@@ -224,22 +373,37 @@ export const ChartDBProvider: React.FC<React.PropsWithChildren> = ({
|
||||
: table
|
||||
)
|
||||
);
|
||||
|
||||
const dbTable = await db.getTable({ diagramId, id: tableId });
|
||||
|
||||
if (!dbTable) {
|
||||
return;
|
||||
}
|
||||
|
||||
await db.updateTable({
|
||||
id: tableId,
|
||||
attributes: {
|
||||
...dbTable,
|
||||
indexes: dbTable.indexes.map((i) =>
|
||||
i.id === indexId ? { ...i, ...index } : i
|
||||
),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const addRelationship = (relationship: DBRelationship) => {
|
||||
const addRelationship: ChartDBContext['addRelationship'] = async (
|
||||
relationship: DBRelationship
|
||||
) => {
|
||||
setRelationships((relationships) => [...relationships, relationship]);
|
||||
|
||||
await db.addRelationship({ diagramId, relationship });
|
||||
};
|
||||
|
||||
const createRelationship = ({
|
||||
const createRelationship: ChartDBContext['createRelationship'] = async ({
|
||||
sourceTableId,
|
||||
targetTableId,
|
||||
sourceFieldId,
|
||||
targetFieldId,
|
||||
}: {
|
||||
sourceTableId: string;
|
||||
targetTableId: string;
|
||||
sourceFieldId: string;
|
||||
targetFieldId: string;
|
||||
}) => {
|
||||
const sourceTableName = getTable(sourceTableId)?.name ?? '';
|
||||
const targetTableName = getTable(targetTableId)?.name ?? '';
|
||||
@@ -254,29 +418,39 @@ export const ChartDBProvider: React.FC<React.PropsWithChildren> = ({
|
||||
createdAt: Date.now(),
|
||||
};
|
||||
|
||||
addRelationship(relationship);
|
||||
await addRelationship(relationship);
|
||||
|
||||
return relationship;
|
||||
};
|
||||
|
||||
const getRelationship = (id: string) =>
|
||||
const getRelationship: ChartDBContext['getRelationship'] = (id: string) =>
|
||||
relationships.find((relationship) => relationship.id === id) ?? null;
|
||||
|
||||
const removeRelationship = (id: string) => {
|
||||
const removeRelationship: ChartDBContext['removeRelationship'] = async (
|
||||
id: string
|
||||
) => {
|
||||
setRelationships((relationships) =>
|
||||
relationships.filter((relationship) => relationship.id !== id)
|
||||
);
|
||||
|
||||
await db.deleteRelationship({ diagramId, id });
|
||||
};
|
||||
|
||||
const removeRelationships = (...ids: string[]) => {
|
||||
const removeRelationships: ChartDBContext['removeRelationships'] = async (
|
||||
...ids: string[]
|
||||
) => {
|
||||
setRelationships((relationships) =>
|
||||
relationships.filter(
|
||||
(relationship) => !ids.includes(relationship.id)
|
||||
)
|
||||
);
|
||||
|
||||
await Promise.all(
|
||||
ids.map((id) => db.deleteRelationship({ diagramId, id }))
|
||||
);
|
||||
};
|
||||
|
||||
const updateRelationship = (
|
||||
const updateRelationship: ChartDBContext['updateRelationship'] = async (
|
||||
id: string,
|
||||
relationship: Partial<DBRelationship>
|
||||
) => {
|
||||
@@ -285,24 +459,36 @@ export const ChartDBProvider: React.FC<React.PropsWithChildren> = ({
|
||||
r.id === id ? { ...r, ...relationship } : r
|
||||
)
|
||||
);
|
||||
|
||||
await db.updateRelationship({ id, attributes: relationship });
|
||||
};
|
||||
|
||||
const loadDiagram = async (diagramId: string) => {
|
||||
const diagram = await getDiagram(diagramId, {
|
||||
includeRelationships: true,
|
||||
includeTables: true,
|
||||
});
|
||||
const loadDiagram: ChartDBContext['loadDiagram'] = useCallback(
|
||||
async (diagramId: string) => {
|
||||
const diagram = await db.getDiagram(diagramId, {
|
||||
includeRelationships: true,
|
||||
includeTables: true,
|
||||
});
|
||||
|
||||
if (diagram) {
|
||||
setDiagramId(diagram.id);
|
||||
setDiagramName(diagram.name);
|
||||
setDatabaseType(diagram.databaseType);
|
||||
setTables(diagram.tables);
|
||||
setRelationships(diagram.relationships);
|
||||
}
|
||||
if (diagram) {
|
||||
setDiagramId(diagram.id);
|
||||
setDiagramName(diagram.name);
|
||||
setDatabaseType(diagram.databaseType);
|
||||
setTables(diagram.tables);
|
||||
setRelationships(diagram.relationships);
|
||||
}
|
||||
|
||||
return diagram;
|
||||
};
|
||||
return diagram;
|
||||
},
|
||||
[
|
||||
db,
|
||||
setDiagramId,
|
||||
setDiagramName,
|
||||
setDatabaseType,
|
||||
setTables,
|
||||
setRelationships,
|
||||
]
|
||||
);
|
||||
|
||||
return (
|
||||
<chartDBContext.Provider
|
||||
|
||||
Reference in New Issue
Block a user