From 1b1138ab3afdf34a519ebcd1c026a77ce3a6df20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20S=C3=BCle?= Date: Fri, 16 Sep 2022 21:26:27 +0200 Subject: [PATCH 01/15] merge-columns possible to select columns to merge --- .vscode/launch.json | 15 ++++++ .../data-view/models/result-set.model.ts | 1 + src/app/models/ui-request.model.ts | 13 +++++ src/app/services/crud.service.ts | 6 ++- .../edit-columns/edit-columns.component.html | 27 ++++++++++ .../edit-columns/edit-columns.component.ts | 53 ++++++++++++++++++- 6 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..a6a8238d --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "pwa-chrome", + "request": "launch", + "name": "Launch Chrome against localhost", + "url": "http://localhost:4200", + "webRoot": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/src/app/components/data-view/models/result-set.model.ts b/src/app/components/data-view/models/result-set.model.ts index eaaddabf..6137b059 100644 --- a/src/app/components/data-view/models/result-set.model.ts +++ b/src/app/components/data-view/models/result-set.model.ts @@ -165,6 +165,7 @@ export class DbColumn { defaultValue: any; dimension: number; cardinality: number; + mergeable: boolean; //for data sources as: string; diff --git a/src/app/models/ui-request.model.ts b/src/app/models/ui-request.model.ts index 861062dc..e294e987 100644 --- a/src/app/models/ui-request.model.ts +++ b/src/app/models/ui-request.model.ts @@ -210,6 +210,19 @@ export class ColumnRequest extends UIRequest { } } +export class MergeColumnsRequest extends UIRequest { + columnsToMerge: DbColumn[]; + newColumnName: string; + tableType: string; + constructor( tableId: string, columnsToMerge: DbColumn[], newColumnName: string, tableType:string = 'table') { + super(); + this.tableId = tableId; + this.columnsToMerge = columnsToMerge; + this.newColumnName = newColumnName; + this.tableType = tableType; + } +} + export class MaterializedRequest extends UIRequest{ constructor(tableId: string) { super(); diff --git a/src/app/services/crud.service.ts b/src/app/services/crud.service.ts index 42f280ee..7d91d12f 100644 --- a/src/app/services/crud.service.ts +++ b/src/app/services/crud.service.ts @@ -3,7 +3,7 @@ import {HttpClient, HttpHeaders} from '@angular/common/http'; import {WebuiSettingsService} from './webui-settings.service'; import {Index, ModifyPartitionRequest, PartitionFunctionModel, PartitioningRequest} from '../components/data-view/models/result-set.model'; import {webSocket} from 'rxjs/webSocket'; -import {ColumnRequest, ConstraintRequest, DeleteRequest, EditCollectionRequest, EditTableRequest, ExploreTable, MaterializedRequest, MonitoringRequest, QueryRequest, RelAlgRequest, Schema, SchemaRequest, StatisticRequest, TableRequest} from '../models/ui-request.model'; +import {ColumnRequest, ConstraintRequest, DeleteRequest, EditCollectionRequest, EditTableRequest, ExploreTable, MaterializedRequest, MergeColumnsRequest, MonitoringRequest, QueryRequest, RelAlgRequest, Schema, SchemaRequest, StatisticRequest, TableRequest} from '../models/ui-request.model'; import {ForeignKey} from '../views/uml/uml.model'; import {Validators} from '@angular/forms'; import {HubService} from './hub.service'; @@ -170,6 +170,10 @@ export class CrudService { return this._http.post(`${this.httpUrl}/dropColumn`, columnRequest, this.httpOptions); } + mergeColumns ( columnRequest: MergeColumnsRequest ) { + return this._http.post(`${this.httpUrl}/mergeColumns`, columnRequest, this.httpOptions); + } + /** * Get list of tables of a schema to truncate/drop them */ diff --git a/src/app/views/schema-editing/edit-columns/edit-columns.component.html b/src/app/views/schema-editing/edit-columns/edit-columns.component.html index 02d9a0a1..bc03be9c 100644 --- a/src/app/views/schema-editing/edit-columns/edit-columns.component.html +++ b/src/app/views/schema-editing/edit-columns/edit-columns.component.html @@ -524,7 +524,34 @@
Data placements
+ +
+
+
+
Schema Evolutions
+
+
+
+ Merge columns +
+
+
+
+ + +
+
+
+
+ + +
+ +
+
+
diff --git a/src/app/views/schema-editing/edit-columns/edit-columns.component.ts b/src/app/views/schema-editing/edit-columns/edit-columns.component.ts index e0b68ef5..1d38c6e1 100644 --- a/src/app/views/schema-editing/edit-columns/edit-columns.component.ts +++ b/src/app/views/schema-editing/edit-columns/edit-columns.component.ts @@ -6,7 +6,7 @@ import {CrudService} from '../../../services/crud.service'; import {DbColumn, FieldType, Index, ModifyPartitionRequest, PartitionFunctionModel, PartitioningRequest, PolyType, ResultSet, StatisticColumnSet, StatisticTableSet, TableConstraint} from '../../../components/data-view/models/result-set.model'; import {ToastDuration, ToastService} from '../../../components/toast/toast.service'; import {FormControl, FormGroup, Validators} from '@angular/forms'; -import {ColumnRequest, ConstraintRequest, EditTableRequest, MaterializedRequest} from '../../../models/ui-request.model'; +import {ColumnRequest, ConstraintRequest, EditTableRequest, MaterializedRequest, MergeColumnsRequest} from '../../../models/ui-request.model'; import {DbmsTypesService} from '../../../services/dbms-types.service'; import {CatalogColumnPlacement, MaterializedInfos, Placements, PlacementType, Store} from '../../adapters/adapter.model'; import {ModalDirective} from 'ngx-bootstrap/modal'; @@ -39,6 +39,9 @@ export class EditColumnsComponent implements OnInit, OnDestroy { confirmConstraint = -1; newPrimaryKey: DbColumn[]; + mergedColumnName = '' + mergeableColumns: DbColumn[]; + uniqueConstraintName = ''; proposedConstraintName = 'constraintName'; @@ -171,6 +174,7 @@ export class EditColumnsComponent implements OnInit, OnDestroy { this.partitioningRequest.column = this.resultSet.header[0].name; // deep copy: from: https://stackoverflow.com/questions/35504310/deep-copy-an-array-in-angular-2-typescript this.newPrimaryKey = this.resultSet.header.map( x => Object.assign({}, x)); + this.mergeableColumns = this.resultSet.header.map( x => Object.assign({}, x)); }, err => { this._toast.error('Could not load columns of the table.', null, ToastDuration.INFINITE); console.log(err); @@ -462,6 +466,53 @@ export class EditColumnsComponent implements OnInit, OnDestroy { ); } + mergeColumns() { + if( this.mergedColumnName === '' ) { + this._toast.warn('Please provide a name for the merged column.', 'constraint name'); + return; + } + if( ! this._crud.nameIsValid( this.mergedColumnName ) ){ + this._toast.warn(this._crud.invalidNameMessage('column'), 'invalid column name'); + return; + } + // TODO: the new column name can also be one of the merged column names + if( this.resultSet.header.filter( (h) => h.name === this.mergedColumnName ).length > 0 ) { + this._toast.warn( 'There already exists a column with this name', 'invalid column name' ); + return; + } + + const columnsToMerge = []; + this.mergeableColumns.forEach((v, k) => { + if(v.mergeable) { + columnsToMerge.push(v); + } + }); + + const req = new MergeColumnsRequest( this.tableId, columnsToMerge, this.mergedColumnName) + this._crud.mergeColumns( req ).subscribe( + res => { + const result = res; + if( result.error === undefined ){ + // TODO: do we need it? Reset? + this.getColumns(); + this.getPlacementsAndPartitions(); + this.createColumn.name = ''; + this.createColumn.nullable = true; + this.createColumn.dataType = this.types[0].name; + this.createColumn.collectionsType = ''; + this.createColumn.precision = null; + this.createColumn.scale = null; + this.createColumn.defaultValue = null; + } else { + this._toast.exception(result, null, 'server error', ToastDuration.INFINITE); + } + }, err => { + this._toast.error('An error occurred on the server.', null, ToastDuration.INFINITE); + console.log(err); + } + ); + } + addUniqueConstraint(){ if( this.uniqueConstraintName === '' ) { if (!this.proposedConstraintName) { From f5a9c99c8265c053b0ffa2ed8ef58936a69ce8d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20S=C3=BCle?= Date: Sat, 17 Sep 2022 16:15:09 +0200 Subject: [PATCH 02/15] merge-columns list only VARCHAR columns --- .vscode/launch.json | 15 --------------- .../edit-columns/edit-columns.component.ts | 2 +- 2 files changed, 1 insertion(+), 16 deletions(-) delete mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index a6a8238d..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "pwa-chrome", - "request": "launch", - "name": "Launch Chrome against localhost", - "url": "http://localhost:4200", - "webRoot": "${workspaceFolder}" - } - ] -} \ No newline at end of file diff --git a/src/app/views/schema-editing/edit-columns/edit-columns.component.ts b/src/app/views/schema-editing/edit-columns/edit-columns.component.ts index 1d38c6e1..e316dccd 100644 --- a/src/app/views/schema-editing/edit-columns/edit-columns.component.ts +++ b/src/app/views/schema-editing/edit-columns/edit-columns.component.ts @@ -174,7 +174,7 @@ export class EditColumnsComponent implements OnInit, OnDestroy { this.partitioningRequest.column = this.resultSet.header[0].name; // deep copy: from: https://stackoverflow.com/questions/35504310/deep-copy-an-array-in-angular-2-typescript this.newPrimaryKey = this.resultSet.header.map( x => Object.assign({}, x)); - this.mergeableColumns = this.resultSet.header.map( x => Object.assign({}, x)); + this.mergeableColumns = this.resultSet.header.filter(x => x.dataType == 'VARCHAR').map( x => Object.assign({}, x)); }, err => { this._toast.error('Could not load columns of the table.', null, ToastDuration.INFINITE); console.log(err); From c0e08a8a3fcf953a5aacda41c0f5d32d23efd942 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20S=C3=BCle?= Date: Sun, 18 Sep 2022 11:03:42 +0200 Subject: [PATCH 03/15] merge-columns: the new column name can also be one of the column names to merge --- .../edit-columns/edit-columns.component.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/app/views/schema-editing/edit-columns/edit-columns.component.ts b/src/app/views/schema-editing/edit-columns/edit-columns.component.ts index e316dccd..1aa4ae3b 100644 --- a/src/app/views/schema-editing/edit-columns/edit-columns.component.ts +++ b/src/app/views/schema-editing/edit-columns/edit-columns.component.ts @@ -475,11 +475,6 @@ export class EditColumnsComponent implements OnInit, OnDestroy { this._toast.warn(this._crud.invalidNameMessage('column'), 'invalid column name'); return; } - // TODO: the new column name can also be one of the merged column names - if( this.resultSet.header.filter( (h) => h.name === this.mergedColumnName ).length > 0 ) { - this._toast.warn( 'There already exists a column with this name', 'invalid column name' ); - return; - } const columnsToMerge = []; this.mergeableColumns.forEach((v, k) => { @@ -488,6 +483,16 @@ export class EditColumnsComponent implements OnInit, OnDestroy { } }); + // TODO: the new column name can also be one of the merged column names + if( this.resultSet.header + .filter( h => !columnsToMerge.map(h => h.name).includes(h.name)) + .filter( h => h.name === this.mergedColumnName ) + .length > 0 ) { + this._toast.warn( 'There already exists a column with this name', 'invalid column name' ); + return; + } + + const req = new MergeColumnsRequest( this.tableId, columnsToMerge, this.mergedColumnName) this._crud.mergeColumns( req ).subscribe( res => { From cb70484207f96b40b4f69fb8320e5638482c7f1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20S=C3=BCle?= Date: Sun, 18 Sep 2022 11:20:10 +0200 Subject: [PATCH 04/15] merge-columns: extended warning message --- .../edit-columns/edit-columns.component.ts | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/app/views/schema-editing/edit-columns/edit-columns.component.ts b/src/app/views/schema-editing/edit-columns/edit-columns.component.ts index 1aa4ae3b..09347830 100644 --- a/src/app/views/schema-editing/edit-columns/edit-columns.component.ts +++ b/src/app/views/schema-editing/edit-columns/edit-columns.component.ts @@ -483,31 +483,23 @@ export class EditColumnsComponent implements OnInit, OnDestroy { } }); - // TODO: the new column name can also be one of the merged column names if( this.resultSet.header .filter( h => !columnsToMerge.map(h => h.name).includes(h.name)) .filter( h => h.name === this.mergedColumnName ) .length > 0 ) { - this._toast.warn( 'There already exists a column with this name', 'invalid column name' ); + this._toast.warn( 'There already exists a column with this name. However, it is allowed to select one of the names of the columns to be merged', + 'invalid column name' ); return; } - const req = new MergeColumnsRequest( this.tableId, columnsToMerge, this.mergedColumnName) this._crud.mergeColumns( req ).subscribe( res => { const result = res; if( result.error === undefined ){ - // TODO: do we need it? Reset? this.getColumns(); this.getPlacementsAndPartitions(); - this.createColumn.name = ''; - this.createColumn.nullable = true; - this.createColumn.dataType = this.types[0].name; - this.createColumn.collectionsType = ''; - this.createColumn.precision = null; - this.createColumn.scale = null; - this.createColumn.defaultValue = null; + this.mergedColumnName = '' } else { this._toast.exception(result, null, 'server error', ToastDuration.INFINITE); } From 1f6908315d4a6ba7579294665b399b916d2f7fe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20S=C3=BCle?= Date: Fri, 23 Sep 2022 16:42:39 +0200 Subject: [PATCH 05/15] exclude primary keys from the mergeable columns --- src/app/models/ui-request.model.ts | 10 +++++----- .../edit-columns/edit-columns.component.html | 3 ++- .../edit-columns/edit-columns.component.ts | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/app/models/ui-request.model.ts b/src/app/models/ui-request.model.ts index e294e987..84a6b3fb 100644 --- a/src/app/models/ui-request.model.ts +++ b/src/app/models/ui-request.model.ts @@ -211,14 +211,14 @@ export class ColumnRequest extends UIRequest { } export class MergeColumnsRequest extends UIRequest { - columnsToMerge: DbColumn[]; - newColumnName: string; + sourceColumns: DbColumn[]; + targetColumnName: string; tableType: string; - constructor( tableId: string, columnsToMerge: DbColumn[], newColumnName: string, tableType:string = 'table') { + constructor( tableId: string, sourceColumns: DbColumn[], targetColumnName: string, tableType:string = 'table') { super(); this.tableId = tableId; - this.columnsToMerge = columnsToMerge; - this.newColumnName = newColumnName; + this.sourceColumns = sourceColumns; + this.targetColumnName = targetColumnName; this.tableType = tableType; } } diff --git a/src/app/views/schema-editing/edit-columns/edit-columns.component.html b/src/app/views/schema-editing/edit-columns/edit-columns.component.html index bc03be9c..00614c1c 100644 --- a/src/app/views/schema-editing/edit-columns/edit-columns.component.html +++ b/src/app/views/schema-editing/edit-columns/edit-columns.component.html @@ -535,7 +535,8 @@
Schema Evolutions
Merge columns
-
+
+

Currently, only the merge of non-primary, varchar columns is permitted.

diff --git a/src/app/views/schema-editing/edit-columns/edit-columns.component.ts b/src/app/views/schema-editing/edit-columns/edit-columns.component.ts index 09347830..caccfd17 100644 --- a/src/app/views/schema-editing/edit-columns/edit-columns.component.ts +++ b/src/app/views/schema-editing/edit-columns/edit-columns.component.ts @@ -174,7 +174,7 @@ export class EditColumnsComponent implements OnInit, OnDestroy { this.partitioningRequest.column = this.resultSet.header[0].name; // deep copy: from: https://stackoverflow.com/questions/35504310/deep-copy-an-array-in-angular-2-typescript this.newPrimaryKey = this.resultSet.header.map( x => Object.assign({}, x)); - this.mergeableColumns = this.resultSet.header.filter(x => x.dataType == 'VARCHAR').map( x => Object.assign({}, x)); + this.mergeableColumns = this.resultSet.header.filter(x => x.dataType == 'VARCHAR' && !x.primary).map( x => Object.assign({}, x)); }, err => { this._toast.error('Could not load columns of the table.', null, ToastDuration.INFINITE); console.log(err); @@ -468,7 +468,7 @@ export class EditColumnsComponent implements OnInit, OnDestroy { mergeColumns() { if( this.mergedColumnName === '' ) { - this._toast.warn('Please provide a name for the merged column.', 'constraint name'); + this._toast.warn('Please provide a name for the merged column.', 'merged colum name'); return; } if( ! this._crud.nameIsValid( this.mergedColumnName ) ){ From bbd76c35adaa9b754284abb5040f44443f02bf91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20S=C3=BCle?= Date: Tue, 1 Nov 2022 11:56:25 +0100 Subject: [PATCH 06/15] ListPickerComponent to select the columns to merge --- src/app/components/components.module.ts | 5 + .../list-picker/list-picker.component.html | 21 ++++ .../list-picker/list-picker.component.scss | 66 ++++++++++ .../list-picker/list-picker.component.ts | 116 ++++++++++++++++++ .../edit-columns/edit-columns.component.html | 10 +- .../edit-columns/edit-columns.component.ts | 20 +-- 6 files changed, 222 insertions(+), 16 deletions(-) create mode 100644 src/app/components/list-picker/list-picker.component.html create mode 100644 src/app/components/list-picker/list-picker.component.scss create mode 100644 src/app/components/list-picker/list-picker.component.ts diff --git a/src/app/components/components.module.ts b/src/app/components/components.module.ts index ab0474da..7652a7dd 100644 --- a/src/app/components/components.module.ts +++ b/src/app/components/components.module.ts @@ -37,6 +37,8 @@ import { JsonTextComponent } from './data-view/json-text/json-text.component'; import {NgxJsonViewerModule} from 'ngx-json-viewer'; import {JsonEditorComponent} from './json/json-editor.component'; import {JsonElemComponent} from './json/json-elem/json-elem.component'; +import { ListPickerComponent } from './list-picker/list-picker.component'; +import { DragDropModule } from '@angular/cdk/drag-drop'; //import 'hammerjs'; @@ -46,6 +48,7 @@ import {JsonElemComponent} from './json/json-elem/json-elem.component'; RouterModule, CommonModule, ChartsModule, + DragDropModule, TypeaheadModule.forRoot(), AppBreadcrumbModule.forRoot(), TreeModule, @@ -70,6 +73,7 @@ import {JsonElemComponent} from './json/json-elem/json-elem.component'; InformationManagerComponent, RenderItemComponent, InputComponent, + ListPickerComponent, EditorComponent, JsonEditorComponent, DataViewComponent, @@ -95,6 +99,7 @@ import {JsonElemComponent} from './json/json-elem/json-elem.component'; ToastComponent, InformationManagerComponent, InputComponent, + ListPickerComponent, JsonEditorComponent, EditorComponent, DeleteConfirmComponent diff --git a/src/app/components/list-picker/list-picker.component.html b/src/app/components/list-picker/list-picker.component.html new file mode 100644 index 00000000..b2442409 --- /dev/null +++ b/src/app/components/list-picker/list-picker.component.html @@ -0,0 +1,21 @@ +
+ {{ sourceTitle }} +
+
+ {{ option[labelProperty] }} + +
+
+
+ +
+ {{ targetTitle }} +
+
+ + {{ option[labelProperty] }} +
+
+
\ No newline at end of file diff --git a/src/app/components/list-picker/list-picker.component.scss b/src/app/components/list-picker/list-picker.component.scss new file mode 100644 index 00000000..0c67e34c --- /dev/null +++ b/src/app/components/list-picker/list-picker.component.scss @@ -0,0 +1,66 @@ +.app-list-picker { + display: flex; + gap: 10px; + + .source-column, + .target-column { + display: flex; + flex-direction: column; + } + + .list-container { + min-width: 200px; + min-height: 200px; + max-height: 200px; + border: 1px #e4e7ea solid; + flex: 1 1 auto; + border-radius: 0.2rem; + overflow-y: scroll; + } + + .list-container .list-item:not(.cdk-drag-dragging) { + opacity: 1; + padding: 0.2rem 0.5rem; + transition: all 0.2s; + display: flex; + align-items: center; + justify-content: space-between; + border: 1px var(--white) solid; + border-radius: 0; + box-shadow: none; + border: 1x var(--white) solid; + background: var(--white); + + em { + color: var(--gray); + font-size: 10px; + } + } + + .list-container .list-item:not(.cdk-drag-dragging):hover { + background: var(--light); + cursor: pointer; + } + + .list-container .list-item.cdk-drag-placeholder { + opacity: 0.2; + } +} + +.cdk-drag.list-item { + opacity: 1; + padding: 0.2rem 0.5rem; + transition: all 0.1s; + display: flex; + align-items: center; + justify-content: space-between; + background: var(--light); + border: 1px var(--gray) solid; + border-radius: 0.2rem; + box-shadow: 0px 0px 5px var(--light); + + em { + color: var(--gray); + font-size: 10px; + } +} \ No newline at end of file diff --git a/src/app/components/list-picker/list-picker.component.ts b/src/app/components/list-picker/list-picker.component.ts new file mode 100644 index 00000000..3d234e7e --- /dev/null +++ b/src/app/components/list-picker/list-picker.component.ts @@ -0,0 +1,116 @@ +import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; +import { Component, EventEmitter, forwardRef, HostBinding, Input, Output, ViewEncapsulation } from '@angular/core'; +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; + +/** + * ListPickerComponent is used to select multiple values from a list of options. + */ +@Component({ + selector: 'app-list-picker', + templateUrl: './list-picker.component.html', + styleUrls: ['./list-picker.component.scss'], + encapsulation: ViewEncapsulation.None, + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => ListPickerComponent), + multi: true, + }, + ], +}) +export class ListPickerComponent implements ControlValueAccessor { + + @HostBinding("class") + classes = ["app-list-picker"] + + /** + * Title of the source options + */ + @Input() + sourceTitle = "Source"; + + /** + * Title of the target options + */ + @Input() + targetTitle = "Target"; + + /** + * An array of objects to display as the available options. + */ + @Input() + sourceOptions: Array + + /** + * Name of the label field of an option. + */ + @Input() + labelProperty: keyof T | null; + + /** + * Number of maximum options that can be selected. + */ + @Input() + selectionLimit = Infinity; + + /** + * Disable drag and drop sorting + */ + @Input() + disableSort = false; + + /** + * Callback to invoke when selection limit is reached. + */ + @Output() + selectionLimitReached = new EventEmitter(); + + _value: Array | null; + + _disabled: boolean; + + _onChange: (value: Array) => void + + _onTouched: () => void + + writeValue(value: Array): void { + this._value = value + } + + registerOnChange(fn: (value: Array) => void): void { + this._onChange = fn + } + + registerOnTouched(fn: () => void): void { + this._onTouched = fn + } + + setDisabledState?(isDisabled: boolean): void { + this._disabled = isDisabled; + } + + _getSourceOptions = () => { + return this.sourceOptions?.filter(option => !this._value?.includes(option)); + } + + _onAddOption = (option: T) => { + this._onTouched(); + if((this._value?.length ?? 0) < this.selectionLimit) { + this._value = [...this._value ?? [], option]; + this._onChange(this._value); + } else { + this.selectionLimitReached.emit() + } + } + + _onRemoveOption = (option: T) => { + this._value?.splice( this._value?.indexOf(option), 1); + this._onChange(this._value); + this._onTouched(); + } + + + _onMoveOption = (event: CdkDragDrop) => { + moveItemInArray(this._value, event.previousIndex, event.currentIndex); + } +} diff --git a/src/app/views/schema-editing/edit-columns/edit-columns.component.html b/src/app/views/schema-editing/edit-columns/edit-columns.component.html index 00614c1c..e145e5df 100644 --- a/src/app/views/schema-editing/edit-columns/edit-columns.component.html +++ b/src/app/views/schema-editing/edit-columns/edit-columns.component.html @@ -537,11 +537,9 @@
Schema Evolutions

Currently, only the merge of non-primary, varchar columns is permitted.

-
-
- - -
+
+
@@ -549,7 +547,7 @@
Schema Evolutions
- +
diff --git a/src/app/views/schema-editing/edit-columns/edit-columns.component.ts b/src/app/views/schema-editing/edit-columns/edit-columns.component.ts index caccfd17..b41aaa9f 100644 --- a/src/app/views/schema-editing/edit-columns/edit-columns.component.ts +++ b/src/app/views/schema-editing/edit-columns/edit-columns.component.ts @@ -41,6 +41,7 @@ export class EditColumnsComponent implements OnInit, OnDestroy { mergedColumnName = '' mergeableColumns: DbColumn[]; + columnsToMerge: DbColumn[] = []; uniqueConstraintName = ''; proposedConstraintName = 'constraintName'; @@ -467,6 +468,11 @@ export class EditColumnsComponent implements OnInit, OnDestroy { } mergeColumns() { + + if( this.columnsToMerge?.length < 2 ) { + this._toast.warn('Please select at least 2 columns to merge.', 'merged colum name'); + return; + } if( this.mergedColumnName === '' ) { this._toast.warn('Please provide a name for the merged column.', 'merged colum name'); return; @@ -476,15 +482,8 @@ export class EditColumnsComponent implements OnInit, OnDestroy { return; } - const columnsToMerge = []; - this.mergeableColumns.forEach((v, k) => { - if(v.mergeable) { - columnsToMerge.push(v); - } - }); - if( this.resultSet.header - .filter( h => !columnsToMerge.map(h => h.name).includes(h.name)) + .filter( h => !this.columnsToMerge.map(h => h.name).includes(h.name)) .filter( h => h.name === this.mergedColumnName ) .length > 0 ) { this._toast.warn( 'There already exists a column with this name. However, it is allowed to select one of the names of the columns to be merged', @@ -492,14 +491,15 @@ export class EditColumnsComponent implements OnInit, OnDestroy { return; } - const req = new MergeColumnsRequest( this.tableId, columnsToMerge, this.mergedColumnName) + const req = new MergeColumnsRequest( this.tableId, this.columnsToMerge, this.mergedColumnName) this._crud.mergeColumns( req ).subscribe( res => { const result = res; if( result.error === undefined ){ this.getColumns(); this.getPlacementsAndPartitions(); - this.mergedColumnName = '' + this.mergedColumnName = ''; + this.columnsToMerge = []; } else { this._toast.exception(result, null, 'server error', ToastDuration.INFINITE); } From 28b05b2f22892b0889d009edf9ab6bc12aad1fee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20S=C3=BCle?= Date: Tue, 1 Nov 2022 12:28:47 +0100 Subject: [PATCH 07/15] joinString added for MergeColumnsRequest --- src/app/models/ui-request.model.ts | 4 +++- .../schema-editing/edit-columns/edit-columns.component.html | 2 ++ .../schema-editing/edit-columns/edit-columns.component.ts | 4 +++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/app/models/ui-request.model.ts b/src/app/models/ui-request.model.ts index 84a6b3fb..8ee8e511 100644 --- a/src/app/models/ui-request.model.ts +++ b/src/app/models/ui-request.model.ts @@ -212,12 +212,14 @@ export class ColumnRequest extends UIRequest { export class MergeColumnsRequest extends UIRequest { sourceColumns: DbColumn[]; + joinString: string; targetColumnName: string; tableType: string; - constructor( tableId: string, sourceColumns: DbColumn[], targetColumnName: string, tableType:string = 'table') { + constructor( tableId: string, sourceColumns: DbColumn[], joinString: string, targetColumnName: string, tableType:string = 'table') { super(); this.tableId = tableId; this.sourceColumns = sourceColumns; + this.joinString = joinString; this.targetColumnName = targetColumnName; this.tableType = tableType; } diff --git a/src/app/views/schema-editing/edit-columns/edit-columns.component.html b/src/app/views/schema-editing/edit-columns/edit-columns.component.html index e145e5df..0621118f 100644 --- a/src/app/views/schema-editing/edit-columns/edit-columns.component.html +++ b/src/app/views/schema-editing/edit-columns/edit-columns.component.html @@ -543,6 +543,8 @@
Schema Evolutions
+ + diff --git a/src/app/views/schema-editing/edit-columns/edit-columns.component.ts b/src/app/views/schema-editing/edit-columns/edit-columns.component.ts index b41aaa9f..45a0e1cb 100644 --- a/src/app/views/schema-editing/edit-columns/edit-columns.component.ts +++ b/src/app/views/schema-editing/edit-columns/edit-columns.component.ts @@ -40,6 +40,7 @@ export class EditColumnsComponent implements OnInit, OnDestroy { newPrimaryKey: DbColumn[]; mergedColumnName = '' + joinString = '' mergeableColumns: DbColumn[]; columnsToMerge: DbColumn[] = []; @@ -491,7 +492,7 @@ export class EditColumnsComponent implements OnInit, OnDestroy { return; } - const req = new MergeColumnsRequest( this.tableId, this.columnsToMerge, this.mergedColumnName) + const req = new MergeColumnsRequest( this.tableId, this.columnsToMerge, this.joinString, this.mergedColumnName) this._crud.mergeColumns( req ).subscribe( res => { const result = res; @@ -499,6 +500,7 @@ export class EditColumnsComponent implements OnInit, OnDestroy { this.getColumns(); this.getPlacementsAndPartitions(); this.mergedColumnName = ''; + this.joinString = ''; this.columnsToMerge = []; } else { this._toast.exception(result, null, 'server error', ToastDuration.INFINITE); From d93f4f40ca0cb471eaf7b3c032cecc8e8cbfcd3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20S=C3=BCle?= Date: Tue, 1 Nov 2022 17:05:25 +0100 Subject: [PATCH 08/15] joinString added to MergeColumnRequest --- src/app/models/ui-request.model.ts | 6 +++--- .../schema-editing/edit-columns/edit-columns.component.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/app/models/ui-request.model.ts b/src/app/models/ui-request.model.ts index 8ee8e511..1e7f79a7 100644 --- a/src/app/models/ui-request.model.ts +++ b/src/app/models/ui-request.model.ts @@ -212,15 +212,15 @@ export class ColumnRequest extends UIRequest { export class MergeColumnsRequest extends UIRequest { sourceColumns: DbColumn[]; - joinString: string; targetColumnName: string; + joinString: string; tableType: string; - constructor( tableId: string, sourceColumns: DbColumn[], joinString: string, targetColumnName: string, tableType:string = 'table') { + constructor( tableId: string, sourceColumns: DbColumn[], targetColumnName: string, joinString: string, tableType:string = 'table') { super(); this.tableId = tableId; this.sourceColumns = sourceColumns; - this.joinString = joinString; this.targetColumnName = targetColumnName; + this.joinString = joinString; this.tableType = tableType; } } diff --git a/src/app/views/schema-editing/edit-columns/edit-columns.component.ts b/src/app/views/schema-editing/edit-columns/edit-columns.component.ts index 45a0e1cb..f7bd692f 100644 --- a/src/app/views/schema-editing/edit-columns/edit-columns.component.ts +++ b/src/app/views/schema-editing/edit-columns/edit-columns.component.ts @@ -492,7 +492,7 @@ export class EditColumnsComponent implements OnInit, OnDestroy { return; } - const req = new MergeColumnsRequest( this.tableId, this.columnsToMerge, this.joinString, this.mergedColumnName) + const req = new MergeColumnsRequest( this.tableId, this.columnsToMerge, this.mergedColumnName, this.joinString) this._crud.mergeColumns( req ).subscribe( res => { const result = res; @@ -500,8 +500,8 @@ export class EditColumnsComponent implements OnInit, OnDestroy { this.getColumns(); this.getPlacementsAndPartitions(); this.mergedColumnName = ''; - this.joinString = ''; this.columnsToMerge = []; + this.joinString = ''; } else { this._toast.exception(result, null, 'server error', ToastDuration.INFINITE); } From 095b687038ad5dafef6907296b52595267d6c1ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20S=C3=BCle?= Date: Wed, 16 Nov 2022 17:02:24 +0100 Subject: [PATCH 09/15] button for move-table added --- .../edit-tables/edit-tables.component.html | 19 +++++++ .../edit-tables/edit-tables.component.ts | 54 +++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/src/app/views/schema-editing/edit-tables/edit-tables.component.html b/src/app/views/schema-editing/edit-tables/edit-tables.component.html index 2b23b471..b9290fb1 100644 --- a/src/app/views/schema-editing/edit-tables/edit-tables.component.html +++ b/src/app/views/schema-editing/edit-tables/edit-tables.component.html @@ -11,6 +11,7 @@
Tables in {{schema}} [{{schemaType}}]
Table Truncate Drop + Move @@ -50,6 +51,24 @@
Tables in {{schema}} [{{schemaType}}]
+ +
+
+ + +
+ +
+ diff --git a/src/app/views/schema-editing/edit-tables/edit-tables.component.ts b/src/app/views/schema-editing/edit-tables/edit-tables.component.ts index 39cc57c4..6e27ee88 100644 --- a/src/app/views/schema-editing/edit-tables/edit-tables.component.ts +++ b/src/app/views/schema-editing/edit-tables/edit-tables.component.ts @@ -15,6 +15,11 @@ import {UtilService} from '../../../services/util.service'; import * as $ from 'jquery'; import {DbTable} from '../../uml/uml.model'; +class Namespace { + name: string; + id: string; +} + @Component({ selector: 'app-edit-tables', templateUrl: './edit-tables.component.html', @@ -22,6 +27,8 @@ import {DbTable} from '../../uml/uml.model'; }) export class EditTablesComponent implements OnInit, OnDestroy { + private readonly LOCAL_STORAGE_NAMESPACE_KEY = 'polypheny-namespace'; + types: PolyType[] = []; schema: string; schemaType: string; @@ -34,6 +41,10 @@ export class EditTablesComponent implements OnInit, OnDestroy { selectedStore; creatingTable = false; + activeNamespace: string; + namespaces = []; + private existingNamespaces: String[]; + //export table showExportButton = false; exportProgress = 0.0; @@ -79,6 +90,7 @@ export class EditTablesComponent implements OnInit, OnDestroy { }); this.subscriptions.add(sub2); this.documentListener(); + this.updateExistingNamespaces(); } ngOnDestroy() { @@ -105,6 +117,48 @@ export class EditTablesComponent implements OnInit, OnDestroy { }); } + getAvailableNamespaces (): Namespace[] { + if(!this.namespaces) { return []; } + return this.namespaces.filter( (n: string) => { + return n != this.activeNamespace; + }); + } + + private updateExistingNamespaces() { + this._crud.getSchema(new SchemaRequest('views/querying/console/', false, 1, false)).subscribe( + res => { + this.namespaces = []; + for (const namespace of res) { + this.namespaces.push(namespace.name); + } + + this.loadAndSetNamespaceDB(); + } + ); + } + + private loadAndSetNamespaceDB() { + let db = localStorage.getItem(this.LOCAL_STORAGE_NAMESPACE_KEY); + if (db === null || ( this.namespaces && this.namespaces.length > 0 && !this.namespaces.includes(db))) { + if( this.namespaces && this.namespaces.length > 0 ){ + db = this.namespaces[0]; + }else{ + db = 'public'; + } + } + this.setDefaultDB(db); + } + + private setDefaultDB(name: string) { + name = name.trim(); + if( !this.namespaces.includes(name) ){ + this.namespaces.push(name); + } + + this.activeNamespace = name; + localStorage.setItem(this.LOCAL_STORAGE_NAMESPACE_KEY, name); + } + getTables() { this._crud.getTables(new EditTableRequest(this.schema)).subscribe( res => { From 6897a3193c4a0061ed9f7bbf0956eb0ccaa630c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20S=C3=BCle?= Date: Tue, 29 Nov 2022 21:34:48 +0100 Subject: [PATCH 10/15] added movetable functionality to the UI --- src/app/models/ui-request.model.ts | 12 +++ src/app/services/crud.service.ts | 8 ++ .../edit-tables/edit-tables.component.html | 34 +++++---- .../edit-tables/edit-tables.component.ts | 76 ++++++++++--------- 4 files changed, 79 insertions(+), 51 deletions(-) diff --git a/src/app/models/ui-request.model.ts b/src/app/models/ui-request.model.ts index 7b022c23..155a677e 100644 --- a/src/app/models/ui-request.model.ts +++ b/src/app/models/ui-request.model.ts @@ -271,6 +271,18 @@ export class EditTableRequest { } } + export class TransferTableRequest { + table: string; + sourceSchema: string; + targetSchema: string; + + constructor(table: string, sourceNamespaceName: string, targetNamespaceName: string) { + this.table = table; + this.sourceSchema = sourceNamespaceName; + this.targetSchema = targetNamespaceName; + } +} + export class EditCollectionRequest { database: string; collection: string; diff --git a/src/app/services/crud.service.ts b/src/app/services/crud.service.ts index b9933953..e2980cc2 100644 --- a/src/app/services/crud.service.ts +++ b/src/app/services/crud.service.ts @@ -19,6 +19,7 @@ import { GraphRequest, MaterializedRequest, MonitoringRequest, + TransferTableRequest, QueryRequest, RelAlgRequest, Schema, @@ -225,6 +226,13 @@ export class CrudService { return this._http.post(`${this.httpUrl}/createTable`, tableRequest, this.httpOptions); } + /** + * Transfer a table to different namespace/schema + */ + transferTable(tableRequest: TransferTableRequest) { + return this._http.post(`${this.httpUrl}/transferTable`, tableRequest, this.httpOptions); + } + /** * Create a new collection */ diff --git a/src/app/views/schema-editing/edit-tables/edit-tables.component.html b/src/app/views/schema-editing/edit-tables/edit-tables.component.html index b9290fb1..c115c6bb 100644 --- a/src/app/views/schema-editing/edit-tables/edit-tables.component.html +++ b/src/app/views/schema-editing/edit-tables/edit-tables.component.html @@ -11,7 +11,7 @@
Tables in {{schema}} [{{schemaType}}]
Table Truncate Drop - Move + Move @@ -51,24 +51,26 @@
Tables in {{schema}} [{{schemaType}}]
- +
-
- - +
+
+ + +
+
-
- + diff --git a/src/app/views/schema-editing/edit-tables/edit-tables.component.ts b/src/app/views/schema-editing/edit-tables/edit-tables.component.ts index 6e27ee88..e45b19b8 100644 --- a/src/app/views/schema-editing/edit-tables/edit-tables.component.ts +++ b/src/app/views/schema-editing/edit-tables/edit-tables.component.ts @@ -1,6 +1,6 @@ import {Component, OnDestroy, OnInit, ViewChild} from '@angular/core'; import {CrudService} from '../../../services/crud.service'; -import {EditTableRequest, SchemaRequest} from '../../../models/ui-request.model'; +import {EditTableRequest, SchemaRequest, TransferTableRequest} from '../../../models/ui-request.model'; import {ActivatedRoute, Router} from '@angular/router'; import {DbColumn, Index, PolyType, ResultSet, Status} from '../../../components/data-view/models/result-set.model'; import {ToastDuration, ToastService} from '../../../components/toast/toast.service'; @@ -42,8 +42,8 @@ export class EditTablesComponent implements OnInit, OnDestroy { creatingTable = false; activeNamespace: string; - namespaces = []; - private existingNamespaces: String[]; + namespaces: Namespace[]; + selectedSchemas = new Map(); // name of the table, name of the selected namespace //export table showExportButton = false; @@ -90,7 +90,7 @@ export class EditTablesComponent implements OnInit, OnDestroy { }); this.subscriptions.add(sub2); this.documentListener(); - this.updateExistingNamespaces(); + this.updateExistingSchemas(); } ngOnDestroy() { @@ -117,47 +117,24 @@ export class EditTablesComponent implements OnInit, OnDestroy { }); } - getAvailableNamespaces (): Namespace[] { + getAvailableSchemas (): Namespace[] { if(!this.namespaces) { return []; } - return this.namespaces.filter( (n: string) => { - return n != this.activeNamespace; + return this.namespaces.filter( (n: Namespace) => { + return n.name != this.schema; }); } - private updateExistingNamespaces() { + private updateExistingSchemas() { this._crud.getSchema(new SchemaRequest('views/querying/console/', false, 1, false)).subscribe( res => { - this.namespaces = []; - for (const namespace of res) { - this.namespaces.push(namespace.name); - } - - this.loadAndSetNamespaceDB(); + this.namespaces = []; + for (const namespace of res) { + this.namespaces.push(namespace); + } } ); } - private loadAndSetNamespaceDB() { - let db = localStorage.getItem(this.LOCAL_STORAGE_NAMESPACE_KEY); - if (db === null || ( this.namespaces && this.namespaces.length > 0 && !this.namespaces.includes(db))) { - if( this.namespaces && this.namespaces.length > 0 ){ - db = this.namespaces[0]; - }else{ - db = 'public'; - } - } - this.setDefaultDB(db); - } - - private setDefaultDB(name: string) { - name = name.trim(); - if( !this.namespaces.includes(name) ){ - this.namespaces.push(name); - } - - this.activeNamespace = name; - localStorage.setItem(this.LOCAL_STORAGE_NAMESPACE_KEY, name); - } getTables() { this._crud.getTables(new EditTableRequest(this.schema)).subscribe( @@ -422,6 +399,35 @@ export class EditTablesComponent implements OnInit, OnDestroy { } } + transferTable(table : TableModel) { + const req = new TransferTableRequest( table.name, this.schema, this.getSelectedSchemaForTable(table)) + this._crud.transferTable( req ).subscribe( + res => { + const result = res; + if (result.error) { + this._toast.exception(result, 'Could not transfer table:'); + } else { + this._toast.success('Transfered table ' + table.name, result.generatedQuery); + this.updateExistingSchemas(); + this.selectedSchemas.delete(table.name); + this._leftSidebar.setSchema(new SchemaRequest('/views/schema-editing/', true, 2, false), this._router); + } + this.getTables(); + }, err => { + this._toast.error('Could not transfer table'); + console.log(err); + } + ); + } + + selectSchemaForTable(table : TableModel, selectedSchema : string) { + this.selectedSchemas.set(table.name, selectedSchema); + } + + getSelectedSchemaForTable(table : TableModel) { + return this.selectedSchemas.get(table.name); + } + initSocket() { const sub = this._crud.onSocketEvent().subscribe( msg => { From 1ed8173cb3b296feedd75868164e97c6faf5dd74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20S=C3=BCle?= Date: Sun, 11 Dec 2022 12:26:08 +0100 Subject: [PATCH 11/15] UI for TransferTable from document-based --- .../document-edit-collections.component.html | 21 +++++++ .../document-edit-collections.component.ts | 59 ++++++++++++++++++- 2 files changed, 79 insertions(+), 1 deletion(-) diff --git a/src/app/views/schema-editing/document-edit-collections/document-edit-collections.component.html b/src/app/views/schema-editing/document-edit-collections/document-edit-collections.component.html index c2c7c175..9a45f22b 100644 --- a/src/app/views/schema-editing/document-edit-collections/document-edit-collections.component.html +++ b/src/app/views/schema-editing/document-edit-collections/document-edit-collections.component.html @@ -11,6 +11,7 @@
Collections in {{database}} [{{schemaType}}]
Collection Truncate Drop + Move @@ -50,6 +51,26 @@
Collections in {{database}} [{{schemaType}}]
+ +
+
+
+ + +
+ +
+
+ diff --git a/src/app/views/schema-editing/document-edit-collections/document-edit-collections.component.ts b/src/app/views/schema-editing/document-edit-collections/document-edit-collections.component.ts index aa15c042..0b86fed9 100644 --- a/src/app/views/schema-editing/document-edit-collections/document-edit-collections.component.ts +++ b/src/app/views/schema-editing/document-edit-collections/document-edit-collections.component.ts @@ -1,6 +1,6 @@ import {Component, OnDestroy, OnInit, ViewChild} from '@angular/core'; import {CrudService} from '../../../services/crud.service'; -import {EditCollectionRequest, EditTableRequest, SchemaRequest} from '../../../models/ui-request.model'; +import {EditCollectionRequest, EditTableRequest, SchemaRequest, TransferTableRequest} from '../../../models/ui-request.model'; import {ActivatedRoute, Router} from '@angular/router'; import {DbColumn, Index, PolyType, ResultSet, Status} from '../../../components/data-view/models/result-set.model'; import {ToastDuration, ToastService} from '../../../components/toast/toast.service'; @@ -15,6 +15,11 @@ import {UtilService} from '../../../services/util.service'; import * as $ from 'jquery'; import {DbTable} from '../../uml/uml.model'; +class Namespace { + name: string; + id: string; +} + @Component({ selector: 'app-document-edit-collections', templateUrl: './document-edit-collections.component.html', @@ -34,6 +39,10 @@ export class DocumentEditCollectionsComponent implements OnInit, OnDestroy { selectedStore; creatingTable = false; + activeNamespace: string; + namespaces: Namespace[]; + selectedSchemas = new Map(); // name of the collection, name of the selected namespace + //export table showExportButton = false; exportProgress = 0.0; @@ -78,6 +87,7 @@ export class DocumentEditCollectionsComponent implements OnInit, OnDestroy { }); this.subscriptions.add(sub2); this.documentListener(); + this.updateExistingSchemas(); } ngOnDestroy() { @@ -380,6 +390,53 @@ export class DocumentEditCollectionsComponent implements OnInit, OnDestroy { ); } + transferTable(table : TableModel) { + const req = new TransferTableRequest( table.name, this.database, this.getSelectedSchemaForTable(table)) + this._crud.transferTable( req ).subscribe( + res => { + const result = res; + if (result.error) { + this._toast.exception(result, 'Could not transfer collection:'); + } else { + this._toast.success('Transfered collection ' + table.name, result.generatedQuery); + this.updateExistingSchemas(); + this.selectedSchemas.delete(table.name); + this._leftSidebar.setSchema(new SchemaRequest('/views/schema-editing/', true, 2, false), this._router); + } + this.getTables(); + }, err => { + this._toast.error('Could not transfer collection'); + console.log(err); + } + ); + } + + selectSchemaForTable(table : TableModel, selectedSchema : string) { + this.selectedSchemas.set(table.name, selectedSchema); + } + + getSelectedSchemaForTable(table : TableModel) { + return this.selectedSchemas.get(table.name); + } + + getAvailableSchemas (): Namespace[] { + if(!this.namespaces) { return []; } + return this.namespaces.filter( (n: Namespace) => { + return n.name != this.database; + }); + } + + private updateExistingSchemas() { + this._crud.getSchema(new SchemaRequest('views/querying/console/', false, 1, false)).subscribe( + res => { + this.namespaces = []; + for (const namespace of res) { + this.namespaces.push(namespace); + } + } + ); + } + } class TableModel { From 7e1cd667f614effdcde03965e340415e135a6719 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20S=C3=BCle?= Date: Tue, 13 Dec 2022 19:19:37 +0100 Subject: [PATCH 12/15] relational -> document working --- src/app/models/ui-request.model.ts | 4 +- .../document-edit-collections.component.html | 40 +++++++++++++++++-- .../document-edit-collections.component.ts | 34 +++++++++++++--- 3 files changed, 68 insertions(+), 10 deletions(-) diff --git a/src/app/models/ui-request.model.ts b/src/app/models/ui-request.model.ts index 155a677e..b88370da 100644 --- a/src/app/models/ui-request.model.ts +++ b/src/app/models/ui-request.model.ts @@ -275,11 +275,13 @@ export class EditTableRequest { table: string; sourceSchema: string; targetSchema: string; + primaryKeyNames: string; - constructor(table: string, sourceNamespaceName: string, targetNamespaceName: string) { + constructor(table: string, sourceNamespaceName: string, targetNamespaceName: string, primaryKeyNames: string) { this.table = table; this.sourceSchema = sourceNamespaceName; this.targetSchema = targetNamespaceName; + this.primaryKeyNames = primaryKeyNames; } } diff --git a/src/app/views/schema-editing/document-edit-collections/document-edit-collections.component.html b/src/app/views/schema-editing/document-edit-collections/document-edit-collections.component.html index 9a45f22b..073572ac 100644 --- a/src/app/views/schema-editing/document-edit-collections/document-edit-collections.component.html +++ b/src/app/views/schema-editing/document-edit-collections/document-edit-collections.component.html @@ -11,7 +11,7 @@
Collections in {{database}} [{{schemaType}}]
Collection Truncate Drop - Move + Transfer @@ -53,7 +53,7 @@
Collections in {{database}} [{{schemaType}}]
-
+
- +
@@ -210,3 +210,37 @@
+ + diff --git a/src/app/views/schema-editing/document-edit-collections/document-edit-collections.component.ts b/src/app/views/schema-editing/document-edit-collections/document-edit-collections.component.ts index 0b86fed9..9c0607de 100644 --- a/src/app/views/schema-editing/document-edit-collections/document-edit-collections.component.ts +++ b/src/app/views/schema-editing/document-edit-collections/document-edit-collections.component.ts @@ -26,7 +26,7 @@ class Namespace { styleUrls: ['./document-edit-collections.component.scss'] }) export class DocumentEditCollectionsComponent implements OnInit, OnDestroy { - + types: PolyType[] = []; database: string; schemaType: string; @@ -42,6 +42,7 @@ export class DocumentEditCollectionsComponent implements OnInit, OnDestroy { activeNamespace: string; namespaces: Namespace[]; selectedSchemas = new Map(); // name of the collection, name of the selected namespace + tableToTransfer : TableModel; //export table showExportButton = false; @@ -56,6 +57,11 @@ export class DocumentEditCollectionsComponent implements OnInit, OnDestroy { addDefaultValue: new FormControl(true, Validators.required) }); @ViewChild('exportTableModal', {static: false}) public exportTableModal: ModalDirective; + transferTableForm = new FormGroup({ + name: new FormControl('', Validators.required), + }); + @ViewChild('transferTableModal', {static: false}) public transferTableModal: ModalDirective; + constructor( public _crud: CrudService, @@ -390,17 +396,18 @@ export class DocumentEditCollectionsComponent implements OnInit, OnDestroy { ); } - transferTable(table : TableModel) { - const req = new TransferTableRequest( table.name, this.database, this.getSelectedSchemaForTable(table)) + transferTable() { + let primaryKeyNames = this.transferTableForm.controls['name'].value; + const req = new TransferTableRequest( this.tableToTransfer.name, this.database, this.getSelectedSchemaForTable(this.tableToTransfer), primaryKeyNames); this._crud.transferTable( req ).subscribe( res => { const result = res; if (result.error) { this._toast.exception(result, 'Could not transfer collection:'); } else { - this._toast.success('Transfered collection ' + table.name, result.generatedQuery); + this._toast.success('Transfered collection ' + this.tableToTransfer.name, result.generatedQuery); this.updateExistingSchemas(); - this.selectedSchemas.delete(table.name); + this.selectedSchemas.delete(this.tableToTransfer.name); this._leftSidebar.setSchema(new SchemaRequest('/views/schema-editing/', true, 2, false), this._router); } this.getTables(); @@ -408,7 +415,9 @@ export class DocumentEditCollectionsComponent implements OnInit, OnDestroy { this._toast.error('Could not transfer collection'); console.log(err); } - ); + ).add(() => { + this.transferTableModal.hide(); + }); } selectSchemaForTable(table : TableModel, selectedSchema : string) { @@ -437,6 +446,19 @@ export class DocumentEditCollectionsComponent implements OnInit, OnDestroy { ); } + initTransferTableModal(table : TableModel ){ + let selectedSchema = this.getSelectedSchemaForTable(table) + if (selectedSchema == undefined) { + return; + } + this.tableToTransfer = table; + this.transferTableModal.show(); + } + + clearTransferTableModal(){ + this.selectedStore = null; + } + } class TableModel { From 3e8139a57bd4562b2c5e886a907be89645bd224b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20S=C3=BCle?= Date: Wed, 14 Dec 2022 18:07:32 +0100 Subject: [PATCH 13/15] little refactors --- src/app/components/data-view/models/result-set.model.ts | 1 - src/app/models/ui-request.model.ts | 7 ++++++- src/app/services/crud.service.ts | 6 ++++-- .../schema-editing/edit-columns/edit-columns.component.ts | 5 +++-- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/app/components/data-view/models/result-set.model.ts b/src/app/components/data-view/models/result-set.model.ts index bcdd8cf6..1eb31ca4 100644 --- a/src/app/components/data-view/models/result-set.model.ts +++ b/src/app/components/data-view/models/result-set.model.ts @@ -166,7 +166,6 @@ export class DbColumn { defaultValue: any; dimension: number; cardinality: number; - mergeable: boolean; //for data sources as: string; diff --git a/src/app/models/ui-request.model.ts b/src/app/models/ui-request.model.ts index a67997de..4f4d4bc2 100644 --- a/src/app/models/ui-request.model.ts +++ b/src/app/models/ui-request.model.ts @@ -230,12 +230,17 @@ export class ColumnRequest extends UIRequest { } } + +/** + * Merge columns within a relational namespace. + * Used for request where you want to merge multiple columns of a table. + */ export class MergeColumnsRequest extends UIRequest { sourceColumns: DbColumn[]; targetColumnName: string; joinString: string; tableType: string; - constructor( tableId: string, sourceColumns: DbColumn[], targetColumnName: string, joinString: string, tableType:string = 'table') { + constructor( tableId: string, sourceColumns: DbColumn[], targetColumnName: string, joinString: string, tableType:string = 'table' ) { super(); this.tableId = tableId; this.sourceColumns = sourceColumns; diff --git a/src/app/services/crud.service.ts b/src/app/services/crud.service.ts index ade40aee..da65bffa 100644 --- a/src/app/services/crud.service.ts +++ b/src/app/services/crud.service.ts @@ -5,8 +5,7 @@ import { Index, ModifyPartitionRequest, PartitionFunctionModel, - PartitioningRequest, - ResultSet + PartitioningRequest } from '../components/data-view/models/result-set.model'; import {webSocket} from 'rxjs/webSocket'; import { @@ -205,6 +204,9 @@ export class CrudService { return this._http.post(`${this.httpUrl}/dropColumn`, columnRequest, this.httpOptions); } + /** + * Merge columns of a table in a relational namespace + */ mergeColumns ( columnRequest: MergeColumnsRequest ) { return this._http.post(`${this.httpUrl}/mergeColumns`, columnRequest, this.httpOptions); } diff --git a/src/app/views/schema-editing/edit-columns/edit-columns.component.ts b/src/app/views/schema-editing/edit-columns/edit-columns.component.ts index f7bd692f..5f4377f7 100644 --- a/src/app/views/schema-editing/edit-columns/edit-columns.component.ts +++ b/src/app/views/schema-editing/edit-columns/edit-columns.component.ts @@ -39,8 +39,9 @@ export class EditColumnsComponent implements OnInit, OnDestroy { confirmConstraint = -1; newPrimaryKey: DbColumn[]; - mergedColumnName = '' - joinString = '' + //merge columns handling + mergedColumnName = ''; + joinString = ''; mergeableColumns: DbColumn[]; columnsToMerge: DbColumn[] = []; From 0b79634c310646e70df6a67817967fe659ae7791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20S=C3=BCle?= Date: Wed, 14 Dec 2022 19:10:22 +0100 Subject: [PATCH 14/15] little refactor and comments --- src/app/models/ui-request.model.ts | 6 +++++- src/app/services/crud.service.ts | 4 ++-- .../document-edit-collections.component.html | 2 +- .../document-edit-collections.component.ts | 3 +++ .../schema-editing/edit-tables/edit-tables.component.html | 4 ++-- .../schema-editing/edit-tables/edit-tables.component.ts | 2 +- 6 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/app/models/ui-request.model.ts b/src/app/models/ui-request.model.ts index b88370da..f3c10560 100644 --- a/src/app/models/ui-request.model.ts +++ b/src/app/models/ui-request.model.ts @@ -271,13 +271,17 @@ export class EditTableRequest { } } +/** + * Transfer a table from one namespace to another. + * Used for request where you want to transfer a table + */ export class TransferTableRequest { table: string; sourceSchema: string; targetSchema: string; primaryKeyNames: string; - constructor(table: string, sourceNamespaceName: string, targetNamespaceName: string, primaryKeyNames: string) { + constructor( table: string, sourceNamespaceName: string, targetNamespaceName: string, primaryKeyNames: string ) { this.table = table; this.sourceSchema = sourceNamespaceName; this.targetSchema = targetNamespaceName; diff --git a/src/app/services/crud.service.ts b/src/app/services/crud.service.ts index e2980cc2..f4a12b8c 100644 --- a/src/app/services/crud.service.ts +++ b/src/app/services/crud.service.ts @@ -227,9 +227,9 @@ export class CrudService { } /** - * Transfer a table to different namespace/schema + * Transfer a table to another schema */ - transferTable(tableRequest: TransferTableRequest) { + transferTable( tableRequest: TransferTableRequest ) { return this._http.post(`${this.httpUrl}/transferTable`, tableRequest, this.httpOptions); } diff --git a/src/app/views/schema-editing/document-edit-collections/document-edit-collections.component.html b/src/app/views/schema-editing/document-edit-collections/document-edit-collections.component.html index 073572ac..903948f3 100644 --- a/src/app/views/schema-editing/document-edit-collections/document-edit-collections.component.html +++ b/src/app/views/schema-editing/document-edit-collections/document-edit-collections.component.html @@ -235,7 +235,7 @@ diff --git a/src/app/views/schema-editing/document-edit-collections/document-edit-collections.component.ts b/src/app/views/schema-editing/document-edit-collections/document-edit-collections.component.ts index 9c0607de..499f5827 100644 --- a/src/app/views/schema-editing/document-edit-collections/document-edit-collections.component.ts +++ b/src/app/views/schema-editing/document-edit-collections/document-edit-collections.component.ts @@ -396,6 +396,9 @@ export class DocumentEditCollectionsComponent implements OnInit, OnDestroy { ); } + /** + * Transfer table (a collection) from one namepsace to another + */ transferTable() { let primaryKeyNames = this.transferTableForm.controls['name'].value; const req = new TransferTableRequest( this.tableToTransfer.name, this.database, this.getSelectedSchemaForTable(this.tableToTransfer), primaryKeyNames); diff --git a/src/app/views/schema-editing/edit-tables/edit-tables.component.html b/src/app/views/schema-editing/edit-tables/edit-tables.component.html index c115c6bb..fc24e8b6 100644 --- a/src/app/views/schema-editing/edit-tables/edit-tables.component.html +++ b/src/app/views/schema-editing/edit-tables/edit-tables.component.html @@ -11,7 +11,7 @@
Tables in {{schema}} [{{schemaType}}]
Table Truncate Drop - Move + Transfer @@ -67,7 +67,7 @@
Tables in {{schema}} [{{schemaType}}]
  • no other namespaces available
  • - + diff --git a/src/app/views/schema-editing/edit-tables/edit-tables.component.ts b/src/app/views/schema-editing/edit-tables/edit-tables.component.ts index e45b19b8..ecfc43db 100644 --- a/src/app/views/schema-editing/edit-tables/edit-tables.component.ts +++ b/src/app/views/schema-editing/edit-tables/edit-tables.component.ts @@ -400,7 +400,7 @@ export class EditTablesComponent implements OnInit, OnDestroy { } transferTable(table : TableModel) { - const req = new TransferTableRequest( table.name, this.schema, this.getSelectedSchemaForTable(table)) + const req = new TransferTableRequest( table.name, this.schema, this.getSelectedSchemaForTable(table), null) this._crud.transferTable( req ).subscribe( res => { const result = res; From 79cfe00e9d6d1eabbb5aec7949d7e8b203154c7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20S=C3=BCle?= Date: Wed, 14 Dec 2022 19:15:20 +0100 Subject: [PATCH 15/15] more refactors --- src/app/components/components.module.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/app/components/components.module.ts b/src/app/components/components.module.ts index c5bd2264..1c9b8ae1 100644 --- a/src/app/components/components.module.ts +++ b/src/app/components/components.module.ts @@ -37,10 +37,9 @@ import {JsonTextComponent} from './data-view/json-text/json-text.component'; import {NgxJsonViewerModule} from 'ngx-json-viewer'; import {JsonEditorComponent} from './json/json-editor.component'; import {JsonElemComponent} from './json/json-elem/json-elem.component'; -import { ListPickerComponent } from './list-picker/list-picker.component'; -import { DragDropModule } from '@angular/cdk/drag-drop'; +import {ListPickerComponent} from './list-picker/list-picker.component'; +import {DragDropModule} from '@angular/cdk/drag-drop'; import {DataGraphComponent} from './data-view/data-graph/data-graph.component'; -import {MultipleSwitchPipe} from './data-view/multiple-switch.pipe'; import {DatesPipeModule} from './data-view/shared-module'; //import 'hammerjs';