blob: 9b8442d8c399bc0c42a744d1dbfe0fc714cd4d13 [file]
/*
* 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 <algorithm>
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "cli/exit_codes.h"
#include "commands/commands.h"
#include "common/schema.h"
#include "reader/tsfile_reader.h"
#include "utils/storage_utils.h"
namespace tsfile_cli {
namespace {
void write_table_schema_rows(const ParsedArgs& args,
storage::TsFileReader& reader, RowWriter& w) {
const std::string target_table_name = storage::to_lower(args.table);
auto schemas = reader.get_all_table_schemas();
for (auto& schema : schemas) {
if (!schema) {
continue;
}
if (!target_table_name.empty() &&
schema->get_table_name() != target_table_name) {
continue;
}
for (const auto& ms : schema->get_measurement_schemas()) {
if (!ms) {
continue;
}
const std::string& name = ms->measurement_name_;
if (!args.measurements.empty() &&
std::find(args.measurements.begin(), args.measurements.end(),
name) == args.measurements.end()) {
continue;
}
w.write({schema->get_table_name(), name,
tsdatatype_name(ms->data_type_),
tsencoding_name(ms->encoding_),
compression_name(ms->compression_type_)},
{false, false, false, false, false});
}
}
}
} // namespace
int cmd_schema(const ParsedArgs& args, storage::TsFileReader& reader,
OutputFormat fmt, std::ostream& out, std::ostream& /*err*/) {
RowWriter w(
out, fmt,
{"target", "measurement", "datatype", "encoding", "compression"},
{common::STRING, common::STRING, common::STRING, common::STRING,
common::STRING},
args.no_header);
if (is_table_model(args, reader)) {
write_table_schema_rows(args, reader, w);
w.finish();
return kExitOk;
}
storage::DeviceTimeseriesMetadataMap meta =
reader.get_timeseries_metadata();
for (auto& kv : meta) {
std::string target = kv.first ? kv.first->get_device_name() : "";
if (!args.device.empty() && target != args.device) {
continue;
}
// The timeseries metadata (kv.second) carries the data type but not the
// encoding/compression, so fetch the measurement schema separately to
// fill those two columns, keyed by measurement name.
std::map<std::string, std::pair<std::string, std::string>> enc_comp;
if (kv.first) {
std::vector<storage::MeasurementSchema> ms;
if (reader.get_timeseries_schema(kv.first, ms) == 0) {
for (auto& m : ms) {
enc_comp[m.measurement_name_] =
std::make_pair(tsencoding_name(m.encoding_),
compression_name(m.compression_type_));
}
}
}
for (auto& ts : kv.second) {
if (!ts) {
continue;
}
std::string m = ts->get_measurement_name().to_std_string();
if (!args.measurements.empty() &&
std::find(args.measurements.begin(), args.measurements.end(),
m) == args.measurements.end()) {
continue;
}
std::string enc;
std::string comp;
auto it = enc_comp.find(m);
if (it != enc_comp.end()) {
enc = it->second.first;
comp = it->second.second;
}
w.write(
{target, m, tsdatatype_name(ts->get_data_type()), enc, comp},
{false, false, false, enc.empty(), comp.empty()});
}
}
w.finish();
return kExitOk;
}
} // namespace tsfile_cli