1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
/*
Copyright (C) 2019-2024 Selwin van Dijk
This file is part of signalbackup-tools.
signalbackup-tools is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
signalbackup-tools is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with signalbackup-tools. If not, see <https://www.gnu.org/licenses/>.
*/
#include "signalbackup.ih"
void SignalBackup::duplicateQuotes(std::string *s) const
{
size_t pos = 0;
while ((pos = s->find('"', pos)) != std::string::npos)
s->insert((++pos)++, 1, '"'); // this is beautiful ;P
}
bool SignalBackup::exportCsv(std::string const &filename, std::string const &table, bool overwrite) const
{
if (!overwrite && (bepaald::fileOrDirExists(filename) && !bepaald::isDir(filename)))
{
Logger::message("File ", filename, " exists, use --overwrite to overwrite");
return false;
}
// output header
std::ofstream outputfile(filename, std::ios_base::binary);
if (!outputfile.is_open())
{
Logger::error("Failed to open output file '", filename, "' for writing");
return false;
}
SqliteDB::QueryResults results;
if (!d_database.exec("SELECT * FROM " + table, &results))
{
Logger::error("Gathering data from database");
return false;
}
// output header
for (unsigned int i = 0; i < results.columns(); ++i)
outputfile << results.header(i) << ((i == results.columns() - 1) ? '\n' : ',');
// output data
for (unsigned int j = 0; j < results.rows(); ++j)
for (unsigned int i = 0; i < results.columns(); ++i)
{
std::string vas = results.valueAsString(j, i);
duplicateQuotes(&vas);
bool escape = (vas.find_first_of(",\"\n") != std::string::npos) || // contains newline, quote or comma
(!vas.empty() && (std::find_if(vas.begin(), vas.end(), [](char c){ return !std::isspace(c); }) == vas.end())); // is all whitespace (and non empty)
outputfile << (escape ? "\"" : "") << vas << (escape ? "\"" : "") << ((i == results.columns() - 1) ? '\n' : ',');
}
return true;
}
|