Add Dirk Luetjen's ssphys libraries and command-line tool
[vss2svn.git] / ssphys / SSLib / SSItem.cpp
blob5caea54d2587cd8620b64e65a5ddc784b6064863
1 // SSItem.cpp: implementation of the SSItem class.
2 //
3 //////////////////////////////////////////////////////////////////////
5 #include "stdafx.h"
6 #include "SSItem.h"
7 #include "SSVersion.h"
8 #include "SSDatabase.h"
9 #include <SSPhysLib\SSProjectObject.h>
11 //---------------------------------------------------------------------------
12 #include "LeakWatcher.h"
14 #ifdef _DEBUG
15 #define new DEBUG_NEW
16 #undef THIS_FILE
17 static char THIS_FILE[] = __FILE__;
18 #endif
20 //////////////////////////////////////////////////////////////////////
21 // Construction/Destruction
22 //////////////////////////////////////////////////////////////////////
26 SSItem::SSItem()
27 : m_pDatabase (NULL),
28 m_nVersionNumber(0)
32 SSItem::SSItem(SSHistoryFile& rFile, int nVersion)
33 : m_pDatabase (NULL),
34 m_nVersionNumber(nVersion)
38 SSItem::SSItem(SSDatabase* pDb, const std::string& spec, const std::string& phys)
39 : m_pDatabase (pDb),
40 m_MySpec (spec),
41 m_Phys (phys),
42 m_nVersionNumber(0)
47 //SSItem::SSItem(SSDatabase* pDb)
48 // : m_pDatabase (pDb),
49 // m_pParent (NULL),
50 // // m_ItemDescr (project),
51 // m_nVersionNumber(0)
52 //{
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);
59 //}
61 SSItem::SSItem(SSDatabase* pDb, SSItemPtr pParent, SSProjectObject project, int version)
62 : m_pDatabase (pDb),
63 m_pParent (pParent),
64 m_ItemDescr (project)
66 m_ItemDescr.Pin (version);
69 SSItem::SSItem(SSDatabase* pDb, SSItemPtr pParent, SSProjectObject project)
70 : m_pDatabase (pDb),
71 m_pParent (pParent),
72 m_ItemDescr (project)
76 SSItem::~SSItem()
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.
109 std::string spec;
110 SSItemPtr pParent (m_pParent);
112 spec = GetName ();
113 if (!pParent)
115 if (spec.size() < 2 && spec.compare(0, 2, "$/") != 0)
116 throw SSException ("internal error: the root project must start with $/");
119 while (pParent)
121 std::string parentSpec = pParent->GetSpec();
123 if (*parentSpec.rbegin() != '/')
124 parentSpec += "/";
126 spec = parentSpec + spec;
127 pParent = pParent->GetParent();
130 return spec;
133 std::string SSItem::GetLocalSpec ()
135 return "";
138 std::string SSItem::GetName ()
140 return m_ItemDescr.GetName ();
143 long SSItem::GetVersionNumber ( )
145 int pin = m_ItemDescr.GetPinnedToVersion();
146 if (pin)
147 return pin;
149 // std::auto_ptr<SSHistoryFile> pFile (m_pDatabase->GetDataFile (m_ItemDescr.GetPhysFile()));
150 // if (pFile.get())
151 // {
152 // pFile->Open ();
153 // std::auto_ptr<SSVersionObject> version (pFile->GetLastVersion());
154 // return version->GetVersionNumber ();
155 // }
156 // else
157 // throw SSException (std::string ("Could not open File: ") + pFile->GetFileName());
159 return 0;
162 long SSItem::GetIsCheckedOut ( )
164 return 0;
167 SSItemPtr SSItem::GetParent ()
169 return m_pParent;
172 SSItems* SSItem::GetItems (bool bIncludeDeleted)
174 // valid only for project items
175 if (GetType () != SSITEM_PROJECT)
176 return NULL;
178 // get the correct phys file
179 std::auto_ptr<SSHistoryFile> pFile (m_pDatabase->GetDataFile (m_ItemDescr.GetPhysFile()));
180 if (pFile.get())
182 pFile->Open ();
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);
198 return pItems;
200 else
201 throw SSException (std::string ("Could not open File: ") + pFile->GetFileName());
203 return NULL;
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);
240 SSItems::~SSItems ()
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 ());
253 if (i<GetCount ())
254 return m_Items[i];
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 ();
262 while (recordPtr)
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)
279 return true;
282 bool SSItems::Apply (const SSCreatedProjectAction& rAction)
284 return true;
287 bool SSItems::Apply (const SSCreatedFileAction& rAction)
289 return true;
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");
298 PROJECT_ENTRY pe;
299 // pe.flags = ??;
300 pe.name = rAction.GetSSName ();
301 strncpy (pe.phys, rAction.GetPhysical().c_str(), 8);
302 pe.phys[8] = '\0';
303 pe.pinnedToVersion = 0;
304 // pe.type = ??
305 SSProjectObject pr (pe);
306 SSItemPtr pItem (new SSItem (m_pParent->GetDatabase(), m_pParent, pr));
308 m_Items.push_back (pItem);
310 return true;
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");
318 PROJECT_ENTRY pe;
319 // pe.flags = ??;
320 pe.name = rAction.GetSSName ();
321 strncpy (pe.phys, rAction.GetPhysical().c_str(), 8);
322 pe.phys[8] = '\0';
323 pe.pinnedToVersion = 0;
324 // pe.type = ??
325 SSProjectObject pr (pe);
326 SSItemPtr pItem (new SSItem (m_pParent->GetDatabase(), m_pParent, pr));
328 m_Items.push_back (pItem);
330 return true;
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())
338 m_Items.erase(itor);
339 else
340 throw SSException ("item not found");
342 return true;
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())
350 m_Items.erase(itor);
351 else
352 throw SSException ("item not found");
354 return true;
357 bool SSItems::Apply (const SSDeletedFileAction& rAction)
359 SSItemPtr pItem = GetPhysicalItem (rAction.GetPhysical());
360 if (pItem)
361 pItem->Recover ();
362 else
363 throw SSException ("item not found");
365 return true;
367 bool SSItems::Apply (const SSDeletedProjectAction& rAction)
369 SSItemPtr pItem = GetPhysicalItem (rAction.GetPhysical());
370 if (pItem)
371 pItem->Recover ();
372 else
373 throw SSException ("item not found");
375 return true;
378 //bool SSItems::DeleteFile (SSAction& rAction)
380 // SSItemPtr pItem = GetPhysicalItem (rAction.GetPhysical());
381 // if (pItem)
382 // pItem->Delete ();
383 // else
384 // throw SSException ("item not found");
386 // return true;
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());
396 if (!pItem)
397 throw SSException ("item not found");
399 pItem->Rename (rAction.GetSSName(), rAction.GetNewSSName ());
400 return true;
403 bool SSItems::Apply (const SSRenamedFileAction& rAction) //, SSNAME oldName, SSNAME newName)
405 SSItemPtr pItem = GetPhysicalItem (rAction.GetPhysical());
406 if (!pItem)
407 throw SSException ("item not found");
409 pItem->Rename (rAction.GetSSName(), rAction.GetNewSSName ());
410 return true;
413 bool SSItems::Apply (const SSCheckedInAction& rAction)
415 return true;
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)
432 if (foundItemPtr)
433 throw SSException ("duplicate entry");
435 foundItemPtr = itemPtr;
439 return foundItemPtr;
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;