Library: extend the DataFile to allow using it without storage

...seems obvious and does not compromise the simplistic design...
...we do check the file path anyway, just need to add saveAs()...
This commit is contained in:
Fischlurch 2024-03-13 18:57:48 +01:00
parent 1c2cbd4d47
commit 4a8364e422
3 changed files with 106 additions and 10 deletions

View file

@ -71,6 +71,8 @@
**
** std::vector<int>& counters = daz.n.data;
** \endcode
**
** @see DataCSV_test
**
*/
@ -240,7 +242,7 @@ namespace stat{
fs::path filename_;
public:
DataFile(fs::path csvFile)
DataFile(fs::path csvFile ="")
: filename_{fs::consolidated (csvFile)}
{
loadData();
@ -334,6 +336,9 @@ namespace stat{
save (size_t lineLimit =std::numeric_limits<size_t>::max()
,bool backupOld =false)
{
if (filename_.empty())
throw error::Logic{"Unable to save DataFile without filename given."};
fs::path newFilename{filename_};
newFilename += ".tmp";
@ -355,6 +360,22 @@ namespace stat{
} // lock onto absolute path
void
saveAs (fs::path newStorage
,size_t lineLimit =std::numeric_limits<size_t>::max())
{
newStorage = fs::consolidated (newStorage);
if (fs::exists(newStorage))
throw error::Invalid{_Fmt{"Storing DataFile rejected: target %s exists already"}
% newStorage};
if (not (newStorage.parent_path().empty()
or fs::exists(newStorage.parent_path())))
throw error::Invalid{_Fmt{"DataFile(%s) placed into nonexistent directory %s"}
% newStorage.filename() % newStorage.parent_path()};
filename_ = newStorage;
save (lineLimit);
}
private: /* === Implementation === */

View file

@ -31,11 +31,13 @@
//#include "lib/time/timevalue.hpp"
//#include "lib/error.hpp"
//#include "lib/util-foreach.hpp"
#include "lib/util.hpp"
#include "lib/format-cout.hpp" ///////////////////////TODO
#include "lib/test/diagnostic-output.hpp" ///////////////////////TODO
//#include <functional>
//#include <string>
#include <string>
#include <vector>
//using lumiera::Error;
//using lumiera::LUMIERA_ERROR_EXCEPTION;
@ -45,21 +47,37 @@
//using boost::algorithm::is_lower;
//using boost::algorithm::is_digit;
using util::isnil;
//using std::function;
//using std::string;
using std::string;
using std::vector;
namespace lib {
namespace stat{
namespace test{
template<class T>
class Wrmrmpft
namespace {//Setup for test
/** Define the layout of a data row */
struct TableForm
{
T tt_;
Column<string> id{"ID"};
Column<double> val{"Value"};
Column<int> off{"Offset"};
auto allColumns()
{ return std::tie(id
,val
,off
);
}
};
using TestTab = DataFile<TableForm>;
}//(End)Test setup
struct Murpf { };
/***********************************************************//**
@ -74,17 +92,43 @@ namespace test{
void
run (Arg)
{
simpleUsage();
checkGarbageStr();
checkTypeDisplay();
checkThrowChecker();
checkLocalManipulation();
}
/** @test prints "sizeof()" including some type name. */
/** @test add rows and data to a table without filename. */
void
checkTypeDisplay ()
simpleUsage ()
{
TestTab tab;
CHECK (isnil (tab));
tab.newRow();
CHECK (not isnil (tab));
CHECK (1 == tab.size());
CHECK ( "" == string{tab.id});
CHECK (0.0 == tab.val);
CHECK ( 0 == tab.off);
tab.id = "one";
tab.val = 1.0;
tab.dupRow();
CHECK (2 == tab.size());
CHECK ("one" == string{tab.id});
CHECK ( 1.0 == tab.val);
CHECK ( 0 == tab.off);
tab.id = "two";
tab.val = 5.0;
tab.off = -23;
CHECK ("two" == string{tab.id});
CHECK ( 5.0 == tab.val);
CHECK ( -23 == tab.off);
CHECK (tab.off.header == "Offset");
CHECK (tab.off.data == vector({0,-23}));
}
@ -93,6 +137,7 @@ namespace test{
void
checkGarbageStr()
{
UNIMPLEMENTED("Rabäääääh");
}

View file

@ -112041,6 +112041,29 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="flag-yellow"/>
</node>
</node>
<node CREATED="1710351128227" ID="ID_1587957134" MODIFIED="1710351136356" TEXT="Erg&#xe4;nzungen">
<icon BUILTIN="idea"/>
<node COLOR="#338800" CREATED="1710351138211" ID="ID_424130600" MODIFIED="1710351150207" TEXT="Hilfsfunktionen zum Feststellen der Permissions einer Datei">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1710351151183" ID="ID_1693319710" MODIFIED="1710352549516" TEXT="DataFile kann auch leer verwendet werden">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
Das ist naheliegend und kompromittiert das Design nicht wesentlich; File-Operationen k&#246;nnen ohnehin immer Fehler ausl&#246;sen, und da ein Pfad invalid sein kann, ist auch das Original-Design der Tabelle in dieser Hinsicht inh&#228;rent stateful.
</p>
</body>
</html>
</richcontent>
<linktarget COLOR="#254cae" DESTINATION="ID_1693319710" ENDARROW="Default" ENDINCLINATION="138;10;" ID="Arrow_ID_1520501008" SOURCE="ID_101637286" STARTARROW="None" STARTINCLINATION="112;7;"/>
<icon BUILTIN="yes"/>
<node COLOR="#435e98" CREATED="1710351177329" ID="ID_1224481019" MODIFIED="1710352477647" TEXT="leer-Check vor Speichern"/>
<node COLOR="#435e98" CREATED="1710351185059" ID="ID_431256200" MODIFIED="1710352477645" STYLE="fork" TEXT="saveAs()-Funktion bereistellen"/>
</node>
</node>
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1710169538785" HGAP="-5" ID="ID_1706582137" MODIFIED="1710169562437" VSHIFT="16">
<richcontent TYPE="NODE"><html>
<head/>
@ -112077,6 +112100,13 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1710163662386" ID="ID_694159551" MODIFIED="1710170478456" TEXT="DataCSV_test">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1710351225837" ID="ID_1756484657" MODIFIED="1710352395458" TEXT="simpleUsage">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1710352396692" ID="ID_101637286" MODIFIED="1710352560707" TEXT="f&#xfc;hre hiermit Tabellen ohne File-Storage ein">
<arrowlink COLOR="#254cae" DESTINATION="ID_1693319710" ENDARROW="Default" ENDINCLINATION="138;10;" ID="Arrow_ID_1520501008" STARTARROW="None" STARTINCLINATION="112;7;"/>
<icon BUILTIN="yes"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1710163672834" ID="ID_778295326" MODIFIED="1710170479867" TEXT="Statistic_test">
<icon BUILTIN="flag-yellow"/>