mirror of
https://github.com/status-im/sourcecred.git
synced 2025-01-11 13:14:28 +00:00
mirror: update EAV primitives (#1342)
Summary: This commit modifies `_updateOwnData` to write to both the old type-specific primitives tables as well as the new EAV table. This establishes the invariant that a node with non-null `last_update` will always have primitive data (if its object type has primitive fields). Test Plan: Existing tests expanded. Commenting out each of the `updateEavPrimitive` calls (independently) causes a test to fail. Note that every test that queries an internal `primitives_*` table to inspect the database state has been expanded to make an equivalent query against the `primitives` table as well. wchargin-branch: mirror-eav-update
This commit is contained in:
parent
463f3a073a
commit
3cb22565e5
@ -196,7 +196,7 @@ export class Mirror {
|
||||
// it requires bumping the version, bump it: requiring some extra
|
||||
// one-time cache resets is okay; doing the wrong thing is not.
|
||||
const blob = stringify({
|
||||
version: "MIRROR_v5",
|
||||
version: "MIRROR_v6",
|
||||
schema: this._schema,
|
||||
options: {
|
||||
blacklistedIds: this._blacklistedIds,
|
||||
@ -1356,7 +1356,7 @@ export class Mirror {
|
||||
].join("_"): string): any);
|
||||
},
|
||||
};
|
||||
const updatePrimitives: ({|
|
||||
const updateTypeSpecificPrimitives: ({|
|
||||
+id: Schema.ObjectId,
|
||||
// These keys can be top-level primitive fields or the primitive
|
||||
// children of a nested field. The values are the JSON encodings
|
||||
@ -1387,6 +1387,19 @@ export class Mirror {
|
||||
);
|
||||
return _makeSingleUpdateFunction(stmt);
|
||||
})();
|
||||
const updateEavPrimitive: ({|
|
||||
+id: Schema.ObjectId,
|
||||
+fieldname: string,
|
||||
+value: string | 0 | 1,
|
||||
|}) => void = _makeSingleUpdateFunction(
|
||||
db.prepare(
|
||||
dedent`\
|
||||
UPDATE primitives
|
||||
SET value = :value
|
||||
WHERE object_id = :id AND fieldname = :fieldname
|
||||
`
|
||||
)
|
||||
);
|
||||
|
||||
for (const entry of queryResult) {
|
||||
const primitives: {|
|
||||
@ -1406,9 +1419,9 @@ export class Mirror {
|
||||
`of type ${s(typename)} (got ${(primitive: empty)})`
|
||||
);
|
||||
}
|
||||
primitives[
|
||||
parameterNameFor.topLevelField(fieldname)
|
||||
] = JSON.stringify(primitive);
|
||||
const jsonValue = JSON.stringify(primitive);
|
||||
primitives[parameterNameFor.topLevelField(fieldname)] = jsonValue;
|
||||
updateEavPrimitive({id: entry.id, fieldname, value: jsonValue});
|
||||
}
|
||||
|
||||
// Add nested primitives.
|
||||
@ -1428,6 +1441,11 @@ export class Mirror {
|
||||
}
|
||||
primitives[parameterNameFor.topLevelField(nestFieldname)] =
|
||||
topLevelNested == null ? 0 : 1;
|
||||
updateEavPrimitive({
|
||||
id: entry.id,
|
||||
fieldname: nestFieldname,
|
||||
value: topLevelNested == null ? 0 : 1,
|
||||
});
|
||||
const eggFields = objectType.nestedFields[nestFieldname].primitives;
|
||||
for (const eggFieldname of Object.keys(eggFields)) {
|
||||
const eggValue: PrimitiveResult | NodeFieldResult =
|
||||
@ -1442,13 +1460,19 @@ export class Mirror {
|
||||
`of type ${s(typename)} (got ${(primitive: empty)})`
|
||||
);
|
||||
}
|
||||
const jsonValue = JSON.stringify(primitive);
|
||||
primitives[
|
||||
parameterNameFor.nestedField(nestFieldname, eggFieldname)
|
||||
] = JSON.stringify(primitive);
|
||||
] = jsonValue;
|
||||
updateEavPrimitive({
|
||||
id: entry.id,
|
||||
fieldname: `${nestFieldname}.${eggFieldname}`,
|
||||
value: jsonValue,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
updatePrimitives(primitives);
|
||||
updateTypeSpecificPrimitives(primitives);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -932,6 +932,30 @@ describe("graphql/mirror", () => {
|
||||
|
||||
// Check that some objects have the right primitives.
|
||||
// (These poke at the internals of the storage format a bit.)
|
||||
|
||||
// Check primitives (EAV format).
|
||||
expect(
|
||||
db
|
||||
.prepare(
|
||||
"SELECT object_id AS id, fieldname, value " +
|
||||
"FROM objects JOIN primitives ON objects.id = object_id " +
|
||||
"WHERE " +
|
||||
"typename IN ('Repository', 'Issue', 'User', 'ClosedEvent') " +
|
||||
"ORDER BY id, fieldname ASC"
|
||||
)
|
||||
.all()
|
||||
).toEqual([
|
||||
{id: "issue:#1", fieldname: "title", value: '"something wicked"'},
|
||||
{id: "issue:#1", fieldname: "url", value: '"url://foo/bar/issue/1"'},
|
||||
{id: "issue:#2", fieldname: "title", value: '"this way comes"'},
|
||||
{id: "issue:#2", fieldname: "url", value: '"url://foo/bar/issue/2"'},
|
||||
{id: "repo:foo/bar", fieldname: "url", value: '"url://foo/bar"'},
|
||||
{id: "user:alice", fieldname: "login", value: null},
|
||||
{id: "user:alice", fieldname: "url", value: null},
|
||||
// nothing for `ClosedEvent` (it has no primitive fields)
|
||||
]);
|
||||
|
||||
// Check primitives (legacy format).
|
||||
expect(
|
||||
db
|
||||
.prepare("SELECT * FROM primitives_Repository ORDER BY id ASC")
|
||||
@ -942,13 +966,13 @@ describe("graphql/mirror", () => {
|
||||
).toEqual([
|
||||
{
|
||||
id: "issue:#1",
|
||||
url: JSON.stringify("url://foo/bar/issue/1"),
|
||||
title: JSON.stringify("something wicked"),
|
||||
url: JSON.stringify("url://foo/bar/issue/1"),
|
||||
},
|
||||
{
|
||||
id: "issue:#2",
|
||||
url: JSON.stringify("url://foo/bar/issue/2"),
|
||||
title: JSON.stringify("this way comes"),
|
||||
url: JSON.stringify("url://foo/bar/issue/2"),
|
||||
},
|
||||
]);
|
||||
expect(
|
||||
@ -2142,9 +2166,26 @@ describe("graphql/mirror", () => {
|
||||
expect(
|
||||
db.prepare("SELECT * FROM primitives_Issue ORDER BY id ASC").all()
|
||||
).toEqual([
|
||||
{id: "issue:#1", url: '"url://issue/1"', title: "13.75"},
|
||||
{id: "issue:#2", url: "null", title: "false"},
|
||||
{id: "issue:#3", url: null, title: null},
|
||||
{id: "issue:#1", title: "13.75", url: '"url://issue/1"'},
|
||||
{id: "issue:#2", title: "false", url: "null"},
|
||||
{id: "issue:#3", title: null, url: null},
|
||||
]);
|
||||
expect(
|
||||
db
|
||||
.prepare(
|
||||
"SELECT object_id AS id, fieldname, value " +
|
||||
"FROM objects JOIN primitives ON objects.id = object_id " +
|
||||
"WHERE typename = 'Issue' " +
|
||||
"ORDER BY id, fieldname ASC"
|
||||
)
|
||||
.all()
|
||||
).toEqual([
|
||||
{id: "issue:#1", fieldname: "title", value: "13.75"},
|
||||
{id: "issue:#1", fieldname: "url", value: '"url://issue/1"'},
|
||||
{id: "issue:#2", fieldname: "title", value: "false"},
|
||||
{id: "issue:#2", fieldname: "url", value: "null"},
|
||||
{id: "issue:#3", fieldname: "title", value: null},
|
||||
{id: "issue:#3", fieldname: "url", value: null},
|
||||
]);
|
||||
});
|
||||
it("stores data with non-`null` nested fields", () => {
|
||||
@ -2178,9 +2219,9 @@ describe("graphql/mirror", () => {
|
||||
).toEqual([
|
||||
{
|
||||
id: "commit:oid",
|
||||
oid: '"yes"',
|
||||
author: +true,
|
||||
"author.date": '"today"',
|
||||
oid: '"yes"',
|
||||
},
|
||||
{
|
||||
id: "commit:zzz",
|
||||
@ -2189,6 +2230,23 @@ describe("graphql/mirror", () => {
|
||||
"author.date": "null",
|
||||
},
|
||||
]);
|
||||
expect(
|
||||
db
|
||||
.prepare(
|
||||
"SELECT object_id AS id, fieldname, value " +
|
||||
"FROM objects JOIN primitives ON objects.id = object_id " +
|
||||
"WHERE typename = 'Commit' " +
|
||||
"ORDER BY id, fieldname ASC"
|
||||
)
|
||||
.all()
|
||||
).toEqual([
|
||||
{id: "commit:oid", fieldname: "author", value: +true},
|
||||
{id: "commit:oid", fieldname: "author.date", value: '"today"'},
|
||||
{id: "commit:oid", fieldname: "oid", value: '"yes"'},
|
||||
{id: "commit:zzz", fieldname: "author", value: +true},
|
||||
{id: "commit:zzz", fieldname: "author.date", value: "null"},
|
||||
{id: "commit:zzz", fieldname: "oid", value: '"zzz"'},
|
||||
]);
|
||||
expect(
|
||||
db.prepare("SELECT * FROM links ORDER BY parent_id ASC").all()
|
||||
).toEqual([
|
||||
@ -2247,6 +2305,20 @@ describe("graphql/mirror", () => {
|
||||
"author.date": "null",
|
||||
},
|
||||
]);
|
||||
expect(
|
||||
db
|
||||
.prepare(
|
||||
"SELECT object_id AS id, fieldname, value " +
|
||||
"FROM objects JOIN primitives ON objects.id = object_id " +
|
||||
"WHERE typename = 'Commit' " +
|
||||
"ORDER BY id, fieldname ASC"
|
||||
)
|
||||
.all()
|
||||
).toEqual([
|
||||
{id: "commit:oid", fieldname: "author", value: +false},
|
||||
{id: "commit:oid", fieldname: "author.date", value: "null"},
|
||||
{id: "commit:oid", fieldname: "oid", value: '"mmm"'},
|
||||
]);
|
||||
expect(
|
||||
db.prepare("SELECT * FROM links ORDER BY parent_id ASC").all()
|
||||
).toEqual([
|
||||
@ -2289,6 +2361,17 @@ describe("graphql/mirror", () => {
|
||||
.prepare("SELECT * FROM primitives_LockedEvent ORDER BY id ASC")
|
||||
.all()
|
||||
).toEqual([{id: "dos"}, {id: "uno"}]);
|
||||
expect(
|
||||
db
|
||||
.prepare(
|
||||
"SELECT objects.id AS o_id, primitives.rowid AS p_rowid " +
|
||||
"FROM objects LEFT OUTER JOIN primitives " +
|
||||
"ON objects.id = object_id " +
|
||||
"WHERE typename = 'LockedEvent' " +
|
||||
"ORDER BY o_id ASC"
|
||||
)
|
||||
.all()
|
||||
).toEqual([{o_id: "dos", p_rowid: null}, {o_id: "uno", p_rowid: null}]);
|
||||
expect(
|
||||
db
|
||||
.prepare("SELECT * FROM links ORDER BY parent_id ASC")
|
||||
|
Loading…
x
Reference in New Issue
Block a user