00001
00002
00003 #include <string>
00004 #include <ept/token.h>
00005 #include <ept/core/apt.h>
00006 #include <apt-pkg/algorithms.h>
00007
00008 #ifndef EPT_APT_ACTION_H
00009 #define EPT_APT_ACTION_H
00010
00011 namespace ept {
00012 namespace core {
00013 namespace package {
00014
00015 struct Action {
00016 enum Type { Install, ReInstall, Remove, Keep, Purge, SystemUpgrade };
00017 Token m_token;
00018 Type m_type;
00019
00020 Token token() { return m_token; }
00021 Type type() { return m_type; }
00022
00023 void apply( package::Source &pkgs )
00024 {
00025 Type a = m_type;
00026 pkgDepCache &dc = pkgs.db().state();
00027
00028 if ( a == SystemUpgrade ) {
00029 pkgDistUpgrade( dc );
00030 } else {
00031 if ( !pkgs.exists( m_token ) )
00032 return;
00033 pkgCache::PkgIterator p = pkgs.lookupToken( m_token );
00034
00035 pkgProblemResolver fix( &dc );
00036 if ( a == Install || a == ReInstall ) {
00037 fix.Clear( p );
00038 fix.Protect( p );
00039 dc.MarkInstall( p, true );
00040 fix.InstallProtect();
00041 if ( a == ReInstall )
00042 dc.SetReInstall( p, true );
00043 } else if ( a == Remove || a == Purge ) {
00044 fix.Clear( p );
00045 fix.Protect( p );
00046 fix.Remove( p );
00047 dc.MarkDelete( p, a == Purge ? true : false );
00048 } else if ( a == Keep ) {
00049 fix.Clear( p );
00050 fix.Protect( p );
00051 dc.MarkKeep( p, true );
00052 }
00053 fix.Resolve( true );
00054 }
00055 }
00056
00057 bool redundant( package::Source &pkgs ) {
00058 if ( m_type == SystemUpgrade ) {
00059
00060 return false;
00061 }
00062 if ( !pkgs.exists( m_token ) )
00063 return true;
00064 PackageState s = pkgs.db().packageState( m_token );
00065 Type a = m_type;
00066
00067
00068 if ( ( a == Install || a == ReInstall )
00069 && ( !s.upgradable() && s.installed() ) )
00070 return true;
00071 if ( ( a == Remove || a == Purge ) && !s.installed() )
00072 return true;
00073 return false;
00074 }
00075
00076 Action( Token t, Type a )
00077 : m_token( t ), m_type( a )
00078 {}
00079 };
00080
00081 struct ActionList {
00082 typedef std::vector< Action > List;
00083 List m_list;
00084
00085 void clear() {
00086 m_list.clear();
00087 }
00088
00089 bool empty() {
00090 return m_list.empty();
00091 }
00092
00093 void add( Action a ) {
00094 List::iterator rm = m_list.end(), i;
00095 for ( i = m_list.begin(); i != m_list.end(); ++i ) {
00096 if ( i->token() == a.token() ) {
00097 rm = i;
00098 break;
00099 }
00100 }
00101 if ( rm != m_list.end() )
00102 m_list.erase( rm );
00103
00104 m_list.push_back( a );
00105 }
00106
00107 Action latest() {
00108 return m_list.back();
00109 }
00110
00111 void replay( package::Source &pkgs ) {
00112 for ( List::iterator i = m_list.begin(); i != m_list.end(); ++i ) {
00113 i->apply( pkgs );
00114 }
00115 }
00116
00117 void prune( package::Source &pkgs ) {
00118 List l;
00119 std::swap( l, m_list );
00120 for ( List::iterator i = m_list.begin(); i != m_list.end(); ++i ) {
00121 if ( !i->redundant( pkgs ) )
00122 m_list.push_back( *i );
00123 }
00124
00125
00126
00127
00128 }
00129 };
00130
00131 }
00132 }
00133 }
00134
00135 #endif