Skip to content

Commit a6c55dd

Browse files
authored
Merge pull request #289 from ayende/RDBC-509
RDBC-509 SaveChanges after query modifies the change vector
2 parents ca1af9d + 40b9975 commit a6c55dd

File tree

2 files changed

+73
-3
lines changed

2 files changed

+73
-3
lines changed

src/Documents/Session/EntityToJson.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,30 @@ export class EntityToJson {
112112
documentInfo.metadata[CONSTANTS.Documents.Metadata.RAVEN_JS_TYPE] || typeInfo.typeName;
113113
}
114114

115+
function differentNestedTypes(): boolean {
116+
const existing = documentInfo.metadataInstance[CONSTANTS.Documents.Metadata.NESTED_OBJECT_TYPES];
117+
if (!existing) {
118+
return true;
119+
}
120+
if (Object.keys(existing).length !== Object.keys(typeInfo.nestedTypes).length) {
121+
return true;
122+
}
123+
for (const key in typeInfo.nestedTypes) {
124+
if (typeInfo.nestedTypes[key] !== existing[key]) {
125+
return true;
126+
}
127+
}
128+
return false;
129+
}
130+
115131
if (documentInfo.metadataInstance) {
116-
documentInfo.metadataInstance[CONSTANTS.Documents.Metadata.NESTED_OBJECT_TYPES] = typeInfo.nestedTypes;
117-
documentInfo.metadataInstance[CONSTANTS.Documents.Metadata.RAVEN_JS_TYPE] =
118-
documentInfo.metadataInstance["Raven-Node-Type"] || typeInfo.typeName;
132+
if (differentNestedTypes()) {
133+
documentInfo.metadataInstance[CONSTANTS.Documents.Metadata.NESTED_OBJECT_TYPES] = typeInfo.nestedTypes;
134+
}
135+
const nodeType = documentInfo.metadataInstance[CONSTANTS.Documents.Metadata.RAVEN_JS_TYPE] || typeInfo.typeName;
136+
if (documentInfo.metadataInstance[CONSTANTS.Documents.Metadata.RAVEN_JS_TYPE] !== nodeType) {
137+
documentInfo.metadataInstance[CONSTANTS.Documents.Metadata.RAVEN_JS_TYPE] = nodeType;
138+
}
119139
}
120140

121141
let setMetadata: boolean = false;
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { testContext, disposeTestDocumentStore } from "../../Utils/TestUtil";
2+
3+
import {
4+
IDocumentStore,
5+
} from "../../../src";
6+
import { assertThat } from "../../Utils/AssertExtensions";
7+
8+
class Item {
9+
v: string;
10+
11+
constructor(v: string) {
12+
this.v = v;
13+
}
14+
}
15+
16+
describe("SpuriousSaveChanges", function () {
17+
18+
let store: IDocumentStore;
19+
20+
beforeEach(async function () {
21+
store = await testContext.getDocumentStore();
22+
});
23+
24+
afterEach(async () =>
25+
await disposeTestDocumentStore(store)
26+
);
27+
28+
it("willNotSaveUnmodifiedDocuments", async () => {
29+
30+
await createData(store);
31+
32+
{
33+
const session = store.openSession();
34+
const result = await session.query<Item>({ collection: "items" })
35+
.all();
36+
assertThat(session.advanced.hasChanged(result[0]))
37+
.isFalse();
38+
const old = session.advanced.numberOfRequests;
39+
await session.saveChanges();
40+
assertThat(session.advanced.numberOfRequests)
41+
.isEqualTo(old);
42+
}
43+
});
44+
45+
async function createData(store: IDocumentStore): Promise<void> {
46+
const session = store.openSession();
47+
await session.store(new Item("f"), "items/1");
48+
await session.saveChanges();
49+
}
50+
});

0 commit comments

Comments
 (0)