blob: 0c23fd36b69937fda35300f356f0c063aad54dba [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include "util/table-printer.h"
#include "common/logging.h"
#include <iomanip>
#include <sstream>
#include "common/names.h"
using namespace impala;
// Number of spaces to pad adjacent columns.
const int COLUMN_PAD = 2;
TablePrinter::TablePrinter() : max_output_width_(-1) {
}
void TablePrinter::AddColumn(const string& label, bool left_align) {
labels_.push_back(label);
left_align_.push_back(left_align);
max_col_widths_.push_back(label.size());
}
void TablePrinter::set_max_output_width(int width) {
max_output_width_ = width;
}
// Add a row to the table. This must have the same width as labels.
void TablePrinter::AddRow(const vector<string>& row) {
DCHECK_EQ(row.size(), labels_.size());
rows_.push_back(row);
for (int i = 0; i < row.size(); ++i) {
if (row[i].size() > max_col_widths_[i]) max_col_widths_[i] = row[i].size();
}
}
void TablePrinter::PrintRow(stringstream* s, const vector<string>& row,
const vector<int>& widths) const {
DCHECK_EQ(row.size(), labels_.size());
stringstream& ss = *s;
for (int i = 0; i < row.size(); ++i) {
if (left_align_[i]) {
ss << std::left;
} else {
ss << std::right;
}
ss << setw(widths[i]);
stringstream tmp;
if (i != 0) tmp << " ";
if (row[i].size() > widths[i] - COLUMN_PAD) {
tmp << string(row[i].data(), widths[i] - COLUMN_PAD - 3) << "...";
} else {
tmp << row[i];
}
if (i != row.size() - 1) tmp << " ";
ss << tmp.str();
}
}
string TablePrinter::ToString(const string& prefix) const {
vector<int> output_widths = max_col_widths_;
int total_width = 0;
for (int i = 0; i < output_widths.size(); ++i) {
if (max_output_width_ >= 0) {
output_widths[i] = std::min(output_widths[i], max_output_width_);
}
output_widths[i] += COLUMN_PAD;
total_width += output_widths[i];
}
stringstream ss;
ss << prefix;
// Print the labels and line after.
PrintRow(&ss, labels_, output_widths);
ss << endl;
// Print line after labels
for (int i = 0; i < total_width; ++i) {
ss << "-";
}
ss << endl;
// Print the rows
for (int i = 0; i < rows_.size(); ++i) {
PrintRow(&ss, rows_[i], output_widths);
if (i != rows_.size() - 1) ss << endl;
}
return ss.str();
}