Skip to content

Commit 30fb9dc

Browse files
committed
fix: move EntityPrivacyUtils back into core package
1 parent be40bcf commit 30fb9dc

23 files changed

Lines changed: 615 additions & 98 deletions

packages/entity-database-adapter-knex-testing-utils/src/StubPostgresDatabaseAdapter.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,21 @@ export class StubPostgresDatabaseAdapter<
8989
return [...results];
9090
}
9191

92+
protected async fetchOneWhereInternalAsync(
93+
queryInterface: any,
94+
tableName: string,
95+
tableColumns: readonly string[],
96+
tableTuple: readonly any[],
97+
): Promise<object | null> {
98+
const results = await this.fetchManyWhereInternalAsync(
99+
queryInterface,
100+
tableName,
101+
tableColumns,
102+
[tableTuple],
103+
);
104+
return results[0] ?? null;
105+
}
106+
92107
private static compareByOrderBys(
93108
orderBys: {
94109
columnName: string;

packages/entity-database-adapter-knex-testing-utils/src/__tests__/StubPostgresDatabaseAdapter-test.ts

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,108 @@ describe(StubPostgresDatabaseAdapter, () => {
181181
});
182182
});
183183

184+
describe('fetchOneWhereAsync', () => {
185+
it('fetches one where single', async () => {
186+
const queryContext = instance(mock(EntityQueryContext));
187+
const databaseAdapter = new StubPostgresDatabaseAdapter<TestFields, 'customIdField'>(
188+
testEntityConfiguration,
189+
StubPostgresDatabaseAdapter.convertFieldObjectsToDataStore(
190+
testEntityConfiguration,
191+
new Map([
192+
[
193+
testEntityConfiguration.tableName,
194+
[
195+
{
196+
customIdField: 'hello',
197+
testIndexedField: 'h1',
198+
intField: 5,
199+
stringField: 'huh',
200+
dateField: new Date(),
201+
nullableField: null,
202+
},
203+
{
204+
customIdField: 'world',
205+
testIndexedField: 'h2',
206+
intField: 3,
207+
stringField: 'huh',
208+
dateField: new Date(),
209+
nullableField: null,
210+
},
211+
],
212+
],
213+
]),
214+
),
215+
);
216+
217+
const result = await databaseAdapter.fetchOneWhereAsync(
218+
queryContext,
219+
new SingleFieldHolder('stringField'),
220+
new SingleFieldValueHolder('huh'),
221+
);
222+
expect(result).toMatchObject({
223+
stringField: 'huh',
224+
});
225+
});
226+
227+
it('returns null when no record found', async () => {
228+
const queryContext = instance(mock(EntityQueryContext));
229+
const databaseAdapter = new StubPostgresDatabaseAdapter<TestFields, 'customIdField'>(
230+
testEntityConfiguration,
231+
new Map(),
232+
);
233+
234+
const result = await databaseAdapter.fetchOneWhereAsync(
235+
queryContext,
236+
new SingleFieldHolder('stringField'),
237+
new SingleFieldValueHolder('huh'),
238+
);
239+
expect(result).toBeNull();
240+
});
241+
242+
it('fetches one where composite', async () => {
243+
const queryContext = instance(mock(EntityQueryContext));
244+
const databaseAdapter = new StubPostgresDatabaseAdapter<TestFields, 'customIdField'>(
245+
testEntityConfiguration,
246+
StubPostgresDatabaseAdapter.convertFieldObjectsToDataStore(
247+
testEntityConfiguration,
248+
new Map([
249+
[
250+
testEntityConfiguration.tableName,
251+
[
252+
{
253+
customIdField: 'hello',
254+
testIndexedField: 'h1',
255+
intField: 5,
256+
stringField: 'huh',
257+
dateField: new Date(),
258+
nullableField: null,
259+
},
260+
{
261+
customIdField: 'world',
262+
testIndexedField: 'h2',
263+
intField: 5,
264+
stringField: 'huh',
265+
dateField: new Date(),
266+
nullableField: null,
267+
},
268+
],
269+
],
270+
]),
271+
),
272+
);
273+
274+
const result = await databaseAdapter.fetchOneWhereAsync(
275+
queryContext,
276+
new CompositeFieldHolder<TestFields, 'customIdField'>(['stringField', 'intField']),
277+
new CompositeFieldValueHolder({ stringField: 'huh', intField: 5 }),
278+
);
279+
expect(result).toMatchObject({
280+
stringField: 'huh',
281+
intField: 5,
282+
});
283+
});
284+
});
285+
184286
describe('fetchManyByFieldEqualityConjunctionAsync', () => {
185287
it('supports conjuntions and query modifiers', async () => {
186288
const queryContext = instance(mock(EntityQueryContext));

packages/entity-database-adapter-knex/src/PostgresEntityDatabaseAdapter.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,25 @@ export class PostgresEntityDatabaseAdapter<
8787
);
8888
}
8989

90+
protected async fetchOneWhereInternalAsync(
91+
queryInterface: Knex,
92+
tableName: string,
93+
tableColumns: readonly string[],
94+
tableTuple: readonly any[],
95+
): Promise<object | null> {
96+
const results = await this.fetchManyByFieldEqualityConjunctionInternalAsync(
97+
queryInterface,
98+
tableName,
99+
tableColumns.map((column, index) => ({
100+
tableField: column,
101+
tableValue: tableTuple[index],
102+
})),
103+
[],
104+
{ limit: 1, orderBy: undefined, offset: undefined },
105+
);
106+
return results[0] ?? null;
107+
}
108+
90109
private applyQueryModifiersToQueryOrderByRaw(
91110
query: Knex.QueryBuilder,
92111
querySelectionModifiers: TableQuerySelectionModifiersWithOrderByRaw,

packages/entity-database-adapter-knex/src/__integration-tests__/PostgresEntityIntegration-test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,42 @@ describe('postgres entity integration', () => {
306306
});
307307
});
308308

309+
describe('single field value loading (fetchOneWhereInternalAsync)', () => {
310+
it('supports one loading', async () => {
311+
const vc1 = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance));
312+
313+
await enforceAsyncResult(
314+
PostgresTestEntity.creatorWithAuthorizationResults(vc1)
315+
.setField('name', 'hello')
316+
.setField('hasACat', false)
317+
.setField('hasADog', true)
318+
.createAsync(),
319+
);
320+
321+
await enforceAsyncResult(
322+
PostgresTestEntity.creatorWithAuthorizationResults(vc1)
323+
.setField('name', 'world')
324+
.setField('hasACat', false)
325+
.setField('hasADog', true)
326+
.createAsync(),
327+
);
328+
329+
await enforceAsyncResult(
330+
PostgresTestEntity.creatorWithAuthorizationResults(vc1)
331+
.setField('name', 'wat')
332+
.setField('hasACat', false)
333+
.setField('hasADog', false)
334+
.createAsync(),
335+
);
336+
337+
const result = await PostgresTestEntity.loaderWithAuthorizationResults(vc1)[
338+
'loadOneByFieldEqualingAsync'
339+
]('hasACat', false);
340+
expect(result?.enforceValue()).not.toBeNull();
341+
expect(result?.enforceValue().getField('hasACat')).toBe(false);
342+
});
343+
});
344+
309345
it('supports single field and composite field equality loading', async () => {
310346
const vc1 = new ViewerContext(createKnexIntegrationTestEntityCompanionProvider(knexInstance));
311347

packages/entity-database-adapter-knex/src/__tests__/BasePostgresEntityDatabaseAdapter-test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class TestEntityDatabaseAdapter extends BasePostgresEntityDatabaseAdapter<
1414
'customIdField'
1515
> {
1616
private readonly fetchResults: object[];
17+
private readonly fetchOneResult: object | null;
1718
private readonly insertResults: object[];
1819
private readonly updateResults: object[];
1920
private readonly fetchEqualityConditionResults: object[];
@@ -23,6 +24,7 @@ class TestEntityDatabaseAdapter extends BasePostgresEntityDatabaseAdapter<
2324

2425
constructor({
2526
fetchResults = [],
27+
fetchOneResult = null,
2628
insertResults = [],
2729
updateResults = [],
2830
fetchEqualityConditionResults = [],
@@ -31,6 +33,7 @@ class TestEntityDatabaseAdapter extends BasePostgresEntityDatabaseAdapter<
3133
deleteCount = 0,
3234
}: {
3335
fetchResults?: object[];
36+
fetchOneResult?: object | null;
3437
insertResults?: object[];
3538
updateResults?: object[];
3639
fetchEqualityConditionResults?: object[];
@@ -40,6 +43,7 @@ class TestEntityDatabaseAdapter extends BasePostgresEntityDatabaseAdapter<
4043
}) {
4144
super(testEntityConfiguration);
4245
this.fetchResults = fetchResults;
46+
this.fetchOneResult = fetchOneResult;
4347
this.insertResults = insertResults;
4448
this.updateResults = updateResults;
4549
this.fetchEqualityConditionResults = fetchEqualityConditionResults;
@@ -61,6 +65,15 @@ class TestEntityDatabaseAdapter extends BasePostgresEntityDatabaseAdapter<
6165
return this.fetchResults;
6266
}
6367

68+
protected async fetchOneWhereInternalAsync(
69+
_queryInterface: any,
70+
_tableName: string,
71+
_tableColumns: readonly string[],
72+
_tableTuple: readonly any[],
73+
): Promise<object | null> {
74+
return this.fetchOneResult;
75+
}
76+
6477
protected async fetchManyByRawWhereClauseInternalAsync(
6578
_queryInterface: any,
6679
_tableName: string,

packages/entity-database-adapter-knex/src/__tests__/fixtures/StubPostgresDatabaseAdapter.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,21 @@ export class StubPostgresDatabaseAdapter<
9090
return [...results];
9191
}
9292

93+
protected async fetchOneWhereInternalAsync(
94+
queryInterface: any,
95+
tableName: string,
96+
tableColumns: readonly string[],
97+
tableTuple: readonly any[],
98+
): Promise<object | null> {
99+
const results = await this.fetchManyWhereInternalAsync(
100+
queryInterface,
101+
tableName,
102+
tableColumns,
103+
[tableTuple],
104+
);
105+
return results[0] ?? null;
106+
}
107+
93108
private static compareByOrderBys(
94109
orderBys: {
95110
columnName: string;

packages/entity-database-adapter-knex/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,3 @@ export * from './extensions/EntityTableDataCoordinatorExtensions';
2222
export * from './extensions/ReadonlyEntityExtensions';
2323
export * from './extensions/ViewerScopedEntityCompanionExtensions';
2424
export * from './internal/EntityKnexDataManager';
25-
export * from './utils/EntityPrivacyUtils';

packages/entity-example/src/adapters/InMemoryDatabaseAdapter.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,21 @@ class InMemoryDatabaseAdapter<
5555
return [...results];
5656
}
5757

58+
protected override async fetchOneWhereInternalAsync(
59+
queryInterface: any,
60+
tableName: string,
61+
tableColumns: readonly string[],
62+
tableTuple: readonly any[],
63+
): Promise<object | null> {
64+
const results = await this.fetchManyWhereInternalAsync(
65+
queryInterface,
66+
tableName,
67+
tableColumns,
68+
[tableTuple],
69+
);
70+
return results[0] ?? null;
71+
}
72+
5873
protected async insertInternalAsync(
5974
_queryInterface: any,
6075
_tableName: string,

packages/entity-testing-utils/src/StubDatabaseAdapter.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,21 @@ export class StubDatabaseAdapter<
7979
return [...results];
8080
}
8181

82+
protected async fetchOneWhereInternalAsync(
83+
queryInterface: any,
84+
tableName: string,
85+
tableColumns: readonly string[],
86+
tableTuple: readonly any[],
87+
): Promise<object | null> {
88+
const results = await this.fetchManyWhereInternalAsync(
89+
queryInterface,
90+
tableName,
91+
tableColumns,
92+
[tableTuple],
93+
);
94+
return results[0] ?? null;
95+
}
96+
8297
private generateRandomID(): any {
8398
const idSchemaField = this.entityConfiguration2.schema.get(this.entityConfiguration2.idField);
8499
invariant(

0 commit comments

Comments
 (0)