src/SqlHandler.h
branchv_0
changeset 12 0b38339b871b
parent 11 ccf19c7e7adf
child 14 eacacf060755
equal deleted inserted replaced
11:ccf19c7e7adf 12:0b38339b871b
    22 #include <vector>
    22 #include <vector>
    23 #include <locale>
    23 #include <locale>
    24 #include <codecvt>
    24 #include <codecvt>
    25 #include <unistd.h>
    25 #include <unistd.h>
    26 #include <cassert>
    26 #include <cassert>
       
    27 #include <sys/stat.h>
    27 
    28 
    28 #include <sqlite3.h>
    29 #include <sqlite3.h>
    29 
    30 
    30 #include <relpipe/reader/typedefs.h>
    31 #include <relpipe/reader/typedefs.h>
    31 #include <relpipe/reader/TypeId.h>
    32 #include <relpipe/reader/TypeId.h>
   138 };
   139 };
   139 
   140 
   140 class SqlHandler : public RelationalReaderValueHandler {
   141 class SqlHandler : public RelationalReaderValueHandler {
   141 private:
   142 private:
   142 	Configuration configuration;
   143 	Configuration configuration;
       
   144 	boolean_t fileAlreadyExisted = false;
   143 	writer::RelationalWriter* relationalWriter;
   145 	writer::RelationalWriter* relationalWriter;
   144 	std::wstring_convert<codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings
   146 	std::wstring_convert<codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings
   145 	vector<AttributeMetadata> currentReaderMetadata;
   147 	vector<AttributeMetadata> currentReaderMetadata;
   146 	integer_t currentAttributeIndex = 0;
   148 	integer_t currentAttributeIndex = 0;
   147 	std::unique_ptr<Connection> connection;
   149 	std::unique_ptr<Connection> connection;
   184 	}
   186 	}
   185 
   187 
   186 public:
   188 public:
   187 
   189 
   188 	SqlHandler(writer::RelationalWriter* relationalWriter, Configuration& configuration) : relationalWriter(relationalWriter), configuration(configuration) {
   190 	SqlHandler(writer::RelationalWriter* relationalWriter, Configuration& configuration) : relationalWriter(relationalWriter), configuration(configuration) {
   189 		std::string file = configuration.file.size() ? convertor.to_bytes(configuration.file) : ":memory:";
   191 		std::string file;
       
   192 		if (configuration.file.size()) {
       
   193 			file = convertor.to_bytes(configuration.file);
       
   194 
       
   195 			// in C++17 we can use: std::filesystem::exists()
       
   196 			struct stat fileStat;
       
   197 			fileAlreadyExisted = (stat(file.c_str(), &fileStat) == 0);
       
   198 		} else {
       
   199 			file = ":memory:";
       
   200 		}
       
   201 
   190 		connection.reset(new Connection(file.c_str()));
   202 		connection.reset(new Connection(file.c_str()));
   191 	}
   203 	}
   192 
   204 
   193 	virtual ~SqlHandler() {
   205 	virtual ~SqlHandler() {
   194 	}
   206 	}
   253 				break;
   265 				break;
   254 			}
   266 			}
   255 			default:
   267 			default:
   256 				throw SqlException(L"Unsupported type in attribute()");
   268 				throw SqlException(L"Unsupported type in attribute()");
   257 		}
   269 		}
   258 		
   270 
   259 		if (currentAttributeIndex % currentReaderMetadata.size() == 0) {
   271 		if (currentAttributeIndex % currentReaderMetadata.size() == 0) {
   260 			currentInsert->next();
   272 			currentInsert->next();
   261 			currentInsert->reset();
   273 			currentInsert->reset();
   262 			currentAttributeIndex = 0;
   274 			currentAttributeIndex = 0;
   263 		}
   275 		}
   264 	}
   276 	}
   265 
   277 
   266 	void endOfPipe() {
   278 	void endOfPipe() {
       
   279 		// run the transformation – process all statements:
   267 		for (const Statement& statement : configuration.statements) processStatement(statement);
   280 		for (const Statement& statement : configuration.statements) processStatement(statement);
   268 
   281 
   269 		if (configuration.file.size() && !configuration.keepFile) {
   282 		// delete or keep the file:
   270 			int result = unlink(convertor.to_bytes(configuration.file).c_str());
   283 		if (configuration.file.size()) {
   271 			if (result) throw SqlException(L"Unable to delete SQLite file.");
   284 			if (configuration.keepFile == KeepFile::Never || (configuration.keepFile == KeepFile::Automatic && !fileAlreadyExisted)) {
   272 		}
   285 				std::wcerr << L"will unlink file" << std::endl;
       
   286 				int result = unlink(convertor.to_bytes(configuration.file).c_str());
       
   287 				if (result) throw SqlException(L"Unable to delete SQLite file.");
       
   288 			}
       
   289 		} // else: we had no file, everything was in memory
   273 	}
   290 	}
   274 
   291 
   275 };
   292 };
   276 
   293 
   277 }
   294 }