{% autoescape None %}
{% extends ../../../templates/base.html %}

{% block title %}[{{instance.hostname}}:{{instance.pg_port}}] - Maintenance{% end %}

{% block content %}

{% include breadcrumb.html %}

<div id="app">
  <h3>
    Table: <strong>{{ table }}</strong>
  </h3>
  <div class="text-center" v-if="loading">
    <img src="/images/ring-alt.svg" class="fa-fw fa-2x">
  </div>
  <div v-cloak v-if="!loading">
    <div class="row mb-2">
      <div class="col">
        <size-distribution-bar
          :height="'10px;'"
          :total="table.total_bytes"
          :cat1="table.table_size"
          :cat1raw="table.table_bytes"
          cat1label="Heap"
          :cat1bis="table.bloat_size"
          :cat1bisraw="table.bloat_bytes || 0"
          cat1bislabel="Heap Bloat"
          :cat2="table.index_size"
          :cat2raw="table.index_bytes"
          cat2label="Indexes"
          :cat2bis="table.index_bloat_size"
          :cat2bisraw="table.index_bloat_bytes"
          cat2bislabel="Indexes Bloat"
          :cat3="table.toast_size"
          :cat3raw="table.toast_bytes"
          cat3label="Toast"
          >
        </size-distribution-bar>
      </div>
    </div>
    <div class="row">
      <div class="col">
        <dl>
          <dt>
          Total
          </dt>
          <dd>
          {{! table.total_size }}
          <br>
          <span class="text-muted">~ {{! table.row_estimate }} rows</span>
          <small class="text-muted">(~ {{! table.n_dead_tup }} dead)</small>
          </dd>
        </dl>
      </div>
      <div class="col">
        <dl>
          <dt>
          Heap
          <span class="bg-cat1 legend fa-fw d-inline-block">&nbsp;</span>
          </dt>
          <dd>
          {{! table.table_size }}
          <br>
          <em class="text-muted">
            Bloat:
            {{! parseInt(table.bloat_bytes / table.table_bytes * 100) }}%
            <span class="small">
              ({{! table.bloat_size }})
            </span>
          </em>
          </dd>
        </dl>
      </div>
      <div class="col">
        <dl>
          <dt>
          Indexes
          <span class="bg-cat2 legend fa-fw d-inline-block">&nbsp;</span>
          </dt>
          <dd>
          {{! table.index_size }}
          <br>
          <em class="text-muted">
            Bloat:
            {{! parseInt(table.index_bloat_bytes / table.index_bytes * 100) }}%
            <span class="small">
              ({{! table.index_bloat_size }})
            </span>
          </em>
          </dd>
        </dl>
      </div>
      <div class="col">
        <dl>
          <dt>
          <span class="bg-secondary legend fa-fw d-inline-block">&nbsp;</span>
          Toast
          </dt>
          <dd>
          {{! table.toast_size }}
          </dd>
        </dl>
      </div>
      <div class="col">
        <dl>
          <dt>
          Fill Factor
          </dt>
          <dd>
          {{! table.fillfactor }}%
          </dd>
        </dl>
      </div>
    </div>
    <div class="row">
      <div class="col-4">
        Last ANALYZE:
        <em :title="getLatestAnalyze().date">
          <strong v-if="getLatestAnalyze().date">
          {{! getLatestAnalyze().date | relative_time }}
          </strong>
          <span v-else>N/A</span>
          <span v-if="getLatestAnalyze().auto">(auto)</span>
        </em>
        <span class="text-muted small" v-if="table.n_mod_since_analyze">
        (~ {{! table.n_mod_since_analyze }} rows modified since then)
        </span>
        <br>
        <small>
          {{! table.analyze_count }} analyzes - {{! table.autoanalyze_count }} auto analyzes
        </small>
      </div>
      <div class="col-4">
        Last VACUUM:
        <em :title="getLatestVacuum().date">
          <strong v-if="getLatestVacuum().date">
            {{! getLatestVacuum().date | relative_time }}
          </strong>
          <span v-else>N/A</span>
          <span v-if="getLatestVacuum().auto">(auto)</span>
        </em>
        <br>
        <small>
          {{! table.vacuum_count }} vacuums - {{! table.autovacuum_count }} auto vacuums
        </small>
      </div>
    </div>
    <div class="row">
      <div class="col-4">
        <div>
          <button type="button" class="btn btn-outline-secondary" data-toggle="modal" data-target="#analyzeModal" v-on:click="checkSession">
            ANALYZE
          </button>
          {% include includes/analyze_modal.html %}
          {% include includes/scheduled_analyze.html %}
        </div>
      </div>
      <div class="col-4">
        <div>
          <button type="button" class="btn btn-outline-secondary" data-toggle="modal" data-target="#vacuumModal" v-on:click="checkSession">
            VACUUM
          </button>
          {% include includes/vacuum_modal.html %}
          {% include includes/scheduled_vacuum.html %}
        </div>
      </div>
      <div class="col-4">
        <div>
          <button type="button" class="btn btn-outline-secondary" data-toggle="modal" data-target="#reindexModal" v-on:click="reindexElementType='table';reindexElementName=table.name;checkSession($event)">
            REINDEX
          </button>
          {% include includes/reindex_modal.html %}
          {% include includes/scheduled_reindex.html %}
        </div>
      </div>
    </div>
    <div class="row">
      <div class="col">
        <p class="text-danger" v-if="table.n_mod_since_analyze / table.n_live_tup > .5">
          <i class="fa fa-exclamation-triangle"></i>The number of modified rows since last analyze is high, you should consider lauching an ANALYZE
          <br>
          <span class="pl-4 text-muted margin-left">
            Out of date analyzes can result in stats not being accurate, which eventually leads to slow queries.
          </span>
        </p>
        <p class="text-danger" v-if="table.n_dead_tup / table.n_live_tup > .1">
          <i class="fa fa-exclamation-triangle"></i>The number of dead tuples is high, you should consider running a VACUUM.
          <br>
          <span class="pl-4 text-muted margin-left">
            Dead tuples waste space and slow down queries.
          </span>
        </p>
        <p class="text-danger" v-if="table.bloat_bytes / table.table_bytes > .5">
          <i class="fa fa-exclamation-triangle"></i>Overall table bloat is high. You should consider running a Full VACUUUM.
          <br>
          <span class="pl-4 text-muted margin-left">
            Table bloat wastes space and slows down queries.
          </span>
        </p>
        <p class="text-danger" v-if="table.index_bloat_bytes / table.index_bytes > .5">
          <i class="fa fa-exclamation-triangle"></i>Overall index bloat is high. You should consider running a Full VACUUUM or REINDEX.
          <br>
          <span class="pl-4 text-muted margin-left">
            Index bloat wastes space and slows down queries.
          </span>
        </p>
      </div>
    </div>
    <div class="d-flex">
      <h4>
        Indexes <span class="text-muted small">({{! table.indexes.length }})</span>
      </h4>
      <div class="ml-auto">
        <button class="btn btn-sm btn-outline-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Sort by {{! indexSortCriterias[indexSortCriteria][0] }}</button>
        <div class="dropdown-menu">
          <h6 class="dropdown-header">Sort by:</h6>
          <a v-for="(criteria, key) in indexSortCriterias" class="dropdown-item" href="#" v-on:click="indexSortBy(key, criteria[1])">
            <i :class="['fa fa-fw', {'fa-check': indexSortCriteria == key}]"></i>
            {{! criteria[0] }}
          </a>
        </div>
      </div>
    </div>
    {% include includes/reindex_modal.html %}
    <table class="table table-sm table-query table-striped table-bordered">
      <tbody>
        <tr v-for="index in indexesSorted">
          <td>
            <strong>{{! index.name }}</strong>
            <small>
              ({{! index.type }})
            </small>
            <span v-if="index.tablespace">
              <em class="text-muted small">in </em>
              {{! index.tablespace }}
            </span>
          </td>
          <td class="text-right align-middle">
            <span :class="[indexSortCriteria == 'total_bytes' ? 'font-weight-bold' : '']">
            {{! index.total_size }}
            </span>
            <small style="min-width: 70px;" :class="['d-inline-block', indexSortCriteria == 'bloat_ratio' ? 'font-weight-bold' : 'text-muted']">
              <template v-if="index.bloat_bytes">
                Bloat: {{! index.bloat_ratio.toFixed(1) }}%
              </template>
            </small>
          </td>
          <td class="align-middle text-right">
            <span class="badge badge-secondary" v-if="index.scans">
              {{! index.scans }} scans
            </span>
          </td>
          <td class="query" width="80%">
            <pre><code class="sql">{{! index.def }}</code></pre>
          </td>
          <td class="align-middle" width="5%">
            <button class="btn btn-outline-secondary btn-sm py-0" data-toggle="modal" data-target="#reindexModal" v-on:click="reindexElementType='index';reindexElementName=index.name;checkSession($event)">Reindex</button>
            <ul class="list list-unstyled mb-0" v-if="scheduledReindexes.length > 0">
              <li v-for="scheduledReindex in scheduledReindexes" v-if="scheduledReindex.index == index.name">
                <template v-if="scheduledReindex.status == 'todo'">
                  <em v-if="scheduledReindex.status == 'todo'">
                    <span class="text-muted" :title="scheduledReindex.datetime.toString()"><i class="fa fa-clock-o"></i> {{! scheduledReindex.datetime | relative_time(false) }}</span>
                  </em>
                  <button class="btn btn-link py-0" v-on:click="cancelReindex(scheduledReindex.id)" v-if="scheduledReindex.status == 'todo'">Cancel</button>
                </template>
                <template v-else-if="scheduledReindex.status == 'doing'">
                  <em class="text-muted">
                    <img id="loadingIndicator" src="/images/ring-alt.svg" class="fa-fw">
                    in progress
                  </em>
                </template>
                <template v-else-if="scheduledReindex.status == 'canceled'">
                  <em class="text-muted">canceled</em>
                </template>
                <template v-else>
                  <em class="text-muted">{{! scheduledReindex.status }}</em>
                </template>
              </li>
            </ul>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

<script src="/js/lodash.min.js"></script>
<script src="/js/moment.min.js"></script>
<script src="/js/highlightjs/highlight.pack.js"></script>
<script src="/js/vue.min.js"></script>
<script src="/js/maintenance/vue.filter.relative-time.js"></script>
<script src="/js/maintenance/vue.size-distribution-bar.js"></script>
<script src="/js/daterangepicker.js"></script>
<script src="/js/maintenance/temboard.maintenance.errors.js"></script>
<script src="/js/maintenance/temboard.maintenance.table.js"></script>
<script>
var apiUrl = '/proxy/{{ instance.agent_address }}/{{ instance.agent_port }}/maintenance/{{ database }}/schema/{{ schema }}/table/{{ table }}';
var schemaApiUrl = '/proxy/{{ instance.agent_address }}/{{ instance.agent_port }}/maintenance/{{ database }}/schema/{{ schema }}';
var maintenanceBaseUrl = '/proxy/{{ instance.agent_address }}/{{ instance.agent_port }}/maintenance';
var agentLoginUrl = '/server/{{ instance.agent_address }}/{{ instance.agent_port }}/login';
var xsession = {{ json_encode(xsession) }};
</script>

{% end %}
