Skip to content

Commit

Permalink
small refactoring to avoid memory leaks
Browse files Browse the repository at this point in the history
  • Loading branch information
PeterPetrik committed Jul 10, 2019
1 parent 0481bf5 commit e9b373b
Show file tree
Hide file tree
Showing 5 changed files with 321 additions and 181 deletions.
179 changes: 68 additions & 111 deletions geodiff/src/geodiff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,71 +32,57 @@ void GEODIFF_init()

int GEODIFF_createChangeset( const char *base, const char *modified, const char *changeset )
{
try
if ( !base || !modified || !changeset )
{
Buffer sqlBuf;

sqlite3 *db;
sqlite3_session *session;
int rc;
sqlite3_stmt *pStmt;
Logger::instance().error( "NULL arguments to GEODIFF_createChangeset" );
return GEODIFF_ERROR;
}

printf( "%s\n%s\n%s\n", modified, base, changeset );
if ( !fileexists( base ) || !fileexists( modified ) )
{
Logger::instance().error( "Missing input files in GEODIFF_createChangeset" );
return GEODIFF_ERROR;
}

rc = sqlite3_open( modified, &db );
if ( rc )
{
Logger::instance().error( "err diff 1" );
return GEODIFF_ERROR;
}
try
{
std::shared_ptr<Sqlite3Db> db = std::make_shared<Sqlite3Db>();
db->open( modified );

Buffer sqlBuf;
sqlBuf.printf( "ATTACH '%s' AS aux", base );
rc = sqlite3_exec( db, sqlBuf.c_buf(), NULL, 0, NULL );
if ( rc )
{
printf( "err diff 2" );
return GEODIFF_ERROR;
}
db->exec( sqlBuf );

rc = sqlite3session_create( db, "main", &session );
if ( rc )
{
printf( "err diff 3" );
return GEODIFF_ERROR;
}
Sqlite3Session session;
session.create( db, "main" );

pStmt = db_prepare( db, "%s", all_tables_sql() );
while ( SQLITE_ROW == sqlite3_step( pStmt ) )
Sqlite3Stmt statament;
statament.prepare( db, "%s", all_tables_sql() );
while ( SQLITE_ROW == sqlite3_step( statament.get() ) )
{
rc = sqlite3session_attach( session, ( const char * )sqlite3_column_text( pStmt, 0 ) );
int rc = sqlite3session_attach( session.get(), ( const char * )sqlite3_column_text( statament.get(), 0 ) );
if ( rc )
{
printf( "err diff 4" );
Logger::instance().error( "Unable to attach session to database in GEODIFF_createChangeset" );
return GEODIFF_ERROR;
}
rc = sqlite3session_diff( session, "aux", ( const char * )sqlite3_column_text( pStmt, 0 ), NULL );
rc = sqlite3session_diff( session.get(), "aux", ( const char * )sqlite3_column_text( statament.get(), 0 ), NULL );
if ( rc )
{
printf( "err diff 5" );
Logger::instance().error( "Unable to diff tables in GEODIFF_createChangeset" );
return GEODIFF_ERROR;
}
}
sqlite3_finalize( pStmt );

/* Create a changeset */
Buffer changesetBuf;
changesetBuf.read(session);
changesetBuf.read( session );
changesetBuf.write( changeset );

sqlite3session_delete( session );
sqlite3_close( db );

return GEODIFF_SUCCESS;

}
catch ( GeoDiffException exc )
{
printf( "%s\n", exc.what() );
Logger::instance().error( exc );
return GEODIFF_ERROR;
}
}
Expand All @@ -107,103 +93,94 @@ static int conflict_callback( void *ctx, int conflict, sqlite3_changeset_iter *i
{
nconflicts++;
std::string s = conflict2Str( conflict );
printf( "CONFLICT! %s ", s.c_str() );
Logger::instance().warn( "CONFLICT: " + s );
changesetIter2Str( iterator );
return SQLITE_CHANGESET_REPLACE;
}

int GEODIFF_applyChangeset( const char *base, const char *patched, const char *changeset )
{
try
if ( !base || !patched || !changeset )
{
Logger::instance().error( "NULL arguments to GEODIFF_applyChangeset" );
return GEODIFF_ERROR;
}

if ( !fileexists( base ) || !fileexists( changeset ) )
{
Logger::instance().error( "Missing input files in GEODIFF_applyChangeset" );
return GEODIFF_ERROR;
}

try
{
// static variable... how ugly!!!
nconflicts = 0;

sqlite3 *db;
int rc;
sqlite3_stmt *pStmt;
char *name;
char *sql;

// TODO consider using sqlite3changeset_apply_strm streamed versions
// make a copy
filecopy( patched, base );

// read to memory
// read changeset to buffer
Buffer cbuf;
cbuf.read( changeset );
if ( cbuf.isEmpty() )
{
printf( "--- no changes ---" );
Logger::instance().info( "--- no changes ---" );
return GEODIFF_SUCCESS;
}

rc = sqlite3_open( patched, &db );
if ( rc )
{
printf( "err sqlite3_open" );
return GEODIFF_ERROR;
}
std::shared_ptr<Sqlite3Db> db = std::make_shared<Sqlite3Db>();
db->open( patched );

// get all triggers sql commands
std::vector<std::string> triggerNames;
std::vector<std::string> triggerCmds;

pStmt = db_prepare( db, "%s", "select name, sql from sqlite_master where type = 'trigger'" );
while ( SQLITE_ROW == sqlite3_step( pStmt ) )
Sqlite3Stmt statament;
statament.prepare( db, "%s", "select name, sql from sqlite_master where type = 'trigger'" );
while ( SQLITE_ROW == sqlite3_step( statament.get() ) )
{
name = ( char * ) sqlite3_column_text( pStmt, 0 );
// printf("%s", name);
sql = ( char * ) sqlite3_column_text( pStmt, 1 );
char *name = ( char * ) sqlite3_column_text( statament.get(), 0 );
char *sql = ( char * ) sqlite3_column_text( statament.get(), 1 );
triggerNames.push_back( name );
triggerCmds.push_back( sql );
}
sqlite3_finalize( pStmt );
statament.close();

for ( std::string name : triggerNames )
{
pStmt = db_prepare( db, "drop trigger %s", name.c_str() );
sqlite3_step( pStmt );
sqlite3_finalize( pStmt );
statament.prepare( db, "drop trigger %s", name.c_str() );
sqlite3_step( statament.get() );
statament.close();
}

// error: no such function: ST_IsEmpty otherwise
// https://gis.stackexchange.com/q/294626/59405
// rc = sqlite3_enable_load_extension(db, 1);
// if(rc) RUNTIME_ERROR("sql error 2");

// rc = sqlite3_load_extension(db, "mod_spatialite.so", NULL, NULL);
// if(rc) RUNTIME_ERROR("sql error 3");

// TODO use _v2 and data-> for rebaser!
rc = sqlite3changeset_apply( db, cbuf.size(), cbuf.v_buf(), NULL, conflict_callback, NULL );
// apply changeset
int rc = sqlite3changeset_apply( db->get(), cbuf.size(), cbuf.v_buf(), NULL, conflict_callback, NULL );
if ( rc )
{
printf( "err sqlite3changeset_apply" );
Logger::instance().error( "Unable to perform sqlite3changeset_apply" );
return GEODIFF_ERROR;
}

// recreate triggers
for ( std::string cmd : triggerCmds )
{
pStmt = db_prepare( db, "%s", cmd.c_str() );
sqlite3_step( pStmt );
sqlite3_finalize( pStmt );
statament.prepare( db, "%s", cmd.c_str() );
sqlite3_step( statament.get() );
statament.close();
}

sqlite3_close( db );

if ( nconflicts > 0 )
{
printf( "NConflicts %d found ", nconflicts );
Logger::instance().warn( "NConflicts " + std::to_string( nconflicts ) + " found " );
return GEODIFF_CONFICTS;
}
return GEODIFF_SUCCESS;

}
catch ( GeoDiffException exc )
{
printf( "%s\n", exc.what() );
Logger::instance().error( exc );
return GEODIFF_ERROR;
}
}
Expand All @@ -212,65 +189,45 @@ int GEODIFF_listChanges( const char *changeset )
{
try
{
int rc;
sqlite3_changeset_iter *pp;
int nchanges = 0;

printf( "CHANGES:\n" );

Buffer buf;
buf.read( changeset );
if ( buf.isEmpty() )
{
printf( "--- no changes ---" );
Logger::instance().info( "--- no changes ---" );
return GEODIFF_SUCCESS;
}

rc = sqlite3changeset_start(
&pp,
buf.size(),
buf.v_buf()
);
if ( rc != SQLITE_OK )
Sqlite3ChangesetIter pp;
pp.start( buf );
while ( SQLITE_ROW == sqlite3changeset_next( pp.get() ) )
{
printf( "sqlite3changeset_start error %d\n", rc );
return -1;
}

while ( SQLITE_ROW == sqlite3changeset_next( pp ) )
{
changesetIter2Str( pp );
changesetIter2Str( pp.get() );
nchanges = nchanges + 1 ;
}

sqlite3changeset_finalize( pp );
return nchanges;

}
catch ( GeoDiffException exc )
{
printf( "%s\n", exc.what() );
Logger::instance().error( exc );
return -1;
}
}


int GEODIFF_createRebasedChangeset( const char *base, const char *modified, const char *changeset_their, const char *changeset )
{
try
{

std::string changeset_BASE_MODIFIED = std::string( changeset ) + "_BASE_MODIFIED";
int rc = GEODIFF_createChangeset( base, modified, changeset_BASE_MODIFIED.c_str() );
if ( rc != GEODIFF_SUCCESS )
return rc;

return rebase( changeset_their, changeset, changeset_BASE_MODIFIED );

}
catch ( GeoDiffException exc )
{
printf( "%s\n", exc.what() );
Logger::instance().error( exc );
return GEODIFF_ERROR;
}
}
5 changes: 2 additions & 3 deletions geodiff/src/geodiffrebase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,7 @@ int rebase( const std::string &changeset_BASE_THEIRS,
buf_BASE_THEIRS.read( changeset_BASE_THEIRS );
if ( buf_BASE_THEIRS.isEmpty() )
{
printf( " -- no rabase needed! --\n" );
Logger::instance().info( " -- no rabase needed! --\n" );
filecopy( changeset_BASE_MODIFIED, changeset_THEIRS_MODIFIED );
return GEODIFF_SUCCESS;
}
Expand All @@ -709,7 +709,7 @@ int rebase( const std::string &changeset_BASE_THEIRS,
buf_BASE_MODIFIED.read( changeset_BASE_MODIFIED );
if ( buf_BASE_MODIFIED.isEmpty() )
{
printf( " -- no rabase needed! --\n" );
Logger::instance().info( " -- no rabase needed! --\n" );
filecopy( changeset_BASE_THEIRS, changeset_THEIRS_MODIFIED );
return GEODIFF_SUCCESS;
}
Expand All @@ -722,7 +722,6 @@ int rebase( const std::string &changeset_BASE_THEIRS,
MappingIds mapping;
_find_mapping_for_new_changeset( buf_BASE_MODIFIED, inserted, deleted, mapping );

// finally
_prepare_new_changeset( buf_BASE_MODIFIED, changeset_THEIRS_MODIFIED, mapping, updated );

return GEODIFF_SUCCESS;
Expand Down

0 comments on commit e9b373b

Please sign in to comment.