Newer
Older
GitBucket / src / main / twirl / gitbucket / core / admin / dbviewer.scala.html
@(tables: Seq[gitbucket.core.controller.Table])(implicit context: gitbucket.core.controller.Context)
@import gitbucket.core.view.helpers
@gitbucket.core.html.main("Database viewer") {
  @gitbucket.core.admin.html.menu("dbviewer") {
    <div class="container">
      <div class="col-md-3">
        <div id="table-tree">
          <ul>
          @tables.map { table =>
            <li data-jstree='{"icon":"@context.path/assets/common/images/table.gif"}' data-table="@table.name">@table.name
              <ul>
              @table.columns.map { column =>
                <li data-jstree='{"icon":"@context.path/assets/common/images/column.gif"}' data-table="@table.name" data-column="@column.name">
                  @column.name @if(column.primaryKey){ (PK) }
                </li>
              }
              </ul>
            </li>
          }
          </ul>
        </div>
      </div>
      <div class="col-md-9">
        <div id="editor" style="width: 100%; height: 300px;"></div>
        <div class="block">
          <input type="button" value="Run query" id="run-query" class="btn btn-success">
          <input type="button" value="Clear" id="clear-query" class="btn btn-default">
          <label for="autorun">
            <input type="checkbox" id="autorun" name="autorun"/> Auto Run Query
          </label>
        </div>
        <div id="result"></div>
      </div>
    </div>
  }
}
<script src="@helpers.assets("/vendors/ace/ace.js")" type="text/javascript" charset="utf-8"></script>
<script src="@helpers.assets("/vendors/vakata-jstree-3.3.4/jstree.min.js")" type="text/javascript" charset="utf-8"></script>
<link rel="stylesheet" href="@helpers.assets("/vendors/vakata-jstree-3.3.4/themes/default/style.min.css")" />
<script>
function getPosition(editor, position){
  var session = editor.getSession();
  var result = 0;
  for(var i = 0; i < position.row; i++){
    result = result + session.getLine(i).length + 1;
  }
  return result + position.column;
}

$(function(){
  $('#editor').text($('#initial').val());
  var editor = ace.edit("editor");
  editor.setTheme("ace/theme/monokai");
  editor.getSession().setMode("ace/mode/sql");

  $('#table-tree').jstree();

  $('#table-tree').on('select_node.jstree', function(e, data){
    if(editor.getValue().trim() == '' || $('#autorun').is(':checked')){
      if(data.node.data['column']){
        editor.setValue('SELECT ' + data.node.data['column'] + ' FROM ' + data.node.data['table']);
      } else if(data.node.data['table']){
        editor.setValue('SELECT * FROM ' + data.node.data['table']);
      }
      if($('#autorun').is(':checked')){
        $('#run-query').click();
      }
    } else {
      var position = editor.getCursorPosition();
      var prefix = '';
      // Check a previous character
      if(position.column != 0){
        var range = new ace.Range(position.row, position.column - 1, position.row, position.column);
        var c = editor.getSession().getTextRange(range);
        if(c != '' && c != ' ' && c != '.' && c != ',' && c != '\t' && c != '\r' && c != '\n'){
          prefix = ', ';
        }
      }
      if(data.node.data['column']){
        editor.getSession().insert(position, prefix + data.node.data['column']);
      } else if(data.node.data['table']){
        editor.getSession().insert(position, prefix + data.node.data['table']);
      }
    }
    editor.focus();
  });

  $('#clear-query').click(function(){
    editor.setValue('');
  });

  $('#run-query').click(function(){
    var selectedText = editor.getSession().doc.getTextRange(editor.selection.getRange()).trim();

    $.post('@context.path/admin/dbviewer/_query', { query: selectedText == '' ? editor.getValue() : selectedText },
      function(data){
        if(data.type == "query"){
          var table = $('<table class="table table-bordered table-hover table-scroll">');

          var header = $('<tr>');
          $.each(data.columns, function(i, column){
            header.append($('<th>').text(column));
          });
          table.append($('<thead>').append(header));

          var body = $('<tbody>');
          $.each(data.rows, function(i, rs){
            var row = $('<tr>');
            $.each(data.columns, function(i, column){
              row.append($('<td>').text(rs[column]));
            });
            body.append(row);
          });

          table.append(body);
          $('#result').empty().append(table);

        } else if(data.type == "update"){
          $('#result').empty().append($('<span>').text('Updated ' + data.rows + ' rows.'));

        } else if(data.type == "error"){
          $('#result').empty().append($('<span class="error">').text(data.message));
        }
      }
    );
  });
});
</script>