Skip to content

Commit 2bd5743

Browse files
authored
Merge pull request #321 from ml054/RDBC-595
RDBC-595 Expose createField function in maputils
2 parents f578073 + 8042504 commit 2bd5743

File tree

3 files changed

+156
-2
lines changed

3 files changed

+156
-2
lines changed

src/Documents/Indexes/StronglyTyped.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
11
import { FieldIndexing, FieldStorage, FieldTermVector } from "./Enums";
22
import { MetadataObject } from "../Session/MetadataObject";
3+
import { IndexFieldOptions } from "./IndexFieldOptions";
34

45
export type IndexingMapDefinition<TInput, TOutput> = (document: TInput) => TOutput | TOutput[];
56

67
export type IndexingReduceDefinition<TItem> = (result: IndexingGroupResults<TItem>) => IndexingMapReduceFormatter<TItem>;
78

89
type KeySelector<TDocument, TKey> = (document: TDocument) => TKey;
910

11+
export interface CreateFieldOptions {
12+
storage?: boolean;
13+
indexing?: FieldIndexing;
14+
termVector?: FieldTermVector;
15+
}
16+
1017
export interface IndexingMapUtils {
1118
load<T = any>(documentId: string, collection: string): T;
1219
cmpxchg<T = any>(key: string): T;
1320
getMetadata(document: any): MetadataObject;
1421
id(document: any): string;
1522
createSpatialField(wkt: string): SpatialField;
1623
createSpatialField(lat: number, lng: number): SpatialField;
24+
createField(name: string, value: any, options: CreateFieldOptions): void;
1725
}
1826

1927
export class StubMapUtils<T> implements IndexingMapUtils {
@@ -22,6 +30,7 @@ export class StubMapUtils<T> implements IndexingMapUtils {
2230
getMetadata: (document: any) => MetadataObject;
2331
id: (document: any) => string;
2432
createSpatialField: (wktOrLat: string | number, lng?: number) => void;
33+
createField: (name: string, value: any, options?: CreateFieldOptions) => void;
2534
}
2635

2736
interface Group<TDocument, TKey> {
@@ -76,4 +85,4 @@ export type CreatedField = {
7685
$options: CreatedFieldOptions;
7786
}
7887

79-
export type SpatialField = void;
88+
export type SpatialField = void;

test/Documents/Queries/HashCalculatorTest.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as assert from "assert";
22

33
import { HashCalculator } from "../../../src/Documents/Queries/HashCalculator";
4-
import { TypesAwareObjectMapper } from "../../../src/Mapping/ObjectMapper";
4+
import { TypesAwareObjectMapper } from "../../../src";
55

66
const mockObjectMapper = {
77
toObjectLiteral: obj => obj.toString()
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
import { AbstractJavaScriptIndexCreationTask, GetTermsOperation, IDocumentStore } from "../../../src";
2+
import { disposeTestDocumentStore, testContext } from "../../Utils/TestUtil";
3+
import { assertThat } from "../../Utils/AssertExtensions";
4+
5+
6+
describe("RavenDB_18936Test", function () {
7+
8+
let store: IDocumentStore;
9+
10+
beforeEach(async function () {
11+
store = await testContext.getDocumentStore();
12+
});
13+
14+
afterEach(async () =>
15+
await disposeTestDocumentStore(store));
16+
17+
it("CanCreateDynamicFieldsInsideMapJsIndex", async () => {
18+
const index = new CreateFieldInsideMapJavaScript();
19+
await index.execute(store);
20+
21+
{
22+
const s = store.openSession();
23+
24+
const attributes = [
25+
new Attribute("T1", 10.99),
26+
new Attribute("T2", 12.99),
27+
new Attribute("T3", 13.99)
28+
];
29+
30+
const item = new Item();
31+
item.attributes = attributes;
32+
33+
await s.store(item);
34+
35+
const item2 = new Item();
36+
item2.attributes = [
37+
new Attribute("T1", 11.99)
38+
];
39+
40+
await s.store(item2);
41+
42+
await s.saveChanges();
43+
}
44+
45+
{
46+
const s = store.openSession();
47+
const items = await s.advanced.documentQuery(Item, CreateFieldInsideMapJavaScript)
48+
.waitForNonStaleResults()
49+
.orderByDescending("T1")
50+
.all();
51+
52+
assertThat(items)
53+
.hasSize(2);
54+
55+
await assertTerm(store, index.getIndexName(), "T1", ["10.99", "11.99"]);
56+
await assertTerm(store, index.getIndexName(), "T2", ["12.99"]);
57+
await assertTerm(store, index.getIndexName(), "T3", ["13.99"]);
58+
}
59+
});
60+
61+
it("CanCreateDynamicFieldFromArray", async function () {
62+
63+
{
64+
const session = store.openSession();
65+
const item = new Item();
66+
item.id = "Maciej";
67+
await session.store(item);
68+
await session.saveChanges();
69+
}
70+
71+
const index = new CreateFieldInsideArrayJavaScript();
72+
await index.execute(store);
73+
74+
await testContext.waitForIndexing(store);
75+
76+
await assertTerm(store, index.getIndexName(), "name", ["john"]);
77+
})
78+
});
79+
80+
81+
async function assertTerm(store: IDocumentStore, index: string, fieldName: string, termsThatShouldBeStored: string[]) {
82+
const terms = await store.maintenance.send(new GetTermsOperation(index, fieldName, null, 1024));
83+
84+
assertThat(termsThatShouldBeStored)
85+
.hasSize(terms.length);
86+
87+
for (const term of termsThatShouldBeStored) {
88+
assertThat(terms)
89+
.contains(term);
90+
}
91+
}
92+
93+
class CreateFieldInsideArrayJavaScript extends AbstractJavaScriptIndexCreationTask<Item> {
94+
constructor() {
95+
super();
96+
97+
const { createField } = this.mapUtils();
98+
99+
this.map("Items", p => {
100+
// noinspection JSVoidFunctionReturnValueUsed
101+
return {
102+
_: [ createField("name", "john", {
103+
indexing: "Exact",
104+
storage: false,
105+
termVector: null
106+
}) ]
107+
}
108+
})
109+
}
110+
}
111+
112+
class CreateFieldInsideMapJavaScript extends AbstractJavaScriptIndexCreationTask<Item> {
113+
114+
constructor() {
115+
super();
116+
117+
const { createField } = this.mapUtils();
118+
119+
this.map("Items", p => {
120+
return {
121+
_: p.attributes.map(x => createField(x.name, x.value, {
122+
indexing: "Exact",
123+
storage: true,
124+
termVector: null
125+
}))
126+
}
127+
})
128+
}
129+
}
130+
131+
132+
class Item {
133+
id: string;
134+
attributes: Attribute[];
135+
}
136+
137+
class Attribute {
138+
name: string;
139+
value: number;
140+
141+
constructor(name?: string, value?: number) {
142+
this.name = name;
143+
this.value = value;
144+
}
145+
}

0 commit comments

Comments
 (0)