Imported Upstream version 17.23.0
[platform/upstream/libzypp.git] / zypp / HistoryLogData.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9
10 /** \file zypp/HistoryLogData.cc
11  *
12  */
13 #include <sstream>
14
15 #include "zypp/base/PtrTypes.h"
16 #include "zypp/base/String.h"
17 #include "zypp/base/Logger.h"
18 #include "zypp/parser/ParseException.h"
19
20 #include "zypp/HistoryLogData.h"
21
22 using namespace std;
23
24 ///////////////////////////////////////////////////////////////////
25 namespace zypp
26 {
27   using parser::ParseException;
28
29   ///////////////////////////////////////////////////////////////////
30   //
31   //    class HistoryActionID
32   //
33   ///////////////////////////////////////////////////////////////////
34
35   const HistoryActionID HistoryActionID::NONE                   (HistoryActionID::NONE_e);
36   const HistoryActionID HistoryActionID::INSTALL                (HistoryActionID::INSTALL_e);
37   const HistoryActionID HistoryActionID::REMOVE                 (HistoryActionID::REMOVE_e);
38   const HistoryActionID HistoryActionID::REPO_ADD               (HistoryActionID::REPO_ADD_e);
39   const HistoryActionID HistoryActionID::REPO_REMOVE            (HistoryActionID::REPO_REMOVE_e);
40   const HistoryActionID HistoryActionID::REPO_CHANGE_ALIAS      (HistoryActionID::REPO_CHANGE_ALIAS_e);
41   const HistoryActionID HistoryActionID::REPO_CHANGE_URL        (HistoryActionID::REPO_CHANGE_URL_e);
42   const HistoryActionID HistoryActionID::STAMP_COMMAND          (HistoryActionID::STAMP_COMMAND_e);
43   const HistoryActionID HistoryActionID::PATCH_STATE_CHANGE     (HistoryActionID::PATCH_STATE_CHANGE_e);
44
45   HistoryActionID::HistoryActionID(const std::string & strval_r)
46     : _id(parse(strval_r))
47   {}
48
49   HistoryActionID::ID HistoryActionID::parse( const std::string & strval_r )
50   {
51     typedef std::map<std::string,ID> MapType;
52     static MapType _table;
53     if ( _table.empty() )
54     {
55       // initialize it
56       _table["install"] = INSTALL_e;
57       _table["remove"]  = REMOVE_e;
58       _table["radd"]    = REPO_ADD_e;
59       _table["rremove"] = REPO_REMOVE_e;
60       _table["ralias"]  = REPO_CHANGE_ALIAS_e;
61       _table["rurl"]    = REPO_CHANGE_URL_e;
62       _table["command"] = STAMP_COMMAND_e;
63       _table["patch"]   = PATCH_STATE_CHANGE_e;
64       _table["NONE"]    = _table["none"] = NONE_e;
65     }
66
67     MapType::const_iterator it = _table.find( strval_r );
68     if ( it != _table.end() )
69       return it->second;
70     // else:
71     WAR << "Unknown history action ID '" + strval_r + "'" << endl;
72     return NONE_e;
73   }
74
75
76   const std::string & HistoryActionID::asString( bool pad ) const
77   {
78     typedef std::pair<std::string,std::string> PairType;
79     typedef std::map<ID, PairType> MapType;
80     static MapType _table;
81     if ( _table.empty() )
82     {
83       // initialize it                                     pad(7) (for now)
84       _table[INSTALL_e]           = PairType( "install" , "install" );
85       _table[REMOVE_e]            = PairType( "remove"  , "remove " );
86       _table[REPO_ADD_e]          = PairType( "radd"    , "radd   " );
87       _table[REPO_REMOVE_e]       = PairType( "rremove" , "rremove" );
88       _table[REPO_CHANGE_ALIAS_e] = PairType( "ralias"  , "ralias " );
89       _table[REPO_CHANGE_URL_e]   = PairType( "rurl"    , "rurl   " );
90       _table[STAMP_COMMAND_e]     = PairType( "command" , "command" );
91       _table[PATCH_STATE_CHANGE_e]= PairType( "patch"   , "patch  " );
92       _table[NONE_e]              = PairType( "NONE"    , "NONE   " );
93     }
94
95     return( pad ? _table[_id].second : _table[_id].first );
96   }
97
98   std::ostream & operator << (std::ostream & str, const HistoryActionID & id)
99   { return str << id.asString(); }
100
101   ///////////////////////////////////////////////////////////////////
102
103   ///////////////////////////////////////////////////////////////////
104   //
105   //    class HistoryLogData::Impl
106   //
107   ///////////////////////////////////////////////////////////////////
108   class HistoryLogData::Impl
109   {
110   public:
111     Impl( FieldVector & fields_r, size_type expect_r )
112     {
113       _checkFields( fields_r, expect_r );
114       _field.swap( fields_r );
115       // For whatever reason writer is ' '-padding the action field
116       // but we don't want to modify the vector before we moved it.
117       _field[ACTION_INDEX] = str::trim( _field[ACTION_INDEX] );
118       _action = HistoryActionID( _field[ACTION_INDEX] );
119     }
120
121     Impl( FieldVector & fields_r, HistoryActionID action_r, size_type expect_r )
122     {
123       _checkFields( fields_r, expect_r );
124       // For whatever reason writer is ' '-padding the action field
125       // but we don't want to modify the vector before we moved it.
126       std::string trimmed( str::trim( fields_r[ACTION_INDEX] ) );
127       _action = HistoryActionID( trimmed );
128       if ( _action != action_r )
129       {
130         ZYPP_THROW( ParseException( str::form( "Bad action id. Got %s, expected %s.",
131                                                _action.asString().c_str(),
132                                                action_r.asString().c_str() ) ) );
133       }
134       _field.swap( fields_r );
135       // now adjust action field:
136       _field[ACTION_INDEX] = trimmed;
137     }
138
139     void _checkFields( const FieldVector & fields_r, size_type expect_r )
140     {
141       if ( expect_r < 2 )       // at least 2 fields (date and action) are required
142         expect_r = 2;
143       if ( fields_r.size() < expect_r )
144       {
145         ZYPP_THROW( ParseException( str::form( "Bad number of fields. Got %zd, expected at least %zd.",
146                                                fields_r.size(),
147                                                expect_r ) ) );
148       }
149       try
150       {
151         _date = Date( fields_r[DATE_INDEX], HISTORY_LOG_DATE_FORMAT );
152       }
153       catch ( const std::exception & excpt )
154       {
155         ZYPP_THROW( ParseException( excpt.what() ) );   // invalid date format
156       }
157       // _action handled later
158     }
159
160   public:
161     FieldVector         _field;
162     Date                _date;
163     HistoryActionID     _action;
164   };
165
166   ///////////////////////////////////////////////////////////////////
167   //
168   //    class HistoryLogData
169   //
170   ///////////////////////////////////////////////////////////////////
171
172   HistoryLogData::HistoryLogData( FieldVector & fields_r, size_type expect_r )
173   : _pimpl( new Impl( fields_r, expect_r ) )
174   {}
175
176   HistoryLogData::HistoryLogData( FieldVector & fields_r, HistoryActionID expectedId_r, size_type expect_r )
177   : _pimpl( new Impl( fields_r, expectedId_r, expect_r ) )
178   {}
179
180   HistoryLogData::~HistoryLogData()
181   {}
182
183   HistoryLogData::Ptr HistoryLogData::create( FieldVector & fields_r )
184   {
185     if ( fields_r.size() >= 2 )
186     {
187       // str::trim( _field[ACTION_INDEX] );
188       switch ( HistoryActionID( str::trim( fields_r[ACTION_INDEX] ) ).toEnum() )
189       {
190 #define OUTS(E,T) case HistoryActionID::E: return Ptr( new T( fields_r ) ); break;
191         OUTS( INSTALL_e,                HistoryLogDataInstall );
192         OUTS( REMOVE_e,                 HistoryLogDataRemove );
193         OUTS( REPO_ADD_e,               HistoryLogDataRepoAdd );
194         OUTS( REPO_REMOVE_e,            HistoryLogDataRepoRemove );
195         OUTS( REPO_CHANGE_ALIAS_e,      HistoryLogDataRepoAliasChange );
196         OUTS( REPO_CHANGE_URL_e,        HistoryLogDataRepoUrlChange );
197         OUTS( STAMP_COMMAND_e,          HistoryLogDataStampCommand );
198         OUTS( PATCH_STATE_CHANGE_e,     HistoryLogPatchStateChange );
199 #undef OUTS
200         // intentionally no default:
201         case HistoryActionID::NONE_e:
202           break;
203       }
204     }
205     // unknown action or invalid fields? Ctor will accept or throw.
206     return Ptr( new HistoryLogData( fields_r ) );
207   }
208
209   bool HistoryLogData::empty() const
210   { return _pimpl->_field.empty(); }
211
212   HistoryLogData::size_type HistoryLogData::size() const
213   { return _pimpl->_field.size(); }
214
215   HistoryLogData::const_iterator HistoryLogData::begin() const
216   { return _pimpl->_field.begin(); }
217
218   HistoryLogData::const_iterator HistoryLogData::end() const
219   { return _pimpl->_field.end(); }
220
221   const std::string & HistoryLogData::optionalAt( size_type idx_r ) const
222   {
223     static const std::string _empty;
224     return( idx_r < size() ? _pimpl->_field[idx_r] : _empty );
225   }
226
227   const std::string & HistoryLogData::at( size_type idx_r ) const
228   { return _pimpl->_field.at( idx_r ); }
229
230
231   Date HistoryLogData::date() const
232   { return _pimpl->_date; }
233
234   HistoryActionID HistoryLogData::action() const
235   { return _pimpl->_action; }
236
237
238   std::ostream & operator<<( std::ostream & str, const HistoryLogData & obj )
239   { return str << str::joinEscaped( obj.begin(), obj.end(), '|' ); }
240
241   ///////////////////////////////////////////////////////////////////
242   //    class HistoryLogDataInstall
243   ///////////////////////////////////////////////////////////////////
244     HistoryLogDataInstall::HistoryLogDataInstall( FieldVector & fields_r )
245     : HistoryLogData( fields_r )
246     {}
247     std::string HistoryLogDataInstall::name()           const { return optionalAt( NAME_INDEX ); }
248     Edition     HistoryLogDataInstall::edition()        const { return Edition( optionalAt( EDITION_INDEX ) ); }
249     Arch        HistoryLogDataInstall::arch()           const { return Arch( optionalAt( ARCH_INDEX ) ); }
250     std::string HistoryLogDataInstall::reqby()          const { return optionalAt( REQBY_INDEX ); }
251     std::string HistoryLogDataInstall::repoAlias()      const { return optionalAt( REPOALIAS_INDEX ); }
252     CheckSum    HistoryLogDataInstall::checksum()       const { return optionalAt( CHEKSUM_INDEX ); }
253     std::string HistoryLogDataInstall::userdata()       const { return optionalAt( USERDATA_INDEX ); }
254
255     ///////////////////////////////////////////////////////////////////
256     //  class HistoryLogPatchStateChange
257     ///////////////////////////////////////////////////////////////////
258     HistoryLogPatchStateChange::HistoryLogPatchStateChange( FieldVector & fields_r )
259       : HistoryLogData( fields_r )
260     {}
261     std::string HistoryLogPatchStateChange::name()      const { return optionalAt( NAME_INDEX ); }
262     Edition     HistoryLogPatchStateChange::edition()   const { return Edition( optionalAt( EDITION_INDEX ) ); }
263     Arch        HistoryLogPatchStateChange::arch()      const { return Arch( optionalAt( ARCH_INDEX ) ); }
264     std::string HistoryLogPatchStateChange::repoAlias() const { return optionalAt( REPOALIAS_INDEX ); }
265     Patch::SeverityFlag HistoryLogPatchStateChange::severity() const { return Patch::severityFlag( optionalAt( SEVERITY_INDEX ) ); }
266     Patch::Category HistoryLogPatchStateChange::category() const { return Patch::categoryEnum( optionalAt( CATEGORY_INDEX ) ); }
267     string HistoryLogPatchStateChange::oldstate() const { return optionalAt( OLDSTATE_INDEX ); }
268     string HistoryLogPatchStateChange::newstate() const { return optionalAt( NEWSTATE_INDEX ); }
269     std::string HistoryLogPatchStateChange::userdata()  const { return optionalAt( USERDATA_INDEX ); }
270
271   ///////////////////////////////////////////////////////////////////
272   //    class HistoryLogDataRemove
273   ///////////////////////////////////////////////////////////////////
274     HistoryLogDataRemove::HistoryLogDataRemove( FieldVector & fields_r )
275     : HistoryLogData( fields_r )
276     {}
277     std::string HistoryLogDataRemove::name()            const { return optionalAt( NAME_INDEX ); }
278     Edition     HistoryLogDataRemove::edition()         const { return Edition( optionalAt( EDITION_INDEX ) ); }
279     Arch        HistoryLogDataRemove::arch()            const { return Arch( optionalAt( ARCH_INDEX ) ); }
280     std::string HistoryLogDataRemove::reqby()           const { return optionalAt( REQBY_INDEX ); }
281     std::string HistoryLogDataRemove::userdata()        const { return optionalAt( USERDATA_INDEX ); }
282
283   ///////////////////////////////////////////////////////////////////
284   //    class HistoryLogDataRepoAdd
285   ///////////////////////////////////////////////////////////////////
286     HistoryLogDataRepoAdd::HistoryLogDataRepoAdd( FieldVector & fields_r )
287     : HistoryLogData( fields_r )
288     {}
289     std::string HistoryLogDataRepoAdd::alias()          const { return optionalAt( ALIAS_INDEX ); }
290     Url         HistoryLogDataRepoAdd::url()            const { return optionalAt( URL_INDEX ); }
291     std::string HistoryLogDataRepoAdd::userdata()       const { return optionalAt( USERDATA_INDEX ); }
292
293   ///////////////////////////////////////////////////////////////////
294   //    class HistoryLogDataRepoRemove
295   ///////////////////////////////////////////////////////////////////
296     HistoryLogDataRepoRemove::HistoryLogDataRepoRemove( FieldVector & fields_r )
297     : HistoryLogData( fields_r )
298     {}
299     std::string HistoryLogDataRepoRemove::alias()       const { return optionalAt( ALIAS_INDEX ); }
300     std::string HistoryLogDataRepoRemove::userdata()    const { return optionalAt( USERDATA_INDEX ); }
301
302   ///////////////////////////////////////////////////////////////////
303   //    class HistoryLogDataRepoAliasChange
304   ///////////////////////////////////////////////////////////////////
305     HistoryLogDataRepoAliasChange::HistoryLogDataRepoAliasChange( FieldVector & fields_r )
306     : HistoryLogData( fields_r )
307     {}
308     std::string HistoryLogDataRepoAliasChange::oldAlias()       const { return optionalAt( OLDALIAS_INDEX ); }
309     std::string HistoryLogDataRepoAliasChange::newAlias()       const { return optionalAt( NEWALIAS_INDEX ); }
310     std::string HistoryLogDataRepoAliasChange::userdata()       const { return optionalAt( USERDATA_INDEX ); }
311
312   ///////////////////////////////////////////////////////////////////
313   //    class HistoryLogDataRepoUrlChange
314   ///////////////////////////////////////////////////////////////////
315     HistoryLogDataRepoUrlChange::HistoryLogDataRepoUrlChange( FieldVector & fields_r )
316     : HistoryLogData( fields_r )
317     {}
318     std::string HistoryLogDataRepoUrlChange::alias()    const { return optionalAt( ALIAS_INDEX ); }
319     Url         HistoryLogDataRepoUrlChange::newUrl()   const { return optionalAt( NEWURL_INDEX ); }
320     std::string HistoryLogDataRepoUrlChange::userdata() const { return optionalAt( USERDATA_INDEX ); }
321
322   ///////////////////////////////////////////////////////////////////
323   //    class HistoryLogDataStampCommand
324   ///////////////////////////////////////////////////////////////////
325     HistoryLogDataStampCommand::HistoryLogDataStampCommand( FieldVector & fields_r )
326     : HistoryLogData( fields_r )
327     {}
328     std::string HistoryLogDataStampCommand::executedBy()        const { return optionalAt( USER_INDEX ); }
329     std::string HistoryLogDataStampCommand::command()           const { return optionalAt( COMMAND_INDEX ); }
330     std::string HistoryLogDataStampCommand::userdata()          const { return optionalAt( USERDATA_INDEX ); }
331
332 } // namespace zypp
333 ///////////////////////////////////////////////////////////////////