Skip to content

Commit

Permalink
Added escape string test
Browse files Browse the repository at this point in the history
  • Loading branch information
rfdavid committed Aug 3, 2023
1 parent e962c36 commit d812ea4
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 39 deletions.
2 changes: 1 addition & 1 deletion src/include/processor/operator/copy_to/csv_file_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ class CSVFileWriter {
std::unique_ptr<common::FileInfo> fileInfo;

void escapeString(std::string& value);
void writeValue(common::ValueVector* vector);
void flush();
void writeValue(common::ValueVector* vector, int64_t pos);

template<typename T>
void writeToBuffer(common::ValueVector* vector, int64_t pos, bool escapeStringValue = false);
Expand Down
77 changes: 39 additions & 38 deletions src/processor/operator/copy_to/csv_file_writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,6 @@ using namespace kuzu::common;
namespace kuzu {
namespace processor {

template<typename T>
void CSVFileWriter::writeListToBuffer(common::ValueVector* vector, int64_t pos) {
auto value = TypeUtils::toString(vector->getValue<T>(pos), vector);
escapeString(value);
writeToBuffer(value);
}

template<typename T>
void CSVFileWriter::writeToBuffer(
common::ValueVector* vector, int64_t pos, bool escapeStringValue) {
auto value = TypeUtils::toString(vector->getValue<T>(pos));
if (escapeStringValue) {
escapeString(value);
}
writeToBuffer(value);
}

void CSVFileWriter::open(const std::string& filePath) {
fileInfo = FileUtils::openFile(filePath, O_WRONLY | O_CREAT | O_TRUNC);
}
Expand All @@ -44,20 +27,47 @@ void CSVFileWriter::writeHeader(const std::vector<std::string>& columnNames) {
flush();
}

void CSVFileWriter::flush() {
const std::string str = buffer.str();
FileUtils::writeToFile(fileInfo.get(), (uint8_t*)str.data(), str.size(), fileOffset);
fileOffset += str.size();
buffer.str("");
void CSVFileWriter::writeValues(std::vector<common::ValueVector*>& outputVectors) {
bool hasData = true;
if (outputVectors.size() == 0) {
return;
}
auto i = 0u;
for (; i < outputVectors.size() - 1; i++) {
assert(outputVectors[i]->state->isFlat);
writeValue(outputVectors[i]);
writeToBuffer(CopyConstants::DEFAULT_CSV_DELIMITER);
}
writeValue(outputVectors[i]);
writeToBuffer(CopyConstants::DEFAULT_CSV_LINE_BREAK);
flush();
}

template<typename T>
void CSVFileWriter::writeToBuffer(
common::ValueVector* vector, int64_t pos, bool escapeStringValue) {
auto value = TypeUtils::toString(vector->getValue<T>(pos));
if (escapeStringValue) {
escapeString(value);
}
writeToBuffer(value);
}

template<typename T>
void CSVFileWriter::writeListToBuffer(common::ValueVector* vector, int64_t pos) {
auto value = TypeUtils::toString(vector->getValue<T>(pos), vector);
escapeString(value);
writeToBuffer(value);
}

void CSVFileWriter::escapeString(std::string& value) {
StringUtils::replaceAll(value, "\"", "\"\"");
value = "\"" + value + "\"";
}

void CSVFileWriter::writeValue(common::ValueVector* vector, int64_t pos) {
auto selPos = vector->state->selVector->selectedPositions[pos];
void CSVFileWriter::writeValue(common::ValueVector* vector) {
// vectors are always flat
auto selPos = vector->state->selVector->selectedPositions[0];
switch (vector->dataType.getLogicalTypeID()) {
case LogicalTypeID::BOOL:
return writeToBuffer<int8_t>(vector, selPos);
Expand Down Expand Up @@ -92,20 +102,11 @@ void CSVFileWriter::writeValue(common::ValueVector* vector, int64_t pos) {
}
}

void CSVFileWriter::writeValues(std::vector<common::ValueVector*>& outputVectors) {
bool hasData = true;
if (outputVectors.size() == 0) {
return;
}
auto i = 0u;
for (; i < outputVectors.size() - 1; i++) {
assert(outputVectors[i]->state->isFlat);
writeValue(outputVectors[i], 0);
writeToBuffer(CopyConstants::DEFAULT_CSV_DELIMITER);
}
writeValue(outputVectors[i], 0);
writeToBuffer(CopyConstants::DEFAULT_CSV_LINE_BREAK);
flush();
void CSVFileWriter::flush() {
const std::string str = buffer.str();
FileUtils::writeToFile(fileInfo.get(), (uint8_t*)str.data(), str.size(), fileOffset);
fileOffset += str.size();
buffer.str("");
}

} // namespace processor
Expand Down
12 changes: 12 additions & 0 deletions test/test_files/copy/copy_to.test
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,18 @@ Cannot open file: a/b/c/d.csv
1.731000
MAX(p.height)

-CASE StringEscapeCopyTo

-STATEMENT COPY (RETURN 100,'a string with "quotes"',5.6,'","') TO "${DATABASE_PATH}/string.csv"
---- ok
-STATEMENT CREATE NODE TABLE stringTable (number INT, str STRING, frac DOUBLE, str2 STRING, PRIMARY KEY (str))
---- ok
-STATEMENT COPY stringTable FROM '${DATABASE_PATH}/string.csv' (HEADER=TRUE)
---- ok
-STATEMENT MATCH (s:stringTable) RETURN s.number, s.str, s.frac, s.str2
---- 1
100|a string with "quotes"|5.600000|","

-CASE CountResultCopyTo

-STATEMENT COPY (MATCH (p:person) RETURN COUNT(*)) TO "${DATABASE_PATH}/count.csv"
Expand Down

0 comments on commit d812ea4

Please sign in to comment.