should be able to detect new and deleted files correctly now

pull/40/head
Matchman Green 2012-05-31 01:17:22 +08:00
parent 8b1b388713
commit 7e5b7e0b7d
5 changed files with 60 additions and 65 deletions

View File

@ -102,13 +102,32 @@ Resource::Resource( const fs::path& path ) :
/// Update the state according to information (i.e. Entry) from remote. This function
/// compares the modification time and checksum of both copies and determine which
/// one is newer.
void Resource::FromRemote( const Entry& remote )
void Resource::FromRemote( const Entry& remote, const DateTime& last_sync )
{
// sync folder is easy
fs::path path = Path() ;
// sync folder
if ( remote.Kind() == "folder" && IsFolder() )
{
Log( "folder %1% is in sync", Name(), log::verbose ) ;
m_state = sync ;
// already sync
if ( fs::is_directory( path ) )
{
Log( "folder %1% is in sync", path, log::verbose ) ;
m_state = sync ;
}
// remote file created after last sync, so remote is newer
else if ( remote.MTime() > last_sync )
{
Log( "creating %1% directory", path, log::info ) ;
fs::create_directories( path ) ;
m_state = sync ;
}
else
{
Trace( "should I delete the local directory %1%?", path ) ;
m_state = local_deleted ;
}
}
// if checksum is equal, no need to compare the mtime
@ -118,17 +137,32 @@ void Resource::FromRemote( const Entry& remote )
m_state = sync ;
}
// local not exists
else if ( !fs::exists( path ) )
{
if ( remote.MTime() > last_sync )
{
Trace( "new file found in remote", path ) ;
m_state = remote_new ;
}
else
{
Trace( "should I delete the local file %1%?", path ) ;
m_state = local_deleted ;
}
}
// use mtime to check which one is more recent
else
{
assert( m_state == local_new || m_state == local_changed || m_state == local_deleted ) ;
assert( m_state == local_new || m_state == local_changed || m_state == remote_deleted ) ;
// if remote is modified
if ( remote.MTime() > m_entry.MTime() )
m_state = remote_changed ;
// remote also has the file, so it's not new in local
else if ( m_state == local_new || m_state == local_deleted )
else if ( m_state == local_new || m_state == remote_deleted )
m_state = local_changed ;
Log( "%1% state is %2%", Name(), m_state, log::verbose ) ;
@ -150,9 +184,11 @@ void Resource::FromLocal( const DateTime& last_sync )
else
{
// assume file is local_deleted?? very strange. change it tomorrow
// if the file is not created after last sync, assume file is
// remote_deleted first, it will be updated to sync/remote_changed
// in FromRemote()
DateTime mtime = os::FileMTime( path ) ;
m_state = ( mtime > last_sync ? local_new : local_deleted ) ;
m_state = ( mtime > last_sync ? local_new : remote_deleted ) ;
Log( "%1% found on disk: %2%", Name(), m_state ) ;
}
@ -275,6 +311,10 @@ void Resource::Sync( http::Agent *http, const http::Headers& auth )
m_state = sync ;
break ;
case remote_deleted :
Log( "sync %1% deleted in remote. delete?", Path(), log::verbose ) ;
break ;
case sync :
Log( "sync %1% already in sync", Path(), log::verbose ) ;
break ;
@ -448,7 +488,8 @@ std::ostream& operator<<( std::ostream& os, Resource::State s )
{
static const char *state[] =
{
"sync", "local_new", "local_changed", "local_deleted", "remote_new", "remote_changed"
"sync", "local_new", "local_changed", "local_deleted", "remote_new",
"remote_changed", "remote_deleted"
} ;
assert( s >= 0 && s < Count(state) ) ;
return os << state[s] ;

View File

@ -71,7 +71,7 @@ public :
bool IsInRootTree() const ;
bool IsRoot() const ;
void FromRemote( const Entry& e ) ;
void FromRemote( const Entry& remote, const DateTime& last_sync ) ;
void FromLocal( const DateTime& last_sync ) ;
void Sync( http::Agent *http, const http::Headers& auth ) ;

View File

@ -160,11 +160,11 @@ void ResourceTree::Erase( Resource *coll )
s.erase( s.find( coll ) ) ;
}
void ResourceTree::Update( Resource *coll, const Entry& e )
void ResourceTree::Update( Resource *coll, const Entry& e, const DateTime& last_sync )
{
assert( coll != 0 ) ;
coll->FromRemote( e ) ;
coll->FromRemote( e, last_sync ) ;
ReInsert( coll ) ;
}
@ -177,33 +177,5 @@ ResourceTree::iterator ResourceTree::end()
{
return m_set.get<ByIdentity>().end() ;
}
/*
void ResourceTree::Read( const Json& json )
{
Clear() ;
assert( m_root == 0 ) ;
m_root = new Resource ;
AddTree( m_root, json ) ;
}
void ResourceTree::AddTree( Resource *node, const Json& json )
{
assert( node != 0 ) ;
m_set.insert( node ) ;
std::vector<Json> array = json["child"].AsArray() ;
for ( std::vector<Json>::iterator i = array.begin() ; i != array.end() ; ++i )
{
Resource *c = new Resource( *i, node ) ;
node->AddChild( c ) ;
AddTree( c, *i ) ;
}
}
Json ResourceTree::Serialize() const
{
return m_root->Serialize() ;
}
*/
} // end of namespace

View File

@ -81,7 +81,7 @@ public :
void Insert( Resource *coll ) ;
void Erase( Resource *coll ) ;
void Update( Resource *coll, const Entry& e ) ;
void Update( Resource *coll, const Entry& e, const DateTime& last_sync ) ;
Resource* Root() ;
const Resource* Root() const ;
@ -89,12 +89,8 @@ public :
iterator begin() ;
iterator end() ;
// void Read( const Json& json ) ;
// Json Serialize() const ;
private :
void Clear() ;
// void AddTree( Resource *node, const Json& json ) ;
private :
details::Folders m_set ;

View File

@ -128,7 +128,7 @@ bool State::Update( const Entry& e )
if ( Resource *res = m_res.FindByHref( e.SelfHref() ) )
{
m_res.Update( res, e ) ;
m_res.Update( res, e, m_last_sync ) ;
return true ;
}
else if ( Resource *parent = m_res.FindByHref( e.ParentHref() ) )
@ -141,31 +141,17 @@ bool State::Update( const Entry& e )
if ( child != 0 )
{
// since we are updating the ID and Href, we need to remove it and re-add it.
m_res.Update( child, e ) ;
m_res.Update( child, e, m_last_sync ) ;
}
// folder entry exist in google drive, but not local. we should create
// the directory
else if ( e.Kind() == "folder" || !e.Filename().empty() )
{
// TODO: compare the last sync time to determine which one is newer
if ( e.MTime() > m_last_sync )
{
child = new Resource( e ) ;
parent->AddChild( child ) ;
m_res.Insert( child ) ;
fs::path child_path = child->Path() ;
if ( child->IsFolder() && !fs::is_directory( child_path ) )
{
Log( "creating %1% directory", child_path, log::info ) ;
fs::create_directories( child_path ) ;
}
}
else
{
Trace( "should I delete the local %1%/%2%", parent->Path(), e.Filename() ) ;
}
child = new Resource( e ) ;
parent->AddChild( child ) ;
m_res.Insert( child ) ;
m_res.Update( child, e, m_last_sync ) ;
}
else
{