1 // SSItem.cpp: implementation of the SSItem class.
3 //////////////////////////////////////////////////////////////////////
8 #include "SSDatabase.h"
9 #include <SSPhysLib\SSProjectObject.h>
11 //---------------------------------------------------------------------------
12 #include "LeakWatcher.h"
17 static char THIS_FILE
[] = __FILE__
;
20 //////////////////////////////////////////////////////////////////////
21 // Construction/Destruction
22 //////////////////////////////////////////////////////////////////////
32 SSItem::SSItem(SSHistoryFile& rFile, int nVersion)
34 m_nVersionNumber(nVersion)
38 SSItem::SSItem(SSDatabase* pDb, const std::string& spec, const std::string& phys)
47 //SSItem::SSItem(SSDatabase* pDb)
48 // : m_pDatabase (pDb),
50 // // m_ItemDescr (project),
51 // m_nVersionNumber(0)
53 // m_ItemDescr.type = SSITEM_PROJECT;
54 // m_ItemDescr.flags = 0;
55 // m_ItemDescr.name.flags = 0;
56 // strncpy (m_ItemDescr.name.name, "$", 2);
57 // m_ItemDescr.name.nsmap = 0;
58 // strncpy (m_ItemDescr.phys, "AAAAAAAA", 9);
61 SSItem::SSItem(SSDatabase
* pDb
, SSItemPtr pParent
, SSProjectObject project
, int version
)
66 m_ItemDescr
.Pin (version
);
69 SSItem::SSItem(SSDatabase
* pDb
, SSItemPtr pParent
, SSProjectObject project
)
80 bool SSItem::GetBinary ()
82 return m_ItemDescr
.IsStoreBinaryDiff ();
85 bool SSItem::GetDeleted ()
87 return m_ItemDescr
.IsDeleted ();
90 int SSItem::GetType ()
92 return m_ItemDescr
.GetType ();
95 std::string
SSItem::GetSpec ()
97 // Here is a minor oddity in the naming of the specification
98 // The spec of the root project is $/, but the name of any subproject is
99 // $/subproject (note without the slash at the end)
101 // The encoding of the path specification leads to the small problem, that
102 // a pinned version of the root project is written in the form $/;10. Chaining
103 // subproject to that form of the root project specification leads to
104 // $/;10project;20. To be unambigous in this way, we need to introduce another
105 // path sperator: $/;10/project;20, even if this looks strange
107 // Due to the nature ss handles the specification $;10 is valid. It is the version 10
108 // of the current project.
110 SSItemPtr
pParent (m_pParent
);
115 if (spec
.size() < 2 && spec
.compare(0, 2, "$/") != 0)
116 throw SSException ("internal error: the root project must start with $/");
121 std::string parentSpec
= pParent
->GetSpec();
123 if (*parentSpec
.rbegin() != '/')
126 spec
= parentSpec
+ spec
;
127 pParent
= pParent
->GetParent();
133 std::string
SSItem::GetLocalSpec ()
138 std::string
SSItem::GetName ()
140 return m_ItemDescr
.GetName ();
143 long SSItem::GetVersionNumber ( )
145 int pin
= m_ItemDescr
.GetPinnedToVersion();
149 // std::auto_ptr<SSHistoryFile> pFile (m_pDatabase->GetDataFile (m_ItemDescr.GetPhysFile()));
153 // std::auto_ptr<SSVersionObject> version (pFile->GetLastVersion());
154 // return version->GetVersionNumber ();
157 // throw SSException (std::string ("Could not open File: ") + pFile->GetFileName());
162 long SSItem::GetIsCheckedOut ( )
167 SSItemPtr
SSItem::GetParent ()
172 SSItems
* SSItem::GetItems (bool bIncludeDeleted
)
174 // valid only for project items
175 if (GetType () != SSITEM_PROJECT
)
178 // get the correct phys file
179 std::auto_ptr
<SSHistoryFile
> pFile (m_pDatabase
->GetDataFile (m_ItemDescr
.GetPhysFile()));
183 SSProjectFile
projectFile (pFile
->GetFileName () + pFile
->GetLatestExt ());
184 SSItems
* pItems
= new SSItems (shared_from_this(), projectFile
, true);
186 // reverse apply the history
187 SSVersionObject version
= pFile
->GetLastVersion();
188 int myVersion
= GetVersionNumber ();
189 while (version
&& ( (myVersion
> 0 && version
.GetVersionNumber() > myVersion
) )
190 /* || (versionPtr->GetDate() > m_pDatabase->GetVersionDate ()) */)
192 SSAction
* pAction
= version
.GetAction();
193 if (!pAction
->Accept (*pItems
))
194 throw SSException("unsupported action");
196 version
= pFile
->GetPrevVersion (version
);
201 throw SSException (std::string ("Could not open File: ") + pFile
->GetFileName());
206 SSItemPtr
SSItem::GetVersion (std::string version
)
208 int v
= atoi (version
.c_str());
209 return SSItemPtr (new SSItem (m_pDatabase
, m_pParent
, m_ItemDescr
, v
));
212 SSVersions
* SSItem::GetVersions (long iFlags
)
214 return new SSVersions (shared_from_this(), m_ItemDescr
.GetPhysFile(), iFlags
);
217 std::string
SSItem::GetPhysical()
219 return m_ItemDescr
.GetPhysFile();
223 void SSItem::Recover()
225 m_ItemDescr
.Recover ();
228 void SSItem::Delete()
230 m_ItemDescr
.Delete ();
233 void SSItem::Rename(SSNAME oldName
, SSNAME newName
)
235 m_ItemDescr
.Rename (oldName
, newName
);
244 SSItems::SSItems (SSItemPtr pParentItem
, SSProjectFile
& rFile
, bool bIncludeDeleted
)
245 : m_pParent (pParentItem
)
247 BuildList (pParentItem
, rFile
, bIncludeDeleted
);
250 SSItemPtr
SSItems::GetItem (long i
)
252 assert (i
< GetCount ());
255 return static_cast<SSItem
*>(NULL
);
258 void SSItems::BuildList (SSItemPtr pParentItem
, SSProjectFile
& rFile
, bool bIncludeDeleted
)
260 // iterate all records and add the items to the collection
261 SSRecordPtr recordPtr
= rFile
.GetFirstRecord ();
264 if (recordPtr
->GetType() == eProjectEntry
)
266 SSProjectObject
project (recordPtr
);
267 if (!project
.IsDeleted() || bIncludeDeleted
)
269 m_Items
.push_back (SSItemPtr(new SSItem (pParentItem
->GetDatabase (), pParentItem
, project
)));
273 recordPtr
= rFile
.GetNextRecord (recordPtr
);
277 bool SSItems::Apply (const SSLabeledAction
& rAction
)
282 bool SSItems::Apply (const SSCreatedProjectAction
& rAction
)
287 bool SSItems::Apply (const SSCreatedFileAction
& rAction
)
292 bool SSItems::Apply (const SSDestroyedFileAction
& rAction
)
294 // durch map wahrscheinlich besser zu lösen
295 if (GetPhysicalItem (rAction
.GetPhysical()))
296 throw SSException ("adding already existing item");
300 pe
.name
= rAction
.GetSSName ();
301 strncpy (pe
.phys
, rAction
.GetPhysical().c_str(), 8);
303 pe
.pinnedToVersion
= 0;
305 SSProjectObject
pr (pe
);
306 SSItemPtr
pItem (new SSItem (m_pParent
->GetDatabase(), m_pParent
, pr
));
308 m_Items
.push_back (pItem
);
312 bool SSItems::Apply (const SSDestroyedProjectAction
& rAction
)
314 // durch map wahrscheinlich besser zu lösen
315 if (GetPhysicalItem (rAction
.GetPhysical()))
316 throw SSException ("adding already existing item");
320 pe
.name
= rAction
.GetSSName ();
321 strncpy (pe
.phys
, rAction
.GetPhysical().c_str(), 8);
323 pe
.pinnedToVersion
= 0;
325 SSProjectObject
pr (pe
);
326 SSItemPtr
pItem (new SSItem (m_pParent
->GetDatabase(), m_pParent
, pr
));
328 m_Items
.push_back (pItem
);
332 bool SSItems::Apply (const SSAddedFileAction
& rAction
)
334 SSItemPtr pItem
= GetPhysicalItem (rAction
.GetPhysical());
335 std::vector
<SSItemPtr
>::iterator itor
= std::find (m_Items
.begin(), m_Items
.end(), pItem
);
337 if (itor
!= m_Items
.end())
340 throw SSException ("item not found");
344 bool SSItems::Apply (const SSAddedProjectAction
& rAction
)
346 SSItemPtr pItem
= GetPhysicalItem (rAction
.GetPhysical());
347 std::vector
<SSItemPtr
>::iterator itor
= std::find (m_Items
.begin(), m_Items
.end(), pItem
);
349 if (itor
!= m_Items
.end())
352 throw SSException ("item not found");
357 bool SSItems::Apply (const SSDeletedFileAction
& rAction
)
359 SSItemPtr pItem
= GetPhysicalItem (rAction
.GetPhysical());
363 throw SSException ("item not found");
367 bool SSItems::Apply (const SSDeletedProjectAction
& rAction
)
369 SSItemPtr pItem
= GetPhysicalItem (rAction
.GetPhysical());
373 throw SSException ("item not found");
378 //bool SSItems::DeleteFile (SSAction& rAction)
380 // SSItemPtr pItem = GetPhysicalItem (rAction.GetPhysical());
384 // throw SSException ("item not found");
388 //bool SSItems::DeleteProject (SSAction& rAction)
390 // return DeleteFile (pAction);
393 bool SSItems::Apply (const SSRenamedProjectAction
& rAction
) //, SSNAME oldName, SSNAME newName)
395 SSItemPtr pItem
= GetPhysicalItem (rAction
.GetPhysical());
397 throw SSException ("item not found");
399 pItem
->Rename (rAction
.GetSSName(), rAction
.GetNewSSName ());
403 bool SSItems::Apply (const SSRenamedFileAction
& rAction
) //, SSNAME oldName, SSNAME newName)
405 SSItemPtr pItem
= GetPhysicalItem (rAction
.GetPhysical());
407 throw SSException ("item not found");
409 pItem
->Rename (rAction
.GetSSName(), rAction
.GetNewSSName ());
413 bool SSItems::Apply (const SSCheckedInAction
& rAction
)
418 SSItemPtr
SSItems::GetPhysicalItem (std::string physical
)
420 #pragma message ("speed up by using a map and no full search")
421 std::vector
<SSItemPtr
>::iterator itor
;
422 std::vector
<SSItemPtr
>::iterator end
= m_Items
.end();
424 SSItemPtr foundItemPtr
;
425 for (itor
= m_Items
.begin(); itor
!= end
; ++itor
)
427 SSItemPtr itemPtr
= *itor
;
428 // std::cout << itemPtr->GetPhysical () << std::endl;
429 std::string current
= itemPtr
->GetPhysical ();
430 if (current
== physical
)
433 throw SSException ("duplicate entry");
435 foundItemPtr
= itemPtr
;
442 void SSItems::Dump (std::ostream
& os
) const
444 std::vector
<SSItemPtr
>::iterator itor
;
445 std::vector
<SSItemPtr
>::iterator end
= m_Items
.end();
447 for (itor
= m_Items
.begin(); itor
!= end
; ++itor
)
449 oss
<< (*itor
)->GetPhysical () << ": " << (*itor
)->GetName () << std::endl
;