Skip to content
Snippets Groups Projects
Commit 5c661699 authored by Martin Weise's avatar Martin Weise
Browse files

fixed smaller bugs

parent fa21064a
No related branches found
No related tags found
2 merge requests!81New stable release,!80Multiple features connected with user management and ownership of databases
......@@ -36,7 +36,7 @@ def create_user(username):
"password": username,
"email": username + "@gmail.com"
})
print("created user")
print("created user with id %d" % response.id)
return response
......@@ -45,7 +45,7 @@ def auth_user(username):
"username": username,
"password": username
})
print("authenticated user")
print("authenticated user with id %d" % response.id)
token = response.token
container.api_client.default_headers = {"Authorization": "Bearer " + token}
database.api_client.default_headers = {"Authorization": "Bearer " + token}
......@@ -64,7 +64,7 @@ def create_container():
"repository": "mariadb",
"tag": "10.5"
})
print("created container")
print("created container with id %d" % response.id)
return response
......@@ -72,8 +72,9 @@ def start_container(container_id):
response = container.modify({
"action": "start"
}, container_id)
print("... starting")
time.sleep(5)
print("started container")
print("started container with id %d" % response.id)
return response
......@@ -83,7 +84,7 @@ def create_database(container_id, is_public=True):
"description": "Hourly measurements in Zürich, Switzerland",
"is_public": is_public
}, container_id)
print("created database")
print("created database with id %d" % response.id)
return response
......@@ -99,7 +100,7 @@ def update_database(container_id, database_id, is_public=True):
"is_public": is_public,
"publication": "2022-07-19"
}, container_id, database_id)
print("updated database")
print("updated database with id %d" % response.id)
return response
......@@ -154,13 +155,13 @@ def create_table(container_id, database_id, columns=None):
"description": "Airquality in Zürich, Switzerland",
"columns": columns
}, container_id, database_id)
print("created table")
print("created table with id %d" % response.id)
return response
def find_table(container_id, database_id, table_id):
response = table.find_by_id(container_id, database_id, table_id)
print("found table")
print("found table with id %d" % response.id)
return response
......@@ -172,7 +173,7 @@ def fill_table(container_id, database_id, table_id):
"quote": "\"",
"skip_lines": 1
}, container_id, database_id, table_id)
print("filled table")
print("filled table with id %d" % table_id)
return response
......@@ -181,7 +182,7 @@ def create_query(container_id, database_id, statement, page=0, size=3):
response = query.execute({
"statement": statement
}, container_id, database_id, page=page, size=size)
print("executed query")
print("executed query with id %d" % response.id)
return response
except api_query.rest.ApiException as e:
print(e)
......@@ -209,7 +210,7 @@ def create_identifier(container_id, database_id, query_id, visibility="everyone"
"relation": "IsCitedBy"
}]
}, token, container_id, database_id)
print("created identifier")
print("created identifier with id %d" % response.id)
return response
......@@ -271,3 +272,24 @@ if __name__ == '__main__':
"primary_key": True,
"null_allowed": False,
}])
#
# create 1 user and 1 container and issue queries to own and foreign database
#
create_user("test2")
auth_user("test2")
# container 4
cid = create_container().id
start_container(cid)
dbid = create_database(cid).id
update_database(cid, dbid)
tid = create_table(cid, dbid).id
tname = find_table(cid, dbid, tid).internal_name
fill_table(cid, dbid, tid)
create_query(cid, dbid, "select `id` from `" + tname + "`")
create_query(cid, dbid, "select `date` from `" + tname + "`")
qid = create_query(cid, dbid, "select `date`, `location`, `status` from `" + tname + "`").id
create_identifier(cid, dbid, qid)
# container 1
tname = find_table(1, 1, 1).internal_name
qid = create_query(1, 1, "select `id` from `" + tname + "`").id
create_identifier(1, 1, qid)
......@@ -79,6 +79,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
......
......@@ -65,13 +65,13 @@ public class QueryEndpoint extends AbstractEndpoint {
@PutMapping("/{queryId}")
@Transactional(readOnly = true)
@Operation(summary = "Re-execute some query")
@Operation(summary = "Re-execute some query", security = @SecurityRequirement(name = "bearerAuth"))
public ResponseEntity<QueryResultDto> reExecute(@NotNull @PathVariable("id") Long containerId,
@NotNull @PathVariable("databaseId") Long databaseId,
@NotNull @PathVariable("queryId") Long queryId,
@RequestParam(value = "page", required = false) Long page,
@RequestParam(value = "size", required = false) Long size,
@NotNull Principal principal)
Principal principal)
throws QueryStoreException, QueryNotFoundException, DatabaseNotFoundException, ImageNotSupportedException,
TableNotFoundException, QueryMalformedException, ContainerNotFoundException, TableMalformedException,
ColumnParseException, NotAllowedException, DatabaseConnectionException {
......@@ -92,7 +92,7 @@ public class QueryEndpoint extends AbstractEndpoint {
public ResponseEntity<InputStreamResource> export(@NotNull @PathVariable("id") Long containerId,
@NotNull @PathVariable("databaseId") Long databaseId,
@NotNull @PathVariable("queryId") Long queryId,
@NotNull Principal principal)
Principal principal)
throws QueryStoreException, QueryNotFoundException, DatabaseNotFoundException, ImageNotSupportedException,
ContainerNotFoundException, TableMalformedException, FileStorageException, NotAllowedException,
QueryMalformedException, DatabaseConnectionException {
......
......@@ -28,7 +28,7 @@ server.port: 9093
logging:
pattern.console: "%d %highlight(%-5level) %msg%n"
level:
root: warn
root: debug
at.tuwien.: trace
at.tuwien.mapper.: trace
at.tuwien.service.: trace
......
......@@ -70,6 +70,8 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
.antMatchers(HttpMethod.GET, "/api/container/**/database/**/table/**/history/**").permitAll()
.antMatchers(HttpMethod.GET, "/api/container/**/database/**/table/**/export/**").permitAll()
.antMatchers(HttpMethod.GET, "/api/container/**/database/**/query/**").permitAll()
.antMatchers(HttpMethod.GET, "/api/container/**/database/**/query/**/export").permitAll()
.antMatchers(HttpMethod.PUT, "/api/container/**/database/**/query/**").permitAll()
.antMatchers("/v3/api-docs.yaml",
"/v3/api-docs/**",
"/swagger-ui/**",
......
<template>
<div>
<v-progress-linear v-if="loading" :color="loadingColor" />
<v-toolbar v-if="db" flat>
<v-toolbar v-if="cached_database" flat>
<v-toolbar-title>
{{ db.name }}
<span>{{ cached_database.name }}</span>
<v-icon v-if="!cached_database.is_public" color="primary" class="mb-1" right>mdi-lock-outline</v-icon>
<v-icon v-if="cached_database.is_public" class="mb-1" right>mdi-lock-open-outline</v-icon>
</v-toolbar-title>
<v-spacer />
<v-toolbar-title>
......@@ -40,11 +41,15 @@ export default {
return {
tab: null,
loading: false,
error: false
error: false,
database: {
id: null,
is_public: null
}
}
},
computed: {
db () {
cached_database () {
return this.$store.state.db
},
databaseId () {
......@@ -65,17 +70,28 @@ export default {
}
}
},
mounted () {
this.init()
watch: {
$route () {
if (this.database.id !== this.$route.params.database_id) {
this.loadDatabase()
}
}
},
methods: {
async init () {
if (this.db != null) {
mounted () {
if (this.database.id) {
return
}
if (this.cached_database && this.cached_database.id === this.$route.params.database_id) {
return
}
this.loadDatabase()
},
methods: {
async loadDatabase () {
try {
this.loading = true
const res = await this.$axios.get(`/api/container/${this.$route.params.container_id}/database/${this.$route.params.database_id}`, this.config)
this.database = res.data
console.debug('database', res.data)
this.$store.commit('SET_DATABASE', res.data)
this.loading = false
......
......@@ -117,6 +117,9 @@ export default {
},
executionUTC () {
return formatTimestampUTCLabel(this.queryDetails.execution)
},
creator () {
return this.queryDetails.creator
}
},
mounted () {
......
......@@ -207,7 +207,7 @@
</v-list-item-title>
<v-list-item-content>
<v-alert
v-if="!loadingQuery && erroneous"
v-if="!error && !loadingQuery && erroneous"
border="left"
color="error">
This query failed to execute and did not produce a subset.
......@@ -425,10 +425,7 @@ export default {
async download () {
this.downloadLoading = true
try {
const res = await this.$axios.get(`/api/container/${this.$route.params.container_id}/database/${this.$route.params.database_id}/query/${this.$route.params.query_id}/export`, {
headers: { Authorization: `Bearer ${this.token}` },
responseType: 'text'
})
const res = await this.$axios.get(`/api/container/${this.$route.params.container_id}/database/${this.$route.params.database_id}/query/${this.$route.params.query_id}/export`, this.config)
console.debug('export query result', res)
const url = window.URL.createObjectURL(new Blob([res.data]))
const link = document.createElement('a')
......
......@@ -18,43 +18,43 @@
<thead>
<tr>
<th>Name</th>
<th>Visibility</th>
<th>Engine</th>
<th>Creator</th>
<th>Visibility</th>
<th>Created</th>
</tr>
</thead>
<tbody>
<tr v-if="containers.length === 0" aria-readonly="true">
<tbody
v-if="!loading">
<tr v-if="databases.length === 0" aria-readonly="true">
<td colspan="5">
<span v-if="!loading">(no databases)</span>
<span>(no databases)</span>
</td>
</tr>
<tr
v-for="item in containers"
v-for="item in databases"
:key="item.id"
class="database"
@click="loadDatabase(item)">
<td>{{ item.name }}</td>
<td>
<v-skeleton-loader v-if="!item.database" type="text" width="50" class="mt-1" />
<span v-if="item.database">
<span v-if="item.database.is_public">Public</span>
<span v-if="!item.database.is_public">Private <v-icon right>mdi-eye-off</v-icon></span>
</span>
<span>{{ item.name }}</span>
</td>
<td>
<span v-if="item.database">{{ item.database.engine }}</span>
<v-skeleton-loader v-if="!item.database" type="text" width="100" class="mt-1" />
<span>{{ item.engine }}</span>
</td>
<td>
<span v-if="item.database">{{ formatCreator(item.database.creator) }}</span>
<v-skeleton-loader v-if="!item.database" type="text" width="100" class="mt-1" />
<sup v-if="item.database">
<v-icon v-if="item.database.creator.email_verified" small color="primary">mdi-check-decagram</v-icon>
<span>{{ formatCreator(item.creator) }}</span>
<sup>
<v-icon v-if="item.creator.email_verified" small color="primary">mdi-check-decagram</v-icon>
</sup>
</td>
<td>{{ createdUTC(item.created) }}</td>
<td>
<v-icon v-if="!item.is_public" color="primary" class="private-icon" right>mdi-lock-outline</v-icon>
<v-icon v-if="item.is_public" class="private-icon" right>mdi-lock-open-outline</v-icon>
</td>
<td>
{{ createdUTC(item.created) }}
</td>
</tr>
</tbody>
</template>
......@@ -81,12 +81,12 @@ export default {
data () {
return {
createDbDialog: false,
databases: [],
containers: [],
searchQuery: null,
items: [
{ text: 'Databases', to: '/container', activeClass: '' }
],
loadingContainers: false,
loading: false,
error: false,
iconSelect: mdiDatabaseArrowRightOutline
......@@ -122,7 +122,7 @@ export default {
async loadContainers () {
this.createDbDialog = false
try {
this.loadingContainers = true
this.loading = true
const res = await this.$axios.get('/api/container/')
this.containers = res.data
console.debug('containers', this.containers)
......@@ -130,20 +130,20 @@ export default {
} catch (err) {
console.error('containers', err)
this.error = true
this.loading = false
}
this.loadingContainers = false
},
async loadDatabases () {
if (this.containers.length === 0) {
return
}
const containers = []
this.loading = true
for (const container of this.containers) {
try {
const res = await this.$axios.get(`/api/container/${container.id}/database`, this.config)
for (const database of res.data) {
container.database = database
containers.push(container)
for (const info of res.data) {
info.container_id = container.id
this.databases.push(info)
}
} catch (err) {
if (err.response === undefined || err.response.status === undefined || err.response.status !== 401) {
......@@ -151,18 +151,14 @@ export default {
}
}
}
this.containers = containers
console.debug('databases loaded', this.containers)
this.loading = false
console.debug('databases', this.databases)
},
createdUTC (str) {
return formatTimestampUTCLabel(str)
},
loadDatabase (container) {
if (!container.id || !container.database) {
console.error('container id', container.id, 'or database id missing')
return
}
this.$router.push(`/container/${container.id}/database/${container.database.id}/info`)
loadDatabase (database) {
this.$router.push(`/container/${database.container_id}/database/${database.id}/info`)
}
}
}
......@@ -184,4 +180,8 @@ export default {
.v-progress-circular {
margin-left: 8px;
}
.private-icon {
flex: 0 !important;
margin-right: 16px;
}
</style>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment