From bd231a3d63310049c2467fff15670f351cec3e41 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 4 Apr 2021 19:45:23 +0200 Subject: [PATCH] catalog-backend/next: add Context Signed-off-by: Patrik Oldsberg --- .../src/next/Context/BaseContext.ts | 26 ++++++++++++ .../src/next/Context/ContextWithValue.ts | 40 +++++++++++++++++++ .../src/next/Context/TransactionContext.ts | 40 +++++++++++++++++++ .../catalog-backend/src/next/Context/index.ts | 21 ++++++++++ .../catalog-backend/src/next/Context/types.ts | 23 +++++++++++ 5 files changed, 150 insertions(+) create mode 100644 plugins/catalog-backend/src/next/Context/BaseContext.ts create mode 100644 plugins/catalog-backend/src/next/Context/ContextWithValue.ts create mode 100644 plugins/catalog-backend/src/next/Context/TransactionContext.ts create mode 100644 plugins/catalog-backend/src/next/Context/index.ts create mode 100644 plugins/catalog-backend/src/next/Context/types.ts diff --git a/plugins/catalog-backend/src/next/Context/BaseContext.ts b/plugins/catalog-backend/src/next/Context/BaseContext.ts new file mode 100644 index 0000000000..c9553cffd5 --- /dev/null +++ b/plugins/catalog-backend/src/next/Context/BaseContext.ts @@ -0,0 +1,26 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Context, ContextKey } from './types'; + +/** + * A base Context implementation that does not hold any value. + */ +export class BaseContext implements Context { + getContextValue(key: ContextKey): T { + return key.defaultValue; + } +} diff --git a/plugins/catalog-backend/src/next/Context/ContextWithValue.ts b/plugins/catalog-backend/src/next/Context/ContextWithValue.ts new file mode 100644 index 0000000000..8e61e2c6f2 --- /dev/null +++ b/plugins/catalog-backend/src/next/Context/ContextWithValue.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { BaseContext } from './BaseContext'; +import { Context, ContextKey } from './types'; + +/** + * A Context implementation that holds a single value, optionally extending an existing context. + */ +export class ContextWithValue implements Context { + static create(key: ContextKey, value: unknown, parent?: Context) { + return new ContextWithValue(parent ?? new BaseContext(), key, value); + } + + private constructor( + private readonly parent: Context, + private readonly key: ContextKey, + private readonly value: unknown, + ) {} + + getContextValue(key: ContextKey): T { + if (this.key === key) { + return this.value as T; + } + return this.parent.getContextValue(key); + } +} diff --git a/plugins/catalog-backend/src/next/Context/TransactionContext.ts b/plugins/catalog-backend/src/next/Context/TransactionContext.ts new file mode 100644 index 0000000000..6ac50fbc07 --- /dev/null +++ b/plugins/catalog-backend/src/next/Context/TransactionContext.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Context, ContextKey } from './types'; +import { Knex } from 'knex'; +import { ContextWithValue } from './ContextWithValue'; + +const transactionContextKey = new ContextKey( + undefined, +); + +/** + * TransactionContext handles the wrapping of a knex transaction in a Context. + */ +export class TransactionContext { + static create(tx: Knex.Transaction, parent?: Context) { + return ContextWithValue.create(transactionContextKey, tx, parent); + } + + static getTransaction(context: Context): Knex.Transaction { + const transaction = context.getContextValue(transactionContextKey); + if (!transaction) { + throw new Error(`No transaction available in context`); + } + return transaction; + } +} diff --git a/plugins/catalog-backend/src/next/Context/index.ts b/plugins/catalog-backend/src/next/Context/index.ts new file mode 100644 index 0000000000..992f5e89a6 --- /dev/null +++ b/plugins/catalog-backend/src/next/Context/index.ts @@ -0,0 +1,21 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { BaseContext } from './BaseContext'; +export { ContextWithValue } from './ContextWithValue'; +export { TransactionContext } from './TransactionContext'; +export { ContextKey } from './types'; +export type { Context } from './types'; diff --git a/plugins/catalog-backend/src/next/Context/types.ts b/plugins/catalog-backend/src/next/Context/types.ts new file mode 100644 index 0000000000..0973b83515 --- /dev/null +++ b/plugins/catalog-backend/src/next/Context/types.ts @@ -0,0 +1,23 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export class ContextKey { + constructor(readonly defaultValue: T) {} +} + +export interface Context { + getContextValue(key: ContextKey): T; +}