Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | 48x 48x 48x 48x 48x 48x 48x 17x 117x 48x 117x 204x 204x 30x 17x 30x 30x 55x 174x 174x 10x 174x 48x 117x 117x 198x 30x 168x 117x 48x 48x 39x 39x 48x 48x 17x 48x | import type { NormalizedData, NormalizedValue } from "../normalize";
import { createForeignKey } from "./create-foreign-key";
import { getIsNullable } from "./get-is-nullable";
import { getType, UnknownTypeError } from "./get-type";
import type { Field, RelationalTable } from "./types";
export function createRelationalStructure(
prefix: string,
data: NormalizedData,
parentTable?: RelationalTable,
): RelationalTable[] {
const fields: Map<string, Field> = new Map();
const fieldTypes: Map<string, Field["type"]> = new Map();
const fieldIsNullable: Map<string, Field["isNullable"]> = new Map();
const nestedData: Map<string, NormalizedData> = new Map();
const selfData: Record<string, NormalizedValue>[] = [];
fields.set("normalize_id", {
key: "normalize_id",
type: "integer",
isPrimaryKey: true,
});
if (parentTable) {
fields.set("normalize_parent_id", {
key: "normalize_parent_id",
type: "integer",
reference: createForeignKey(parentTable, "normalize_id"),
});
}
const keys = new Set(data.map((row) => Object.keys(row)).flat());
data.forEach((row, normalize_parent_id) => {
for (const key of keys) {
const value = row[key];
if (Array.isArray(value)) {
if (!nestedData.has(key)) {
nestedData.set(key, []);
}
const nestedDataByKey = nestedData.get(key)!;
value.forEach((item) =>
nestedDataByKey.push({ ...item, normalize_parent_id }),
);
} else {
try {
fieldTypes.set(key, getType(fieldTypes.get(key), value));
} catch (error) {
Iif (!(error instanceof UnknownTypeError)) {
throw error;
}
}
fieldIsNullable.set(
key,
getIsNullable(fieldIsNullable.get(key), value),
);
}
}
});
data.forEach((row, normalize_id) => {
const selfDataItem: Record<string, NormalizedValue> = { normalize_id };
for (const [key, value] of Object.entries(row)) {
if (Array.isArray(value)) {
continue;
}
selfDataItem[key] = value;
}
selfData.push(selfDataItem);
});
fieldTypes.delete("normalize_parent_id");
for (const [key, type] of fieldTypes.entries()) {
const isNullable = fieldIsNullable.get(key);
fields.set(key, {
key,
type,
...(isNullable ? { isNullable } : {}),
});
}
const relationalTable: RelationalTable = {
name: prefix,
fields: [...fields.values()],
data: selfData,
};
const nestedRelationalTables = [...nestedData.entries()]
.map((entry) =>
createRelationalStructure(
`${prefix}_${entry[0]}`,
entry[1],
relationalTable,
),
)
.flat();
return [relationalTable, ...nestedRelationalTables];
}
|