diff --git a/.docs/images/architecture.drawio b/.docs/images/architecture.drawio index ac29a38ba62412830054497f89fa0826c450f216..c2332494da9169fe06cbbae677863eb275c6b31d 100644 --- a/.docs/images/architecture.drawio +++ b/.docs/images/architecture.drawio @@ -1,4 +1,4 @@ -<mxfile host="Electron" modified="2024-01-17T12:11:17.954Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/22.1.18 Chrome/120.0.6099.199 Electron/28.1.2 Safari/537.36" etag="j6PPhzgFbNeUxK9L3AUE" version="22.1.18" type="device" pages="7"> +<mxfile host="Electron" modified="2024-01-17T12:41:27.263Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/22.1.18 Chrome/120.0.6099.199 Electron/28.1.2 Safari/537.36" etag="2tlEwPCE5mA3LfufPqf1" version="22.1.18" type="device" pages="7"> <diagram id="mvBsv1rP8O80Qe3yGnn_" name="docker-compose"> <mxGraphModel dx="2074" dy="1182" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0"> <root> @@ -238,19 +238,19 @@ </mxGeometry> </mxCell> <mxCell id="ZFea1dL5_0zV0EoV6Noq-4" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#E6E6E6;" vertex="1" parent="1"> - <mxGeometry x="630" y="760" width="30" height="16" as="geometry" /> + <mxGeometry x="730" y="660" width="30" height="16" as="geometry" /> </mxCell> <mxCell id="ZFea1dL5_0zV0EoV6Noq-5" value="External images" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1"> - <mxGeometry x="667.5" y="760" width="140" height="16" as="geometry" /> + <mxGeometry x="767.5" y="660" width="140" height="16" as="geometry" /> </mxCell> <mxCell id="ZFea1dL5_0zV0EoV6Noq-6" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1"> - <mxGeometry x="630" y="780" width="30" height="16" as="geometry" /> + <mxGeometry x="730" y="680" width="30" height="16" as="geometry" /> </mxCell> <mxCell id="ZFea1dL5_0zV0EoV6Noq-7" value="Maintained images" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1"> - <mxGeometry x="667.5" y="780" width="140" height="16" as="geometry" /> + <mxGeometry x="767.5" y="680" width="140" height="16" as="geometry" /> </mxCell> <mxCell id="ZFea1dL5_0zV0EoV6Noq-8" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#000000;" vertex="1" parent="1"> - <mxGeometry x="645" y="760" width="15" height="16" as="geometry" /> + <mxGeometry x="745" y="660" width="15" height="16" as="geometry" /> </mxCell> </root> </mxGraphModel> diff --git a/dbrepo-metadata-db/setup-schema.sql b/dbrepo-metadata-db/setup-schema.sql index 3165796d3dd1a263ef031f98b64300889c385f21..2981117119cc6fbba19a9ca80752695925ff1f63 100644 --- a/dbrepo-metadata-db/setup-schema.sql +++ b/dbrepo-metadata-db/setup-schema.sql @@ -178,7 +178,7 @@ CREATE TABLE IF NOT EXISTS `mdb_columns_enums` id bigint NOT NULL AUTO_INCREMENT, column_id bigint NOT NULL, value CHARACTER VARYING(255) NOT NULL, - FOREIGN KEY (column_id) REFERENCES mdb_columns (ID), + FOREIGN KEY (column_id) REFERENCES mdb_columns (ID) ON DELETE CASCADE, PRIMARY KEY (id) ) WITH SYSTEM VERSIONING; @@ -187,7 +187,7 @@ CREATE TABLE IF NOT EXISTS `mdb_columns_sets` id bigint NOT NULL AUTO_INCREMENT, column_id bigint NOT NULL, value CHARACTER VARYING(255) NOT NULL, - FOREIGN KEY (column_id) REFERENCES mdb_columns (ID), + FOREIGN KEY (column_id) REFERENCES mdb_columns (ID) ON DELETE CASCADE, PRIMARY KEY (id) ) WITH SYSTEM VERSIONING; diff --git a/dbrepo-metadata-db/setup-schema_local.sql b/dbrepo-metadata-db/setup-schema_local.sql index 4b35338875b707d7a951461bd54314017e573d16..426acf93fa6eaa2f0d5b0ceea942a060adebca65 100644 --- a/dbrepo-metadata-db/setup-schema_local.sql +++ b/dbrepo-metadata-db/setup-schema_local.sql @@ -1,7 +1,8 @@ BEGIN; -INSERT INTO `mdb_containers` (name, internal_name, image_id, host, port, sidecar_host, sidecar_port, +INSERT INTO `mdb_containers` (name, internal_name, image_id, host, port, ui_host, ui_port, sidecar_host, sidecar_port, privileged_username, privileged_password) -VALUES ('MariaDB Galera 11.1.3', 'mariadb_11_1_3', 1, 'data-db', 3306, 'data-db-sidecar', 3305, 'root', 'dbrepo'); +VALUES ('MariaDB Galera 11.1.3', 'mariadb_11_1_3', 1, 'data-db', 3306, 'localhost', 3306, 'data-db-sidecar', 3305, + 'root', 'dbrepo'); COMMIT; diff --git a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumn.java b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumn.java index 0ba70fbd4a5331be6bab983701bec75b94b854a4..9cd43c09771e608b11490ab2e3ffa07640705a1f 100644 --- a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumn.java +++ b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumn.java @@ -6,6 +6,8 @@ import at.tuwien.entities.database.table.Table; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.*; import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.OnDelete; +import org.hibernate.annotations.OnDeleteAction; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; @@ -104,14 +106,18 @@ public class TableColumn implements Comparable<TableColumn> { inverseJoinColumns = @JoinColumn(name = "id", referencedColumnName = "id")) private TableColumnUnit unit; - @ElementCollection(targetClass = String.class, fetch = FetchType.EAGER) + @ElementCollection(fetch = FetchType.LAZY, targetClass = String.class) @CollectionTable(name = "mdb_columns_enums", joinColumns = @JoinColumn(name = "column_id")) @Column(name = "value", nullable = false) + @JoinColumn(name = "column_id") + @OnDelete(action = OnDeleteAction.CASCADE) private List<String> enums; - @ElementCollection(targetClass = String.class, fetch = FetchType.EAGER) + @ElementCollection(fetch = FetchType.LAZY, targetClass = String.class) @CollectionTable(name = "mdb_columns_sets", joinColumns = @JoinColumn(name = "column_id")) @Column(name = "value", nullable = false) + @JoinColumn(name = "column_id") + @OnDelete(action = OnDeleteAction.CASCADE) private List<String> sets; @Column diff --git a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/TableMapper.java b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/TableMapper.java index 80510416cee75bff784a1199d688b0452386f862..999704345ef34d9ad2482a57df73289ebb394f81 100644 --- a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/TableMapper.java +++ b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/TableMapper.java @@ -321,14 +321,14 @@ public interface TableMapper { final StringBuilder sequence = new StringBuilder(); if (data.getColumns().stream().anyMatch(TableColumn::getAutoGenerated)) { log.debug("table with id {} has sequence generated which needs to be dropped too", data.getId()); - sequence.append("DROP SEQUENCE `") + sequence.append("DROP SEQUENCE IF EXISTS `") .append(tableToSequenceName(data)) .append("`;"); } - final StringBuilder table = new StringBuilder("DROP TABLE `") + final StringBuilder table = new StringBuilder("DROP TABLE IF EXISTS `") .append(data.getInternalName()) .append("`;"); - final StringBuilder view = new StringBuilder("DROP VIEW `hs_") + final StringBuilder view = new StringBuilder("DROP VIEW IF EXISTS `hs_") .append(data.getInternalName()) .append("`;"); try { @@ -342,7 +342,7 @@ public interface TableMapper { log.trace("mapped drop view statement {}", table); } catch (SQLException e) { log.error("Failed to drop table or sequence: {}", e.getMessage()); - throw new QueryMalformedException("Failed to drop table or sequence", e); + throw new QueryMalformedException("Failed to drop table or sequence: " + e.getMessage(), e); } } diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationWriteTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationWriteTest.java index fd19d92df0b74fc5ed329bc4954311243a48576a..8ef2a0ce4ad5bf39739c24123b651de325383f3a 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationWriteTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationWriteTest.java @@ -139,218 +139,15 @@ public class TableServiceIntegrationWriteTest extends BaseUnitTest { @Test public void create_full_succeeds() throws Exception { - final TableCreateDto request = TableCreateDto.builder() - .name("full") - .description("full example") - .constraints(ConstraintsCreateDto.builder() - .uniques(List.of()) - .foreignKeys(List.of()) - .build()) - .columns(List.of(ColumnCreateDto.builder() - .name("col1a") - .type(ColumnTypeDto.CHAR) - .nullAllowed(true) - .primaryKey(false) - .build(), - ColumnCreateDto.builder() - .name("col1b") - .type(ColumnTypeDto.CHAR) - .nullAllowed(true) - .primaryKey(false) - .size(50L) - .build(), - ColumnCreateDto.builder() - .name("col2a") - .type(ColumnTypeDto.VARCHAR) - .nullAllowed(true) - .primaryKey(false) - .build(), - ColumnCreateDto.builder() - .name("col2b") - .type(ColumnTypeDto.VARCHAR) - .nullAllowed(true) - .primaryKey(false) - .size(1024L) - .build(), - ColumnCreateDto.builder() - .name("col3") - .type(ColumnTypeDto.BINARY) - .nullAllowed(true) - .primaryKey(false) - .build(), - ColumnCreateDto.builder() - .name("col4") - .type(ColumnTypeDto.VARBINARY) - .nullAllowed(true) - .primaryKey(false) - .size(200L) - .build(), - ColumnCreateDto.builder() - .name("col5") - .type(ColumnTypeDto.TINYBLOB) - .nullAllowed(true) - .primaryKey(false) - .build(), - ColumnCreateDto.builder() - .name("col6") - .type(ColumnTypeDto.TINYTEXT) - .nullAllowed(true) - .primaryKey(false) - .build(), - ColumnCreateDto.builder() - .name("col7") - .type(ColumnTypeDto.TEXT) - .nullAllowed(true) - .primaryKey(false) - .build(), - ColumnCreateDto.builder() - .name("col8") - .type(ColumnTypeDto.BLOB) - .nullAllowed(true) - .primaryKey(false) - .build(), - ColumnCreateDto.builder() - .name("col9") - .type(ColumnTypeDto.MEDIUMTEXT) - .nullAllowed(true) - .primaryKey(false) - .build(), - ColumnCreateDto.builder() - .name("col10") - .type(ColumnTypeDto.MEDIUMBLOB) - .nullAllowed(true) - .primaryKey(false) - .build(), - ColumnCreateDto.builder() - .name("col11") - .type(ColumnTypeDto.LONGTEXT) - .nullAllowed(true) - .primaryKey(false) - .build(), - ColumnCreateDto.builder() - .name("col12") - .type(ColumnTypeDto.LONGBLOB) - .nullAllowed(true) - .primaryKey(false) - .build(), - ColumnCreateDto.builder() - .name("col13") - .type(ColumnTypeDto.ENUM) - .nullAllowed(true) - .primaryKey(false) - .enums(List.of("val1", "val2")) - .build(), - ColumnCreateDto.builder() - .name("col14") - .type(ColumnTypeDto.SET) - .nullAllowed(true) - .primaryKey(false) - .sets(List.of("val1", "val2")) - .build(), - ColumnCreateDto.builder() - .name("col15") - .type(ColumnTypeDto.BIT) - .nullAllowed(true) - .primaryKey(false) - .build(), - ColumnCreateDto.builder() - .name("col16") - .type(ColumnTypeDto.TINYINT) - .nullAllowed(true) - .primaryKey(false) - .build(), - ColumnCreateDto.builder() - .name("col17") - .type(ColumnTypeDto.BOOL) - .nullAllowed(true) - .primaryKey(false) - .build(), - ColumnCreateDto.builder() - .name("col18") - .type(ColumnTypeDto.SMALLINT) - .nullAllowed(true) - .primaryKey(false) - .build(), - ColumnCreateDto.builder() - .name("col19") - .type(ColumnTypeDto.MEDIUMINT) - .nullAllowed(true) - .primaryKey(false) - .build(), - ColumnCreateDto.builder() - .name("col20") - .type(ColumnTypeDto.INT) - .nullAllowed(true) - .primaryKey(false) - .build(), - ColumnCreateDto.builder() - .name("col21") - .type(ColumnTypeDto.BIGINT) - .nullAllowed(true) - .primaryKey(false) - .build(), - ColumnCreateDto.builder() - .name("col22") - .type(ColumnTypeDto.FLOAT) - .nullAllowed(true) - .primaryKey(false) - .build(), - ColumnCreateDto.builder() - .name("col23") - .type(ColumnTypeDto.DOUBLE) - .nullAllowed(true) - .primaryKey(false) - .build(), - ColumnCreateDto.builder() - .name("col24") - .type(ColumnTypeDto.DECIMAL) - .nullAllowed(true) - .primaryKey(false) - .build(), - ColumnCreateDto.builder() - .name("col25") - .type(ColumnTypeDto.DATE) - .nullAllowed(true) - .primaryKey(false) - .dfid(IMAGE_DATE_1_ID) - .build(), - ColumnCreateDto.builder() - .name("col26") - .type(ColumnTypeDto.DATETIME) - .nullAllowed(true) - .primaryKey(false) - .dfid(IMAGE_DATE_3_ID) - .build(), - ColumnCreateDto.builder() - .name("col27") - .type(ColumnTypeDto.TIMESTAMP) - .nullAllowed(true) - .primaryKey(false) - .dfid(IMAGE_DATE_3_ID) - .build(), - ColumnCreateDto.builder() - .name("col28") - .type(ColumnTypeDto.TIME) - .nullAllowed(true) - .primaryKey(false) - .dfid(IMAGE_DATE_4_ID) - .build(), - ColumnCreateDto.builder() - .name("col29") - .type(ColumnTypeDto.YEAR) - .nullAllowed(true) - .primaryKey(false) - .build())) - .build(); /* test */ - final Table response = tableService.createTable(DATABASE_1_ID, request, USER_1_PRINCIPAL); + final Table response = tableService.createTable(DATABASE_1_ID, TABLE_0_CREATE_DTO, USER_1_PRINCIPAL); assertNotNull(response.getId()); assertEquals("full", response.getInternalName()); assertEquals("full example", response.getDescription()); assertEquals(32, response.getColumns().size()); - for (int i = 1; i < request.getColumns().size(); i++) { - final ColumnCreateDto expected = request.getColumns().get(i); + for (int i = 1; i < TABLE_0_CREATE_DTO.getColumns().size(); i++) { + final ColumnCreateDto expected = TABLE_0_CREATE_DTO.getColumns().get(i); final TableColumn result = response.getColumns().get(i); assertEquals(expected.getName(), result.getName()); assertEquals(expected.getType(), tableMapper.columnTypeToColumnTypeDto(result.getColumnType())); @@ -373,7 +170,7 @@ public class TableServiceIntegrationWriteTest extends BaseUnitTest { } final Map<String, List<Object>> schema = MariaDbConfig.describeTableSchema(response, CONTAINER_1_PRIVILEGED_USERNAME, CONTAINER_1_PRIVILEGED_PASSWORD); for (Map.Entry<String, List<Object>> entry : schema.entrySet()) { - final ColumnCreateDto columnRequest = request.getColumns().stream().filter(c -> c.getName().equals(entry.getKey())).findFirst().get(); + final ColumnCreateDto columnRequest = TABLE_0_CREATE_DTO.getColumns().stream().filter(c -> c.getName().equals(entry.getKey())).findFirst().get(); final TableColumn columnEntity = response.getColumns().stream().filter(c -> c.getName().equals(entry.getKey())).findFirst().get(); final List<Object> columnSchema = schema.get(columnEntity.getInternalName()); if (columnEntity.getInternalName().equals("id")) { @@ -428,6 +225,17 @@ public class TableServiceIntegrationWriteTest extends BaseUnitTest { tableService.deleteTable(DATABASE_1_ID, TABLE_1_ID); } + @Test + @Transactional + public void delete_full_succeeds() throws TableNotFoundException, TableMalformedException, QueryMalformedException, + DatabaseNotFoundException, ImageNotSupportedException, UserNotFoundException, TableNameExistsException, + ContainerNotFoundException { + + /* test */ + final Table response = tableService.createTable(DATABASE_1_ID, TABLE_0_CREATE_DTO, USER_1_PRINCIPAL); + tableService.deleteTable(DATABASE_1_ID, response.getId()); + } + @Test @Transactional public void delete_hasIdentifier_succeeds() throws TableNotFoundException, TableMalformedException, diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/TableServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/TableServiceImpl.java index 8ca16099652fd0ec07921e6131391ec03b527b8d..5e5e25b874fd45813c1723a8ea74558ca8728b2b 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/TableServiceImpl.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/TableServiceImpl.java @@ -266,7 +266,7 @@ public class TableServiceImpl extends HibernateConnector implements TableService tableMapper.tableToDropTableRawQuery(connection, table); } catch (SQLException e) { log.error("Failed to drop table: {}", e.getMessage()); - throw new TableMalformedException("Failed to drop table", e); + throw new TableMalformedException("Failed to drop table: " + e.getMessage(), e); } finally { dataSource.close(); } diff --git a/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java index 51daf587fae7c530227d5f6f5da79b7ab7be3f0e..f4d85aa196fc07d53198a0d3f169e0895d7f9c70 100644 --- a/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java +++ b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java @@ -1120,6 +1120,210 @@ public abstract class BaseTest { .owner(USER_4_BRIEF_DTO) .build(); + public final static TableCreateDto TABLE_0_CREATE_DTO = TableCreateDto.builder() + .name("full") + .description("full example") + .constraints(ConstraintsCreateDto.builder() + .uniques(List.of()) + .foreignKeys(List.of()) + .build()) + .columns(List.of(ColumnCreateDto.builder() + .name("col1a") + .type(ColumnTypeDto.CHAR) + .nullAllowed(true) + .primaryKey(false) + .build(), + ColumnCreateDto.builder() + .name("col1b") + .type(ColumnTypeDto.CHAR) + .nullAllowed(true) + .primaryKey(false) + .size(50L) + .build(), + ColumnCreateDto.builder() + .name("col2a") + .type(ColumnTypeDto.VARCHAR) + .nullAllowed(true) + .primaryKey(false) + .build(), + ColumnCreateDto.builder() + .name("col2b") + .type(ColumnTypeDto.VARCHAR) + .nullAllowed(true) + .primaryKey(false) + .size(1024L) + .build(), + ColumnCreateDto.builder() + .name("col3") + .type(ColumnTypeDto.BINARY) + .nullAllowed(true) + .primaryKey(false) + .build(), + ColumnCreateDto.builder() + .name("col4") + .type(ColumnTypeDto.VARBINARY) + .nullAllowed(true) + .primaryKey(false) + .size(200L) + .build(), + ColumnCreateDto.builder() + .name("col5") + .type(ColumnTypeDto.TINYBLOB) + .nullAllowed(true) + .primaryKey(false) + .build(), + ColumnCreateDto.builder() + .name("col6") + .type(ColumnTypeDto.TINYTEXT) + .nullAllowed(true) + .primaryKey(false) + .build(), + ColumnCreateDto.builder() + .name("col7") + .type(ColumnTypeDto.TEXT) + .nullAllowed(true) + .primaryKey(false) + .build(), + ColumnCreateDto.builder() + .name("col8") + .type(ColumnTypeDto.BLOB) + .nullAllowed(true) + .primaryKey(false) + .build(), + ColumnCreateDto.builder() + .name("col9") + .type(ColumnTypeDto.MEDIUMTEXT) + .nullAllowed(true) + .primaryKey(false) + .build(), + ColumnCreateDto.builder() + .name("col10") + .type(ColumnTypeDto.MEDIUMBLOB) + .nullAllowed(true) + .primaryKey(false) + .build(), + ColumnCreateDto.builder() + .name("col11") + .type(ColumnTypeDto.LONGTEXT) + .nullAllowed(true) + .primaryKey(false) + .build(), + ColumnCreateDto.builder() + .name("col12") + .type(ColumnTypeDto.LONGBLOB) + .nullAllowed(true) + .primaryKey(false) + .build(), + ColumnCreateDto.builder() + .name("col13") + .type(ColumnTypeDto.ENUM) + .nullAllowed(true) + .primaryKey(false) + .enums(List.of("val1", "val2")) + .build(), + ColumnCreateDto.builder() + .name("col14") + .type(ColumnTypeDto.SET) + .nullAllowed(true) + .primaryKey(false) + .sets(List.of("val1", "val2")) + .build(), + ColumnCreateDto.builder() + .name("col15") + .type(ColumnTypeDto.BIT) + .nullAllowed(true) + .primaryKey(false) + .build(), + ColumnCreateDto.builder() + .name("col16") + .type(ColumnTypeDto.TINYINT) + .nullAllowed(true) + .primaryKey(false) + .build(), + ColumnCreateDto.builder() + .name("col17") + .type(ColumnTypeDto.BOOL) + .nullAllowed(true) + .primaryKey(false) + .build(), + ColumnCreateDto.builder() + .name("col18") + .type(ColumnTypeDto.SMALLINT) + .nullAllowed(true) + .primaryKey(false) + .build(), + ColumnCreateDto.builder() + .name("col19") + .type(ColumnTypeDto.MEDIUMINT) + .nullAllowed(true) + .primaryKey(false) + .build(), + ColumnCreateDto.builder() + .name("col20") + .type(ColumnTypeDto.INT) + .nullAllowed(true) + .primaryKey(false) + .build(), + ColumnCreateDto.builder() + .name("col21") + .type(ColumnTypeDto.BIGINT) + .nullAllowed(true) + .primaryKey(false) + .build(), + ColumnCreateDto.builder() + .name("col22") + .type(ColumnTypeDto.FLOAT) + .nullAllowed(true) + .primaryKey(false) + .build(), + ColumnCreateDto.builder() + .name("col23") + .type(ColumnTypeDto.DOUBLE) + .nullAllowed(true) + .primaryKey(false) + .build(), + ColumnCreateDto.builder() + .name("col24") + .type(ColumnTypeDto.DECIMAL) + .nullAllowed(true) + .primaryKey(false) + .build(), + ColumnCreateDto.builder() + .name("col25") + .type(ColumnTypeDto.DATE) + .nullAllowed(true) + .primaryKey(false) + .dfid(IMAGE_DATE_1_ID) + .build(), + ColumnCreateDto.builder() + .name("col26") + .type(ColumnTypeDto.DATETIME) + .nullAllowed(true) + .primaryKey(false) + .dfid(IMAGE_DATE_3_ID) + .build(), + ColumnCreateDto.builder() + .name("col27") + .type(ColumnTypeDto.TIMESTAMP) + .nullAllowed(true) + .primaryKey(false) + .dfid(IMAGE_DATE_3_ID) + .build(), + ColumnCreateDto.builder() + .name("col28") + .type(ColumnTypeDto.TIME) + .nullAllowed(true) + .primaryKey(false) + .dfid(IMAGE_DATE_4_ID) + .build(), + ColumnCreateDto.builder() + .name("col29") + .type(ColumnTypeDto.YEAR) + .nullAllowed(true) + .primaryKey(false) + .build())) + .build(); + public final static Long TABLE_1_ID = 1L; public final static String TABLE_1_NAME = "Weather AUS"; public final static String TABLE_1_INTERNALNAME = "weather_aus"; diff --git a/dbrepo-ui/components/database/DatabaseToolbar.vue b/dbrepo-ui/components/database/DatabaseToolbar.vue index f43f35f4c115468d37bb155b53deeb2381a6b5a9..1bffed98377a455b4d79dad58316fab9eee0b463 100644 --- a/dbrepo-ui/components/database/DatabaseToolbar.vue +++ b/dbrepo-ui/components/database/DatabaseToolbar.vue @@ -29,25 +29,19 @@ <v-spacer /> <v-toolbar-title> <v-btn v-if="canImportCsv" class="mb-1" :to="`/database/${$route.params.database_id}/table/import`"> - <v-icon left>mdi-cloud-upload</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Import</span> csv + <v-icon left>mdi-cloud-upload</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Import </span> csv </v-btn> - <DownloadButton - v-if="database && database.identifier" - :pid="database.identifier.id" - class="mr-2 mb-1"> - <v-icon left>mdi-code-tags</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Identifier</span> xml - </DownloadButton> <v-btn v-if="canCreateSubset" color="secondary" class="mb-1 white--text" :to="`/database/${$route.params.database_id}/query/create`"> - <v-icon v-if="$vuetify.breakpoint.lgAndUp" left>mdi-wrench</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Create</span> Subset + <v-icon v-if="$vuetify.breakpoint.lgAndUp" left>mdi-wrench</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Create </span> Subset </v-btn> <v-btn v-if="canCreateView" color="secondary" class="mb-1 white--text" :to="`/database/${$route.params.database_id}/view/create`"> - <v-icon v-if="$vuetify.breakpoint.lgAndUp" left>mdi-view-carousel-outline</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Create</span> View + <v-icon v-if="$vuetify.breakpoint.lgAndUp" left>mdi-view-carousel-outline</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Create </span> View </v-btn> <v-btn v-if="canCreateTable" color="secondary" class="mb-1" :to="`/database/${$route.params.database_id}/table/create`"> - <v-icon v-if="$vuetify.breakpoint.lgAndUp" left>mdi-table-large-plus</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Create</span> Table + <v-icon v-if="$vuetify.breakpoint.lgAndUp" left>mdi-table-large-plus</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Create </span> Table </v-btn> <v-btn v-if="canCreateIdentifier" color="primary" class="mb-1" :to="`/database/${$route.params.database_id}/persist`"> - <v-icon v-if="$vuetify.breakpoint.lgAndUp" left>mdi-identifier</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Get</span> PID + <v-icon v-if="$vuetify.breakpoint.lgAndUp" left>mdi-identifier</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Get </span> PID </v-btn> </v-toolbar-title> <template v-slot:extension> @@ -74,12 +68,7 @@ </template> <script> -import DownloadButton from '@/components/identifier/DownloadButton.vue' - export default { - components: { - DownloadButton - }, data () { return { tab: null, diff --git a/dbrepo-ui/components/table/TableSchema.vue b/dbrepo-ui/components/table/TableSchema.vue index 9054a2046cc51df5a150485fee7e98354ed7375d..9fa120f44bf03fae3f044f9edd8eee22860d2303 100644 --- a/dbrepo-ui/components/table/TableSchema.vue +++ b/dbrepo-ui/components/table/TableSchema.vue @@ -14,7 +14,7 @@ v-model="c.name" required :rules="[v => !!v || $t('Required')]" - :error-messages="needsSequence && c.name === 'id' ? ['Column needs to be declared as primary key'] : []" + :error-messages="needsSequence && c.name.toLowerCase() === 'id' ? ['Column needs to be declared as primary key'] : []" label="Name *" /> </v-col> <v-col cols="2"> diff --git a/dbrepo-ui/components/table/TableToolbar.vue b/dbrepo-ui/components/table/TableToolbar.vue index 3c4935683718f353c0d54959fbdfbb88f6587e2b..4deb12f3f902ccba38e7ea9f9bd941a48d5e7431 100644 --- a/dbrepo-ui/components/table/TableToolbar.vue +++ b/dbrepo-ui/components/table/TableToolbar.vue @@ -7,33 +7,33 @@ </v-btn> </v-toolbar-title> <v-toolbar-title> - {{ table.name }} + <span v-if="$vuetify.breakpoint.lgAndUp" v-text="table.name" /> </v-toolbar-title> <v-spacer /> <v-toolbar-title> <v-btn v-if="canAddTuple" class="mb-1" @click="addTuple"> - <v-icon left>mdi-plus</v-icon> Add + <v-icon :left="$vuetify.breakpoint.xlOnly">mdi-plus</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Add</span> </v-btn> <v-btn v-if="canEditTuple" color="warning" class="mb-1 black--text" @click="editTuple"> - <v-icon left>mdi-pencil</v-icon> Edit + <v-icon :left="$vuetify.breakpoint.xlOnly">mdi-pencil</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Edit</span> </v-btn> <v-btn v-if="canDeleteTuple" color="error" class="mb-1" :loading="loadingDelete" @click="deleteItems"> - <v-icon left>mdi-delete</v-icon> Delete <span v-if="selection.length > 1"> {{ selection.length }}</span> + <v-icon :left="$vuetify.breakpoint.xlOnly">mdi-delete</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Delete</span> </v-btn> <v-btn v-if="canImportCsv" class="mb-1" :to="`/database/${$route.params.database_id}/table/${$route.params.table_id}/import`"> - <v-icon left>mdi-cloud-upload</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Import</span> csv + <v-icon left>mdi-cloud-upload</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Import </span> csv </v-btn> <v-btn v-if="canExecuteQuery" class="mb-1" :to="`/database/${$route.params.database_id}/query/create?tid=${$route.params.table_id}`" color="secondary"> - <v-icon left>mdi-wrench</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Create</span> Subset + <v-icon left>mdi-wrench</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Create </span> Subset </v-btn> <v-btn v-if="canCreateView" class="mb-1" :to="`/database/${$route.params.database_id}/view/create?tid=${$route.params.table_id}`" color="secondary"> - <v-icon left>mdi-view-carousel</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Create</span> View + <v-icon left>mdi-view-carousel</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Create </span> View </v-btn> <v-btn v-if="canDropTable" class="mb-1" color="error" @click="dropTableDialog = true"> - <v-icon left>mdi-delete</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Drop</span> Table + <v-icon left>mdi-delete</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Drop </span> Table </v-btn> <v-btn v-if="canGetPid" class="mb-1" color="primary" :to="`/database/${$route.params.database_id}/table/${$route.params.table_id}/persist`"> - <v-icon left>mdi-content-save-outline</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Get</span> PID + <v-icon left>mdi-content-save-outline</v-icon> <span v-if="$vuetify.breakpoint.xlOnly">Get </span> PID </v-btn> </v-toolbar-title> </v-toolbar>