Skip to content
Snippets Groups Projects
Select Git revision
  • master
1 result

htb.pl

Blame
  • Builder.vue 5.00 KiB
    <template>
      <div>
        <v-row dense>
          <v-col cols="6">
            <v-select
              v-model="table"
              :items="tables"
              item-text="name"
              return-object
              label="Table"
              @change="loadColumns" />
          </v-col>
          <v-col cols="6">
            <v-select
              v-model="select"
              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-col cols="3" class="actions">
            <v-btn class="execute" color="primary" @click="execute">
              <v-icon left>mdi-run</v-icon>
              Execute
            </v-btn>
            <div class="break"></div>
            <v-btn class="execute" @click="save">
              Save
            </v-btn>
          </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="`/databases/${databaseId}/queries/${queryId}`">
              <v-icon left>mdi-fingerprint</v-icon>
              Obtain Query DOI
            </v-btn>
          </v-col>
        </v-row>
      </div>
    </template>
    
    <script>
    export default {
      data () {
        return {
          table: null,
          tables: [],
          tableDetails: null,
          queryId: null,
          query: {},
          select: [],
          clauses: [],
          result: {
            headers: [],
            rows: []
          },
          loading: false
        }
      },
      computed: {
        selectItems () {
          const columns = this.tableDetails && this.tableDetails.columns
          return columns || []
        },
        columnNames () {
          return this.selectItems && this.selectItems.map(s => s.name)
        },
        databaseId () {
          return this.$route.params.database_id
        }
      },
      watch: {
        clauses: {
          deep: true,
          handler () {
            this.buildQuery()
          }
        }
      },
      async mounted () {
        // XXX same as in TableList
        try {
          const res = await this.$axios.get(
            `/api/database/${this.databaseId}/table`)
          this.tables = res.data
        } catch (err) {
          this.$toast.error('Could not list table.')
        }
      },
      methods: {
        async execute () {
          const query = this.query.sql.replaceAll('`', '')
          this.loading = true
          try {
            const res = await this.$axios.put(`/api/database/${this.databaseId}/query`, {
              Query: 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: 'mdb_' + 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 () {
          const query = this.query.sql.replaceAll('`', '')
          this.loading = true
          try {
            const res = await this.$axios.put(`/api/database/${this.databaseId}/save`, {
              Query: 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 => 'mdb_' + 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/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;
    }
    
    .actions {
      align-items: center;
      display: flex;
      flex-wrap: wrap;
      justify-content: center;
    }
    
    .break {
      flex-basis: 100%;
      height: 0;
    }
    </style>