[feat][Remote objects] Edit a connection (for pg) (#5210)
## Context #4774 ## How was it tested Locally ## In further PRs - Update connection status upon page change - Adapt Info banner to dark mode - placeholders for form
This commit is contained in:
@ -5,8 +5,8 @@ import { isDefined } from 'class-validator';
|
||||
import {
|
||||
ForeignDataWrapperOptions,
|
||||
RemoteServerType,
|
||||
UserMappingOptions,
|
||||
} from 'src/engine/metadata-modules/remote-server/remote-server.entity';
|
||||
import { UserMappingOptionsInput } from 'src/engine/metadata-modules/remote-server/utils/user-mapping-options.utils';
|
||||
|
||||
@Injectable()
|
||||
export class ForeignDataWrapperQueryFactory {
|
||||
@ -39,7 +39,7 @@ export class ForeignDataWrapperQueryFactory {
|
||||
|
||||
createUserMapping(
|
||||
foreignDataWrapperId: string,
|
||||
userMappingOptions: UserMappingOptions,
|
||||
userMappingOptions: UserMappingOptionsInput,
|
||||
) {
|
||||
// CURRENT_USER works for now since we are using only one user. But if we switch to a user per workspace, we need to change this.
|
||||
return `CREATE USER MAPPING IF NOT EXISTS FOR CURRENT_USER SERVER "${foreignDataWrapperId}" OPTIONS (user '${userMappingOptions.username}', password '${userMappingOptions.password}')`;
|
||||
@ -47,7 +47,7 @@ export class ForeignDataWrapperQueryFactory {
|
||||
|
||||
updateUserMapping(
|
||||
foreignDataWrapperId: string,
|
||||
userMappingOptions: Partial<UserMappingOptions>,
|
||||
userMappingOptions: Partial<UserMappingOptionsInput>,
|
||||
) {
|
||||
const options = this.buildUpdateUserMappingOptions(userMappingOptions);
|
||||
|
||||
@ -82,7 +82,7 @@ export class ForeignDataWrapperQueryFactory {
|
||||
}
|
||||
|
||||
private buildUpdateUserMappingOptions(
|
||||
userMappingOptions?: Partial<UserMappingOptions>,
|
||||
userMappingOptions?: Partial<UserMappingOptionsInput>,
|
||||
) {
|
||||
const setStatements: string[] = [];
|
||||
|
||||
|
||||
@ -6,9 +6,8 @@ import GraphQLJSON from 'graphql-type-json';
|
||||
import {
|
||||
ForeignDataWrapperOptions,
|
||||
RemoteServerType,
|
||||
UserMappingOptions,
|
||||
} from 'src/engine/metadata-modules/remote-server/remote-server.entity';
|
||||
import { UserMappingOptionsInput } from 'src/engine/metadata-modules/remote-server/utils/user-mapping-options-input.utils';
|
||||
import { UserMappingOptionsInput } from 'src/engine/metadata-modules/remote-server/utils/user-mapping-options.utils';
|
||||
|
||||
@InputType()
|
||||
export class CreateRemoteServerInput<T extends RemoteServerType> {
|
||||
@ -20,7 +19,7 @@ export class CreateRemoteServerInput<T extends RemoteServerType> {
|
||||
|
||||
@IsOptional()
|
||||
@Field(() => UserMappingOptionsInput, { nullable: true })
|
||||
userMappingOptions?: UserMappingOptions;
|
||||
userMappingOptions?: UserMappingOptionsInput;
|
||||
|
||||
@IsOptional()
|
||||
@Field(() => String, { nullable: true })
|
||||
|
||||
@ -7,6 +7,7 @@ import {
|
||||
ForeignDataWrapperOptions,
|
||||
RemoteServerType,
|
||||
} from 'src/engine/metadata-modules/remote-server/remote-server.entity';
|
||||
import { GetUserMappingOptions } from 'src/engine/metadata-modules/remote-server/utils/user-mapping-options.utils';
|
||||
|
||||
@ObjectType('RemoteServer')
|
||||
export class RemoteServerDTO<T extends RemoteServerType> {
|
||||
@ -23,6 +24,14 @@ export class RemoteServerDTO<T extends RemoteServerType> {
|
||||
@Field(() => GraphQLJSON, { nullable: true })
|
||||
foreignDataWrapperOptions?: ForeignDataWrapperOptions<T>;
|
||||
|
||||
@IsOptional()
|
||||
@Field(() => GetUserMappingOptions, { nullable: true })
|
||||
userMappingOptions?: GetUserMappingOptions;
|
||||
|
||||
@IsOptional()
|
||||
@Field(() => String, { nullable: true })
|
||||
schema?: string;
|
||||
|
||||
@HideField()
|
||||
workspaceId: string;
|
||||
|
||||
|
||||
@ -6,9 +6,8 @@ import GraphQLJSON from 'graphql-type-json';
|
||||
import {
|
||||
ForeignDataWrapperOptions,
|
||||
RemoteServerType,
|
||||
UserMappingOptions,
|
||||
} from 'src/engine/metadata-modules/remote-server/remote-server.entity';
|
||||
import { UserMappingOptionsInput } from 'src/engine/metadata-modules/remote-server/utils/user-mapping-options-input.utils';
|
||||
import { UserMappingOptionsInput } from 'src/engine/metadata-modules/remote-server/utils/user-mapping-options.utils';
|
||||
|
||||
@InputType()
|
||||
export class UpdateRemoteServerInput<T extends RemoteServerType> {
|
||||
@ -21,5 +20,9 @@ export class UpdateRemoteServerInput<T extends RemoteServerType> {
|
||||
|
||||
@IsOptional()
|
||||
@Field(() => UserMappingOptionsInput, { nullable: true })
|
||||
userMappingOptions?: Partial<UserMappingOptions>;
|
||||
userMappingOptions?: Partial<UserMappingOptionsInput>;
|
||||
|
||||
@IsOptional()
|
||||
@Field(() => String, { nullable: true })
|
||||
schema?: string;
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import {
|
||||
} from 'typeorm';
|
||||
|
||||
import { RemoteTableEntity } from 'src/engine/metadata-modules/remote-server/remote-table/remote-table.entity';
|
||||
import { UserMappingOptionsInput as UserMappingOptions } from 'src/engine/metadata-modules/remote-server/utils/user-mapping-options.utils';
|
||||
import { DistantTables } from 'src/engine/metadata-modules/remote-server/remote-table/distant-table/types/distant-table';
|
||||
|
||||
export enum RemoteServerType {
|
||||
@ -26,12 +27,6 @@ export type ForeignDataWrapperOptions<T extends RemoteServerType> =
|
||||
T extends RemoteServerType.POSTGRES_FDW
|
||||
? PostgresForeignDataWrapperOptions
|
||||
: never;
|
||||
|
||||
export type UserMappingOptions = {
|
||||
username: string;
|
||||
password: string;
|
||||
};
|
||||
|
||||
@Entity('remoteServer')
|
||||
export class RemoteServerEntity<T extends RemoteServerType> {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
|
||||
@ -5,6 +5,7 @@ import {
|
||||
} from '@nestjs/common';
|
||||
import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import isEmpty from 'lodash.isempty';
|
||||
import { v4 } from 'uuid';
|
||||
import { DataSource, EntityManager, Repository } from 'typeorm';
|
||||
|
||||
@ -162,7 +163,9 @@ export class RemoteServerService<T extends RemoteServerType> {
|
||||
partialRemoteServerWithUpdates,
|
||||
);
|
||||
|
||||
if (partialRemoteServerWithUpdates.foreignDataWrapperOptions) {
|
||||
if (
|
||||
!isEmpty(partialRemoteServerWithUpdates.foreignDataWrapperOptions)
|
||||
) {
|
||||
const foreignDataWrapperQuery =
|
||||
this.foreignDataWrapperQueryFactory.updateForeignDataWrapper({
|
||||
foreignDataWrapperId,
|
||||
@ -173,7 +176,7 @@ export class RemoteServerService<T extends RemoteServerType> {
|
||||
await entityManager.query(foreignDataWrapperQuery);
|
||||
}
|
||||
|
||||
if (partialRemoteServerWithUpdates.userMappingOptions) {
|
||||
if (!isEmpty(partialRemoteServerWithUpdates.userMappingOptions)) {
|
||||
const userMappingQuery =
|
||||
this.foreignDataWrapperQueryFactory.updateUserMapping(
|
||||
foreignDataWrapperId,
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
import { BadRequestException } from '@nestjs/common';
|
||||
|
||||
import { isDefined } from 'class-validator';
|
||||
|
||||
import {
|
||||
RemoteServerEntity,
|
||||
RemoteServerType,
|
||||
UserMappingOptions,
|
||||
} from 'src/engine/metadata-modules/remote-server/remote-server.entity';
|
||||
import { UserMappingOptionsInput } from 'src/engine/metadata-modules/remote-server/utils/user-mapping-options.utils';
|
||||
|
||||
export type DeepPartial<T> = {
|
||||
[P in keyof T]?: DeepPartial<T[P]>;
|
||||
@ -13,7 +15,7 @@ export type DeepPartial<T> = {
|
||||
const buildUserMappingOptionsQuery = (
|
||||
parameters: any[],
|
||||
parametersPositions: object,
|
||||
userMappingOptions: DeepPartial<UserMappingOptions>,
|
||||
userMappingOptions: DeepPartial<UserMappingOptionsInput>,
|
||||
): string | null => {
|
||||
const shouldUpdateUserMappingOptionsPassword = isDefined(
|
||||
userMappingOptions?.password,
|
||||
@ -130,6 +132,10 @@ export const updateRemoteServerRawQuery = (
|
||||
options.push(fwdOptionsQuery);
|
||||
}
|
||||
|
||||
if (options.length < 1) {
|
||||
throw new BadRequestException('No fields to update');
|
||||
}
|
||||
|
||||
const rawQuery = `UPDATE metadata."remoteServer" SET ${options.join(
|
||||
', ',
|
||||
)} WHERE "id"= $1 RETURNING *`;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { InputType, Field } from '@nestjs/graphql';
|
||||
import { InputType, Field, ObjectType } from '@nestjs/graphql';
|
||||
|
||||
import { IsOptional } from 'class-validator';
|
||||
|
||||
@ -12,3 +12,10 @@ export class UserMappingOptionsInput {
|
||||
@Field(() => String, { nullable: true })
|
||||
password: string;
|
||||
}
|
||||
|
||||
@ObjectType()
|
||||
export class GetUserMappingOptions {
|
||||
@IsOptional()
|
||||
@Field(() => String, { nullable: true })
|
||||
username: string;
|
||||
}
|
||||
Reference in New Issue
Block a user