You now need to explicitly specify whether flux files get merged or

overwritten, because the old behaviour was weird. Reader uses SqliteFluxSink to
write flux files, rather than raw database accesses.
This commit is contained in:
David Given
2020-02-08 12:41:50 +01:00
parent d528978667
commit be41c1de76
5 changed files with 42 additions and 22 deletions

View File

@@ -300,13 +300,13 @@ containing valuable historical data, and you want to read them.
Typically I do this:
```
$ fluxengine read brother -s :d=0 -o brother.img --write-flux=brother.flux --write-svg=brother.svg
$ fluxengine read brother -s :d=0 -o brother.img --write-flux=brother.flux --overwrite --write-svg=brother.svg
```
This will read the disk in drive 0 and write out a filesystem image. It'll
also copy the flux to brother.flux and write out an SVG visualisation. If I
then need to tweak the settings, I can rerun the decode without having to
physically touch the disk like this:
This will read the disk in drive 0 and write out a filesystem image. It'll also
copy the flux to `brother.flux` (replacing any old one) and write out an SVG
visualisation. If I then need to tweak the settings, I can rerun the decode
without having to physically touch the disk like this:
```
$ fluxengine read brother -s brother.flux -o brother.img --write-svg=brother.svg

View File

@@ -147,7 +147,7 @@ public:
void set(const std::string& value) { _value = std::stod(value); }
};
class BoolFlag : public ValueFlag<double>
class BoolFlag : public ValueFlag<bool>
{
public:
BoolFlag(const std::vector<std::string>& names, const std::string helptext,

View File

@@ -4,6 +4,7 @@
#include "flags.h"
extern FlagGroup hardwareFluxSinkFlags;
extern FlagGroup sqliteFluxSinkFlags;
class Fluxmap;
class FluxSpec;
@@ -13,11 +14,9 @@ class FluxSink
public:
virtual ~FluxSink() {}
private:
static std::unique_ptr<FluxSink> createSqliteFluxSink(const std::string& filename);
static std::unique_ptr<FluxSink> createHardwareFluxSink(unsigned drive);
public:
static std::unique_ptr<FluxSink> create(const FluxSpec& spec);
public:

View File

@@ -2,14 +2,37 @@
#include "fluxmap.h"
#include "sql.h"
#include "fluxsink/fluxsink.h"
#include "flags.h"
#include "fmt/format.h"
#include <unistd.h>
FlagGroup sqliteFluxSinkFlags;
static SettableFlag mergeFlag(
{ "--merge" },
"merge new data into existing flux file");
static SettableFlag overwriteFlag(
{ "--overwrite" },
"overwrite existing flux file");
class SqliteFluxSink : public FluxSink
{
public:
SqliteFluxSink(const std::string& filename)
{
if (mergeFlag && overwriteFlag)
Error() << "you can't specify --merge and --overwrite";
if (!mergeFlag)
{
if (!overwriteFlag && (access(filename.c_str(), F_OK) == 0))
Error() << "cowardly refusing to overwrite flux file without --merge or --overwrite specified";
if (remove(filename.c_str()) != 0)
Error() << fmt::format("failed to overwrite flux file");
}
_outdb = sqlOpen(filename, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
int oldVersion = sqlReadIntProperty(_outdb, "version");
if ((oldVersion != 0) && (oldVersion != FLUX_VERSION_CURRENT))
Error() << fmt::format("that flux file is version {}, but this client is for version {}",

View File

@@ -2,6 +2,7 @@
#include "flags.h"
#include "usb.h"
#include "fluxsource/fluxsource.h"
#include "fluxsink/fluxsink.h"
#include "reader.h"
#include "fluxmap.h"
#include "sql.h"
@@ -18,7 +19,13 @@
#include "imagewriter/imagewriter.h"
#include "fmt/format.h"
FlagGroup readerFlags { &hardwareFluxSourceFlags, &fluxmapReaderFlags, &visualiserFlags };
FlagGroup readerFlags
{
&hardwareFluxSourceFlags,
&sqliteFluxSinkFlags,
&fluxmapReaderFlags,
&visualiserFlags
};
static DataSpecFlag source(
{ "--source", "-s" },
@@ -61,7 +68,7 @@ static SettableFlag highDensityFlag(
{ "--high-density", "--hd" },
"set the drive to high density mode");
static sqlite3* outdb;
static std::unique_ptr<FluxSink> outputFluxSink;
void setReaderDefaultSource(const std::string& source)
{
@@ -86,8 +93,8 @@ void Track::readFluxmap()
"{0} ms in {1} bytes\n",
int(fluxmap->duration()/1e6),
fluxmap->bytes());
if (outdb)
sqlWriteFlux(outdb, physicalTrack, physicalSide, *fluxmap);
if (outputFluxSink)
outputFluxSink->writeFlux(physicalTrack, physicalSide, *fluxmap);
}
std::vector<std::unique_ptr<Track>> readTracks()
@@ -100,17 +107,8 @@ std::vector<std::unique_ptr<Track>> readTracks()
if (!destination.get().empty())
{
outdb = sqlOpen(destination, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
std::cout << "Writing a copy of the flux to " << destination.get() << std::endl;
sqlPrepareFlux(outdb);
sqlStmt(outdb, "BEGIN;");
sqlWriteIntProperty(outdb, "version", FLUX_VERSION_CURRENT);
atexit([]()
{
sqlStmt(outdb, "COMMIT;");
sqlClose(outdb);
}
);
outputFluxSink = FluxSink::createSqliteFluxSink(destination.get());
}
std::shared_ptr<FluxSource> fluxSource = FluxSource::create(spec);