mirror: add typename support to `UpdateResult`s (#1664)
Summary: The internal `UpdateResult` structure now lists IDs of objects whose typename has been queried. This list is expected to be empty for now. Test Plan: Unit tests added. wchargin-branch: mirror-typename-updateresult
This commit is contained in:
parent
477243fc2c
commit
5c937d8604
|
@ -735,7 +735,9 @@ export class Mirror {
|
|||
queryResult: UpdateResult
|
||||
): void {
|
||||
for (const topLevelKey of Object.keys(queryResult)) {
|
||||
if (topLevelKey.startsWith(_FIELD_PREFIXES.OWN_DATA)) {
|
||||
if (topLevelKey.startsWith(_FIELD_PREFIXES.TYPENAMES)) {
|
||||
throw new Error("Typename update results not yet supported");
|
||||
} else if (topLevelKey.startsWith(_FIELD_PREFIXES.OWN_DATA)) {
|
||||
const rawValue: OwnDataUpdateResult | NodeConnectionsUpdateResult =
|
||||
queryResult[topLevelKey];
|
||||
const updateRecord: OwnDataUpdateResult = (rawValue: any);
|
||||
|
@ -2092,6 +2094,16 @@ type NestedFieldResult = {
|
|||
+[Schema.Fieldname]: PrimitiveResult | NodeFieldResult,
|
||||
} | null;
|
||||
|
||||
/**
|
||||
* Result describing only the typename of a set of nodes. Used when we
|
||||
* only have references to nodes via unfaithful fields.
|
||||
*/
|
||||
type TypenamesUpdateResult = $ReadOnlyArray<{|
|
||||
+__typename: Schema.Typename,
|
||||
+id: Schema.ObjectId,
|
||||
|}>;
|
||||
export type _TypenamesUpdateResult = TypenamesUpdateResult; // for tests
|
||||
|
||||
/**
|
||||
* Result describing own-data for many nodes of a given type. Whether a
|
||||
* value is a `PrimitiveResult` or a `NodeFieldResult` is determined by
|
||||
|
@ -2107,6 +2119,7 @@ type OwnDataUpdateResult = $ReadOnlyArray<{
|
|||
| NodeFieldResult
|
||||
| NestedFieldResult,
|
||||
}>;
|
||||
export type _OwnDataUpdateResult = OwnDataUpdateResult; // for tests
|
||||
|
||||
/**
|
||||
* Result describing new elements for connections on a single node.
|
||||
|
@ -2117,12 +2130,13 @@ type NodeConnectionsUpdateResult = {
|
|||
+id: Schema.ObjectId,
|
||||
+[connectionFieldname: Schema.Fieldname]: ConnectionFieldResult,
|
||||
};
|
||||
export type _NodeConnectionsUpdateResult = NodeConnectionsUpdateResult; // for tests
|
||||
|
||||
/**
|
||||
* Result describing both own-data updates and connection updates. Each
|
||||
* key's prefix determines what type of results the corresponding value
|
||||
* represents (see constants below). No field prefix is a prefix of
|
||||
* another, so this characterization is complete.
|
||||
* Result describing all kinds of updates. Each key's prefix determines
|
||||
* what type of results the corresponding value represents (see
|
||||
* constants below). No field prefix is a prefix of another, so this
|
||||
* characterization is complete.
|
||||
*
|
||||
* This type would be exact but for facebook/flow#2977, et al.
|
||||
*
|
||||
|
@ -2131,10 +2145,19 @@ type NodeConnectionsUpdateResult = {
|
|||
type UpdateResult = {
|
||||
// The prefix of each key determines what type of results the value
|
||||
// represents. See constants below.
|
||||
+[string]: OwnDataUpdateResult | NodeConnectionsUpdateResult,
|
||||
+[string]:
|
||||
| TypenamesUpdateResult
|
||||
| OwnDataUpdateResult
|
||||
| NodeConnectionsUpdateResult,
|
||||
};
|
||||
|
||||
export const _FIELD_PREFIXES = deepFreeze({
|
||||
/**
|
||||
* A key of an `UpdateResult` has this prefix if and only if the
|
||||
* corresponding value represents `TypenamesUpdateResult`s.
|
||||
*/
|
||||
TYPENAMES: "typenames_",
|
||||
|
||||
/**
|
||||
* A key of an `UpdateResult` has this prefix if and only if the
|
||||
* corresponding value represents `OwnDataUpdateResult`s.
|
||||
|
|
|
@ -13,6 +13,8 @@ import {
|
|||
_inTransaction,
|
||||
_makeSingleUpdateFunction,
|
||||
Mirror,
|
||||
type _OwnDataUpdateResult,
|
||||
type _TypenamesUpdateResult,
|
||||
} from "./mirror";
|
||||
import stringify from "json-stable-stringify";
|
||||
|
||||
|
@ -799,6 +801,20 @@ describe("graphql/mirror", () => {
|
|||
}).toThrow('Bad key in query result: "wat_0"');
|
||||
});
|
||||
|
||||
it("throws if given a key with typename results", () => {
|
||||
const db = new Database(":memory:");
|
||||
const mirror = new Mirror(db, buildGithubSchema());
|
||||
const updateId = mirror._createUpdate(new Date(123));
|
||||
const result = {
|
||||
typenames_0: ([
|
||||
{id: "issue:#1", __typename: "Issue"},
|
||||
]: _TypenamesUpdateResult),
|
||||
};
|
||||
expect(() => {
|
||||
mirror._nontransactionallyUpdateData(updateId, result);
|
||||
}).toThrow("Typename update results not yet supported");
|
||||
});
|
||||
|
||||
// We test the happy path lightly, because it just delegates to
|
||||
// other methods, which are themselves tested. This test is
|
||||
// sufficient to effect full coverage.
|
||||
|
@ -810,14 +826,14 @@ describe("graphql/mirror", () => {
|
|||
mirror.registerObject({typename: "Issue", id: "issue:#1"});
|
||||
mirror.registerObject({typename: "Issue", id: "issue:#2"});
|
||||
const result = {
|
||||
owndata_0: [
|
||||
owndata_0: ([
|
||||
{
|
||||
__typename: "Repository",
|
||||
id: "repo:foo/bar",
|
||||
url: "url://foo/bar",
|
||||
},
|
||||
],
|
||||
owndata_1: [
|
||||
]: _OwnDataUpdateResult),
|
||||
owndata_1: ([
|
||||
{
|
||||
__typename: "Issue",
|
||||
id: "issue:#1",
|
||||
|
@ -846,7 +862,7 @@ describe("graphql/mirror", () => {
|
|||
id: "user:alice",
|
||||
},
|
||||
},
|
||||
],
|
||||
]: _OwnDataUpdateResult),
|
||||
node_0: {
|
||||
id: "repo:foo/bar",
|
||||
issues: {
|
||||
|
@ -3797,13 +3813,13 @@ describe("graphql/mirror", () => {
|
|||
const rowid = mirror._logRequest(query, queryParameters, new Date(123));
|
||||
|
||||
const response = {
|
||||
owndata_0: [
|
||||
owndata_0: ([
|
||||
{
|
||||
__typename: "Repository",
|
||||
id: "repo:foo/bar",
|
||||
url: "url://foo/bar",
|
||||
},
|
||||
],
|
||||
]: _OwnDataUpdateResult),
|
||||
};
|
||||
|
||||
mirror._logResponse(rowid, response, new Date(456));
|
||||
|
|
Loading…
Reference in New Issue