Skip to content

Commit

Permalink
Added the initial update to _version field
Browse files Browse the repository at this point in the history
  • Loading branch information
oskardudycz committed Sep 27, 2024
1 parent b698e00 commit 04d6dd5
Show file tree
Hide file tree
Showing 4 changed files with 253 additions and 47 deletions.
81 changes: 64 additions & 17 deletions src/packages/pongo/src/core/collection/pongoCollection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ import {
import { v4 as uuid } from 'uuid';
import {
type CollectionOperationOptions,
type DeleteManyOptions,
type DeleteOneOptions,
type DocumentHandler,
type InsertManyOptions,
type InsertOneOptions,
type OptionalUnlessRequiredId,
type PongoCollection,
type PongoDb,
Expand All @@ -25,6 +29,10 @@ import {
type PongoInsertOneResult,
type PongoUpdate,
type PongoUpdateResult,
type ReplaceOneOptions,
type UpdateManyOptions,
type UpdateOneOptions,
type UpsertOneOptions,
type WithoutId,
} from '..';
import { pongoCollectionPostgreSQLMigrations } from '../../postgres';
Expand Down Expand Up @@ -108,14 +116,18 @@ export const pongoCollection = <
},
insertOne: async (
document: OptionalUnlessRequiredId<T>,
options?: CollectionOperationOptions,
options?: InsertOneOptions,
): Promise<PongoInsertOneResult> => {
await ensureCollectionCreated(options);

const _id = (document._id as string | undefined | null) ?? uuid();

const result = await command(
SqlFor.insertOne({ ...document, _id } as OptionalUnlessRequiredId<T>),
SqlFor.insertOne({
...document,
_id,
_version: 0,
} as OptionalUnlessRequiredId<T>),
options,
);

Expand All @@ -125,13 +137,14 @@ export const pongoCollection = <
},
insertMany: async (
documents: OptionalUnlessRequiredId<T>[],
options?: CollectionOperationOptions,
options?: InsertManyOptions,
): Promise<PongoInsertManyResult> => {
await ensureCollectionCreated(options);

const rows = documents.map((doc) => ({
...doc,
_id: (doc._id as string | undefined | null) ?? uuid(),
_version: 0,
}));

const result = await command(
Expand All @@ -148,24 +161,42 @@ export const pongoCollection = <
updateOne: async (
filter: PongoFilter<T>,
update: PongoUpdate<T>,
options?: CollectionOperationOptions,
options?: UpdateOneOptions,
): Promise<PongoUpdateResult> => {
await ensureCollectionCreated(options);

const result = await command(
SqlFor.updateOne(filter, update, options),
options,
);
return result.rowCount
? { acknowledged: true, modifiedCount: result.rowCount }
: { acknowledged: false, modifiedCount: 0 };
},
upsertOne: async (
filter: PongoFilter<T>,
update: PongoUpdate<T>,
options?: UpsertOneOptions,
): Promise<PongoUpdateResult> => {
await ensureCollectionCreated(options);

const result = await command(SqlFor.updateOne(filter, update), options);
const result = await command(
SqlFor.upsertOne(filter, update, options),
options,
);
return result.rowCount
? { acknowledged: true, modifiedCount: result.rowCount }
: { acknowledged: false, modifiedCount: 0 };
},
replaceOne: async (
filter: PongoFilter<T>,
document: WithoutId<T>,
options?: CollectionOperationOptions,
options?: ReplaceOneOptions,
): Promise<PongoUpdateResult> => {
await ensureCollectionCreated(options);

const result = await command(
SqlFor.replaceOne(filter, document),
SqlFor.replaceOne(filter, document, options),
options,
);
return result.rowCount
Expand All @@ -175,7 +206,7 @@ export const pongoCollection = <
updateMany: async (
filter: PongoFilter<T>,
update: PongoUpdate<T>,
options?: CollectionOperationOptions,
options?: UpdateManyOptions,
): Promise<PongoUpdateResult> => {
await ensureCollectionCreated(options);

Expand All @@ -186,18 +217,21 @@ export const pongoCollection = <
},
deleteOne: async (
filter?: PongoFilter<T>,
options?: CollectionOperationOptions,
options?: DeleteOneOptions,
): Promise<PongoDeleteResult> => {
await ensureCollectionCreated(options);

const result = await command(SqlFor.deleteOne(filter ?? {}), options);
const result = await command(
SqlFor.deleteOne(filter ?? {}, options),
options,
);
return result.rowCount
? { acknowledged: true, deletedCount: result.rowCount }
: { acknowledged: false, deletedCount: 0 };
},
deleteMany: async (
filter?: PongoFilter<T>,
options?: CollectionOperationOptions,
options?: DeleteManyOptions,
): Promise<PongoDeleteResult> => {
await ensureCollectionCreated(options);

Expand All @@ -217,7 +251,7 @@ export const pongoCollection = <
},
findOneAndDelete: async (
filter: PongoFilter<T>,
options?: CollectionOperationOptions,
options?: DeleteOneOptions,
): Promise<T | null> => {
await ensureCollectionCreated(options);

Expand All @@ -231,7 +265,7 @@ export const pongoCollection = <
findOneAndReplace: async (
filter: PongoFilter<T>,
replacement: WithoutId<T>,
options?: CollectionOperationOptions,
options?: ReplaceOneOptions,
): Promise<T | null> => {
await ensureCollectionCreated(options);

Expand All @@ -246,7 +280,7 @@ export const pongoCollection = <
findOneAndUpdate: async (
filter: PongoFilter<T>,
update: PongoUpdate<T>,
options?: CollectionOperationOptions,
options?: UpdateOneOptions,
): Promise<T | null> => {
await ensureCollectionCreated(options);

Expand Down Expand Up @@ -347,10 +381,23 @@ export type PongoCollectionSQLBuilder = {
createCollection: () => SQL;
insertOne: <T>(document: OptionalUnlessRequiredId<T>) => SQL;
insertMany: <T>(documents: OptionalUnlessRequiredId<T>[]) => SQL;
updateOne: <T>(filter: PongoFilter<T>, update: PongoUpdate<T>) => SQL;
replaceOne: <T>(filter: PongoFilter<T>, document: WithoutId<T>) => SQL;
updateOne: <T>(
filter: PongoFilter<T>,
update: PongoUpdate<T>,
options?: UpdateOneOptions,
) => SQL;
upsertOne: <T>(
filter: PongoFilter<T>,
update: PongoUpdate<T>,
options?: UpsertOneOptions,
) => SQL;
replaceOne: <T>(
filter: PongoFilter<T>,
document: WithoutId<T>,
options?: ReplaceOneOptions,
) => SQL;
updateMany: <T>(filter: PongoFilter<T>, update: PongoUpdate<T>) => SQL;
deleteOne: <T>(filter: PongoFilter<T>) => SQL;
deleteOne: <T>(filter: PongoFilter<T>, options?: DeleteOneOptions) => SQL;
deleteMany: <T>(filter: PongoFilter<T>) => SQL;
findOne: <T>(filter: PongoFilter<T>) => SQL;
find: <T>(filter: PongoFilter<T>) => SQL;
Expand Down
105 changes: 96 additions & 9 deletions src/packages/pongo/src/core/typing/operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,57 @@ export type CollectionOperationOptions = {
session?: PongoSession;
};

export type InsertOneOptions = {
expectedVersion?: Extract<
ExpectedDocumentVersion,
'DOCUMENT_DOES_NOT_EXIST' | 'NO_CONCURRENCY_CHECK'
>;
} & CollectionOperationOptions;

export type InsertManyOptions = {
expectedVersion?: Extract<
ExpectedDocumentVersion,
'DOCUMENT_DOES_NOT_EXIST' | 'NO_CONCURRENCY_CHECK'
>;
} & CollectionOperationOptions;

export type UpdateOneOptions = {
expectedVersion?: Exclude<ExpectedDocumentVersion, 'DOCUMENT_DOES_NOT_EXIST'>;
} & CollectionOperationOptions;

export type UpsertOneOptions = {
expectedVersion?: ExpectedDocumentVersion;
} & CollectionOperationOptions;

export type UpdateManyOptions = {
expectedVersion?: Extract<
ExpectedDocumentVersion,
'DOCUMENT_EXISTS' | 'NO_CONCURRENCY_CHECK'
>;
} & CollectionOperationOptions;

export type ReplaceOneOptions = {
expectedVersion?: Exclude<ExpectedDocumentVersion, 'DOCUMENT_DOES_NOT_EXIST'>;
} & CollectionOperationOptions;

export type DeleteOneOptions = {
expectedVersion?: Exclude<ExpectedDocumentVersion, 'DOCUMENT_DOES_NOT_EXIST'>;
} & CollectionOperationOptions;

export type DeleteManyOptions = {
expectedVersion?: Extract<
ExpectedDocumentVersion,
'DOCUMENT_EXISTS' | 'NO_CONCURRENCY_CHECK'
>;
} & CollectionOperationOptions;

export interface PongoCollection<T extends PongoDocument> {
readonly dbName: string;
readonly collectionName: string;
createCollection(options?: CollectionOperationOptions): Promise<void>;
insertOne(
document: OptionalUnlessRequiredId<T>,
options?: CollectionOperationOptions,
options?: InsertOneOptions,
): Promise<PongoInsertOneResult>;
insertMany(
documents: OptionalUnlessRequiredId<T>[],
Expand All @@ -87,25 +131,30 @@ export interface PongoCollection<T extends PongoDocument> {
updateOne(
filter: PongoFilter<T>,
update: PongoUpdate<T>,
options?: CollectionOperationOptions,
options?: UpdateOneOptions,
): Promise<PongoUpdateResult>;
upsertOne(
filter: PongoFilter<T>,
update: PongoUpdate<T>,
options?: UpsertOneOptions,
): Promise<PongoUpdateResult>;
replaceOne(
filter: PongoFilter<T>,
document: WithoutId<T>,
options?: CollectionOperationOptions,
options?: ReplaceOneOptions,
): Promise<PongoUpdateResult>;
updateMany(
filter: PongoFilter<T>,
update: PongoUpdate<T>,
options?: CollectionOperationOptions,
options?: UpdateManyOptions,
): Promise<PongoUpdateResult>;
deleteOne(
filter?: PongoFilter<T>,
options?: CollectionOperationOptions,
options?: DeleteOneOptions,
): Promise<PongoDeleteResult>;
deleteMany(
filter?: PongoFilter<T>,
options?: CollectionOperationOptions,
options?: DeleteManyOptions,
): Promise<PongoDeleteResult>;
findOne(
filter?: PongoFilter<T>,
Expand All @@ -117,17 +166,17 @@ export interface PongoCollection<T extends PongoDocument> {
): Promise<T[]>;
findOneAndDelete(
filter: PongoFilter<T>,
options?: CollectionOperationOptions,
options?: DeleteOneOptions,
): Promise<T | null>;
findOneAndReplace(
filter: PongoFilter<T>,
replacement: WithoutId<T>,
options?: CollectionOperationOptions,
options?: ReplaceOneOptions,
): Promise<T | null>;
findOneAndUpdate(
filter: PongoFilter<T>,
update: PongoUpdate<T>,
options?: CollectionOperationOptions,
options?: UpdateOneOptions,
): Promise<T | null>;
countDocuments(
filter?: PongoFilter<T>,
Expand Down Expand Up @@ -287,6 +336,44 @@ export type $unset<T> = { [P in keyof T]?: '' };
export type $inc<T> = { [P in keyof T]?: number };
export type $push<T> = { [P in keyof T]?: T[P] };

export type ExpectedDocumentVersionGeneral =
| 'DOCUMENT_EXISTS'
| 'DOCUMENT_DOES_NOT_EXIST'
| 'NO_CONCURRENCY_CHECK';

export type ExpectedDocumentVersionValue = bigint & { __brand: 'sql' };

export type ExpectedDocumentVersion =
| (bigint & { __brand: 'sql' })
| ExpectedDocumentVersionGeneral;

export const DOCUMENT_EXISTS =
'DOCUMENT_EXISTS' as ExpectedDocumentVersionGeneral;
export const DOCUMENT_DOES_NOT_EXIST =
'DOCUMENT_DOES_NOT_EXIST' as ExpectedDocumentVersionGeneral;
export const NO_CONCURRENCY_CHECK =
'NO_CONCURRENCY_CHECK' as ExpectedDocumentVersionGeneral;

export const isGeneralExpectedDocumentVersion = (
version: ExpectedDocumentVersion,
): version is ExpectedDocumentVersionGeneral =>
version === 'DOCUMENT_DOES_NOT_EXIST' ||
version === 'DOCUMENT_EXISTS' ||
version === 'NO_CONCURRENCY_CHECK';

export const expectedVersionValue = (
version: ExpectedDocumentVersion,
): ExpectedDocumentVersionValue | null =>
isGeneralExpectedDocumentVersion(version) ? null : version;

export const expectedVersion = (
version: number | bigint | string | undefined | null,
): ExpectedDocumentVersion => {
return version
? (BigInt(version) as ExpectedDocumentVersion)
: NO_CONCURRENCY_CHECK;
};

export type PongoUpdate<T> = {
$set?: Partial<T>;
$unset?: $unset<T>;
Expand Down
Loading

0 comments on commit 04d6dd5

Please sign in to comment.