Skip to content

Commit

Permalink
Merge pull request #42 from lutraconsulting/confict_file
Browse files Browse the repository at this point in the history
fix #38 create conflict files [API BREAK]
  • Loading branch information
PeterPetrik committed Feb 6, 2020
2 parents 9d75f0b + f6aeadf commit 5488195
Show file tree
Hide file tree
Showing 16 changed files with 564 additions and 178 deletions.
57 changes: 37 additions & 20 deletions geodiff/src/geodiff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,20 @@ int GEODIFF_applyChangeset( const char *base, const char *changeset )
}
}

int GEODIFF_createRebasedChangeset( const char *base, const char *modified, const char *changeset_their, const char *changeset )
int GEODIFF_createRebasedChangeset( const char *base,
const char *modified,
const char *changeset_their,
const char *changeset,
const char *conflictfile
)
{
if ( !conflictfile )
{
Logger::instance().error( "NULL arguments to GEODIFF_createRebasedChangeset" );
return GEODIFF_ERROR;
}
fileremove( conflictfile );

try
{
// get all triggers sql commands
Expand All @@ -257,7 +269,22 @@ int GEODIFF_createRebasedChangeset( const char *base, const char *modified, cons
if ( rc != GEODIFF_SUCCESS )
return rc;

return rebase( changeset_their, changeset, changeset_BASE_MODIFIED.path() );
std::vector<ConflictFeature> conflicts;
rc = rebase( changeset_their, changeset, changeset_BASE_MODIFIED.path(), conflicts );

// output conflicts
if ( conflicts.empty() )
{
Logger::instance().debug( "No conflicts present" );
}
else
{
GeoDiffExporter exporter;
std::string res = exporter.toJSON( conflicts );
flushString( conflictfile, res );
}

return rc;
}
catch ( GeoDiffException exc )
{
Expand Down Expand Up @@ -337,21 +364,8 @@ static int listChangesJSON( const char *changeset, const char *jsonfile, bool on
return 0;
}

std::shared_ptr<Sqlite3Db> db = std::make_shared<Sqlite3Db>();
db->open( ":memory:" );
std::string cmd = "CREATE TABLE gpkg_contents (table_name TEXT NOT NULL PRIMARY KEY,data_type TEXT NOT NULL,identifier TEXT UNIQUE,description TEXT DEFAULT '',last_change DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')),min_x DOUBLE, min_y DOUBLE,max_x DOUBLE, max_y DOUBLE,srs_id INTEGER)";
Sqlite3Stmt statament;
statament.prepare( db, "%s", cmd.c_str() );
sqlite3_step( statament.get() );
statament.close();

bool success = register_gpkg_extensions( db );
if ( !success )
{
throw GeoDiffException( "Unable to enable sqlite3/gpkg extensions" );
}

std::string res = onlySummary ? GeoDiffExporter::toJSONSummary( buf ) : GeoDiffExporter::toJSON( db, buf );
GeoDiffExporter exporter;
std::string res = onlySummary ? exporter.toJSONSummary( buf ) : exporter.toJSON( buf );
flushString( jsonfile, res );
return GEODIFF_SUCCESS;
}
Expand Down Expand Up @@ -422,9 +436,12 @@ int GEODIFF_invertChangeset( const char *changeset, const char *changeset_inv )
}
}

int GEODIFF_rebase( const char *base, const char *modified_their, const char *modified )
int GEODIFF_rebase( const char *base,
const char *modified_their,
const char *modified,
const char *conflictfile )
{
if ( !base || !modified || !modified )
if ( !base || !modified || !modified || !conflictfile )
{
Logger::instance().error( "NULL arguments to GEODIFF_rebase" );
return GEODIFF_ERROR;
Expand Down Expand Up @@ -476,7 +493,7 @@ int GEODIFF_rebase( const char *base, const char *modified_their, const char *mo

// 3A) Create all changesets
TmpFile theirs2final( root + "_theirs2final.bin" );
if ( GEODIFF_createRebasedChangeset( base, modified, base2theirs.c_path(), theirs2final.c_path() ) != GEODIFF_SUCCESS )
if ( GEODIFF_createRebasedChangeset( base, modified, base2theirs.c_path(), theirs2final.c_path(), conflictfile ) != GEODIFF_SUCCESS )
{
Logger::instance().error( "Unable to perform GEODIFF_createChangeset theirs2final" );
return GEODIFF_ERROR;
Expand Down
16 changes: 14 additions & 2 deletions geodiff/src/geodiff.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,16 @@ GEODIFF_EXPORT int GEODIFF_invertChangeset( const char *changeset, const char *c
* \param modified [input] MODIFIED sqlite3/geopackage file
* \param changeset_their [input] changeset between BASE -> MODIFIED_THEIR
* \param changeset [output] changeset between MODIFIED_THEIR -> MODIFIED_THEIR_PLUS_MINE
* \param conflictfile [output] json file containing all the automaticly resolved conflicts. If there are no conflicts, file is not created
* \returns GEODIFF_SUCCESS on success
*/
GEODIFF_EXPORT int GEODIFF_createRebasedChangeset(
const char *base,
const char *modified,
const char *changeset_their,
const char *changeset );
const char *changeset,
const char *conflictfile
);


/**
Expand All @@ -167,17 +170,26 @@ GEODIFF_EXPORT int GEODIFF_createRebasedChangeset(
* \param base [input] BASE sqlite3/geopackage file
* \param modified_their [input] MODIFIED sqlite3/geopackage file
* \param modified [input/output] local copy of the changes to be rebased
* \param conflictfile [output] json file containing all the automaticly resolved conflicts. If there are no conflicts, file is not created
* \returns GEODIFF_SUCCESS on success
*/
GEODIFF_EXPORT int GEODIFF_rebase(
const char *base,
const char *modified_their,
const char *modified
const char *modified,
const char *conflictfile
);


/**
* Applies changeset file (binary) to BASE
*
* When changeset is correctly formed (for example after successful rebase),
* the applyChanges should not raise any conflict. The GEODIFF_CONFLICTS error
* suggests that the base or changeset are not matching each other (e.g. changeset
* created from different base file) or can suggest an internal bug in rebase routine.
* With WARN logging level client should be able to see the place of conflicts.
*
* \param base [input/output] BASE sqlite3/geopackage file
* \param changeset [input] changeset to apply to BASE
* \returns GEODIFF_SUCCESS on success
Expand Down
98 changes: 89 additions & 9 deletions geodiff/src/geodiffexporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
#include <iostream>
#include <sstream>

GeoDiffExporter::GeoDiffExporter()
{
mDb = blankGeopackageDb();
}

std::string GeoDiffExporter::toString( sqlite3_changeset_iter *pp )
{
std::ostringstream ret;
Expand Down Expand Up @@ -72,15 +77,15 @@ std::string GeoDiffExporter::toString( sqlite3_changeset_iter *pp )
return ret.str();
}

void _addValue( std::shared_ptr<Sqlite3Db> db, std::string &stream,
sqlite3_value *ppValue, const std::string &type )
void GeoDiffExporter::addValue( std::string &stream,
sqlite3_value *ppValue, const std::string &type ) const
{
std::string val;
if ( ppValue )
{
if ( sqlite3_value_type( ppValue ) == SQLITE_BLOB )
{
val = convertGeometryToWKT( db, ppValue );
val = convertGeometryToWKT( mDb, ppValue );
if ( val.empty() )
val = Sqlite3Value::toString( ppValue );
}
Expand All @@ -101,7 +106,16 @@ void _addValue( std::shared_ptr<Sqlite3Db> db, std::string &stream,
}
}

std::string GeoDiffExporter::toJSON( std::shared_ptr<Sqlite3Db> db, Sqlite3ChangesetIter &pp )
void GeoDiffExporter::addValue( std::string &stream,
std::shared_ptr<Sqlite3Value> value, const std::string &type ) const
{
if ( value )
return addValue( stream, value->value(), type );
else
return addValue( stream, nullptr, type );
}

std::string GeoDiffExporter::toJSON( Sqlite3ChangesetIter &pp ) const
{
if ( !pp.get() )
return std::string();
Expand Down Expand Up @@ -173,9 +187,9 @@ std::string GeoDiffExporter::toJSON( std::shared_ptr<Sqlite3Db> db, Sqlite3Chang
}
res += " \"column\": " + std::to_string( i ) + ",\n";

_addValue( db, res, ppValueOld, "old" );
addValue( res, ppValueOld, "old" );
res += ",\n";
_addValue( db, res, ppValueNew, "new" );
addValue( res, ppValueNew, "new" );
res += "\n";
res += " }";
}
Expand All @@ -187,7 +201,7 @@ std::string GeoDiffExporter::toJSON( std::shared_ptr<Sqlite3Db> db, Sqlite3Chang
return res;
}

std::string GeoDiffExporter::toJSON( std::shared_ptr<Sqlite3Db> db, Buffer &buf )
std::string GeoDiffExporter::toJSON( Buffer &buf ) const
{
std::string res = "{\n \"geodiff\": [";

Expand All @@ -196,7 +210,7 @@ std::string GeoDiffExporter::toJSON( std::shared_ptr<Sqlite3Db> db, Buffer &buf
bool first = true;
while ( SQLITE_ROW == sqlite3changeset_next( pp.get() ) )
{
std::string msg = GeoDiffExporter::toJSON( db, pp );
std::string msg = GeoDiffExporter::toJSON( pp );
if ( msg.empty() )
continue;

Expand Down Expand Up @@ -225,7 +239,7 @@ struct TableSummary
int deletes;
};

std::string GeoDiffExporter::toJSONSummary( Buffer &buf )
std::string GeoDiffExporter::toJSONSummary( Buffer &buf ) const
{
std::map< std::string, TableSummary > summary;

Expand Down Expand Up @@ -288,3 +302,69 @@ std::string GeoDiffExporter::toJSONSummary( Buffer &buf )
res += "}";
return res;
}

std::string GeoDiffExporter::toJSON( const ConflictFeature &conflict ) const
{
std::string status = "conflict";

std::string res = " {\n";
res += " \"table\": \"" + std::string( conflict.tableName() ) + "\",\n";
res += " \"type\": \"" + status + "\",\n";
res += " \"fid\": \"" + std::to_string( conflict.pk() ) + "\",\n";
res += " \"changes\": [";
bool first = true;

const std::vector<ConflictItem> items = conflict.items();
for ( const ConflictItem &item : items )
{
if ( first )
{
first = false;
res += "\n {\n";
}
else
{
res += ",\n {\n";
}
res += " \"column\": " + std::to_string( item.column() ) + ",\n";
addValue( res, item.base(), "base" );
res += ",\n";
addValue( res, item.theirs(), "old" );
res += ",\n";
addValue( res, item.ours(), "new" );
res += "\n";
res += " }";

}
// close brackets
res += "\n ]\n"; // end properties
res += " }"; // end feature
return res;
}

std::string GeoDiffExporter::toJSON( const std::vector<ConflictFeature> &conflicts ) const
{
std::string res = "{\n \"geodiff\": [";

bool first = true;
for ( const ConflictFeature &item : conflicts )
{
std::string msg = GeoDiffExporter::toJSON( item );
if ( msg.empty() )
continue;

if ( first )
{
res += "\n" + msg;
first = false;
}
else
{
res += ",\n" + msg;
}
}

res += "\n ]\n";
res += "}";
return res;
}
26 changes: 20 additions & 6 deletions geodiff/src/geodiffexporter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,27 @@
#include "sqlite3.h"
#include "geodiffutils.hpp"

namespace GeoDiffExporter
class GeoDiffExporter
{
std::string toString( sqlite3_changeset_iter *pp );
std::string toJSON( std::shared_ptr<Sqlite3Db> db, Buffer &buf );
std::string toJSON( std::shared_ptr<Sqlite3Db> db, Sqlite3ChangesetIter &pp );
public:
GeoDiffExporter();

std::string toJSONSummary( Buffer &buf );
}
static std::string toString( sqlite3_changeset_iter *pp );

std::string toJSON( Buffer &buf ) const;
std::string toJSON( Sqlite3ChangesetIter &pp ) const;
std::string toJSON( const ConflictFeature &conflict ) const;
std::string toJSON( const std::vector<ConflictFeature> &conflicts ) const;
std::string toJSONSummary( Buffer &buf ) const;

private:
void addValue( std::string &stream,
std::shared_ptr<Sqlite3Value> value, const std::string &type ) const;

void addValue( std::string &stream,
sqlite3_value *ppValue, const std::string &type ) const;

std::shared_ptr<Sqlite3Db> mDb; // to be able to run ST_* functions
};

#endif // GEODIFFEXPORTER_H
6 changes: 3 additions & 3 deletions geodiff/src/geodiffinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ void help()
printf( "by default you get only errors printed to stdout\n\n" );
printf( "[version info] geodiffinfo version\n" );
printf( "[create changeset] geodiffinfo createChangeset base modified changeset\n" );
printf( "[create rebased changeset] geodiffinfo createRebasedChangeset base modified changeset_their changeset\n" );
printf( "[create rebased changeset] geodiffinfo createRebasedChangeset base modified changeset_their changeset conflict\n" );
printf( "[apply changeset] geodiffinfo applyChangeset base changeset\n" );
printf( "[list changes (JSON) in changeset] geodiffinfo listChanges changeset json\n" );
printf( "[list summary of changes (JSON) in changeset] geodiffinfo listChangesSummary changeset json\n" );
Expand All @@ -44,12 +44,12 @@ int createChangeset( int argc, char *argv[] )

int createRebasedChangeset( int argc, char *argv[] )
{
if ( argc < 1 + 5 )
if ( argc < 1 + 6 )
{
return err( "invalid number of arguments to createRebasedChangeset" );
}

int ret = GEODIFF_createRebasedChangeset( argv[2], argv[3], argv[4], argv[5] );
int ret = GEODIFF_createRebasedChangeset( argv[2], argv[3], argv[4], argv[5], argv[6] );
return ret;
}

Expand Down
Loading

0 comments on commit 5488195

Please sign in to comment.