@saltcorn/builder 0.9.4-beta.8 → 0.9.4-beta.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builder_bundle.js +12 -12
- package/package.json +2 -1
- package/src/components/Builder.js +17 -4
- package/src/components/Library.js +25 -5
- package/src/components/elements/RelationBadges.js +53 -44
- package/src/components/elements/Tabs.js +3 -1
- package/src/components/elements/View.js +84 -38
- package/src/components/elements/ViewLink.js +79 -34
- package/src/components/elements/utils.js +124 -77
- package/tests/relations_finder.test.js +57 -92
- package/tests/test_data.js +0 -163
|
@@ -18,6 +18,7 @@ import FontIconPicker from "@fonticonpicker/react-fonticonpicker";
|
|
|
18
18
|
import faIcons from "./faicons";
|
|
19
19
|
import { Columns, ntimes } from "./Columns";
|
|
20
20
|
import Tippy from "@tippyjs/react";
|
|
21
|
+
import { RelationType } from "@saltcorn/common-code";
|
|
21
22
|
|
|
22
23
|
export const DynamicFontAwesomeIcon = ({ icon, className }) => {
|
|
23
24
|
if (!icon) return null;
|
|
@@ -445,6 +446,10 @@ const fetchPreview = ({ url, body, options, setPreviews, node_id, isView }) => {
|
|
|
445
446
|
}
|
|
446
447
|
const newHtml = $(".preview-scratchpad").html();
|
|
447
448
|
setPreviews((prevState) => ({ ...prevState, [node_id]: newHtml }));
|
|
449
|
+
})
|
|
450
|
+
.catch((e) => {
|
|
451
|
+
console.log("Unable to fetch the preview:");
|
|
452
|
+
console.log(e);
|
|
448
453
|
});
|
|
449
454
|
};
|
|
450
455
|
|
|
@@ -1447,22 +1452,6 @@ const Tooltip = ({ children }) => {
|
|
|
1447
1452
|
);
|
|
1448
1453
|
};
|
|
1449
1454
|
|
|
1450
|
-
export const buildTableCaches = (allTables) => {
|
|
1451
|
-
const tableIdCache = {};
|
|
1452
|
-
const tableNameCache = {};
|
|
1453
|
-
const fieldCache = {};
|
|
1454
|
-
for (const table of allTables) {
|
|
1455
|
-
tableIdCache[table.id] = table;
|
|
1456
|
-
tableNameCache[table.name] = table;
|
|
1457
|
-
for (const field of table.foreign_keys) {
|
|
1458
|
-
if (!fieldCache[field.reftable_name])
|
|
1459
|
-
fieldCache[field.reftable_name] = [];
|
|
1460
|
-
fieldCache[field.reftable_name].push(field);
|
|
1461
|
-
}
|
|
1462
|
-
}
|
|
1463
|
-
return { tableIdCache, tableNameCache, fieldCache };
|
|
1464
|
-
};
|
|
1465
|
-
|
|
1466
1455
|
export const removeWhitespaces = (str) => {
|
|
1467
1456
|
return str.replace(/\s/g, "X");
|
|
1468
1457
|
};
|
|
@@ -1513,79 +1502,137 @@ export const arrayChunks = (xs, n) => {
|
|
|
1513
1502
|
return arrayOfArrays;
|
|
1514
1503
|
};
|
|
1515
1504
|
|
|
1516
|
-
export const prepCacheAndFinder = ({
|
|
1517
|
-
tables,
|
|
1518
|
-
views,
|
|
1519
|
-
max_relations_layer_depth,
|
|
1520
|
-
}) => {
|
|
1521
|
-
if (tables && views) {
|
|
1522
|
-
const caches = buildTableCaches(tables);
|
|
1523
|
-
const finder = new relationHelpers.RelationsFinder(
|
|
1524
|
-
caches,
|
|
1525
|
-
views,
|
|
1526
|
-
max_relations_layer_depth || 6
|
|
1527
|
-
);
|
|
1528
|
-
return { caches, finder };
|
|
1529
|
-
} else return { caches: null, finder: null };
|
|
1530
|
-
};
|
|
1531
|
-
|
|
1532
1505
|
/**
|
|
1533
|
-
* @param {string[]}
|
|
1506
|
+
* @param {string[]} relations
|
|
1534
1507
|
* @param {string} sourceTbl name of the topview table
|
|
1535
1508
|
* @returns either a same table relation, a parent relation, a child relation, or the first relation
|
|
1536
1509
|
*/
|
|
1537
|
-
export const initialRelation = (
|
|
1510
|
+
export const initialRelation = (relations) => {
|
|
1538
1511
|
let sameTblRel = null;
|
|
1539
1512
|
let parentRel = null;
|
|
1540
1513
|
let childRel = null;
|
|
1541
|
-
for (const
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
const lastToken = tokens[tokens.length - 1];
|
|
1554
|
-
if (
|
|
1555
|
-
lastToken.indexOf("$") > 0 &&
|
|
1556
|
-
(!childRel || childRel.split(".").length > tokens.length)
|
|
1557
|
-
)
|
|
1558
|
-
childRel = path;
|
|
1559
|
-
}
|
|
1514
|
+
for (const relation of relations) {
|
|
1515
|
+
switch (relation.type) {
|
|
1516
|
+
case RelationType.OWN:
|
|
1517
|
+
sameTblRel = relation;
|
|
1518
|
+
break;
|
|
1519
|
+
case RelationType.PARENT_SHOW:
|
|
1520
|
+
parentRel = relation;
|
|
1521
|
+
break;
|
|
1522
|
+
case RelationType.CHILD_LIST:
|
|
1523
|
+
case RelationType.ONE_TO_ONE_SHOW:
|
|
1524
|
+
childRel = relation;
|
|
1525
|
+
break;
|
|
1560
1526
|
}
|
|
1561
1527
|
}
|
|
1562
|
-
return sameTblRel || parentRel || childRel ||
|
|
1528
|
+
return sameTblRel || parentRel || childRel || relations[0];
|
|
1563
1529
|
};
|
|
1564
1530
|
|
|
1565
1531
|
/**
|
|
1566
|
-
*
|
|
1567
|
-
*
|
|
1568
|
-
* @param
|
|
1569
|
-
* @
|
|
1570
|
-
* @param {any} options builder options
|
|
1571
|
-
* @param {RelationsFinder} finder
|
|
1572
|
-
* @param {string} viewname subview name
|
|
1532
|
+
* builder intern path method
|
|
1533
|
+
* @param path
|
|
1534
|
+
* @param tableNameCache
|
|
1535
|
+
* @returns
|
|
1573
1536
|
*/
|
|
1574
|
-
export const
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
)
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1537
|
+
export const buildRelationArray = (path, tableNameCache) => {
|
|
1538
|
+
if (path === ".")
|
|
1539
|
+
return [{ type: "Independent", table: "None (no relation)" }];
|
|
1540
|
+
const tokens = path.split(".");
|
|
1541
|
+
if (tokens.length === 2)
|
|
1542
|
+
return [{ type: "Own", table: `${tokens[1]} (same table)` }];
|
|
1543
|
+
else if (tokens.length >= 3) {
|
|
1544
|
+
const result = [];
|
|
1545
|
+
let currentTbl = tokens[1];
|
|
1546
|
+
for (const relation of tokens.slice(2)) {
|
|
1547
|
+
if (relation.indexOf("$") > 0) {
|
|
1548
|
+
const [inboundTbl, inboundKey] = relation.split("$");
|
|
1549
|
+
result.push({ type: "Inbound", table: inboundTbl, key: inboundKey });
|
|
1550
|
+
currentTbl = inboundTbl;
|
|
1551
|
+
} else {
|
|
1552
|
+
const srcTbl = tableNameCache[currentTbl];
|
|
1553
|
+
const fk = srcTbl.foreign_keys.find((fk) => fk.name === relation);
|
|
1554
|
+
if (fk) {
|
|
1555
|
+
const targetTbl = tableNameCache[fk.reftable_name];
|
|
1556
|
+
result.push({
|
|
1557
|
+
type: "Foreign",
|
|
1558
|
+
table: targetTbl.name,
|
|
1559
|
+
key: relation,
|
|
1560
|
+
});
|
|
1561
|
+
currentTbl = targetTbl.name;
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
return result;
|
|
1566
|
+
}
|
|
1567
|
+
};
|
|
1568
|
+
|
|
1569
|
+
export const buildLayers = (relations, tableName, tableNameCache) => {
|
|
1570
|
+
const result = { table: tableName, inboundKeys: [], fkeys: [] };
|
|
1571
|
+
for (const relation of relations) {
|
|
1572
|
+
const relType = relation.type;
|
|
1573
|
+
let currentLevel = result;
|
|
1574
|
+
if (relType === RelationType.INDEPENDENT) {
|
|
1575
|
+
currentLevel.fkeys.push({
|
|
1576
|
+
name: "none (no relation)",
|
|
1577
|
+
table: "",
|
|
1578
|
+
inboundKeys: [],
|
|
1579
|
+
fkeys: [],
|
|
1580
|
+
relPath: relation.relationString,
|
|
1581
|
+
});
|
|
1582
|
+
} else if (relType === RelationType.OWN) {
|
|
1583
|
+
currentLevel.fkeys.push({
|
|
1584
|
+
name: "same table",
|
|
1585
|
+
table: relation.targetTblName,
|
|
1586
|
+
inboundKeys: [],
|
|
1587
|
+
fkeys: [],
|
|
1588
|
+
relPath: relation.relationString,
|
|
1589
|
+
});
|
|
1590
|
+
} else {
|
|
1591
|
+
let currentTbl = relation.sourceTblName;
|
|
1592
|
+
for (const pathElement of relation.path) {
|
|
1593
|
+
if (pathElement.inboundKey) {
|
|
1594
|
+
currentTbl = pathElement.table;
|
|
1595
|
+
const existing = currentLevel.inboundKeys.find(
|
|
1596
|
+
(key) =>
|
|
1597
|
+
key.name === pathElement.inboundKey && key.table === currentTbl
|
|
1598
|
+
);
|
|
1599
|
+
if (existing) {
|
|
1600
|
+
currentLevel = existing;
|
|
1601
|
+
} else {
|
|
1602
|
+
const nextLevel = {
|
|
1603
|
+
name: pathElement.inboundKey,
|
|
1604
|
+
table: currentTbl,
|
|
1605
|
+
inboundKeys: [],
|
|
1606
|
+
fkeys: [],
|
|
1607
|
+
};
|
|
1608
|
+
currentLevel.inboundKeys.push(nextLevel);
|
|
1609
|
+
currentLevel = nextLevel;
|
|
1610
|
+
}
|
|
1611
|
+
} else if (pathElement.fkey) {
|
|
1612
|
+
const tblObj = tableNameCache[currentTbl];
|
|
1613
|
+
const fkey = tblObj.foreign_keys.find(
|
|
1614
|
+
(key) => key.name === pathElement.fkey
|
|
1615
|
+
);
|
|
1616
|
+
currentTbl = fkey.reftable_name;
|
|
1617
|
+
const existing = currentLevel.fkeys.find(
|
|
1618
|
+
(key) => key.name === pathElement.fkey
|
|
1619
|
+
);
|
|
1620
|
+
if (existing) {
|
|
1621
|
+
currentLevel = existing;
|
|
1622
|
+
} else {
|
|
1623
|
+
const nextLevel = {
|
|
1624
|
+
name: pathElement.fkey,
|
|
1625
|
+
table: currentTbl,
|
|
1626
|
+
inboundKeys: [],
|
|
1627
|
+
fkeys: [],
|
|
1628
|
+
};
|
|
1629
|
+
currentLevel.fkeys.push(nextLevel);
|
|
1630
|
+
currentLevel = nextLevel;
|
|
1631
|
+
}
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
currentLevel.relPath = relation.relationString;
|
|
1590
1636
|
}
|
|
1637
|
+
return result;
|
|
1591
1638
|
};
|
|
@@ -9,7 +9,16 @@ import {
|
|
|
9
9
|
withKeyFromLayerTwo,
|
|
10
10
|
withKeyFromLayerThree,
|
|
11
11
|
withSimplePostTopicrelation,
|
|
12
|
-
} from "
|
|
12
|
+
} from "@saltcorn/common-code/tests/test_data";
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
expectedOne,
|
|
16
|
+
expectedTwo,
|
|
17
|
+
expectedThree,
|
|
18
|
+
expectedFour,
|
|
19
|
+
expectedFive,
|
|
20
|
+
expectedSix,
|
|
21
|
+
} from "@saltcorn/common-code/tests/expected_relations";
|
|
13
22
|
import { ViewSettings } from "../src/components/elements/View";
|
|
14
23
|
import { ViewLinkSettings } from "../src/components/elements/ViewLink";
|
|
15
24
|
|
|
@@ -60,43 +69,47 @@ const doTest = (
|
|
|
60
69
|
renderer.create(<ViewSettings></ViewSettings>);
|
|
61
70
|
expect(spy).toBeCalled();
|
|
62
71
|
const vCallArgs = spy.mock.calls[0];
|
|
63
|
-
expect(vCallArgs[0].
|
|
64
|
-
expect(vCallArgs[0].
|
|
65
|
-
expect(vCallArgs[0].
|
|
72
|
+
expect(vCallArgs[0].relations).toBeDefined();
|
|
73
|
+
expect(vCallArgs[0].relations).toHaveLength(expected.length);
|
|
74
|
+
expect(vCallArgs[0].relations.map((rel) => rel.relationString)).toEqual(
|
|
75
|
+
expect.arrayContaining(expected)
|
|
76
|
+
);
|
|
66
77
|
|
|
67
78
|
renderer.create(<ViewLinkSettings></ViewLinkSettings>);
|
|
68
79
|
expect(spy.mock.calls).toHaveLength(4);
|
|
69
80
|
const vLinkcallArgs = spy.mock.calls[2];
|
|
70
|
-
expect(vLinkcallArgs[0].
|
|
71
|
-
expect(vLinkcallArgs[0].
|
|
72
|
-
expect(vLinkcallArgs[0].
|
|
81
|
+
expect(vLinkcallArgs[0].relations).toBeDefined();
|
|
82
|
+
expect(vLinkcallArgs[0].relations).toHaveLength(expected.length);
|
|
83
|
+
expect(vLinkcallArgs[0].relations.map((rel) => rel.relationString)).toEqual(
|
|
84
|
+
expect.arrayContaining(expected)
|
|
85
|
+
);
|
|
73
86
|
};
|
|
74
87
|
|
|
75
88
|
describe("relations tests", () => {
|
|
76
|
-
beforeAll(() => {
|
|
77
|
-
// inject relationHelpers (normally it's a script tag)
|
|
78
|
-
global.relationHelpers = {
|
|
79
|
-
...require("../../server/public/relation_helpers.js"),
|
|
80
|
-
};
|
|
81
|
-
});
|
|
82
89
|
beforeEach(() => {
|
|
83
90
|
jest.restoreAllMocks();
|
|
84
91
|
});
|
|
85
92
|
describe("single relations", () => {
|
|
86
|
-
it("parent relations",
|
|
87
|
-
const { tables, views } = fixturesData();
|
|
93
|
+
it("parent relations", () => {
|
|
94
|
+
const { tables, views } = fixturesData(__dirname);
|
|
88
95
|
const expected = [".fan_club.artist"];
|
|
89
96
|
doTest(tables, views, "fan_club", "show_artist", expected);
|
|
90
97
|
});
|
|
91
98
|
|
|
92
|
-
it("
|
|
93
|
-
const { tables, views } = fixturesData();
|
|
99
|
+
it("parent relations with layers", () => {
|
|
100
|
+
const { tables, views } = fixturesData(__dirname);
|
|
101
|
+
const expected = [".patients.favbook.publisher"];
|
|
102
|
+
doTest(tables, views, "patients", "show_publisher", expected);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it("one to one relations", () => {
|
|
106
|
+
const { tables, views } = fixturesData(__dirname);
|
|
94
107
|
const expected = [".covers.albums$cover"];
|
|
95
108
|
doTest(tables, views, "covers", "show_album", expected);
|
|
96
109
|
});
|
|
97
110
|
|
|
98
|
-
it("employee department relation",
|
|
99
|
-
const { tables, views } = fixturesData();
|
|
111
|
+
it("employee department relation", () => {
|
|
112
|
+
const { tables, views } = fixturesData(__dirname);
|
|
100
113
|
const expected = [".employee", ".employee.department.manager"];
|
|
101
114
|
doTest(tables, views, "employee", "show_manager", expected);
|
|
102
115
|
});
|
|
@@ -104,85 +117,37 @@ describe("relations tests", () => {
|
|
|
104
117
|
|
|
105
118
|
describe("multi relations", () => {
|
|
106
119
|
describe("inbound relations", () => {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
".users.user_interested_in_topic$user.topic.blog_in_topic$topic",
|
|
110
|
-
".users.user_interested_in_topic$user.topic.inbound_inbound$topic.bp_inbound.post.blog_in_topic$post",
|
|
111
|
-
".users.messages$user.room.participants$room.user.user_interested_in_topic$user.topic.blog_in_topic$topic",
|
|
112
|
-
];
|
|
113
|
-
it("single keys to source and rel table", async () => {
|
|
114
|
-
const { tables, views } = fixturesData();
|
|
120
|
+
it("single keys to source and rel table", () => {
|
|
121
|
+
const { tables, views } = fixturesData(__dirname);
|
|
115
122
|
doTest(tables, views, "users", "blog_in_topic_feed", expectedOne);
|
|
116
123
|
});
|
|
117
124
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
".users.user_interested_in_topic$another_user.topic.blog_in_topic$topic",
|
|
121
|
-
".users.user_interested_in_topic$another_user.topic.inbound_inbound$topic.bp_inbound.post.blog_in_topic$post",
|
|
122
|
-
".users.messages$user.room.participants$room.user.user_interested_in_topic$another_user.topic.blog_in_topic$topic",
|
|
123
|
-
];
|
|
124
|
-
it("multiple keys to source and single key to rel table", async () => {
|
|
125
|
-
const { tables, views } = withAnotherUserField();
|
|
125
|
+
it("multiple keys to source and single key to rel table", () => {
|
|
126
|
+
const { tables, views } = withAnotherUserField(__dirname);
|
|
126
127
|
doTest(tables, views, "users", "blog_in_topic_feed", expectedTwo);
|
|
127
128
|
});
|
|
128
129
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
".users.user_interested_in_topic$user.topic.blog_in_topic$second_topic",
|
|
132
|
-
".users.user_interested_in_topic$another_user.topic.blog_in_topic$second_topic",
|
|
133
|
-
".users.messages$user.room.participants$room.user.user_interested_in_topic$user.topic.blog_in_topic$second_topic",
|
|
134
|
-
".users.messages$user.room.participants$room.user.user_interested_in_topic$another_user.topic.blog_in_topic$second_topic",
|
|
135
|
-
];
|
|
136
|
-
it("multiple keys to source and rel table", async () => {
|
|
137
|
-
const { tables, views } = withSecondTopicField();
|
|
130
|
+
it("multiple keys to source and rel table", () => {
|
|
131
|
+
const { tables, views } = withSecondTopicField(__dirname);
|
|
138
132
|
doTest(tables, views, "users", "blog_in_topic_feed", expectedThree);
|
|
139
133
|
});
|
|
140
134
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
".users.user_interested_in_topic$user.another_user.second_inbound$user.topic.blog_in_topic$topic",
|
|
144
|
-
".users.user_interested_in_topic$user.another_user.second_inbound$user.topic.blog_in_topic$second_topic",
|
|
145
|
-
".users.second_inbound$user.topic.blog_in_topic$topic",
|
|
146
|
-
".users.second_inbound$user.topic.blog_in_topic$second_topic",
|
|
147
|
-
".users.second_inbound$user.topic.inbound_inbound$topic.bp_inbound.post.blog_in_topic$post",
|
|
148
|
-
".users.messages$user.room.participants$room.user.second_inbound$user.topic.blog_in_topic$topic",
|
|
149
|
-
".users.messages$user.room.participants$room.user.second_inbound$user.topic.blog_in_topic$second_topic",
|
|
150
|
-
];
|
|
151
|
-
it("multiple inbound tables", async () => {
|
|
152
|
-
const { tables, views } = withMultipleInbounds();
|
|
135
|
+
it("multiple inbound tables", () => {
|
|
136
|
+
const { tables, views } = withMultipleInbounds(__dirname);
|
|
153
137
|
doTest(tables, views, "users", "blog_in_topic_feed", expectedFour);
|
|
154
138
|
});
|
|
155
139
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
".users.user_interested_in_topic$user.topic.inbound_inbound$topic.post_from_layer_two.blog_in_topic$post",
|
|
159
|
-
".users.user_interested_in_topic$another_user.topic.inbound_inbound$topic.post_from_layer_two.blog_in_topic$post",
|
|
160
|
-
".users.second_inbound$user.topic.inbound_inbound$topic.post_from_layer_two.blog_in_topic$post",
|
|
161
|
-
".users.user_interested_in_topic$user.topic.blog_in_topic$topic.post.inbound_inbound$post_from_layer_two.topic.blog_in_topic$second_topic",
|
|
162
|
-
".users.user_interested_in_topic$user.another_user.second_inbound$user.topic.inbound_inbound$topic.post_from_layer_two.blog_in_topic$post",
|
|
163
|
-
".users.user_interested_in_topic$another_user.topic.blog_in_topic$topic.post.inbound_inbound$post_from_layer_two.topic.blog_in_topic$second_topic",
|
|
164
|
-
".users.second_inbound$user.topic.blog_in_topic$topic.post.inbound_inbound$post_from_layer_two.topic.blog_in_topic$second_topic",
|
|
165
|
-
];
|
|
166
|
-
it("key to source from layer two", async () => {
|
|
167
|
-
const { tables, views } = withKeyFromLayerTwo();
|
|
140
|
+
it("key to source from layer two", () => {
|
|
141
|
+
const { tables, views } = withKeyFromLayerTwo(__dirname);
|
|
168
142
|
doTest(tables, views, "users", "blog_in_topic_feed", expectedFive);
|
|
169
143
|
});
|
|
170
144
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
".users.user_interested_in_topic$user.topic.inbound_level_three$topic.inbound_level_two.bp_inbound.post.blog_in_topic$post",
|
|
174
|
-
".users.user_interested_in_topic$user.topic.inbound_level_three$topic.inbound_level_two.post_from_layer_two.blog_in_topic$post",
|
|
175
|
-
".users.user_interested_in_topic$another_user.topic.inbound_level_three$topic.inbound_level_two.bp_inbound.post.blog_in_topic$post",
|
|
176
|
-
".users.user_interested_in_topic$another_user.topic.inbound_level_three$topic.inbound_level_two.post_from_layer_two.blog_in_topic$post",
|
|
177
|
-
".users.second_inbound$user.topic.inbound_level_three$topic.inbound_level_two.bp_inbound.post.blog_in_topic$post",
|
|
178
|
-
".users.second_inbound$user.topic.inbound_level_three$topic.inbound_level_two.post_from_layer_two.blog_in_topic$post",
|
|
179
|
-
];
|
|
180
|
-
it("three levels inbound", async () => {
|
|
181
|
-
const { tables, views } = withKeyFromLayerThree();
|
|
145
|
+
it("three levels inbound", () => {
|
|
146
|
+
const { tables, views } = withKeyFromLayerThree(__dirname);
|
|
182
147
|
doTest(tables, views, "users", "blog_in_topic_feed", expectedSix);
|
|
183
148
|
});
|
|
184
149
|
|
|
185
|
-
it("simple post topic relation",
|
|
150
|
+
it("simple post topic relation", () => {
|
|
186
151
|
const expected = [
|
|
187
152
|
".",
|
|
188
153
|
".users.favsimpletopic.simple_posts$topic",
|
|
@@ -190,20 +155,20 @@ describe("relations tests", () => {
|
|
|
190
155
|
".users.messages$user.room.participants$room.user.favsimpletopic.simple_posts$topic",
|
|
191
156
|
".users.messages$user.room.participants$room.user.favsimpletopic.simple_post_inbound$topic.post",
|
|
192
157
|
];
|
|
193
|
-
const { tables, views } = withSimplePostTopicrelation();
|
|
158
|
+
const { tables, views } = withSimplePostTopicrelation(__dirname);
|
|
194
159
|
doTest(tables, views, "users", "simple_posts_list", expected);
|
|
195
160
|
});
|
|
196
161
|
});
|
|
197
162
|
|
|
198
163
|
describe("many to many relations", () => {
|
|
199
|
-
it("artist_plays_on_album",
|
|
200
|
-
const { tables, views } = fixturesData();
|
|
164
|
+
it("artist_plays_on_album", () => {
|
|
165
|
+
const { tables, views } = fixturesData(__dirname);
|
|
201
166
|
const expected = [".", ".artists.artist_plays_on_album$artist.album"];
|
|
202
167
|
doTest(tables, views, "artists", "albums_feed", expected);
|
|
203
168
|
});
|
|
204
169
|
|
|
205
|
-
it("tracks on album",
|
|
206
|
-
const { tables, views } = fixturesData();
|
|
170
|
+
it("tracks on album", () => {
|
|
171
|
+
const { tables, views } = fixturesData(__dirname);
|
|
207
172
|
const expected = [
|
|
208
173
|
".",
|
|
209
174
|
".artists.artist_plays_on_album$artist.album.tracks_on_album$album",
|
|
@@ -211,8 +176,8 @@ describe("relations tests", () => {
|
|
|
211
176
|
doTest(tables, views, "artists", "tracks_on_album_feed", expected);
|
|
212
177
|
});
|
|
213
178
|
|
|
214
|
-
it("show pressing_job with embedded fan club feed",
|
|
215
|
-
const { tables, views } = fixturesData();
|
|
179
|
+
it("show pressing_job with embedded fan club feed", () => {
|
|
180
|
+
const { tables, views } = fixturesData(__dirname);
|
|
216
181
|
const expected = [
|
|
217
182
|
".",
|
|
218
183
|
".pressing_job.album.artist_plays_on_album$album.artist.fan_club$artist",
|
|
@@ -222,8 +187,8 @@ describe("relations tests", () => {
|
|
|
222
187
|
});
|
|
223
188
|
|
|
224
189
|
describe("excluded viewtemplates", () => {
|
|
225
|
-
it("excluded viewtemplates",
|
|
226
|
-
const { tables, views } = fixturesData();
|
|
190
|
+
it("excluded viewtemplates", () => {
|
|
191
|
+
const { tables, views } = fixturesData(__dirname);
|
|
227
192
|
const expected = [];
|
|
228
193
|
const excluded = ["Room"];
|
|
229
194
|
doTest(tables, views, "participants", "rooms_view", expected, excluded);
|
|
@@ -232,7 +197,7 @@ describe("relations tests", () => {
|
|
|
232
197
|
|
|
233
198
|
describe("open legacy relations", () => {
|
|
234
199
|
it("ChildList", async () => {
|
|
235
|
-
const { tables, views } = fixturesData();
|
|
200
|
+
const { tables, views } = fixturesData(__dirname);
|
|
236
201
|
const expected = [".", ".books.discusses_books$book"];
|
|
237
202
|
doTest(
|
|
238
203
|
tables,
|
|
@@ -247,7 +212,7 @@ describe("relations tests", () => {
|
|
|
247
212
|
});
|
|
248
213
|
|
|
249
214
|
it("Independent", async () => {
|
|
250
|
-
const { tables, views } = fixturesData();
|
|
215
|
+
const { tables, views } = fixturesData(__dirname);
|
|
251
216
|
const expected = [
|
|
252
217
|
".",
|
|
253
218
|
".blog_posts",
|
|
@@ -266,7 +231,7 @@ describe("relations tests", () => {
|
|
|
266
231
|
});
|
|
267
232
|
|
|
268
233
|
it("Own", async () => {
|
|
269
|
-
const { tables, views } = fixturesData();
|
|
234
|
+
const { tables, views } = fixturesData(__dirname);
|
|
270
235
|
const expected = [".books"];
|
|
271
236
|
doTest(
|
|
272
237
|
tables,
|
package/tests/test_data.js
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import { readFileSync } from "fs";
|
|
2
|
-
import { join } from "path";
|
|
3
|
-
|
|
4
|
-
export const fixturesData = () => {
|
|
5
|
-
const { tables, views } = JSON.parse(
|
|
6
|
-
readFileSync(join(__dirname, "schema_data.json"))
|
|
7
|
-
);
|
|
8
|
-
return { tables, views };
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
let nextFieldId = 3000;
|
|
12
|
-
|
|
13
|
-
export const withAnotherUserField = () => {
|
|
14
|
-
const { tables, views } = JSON.parse(JSON.stringify(fixturesData()));
|
|
15
|
-
const uiit = tables.find(({ name }) => name === "user_interested_in_topic");
|
|
16
|
-
uiit.foreign_keys.push({
|
|
17
|
-
name: "another_user",
|
|
18
|
-
id: nextFieldId++,
|
|
19
|
-
table_id: uiit.id,
|
|
20
|
-
reftable_name: "users",
|
|
21
|
-
is_unique: false,
|
|
22
|
-
});
|
|
23
|
-
return { tables, views };
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export const withSecondTopicField = () => {
|
|
27
|
-
const { tables, views } = JSON.parse(JSON.stringify(withAnotherUserField()));
|
|
28
|
-
const bit = tables.find(({ name }) => name === "blog_in_topic");
|
|
29
|
-
bit.foreign_keys.push({
|
|
30
|
-
name: "second_topic",
|
|
31
|
-
id: nextFieldId++,
|
|
32
|
-
table_id: bit.id,
|
|
33
|
-
reftable_name: "topics",
|
|
34
|
-
is_unique: false,
|
|
35
|
-
});
|
|
36
|
-
return { tables, views };
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
export const withMultipleInbounds = () => {
|
|
40
|
-
const { tables, views } = JSON.parse(JSON.stringify(withSecondTopicField()));
|
|
41
|
-
const nextTableId = tables.length + 1;
|
|
42
|
-
tables.push({
|
|
43
|
-
name: "second_inbound",
|
|
44
|
-
id: nextTableId,
|
|
45
|
-
foreign_keys: [
|
|
46
|
-
{
|
|
47
|
-
name: "topic",
|
|
48
|
-
id: nextFieldId++,
|
|
49
|
-
table_id: nextTableId,
|
|
50
|
-
reftable_name: "topics",
|
|
51
|
-
is_unique: false,
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
name: "user",
|
|
55
|
-
id: nextFieldId++,
|
|
56
|
-
table_id: nextTableId,
|
|
57
|
-
reftable_name: "users",
|
|
58
|
-
is_unique: false,
|
|
59
|
-
},
|
|
60
|
-
],
|
|
61
|
-
});
|
|
62
|
-
return { tables, views };
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
export const withKeyFromLayerTwo = () => {
|
|
66
|
-
const { tables, views } = JSON.parse(JSON.stringify(withMultipleInbounds()));
|
|
67
|
-
const inboundInbound = tables.find(({ name }) => name === "inbound_inbound");
|
|
68
|
-
inboundInbound.foreign_keys.push({
|
|
69
|
-
name: "post_from_layer_two",
|
|
70
|
-
id: nextFieldId++,
|
|
71
|
-
table_id: inboundInbound.id,
|
|
72
|
-
reftable_name: "blog_posts",
|
|
73
|
-
is_unique: false,
|
|
74
|
-
});
|
|
75
|
-
return { tables, views };
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
export const withKeyFromLayerThree = () => {
|
|
79
|
-
const { tables, views } = JSON.parse(JSON.stringify(withKeyFromLayerTwo()));
|
|
80
|
-
const nextTableId = tables.length + 1;
|
|
81
|
-
tables.push({
|
|
82
|
-
name: "inbound_level_three",
|
|
83
|
-
id: nextTableId,
|
|
84
|
-
foreign_keys: [
|
|
85
|
-
{
|
|
86
|
-
name: "inbound_level_two",
|
|
87
|
-
id: nextFieldId++,
|
|
88
|
-
table_id: nextTableId,
|
|
89
|
-
reftable_name: "inbound_inbound",
|
|
90
|
-
is_unique: false,
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
name: "topic",
|
|
94
|
-
id: nextFieldId++,
|
|
95
|
-
table_id: nextTableId,
|
|
96
|
-
reftable_name: "topics",
|
|
97
|
-
is_unique: false,
|
|
98
|
-
},
|
|
99
|
-
],
|
|
100
|
-
});
|
|
101
|
-
return { tables, views };
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
export const withSimplePostTopicrelation = () => {
|
|
105
|
-
const { tables, views } = JSON.parse(JSON.stringify(fixturesData()));
|
|
106
|
-
const simpleTopicsId = tables.length + 1;
|
|
107
|
-
const simplePostsId = simpleTopicsId + 1;
|
|
108
|
-
const simplePostInboundId = simplePostsId + 1;
|
|
109
|
-
tables.push({
|
|
110
|
-
name: "simple_posts",
|
|
111
|
-
id: simplePostsId,
|
|
112
|
-
foreign_keys: [
|
|
113
|
-
{
|
|
114
|
-
name: "topic",
|
|
115
|
-
table_id: simplePostsId,
|
|
116
|
-
id: nextFieldId++,
|
|
117
|
-
reftable_name: "simple_topics",
|
|
118
|
-
is_unique: false,
|
|
119
|
-
},
|
|
120
|
-
],
|
|
121
|
-
});
|
|
122
|
-
tables.push({
|
|
123
|
-
name: "simple_topics",
|
|
124
|
-
id: simpleTopicsId,
|
|
125
|
-
foreign_keys: [],
|
|
126
|
-
});
|
|
127
|
-
tables.push({
|
|
128
|
-
name: "simple_post_inbound",
|
|
129
|
-
id: simplePostInboundId,
|
|
130
|
-
foreign_keys: [
|
|
131
|
-
{
|
|
132
|
-
name: "post",
|
|
133
|
-
table_id: simplePostInboundId,
|
|
134
|
-
id: nextFieldId++,
|
|
135
|
-
reftable_name: "simple_posts",
|
|
136
|
-
is_unique: false,
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
name: "topic",
|
|
140
|
-
table_id: simplePostInboundId,
|
|
141
|
-
id: nextFieldId++,
|
|
142
|
-
reftable_name: "simple_topics",
|
|
143
|
-
is_unique: false,
|
|
144
|
-
},
|
|
145
|
-
],
|
|
146
|
-
});
|
|
147
|
-
const users = tables.find(({ name }) => name === "users");
|
|
148
|
-
users.foreign_keys.push({
|
|
149
|
-
name: "favsimpletopic",
|
|
150
|
-
table_id: users.id,
|
|
151
|
-
id: nextFieldId++,
|
|
152
|
-
reftable_name: "simple_topics",
|
|
153
|
-
is_unique: false,
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
views.push({
|
|
157
|
-
name: "simple_posts_list",
|
|
158
|
-
table_id: simplePostsId,
|
|
159
|
-
display_type: "NO_ROW_LIMIT",
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
return { tables, views };
|
|
163
|
-
};
|