Interface for Source Control

From CacheWiki
Jump to: navigation, search

Contents

Interface for Source Control

Introduction

Because our team is not skilled in subversion yet I have choosed not to integrate subversion into Studio at the moment For beginners could be more easy to use TortoiseSvn as a user friendly GUI for subversion communication. So, all I need is to force Studio to behave as a normal source editor, I mean store or classes and routines to local filesystem (and treat this local repository as a PRIMARY source, NOT DB) and then use third party user friedly software for revision controlling. For that purpose I created Interface, which serves for adding/deleting CLS and MAC files to/from Project.
Thx a lot to Daniel Kutac from Intersystems CZ for help and hints :)

Include file

<?xml version="1.0" encoding="CP1250"?>
<Export generator="Cache" version="21" zv="Cache for Windows (x86-32) 2007.1.4 (Build 707U)" ts="2008-08-30 13:34:32">
<Routine name="RevisionControl" type="INC" timestamp="61238,47749"><![CDATA[
#IfNDef RevisionControl
	/*
		Include file
	*/
	#Include %sySite
	#Define RevisionControl
	
	#define PATHSEPARATOR	$s($$$ISWINDOWS:"\",1:"/1")
	#Define ERREXIT goto exit:($$$ISERR(sc))
	#Define DBERRCHECK if ( (SQLCODE '= 0) && (SQLCODE '= 100) ) { set sc = $$$ERROR($$$GeneralError, $SYSTEM.SQL.SQLCODE(SQLCODE))  goto exit }
	#Define DBERRCHECK0 if ( (SQLCODE '= 0)) { set sc = $$$ERROR($$$GeneralError, $SYSTEM.SQL.SQLCODE(SQLCODE))  goto exit }
	#Define COMMIT if $TLEVEL TCOMMIT
	#Define ROLLBACK if $TLEVEL TROLLBACK 1
	#Define ROLLBACKALL if $TLEVEL TROLLBACK
	#Define FILENAMEFROMPATH(%a) $List($Listfromstring(%a, $$$PATHSEPARATOR), -1)
	#Define CATCH(%a) set sc = %a.AsStatus()  s:($ze="") $ze="<ZOBJ>"_e.Code  d BACK^%ETN  $$$ERREXIT
	#Define EXCEP(%a) d:($$$ISERR(%a)) ##class(%Exception.StatusException).CreateFromStatus(%a)
	
	//ERRCODES
	#Define ERRBASE 100000
	#Define DIRECTORYNOTCREATED ($$$ERRBASE + 1)
	#Define BADARGUMENT	($$$ERRBASE + 2)
#EndIf
]]></Routine>
</Export>

Interface, class file

<?xml version="1.0" encoding="UTF-8"?>
<Export generator="Cache" version="21" zv="Cache for Windows (x86-32) 2007.1.4 (Build 707U)" ts="2008-08-30 14:39:14">
<Class name="RevisionControl.IProjectManipulation">
<Description><![CDATA[
This is a very simple interface for item project manipulation <br>
(MAC and CSP) files. You can export them, import them. <br>
Please <b>see the first section</b> of class variables. Probably you <br>
would to change them. <br>
<b><i>Warning: This class should not be a member of your project!</b></i> <br>
<b><i>created by: jan.vlasak@aposteriori.cz for public use</b></i> <br>
-------------------------------------------------------------------------------- <br>
change log: <br>
-> version: 0.1, basic features, export/import of project items]]></Description>
<IncludeCode>RevisionControl</IncludeCode>
<Super>%RegisteredObject</Super>
<TimeCreated>61215,32643.41447</TimeCreated>

<Property name="version">
<Description>
Version of class</Description>
<Type>%String</Type>
<InitialExpression>"0.1"</InitialExpression>
<Private>1</Private>
</Property>

<UDLText name="T">
<Content><![CDATA[
//-----------------------------------------------------------------------------

]]></Content>
</UDLText>

<Property name="pathSeparator">
<Description>
Path separator</Description>
<Type>%String</Type>
<InitialExpression>$$$PATHSEPARATOR</InitialExpression>
<Private>1</Private>
</Property>

<Property name="repoLocalPath">
<Description>
Default path to repository on filesystem (root, without name of namespace)</Description>
<Type>%String</Type>
<InitialExpression>"d:\@Repo"</InitialExpression>
<Private>1</Private>
</Property>

<Property name="charset">
<Description>
Charset used for export</Description>
<Type>%String</Type>
<InitialExpression>"CP1250"</InitialExpression>
<Private>1</Private>
</Property>

<Property name="projectName">
<Description>
Name of watched project</Description>
<InitialExpression>"Project"</InitialExpression>
<Private>1</Private>
</Property>

<UDLText name="T">
<Content><![CDATA[
//-----------------------------------------------------------------------------

]]></Content>
</UDLText>

<Property name="repoLocalDir">
<Description>
Directory where items are exported (is setted in %OnNew())</Description>
<Type>%String</Type>
<Private>1</Private>
</Property>

<Property name="currNamespace">
<Description>
Name of current nameSpace</Description>
<Type>%String</Type>
<Private>1</Private>
</Property>

<Method name="GetVersion">
<Description>
Get version of class</Description>
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[	q ..version
]]></Implementation>
</Method>

<Method name="%OnNew">
<Description>
Constructor. Local repository is created here (even if exist)</Description>
<FormalSpec>initvalue:%CacheString</FormalSpec>
<Private>1</Private>
<ProcedureBlock>1</ProcedureBlock>
<ReturnType>%Status</ReturnType>
<ServerOnly>1</ServerOnly>
<Implementation><![CDATA[
	
	try
	{
		set sc = $$$OK
		
		//get current namespace
		set ..currNamespace = $zutil(5)
		
		//create directory for export/import items--------------------
		set ..repoLocalDir = ..repoLocalPath _ ..pathSeparator _ ..currNamespace _ ..pathSeparator _ ..projectName
		set created = ##class(%File).CreateDirectoryChain(..repoLocalDir)
		
		if ( created = 0 )
		{
			set sc = $$$ERROR($$$DIRECTORYNOTCREATED, "Dir: " _ ..repoLocalDir)
			$$$EXCEP(sc)
		}
		//---------------------------------------------------------
	}
	catch e
	{
		$$$CATCH(e)
	}

exit
	q sc
]]></Implementation>
</Method>

<Method name="ExportOne">
<Description>
Export obj (class, macro, etc.) to filesystem as one XML file</Description>
<FormalSpec>itemName:%String</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	
	try
	{
		set sc = $$$OK
		
		set exportFilePath = ..ExternalName(itemName)
		
		set sc = ##class(%SYSTEM.OBJ).Export(itemName, exportFilePath, "", "", ..charset)
		$$$EXCEP(sc)
	}
	catch e
	{
		$$$CATCH(e)
	}

exit
	q sc
]]></Implementation>
</Method>

<Method name="ExportAll">
<Description>
Export all items in project to dir individually</Description>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	
	set sc = $$$OK
	
	try
	{
		set sc = ..GetItemsInProject(.names, .types, .exportName)
		$$$EXCEP(sc)
		
		for i = 1: 1: exportName.Count()
		{
			set sc = ..ExportOne( exportName.GetAt(i) )
			$$$EXCEP(sc)
		}
	}
	catch e
	{
		$$$CATCH(e)
	}

exit
	q sc
]]></Implementation>
</Method>

<Method name="GetItemsInProject">
<Description>
Get array of items in project (just CLS/MAC items)</Description>
<FormalSpec>*itemName:%ArrayOfDataTypes,*itemType:%ArrayOfDataTypes,*exportName:%ArrayOfDataTypes</FormalSpec>
<Private>1</Private>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	
	try
	{
		set sc = $$$OK
		set itemName = ##class(%ArrayOfDataTypes).%New()
		set itemType = ##class(%ArrayOfDataTypes).%New()
		set exportName = ##class(%ArrayOfDataTypes).%New()
		
		set r = ##class(%Library.ResultSet).%New("%Studio.Project:ProjectItemsList")
		set sc = r.Execute(..projectName)
		$$$EXCEP(sc)
		
		set i = 0
		while ( r.Next(.sc))
		{
			$$$EXCEP(sc)
			
			set id = r.Data("ID")
			set name = r.Data("Name")
			set type = r.Data("Type")
			set inSourceControl = r.Data("InSourceControl") //not used yet
			
			if (type = "CLS") || (type = "MAC")
			{
				set i = i + 1
				
				set sc = itemName.SetAt(name, i)
				$$$EXCEP(sc)
			
				set sc = itemType.SetAt(type, i)
				$$$EXCEP(sc)
				
				if ( type = "MAC" )
				{
					set sc = exportName.SetAt( name, i )
					$$$EXCEP(sc)
				}
				else
				{
					set sc = exportName.SetAt( name _ "." _ type, i )
					$$$EXCEP(sc)
				}
			} //end of if (type = "CLS") || (type = "MAC")
		} //end of while
	}
	catch e
	{
		$$$CATCH(e)
	}

exit
	q sc
]]></Implementation>
</Method>

<Method name="ImportOne">
<Description><![CDATA[
Import one XML into namespace/project <br>
It takes few seconds to reload the project]]></Description>
<FormalSpec>itemName:%String,importToProject:%Boolean=1</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	
	try
	{	
		set sc = $System.OBJ.Load(..ExternalName(itemName), "-ck") //c = compile, k = dont delete int files
		$$$EXCEP(sc)
		
		if ( importToProject )
		{
			set project = ##class(%Studio.Project).%OpenId(..projectName, 1, .sc)
			$$$EXCEP(sc)
			
			set sc = project.AddItem(itemName)
			$$$EXCEP(sc)
			
			set sc = project.%Save()
			$$$EXCEP(sc)
		}
	}
	catch e
	{
		$$$CATCH(e)
	}
exit	
	q sc
]]></Implementation>
</Method>

<Method name="ImportAll">
<Description><![CDATA[
Import all XML files from local repository <br>
<b> dont call this method twice </b> Firt kill this instance and then
you can call it again.]]></Description>
<FormalSpec>*files:%ArrayOfDataTypes,importToProject:%Boolean=1,withDeleteAll:%Boolean=1</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	
	set sc = $$$OK
	
	try
	{
		TSTART
		
		if ( withDeleteAll )
		{
			set sc = ..DeleteAll()
			$$$EXCEP(sc)
		}
		
		set files = ##class(%ArrayOfDataTypes).%New()
		
		/// first, we must make an array of filenames located there
		set r = ##class(%Library.ResultSet).%New("%Library.File:FileSet")
		set sc = r.Execute(..repoLocalDir, "*.xml", "name")
		$$$EXCEP(sc)
		
		set i = 0
		
		while (r.Next(.sc))
		{
			$$$EXCEP(sc)
			
			set i = i + 1
			
			set sc = files.SetAt(r.Data("Name"), i)
		}
		//-------------------------------------------------------------
		
		for i = 1: 1: files.Count()
		{
			set filePath = files.GetAt(i)
			set fileName = $$$FILENAMEFROMPATH(filePath)
			
			//I want do delete .xml file extension
			set count = ##class(%Utility).Replace(fileName, ".xml", "", 0, .internalName)
			
			/// no replace :(
			if ( count = 0 )
			{
				set sc = $$$ERROR($$$GeneralError, "No replace for filename: " _ fileName)
				$$$EXCEP(sc)
			}
			
			set sc = ..ImportOne(internalName, importToProject)
			$$$EXCEP(sc)
		}
		
	}
	catch e
	{
		$$$CATCH(e)
	}

exit
	if $$$ISERR(sc)
	{
		$$$ROLLBACKALL
	}
	else
	{
		$$$COMMIT
	}

	q sc
]]></Implementation>
</Method>

<Method name="DeleteOne">
<Description><![CDATA[
Delete one item in project/namespace<br>
We can manage only MAC/CLS items, others you have to manage <br>
manually]]></Description>
<FormalSpec>itemName:%String,itemType:%String,removeFromProject:%Boolean=1</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	
	try
	{
		set sc = $$$OK
		
		if ( itemType = "CLS" )
		{
			d:(removeFromProject) ##class(%Studio.Project).DeleteItem(itemName)
			set sc = ##class(%SYSTEM.OBJ).Delete(itemName, "", "")
			$$$EXCEP(sc)
		}
		elseif ( itemType = "MAC" )
		{
			d:(removeFromProject) ##class(%Studio.Project).DeleteItem(itemName)
			set sc = ##class(%Library.Routine).Delete(itemName)
			$$$EXCEP(sc)
		}
		else
		{
			set sc = $$$ERROR($$$BADARGUMENT, "type: " _ itemName)
			$$$EXCEP(sc)
		}
	}
	catch e
	{
		$$$CATCH(e)
	}
exit	
	q sc
]]></Implementation>
</Method>

<Method name="DeleteAll">
<Description><![CDATA[
Delete all items in project (not project itself) <br>
We can manage only MAC/CLS items, others you have to manage <br>
manually]]></Description>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	
	set sc = $$$OK
	
	try
	{
		TSTART
		
		set sc = ..GetItemsInProject(.names, .types, .internalNames)
		$$$EXCEP(sc)
		
		for i = 1: 1: internalNames.Count()
		{
			set item = internalNames.GetAt(i)
			set type = types.GetAt(i)
			
			set sc = ..DeleteOne(item, type)
			$$$EXCEP(sc)
		}
	}
	catch e
	{
		$$$CATCH(e)
	}

exit
	if $$$ISERR(sc)
	{
		$$$ROLLBACKALL
	}
	else
	{
		$$$COMMIT
	}

	q sc
]]></Implementation>
</Method>

<Method name="ExternalName">
<Description>
Convert the internal name, e.g. TEST.MAC to an external name that is used to export
the routine/class/csp item. This is often a filename to write the file out to.</Description>
<FormalSpec>internalName:%String,fullPath:%Boolean=1</FormalSpec>
<Private>1</Private>
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[
	// replace slashes in (csp,..) internalname by underscores
	set internalName = $tr(internalName,"/\","__")
	set len = $l(internalName, ".")
	set type = $zcvt($p(internalName, ".", len),"L")
	set external = $p(internalName,".", 1, len - 1) _ "." _ type _ ".xml"
	set:(fullPath) external = ..repoLocalDir _ ..pathSeparator _ external
	
	q external
]]></Implementation>
</Method>
</Class>
</Export>
Personal tools