Skip to content
Snippets Groups Projects
Select Git revision
  • 38992fd53038aab4deaf99c5442b0c55b4a68b51
  • master default protected
  • replication_test
  • dev protected
  • release-1.10 protected
  • release-1.9 protected
  • 551-init-broker-service-permissions
  • 549-test-oai-pmh
  • 545-saving-multiple-times-breaks-pid-metadata
  • 499-standalone-compute-service-2
  • 539-load-tests
  • hotfix/helm-chart
  • luca_ba_new_interface
  • 534-bug-when-adding-access-to-user-that-is-not-registered-at-dashboard-service
  • release-1.8 protected
  • 533-integrate-semantic-recommendation
  • feature/openshift
  • 518-spark-doesn-t-map-the-headers-correct
  • 485-fixity-checks
  • 530-various-schema-problems-with-subsets
  • release-1.7 protected
  • v1.10.2 protected
  • v1.10.1 protected
  • v1.10.0-rc13 protected
  • v1.10.0-rc12 protected
  • v1.10.0-rc11 protected
  • v1.10.0-rc10 protected
  • v1.10.0-rc9 protected
  • v1.10.0-rc8 protected
  • v1.10.0-rc7 protected
  • v1.10.0-rc6 protected
  • v1.10.0-rc5 protected
  • v1.10.0-rc4 protected
  • v1.10.0-rc3 protected
  • v1.10.0-rc2 protected
  • v1.10.0rc1 protected
  • v1.10.0rc0 protected
  • v1.10.0 protected
  • v1.9.3 protected
  • v1.9.2 protected
  • v1.9.2-rc0 protected
41 results

Builder.vue

Blame
  • Builder.vue 6.78 KiB
    <template>
      <div>
        <v-form
          ref="form"
          v-model="valid"
          lazy-validation>
          <v-toolbar flat>
            <v-toolbar-title>Create Query</v-toolbar-title>
            <v-spacer />
            <v-toolbar-title>
              <v-btn :disabled="!valid" @click="save">
                Save without execution
              </v-btn>
              <v-btn :disabled="!valid" color="primary" @click="execute">
                <v-icon left>mdi-run</v-icon>
                Execute
              </v-btn>
            </v-toolbar-title>
          </v-toolbar>
          <v-card flat>
            <v-card-title>{{ title }}</v-card-title>
            <v-card-text>
              <v-row>
                <v-col cols="6">
                  <v-text-field
                    v-model="title"
                    :rules="[rules.required, rules.titleMin]"
                    class="pa-0"
                    label="Query Title"
                    required />
                </v-col>
              </v-row>
              <v-row>
                <v-col cols="6">
                  <v-textarea
                    v-model="description"
                    :rules="[rules.required]"
                    rows="3"
                    class="pa-0"
                    label="Query Description"
                    required />
                </v-col>
              </v-row>
              <v-row>
                <v-col cols="6">
                  <v-select
                    v-model="table"
                    :rules="[rules.required]"
                    :items="tables"
                    item-text="name"
                    return-object
                    label="Table"
                    @change="loadColumns" />
                </v-col>
                <v-col cols="6">
                  <v-select
                    v-model="select"
                    :rules="[rules.required]"
                    item-text="name"
                    :disabled="!table"
                    :items="selectItems"
                    label="Columns"
                    return-object
                    multiple
                    @change="buildQuery" />
                </v-col>
              </v-row>
              <QueryFilters
                v-if="table"
                v-model="clauses"
                :columns="columnNames" />
              <v-row v-if="query.formatted">
                <v-col>
                  <highlightjs autodetect :code="query.formatted" />
                </v-col>
              </v-row>
              <v-row>
                <v-col>
                  <p>Results</p>
                  <v-data-table
                    :headers="result.headers"
                    :items="result.rows"
                    :loading="loading"
                    :items-per-page="30"
                    class="elevation-1" />
                </v-col>
              </v-row>
              <v-row>
                <v-col>
                  <v-btn v-if="queryId" color="primary" :to="`/container/${$route.params.container_id}/database/${databaseId}/query/${queryId}`">
                    <v-icon left>mdi-fingerprint</v-icon>
                    Obtain Query DOI
                  </v-btn>
                </v-col>
              </v-row>
            </v-card-text>
          </v-card>
        </v-form>
      </div>
    </template>
    
    <script>
    export default {
      data () {
        return {
          valid: false,
          table: null,
          tables: [],
          title: null,
          description: null,
          tableDetails: null,
          queryId: null,
          query: {
            sql: ''
          },
          select: [],
          clauses: [],
          result: {
            headers: [],
            rows: []
          },
          rules: {
            required: value => !!value || 'Required',
            titleMin: value => (value || '').length >= 10 || 'Minimum 10 characters'
          },
          loading: false
        }
      },
      computed: {
        selectItems () {
          const columns = this.tableDetails && this.tableDetails.columns
          return columns || []
        },
        columnNames () {
          return this.selectItems && this.selectItems.map(s => s.internalName)
        },
        databaseId () {
          return this.$route.params.database_id
        },
        tableId () {
          return this.table.id
        }
      },
      watch: {
        clauses: {
          deep: true,
          handler () {
            this.buildQuery()
          }
        }
      },
      async mounted () {
        // XXX same as in TableList
        try {
          const res = await this.$axios.get(
            `/api/container/${this.$route.params.container_id}/database/${this.databaseId}/table`)
          this.tables = res.data
          console.debug('tables', this.tables)
        } catch (err) {
          this.$toast.error('Could not list table.')
        }
      },
      methods: {
        async execute () {
          this.$refs.form.validate()
          const query = this.query.sql.replaceAll('`', '')
          this.loading = true
          try {
            const res = await this.$axios.put(`/api/container/${this.$route.params.container_id}/database/${this.databaseId}/table/${this.tableId}/query/execute`, {
              statement: query
            })
            console.debug('query result', res)
            this.$toast.success('Successfully executed query')
            this.loading = false
            this.queryId = res.data.id
            this.result.headers = this.select.map((s) => {
              return { text: s.name, value: s.name, sortable: false }
            })
            this.result.rows = res.data.result
          } catch (err) {
            console.error('query execute', err)
            this.$toast.error('Could not execute query')
            this.loading = false
          }
        },
        async save () {
          this.$refs.form.validate()
          const query = this.query.sql.replaceAll('`', '')
          this.loading = true
          try {
            const res = await this.$axios.post(`/api/container/${this.$route.params.container_id}/database/${this.databaseId}/table/${this.tableId}/query/save`, {
              statement: query
            })
            console.debug('query result', res)
            this.$toast.success('Successfully saved query')
            this.loading = false
            this.queryId = res.data.id
          } catch (err) {
            console.error('query save', err)
            this.$toast.error('Could not save query')
            this.loading = false
          }
        },
        async buildQuery () {
          if (!this.table) {
            return
          }
          const url = '/server-middleware/query/build'
          const data = {
            table: this.table.internalName,
            select: this.select.map(s => s.name),
            clauses: this.clauses
          }
          try {
            const res = await this.$axios.post(url, data)
            if (res && !res.error) {
              this.query = res.data
            }
          } catch (e) {
            console.log(e)
          }
        },
        async loadColumns () {
          const tableId = this.table.id
          try {
            const res = await this.$axios.get(`/api/container/${this.$route.params.container_id}/database/${this.databaseId}/table/${tableId}`)
            this.tableDetails = res.data
            this.buildQuery()
          } catch (err) {
            this.$toast.error('Could not get table details.')
          }
        }
      }
    }
    </script>
    
    <style lang="scss" scoped>
    /* these are taked from solarized-light (plugins/vendors.js), to override the
    main.scss file from vuetify, because it paints it red */
    ::v-deep code {
      background: #fdf6e3;
      color: #657b83;
    }
    
    </style>