Skip to content

Commit 00c421a

Browse files
committed
add fetchOne method
Summary: Ref T3068 Reviewers: #testers, kuba-orlik Reviewed By: #testers, kuba-orlik Subscribers: kuba-orlik Maniphest Tasks: T3068 Differential Revision: https://hub.sealcode.org/D1632
1 parent 72c34ff commit 00c421a

3 files changed

Lines changed: 104 additions & 0 deletions

File tree

orm.remarkup

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,18 @@ const { items } = await app.collections.items
197197
The order of the methods in chain is not significant, aside from the fact that
198198
`fetch` has to be at the end of the chain.
199199

200+
### Listing one item
201+
202+
Comparable to `fetch` method you can use `fetchOne` which returns exactly one item, or null if value is not found:
203+
204+
```
205+
const item = await app.collections.numbers
206+
.suList()
207+
.filter({ item: { "<": 10 } })
208+
.sort({ item: "desc" })
209+
.fetchOne();
210+
```
211+
200212
## Creating an item in a database
201213

202214
```

src/chip-types/item-list.test.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,4 +271,84 @@ describe("ItemList", () => {
271271
assert.strictEqual(items.length, 0);
272272
}
273273
));
274+
275+
describe("fetchOne method", () => {
276+
it("should return the first item in correct order", async () =>
277+
withRunningApp(
278+
(test_app) =>
279+
class extends test_app {
280+
collections = {
281+
...App.BaseCollections,
282+
articles: new (class Items extends Collection {
283+
fields = {
284+
title: new FieldTypes.Text(),
285+
};
286+
})(),
287+
};
288+
},
289+
async ({ app }) => {
290+
const texts = ["first", "second", "third"];
291+
292+
for (let i = 0; i < texts.length; i++) {
293+
await app.collections.articles.suCreate({
294+
title: texts[i],
295+
});
296+
}
297+
298+
const item = await app.collections.articles
299+
.suList()
300+
.sort({ title: "asc" })
301+
.fetchOne();
302+
303+
const itemDescended = await app.collections.articles
304+
.suList()
305+
.sort({ title: "desc" })
306+
.fetchOne();
307+
308+
assert.strictEqual(item!.get("title"), "first");
309+
assert.strictEqual(itemDescended!.get("title"), "third");
310+
}
311+
));
312+
313+
it("should return the first item or null depends on filter formula", async () =>
314+
withRunningApp(
315+
(test_app) =>
316+
class extends test_app {
317+
collections = {
318+
...App.BaseCollections,
319+
numbers: new (class Items extends Collection {
320+
fields = {
321+
item: new FieldTypes.Int(),
322+
};
323+
})(),
324+
};
325+
},
326+
async ({ app }) => {
327+
const items = [
328+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
329+
17, 18, 19, 20,
330+
];
331+
332+
for (let i = 0; i < items.length; i++) {
333+
await app.collections.numbers.suCreate({
334+
item: items[i],
335+
});
336+
}
337+
338+
const itemFilteredNotFound = await app.collections.numbers
339+
.suList()
340+
.filter({ item: { ">": 20 } })
341+
.fetchOne();
342+
343+
const itemFilteredFound = await app.collections.numbers
344+
.suList()
345+
.filter({ item: { "<": 10 } })
346+
.sort({ item: "desc" })
347+
.fetchOne();
348+
349+
assert.strictEqual(itemFilteredNotFound, null);
350+
assert.strictEqual(itemFilteredFound!.get("item"), 9);
351+
}
352+
));
353+
});
274354
});

src/chip-types/item-list.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,18 @@ export default class ItemList<T extends Collection> {
345345
);
346346
}
347347

348+
/**
349+
* execute crated database request and return one item
350+
*/
351+
async fetchOne(
352+
{ is_http_api_request } = { is_http_api_request: false }
353+
): Promise<CollectionItem<T> | null> {
354+
this.paginate({ items: 1 });
355+
const result = await this.fetch({ is_http_api_request });
356+
357+
return result.items[0] || null;
358+
}
359+
348360
async toCSV(): Promise<string> {
349361
const result = await this.fetch();
350362
const rows = [Collection.getFieldnames(this.collection)];

0 commit comments

Comments
 (0)