libzypp  17.14.0
HistoryLogData.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
9 
13 #include <sstream>
14 
15 #include "zypp/base/PtrTypes.h"
16 #include "zypp/base/String.h"
17 #include "zypp/base/Logger.h"
19 
20 #include "zypp/HistoryLogData.h"
21 
22 using namespace std;
23 
25 namespace zypp
26 {
27  using parser::ParseException;
28 
30  //
31  // class HistoryActionID
32  //
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 
44  HistoryActionID::HistoryActionID(const std::string & strval_r)
45  : _id(parse(strval_r))
46  {}
47 
48  HistoryActionID::ID HistoryActionID::parse( const std::string & strval_r )
49  {
50  typedef std::map<std::string,ID> MapType;
51  static MapType _table;
52  if ( _table.empty() )
53  {
54  // initialize it
55  _table["install"] = INSTALL_e;
56  _table["remove"] = REMOVE_e;
57  _table["radd"] = REPO_ADD_e;
58  _table["rremove"] = REPO_REMOVE_e;
59  _table["ralias"] = REPO_CHANGE_ALIAS_e;
60  _table["rurl"] = REPO_CHANGE_URL_e;
61  _table["command"] = STAMP_COMMAND_e;
62  _table["NONE"] = _table["none"] = NONE_e;
63  }
64 
65  MapType::const_iterator it = _table.find( strval_r );
66  if ( it != _table.end() )
67  return it->second;
68  // else:
69  WAR << "Unknown history action ID '" + strval_r + "'" << endl;
70  return NONE_e;
71  }
72 
73 
74  const std::string & HistoryActionID::asString( bool pad ) const
75  {
76  typedef std::pair<std::string,std::string> PairType;
77  typedef std::map<ID, PairType> MapType;
78  static MapType _table;
79  if ( _table.empty() )
80  {
81  // initialize it pad(7) (for now)
82  _table[INSTALL_e] = PairType( "install" , "install" );
83  _table[REMOVE_e] = PairType( "remove" , "remove " );
84  _table[REPO_ADD_e] = PairType( "radd" , "radd " );
85  _table[REPO_REMOVE_e] = PairType( "rremove" , "rremove" );
86  _table[REPO_CHANGE_ALIAS_e] = PairType( "ralias" , "ralias " );
87  _table[REPO_CHANGE_URL_e] = PairType( "rurl" , "rurl " );
88  _table[STAMP_COMMAND_e] = PairType( "command" , "command" );
89  _table[NONE_e] = PairType( "NONE" , "NONE " );
90  }
91 
92  return( pad ? _table[_id].second : _table[_id].first );
93  }
94 
95  std::ostream & operator << (std::ostream & str, const HistoryActionID & id)
96  { return str << id.asString(); }
97 
99 
101  //
102  // class HistoryLogData::Impl
103  //
106  {
107  public:
108  Impl( FieldVector & fields_r, size_type expect_r )
109  {
110  _checkFields( fields_r, expect_r );
111  _field.swap( fields_r );
112  // For whatever reason writer is ' '-padding the action field
113  // but we don't want to modify the vector before we moved it.
115  _action = HistoryActionID( _field[ACTION_INDEX] );
116  }
117 
118  Impl( FieldVector & fields_r, HistoryActionID action_r, size_type expect_r )
119  {
120  _checkFields( fields_r, expect_r );
121  // For whatever reason writer is ' '-padding the action field
122  // but we don't want to modify the vector before we moved it.
123  std::string trimmed( str::trim( fields_r[ACTION_INDEX] ) );
124  _action = HistoryActionID( trimmed );
125  if ( _action != action_r )
126  {
127  ZYPP_THROW( ParseException( str::form( "Bad action id. Got %s, expected %s.",
128  _action.asString().c_str(),
129  action_r.asString().c_str() ) ) );
130  }
131  _field.swap( fields_r );
132  // now adjust action field:
133  _field[ACTION_INDEX] = trimmed;
134  }
135 
136  void _checkFields( const FieldVector & fields_r, size_type expect_r )
137  {
138  if ( expect_r < 2 ) // at least 2 fields (date and action) are required
139  expect_r = 2;
140  if ( fields_r.size() < expect_r )
141  {
142  ZYPP_THROW( ParseException( str::form( "Bad number of fields. Got %zd, expected at least %zd.",
143  fields_r.size(),
144  expect_r ) ) );
145  }
146  try
147  {
149  }
150  catch ( const std::exception & excpt )
151  {
152  ZYPP_THROW( ParseException( excpt.what() ) ); // invalid date format
153  }
154  // _action handled later
155  }
156 
157  public:
161  };
162 
164  //
165  // class HistoryLogData
166  //
168 
170  : _pimpl( new Impl( fields_r, expect_r ) )
171  {}
172 
174  : _pimpl( new Impl( fields_r, expectedId_r, expect_r ) )
175  {}
176 
178  {}
179 
181  {
182  if ( fields_r.size() >= 2 )
183  {
184  // str::trim( _field[ACTION_INDEX] );
185  switch ( HistoryActionID( str::trim( fields_r[ACTION_INDEX] ) ).toEnum() )
186  {
187 #define OUTS(E,T) case HistoryActionID::E: return Ptr( new T( fields_r ) ); break;
188  OUTS( INSTALL_e, HistoryLogDataInstall );
189  OUTS( REMOVE_e, HistoryLogDataRemove );
190  OUTS( REPO_ADD_e, HistoryLogDataRepoAdd );
191  OUTS( REPO_REMOVE_e, HistoryLogDataRepoRemove );
192  OUTS( REPO_CHANGE_ALIAS_e, HistoryLogDataRepoAliasChange );
193  OUTS( REPO_CHANGE_URL_e, HistoryLogDataRepoUrlChange );
194  OUTS( STAMP_COMMAND_e, HistoryLogDataStampCommand );
195 #undef OUTS
196  // intentionally no default:
198  break;
199  }
200  }
201  // unknown action or invalid fields? Ctor will accept or throw.
202  return Ptr( new HistoryLogData( fields_r ) );
203  }
204 
206  { return _pimpl->_field.empty(); }
207 
209  { return _pimpl->_field.size(); }
210 
212  { return _pimpl->_field.begin(); }
213 
215  { return _pimpl->_field.end(); }
216 
217  const std::string & HistoryLogData::optionalAt( size_type idx_r ) const
218  {
219  static const std::string _empty;
220  return( idx_r < size() ? _pimpl->_field[idx_r] : _empty );
221  }
222 
223  const std::string & HistoryLogData::at( size_type idx_r ) const
224  { return _pimpl->_field.at( idx_r ); }
225 
226 
228  { return _pimpl->_date; }
229 
231  { return _pimpl->_action; }
232 
233 
234  std::ostream & operator<<( std::ostream & str, const HistoryLogData & obj )
235  { return str << str::joinEscaped( obj.begin(), obj.end(), '|' ); }
236 
238  // class HistoryLogDataInstall
241  : HistoryLogData( fields_r )
242  {}
243  std::string HistoryLogDataInstall::name() const { return optionalAt( NAME_INDEX ); }
246  std::string HistoryLogDataInstall::reqby() const { return optionalAt( REQBY_INDEX ); }
249  std::string HistoryLogDataInstall::userdata() const { return optionalAt( USERDATA_INDEX ); }
250 
252  // class HistoryLogDataRemove
255  : HistoryLogData( fields_r )
256  {}
257  std::string HistoryLogDataRemove::name() const { return optionalAt( NAME_INDEX ); }
260  std::string HistoryLogDataRemove::reqby() const { return optionalAt( REQBY_INDEX ); }
261  std::string HistoryLogDataRemove::userdata() const { return optionalAt( USERDATA_INDEX ); }
262 
264  // class HistoryLogDataRepoAdd
267  : HistoryLogData( fields_r )
268  {}
269  std::string HistoryLogDataRepoAdd::alias() const { return optionalAt( ALIAS_INDEX ); }
271  std::string HistoryLogDataRepoAdd::userdata() const { return optionalAt( USERDATA_INDEX ); }
272 
274  // class HistoryLogDataRepoRemove
277  : HistoryLogData( fields_r )
278  {}
279  std::string HistoryLogDataRepoRemove::alias() const { return optionalAt( ALIAS_INDEX ); }
281 
283  // class HistoryLogDataRepoAliasChange
286  : HistoryLogData( fields_r )
287  {}
291 
293  // class HistoryLogDataRepoUrlChange
296  : HistoryLogData( fields_r )
297  {}
298  std::string HistoryLogDataRepoUrlChange::alias() const { return optionalAt( ALIAS_INDEX ); }
301 
303  // class HistoryLogDataStampCommand
306  : HistoryLogData( fields_r )
307  {}
311 
312 } // namespace zypp