<?xml version="1.0" encoding="UTF-8"?>
<Export generator="Cache" version="25" zv="Cache for Windows (x86-64) 2011.1.2 (Build 701U)" ts="2011-12-06 08:26:21">
<Class name="Base.ClassTemplate">
<Description>

	Comment stating the purpose of this class

-----------------------------------------------------------------
	Class Change History:

--- Date --- By ---------------- What ---------------------------
dd.mm.yyyy	LEM		Text
...
...</Description>
<TimeChanged>61808,38023.015</TimeChanged>
<TimeCreated>61808,38023.015</TimeCreated>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>
</Class>


<Class name="Base.CodeAbstract">
<Description>
	A Code consists mainly of a key and a value. Optionally a code has a note.

	It is not possible to create two different codes with the same key. When one tries so,
	the first code with this key gets overwritten by the second one.

	For organization, each code has a property 'class', where it's className is stored.
	Thus, a class defines a corresponding set of codes.
</Description>
<Abstract>1</Abstract>
<Super>%Persistent,%XML.Adaptor,%Populate,Base.Support</Super>
<TimeChanged>62416,57238.536347</TimeChanged>
<TimeCreated>61760,38183.687</TimeCreated>
<Inheritance>right</Inheritance>

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

]]></Content>
</UDLText>

<Parameter name="FileDelimiter">
<Default>;</Default>
</Parameter>

<Parameter name="ToStringDelimiter">
<Default>:</Default>
</Parameter>

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

]]></Content>
</UDLText>

<Property name="class">
<Description>
	The class of a code</Description>
<Type>%String</Type>
<Required>1</Required>
<Parameter name="MAXLEN" value="100"/>
</Property>

<Property name="key">
<Description>
	The key (or id) of a code (like: "1" or "Admin")</Description>
<Type>%String</Type>
<Required>1</Required>
<Parameter name="MAXLEN" value="20"/>
</Property>

<Property name="value">
<Description>
	The value (or content) of a code (like: "Table could not be found" or "Administrator")</Description>
<Type>%String</Type>
<Required>1</Required>
<Parameter name="MAXLEN" value="255"/>
</Property>

<Property name="note">
<Description>
	An optional additional note (or comment) of a code (like: "Occurs when a table name is misspelled" or "Full access granted")</Description>
<Type>%String</Type>
<Parameter name="MAXLEN" value="100"/>
</Property>

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

]]></Content>
</UDLText>

<Query name="all">
<Type>%SQLQuery</Type>
<FormalSpec>className:%String</FormalSpec>
<SqlQuery>	select %ID as id from Base.CodeAbstract where class = :className</SqlQuery>
</Query>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="new">
<Description>
Create a new code with this key, value, and note.
If a code with this key already exists, modify it's value and note.
Set parameter 'doSave' to 0 if you don't want the newly created code to be saved automatically.
This is usually desired only on file-in. Normally you will want to leave doSave to be 1 (default).</Description>
<ClassMethod>1</ClassMethod>
<FormalSpec><![CDATA[key:%String,value:%String,note:%String="",doSave:%Boolean=1,&status:%Status]]></FormalSpec>
<ReturnType>Base.CodeAbstract</ReturnType>
<Implementation><![CDATA[
	set status = $$$OK

	set code = ..get(key)
	if (code = $$$NULLOREF)
	{
		set code = ..%New()
		set code.class = ..%ClassName(1)
		set code.key = key
	}

	set code.value = value
	set code.note = note
	
	if (doSave)
	{
		set status = code.%Save()
		if ($$$ISERR(status))		quit $$$NULLOREF
	}

	quit code
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="fileInAll">
<Description>
	Read a set of codes from a file. The format is csv. Replace all existing codes of this class.</Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>fileName:%String</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	if (..%ClassName(1) = "Base.CodeAbstract")	quit $$$ERROR("Can't fileIn abstract class")

	//	Read all codes of this class in from a file
	//	If that worked, delete all of them from the DB and then save the new ones.

	set file = ##class(%File).%New(fileName)
	set status = file.Open("RU")
	quit:($$$ISERR(status)) status
	
	set newCodes = ##class(%ListOfObjects).%New()
	set lineNr = 0
	while ('file.AtEnd)
	{
		set rawline = file.ReadLine()
		set lineNr = $increment(lineNr)
		
		//	Remove leading whitespaces:
		set line = $zstrip(rawline, "<w")
		
		//	Ignore empty lines:
		if ($length(line) = 0)				continue

		//	Ignore lines starting with a '#' or '//' (= comment lines):
		if ($extract(line, 1, 1) = "#")		continue
		if ($extract(line, 1, 2) = "//")	continue

		set tokensCount = $length(line, ..#FileDelimiter)
		if ((tokensCount '= 2) && (tokensCount '= 3))
		{
			set status = $$$ERROR("Bad number of tokens in line " _ lineNr _ ":'" _ rawline _ "'")
			quit
		}

		set key = $piece(line, ..#FileDelimiter, 1)
		set value = $piece(line, ..#FileDelimiter, 2)
		set note = $piece(line, ..#FileDelimiter, 3)
		
		//	The 0 means: don't save them yet. First read all without errors:
		set status = $$$OK
		set code = ..new(key, value, note, 0, .status)
		quit:($$$ISERR(status))

		do newCodes.Insert(code)
	}
	
	do file.Close()

	quit:($$$ISERR(status)) status

	//	No errors? OK, insert them into the DB:
	do ..%DeleteExtent()
	for i=1:1:newCodes.Count()
	{
		set status = newCodes.GetAt(i).%Save()
		quit:($$$ISERR(status))
	}

	quit status
]]></Implementation>
</Method>

<Method name="fileOutAll">
<Description>
	Write a set of codes to a file. The format is csv.</Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>fileName:%String</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	//	Prevent filing out abstract base class:
	if (..%ClassName(1) = "Base.CodeAbstract")	quit $$$ERROR("Can't fileOut abstract class")

	set file = ##class(%File).%New(fileName)
	set status = file.Open("WSN")
	quit:($$$ISERR(status)) status

	//	Write header:
	set status = file.WriteLine("")
	set status = file.WriteLine("#")
	set status = file.WriteLine("#	File written: 	" _ $zdatetime($horolog, 4))
	set status = file.WriteLine("#	Code Class:   	" _ ..%ClassName(1))
	set status = file.WriteLine("#")
	set status = file.WriteLine("")

	//	Write all codes of this class out to a file
	set all = ..getAllList()
	for i=1:1:all.Count()
	{
		set code = all.GetAt(i)
		set status = code.fileOut(file)
		quit:($$$ISERR(status))
	}

	do file.Close()

	quit status
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="get">
<Description>
Return a code by its key. If it doesn't exist, return $$$NULLOREF.</Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>key:%String</FormalSpec>
<ReturnType>Base.CodeAbstract</ReturnType>
<Implementation><![CDATA[
	set class = ..%ClassName(1)

	&sql(select %ID into :id from Base.CodeAbstract where (class = :class) and ("key" = :key))
	if (SQLCODE = 0)		quit ..%OpenId(id)

	quit $$$NULLOREF
]]></Implementation>
</Method>

<Method name="find">
<Description>
Return a code by its value. If it doesn't exist, return $$$NULLOREF.</Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>value:%String</FormalSpec>
<ReturnType>Base.CodeAbstract</ReturnType>
<Implementation><![CDATA[
	set class = ..%ClassName(1)

	&sql(select %ID into :id from Base.CodeAbstract where (class = :class) and ("value" = :value))
	if (SQLCODE = 0)		quit ..%OpenId(id)

	quit $$$NULLOREF
]]></Implementation>
</Method>

<Method name="getAllList">
<Description>
Return a list containing all Codes.</Description>
<ClassMethod>1</ClassMethod>
<ReturnType>%ListOfObjects</ReturnType>
<Implementation><![CDATA[
	set resultList = ##class(%ListOfObjects).%New()

	set resultSet = ##class(%ResultSet).%New("Base.CodeAbstract:all")
	set status = resultSet.Execute(..%ClassName(1))
	if $$$ISERR(status)		do DisplayError^%apiOBJ(status)		quit $$$NULLOREF

	while resultSet.Next(.status)
	{
		if $$$ISERR(status) quit

		set id = resultSet.Data("id")
		set code = ..%OpenId(id)
		do resultList.Insert(code)
	}

	if $$$ISERR(status)		do DisplayError^%apiOBJ(status)		quit $$$NULLOREF

	quit resultList
]]></Implementation>
</Method>

<Method name="getAllArray">
<Description>
Return an array containing all Codes.</Description>
<ClassMethod>1</ClassMethod>
<ReturnType>%ArrayOfObjects</ReturnType>
<Implementation><![CDATA[
	set resultArray = ##class(%ArrayOfObjects).%New()

	set resultSet = ##class(%ResultSet).%New("Base.CodeAbstract:all")
	set status = resultSet.Execute(..%ClassName(1))
	if $$$ISERR(status)		do DisplayError^%apiOBJ(status)		quit $$$NULLOREF

	while resultSet.Next(.status)
	{
		if $$$ISERR(status) quit

		set id = resultSet.Data("id")
		set code = ..%OpenId(id)
		do resultArray.SetAt(code, id)
	}

	if $$$ISERR(status)		do DisplayError^%apiOBJ(status)		quit $$$NULLOREF

	quit resultArray
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="setValue">
<FormalSpec>value:%String</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	set ..value = value
	quit ..%Save()
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="equals">
<Description>
	Compares two codes. Only if they have the same class and key, they are equal.</Description>
<FormalSpec>other:Base.CodeAbstract</FormalSpec>
<ReturnType>%Boolean</ReturnType>
<Implementation><![CDATA[	quit ((..class = other.class) && (..key = other.key))
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="toString">
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[
	quit "[Code:" _
			..class _ ..#ToStringDelimiter _
			..key _ ..#ToStringDelimiter _
			..value _
			$case(..note, "":"",: ..#ToStringDelimiter _ ..note) _
		"]"
]]></Implementation>
</Method>

<Method name="writeAll">
<ClassMethod>1</ClassMethod>
<Implementation><![CDATA[
	set all = ..getAllList()
	
	for i=1:1:all.Count()
	{
		do all.GetAt(i).write()
		write !
	}
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="fileOut">
<Description>
	Private.</Description>
<FormalSpec>file:%FileCharacterStream</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[	quit file.WriteLine(..key _ ..#FileDelimiter _ ..value _ ..#FileDelimiter _ ..note)
]]></Implementation>
</Method>

<Storage name="Default">
<Type>%Library.CacheStorage</Type>
<DataLocation>^Base.CodeAbstractD</DataLocation>
<DefaultData>CodeAbstractDefaultData</DefaultData>
<IdLocation>^Base.CodeAbstractD</IdLocation>
<IndexLocation>^Base.CodeAbstractI</IndexLocation>
<StreamLocation>^Base.CodeAbstractS</StreamLocation>
<Data name="CodeAbstractDefaultData">
<Structure>listnode</Structure>
<Subscript/>
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
<Value name="2">
<Value>group</Value>
</Value>
<Value name="3">
<Value>id</Value>
</Value>
<Value name="4">
<Value>value</Value>
</Value>
<Value name="5">
<Value>note</Value>
</Value>
<Value name="6">
<Value>key</Value>
</Value>
<Value name="7">
<Value>class</Value>
</Value>
</Data>
</Storage>
</Class>


<Class name="Base.CodeExamples.Example1">
<Description>

Do the following to test this class:

1:	To create some instances:
		write ##class(Base.CodeExamples.Example1).createSome()
	
2:	To test the instances created:
		do ##class(Base.CodeExamples.Example1).writeAll()
		do ##class(Base.CodeExamples.Example1).get(1).write()
		do ##class(Base.CodeExamples.Example1).get(2).write()
		do ##class(Base.CodeExamples.Example1).get(3).write()
		write ##class(Base.CodeExamples.Example1).get(10)

3:	To compare the instances created:
		write ##class(Base.CodeExamples.Example1).get(1).equals(##class(Base.CodeExamples.Example1).get(1))
		write ##class(Base.CodeExamples.Example1).get(1).equals(##class(Base.CodeExamples.Example1).get(2))

4:	To check the instances created:
		write ##class(Base.CodeExamples.Example1).get(1).isOne()
		write ##class(Base.CodeExamples.Example1).get(1).isTwo()
		write ##class(Base.CodeExamples.Example1).get(2).isOne()
		write ##class(Base.CodeExamples.Example1).get(2).isTwo()

5:	To write the instances created out to a file:
		write ##class(Base.CodeExamples.Example1).fileOutAll("Code_Example1.csv")
		Then take a look at the file "Code_Example1.csv"

6:	To read the instances in from a file:
		Modify the file created in step 4 according to your needs
		write ##class(Base.CodeExamples.Example1).fileInAll("Code_Example1.csv")
		Then see what happened:
		do ##class(Base.CodeExamples.Example1).writeAll()
</Description>
<Super>Base.CodeAbstract</Super>
<TimeChanged>61802,44282.812</TimeChanged>
<TimeCreated>61775,30152.109</TimeCreated>

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

]]></Content>
</UDLText>

<Method name="createSome">
<Description>
write ##class(Base.CodeExamples.Example1).createSome()</Description>
<ClassMethod>1</ClassMethod>
<Implementation><![CDATA[
	set status = ..%DeleteExtent()
	quit:($$$ISERR(status)) status

	set type = ..new("1", "One", "This is the first one",, .status)
	quit:($$$ISERR(status)) status

	set type = ..new("2", "Two", "This is the second one",, .status)
	quit:($$$ISERR(status)) status

	set type = ..new("3", "Three", "This is the third one",, .status)
	quit status
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<UDLText name="T">
<Content><![CDATA[
//	Such methods are recommended to free the users from knowing what the different keys actually mean

]]></Content>
</UDLText>

<Method name="isOne">
<Implementation><![CDATA[	quit (..key = "1")
]]></Implementation>
</Method>

<Method name="isTwo">
<Implementation><![CDATA[	quit (..key = "2")
]]></Implementation>
</Method>

<Method name="isThree">
<Implementation><![CDATA[	quit (..key = "3")
]]></Implementation>
</Method>

<Storage name="Default">
<Type>%Library.CacheStorage</Type>
</Storage>
</Class>


<Class name="Base.CodeExamples.Example2">
<Description>

This class comes with no methods implemented at all. It's the simplest way to utilize Codes.

1:	To create some instances:
			Create a textfile named: "Code_Example2.csv" (the name doesn't matter, you can pick any)
			Insert into this file the following text:
				10;First;Number One
				20;Second;Number Two
				30;Third;Number Three
				40;Fourth;Number Four
				50;Fifth;Number Five
			Then file it in:
		write ##class(Base.CodeExamples.Example2).fileInAll("Code_Example2.csv")
		Then see what happened:
		do ##class(Base.CodeExamples.Example2).writeAll()
	
2:	To test the instances created:
		do ##class(Base.CodeExamples.Example2).writeAll()
		do ##class(Base.CodeExamples.Example2).get(10).write()
		do ##class(Base.CodeExamples.Example2).get(20).write()
		do ##class(Base.CodeExamples.Example2).get(30).write()
		write ##class(Base.CodeExamples.Example2).get(99)

3:	To compare the instances created:
		write ##class(Base.CodeExamples.Example2).get(10).equals(##class(Base.CodeExamples.Example2).get(10))
		write ##class(Base.CodeExamples.Example2).get(10).equals(##class(Base.CodeExamples.Example2).get(20))
</Description>
<Super>Base.CodeAbstract</Super>
<TimeChanged>61775,33087.812</TimeChanged>
<TimeCreated>61775,30230.593</TimeCreated>

<Storage name="Default">
<Type>%Library.CacheStorage</Type>
</Storage>
</Class>


<Class name="Base.DBLogger.GUI.AbstractZENPage">
<Description>
Created using the page template: Default</Description>
<Super>%ZEN.Component.page</Super>
<TimeChanged>61837,37346.487</TimeChanged>
<TimeCreated>61831,60756.015</TimeCreated>

<Parameter name="APPLICATION">
<Description>
Class name of application this page belongs to.</Description>
<Default>Base.DBLogger.GUI.Application</Default>
</Parameter>

<Parameter name="PAGENAME">
<Description>
Displayed name of this page.</Description>
<Default>(Abstract)</Default>
</Parameter>

<Parameter name="DOMAIN">
<Description>
Domain used for localization.</Description>
</Parameter>

<XData name="Style">
<Description>
This Style block contains page-specific CSS style definitions.</Description>
<Data><![CDATA[
<style type="text/css">
</style>
]]></Data>
</XData>

<XData name="Contents">
<Description>
This XML block defines the contents of this page.</Description>
<XMLNamespace>http://www.intersystems.com/zen</XMLNamespace>
</XData>

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

]]></Content>
</UDLText>

<UDLText name="T">
<Content><![CDATA[
//	====	Server Callback Methods:	=======================================

]]></Content>
</UDLText>

<Method name="DrawDate">
<Description>
	Input is a date in US (or ODBC) format. Output is a date in european format.</Description>
<FormalSpec>pTable:%ZEN.Component.tablePane,pName:%String,pSeed:%String</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	set value = %query(pName)
	if (value = "")		write "&nbsp;"		quit $$$OK

	//	This converts the date from the US-Format 1 (mm/dd/yyyy) to european format 4 (dd/mm/yyyy)
	write ..toGermanDateFormat($zdate($zdateh(value, 1), 4))

	quit $$$OK
]]></Implementation>
</Method>

<Method name="DrawHorologToDateTime">
<Description>
	Input is a string in horolog format. Output is a datetime in european format. pSeed contains the seconds precision.</Description>
<FormalSpec>pTable:%ZEN.Component.tablePane,pName:%String,pSeed:%String</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	set value = %query(pName)
	if (value = "")		write "&nbsp;"		quit $$$OK

	if (pSeed = "")		set pSeed = 0

	//	This converts the datetime from horolog format to european format
	write ..toGermanDateFormat($zdatetime(value, 4, 1, pSeed))

	quit $$$OK
]]></Implementation>
</Method>

<Method name="DrawTimeStampToDateTime">
<Description>
	Input is a string in timestamp format. Output is a datetime in european format. pSeed contains the seconds precision.</Description>
<FormalSpec>pTable:%ZEN.Component.tablePane,pName:%String,pSeed:%String</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	set value = %query(pName)
	if (value = "")		write "&nbsp;"		quit $$$OK

	if (pSeed = "")		set pSeed = 0

	//	This converts the datetime from timestamp format to european format
	write "X" _ ..toGermanDateFormat($zdatetime($zdatetimeh(value, 3, 1, pSeed), 4, 1, pSeed))

	quit $$$OK
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<UDLText name="T">
<Content><![CDATA[
//	====	Server Support Methods:		=======================================

]]></Content>
</UDLText>

<Method name="toGermanDateFormat">
<ClassMethod>1</ClassMethod>
<FormalSpec>dateOrDateTime:%String</FormalSpec>
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[	quit $translate(dateOrDateTime, "/", ".")
]]></Implementation>
</Method>
</Class>


<Class name="Base.DBLogger.GUI.Application">
<Description>
Alliance.Ens.DispCons.Application</Description>
<Super>%ZEN.application</Super>
<TimeChanged>61831,62364.515</TimeChanged>
<TimeCreated>61831,62364.515</TimeCreated>

<Parameter name="APPLICATIONNAME">
<Description>
This is the name of this application.</Description>
<Default>DBLogger</Default>
</Parameter>

<Parameter name="HOMEPAGE">
<Description>
This is the URL of the main starting page of this application.</Description>
<Default>Base.DBLogger.Logs.cls</Default>
</Parameter>

<XData name="Style">
<Description>
This Style block contains application-wide CSS style definitions.</Description>
<Data><![CDATA[
<style type="text/css">

/*Style classes for use on this page */

	body { font-family: arial; }

	table.tpTable caption {
		background: transparent;
		font-size: 1.4em;
		font-weight: bold;
		text-align: left;
		border: none;
		padding: 10;
	}

	/* even rows */
	 .tpEven { color: black; background: #ebe3ff; }
	
	/* odd rows */
	 .tpOdd { color: black; background: white; }

	/* this is a selected row */
	table.tpTable tr.tpSelected { background: #3d80df; color: white; }

	/* hover for odd and even rows */
	tr.tpOdd:hover,tr.tpEven:hover { 
		background-color: #3d80df; 
		color: #ffffff;
	}

	/* table header style */
	table.tpTable th {
		border-right: 1px solid gray;
		border-bottom: 1px solid gray;
		background: #C5D6D6;
		color: black;
		font-weight: bold;
		text-align: left;
		padding: 2px;
		overflow: hidden;
	}

	/* selected column header (th) */
	table.tpTable th.tpHdrSelected { background: #3d80df; }

	/* filter layour */
	table.tpFilterLayout td { border: none; background: #C5D6D6; }

</style>
]]></Data>
</XData>
</Class>


<Class name="Base.DBLogger.GUI.LoggerModel">
<Super>%ZEN.DataModel.ObjectDataModel</Super>
<TimeChanged>61840,58568.281</TimeChanged>
<TimeCreated>61839,43234</TimeCreated>

<Property name="name">
<Type>%String</Type>
<Parameter name="MAXLEN" value="100"/>
<Parameter name="ZENLABEL" value="Name"/>
</Property>

<Property name="logLevelFilterKey">
<Type>%String</Type>
<Parameter name="MAXLEN" value="20"/>
<Parameter name="ZENLABEL" value="Log Level Filter"/>
</Property>

<Property name="isActive">
<Type>%Boolean</Type>
<Parameter name="ZENLABEL" value="Is Active"/>
</Property>

<Method name="%OnOpenSource">
<Description>
Load an instance of the source object for this DataModel.</Description>
<FormalSpec>pID:%String,pConcurrency:%Integer=-1,*pSC:%Status=$$$OK</FormalSpec>
<ReturnType>%RegisteredObject</ReturnType>
<Implementation><![CDATA[	Quit ##class(Base.DBLogger.Logger).%OpenId(pID,pConcurrency,.pSC)
]]></Implementation>
</Method>

<Method name="%OnSaveSource">
<Description>
Save instance of associated source object.</Description>
<FormalSpec>pSource:Base.DBLogger.Logger</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	Set tSC=pSource.%Save()
	If $$$ISOK(tSC) Set ..%id=pSource.%Id()
	Quit tSC
]]></Implementation>
</Method>

<Method name="%OnNewSource">
<Description>
Load an instance of a new (unsaved) source object for this DataModel.</Description>
<FormalSpec>*pSC:%Status=$$$OK</FormalSpec>
<ReturnType>%RegisteredObject</ReturnType>
<Implementation><![CDATA[	quit ##class(Base.DBLogger.Logger).%New()
]]></Implementation>
</Method>

<Method name="%OnDeleteSource">
<Description>
Delete instance of associated source object.</Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>pID:%String</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[	Quit ##class(Base.DBLogger.Logger).%DeleteId(pID)
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="%OnLoadModel">
<Description>
Do the actual work of loading values from the source object.</Description>
<FormalSpec>pSource:Base.DBLogger.Logger</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	set ..isActive = pSource.isActive
	set ..name = pSource.name
	set ..logLevelFilterKey = pSource.logLevelFilter.key

	quit $$$OK
]]></Implementation>
</Method>

<Method name="%OnStoreModel">
<Description>
Do the actual work of storing values into the source object.</Description>
<FormalSpec>pSource:Base.DBLogger.Logger</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	set pSource.isActive = ..isActive
	set pSource.name = ..name
	set pSource.logLevelFilter = ##class(Base.DBLogger.LogLevelFilter).get(..logLevelFilterKey)

	quit $$$OK
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="nameIsValidJS">
<ClassMethod>1</ClassMethod>
<FormalSpec>value</FormalSpec>
<Language>javascript</Language>
<ClientMethod>1</ClientMethod>
<Implementation><![CDATA[	return ('' == value) ? 'Name darf nicht leer sein' : '';
]]></Implementation>
</Method>

<Method name="logLevelFilterKeyIsValidJS">
<ClassMethod>1</ClassMethod>
<FormalSpec>value</FormalSpec>
<Language>javascript</Language>
<ClientMethod>1</ClientMethod>
<Implementation><![CDATA[	return ('' == value) ? 'Log Level Filter darf nicht leer sein' : '';
]]></Implementation>
</Method>
</Class>


<Class name="Base.DBLogger.GUI.Loggers">
<Super>Base.DBLogger.GUI.AbstractZENPage</Super>
<TimeChanged>61842,38967.765</TimeChanged>
<TimeCreated>61837,31638.615</TimeCreated>

<Parameter name="PAGENAME">
<Description>
Displayed name of this page.</Description>
<Default>DB Loggers</Default>
</Parameter>

<XData name="Contents">
<Description>
This XML block defines the contents of this page.</Description>
<XMLNamespace>http://www.intersystems.com/zen</XMLNamespace>
<Data><![CDATA[
<page xmlns="http://www.intersystems.com/zen" title="DB Loggers">

<hgroup width="100%">

<vgroup width="5%"/>
<vgroup width="90%">

<spacer height="10"/>

<menu id="menu" layout="horizontal">
<menuItem caption="Loggers" link="Base.DBLogger.GUI.Loggers.cls" containerStyle="background: white; font-weight: bold;"/>
<menuItem caption="Logs" link="Base.DBLogger.GUI.Logs.cls" containerStyle="background: lightgray;"/>
</menu>

<spacer height="30"/>

<dataController id="MasterFilterController" modelClass="Base.DBLogger.GUI.MasterFilterModel" modelId="1"/>

<form id="MasterFilterForm" controllerId="MasterFilterController" layout="horizontal">

<label value="Master Filter: "/>
<spacer width="20"/>
<select name="MasterFilter" dataBinding="logLevelFilterKey" onchange="zenPage.saveMasterFilter();" sql='select "key", "value" from Base_DBLogger.LogLevelFilter' showEmpty="false"/>

</form>

<tableNavigatorBar id="LogsTableNavBar" tablePaneId="LoggersTable"/>

<hgroup width="100%">

<tablePane
id="LoggersTable"
tableName="Base_DBLogger.Logger"
orderByClause="name"
valueColumn="ID"
width="40%"
fixedHeaders="false"
maxRows="100"
pageSize="20"
extraColumnWidth="3%"
showRowNumbers="false"
rowSelect="true"
showZebra="true"
useSnapshot="true"
onselectrow="zenPage.rowSelected(zenThis,which);"
>
<column hidden="true" colName="ID"/>
<column header="Active" colName="isActive" style="text-align:center;"/>
<column header="Package or Class" colName="name"/>
<column header="Filter" colName="logLevelFilter->value"/>
</tablePane>

<spacer width="50"/>

<vgroup valign="top">

<fieldSet legend="Details" cellStyle="padding: 10px;" enclosingStyle="border-style: solid; border-width: 1px; border-color: black;">

<dataController id="LoggerController" modelClass="Base.DBLogger.GUI.LoggerModel"/>

<form id="LoggerForm" controllerId="LoggerController" layout="horizontal">

<checkbox id="IsActiveCheckBox" label="Is Active" dataBinding="isActive" width="100"/>
<text id="NameField" label="Package or Class" dataBinding="name" width="200" maxlength="100"/>
<select label="Filter" dataBinding="logLevelFilterKey" sql='select "key", "value" from Base_DBLogger.LogLevelFilter' showEmpty="false"/>

</form>

<hgroup>
<button caption="Save" onclick="zenPage.saveLogger();"/>
<spacer width="10"/>
<button caption="New" onclick="zenPage.newLogger();"/>
<spacer width="10"/>
<button id="DeleteButton" caption="Delete" onclick="zenPage.deleteLogger();"/>
</hgroup>

</fieldSet>

</vgroup>
</hgroup>
</vgroup>
<vgroup width="5%"/>

</hgroup>

</page>
]]></Data>
</XData>

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

]]></Content>
</UDLText>

<UDLText name="T">
<Content><![CDATA[
//	====	Client Methods:		===============================================

]]></Content>
</UDLText>

<Method name="rowSelected">
<Description><![CDATA[
Row in Master table select; update controller.
<var>which</var> indicates how this event was fired.]]></Description>
<FormalSpec>table,which</FormalSpec>
<Language>javascript</Language>
<ClientMethod>1</ClientMethod>
<Implementation><![CDATA[
	var id = table.getValue();

	if (id == 1)
	{
		zenPage.getComponentById('DeleteButton').setDisabled(true);
		zenPage.getComponentById('NameField').setReadOnly(true);
		zenPage.getComponentById('IsActiveCheckBox').setReadOnly(true);
	}
	else
	{
		zenPage.getComponentById('DeleteButton').setDisabled(false);
		zenPage.getComponentById('NameField').setReadOnly(false);
		zenPage.getComponentById('IsActiveCheckBox').setReadOnly(false);
	}

	var controller = zenPage.getComponentById('LoggerController');
	controller.setProperty('modelId',id);
]]></Implementation>
</Method>

<Method name="saveLogger">
<Language>javascript</Language>
<ClientMethod>1</ClientMethod>
<Implementation><![CDATA[
	zenPage.getComponentById('LoggerForm').save();
	zenPage.getComponentById('LoggersTable').executeQuery(true);
]]></Implementation>
</Method>

<Method name="newLogger">
<Language>javascript</Language>
<ClientMethod>1</ClientMethod>
<Implementation><![CDATA[	zenPage.getComponentById('LoggerController').createNewObject();
]]></Implementation>
</Method>

<Method name="deleteLogger">
<Language>javascript</Language>
<ClientMethod>1</ClientMethod>
<Implementation><![CDATA[
	var controller = zenPage.getComponentById('LoggerController');
	controller.deleteId(controller.getModelId());
	controller.createNewObject();

	zenPage.getComponentById('LoggersTable').executeQuery(true);
]]></Implementation>
</Method>

<Method name="saveMasterFilter">
<Language>javascript</Language>
<ClientMethod>1</ClientMethod>
<Implementation><![CDATA[	zenPage.getComponentById('MasterFilterForm').save();
]]></Implementation>
</Method>
</Class>


<Class name="Base.DBLogger.GUI.Logs">
<Super>Base.DBLogger.GUI.AbstractZENPage</Super>
<TimeChanged>61842,41378.39</TimeChanged>
<TimeCreated>61831,60760.312</TimeCreated>

<Parameter name="PAGENAME">
<Description>
Displayed name of this page.</Description>
<Default>DB Logs</Default>
</Parameter>

<XData name="Contents">
<Description>
This XML block defines the contents of this page.</Description>
<XMLNamespace>http://www.intersystems.com/zen</XMLNamespace>
<Data><![CDATA[
<page xmlns="http://www.intersystems.com/zen" title="DB Logs">

<hgroup width="100%">

<vgroup width="5%"/>
<vgroup width="90%">

<spacer height="10"/>

<menu id="menu" layout="horizontal">
<menuItem caption="Loggers" link="Base.DBLogger.GUI.Loggers.cls" containerStyle="background: lightgray;"/>
<menuItem caption="Logs" link="Base.DBLogger.GUI.Logs.cls" containerStyle="background: white; font-weight: bold;"/>
</menu>

<spacer height="30"/>

<hgroup>
<tableNavigatorBar id="LogsTableNavBar" tablePaneId="LogsTable"/>

<spacer width="20"/>

<button caption="Purge all" onclick="zenPage.purge(0);"/>
<spacer width="10"/>
<button caption="Purge -100" disabled="false" onclick="zenPage.purge(100);"/>
<spacer width="10"/>
<button caption="Purge -1000" disabled="false" onclick="zenPage.purge(1000);"/>
</hgroup>

<tablePane
id="LogsTable"
tableName="Base_DBLogger.LogEntry"
orderByClause="ID desc"
valueColumn="ID"
width="100%"
fixedHeaders="false"
maxRows="1000"
pageSize="20"
extraColumnWidth="3%"
showRowNumbers="true"
rowSelect="false"
showZebra="true"
useSnapshot="true"
>
<condition colName="logLevel" predicate="EQ" value="Fatal" cellStyle="background: plum;" rowStyle="font-weight: bold; color: red;"/>
<condition colName="logLevel" predicate="EQ" value="Error" cellStyle="background: #ff9999;"/>
<condition colName="logLevel" predicate="EQ" value="Warning" cellStyle="background: #ffff99;"/>
<condition colName="logLevel" predicate="EQ" value="Info" cellStyle="background: white;"/>
<condition colName="logLevel" predicate="EQ" value="Debug" cellStyle="background: lightblue;"/>
<column header="Id" colName="ID"/>
<column header="Log Time" colName='"timestamp"' OnDrawCell="DrawTimeStampToDateTime" seed="3" filterType="date"/>
<column header="Type" colName="logLevel" filterType="query" filterQuery="select value from Base_DBLogger.LogLevel where class = 'Base.DBLogger.LogLevel'"/>
<column header="ClassName" colName="className" filterType="text" filterOp="["/>
<column header="MethodName" colName="methodName" filterType="text" filterOp="["/>
<column header="Message" colName="message" filterType="text" filterOp="["/>
<column header="Logger" colName="loggerName" filterType="query" filterQuery="select name from Base_DBLogger.Logger"/>
</tablePane>

</vgroup>
<vgroup width="5%"/>

</hgroup>

</page>
]]></Data>
</XData>

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

]]></Content>
</UDLText>

<UDLText name="T">
<Content><![CDATA[
//	====	Client Methods:		===============================================

]]></Content>
</UDLText>

<Method name="purge">
<ClassMethod>1</ClassMethod>
<FormalSpec>leaveRows:%Integer=0</FormalSpec>
<ZenMethod>1</ZenMethod>
<Implementation><![CDATA[
	do ##class(Base.DBLogger.LogEntry).purge(leaveRows)

	&js<zenPage.getComponentById('LogsTable').executeQuery(true);>
]]></Implementation>
</Method>
</Class>


<Class name="Base.DBLogger.GUI.MasterFilterModel">
<Super>%ZEN.DataModel.ObjectDataModel</Super>
<TimeChanged>61842,41082.453</TimeChanged>
<TimeCreated>61839,60410.859</TimeCreated>

<Property name="logLevelFilterKey">
<Type>%String</Type>
<Parameter name="MAXLEN" value="20"/>
<Parameter name="ZENLABEL" value="Master Filter"/>
</Property>

<Method name="%OnOpenSource">
<Description>
Load an instance of the source object for this DataModel.</Description>
<FormalSpec>pID:%String,pConcurrency:%Integer=-1,*pSC:%Status=$$$OK</FormalSpec>
<ReturnType>%RegisteredObject</ReturnType>
<Implementation><![CDATA[	quit ##class(Base.DBLogger.MasterLogLevelFilter).%OpenId(1)
]]></Implementation>
</Method>

<Method name="%OnSaveSource">
<Description>
Save instance of associated source object.</Description>
<FormalSpec>pSource:Base.DBLogger.MasterLogLevelFilter</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	Set tSC=pSource.%Save()
	If $$$ISOK(tSC) Set ..%id=pSource.%Id()
	Quit tSC
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="%OnLoadModel">
<Description>
Do the actual work of loading values from the source object.</Description>
<FormalSpec>pSource:Base.DBLogger.MasterLogLevelFilter</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	set ..logLevelFilterKey = pSource.masterLogLevelFilter.key
	quit $$$OK
]]></Implementation>
</Method>

<Method name="%OnStoreModel">
<Description>
Do the actual work of storing values into the source object.</Description>
<FormalSpec>pSource:Base.DBLogger.MasterLogLevelFilter</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	set pSource.masterLogLevelFilter = ##class(Base.DBLogger.LogLevelFilter).get(..logLevelFilterKey)
	quit $$$OK
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="logLevelFilterKeyIsValidJS">
<ClassMethod>1</ClassMethod>
<FormalSpec>value</FormalSpec>
<Language>javascript</Language>
<ClientMethod>1</ClientMethod>
<Implementation><![CDATA[	return ('' == value) ? 'Master Log Level Filter darf nicht leer sein' : '';
]]></Implementation>
</Method>
</Class>


<Class name="Base.DBLogger.LogEntry">
<IncludeCode>DBLogger</IncludeCode>
<Super>%Persistent,Base.Support</Super>
<TimeChanged>62416,57239.751876</TimeChanged>
<TimeCreated>61826,38317</TimeCreated>
<Inheritance>right</Inheritance>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Property name="className">
<Type>%String</Type>
<Parameter name="MAXLEN" value="100"/>
</Property>

<Property name="methodName">
<Type>%String</Type>
<Parameter name="MAXLEN" value="50"/>
</Property>

<Property name="loggerName">
<Type>%String</Type>
<Parameter name="MAXLEN" value="100"/>
</Property>

<Property name="logLevel">
<Type>%String</Type>
<Required>1</Required>
<Parameter name="MAXLEN" value="10"/>
</Property>

<Property name="timestamp">
<Type>%String</Type>
<Required>1</Required>
<Parameter name="MAXLEN" value="30"/>
</Property>

<Property name="message">
<Type>%String</Type>
<Parameter name="MAXLEN" value="255"/>
</Property>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="%OnNew">
<FormalSpec>logRequest:Base.DBLogger.LogRequest</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	set ..className = logRequest.location.class
	set ..methodName = logRequest.location.method
	set ..loggerName = logRequest.logger.name
	set ..logLevel = logRequest.logLevel.value
	set ..timestamp = logRequest.timestamp.toDateTime(3, 1, 6)
	set ..message = logRequest.message

	quit $$$OK
]]></Implementation>
</Method>

<Method name="log">
<ClassMethod>1</ClassMethod>
<FormalSpec>logRequest:Base.DBLogger.LogRequest</FormalSpec>
<Implementation><![CDATA[
	set logEntry = ..%New(logRequest)
	if (logEntry = $$$NULLOREF)		quit

	set status = logEntry.%Save()
	if ($$$ISERR(status))		write !, status
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="purge">
<ClassMethod>1</ClassMethod>
<FormalSpec>leaveRows:%Integer=0</FormalSpec>
<Implementation><![CDATA[
	if (leaveRows = 0)
	{
		do ..%DeleteExtent()
	}
	else
	{
		&sql(delete from Base_DBLogger.LogEntry
			where id <= (select max(id) - :leaveRows from Base_DBLogger.LogEntry)
		)

		if (SQLCODE < 0)
		{
			$$$DBLogError("DBLog purge failed with error: " _ SQLCODE)
		}
	}

	$$$DBLogInfo("DBLog purged leaving rows: " _ leaveRows)
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="toString">
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[
	quit "[LogEntry:" _
			..className _ ":" _
			..methodName _ ":" _
			..logLevel _ ":" _
			..message _ ":" _
			..timestamp _
		"]"
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Storage name="Default">
<Type>%Library.CacheStorage</Type>
<DataLocation>^Base.DBLogger.LogEntryD</DataLocation>
<DefaultData>LogEntryDefaultData</DefaultData>
<IdLocation>^Base.DBLogger.LogEntryD</IdLocation>
<IndexLocation>^Base.DBLogger.LogEntryI</IndexLocation>
<StreamLocation>^Base.DBLogger.LogEntryS</StreamLocation>
<Data name="LogEntryDefaultData">
<Structure>listnode</Structure>
<Subscript/>
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
<Value name="2">
<Value>class</Value>
</Value>
<Value name="3">
<Value>method</Value>
</Value>
<Value name="4">
<Value>logLevel</Value>
</Value>
<Value name="5">
<Value>timestamp</Value>
</Value>
<Value name="6">
<Value>message</Value>
</Value>
<Value name="7">
<Value>className</Value>
</Value>
<Value name="8">
<Value>methodName</Value>
</Value>
<Value name="9">
<Value>loggerName</Value>
</Value>
</Data>
</Storage>
</Class>


<Class name="Base.DBLogger.LogLevel">
<Super>Base.CodeAbstract</Super>
<TimeChanged>61842,41168.578</TimeChanged>
<TimeCreated>61826,38418.453</TimeCreated>

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

]]></Content>
</UDLText>

<Parameter name="Debug">
<Default>10</Default>
</Parameter>

<Parameter name="Info">
<Default>20</Default>
</Parameter>

<Parameter name="Warning">
<Default>30</Default>
</Parameter>

<Parameter name="Error">
<Default>40</Default>
</Parameter>

<Parameter name="Fatal">
<Default>50</Default>
</Parameter>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="initialize">
<Description>
write ##class(Base.DBLogger.LogLevel).initialize()</Description>
<ClassMethod>1</ClassMethod>
<Implementation><![CDATA[
	set status = ..%DeleteExtent()
	quit:($$$ISERR(status)) status

	set type = ..new(..#Debug, "Debug",,, .status)
	quit:($$$ISERR(status)) status

	set type = ..new(..#Info, "Info",,, .status)
	quit:($$$ISERR(status)) status

	set type = ..new(..#Warning, "Warning",,, .status)
	quit:($$$ISERR(status)) status

	set type = ..new(..#Error, "Error",,, .status)
	quit:($$$ISERR(status)) status

	set type = ..new(..#Fatal, "Fatal",,, .status)
	quit:($$$ISERR(status)) status

	quit status
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="Debug">
<ClassMethod>1</ClassMethod>
<ReturnType>Base.DBLogger.LogLevel</ReturnType>
<Implementation><![CDATA[	quit ..get(..#Debug)
]]></Implementation>
</Method>

<Method name="Info">
<ClassMethod>1</ClassMethod>
<ReturnType>Base.DBLogger.LogLevel</ReturnType>
<Implementation><![CDATA[	quit ..get(..#Info)
]]></Implementation>
</Method>

<Method name="Warning">
<ClassMethod>1</ClassMethod>
<ReturnType>Base.DBLogger.LogLevel</ReturnType>
<Implementation><![CDATA[	quit ..get(..#Warning)
]]></Implementation>
</Method>

<Method name="Error">
<ClassMethod>1</ClassMethod>
<ReturnType>Base.DBLogger.LogLevel</ReturnType>
<Implementation><![CDATA[	quit ..get(..#Error)
]]></Implementation>
</Method>

<Method name="Fatal">
<ClassMethod>1</ClassMethod>
<ReturnType>Base.DBLogger.LogLevel</ReturnType>
<Implementation><![CDATA[	quit ..get(..#Fatal)
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="isDebug">
<ReturnType>%Boolean</ReturnType>
<Implementation><![CDATA[	quit (..key = ..#Debug)
]]></Implementation>
</Method>

<Method name="isInfo">
<ReturnType>%Boolean</ReturnType>
<Implementation><![CDATA[	quit (..key = ..#Info)
]]></Implementation>
</Method>

<Method name="isWarning">
<ReturnType>%Boolean</ReturnType>
<Implementation><![CDATA[	quit (..key = ..#Warning)
]]></Implementation>
</Method>

<Method name="isError">
<ReturnType>%Boolean</ReturnType>
<Implementation><![CDATA[	quit (..key = ..#Error)
]]></Implementation>
</Method>

<Method name="isFatal">
<ReturnType>%Boolean</ReturnType>
<Implementation><![CDATA[	quit (..key = ..#Fatal)
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Storage name="Default">
<Type>%Library.CacheStorage</Type>
</Storage>
</Class>


<Class name="Base.DBLogger.LogLevelFilter">
<Super>Base.DBLogger.LogLevel</Super>
<TimeChanged>61840,32640.359</TimeChanged>
<TimeCreated>61826,38418.453</TimeCreated>

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

]]></Content>
</UDLText>

<Parameter name="All">
<Default>0</Default>
</Parameter>

<Parameter name="None">
<Default>99</Default>
</Parameter>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="initialize">
<Description>
write ##class(Base.DBLogger.LogLevelFilter).initialize()</Description>
<ClassMethod>1</ClassMethod>
<Implementation><![CDATA[
	set status = ..%DeleteExtent()
	quit:($$$ISERR(status)) status

	set type = ..new(..#All, "All",,, .status)
	quit:($$$ISERR(status)) status

	set type = ..new(..#Debug, "Debug",,, .status)
	quit:($$$ISERR(status)) status

	set type = ..new(..#Info, "Info",,, .status)
	quit:($$$ISERR(status)) status

	set type = ..new(..#Warning, "Warning",,, .status)
	quit:($$$ISERR(status)) status

	set type = ..new(..#Error, "Error",,, .status)
	quit:($$$ISERR(status)) status

	set type = ..new(..#Fatal, "Fatal",,, .status)
	quit:($$$ISERR(status)) status

	set type = ..new(..#None, "None",,, .status)
	quit:($$$ISERR(status)) status

	quit status
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="All">
<ClassMethod>1</ClassMethod>
<ReturnType>Base.DBLogger.LogLevelFilter</ReturnType>
<Implementation><![CDATA[	quit ..get(..#All)
]]></Implementation>
</Method>

<Method name="None">
<ClassMethod>1</ClassMethod>
<ReturnType>Base.DBLogger.LogLevelFilter</ReturnType>
<Implementation><![CDATA[	quit ..get(..#None)
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="isAll">
<ReturnType>%Boolean</ReturnType>
<Implementation><![CDATA[	quit (..key = ..#All)
]]></Implementation>
</Method>

<Method name="isNone">
<ReturnType>%Boolean</ReturnType>
<Implementation><![CDATA[	quit (..key = ..#None)
]]></Implementation>
</Method>

<Method name="allowsLogLevel">
<FormalSpec>logLevel:Base.DBLogger.LogLevel</FormalSpec>
<ReturnType>%Boolean</ReturnType>
<Implementation><![CDATA[	quit logLevel.key >= ..key
]]></Implementation>
</Method>

<Method name="allowsLogRequest">
<FormalSpec>logRequest:Base.DBLogger.LogRequest</FormalSpec>
<ReturnType>%Boolean</ReturnType>
<Implementation><![CDATA[	quit ..allowsLogLevel(logRequest.logLevel)
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Storage name="Default">
<Type>%Library.CacheStorage</Type>
</Storage>
</Class>


<Class name="Base.DBLogger.LogRequest">
<Super>%RegisteredObject,Base.Support</Super>
<TimeChanged>61840,35775.218</TimeChanged>
<TimeCreated>61826,38317</TimeCreated>
<Inheritance>right</Inheritance>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Property name="location">
<Type>Base.StackElement</Type>
<Required>1</Required>
</Property>

<Property name="logLevel">
<Type>Base.DBLogger.LogLevel</Type>
<Required>1</Required>
</Property>

<Property name="timestamp">
<Type>Base.DateTime</Type>
<Required>1</Required>
</Property>

<Property name="message">
<Type>%String</Type>
</Property>

<Property name="logger">
<Type>Base.DBLogger.Logger</Type>
</Property>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="%OnNew">
<FormalSpec>logLevel:Base.DBLogger.LogLevel,message:%String=""</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	set status = $$$OK

	set ..location = ##class(Base.Stack).%New().GetAt(4)
	set ..timestamp = ##class(Base.DateTime).now()
	set ..logLevel = logLevel
	set ..message = message

	quit status
]]></Implementation>
</Method>

<Method name="log">
<ClassMethod>1</ClassMethod>
<FormalSpec>level:Base.DBLogger.LogLevel,message:%String=""</FormalSpec>
<Implementation><![CDATA[
	if ('##class(Base.DBLogger.MasterLogLevelFilter).allowsLogLevel(level))		quit

	set logRequest = ..%New(level, message)
	do ##class(Base.DBLogger.Logger).logRequest(logRequest)
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="toString">
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[
	quit "[LogRequest:" _
			..logLevel.value _ ":" _
			..message _ ":" _
			..location.toString() _ ":" _
			..timestamp.toDateTime() _
		"]"
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>
</Class>


<Class name="Base.DBLogger.Logger">
<IncludeCode>DBLogger</IncludeCode>
<Super>%Persistent,Base.Support</Super>
<TimeChanged>62416,57239.815713</TimeChanged>
<TimeCreated>61826,38317</TimeCreated>
<Inheritance>right</Inheritance>

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

]]></Content>
</UDLText>

<Parameter name="RootLoggerName">
<Default> ROOT</Default>
</Parameter>

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

]]></Content>
</UDLText>

<Property name="name">
<Type>%String</Type>
<Required>1</Required>
<Parameter name="MAXLEN" value="100"/>
</Property>

<Property name="logLevelFilter">
<Type>Base.DBLogger.LogLevelFilter</Type>
<Required>1</Required>
</Property>

<Property name="isActive">
<Type>%Boolean</Type>
<InitialExpression>"1"</InitialExpression>
</Property>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="initialize">
<Description>
	write ##class(Base.DBLogger.Logger).initialize()</Description>
<ClassMethod>1</ClassMethod>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	set status = ..%DeleteExtent()
	if ($$$ISERR(status))			quit $$$NULLOREF

	do ..new(..#RootLoggerName, ##class(Base.DBLogger.LogLevelFilter).Warning(), .status)
	if ($$$ISERR(status))			quit $$$NULLOREF

	do ..new("Base", ##class(Base.DBLogger.LogLevelFilter).Info(), .status)
	if ($$$ISERR(status))			quit $$$NULLOREF

	do ..new("Base.DBLogger", ##class(Base.DBLogger.LogLevelFilter).All(), .status)
	if ($$$ISERR(status))			quit $$$NULLOREF

	$$$DBLogInfo("DBLogger successfully initialized, logging is enabled")

	quit status
]]></Implementation>
</Method>

<Method name="new">
<ClassMethod>1</ClassMethod>
<FormalSpec><![CDATA[name:%String,logLevelFilter:Base.DBLogger.LogLevelFilter,&status:%Status]]></FormalSpec>
<ReturnType>Base.DBLogger.Logger</ReturnType>
<Implementation><![CDATA[
	set logger = ..%New()
	if (logger = $$$NULLOREF)		quit $$$NULLOREF

	set logger.name = name
	set logger.logLevelFilter = logLevelFilter

	set status = logger.%Save()
	if ($$$ISERR(status))			quit $$$NULLOREF

	quit logger
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="getLoggerInChargeForLogRequest">
<ClassMethod>1</ClassMethod>
<FormalSpec>logRequest:Base.DBLogger.LogRequest</FormalSpec>
<ReturnType>Base.DBLogger.Logger</ReturnType>
<Implementation><![CDATA[
	set inCharge = $$$NULLOREF
	set name = logRequest.location.class

	for i=$length(name, "."):-1:1
	{
		set parentName = $piece(name, ".", 1, i)
		set logger = ..get(parentName)

		if ((logger '= $$$NULLOREF) && (logger.isActive))
		{
			set inCharge = logger
			quit
		}
	}

	if (inCharge = $$$NULLOREF)		quit ..getRootLogger()
	quit inCharge
]]></Implementation>
</Method>

<Method name="get">
<Description>
	write ##class(Base.DBLogger.Logger).get("asdf.qwer.asdf.qwer")
	write ##class(Base.DBLogger.Logger).get("Base.Egal")</Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>name:%String</FormalSpec>
<ReturnType>Base.DBLogger.Logger</ReturnType>
<Implementation><![CDATA[
	set id = ""
	&sql(select %ID into id from Base_DBLogger.Logger where name = :name)

	//	Return null if id is empty:
	quit ..%OpenId(id)
]]></Implementation>
</Method>

<Method name="getRootLogger">
<ClassMethod>1</ClassMethod>
<ReturnType>Base.DBLogger.Logger</ReturnType>
<Implementation><![CDATA[	quit ..get(..#RootLoggerName)
]]></Implementation>
</Method>

<Method name="logRequest">
<ClassMethod>1</ClassMethod>
<FormalSpec>logRequest:Base.DBLogger.LogRequest</FormalSpec>
<Implementation><![CDATA[
	set logger = ..getLoggerInChargeForLogRequest(logRequest)
	do logger.log(logRequest)
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="log">
<FormalSpec>logRequest</FormalSpec>
<Implementation><![CDATA[
	if ('..logLevelFilter.allowsLogRequest(logRequest))		quit

	set logRequest.logger = ##this
	do ##class(Base.DBLogger.LogEntry).log(logRequest)
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="toString">
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[
	quit "[Logger:" _
			..isActive _ ":" _
			..name _ ":" _
			..logLevelFilter.value _
		"]"
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="test">
<Description>
	do ##class(Base.DBLogger.Logger).test()</Description>
<ClassMethod>1</ClassMethod>
<Implementation><![CDATA[
	$$$DBLogDebug("Test-Debug")
	$$$DBLogInfo("Test-Info")
	$$$DBLogWarning("Test-Warnung")
	$$$DBLogError("Test-Error")
	$$$DBLogFatal("Test-Fatal")
]]></Implementation>
</Method>

<Storage name="Default">
<Type>%Library.CacheStorage</Type>
<DataLocation>^Base.DBLogger.LoggerD</DataLocation>
<DefaultData>LoggerDefaultData</DefaultData>
<IdLocation>^Base.DBLogger.LoggerD</IdLocation>
<IndexLocation>^Base.DBLogger.LoggerI</IndexLocation>
<StreamLocation>^Base.DBLogger.LoggerS</StreamLocation>
<Data name="LoggerDefaultData">
<Structure>listnode</Structure>
<Subscript/>
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
<Value name="2">
<Value>name</Value>
</Value>
<Value name="3">
<Value>logLevelFilter</Value>
</Value>
<Value name="4">
<Value>isActive</Value>
</Value>
</Data>
</Storage>
</Class>


<Class name="Base.DBLogger.MasterLogLevelFilter">
<Super>%Persistent,Base.Support</Super>
<TimeChanged>62416,57239.886129</TimeChanged>
<TimeCreated>61839,54821.14</TimeCreated>
<Inheritance>right</Inheritance>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Property name="masterLogLevelFilter">
<Type>Base.DBLogger.LogLevelFilter</Type>
</Property>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="initialize">
<Description>
write ##class(Base.DBLogger.MasterLogLevelFilter).initialize()</Description>
<ClassMethod>1</ClassMethod>
<Implementation><![CDATA[
	set status = ..%DeleteExtent()
	quit:($$$ISERR(status)) status

	set masterFilter = ..%New()
	set masterFilter.masterLogLevelFilter = ##class(Base.DBLogger.LogLevelFilter).All()

	quit masterFilter.%Save()
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="getMasterFilter">
<Description>
write ##class(Base.DBLogger.MasterLogLevelFilter).getMasterFilter()</Description>
<ClassMethod>1</ClassMethod>
<ReturnType>Base.DBLogger.LogLevelFilter</ReturnType>
<Implementation><![CDATA[	quit ..%OpenId(1).masterLogLevelFilter
]]></Implementation>
</Method>

<Method name="setMasterFilter">
<Description>
write ##class(Base.DBLogger.MasterLogLevelFilter).setMasterFilter(...)</Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>filter:Base.DBLogger.LogLevelFilter</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	set masterFilter = ..%OpenId(1)
	set masterFilter.masterLogLevelFilter = filter

	quit masterFilter.%Save()
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="allowsLogLevel">
<ClassMethod>1</ClassMethod>
<FormalSpec>logLevel:Base.DBLogger.LogLevel</FormalSpec>
<ReturnType>%Boolean</ReturnType>
<Implementation><![CDATA[	quit ..getMasterFilter().allowsLogLevel(logLevel)
]]></Implementation>
</Method>

<Method name="allowsLogRequest">
<ClassMethod>1</ClassMethod>
<FormalSpec>logRequest:Base.DBLogger.LogRequest</FormalSpec>
<ReturnType>%Boolean</ReturnType>
<Implementation><![CDATA[	quit ..allowsLogLevel(logRequest.logLevel)
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="toString">
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[	quit " MasterFilter:" _ ..masterLogLevelFilter.toString()
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Storage name="Default">
<Type>%Library.CacheStorage</Type>
<DataLocation>^Base.DBLogger.MasterLogLe4840D</DataLocation>
<DefaultData>MasterLogLevelFilterDefaultData</DefaultData>
<IdLocation>^Base.DBLogger.MasterLogLe4840D</IdLocation>
<IndexLocation>^Base.DBLogger.MasterLogLe4840I</IndexLocation>
<StreamLocation>^Base.DBLogger.MasterLogLe4840S</StreamLocation>
<Data name="MasterLogLevelFilterDefaultData">
<Structure>listnode</Structure>
<Subscript/>
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
<Value name="2">
<Value>masterLogLevelFilter</Value>
</Value>
</Data>
</Storage>
</Class>


<Class name="Base.DateTime">
<Description>
	Instances of this class represent a date + time value (with fractional seconds).

		Last change: 22.03.2010 by Lem
</Description>
<Super>%SerialObject,%XML.Adaptor,%Populate</Super>
<TimeChanged>61842,36740.093</TimeChanged>
<TimeCreated>61792,27098.343</TimeCreated>
<Inheritance>right</Inheritance>

<Parameter name="SecsPerDay">
<Description>
	The number of seconds per day (is needed for arithmetic)</Description>
<Default>86400</Default>
</Parameter>

<Parameter name="SecsPerMinute">
<Description>
	The number of seconds per minute (is needed for arithmetic)</Description>
<Default>60</Default>
</Parameter>

<Parameter name="MinsPerHour">
<Description>
	The number of minutes per hour (is needed for arithmetic)</Description>
<Default>60</Default>
</Parameter>

<Parameter name="HoursPerDay">
<Description>
	The number of hours per day (is needed for arithmetic)</Description>
<Default>24</Default>
</Parameter>

<Parameter name="DaysPerWeek">
<Description>
	The number of days per week (is needed for arithmetic)</Description>
<Default>7</Default>
</Parameter>

<Parameter name="StandardDateFormat">
<Description>
	The date format used for the toString() method</Description>
<Default>4</Default>
</Parameter>

<Parameter name="StandardTimeFormat">
<Description>
	The time format used for the toString() method</Description>
<Default>1</Default>
</Parameter>

<Parameter name="StandardTimePrecision">
<Description>
	The time precision used for the toString() method</Description>
<Default>3</Default>
</Parameter>

<Parameter name="InternalDateFormat">
<Description>
	The internal date format. Don't change, otherwise many functions won't work any more!</Description>
<Default>3</Default>
</Parameter>

<Parameter name="InternalTimeFormat">
<Description>
	The internal time format. Don't change, otherwise many functions won't work any more!</Description>
<Default>1</Default>
</Parameter>

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

]]></Content>
</UDLText>

<Property name="horolog">
<Description>
	Internal date/time representation is in horolog format.
		It's capable of arithmetic, fractional seconds, and is very slim.</Description>
<Type>%String</Type>
<Parameter name="MAXLEN" value="20"/>
</Property>

<Property name="precision">
<Description>
		Number of fractional seconds digits</Description>
<Type>%Integer</Type>
<Parameter name="MAXVAL" value="6"/>
<Parameter name="MINVAL" value="0"/>
</Property>

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

]]></Content>
</UDLText>

<Method name="OnPopulate">
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	set ..horolog = $zutil(188)
	set ..precision = ..#StandardTimePrecision

	quit $$$OK
]]></Implementation>
</Method>

<Method name="%OnNew">
<Description>
	Create a new instance. If a horolog is supplied, take this, otherwise take $zutil(188) = now incl. fractional seconds</Description>
<FormalSpec>horolog:%String=""</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	set ..horolog = $case(horolog,"":$zutil(188),:horolog)
	set ..precision = ..#StandardTimePrecision

	quit $$$OK
]]></Implementation>
</Method>

<Method name="newFromHorolog">
<Description>
	Convenience method, easier to read</Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>horolog:%String</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[	quit ..%New(horolog)
]]></Implementation>
</Method>

<Method name="newFromTimeStamp">
<Description>
	Create a new instance according to datetime, which is in %TimeStamp (= ODBC) format.</Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>timeStamp:%String</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[	quit ..newFromDateTime(timeStamp, 3, 1)
]]></Implementation>
</Method>

<Method name="newFromDate">
<Description>
	Create a new instance according to date and dFormat.</Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>date:%String,dFormat:%Integer=..#StandardDateFormat</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[	quit ..%New($zdateh(date, dFormat))
]]></Implementation>
</Method>

<Method name="newFromDateTime">
<Description>
	Create a new instance according to datetime, dFormat, and tFormat.</Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>datetime:%String,dFormat:%Integer=..#StandardDateFormat,tFormat:%Integer=..#StandardTimeFormat</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[	quit ..%New($zdatetimeh(datetime, dFormat, tFormat))
]]></Implementation>
</Method>

<Method name="new">
<Description>
	Create a new instance with the given data. hour, minute and second are optional.</Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>year:%Integer,month:%Integer,day:%Integer,hour:%Integer=0,minute:%Integer=0,second:%Float=0.0</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[
	set odbcString = year _ "-"
					_ ##class(Base.String).fillLeftWithZeros(month) _ "-"
					_ ##class(Base.String).fillLeftWithZeros(day) _ " "
					_ ##class(Base.String).fillLeftWithZeros(hour) _ ":"
					_ ##class(Base.String).fillLeftWithZeros(minute) _ ":"
					_ ##class(Base.String).fillLeftWithZeros(second)
	quit ..%New($zdatetimeh(odbcString, ..#InternalDateFormat, ..#InternalTimeFormat))
]]></Implementation>
</Method>

<Method name="now">
<Description>
	Convenience method, easy to read. Create a new instance representing the date and time NOW, incl. fractional seconds.</Description>
<ClassMethod>1</ClassMethod>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[	quit ..%New()
]]></Implementation>
</Method>

<Method name="nowUTC">
<Description>
	Create a new instance representing the date and time NOW in UTC, incl. fractional seconds.</Description>
<ClassMethod>1</ClassMethod>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[	quit ..%New($ztimestamp)
]]></Implementation>
</Method>

<Method name="today">
<Description>
	Create a new instance representing today at 00:00:00.</Description>
<ClassMethod>1</ClassMethod>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[	quit ..%New(..horologDatePart($horolog))
]]></Implementation>
</Method>

<Method name="tomorrow">
<Description>
	Create a new instance representing tomorrow at 00:00:00.</Description>
<ClassMethod>1</ClassMethod>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[	quit ..inDays(1)
]]></Implementation>
</Method>

<Method name="yesterday">
<Description>
	Create a new instance representing yesterday at 00:00:00.</Description>
<ClassMethod>1</ClassMethod>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[	quit ..beforeDays(1)
]]></Implementation>
</Method>

<Method name="inDays">
<Description>
	Create a new instance representing the day in 'in' days at 00:00:00. 'in' can be negative, too.</Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>in:%Integer</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[	quit ..%New(..horologDatePart($horolog) + in)
]]></Implementation>
</Method>

<Method name="beforeDays">
<Description>
	Create a new instance representing the day before 'before' days at 00:00:00. 'before' can be negative, too.</Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>before:%Integer</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[	quit ..inDays(-before)
]]></Implementation>
</Method>

<Method name="copy">
<Description>
	Make a copy of this instance.</Description>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[	quit ..%New(..horolog)
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="getYear">
<ReturnType>%Integer</ReturnType>
<Implementation><![CDATA[	quit $inumber($piece(..toDateInternal(), "-", 1), "")
]]></Implementation>
</Method>

<Method name="getMonth">
<ReturnType>%Integer</ReturnType>
<Implementation><![CDATA[	quit $inumber($piece(..toDateInternal(), "-", 2), "")
]]></Implementation>
</Method>

<Method name="getDay">
<ReturnType>%Integer</ReturnType>
<Implementation><![CDATA[	quit $inumber($piece(..toDateInternal(), "-", 3), "")
]]></Implementation>
</Method>

<Method name="getHour">
<ReturnType>%Integer</ReturnType>
<Implementation><![CDATA[	quit $inumber($piece(..toTimeInternal(), ":", 1), "")
]]></Implementation>
</Method>

<Method name="getMinute">
<ReturnType>%Integer</ReturnType>
<Implementation><![CDATA[	quit $inumber($piece(..toTimeInternal(), ":", 2), "")
]]></Implementation>
</Method>

<Method name="getSecond">
<ReturnType>%Float</ReturnType>
<Implementation><![CDATA[	quit $inumber($piece(..toTimeInternal(), ":", 3), "")
]]></Implementation>
</Method>

<Method name="getPrecision">
<ReturnType>%Integer</ReturnType>
<Implementation><![CDATA[	quit ..precision
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="setYear">
<Description>
	Set the year. If out of range, raise an error.</Description>
<FormalSpec>year:%Integer</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[
	set odbcString = ..toDateInternal()
	set $piece(odbcString, "-", 1) = year
	set ..horolog = $zdateh(odbcString, ..#InternalDateFormat) _ "," _ ..getTimePart()

	quit ##this
]]></Implementation>
</Method>

<Method name="setMonth">
<Description>
	Set the month (1-12). If out of range, raise an error.</Description>
<FormalSpec>month:%Integer</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[
	set odbcString = ..toDateInternal()
	set $piece(odbcString, "-", 2) = month
	set ..horolog = $zdateh(odbcString, ..#InternalDateFormat) _ "," _ ..getTimePart()

	quit ##this
]]></Implementation>
</Method>

<Method name="setDay">
<Description>
	Set the day. If out of range, raise an error.</Description>
<FormalSpec>day:%Integer</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[
	set odbcString = ..toDateInternal()
	set $piece(odbcString, "-", 3) = day
	set ..horolog = $zdateh(odbcString, ..#InternalDateFormat) _ "," _ ..getTimePart()

	quit ##this
]]></Implementation>
</Method>

<Method name="setHour">
<Description>
	Set the hours. If out of range, raise an error.</Description>
<FormalSpec>hour:%Integer</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[
	set odbcString = ..toTimeInternal()
	set $piece(odbcString, ":", 1) = hour
	set ..horolog = ..getDatePart() _ "," _ $ztimeh(odbcString, ..#InternalTimeFormat)

	quit ##this
]]></Implementation>
</Method>

<Method name="setMinute">
<Description>
	Set the minutes. If out of range, raise an error.</Description>
<FormalSpec>min:%Integer</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[
	set odbcString = ..toTimeInternal()
	set $piece(odbcString, ":", 2) = min
	set ..horolog = ..getDatePart() _ "," _ $ztimeh(odbcString, ..#InternalTimeFormat)

	quit ##this
]]></Implementation>
</Method>

<Method name="setSecond">
<Description>
	Set the seconds, can include fractional seconds. If out of range, raise an error.</Description>
<FormalSpec>sex:%Float</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[
	set odbcString = ..toTimeInternal()
	set $piece(odbcString, ":", 3) = sex
	set ..horolog = ..getDatePart() _ "," _ $ztimeh(odbcString, ..#InternalTimeFormat)

	quit ##this
]]></Implementation>
</Method>

<Method name="setPrecision">
<Description>
	Set the fractional seconds precision. If out of range, raise an error.</Description>
<FormalSpec>precision:%Integer=..#StandardTimePrecision</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	if ((precision < 0) || (precision > 6))		quit $$$ERROR("Invalid precision, must be between 0 and 6")
	set ..precision = precision

	quit $$$OK
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="addYears">
<Description>
	Add years to the current instance. Negative values are allowed, too.</Description>
<FormalSpec>years:%Integer</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[
	//	The implementation is different than the other add* methods because:
	//		nr. of days is not constant due to leap years
	//		over- and underflow can not happen
	quit ..setYear(..getYear() + years)
]]></Implementation>
</Method>

<Method name="addMonths">
<Description>
		NOT YET IMPLEMENTED!
	Add months to the current instance. Negative values are allowed, too.</Description>
<FormalSpec>months:%Integer</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[	quit $$$ERROR("Not yet implemented")
]]></Implementation>
</Method>

<Method name="addWeeks">
<Description>
	Add weeks to the current instance. Negative values are allowed, too.</Description>
<FormalSpec>weeks:%Integer</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[	quit ..addDays(weeks * ..#DaysPerWeek)
]]></Implementation>
</Method>

<Method name="addDays">
<Description>
	Add days to the current instance. Negative values are allowed, too.</Description>
<FormalSpec>days:%Integer</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[	quit ..addHours(days * ..#HoursPerDay)
]]></Implementation>
</Method>

<Method name="addHours">
<Description>
	Add hours to the current instance. Negative values are allowed, too.</Description>
<FormalSpec>hours:%Integer</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[	quit ..addMinutes(hours * ..#MinsPerHour)
]]></Implementation>
</Method>

<Method name="addMinutes">
<Description>
	Add minutes to the current instance. Negative values are allowed, too.</Description>
<FormalSpec>mins:%Integer</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[	quit ..addSeconds(mins * ..#SecsPerMinute)
]]></Implementation>
</Method>

<Method name="addSeconds">
<Description>
	Add seconds to the current instance. Negative values and fractions are allowed, too.</Description>
<FormalSpec>secs:%Float</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[
	set newSecs = ..getTimePart() + secs

	set overflow = newSecs \ ..#SecsPerDay
	set remainder = newSecs # ..#SecsPerDay

	//	Special handling of underflow:
	//	Cache has a very strange opinion about calculating the division remainder of negative numbers:
	//			-10 # 3 -> 2 ???!!!
	if ((newSecs < 0) && (remainder > 0))		set overflow = overflow - 1

	set newDatePart = ..getDatePart() + overflow
	set newTimePart = remainder

	set ..horolog = newDatePart _ "," _ newTimePart
	
	quit ##this
]]></Implementation>
</Method>

<Method name="addDuration">
<Description>
	Add the duration to the current instance.
	Since durations are never negative, use subtractDuration(duration) for subtraction.</Description>
<FormalSpec>duration:Base.Duration</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[	quit ..addSeconds(duration.seconds)
]]></Implementation>
</Method>

<Method name="subtractDuration">
<Description>
	Subtract the duration from the current instance (durations are never negative).</Description>
<FormalSpec>duration:Base.Duration</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[	quit ..addSeconds(-duration.seconds)
]]></Implementation>
</Method>

<Method name="durationBetween">
<Description>
	Return the duration between the current instance and dateTime.
	The duration returned is never negative, so it's actually the 'absolute' duration.</Description>
<FormalSpec>dateTime:Base.DateTime</FormalSpec>
<ReturnType>Base.Duration</ReturnType>
<Implementation><![CDATA[
	//	dayDiff is always positive, secsDiff might be negative.

	if (..isBefore(dateTime))
	{
		set dayDiff = dateTime.getDatePart() - ..getDatePart()
		set secsDiff = dateTime.getTimePart() - ..getTimePart()
	}
	else
	{
		set dayDiff = ..getDatePart() - dateTime.getDatePart()
		set secsDiff = ..getTimePart() - dateTime.getTimePart()
	}

	quit ##class(Base.Duration).%New((dayDiff * ..#SecsPerDay) + secsDiff)
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="isEqual">
<Description>
	Return true if the current instance and dateTime are equal, false otherwise.</Description>
<FormalSpec>dateTime:Base.DateTime</FormalSpec>
<ReturnType>%Boolean</ReturnType>
<Implementation><![CDATA[	quit (..horolog = dateTime.horolog)
]]></Implementation>
</Method>

<Method name="isNotEqual">
<Description>
	Return true if the current instance and dateTime are not equal, false otherwise.</Description>
<FormalSpec>dateTime:Base.DateTime</FormalSpec>
<ReturnType>%Boolean</ReturnType>
<Implementation><![CDATA[	quit '(..isEqual(dateTime))
]]></Implementation>
</Method>

<Method name="isBefore">
<Description>
	Return true if the current instance is before dateTime, false otherwise.</Description>
<FormalSpec>dateTime:Base.DateTime</FormalSpec>
<ReturnType>%Boolean</ReturnType>
<Implementation><![CDATA[
	//	Compare the dates. If they are equal, compare the times:
	if (..getDatePart() = dateTime.getDatePart())
	{
		quit (..getTimePart() < dateTime.getTimePart())
	}
	else
	{
		quit (..getDatePart() < dateTime.getDatePart())
	}
]]></Implementation>
</Method>

<Method name="isAfter">
<Description>
	Return true if the current instance is after dateTime, false otherwise.</Description>
<FormalSpec>dateTime:Base.DateTime</FormalSpec>
<ReturnType>%Boolean</ReturnType>
<Implementation><![CDATA[	quit dateTime.isBefore(##this)
]]></Implementation>
</Method>

<Method name="isBetween">
<Description>
	Return true if the current instance is between (excluding) the two dateTimes, false otherwise.</Description>
<FormalSpec>from:Base.DateTime,to:Base.DateTime</FormalSpec>
<ReturnType>%Boolean</ReturnType>
<Implementation><![CDATA[	quit (from.isBefore(##this) && to.isAfter(##this))
]]></Implementation>
</Method>

<Method name="isNotBetween">
<Description>
	Return true if the current instance is not between (including) the two dateTimes, false otherwise.</Description>
<FormalSpec>from:Base.DateTime,to:Base.DateTime</FormalSpec>
<ReturnType>%Boolean</ReturnType>
<Implementation><![CDATA[	quit '(..isBetween(from, to))
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="toHorolog">
<Description>
	Return horolog-formatted string</Description>
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[	quit ..horolog
]]></Implementation>
</Method>

<Method name="toDate">
<Description>
	Return the date in the given format (default is the standard date format)</Description>
<FormalSpec>dFormat:%Integer=..#StandardDateFormat</FormalSpec>
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[	quit $zdate(..horolog, dFormat)
]]></Implementation>
</Method>

<Method name="toTime">
<Description>
	Return the time in the given format (default is the standard time format)</Description>
<FormalSpec>tFormat:%Integer=..#StandardTimeFormat,tPrecision:%Integer=..precision</FormalSpec>
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[	quit $ztime(..getTimePart(), tFormat, tPrecision)
]]></Implementation>
</Method>

<Method name="toDateTime">
<Description>
	Return the date and time in the given formats (defaults are the standard date and time formats)</Description>
<FormalSpec>dFormat:%Integer=..#StandardDateFormat,tFormat:%Integer=..#StandardTimeFormat,tPrecision:%Integer=..precision</FormalSpec>
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[	quit $zdatetime(..horolog, dFormat, tFormat, tPrecision)
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="fromHorolog">
<Description>
	Set the date and time according to the given horolog.</Description>
<FormalSpec>horolog:%String</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[
	set ..horolog = horolog
	quit ##this
]]></Implementation>
</Method>

<Method name="fromTimeStamp">
<Description>
	Set the date and time according to datetime, which is in %TimeStamp (= ODBC) format.</Description>
<FormalSpec>timeStamp:%String</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[	quit ..fromDateTime(timeStamp, 3, 1)
]]></Implementation>
</Method>

<Method name="fromDate">
<Description>
	Set the date according to the given date. Time is set to 00:00:00</Description>
<FormalSpec>date:%String,dFormat:%Integer=..#StandardDateFormat</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[
	set ..horolog = $zdateh(date, dFormat)
	quit ##this
]]></Implementation>
</Method>

<Method name="fromDateTime">
<Description>
	Set the date and time according to the given date and time.</Description>
<FormalSpec>datetime:%String,dFormat:%Integer=..#StandardDateFormat,tFormat:%Integer=..#StandardTimeFormat</FormalSpec>
<ReturnType>Base.DateTime</ReturnType>
<Implementation><![CDATA[
	set ..horolog = $zdatetimeh(datetime, dFormat, tFormat)
	quit ##this
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="toString">
<Description>
	For easy testing.</Description>
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[	quit "[DateTime:" _ $zdatetime(..horolog, ..#StandardDateFormat, ..#StandardTimeFormat, ..precision) _ "]"
]]></Implementation>
</Method>

<Method name="write">
<Description>
	For easy testing.</Description>
<Implementation><![CDATA[	write ..toString()
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="getDatePart">
<Description>
		Return the date part of the horolog property</Description>
<Internal>1</Internal>
<Private>1</Private>
<ReturnType>%Integer</ReturnType>
<Implementation><![CDATA[	quit ..horologDatePart(..horolog)
]]></Implementation>
</Method>

<Method name="getTimePart">
<Description>
		Return the time part of the horolog property including fractional seconds</Description>
<Internal>1</Internal>
<Private>1</Private>
<ReturnType>%Float</ReturnType>
<Implementation><![CDATA[	quit ..horologTimePart(..horolog)
]]></Implementation>
</Method>

<Method name="toDateInternal">
<Description>
	Return the date in the internal format</Description>
<Internal>1</Internal>
<Private>1</Private>
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[	quit $zdate(..horolog, ..#InternalDateFormat)
]]></Implementation>
</Method>

<Method name="toTimeInternal">
<Description>
	Return the time in the internal format, with the individual instance's precision</Description>
<Internal>1</Internal>
<Private>1</Private>
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[	quit $ztime(..getTimePart(), ..#InternalTimeFormat, ..precision)
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="horologDatePart">
<Description>
[Previously private]</Description>
<Internal>1</Internal>
<ClassMethod>1</ClassMethod>
<FormalSpec>horolog</FormalSpec>
<ReturnType>%Integer</ReturnType>
<Implementation><![CDATA[	quit $piece(horolog, ",", 1)
]]></Implementation>
</Method>

<Method name="horologTimePart">
<Description>
[Previously private]</Description>
<Internal>1</Internal>
<ClassMethod>1</ClassMethod>
<FormalSpec>horolog</FormalSpec>
<ReturnType>%Float</ReturnType>
<Implementation><![CDATA[	quit $piece(horolog, ",", 2)
]]></Implementation>
</Method>

<Storage name="Default">
<Type>%Library.CacheSerialState</Type>
<State>DateTimeState</State>
<StreamLocation>^Base.DateTimeS</StreamLocation>
<Data name="DateTimeState">
<Structure>listnode</Structure>
<Subscript/>
<Value name="1">
<Value>horolog</Value>
</Value>
<Value name="2">
<Value>precision</Value>
</Value>
</Data>
</Storage>
</Class>


<Class name="Base.Duration">
<Description>
	Instances of this class represent a duration (days, hours, minutes and seconds, without fractional seconds).
		It's not possible to create a negative duration. If you try, the resulting duration is 0:00:00:00.

		Last change: 09.03.2010 by Lem
</Description>
<Super>%SerialObject,%XML.Adaptor</Super>
<TimeChanged>61819,59638.437</TimeChanged>
<TimeCreated>61792,70922.875</TimeCreated>
<Inheritance>right</Inheritance>

<Parameter name="SecsPerDay">
<Description>
	The number of seconds per day (is needed for arithmetic)</Description>
<Default>86400</Default>
</Parameter>

<Parameter name="SecsPerHour">
<Description>
	The number of seconds per hour (is needed for arithmetic)</Description>
<Default>3600</Default>
</Parameter>

<Parameter name="SecsPerMinute">
<Description>
	The number of seconds per minute (is needed for arithmetic)</Description>
<Default>60</Default>
</Parameter>

<Parameter name="DurationStringSeparator">
<Description>
	The internal separator. Don't change, otherwise many functions won't work any more!</Description>
<Default>:</Default>
</Parameter>

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

]]></Content>
</UDLText>

<Property name="seconds">
<Description>
	Internal duration representation is the number of seconds. It's capable of arithmetic and is very slim.</Description>
<Type>%Integer</Type>
<Parameter name="MINVAL" value="0"/>
</Property>

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

]]></Content>
</UDLText>

<Method name="%OnNew">
<Description>
	Create a new instance.</Description>
<FormalSpec>seconds:%Integer=0</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	do ..basicSetSeconds(seconds)
	quit $$$OK
]]></Implementation>
</Method>

<Method name="new">
<Description>
	Create a new instance with the given data. All are optional.</Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>days:%Integer=0,hours:%Integer=0,minutes:%Integer=0,seconds:%Integer=0</FormalSpec>
<ReturnType>Base.Duration</ReturnType>
<Implementation><![CDATA[	quit ..%New((days * ..#SecsPerDay) + (hours * ..#SecsPerHour) + (minutes * ..#SecsPerMinute) + seconds)
]]></Implementation>
</Method>

<Method name="copy">
<Description>
	Make a copy of this instance.</Description>
<ReturnType>Base.Duration</ReturnType>
<Implementation><![CDATA[	quit ..%New(..seconds)
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="getDays">
<ReturnType>%Integer</ReturnType>
<Implementation><![CDATA[	quit $inumber($piece(..toDurationString(), ..#DurationStringSeparator, 1), "")
]]></Implementation>
</Method>

<Method name="getHours">
<ReturnType>%Integer</ReturnType>
<Implementation><![CDATA[	quit $inumber($piece(..toDurationString(), ..#DurationStringSeparator, 2), "")
]]></Implementation>
</Method>

<Method name="getMinutes">
<ReturnType>%Integer</ReturnType>
<Implementation><![CDATA[	quit $inumber($piece(..toDurationString(), ..#DurationStringSeparator, 3), "")
]]></Implementation>
</Method>

<Method name="getSeconds">
<ReturnType>%Integer</ReturnType>
<Implementation><![CDATA[	quit $inumber($piece(..toDurationString(), ..#DurationStringSeparator, 4), "")
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="setDays">
<Description>
	Set the days</Description>
<FormalSpec>days:%Integer</FormalSpec>
<ReturnType>Base.Duration</ReturnType>
<Implementation><![CDATA[
	set durationString = ..toDurationString()
	set $piece(durationString, ..#DurationStringSeparator, 1) = days
	quit ..fromDurationString(durationString)
]]></Implementation>
</Method>

<Method name="setHours">
<Description>
	Set the hours.</Description>
<FormalSpec>hours:%Integer</FormalSpec>
<ReturnType>Base.Duration</ReturnType>
<Implementation><![CDATA[
	set durationString = ..toDurationString()
	set $piece(durationString, ..#DurationStringSeparator, 2) = hours
	quit ..fromDurationString(durationString)
]]></Implementation>
</Method>

<Method name="setMinutes">
<Description>
	Set the minutes.</Description>
<FormalSpec>mins:%Integer</FormalSpec>
<ReturnType>Base.Duration</ReturnType>
<Implementation><![CDATA[
	set durationString = ..toDurationString()
	set $piece(durationString, ..#DurationStringSeparator, 3) = mins
	quit ..fromDurationString(durationString)
]]></Implementation>
</Method>

<Method name="setSeconds">
<Description>
	Set the seconds.</Description>
<FormalSpec>sex:%Integer</FormalSpec>
<ReturnType>Base.Duration</ReturnType>
<Implementation><![CDATA[
	set durationString = ..toDurationString()
	set $piece(durationString, ..#DurationStringSeparator, 4) = sex
	quit ..fromDurationString(durationString)
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="addDays">
<Description>
	Add days to the current instance. Negative values are allowed, too.</Description>
<FormalSpec>days:%Integer</FormalSpec>
<ReturnType>Base.Duration</ReturnType>
<Implementation><![CDATA[	quit ..addSeconds(days * ..#SecsPerDay)
]]></Implementation>
</Method>

<Method name="addHours">
<Description>
	Add hours to the current instance. Negative values are allowed, too.</Description>
<FormalSpec>hours:%Integer</FormalSpec>
<ReturnType>Base.Duration</ReturnType>
<Implementation><![CDATA[	quit ..addSeconds(hours * ..#SecsPerHour)
]]></Implementation>
</Method>

<Method name="addMinutes">
<Description>
	Add minutes to the current instance. Negative values are allowed, too.</Description>
<FormalSpec>mins:%Integer</FormalSpec>
<ReturnType>Base.Duration</ReturnType>
<Implementation><![CDATA[	quit ..addSeconds(mins * ..#SecsPerMinute)
]]></Implementation>
</Method>

<Method name="addSeconds">
<Description>
	Add seconds to the current instance. Negative values are allowed, too.</Description>
<FormalSpec>secs:%Integer</FormalSpec>
<ReturnType>Base.Duration</ReturnType>
<Implementation><![CDATA[	quit ..basicSetSeconds(..seconds + secs)
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="isEqual">
<Description>
	Return true if the current instance and duration are equal, false otherwise.</Description>
<FormalSpec>duration:Base.Duration</FormalSpec>
<ReturnType>%Boolean</ReturnType>
<Implementation><![CDATA[	quit (..seconds = duration.seconds)
]]></Implementation>
</Method>

<Method name="isNotEqual">
<Description>
	Return true if the current instance and duration are not equal, false otherwise.</Description>
<FormalSpec>duration:Base.Duration</FormalSpec>
<ReturnType>%Boolean</ReturnType>
<Implementation><![CDATA[	quit '(..isEqual(duration))
]]></Implementation>
</Method>

<Method name="isShorterThan">
<Description>
	Return true if the current instance is shorter than duration, false otherwise.</Description>
<FormalSpec>duration:Base.Duration</FormalSpec>
<ReturnType>%Boolean</ReturnType>
<Implementation><![CDATA[	quit (..seconds < duration.seconds)
]]></Implementation>
</Method>

<Method name="isLongerThan">
<Description>
	Return true if the current instance is longer than duration, false otherwise.</Description>
<FormalSpec>duration:Base.Duration</FormalSpec>
<ReturnType>%Boolean</ReturnType>
<Implementation><![CDATA[	quit (..seconds > duration.seconds)
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="toDurationString">
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[
	set days = ..seconds \ ..#SecsPerDay
	set remainder = ..seconds # ..#SecsPerDay
	set hours = remainder \ ..#SecsPerHour
	set remainder = remainder # ..#SecsPerHour
	set minutes = remainder \ ..#SecsPerMinute
	set seconds = remainder # ..#SecsPerMinute

	quit days _ ..#DurationStringSeparator _
		##class(Base.String).fillLeftWithZeros(hours) _ ..#DurationStringSeparator _
		##class(Base.String).fillLeftWithZeros(minutes) _ ..#DurationStringSeparator _
		##class(Base.String).fillLeftWithZeros(seconds)
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="fromDurationString">
<FormalSpec>durationString:%String</FormalSpec>
<ReturnType>Base.Duration</ReturnType>
<Implementation><![CDATA[
	set days = $inumber($piece(durationString, ..#DurationStringSeparator, 1), "")
	set hours = $inumber($piece(durationString, ..#DurationStringSeparator, 2), "")
	set minutes = $inumber($piece(durationString, ..#DurationStringSeparator, 3), "")
	set seconds = $inumber($piece(durationString, ..#DurationStringSeparator, 4), "")
	quit ..basicSetSeconds((days * ..#SecsPerDay) + (hours * ..#SecsPerHour) + (minutes * ..#SecsPerMinute) + seconds)
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="toString">
<Description>
	For easy testing.</Description>
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[	quit "[Duration:" _ ..toDurationString() _ "]"
]]></Implementation>
</Method>

<Method name="write">
<Description>
	For easy testing.</Description>
<Implementation><![CDATA[	write ..toString()
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="basicSetSeconds">
<Internal>1</Internal>
<FormalSpec>seconds:%Integer</FormalSpec>
<Private>1</Private>
<ReturnType>Base.Duration</ReturnType>
<Implementation><![CDATA[
	set ..seconds = $select(seconds > 0: seconds, 1: 0)
	quit ##this
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Storage name="Default">
<Type>%Library.CacheSerialState</Type>
<State>DurationState</State>
<StreamLocation>^Base.DurationS</StreamLocation>
<Data name="DurationState">
<Structure>listnode</Structure>
<Subscript/>
<Value name="1">
<Value>seconds</Value>
</Value>
</Data>
</Storage>
</Class>


<Class name="Base.Initializer">
<Description>

	write ##class(Base.Initializer).initialize()
	write ##class(Base.Initializer).initialize(1)
</Description>
<Super>Base.InitializerAbstract</Super>
<TimeChanged>61842,28683.187</TimeChanged>
<TimeCreated>61819,77894.265</TimeCreated>

<Method name="runInitialization">
<Description>
	Actually do the initialization.
		This method has to be overridden in subclasses.</Description>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	set status = ##class(Base.DBLogger.LogLevel).initialize()
	quit:($$$ISERR(status)) status

	set status = ##class(Base.DBLogger.LogLevelFilter).initialize()
	quit:($$$ISERR(status)) status

	set status = ##class(Base.DBLogger.MasterLogLevelFilter).initialize()
	quit:($$$ISERR(status)) status

	set status = ##class(Base.DBLogger.Logger).initialize()
	quit:($$$ISERR(status)) status

	quit $$$OK
]]></Implementation>
</Method>

<Storage name="Default">
<Type>%Library.CacheStorage</Type>
</Storage>
</Class>


<Class name="Base.InitializerAbstract">
<Description>
	
	This class is an abstract superclass for Project initialization.
	For one project, subProject, and version, the initialization should happen only once.
	
	Every initialization is stored in the DB, so this class can check whether this project,
	subproject and version has already been initialized before.
	
	When calling the class method initialize(force), the initialization method runInitialization()
	gets called only if this project, subproject, and version were never initialized before.
	
	Setting the optional boolean parameter 'force' to 1, makes the initialization method runInitialization()
	be called in any case.
</Description>
<Abstract>1</Abstract>
<Super>%Persistent,Base.Support</Super>
<TimeChanged>62427,55465.721943</TimeChanged>
<TimeCreated>61808,32022.734</TimeCreated>
<Inheritance>right</Inheritance>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Property name="project">
<Type>%String</Type>
<Parameter name="MAXLEN" value="20"/>
</Property>

<Property name="subProject">
<Type>%String</Type>
<Parameter name="MAXLEN" value="20"/>
</Property>

<Property name="version">
<Type>%String</Type>
<Parameter name="MAXLEN" value="20"/>
</Property>

<Property name="lastProjectChange">
<Type>%String</Type>
<Parameter name="MAXLEN" value="20"/>
</Property>

<Property name="isInitialized">
<Type>%Boolean</Type>
<InitialExpression>$$$NO</InitialExpression>
</Property>

<Property name="isForced">
<Type>%Boolean</Type>
<InitialExpression>$$$NO</InitialExpression>
</Property>

<Property name="errorMessage">
<Type>%String</Type>
<Parameter name="MAXLEN" value="200"/>
</Property>

<Property name="timeStamp">
<Type>Base.DateTime</Type>
<InitialExpression>##class(Base.DateTime).now()</InitialExpression>
</Property>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="initialize">
<Description>
	write ##class(Base.InitializerAbstract).initialize()
	write ##class(Base.InitializerAbstract).initialize(1)</Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>force:%Boolean=0</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	set status = $$$OK

	set initializer = ..%New()
	if (('force) && initializer.isInitialized())		quit $$$NO

	set status = initializer.runInitialization()

	if ($$$ISERR(status))
	{
		set initializer.isInitialized = $$$NO
		do DecomposeStatus^%apiOBJ(status, .errorMessage)
		set initializer.errorMessage = errorMessage(errorMessage)
	}
	else
	{
		set initializer.isInitialized = $$$YES
	}

	set initializer.isForced = force
	set initializer.timeStamp = ##class(Base.DateTime).now()

	set wasSaveOK = initializer.%Save()
	if $$$ISERR(wasSaveOK)		quit wasSaveOK
	
	quit status
]]></Implementation>
</Method>

<Method name="%OnNew">
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	set status = $$$OK
	set versionClass = ""

	try
	{
		set myPackage = $piece(..%ClassName(1), ".", 1, ($length(..%ClassName(1), ".") - 1))
		set versionClass = myPackage _ ".Version"
		set versionString = $CLASSMETHOD(versionClass, "toString")

		set ..project = $CLASSMETHOD(versionClass, "getProject")
		set ..subProject = $CLASSMETHOD(versionClass, "getSubProject")
		set ..version = $CLASSMETHOD(versionClass, "getVersion")
		set ..lastProjectChange = $CLASSMETHOD(versionClass, "getLastProjectChange")
	}
	catch ex
	{
		set exString = ex.Name
		set status = $$$ERROR(exString)
	}

	quit status
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="runInitialization">
<Description>
	Actually do the initialization.
		This method has to be overridden in subclasses.</Description>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	set status = $$$OK

	//	(Do something)

	quit status
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="toString">
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[
	quit "[" _ ..%ClassName(1) _ ":" _
		..project _ ":" _
		..subProject _ ":" _
		..version _ ":" _
		..lastProjectChange _ ":" _
		..isInitialized _ ":" _
		..timeStamp.toString() _ "]"
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="isInitialized">
<Description>
	Return true if at least one successful initialization happened on this project, subproject and version.
	Return false otherwise.</Description>
<ReturnType>%Boolean</ReturnType>
<Implementation><![CDATA[
	set project = ..project
	set subProject = ..subProject
	set version = ..version

	&sql(
		select	count(*) into :count
		from	Base.InitializerAbstract
		where	project = :project
		and		subProject = :subProject
		and		version = :version
		and		isInitialized = 1
	)
	
	if (SQLCODE '= 0)		quit $$$NO		//	Some error occurred

	//	Return true if initialization occurred at least once, false if initialization never happened.
	quit (count > 0)
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Storage name="Default">
<Type>%Library.CacheStorage</Type>
<DataLocation>^Base.InitializerAbstractD</DataLocation>
<DefaultData>InitializerAbstractDefaultData</DefaultData>
<IdLocation>^Base.InitializerAbstractD</IdLocation>
<IndexLocation>^Base.InitializerAbstractI</IndexLocation>
<StreamLocation>^Base.InitializerAbstractS</StreamLocation>
<Data name="InitializerAbstractDefaultData">
<Structure>listnode</Structure>
<Subscript/>
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
<Value name="2">
<Value>project</Value>
</Value>
<Value name="3">
<Value>subProject</Value>
</Value>
<Value name="4">
<Value>version</Value>
</Value>
<Value name="5">
<Value>lastProjectChange</Value>
</Value>
<Value name="6">
<Value>isInitialized</Value>
</Value>
<Value name="7">
<Value>isForced</Value>
</Value>
<Value name="8">
<Value>errorMessage</Value>
</Value>
<Value name="9">
<Value>timeStamp</Value>
</Value>
</Data>
</Storage>
</Class>


<Project name="Base">
  <Items>
    <ProjectItem name="Base.ClassTemplate" type="CLS"></ProjectItem>
    <ProjectItem name="Base.CodeAbstract" type="CLS"></ProjectItem>
    <ProjectItem name="Base.CodeExamples.Example1" type="CLS"></ProjectItem>
    <ProjectItem name="Base.CodeExamples.Example2" type="CLS"></ProjectItem>
    <ProjectItem name="Base.DBLogger.GUI.AbstractZENPage" type="CLS"></ProjectItem>
    <ProjectItem name="Base.DBLogger.GUI.Application" type="CLS"></ProjectItem>
    <ProjectItem name="Base.DBLogger.GUI.LoggerModel" type="CLS"></ProjectItem>
    <ProjectItem name="Base.DBLogger.GUI.Loggers" type="CLS"></ProjectItem>
    <ProjectItem name="Base.DBLogger.GUI.Logs" type="CLS"></ProjectItem>
    <ProjectItem name="Base.DBLogger.GUI.MasterFilterModel" type="CLS"></ProjectItem>
    <ProjectItem name="Base.DBLogger.LogEntry" type="CLS"></ProjectItem>
    <ProjectItem name="Base.DBLogger.LogLevel" type="CLS"></ProjectItem>
    <ProjectItem name="Base.DBLogger.LogLevelFilter" type="CLS"></ProjectItem>
    <ProjectItem name="Base.DBLogger.LogRequest" type="CLS"></ProjectItem>
    <ProjectItem name="Base.DBLogger.Logger" type="CLS"></ProjectItem>
    <ProjectItem name="Base.DBLogger.MasterLogLevelFilter" type="CLS"></ProjectItem>
    <ProjectItem name="Base.DateTime" type="CLS"></ProjectItem>
    <ProjectItem name="Base.Duration" type="CLS"></ProjectItem>
    <ProjectItem name="Base.Initializer" type="CLS"></ProjectItem>
    <ProjectItem name="Base.InitializerAbstract" type="CLS"></ProjectItem>
    <ProjectItem name="Base.Stack" type="CLS"></ProjectItem>
    <ProjectItem name="Base.StackElement" type="CLS"></ProjectItem>
    <ProjectItem name="Base.String" type="CLS"></ProjectItem>
    <ProjectItem name="Base.Support" type="CLS"></ProjectItem>
    <ProjectItem name="Base.UnitTests" type="CLS"></ProjectItem>
    <ProjectItem name="Base.UnitTests.DBLoggerTester" type="CLS"></ProjectItem>
    <ProjectItem name="Base.UnitTests.DBLoggerTesterSub" type="CLS"></ProjectItem>
    <ProjectItem name="Base.UnitTests.DBLoggerTesterSubSub" type="CLS"></ProjectItem>
    <ProjectItem name="Base.UnitTests.DateTimeTestUser" type="CLS"></ProjectItem>
    <ProjectItem name="Base.UnitTests.DateTimeTester" type="CLS"></ProjectItem>
    <ProjectItem name="Base.UnitTests.DurationTester" type="CLS"></ProjectItem>
    <ProjectItem name="Base.Version" type="CLS"></ProjectItem>
    <ProjectItem name="Base.VersionAbstract" type="CLS"></ProjectItem>
    <ProjectItem name="DBLogger.INC" type="MAC"></ProjectItem>
  </Items>
</Project>


<Class name="Base.Stack">
<Super>%SerialObject,%XML.Adaptor,Base.Support</Super>
<TimeChanged>61819,58485.625</TimeChanged>
<TimeCreated>61819,47955</TimeCreated>
<Inheritance>right</Inheritance>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Property name="stackElements">
<Type>Base.StackElement</Type>
<Collection>list</Collection>
</Property>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="%OnNew">
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	set $ecode = ""
	set status = $$$OK

	//	Ignore the uppermost 2 stack elements because they just show the construction of this stack:
	//	Go in reverse order, so the most recent stack element is at the top = the 1st element:
	for i=($stack - 2):-1:0
	{
		set type = $stack(i)
		set place = $stack(i, "place")
		set source = $stack(i, "mcode")
		set error = $stack(i, "ecode")

		set element = ##class(Base.StackElement).%New(i, type, place, source, error)
		do ..stackElements.Insert(element)
	}

	quit status
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="Count">
<ReturnType>%Integer</ReturnType>
<Implementation><![CDATA[	quit ..stackElements.Count()
]]></Implementation>
</Method>

<Method name="GetAt">
<FormalSpec>i:%Integer</FormalSpec>
<ReturnType>Base.StackElement</ReturnType>
<Implementation><![CDATA[	quit ..stackElements.GetAt(i)
]]></Implementation>
</Method>

<Method name="top">
<ReturnType>Base.StackElement</ReturnType>
<Implementation><![CDATA[	quit ..GetAt(1)
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="toString">
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[
	set string = "[Stack:" _
		..stackElements.Count() _ ":"

	for i=1:1:..stackElements.Count()
	{
		set stackElement = ..stackElements.GetAt(i)
		set string = string _ ##class(Base.String).crLf() _ ##class(Base.String).tab() _ stackElement.toString()
	}

	set string = string _ ##class(Base.String).crLf() _ "]"
	
	quit string
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="one">
<Description>
do ##class(Base.Stack).one()</Description>
<ClassMethod>1</ClassMethod>
<Implementation><![CDATA[	do ..two()
]]></Implementation>
</Method>

<Method name="two">
<ClassMethod>1</ClassMethod>
<Implementation><![CDATA[	do ..three()
]]></Implementation>
</Method>

<Method name="three">
<ClassMethod>1</ClassMethod>
<Implementation><![CDATA[	do ..four()
]]></Implementation>
</Method>

<Method name="four">
<ClassMethod>1</ClassMethod>
<Implementation><![CDATA[	do ..five()
]]></Implementation>
</Method>

<Method name="five">
<ClassMethod>1</ClassMethod>
<Implementation><![CDATA[	do ..writeStack()
]]></Implementation>
</Method>

<Method name="writeStack">
<ClassMethod>1</ClassMethod>
<Implementation><![CDATA[
	set stack = ##class(Base.Stack).%New()
	do stack.top().write()
	do stack.write()
]]></Implementation>
</Method>

<Storage name="Default">
<Type>%Library.CacheSerialState</Type>
<State>StackState</State>
<StreamLocation>^Base.StackS</StreamLocation>
<Data name="StackState">
<Structure>listnode</Structure>
<Subscript/>
<Value name="1">
<Value>stackElements</Value>
</Value>
</Data>
</Storage>
</Class>


<Class name="Base.StackElement">
<Super>%SerialObject,%XML.Adaptor,Base.Support</Super>
<TimeChanged>61819,56969.125</TimeChanged>
<TimeCreated>61819,51586.796</TimeCreated>
<Inheritance>right</Inheritance>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Property name="level">
<Type>%Integer</Type>
</Property>

<Property name="type">
<Type>%String</Type>
</Property>

<Property name="place">
<Type>%String</Type>
</Property>

<Property name="class">
<Type>%String</Type>
</Property>

<Property name="method">
<Type>%String</Type>
</Property>

<Property name="source">
<Type>%String</Type>
</Property>

<Property name="error">
<Type>%String</Type>
</Property>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="%OnNew">
<FormalSpec>level,type,place,source,error</FormalSpec>
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	set ..level = level
	set ..type = type
	set ..place = place
	set ..source = source
	set ..error = error
	
	if ($find(place, "^") > 0)
	{
		set ..method = $piece($piece(place, "^", 1), "+", 1)
		if ($extract(..method, 1) = "z")	set ..method = $extract(..method, 2, *)

		set ..class = $piece($piece(place, "^", 2), "+", 1)
		set ..class = $piece(..class, ".", 1, $length(..class, ".") - 1)
	}

	quit $$$OK
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="toString">
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[
	quit "[StackElement:" _
		..level _ ":" _
		..class _ ":" _
		..method _ ":" _ 
		..source _
		"]"
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Storage name="Default">
<Type>%Library.CacheSerialState</Type>
<State>StackElementState</State>
<StreamLocation>^Base.StackElementS</StreamLocation>
<Data name="StackElementState">
<Structure>listnode</Structure>
<Subscript/>
<Value name="1">
<Value>level</Value>
</Value>
<Value name="2">
<Value>type</Value>
</Value>
<Value name="3">
<Value>place</Value>
</Value>
<Value name="4">
<Value>class</Value>
</Value>
<Value name="5">
<Value>method</Value>
</Value>
<Value name="6">
<Value>source</Value>
</Value>
<Value name="7">
<Value>error</Value>
</Value>
</Data>
</Storage>
</Class>


<Class name="Base.String">
<Description>

	Useful utilities for Strings
</Description>
<Abstract>1</Abstract>
<TimeChanged>62046,58597.909402</TimeChanged>
<TimeCreated>61819,57621.89</TimeCreated>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="crLf">
<Description>
	##class(Base.String).crLf(2)</Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>num:%Integer=1</FormalSpec>
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[	quit ..repeatString($char(10, 13), num)
]]></Implementation>
</Method>

<Method name="tab">
<Description>
	##class(Base.String).tab(2)</Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>num:%Integer=1</FormalSpec>
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[	quit ..repeatString($char(9), num)
]]></Implementation>
</Method>

<Method name="space">
<Description>
	##class(Base.String).space(2)</Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>num:%Integer=4</FormalSpec>
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[	quit ..repeatString(" ", num)
]]></Implementation>
</Method>

<Method name="repeatString">
<Description>
	##class(Base.String).repeatString("Hello! ", 2)</Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>string:%String,num:%Integer</FormalSpec>
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[
	set result = ""
	for i=1:1:num	{ set result = result _ string }
	quit result
]]></Implementation>
</Method>

<Method name="fillLeftWithZeros">
<Description>
	##class(Base.String).fillLeftWithZeros(123, 6)</Description>
<ClassMethod>1</ClassMethod>
<FormalSpec>value:%Integer,size:%Integer=2</FormalSpec>
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[	quit $translate($justify(value, size), " ", "0")
]]></Implementation>
</Method>

<Method name="DecimalToString">
<ClassMethod>1</ClassMethod>
<FormalSpec>number:%Decimal</FormalSpec>
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[
	// Formats the decimal, deletes the minux sign, but
	// adds the leading 0 and rounds to 2 decimals.
	// after formatting -> add the minus sign again if required
	set retval = $FNUMBER(number, "-", 2)
	if (number < 0) {
		set retval = "-"_retval	
	}
	Quit retval
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>
</Class>


<Class name="Base.Support">
<Abstract>1</Abstract>
<TimeChanged>61819,53800.984</TimeChanged>
<TimeCreated>61819,53800.984</TimeCreated>

<Method name="toString">
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[	quit "[" _ ..%ClassName(1) _ "]"
]]></Implementation>
</Method>

<Method name="write">
<Implementation><![CDATA[	write !, ..toString()
]]></Implementation>
</Method>
</Class>


<Class name="Base.UnitTests">
<Description>
	Rudimentary unit tests.

		Last change: 20.03.2010 by Lem
</Description>
<Super>%RegisteredObject</Super>
<TimeChanged>61805,34710.609</TimeChanged>
<TimeCreated>61804,59494.921</TimeCreated>

<Property name="testCounter">
<Type>%Integer</Type>
<InitialExpression>0</InitialExpression>
</Property>

<Property name="errorCounter">
<Type>%Integer</Type>
<InitialExpression>0</InitialExpression>
</Property>

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

]]></Content>
</UDLText>

<Method name="runAllTests">
<ClassMethod>1</ClassMethod>
<Implementation><![CDATA[
	set tester = ..%New()
	do tester.runTest()

	write !, tester.testCounter _ " tests done, " _ tester.errorCounter _ " errors found."
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

<Method name="assertIsEqual">
<FormalSpec>expression,value</FormalSpec>
<Implementation><![CDATA[
	set ..testCounter = ..testCounter + 1

	if (expression '= value)
	{
		set ..errorCounter = ..errorCounter + 1
		write !, "!!!" _ ..testCounter _ ":<" _ expression _ ">:shouldBe<" _ value _ ">"
	}
]]></Implementation>
</Method>

<Method name="assertIsNotEqual">
<FormalSpec>expression,value</FormalSpec>
<Implementation><![CDATA[
	set ..testCounter = ..testCounter + 1

	if (expression = value)
	{
		set ..errorCounter = ..errorCounter + 1
		write !, "!!!" _ ..testCounter _ ":<" _ expression _ ">:shouldNotBe<" _ value _ ">"
	}
]]></Implementation>
</Method>

<Method name="assertIsTrue">
<FormalSpec>expression</FormalSpec>
<Implementation><![CDATA[
	set ..testCounter = ..testCounter + 1

	if (expression '= $$$YES)
	{
		set ..errorCounter = ..errorCounter + 1
		write !, "!!!" _ ..testCounter _ ":<" _ expression _ ">:shouldBeTrue"
	}
]]></Implementation>
</Method>

<Method name="assertIsFalse">
<FormalSpec>expression</FormalSpec>
<Implementation><![CDATA[
	set ..testCounter = ..testCounter + 1

	if (expression '= $$$NO)
	{
		set ..errorCounter = ..errorCounter + 1
		write !, "!!!" _ ..testCounter _ ":>" _ expression _ ">:shouldBeFalse"
	}
]]></Implementation>
</Method>

<Method name="assertIsOK">
<FormalSpec>expression</FormalSpec>
<Implementation><![CDATA[
	set ..testCounter = ..testCounter + 1

	if ('$$$ISOK(expression))
	{
		set ..errorCounter = ..errorCounter + 1
		write !, "!!!" _ ..testCounter _ ":<" _ expression _ ">:shouldBeOK"
	}
]]></Implementation>
</Method>

<Method name="assertIsError">
<FormalSpec>expression</FormalSpec>
<Implementation><![CDATA[
	set ..testCounter = ..testCounter + 1

	if ('$$$ISERR(expression))
	{
		set ..errorCounter = ..errorCounter + 1
		write !, "!!!" _ ..testCounter _ ":>" _ expression _ ">:shouldBeError"
	}
]]></Implementation>
</Method>
</Class>


<Class name="Base.UnitTests.DBLoggerTester">
<Abstract>1</Abstract>
<IncludeCode>DBLogger</IncludeCode>
<TimeChanged>61840,55304.812</TimeChanged>
<TimeCreated>61840,54951.468</TimeCreated>

<UDLText name="T">
<Content><![CDATA[
//		do ##class(Base.UnitTests.DBLoggerTester).writeSomeLogs()

]]></Content>
</UDLText>

<Method name="writeSomeLogs">
<ClassMethod>1</ClassMethod>
<Implementation><![CDATA[
	$$$DBLogDebug("Log on Debug level")
	$$$DBLogInfo("Log on Info level")
	$$$DBLogWarning("Log on Warning level")
	$$$DBLogError("Log on Error level")
	$$$DBLogFatal("Log on Fatal level")
	
	do ##class(Base.UnitTests.DBLoggerTesterSub).writeSomeLogs()
]]></Implementation>
</Method>
</Class>


<Class name="Base.UnitTests.DBLoggerTesterSub">
<Abstract>1</Abstract>
<IncludeCode>DBLogger</IncludeCode>
<Super>Base.UnitTests.DBLoggerTester</Super>
<TimeChanged>61840,55287.171</TimeChanged>
<TimeCreated>61840,55121.281</TimeCreated>

<Method name="writeSomeLogs">
<ClassMethod>1</ClassMethod>
<Implementation><![CDATA[
	$$$DBLogDebug("Log on Debug level")
	$$$DBLogInfo("Log on Info level")
	$$$DBLogWarning("Log on Warning level")
	$$$DBLogError("Log on Error level")
	$$$DBLogFatal("Log on Fatal level")
	
	do ##class(Base.UnitTests.DBLoggerTesterSubSub).writeSomeLogs()
]]></Implementation>
</Method>
</Class>


<Class name="Base.UnitTests.DBLoggerTesterSubSub">
<Abstract>1</Abstract>
<IncludeCode>DBLogger</IncludeCode>
<Super>Base.UnitTests.DBLoggerTesterSub</Super>
<TimeChanged>61840,55146.25</TimeChanged>
<TimeCreated>61840,55137.968</TimeCreated>

<Method name="writeSomeLogs">
<ClassMethod>1</ClassMethod>
<Implementation><![CDATA[
	$$$DBLogDebug("Log on Debug level")
	$$$DBLogInfo("Log on Info level")
	$$$DBLogWarning("Log on Warning level")
	$$$DBLogError("Log on Error level")
	$$$DBLogFatal("Log on Fatal level")
]]></Implementation>
</Method>
</Class>


<Class name="Base.UnitTests.DateTimeTestUser">
<Super>%Persistent</Super>
<TimeChanged>62416,57240.132598</TimeChanged>
<TimeCreated>61799,57992.796</TimeCreated>

<Property name="dateTime">
<Type>Base.DateTime</Type>
</Property>

<Method name="%OnNew">
<ReturnType>%Status</ReturnType>
<Implementation><![CDATA[
	set dateTime = ##class(Base.DateTime).now()
	quit $$$OK
]]></Implementation>
</Method>

<Storage name="Default">
<Type>%Library.CacheStorage</Type>
<DataLocation>^Base.UnitT3104.DateTimeTesED4ED</DataLocation>
<DefaultData>DateTimeTestUserDefaultData</DefaultData>
<IdLocation>^Base.UnitT3104.DateTimeTesED4ED</IdLocation>
<IndexLocation>^Base.UnitT3104.DateTimeTesED4EI</IndexLocation>
<StreamLocation>^Base.UnitT3104.DateTimeTesED4ES</StreamLocation>
<Data name="DateTimeTestUserDefaultData">
<Structure>listnode</Structure>
<Subscript/>
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
<Value name="2">
<Value>dateTime</Value>
</Value>
</Data>
</Storage>
</Class>


<Class name="Base.UnitTests.DateTimeTester">
<Super>Base.UnitTests</Super>
<TimeChanged>61842,36582.484</TimeChanged>
<TimeCreated>61795,29277.109</TimeCreated>

<Method name="runTest">
<Description>
	do ##class(Base.UnitTests.DateTimeTester).runAllTests()</Description>
<Implementation><![CDATA[
	//	Instance creation

	set dateTime20000101 = ##class(Base.DateTime).new(2000, 1, 1)
	do ..assertIsDate(dateTime20000101, 2000, 1, 1, 0, 0, 0)

	set dateTime20000102 = ##class(Base.DateTime).new(2000, 1, 2)
	do ..assertIsDate(dateTime20000102, 2000, 1, 2, 0, 0, 0)

	set dateTime20000103 = ##class(Base.DateTime).new(2000, 1, 3)
	do ..assertIsDate(dateTime20000103, 2000, 1, 3, 0, 0, 0)

	set dateTime200001040506078 = ##class(Base.DateTime).new(2000, 1, 4, 5, 6, 7.8)
	do ..assertIsDate(dateTime200001040506078, 2000, 1, 4, 5, 6, 7.8)

	set dateTimeFromHorolog = ##class(Base.DateTime).newFromHorolog("60000,54321")
	do ..assertIsDate(dateTimeFromHorolog, 2005, 4, 10, 15, 05, 21)

	set dateTimeFromHorologFrac = ##class(Base.DateTime).newFromHorolog("60000,54321.12345")
	do ..assertIsDate(dateTimeFromHorologFrac, 2005, 4, 10, 15, 05, 21.123)

	set dateTime20101020 = ##class(Base.DateTime).newFromDate("20/10/2010")
	do ..assertIsDate(dateTime20101020, 2010, 10, 20, 0, 0, 0)

	set dateTime20101122 = ##class(Base.DateTime).newFromDate("2010-11-22", 3)
	do ..assertIsDate(dateTime20101122, 2010, 11, 22, 0, 0, 0)

	set dateTime20101020102030 = ##class(Base.DateTime).newFromDateTime("20/10/2010 10:20:30")
	do ..assertIsDate(dateTime20101020102030, 2010, 10, 20, 10, 20, 30)

	set dateTime20101122112233 = ##class(Base.DateTime).newFromDateTime("2010-11-22 11:22:33", 3)
	do ..assertIsDate(dateTime20101122112233, 2010, 11, 22, 11, 22, 33)

	set dateTime2010112211223344 = ##class(Base.DateTime).newFromDateTime("2010-11-22 11:22:33.44", 3)
	do ..assertIsDate(dateTime2010112211223344, 2010, 11, 22, 11, 22, 33.44)

	//	Accessing

	do ..assertIsEqual(dateTime2010112211223344.getYear(), 2010)
	do ..assertIsEqual(dateTime2010112211223344.getMonth(), 11)
	do ..assertIsEqual(dateTime2010112211223344.getDay(), 22)
	do ..assertIsEqual(dateTime2010112211223344.getHour(), 11)
	do ..assertIsEqual(dateTime2010112211223344.getMinute(), 22)
	do ..assertIsEqual(dateTime2010112211223344.getSecond(), 33.44)
	do ..assertIsEqual(dateTime2010112211223344.getPrecision(), 3)

	//	Copying

	set dateTime20000103copy = dateTime20000103.copy()
	do ..assertIsDate(dateTime20000103copy, 2000, 1, 3, 0, 0, 0)

	//	Setting

	do dateTime20000103copy.setYear(2010)
	do ..assertIsDate(dateTime20000103copy, 2010, 1, 3, 0, 0, 0)

	do dateTime20000103copy.setMonth(10)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 3, 0, 0, 0)

	do dateTime20000103copy.setDay(10)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 0, 0, 0)

	do dateTime20000103copy.setHour(10)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 0, 0)

	do dateTime20000103copy.setMinute(10)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 10, 0)

	do dateTime20000103copy.setSecond(10)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 10, 10)

	do dateTime20000103copy.setSecond(10.10)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 10, 10.1)

	do dateTime20000103copy.setSecond(10.12345678)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 10, 10.123)
	do dateTime20000103copy.setPrecision(5)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 10, 10.12345)
	do dateTime20000103copy.setPrecision(0)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 10, 10)
	do dateTime20000103copy.setPrecision()
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 10, 10.123)

	do dateTime20000103copy.setSecond(10)

	//	Arithmetic

	do dateTime20000103copy.addYears(10)
	do ..assertIsDate(dateTime20000103copy, 2020, 10, 10, 10, 10, 10)

	do dateTime20000103copy.addYears(-10)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 10, 10)

	do dateTime20000103copy.addWeeks(10)
	do ..assertIsDate(dateTime20000103copy, 2010, 12, 19, 10, 10, 10)

	do dateTime20000103copy.addWeeks(-10)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 10, 10)

	do dateTime20000103copy.addDays(10)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 20, 10, 10, 10)

	do dateTime20000103copy.addDays(-10)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 10, 10)

	do dateTime20000103copy.addHours(10)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 20, 10, 10)

	do dateTime20000103copy.addHours(-10)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 10, 10)

	do dateTime20000103copy.addMinutes(10)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 20, 10)

	do dateTime20000103copy.addMinutes(-10)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 10, 10)

	do dateTime20000103copy.addSeconds(10)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 10, 20)

	do dateTime20000103copy.addSeconds(-10)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 10, 10)

	do dateTime20000103copy.addSeconds(10.010)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 10, 20.010)

	do dateTime20000103copy.addSeconds(-10.010)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 10, 10)

	//	Arithmetic with overflow

	do dateTime20000103copy.addWeeks(100)
	do ..assertIsDate(dateTime20000103copy, 2012, 9, 9, 10, 10, 10)

	do dateTime20000103copy.addWeeks(-100)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 10, 10)

	do dateTime20000103copy.addDays(100)
	do ..assertIsDate(dateTime20000103copy, 2011, 1, 18, 10, 10, 10)

	do dateTime20000103copy.addDays(-100)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 10, 10)

	do dateTime20000103copy.addHours(100)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 14, 14, 10, 10)

	do dateTime20000103copy.addHours(-100)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 10, 10)

	do dateTime20000103copy.addMinutes(100)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 11, 50, 10)

	do dateTime20000103copy.addMinutes(-100)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 10, 10)

	do dateTime20000103copy.addSeconds(100)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 11, 50)

	do dateTime20000103copy.addSeconds(-100)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 10, 10)

	do dateTime20000103copy.addSeconds(100.999)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 11, 50.999)

	do dateTime20000103copy.addSeconds(-100.999)
	do ..assertIsDate(dateTime20000103copy, 2010, 10, 10, 10, 10, 10)

	//	Arithmetic with underflow:
	//	Special case: underflow with remainder = 0 (time = 00:00:00)
	
	set dateTime20000101copy = dateTime20000101.copy()
	do ..assertIsDate(dateTime20000101copy, 2000, 1, 1, 0, 0, 0)

	do dateTime20000101copy.addDays(-1)
	do ..assertIsDate(dateTime20000101copy, 1999, 12, 31, 0, 0, 0)

	do dateTime20000101copy.addDays(-2)
	do ..assertIsDate(dateTime20000101copy, 1999, 12, 29, 0, 0, 0)

	do dateTime20000101copy.addWeeks(-1)
	do ..assertIsDate(dateTime20000101copy, 1999, 12, 22, 0, 0, 0)

	//	Comparing

	do ..assertIsTrue(dateTime20101020102030.isEqual(dateTime20101020102030))
	do ..assertIsFalse(dateTime20101020102030.isEqual(dateTime20101122112233))

	do ..assertIsFalse(dateTime20101020102030.isNotEqual(dateTime20101020102030))
	do ..assertIsTrue(dateTime20101020102030.isNotEqual(dateTime20101122112233))

	do ..assertIsFalse(dateTime20101020.isBefore(dateTime20101020))
	do ..assertIsTrue(dateTime20101020.isBefore(dateTime20101122))
	do ..assertIsFalse(dateTime20101122.isBefore(dateTime20101020))

	do ..assertIsFalse(dateTime20101020102030.isBefore(dateTime20101020102030))
	do ..assertIsTrue(dateTime20101020102030.isBefore(dateTime20101122112233))
	do ..assertIsFalse(dateTime20101122112233.isBefore(dateTime20101020102030))

	do ..assertIsFalse(dateTime20101020.isAfter(dateTime20101020))
	do ..assertIsFalse(dateTime20101020.isAfter(dateTime20101122))
	do ..assertIsTrue(dateTime20101122.isAfter(dateTime20101020))

	do ..assertIsFalse(dateTime20101020102030.isAfter(dateTime20101020102030))
	do ..assertIsFalse(dateTime20101020102030.isAfter(dateTime20101122112233))
	do ..assertIsTrue(dateTime20101122112233.isAfter(dateTime20101020102030))

	do ..assertIsTrue(dateTime20000102.isBetween(dateTime20000101, dateTime20000103))
	do ..assertIsFalse(dateTime20000101.isBetween(dateTime20000102, dateTime20000103))
	do ..assertIsFalse(dateTime20000101.isBetween(dateTime20000103, dateTime20000102))

	do ..assertIsFalse(dateTime20000102.isNotBetween(dateTime20000101, dateTime20000103))
	do ..assertIsTrue(dateTime20000101.isNotBetween(dateTime20000102, dateTime20000103))
	do ..assertIsTrue(dateTime20000101.isNotBetween(dateTime20000103, dateTime20000102))

	//	Converting to

	do ..assertIsEqual(dateTimeFromHorolog.toHorolog(), "60000,54321")
	do ..assertIsEqual(dateTimeFromHorologFrac.toHorolog(), "60000,54321.12345")

	do ..assertIsEqual(dateTime20101020102030.toDate(), "20/10/2010")
	do ..assertIsEqual(dateTime20101020102030.toDate(3), "2010-10-20")

	do ..assertIsEqual(dateTime20101020102030.toTime(), "10:20:30.000")
	do ..assertIsEqual(dateTime20101020102030.toTime(,6), "10:20:30.000000")
	do ..assertIsEqual(dateTime20101020102030.toTime(,0), "10:20:30")
	do ..assertIsEqual(dateTime20101020102030.toTime(3), "10:20:30.000AM")
	do ..assertIsEqual(dateTime20101020102030.toTime(3, 6), "10:20:30.000000AM")
	do ..assertIsEqual(dateTime20101020102030.toTime(3, 0), "10:20:30AM")

	do ..assertIsEqual(dateTime20101020102030.toDateTime(), "20/10/2010 10:20:30.000")
	do ..assertIsEqual(dateTime20101020102030.toDateTime(,,6), "20/10/2010 10:20:30.000000")
	do ..assertIsEqual(dateTime20101020102030.toDateTime(,,0), "20/10/2010 10:20:30")
	do ..assertIsEqual(dateTime20101020102030.toDateTime(3, 3), "2010-10-20 10:20:30.000AM")
	do ..assertIsEqual(dateTime20101020102030.toDateTime(3, 3, 6), "2010-10-20 10:20:30.000000AM")
	do ..assertIsEqual(dateTime20101020102030.toDateTime(3, 3, 0), "2010-10-20 10:20:30AM")

	//	Converting from

	do ..assertIsDate(dateTime20101020102030.fromHorolog("60000,54321"), 2005, 4, 10, 15, 05, 21)

	do ..assertIsDate(dateTime20101020102030.fromDate("09/02/1963"), 1963, 2, 9, 0, 0, 0)
	do ..assertIsDate(dateTime20101020102030.fromDate("1963-02-09", 3), 1963, 2, 9, 0, 0, 0)

	do ..assertIsDate(dateTime20101020102030.fromDateTime("09/02/1963 11:22:33"), 1963, 2, 9, 11, 22, 33)
	do ..assertIsDate(dateTime20101020102030.fromDateTime("1963-02-09 11:22:33AM", 3, 3), 1963, 2, 9, 11, 22, 33)

	do ..assertIsDate(dateTime20101020102030.fromDateTime("09/02/1963 11:22:33.44"), 1963, 2, 9, 11, 22, 33.44)
	do ..assertIsDate(dateTime20101020102030.fromDateTime("1963-02-09 11:22:33.44AM", 3, 3), 1963, 2, 9, 11, 22, 33.44)


	//	Using in a persistent class:

	set dateTimeUser = ##class(Base.UnitTests.DateTimeTestUser).%New()
	do dateTimeUser.dateTime.setPrecision(4)
	set p = dateTimeUser.dateTime.getPrecision()
	set h = dateTimeUser.dateTime.toHorolog()
	do ..assertIsOK(dateTimeUser.%Save())
	set id = dateTimeUser.%Id()
	kill dateTimeUser
	set dateTimeUser = ##class(Base.UnitTests.DateTimeTestUser).%OpenId(id)
	do ..assertIsEqual(dateTimeUser.dateTime.toHorolog(), h)
	do ..assertIsEqual(dateTimeUser.dateTime.getPrecision(), 4)
	do ##class(Base.UnitTests.DateTimeTestUser).%DeleteId(id)
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="assertIsDate">
<FormalSpec>dateTime,year,month,day,hour,minute,second</FormalSpec>
<Implementation><![CDATA[
	do ..assertIsEqual(dateTime.getYear(), year)
	do ..assertIsEqual(dateTime.getMonth(), month)
	do ..assertIsEqual(dateTime.getDay(), day)
	do ..assertIsEqual(dateTime.getHour(), hour)
	do ..assertIsEqual(dateTime.getMinute(), minute)
	do ..assertIsEqual(dateTime.getSecond(), second)
]]></Implementation>
</Method>
</Class>


<Class name="Base.UnitTests.DurationTester">
<Super>Base.UnitTests</Super>
<TimeChanged>61827,26839.828</TimeChanged>
<TimeCreated>61795,38619.531</TimeCreated>

<Method name="runTest">
<Description>
	do ##class(Base.UnitTests.DurationTester).runAllTests()</Description>
<Implementation><![CDATA[
	//	Instance creation

	set duration11223344 = ##class(Base.Duration).new(11, 22, 33, 44)
	do ..assertIsDuration(duration11223344, 11, 22, 33, 44)

	set duration100000 = ##class(Base.Duration).%New(100000)
	do ..assertIsDuration(duration100000, 1, 3, 46, 40)

	//	Accessing

	do ..assertIsEqual(duration11223344.getDays(), 11)
	do ..assertIsEqual(duration11223344.getHours(), 22)
	do ..assertIsEqual(duration11223344.getMinutes(), 33)
	do ..assertIsEqual(duration11223344.getSeconds(), 44)

	//	Copying

	set duration11223344copy = duration11223344.copy()
	do ..assertIsDuration(duration11223344copy, 11, 22, 33, 44)

	//	Setting

	do duration11223344copy.setDays(22)
	do ..assertIsDuration(duration11223344copy, 22, 22, 33, 44)

	do duration11223344copy.setHours(11)
	do ..assertIsDuration(duration11223344copy, 22, 11, 33, 44)

	do duration11223344copy.setMinutes(44)
	do ..assertIsDuration(duration11223344copy, 22, 11, 44, 44)

	do duration11223344copy.setSeconds(33)
	do ..assertIsDuration(duration11223344copy, 22, 11, 44, 33)

	//	Setting with overflow

	set duration0 = ##class(Base.Duration).%New()
	do ..assertIsDuration(duration0, 0, 0, 0, 0)

	do duration0.setHours(100)
	do ..assertIsDuration(duration0, 4, 4, 0, 0)

	do duration0.setMinutes(100)
	do ..assertIsDuration(duration0, 4, 5, 40, 0)

	do duration0.setSeconds(100)
	do ..assertIsDuration(duration0, 4, 5, 41, 40)

	//	Arithmetic with overflow

	set duration0 = ##class(Base.Duration).%New()
	do ..assertIsDuration(duration0, 0, 0, 0, 0)

	do duration0.addDays(100)
	do ..assertIsDuration(duration0, 100, 0, 0, 0)

	do duration0.addDays(100)
	do ..assertIsDuration(duration0, 200, 0, 0, 0)

	do duration0.addDays(-100)
	do ..assertIsDuration(duration0, 100, 0, 0, 0)

	do duration0.addHours(100)
	do ..assertIsDuration(duration0, 104, 4, 0, 0)

	do duration0.addHours(-100)
	do ..assertIsDuration(duration0, 100, 0, 0, 0)

	do duration0.addMinutes(100)
	do ..assertIsDuration(duration0, 100, 1, 40, 0)

	do duration0.addMinutes(-100)
	do ..assertIsDuration(duration0, 100, 0, 0, 0)

	do duration0.addSeconds(100)
	do ..assertIsDuration(duration0, 100, 0, 1, 40)

	do duration0.addSeconds(-100)
	do ..assertIsDuration(duration0, 100, 0, 0, 0)

	//	Arithmetic with underflow

	do duration0.addDays(-200)
	do ..assertIsDuration(duration0, 0, 0, 0, 0)

	//	Comparing

	do ..assertIsTrue(duration0.isEqual(duration0))
	do ..assertIsFalse(duration0.isEqual(duration11223344))

	do ..assertIsFalse(duration0.isNotEqual(duration0))
	do ..assertIsTrue(duration0.isNotEqual(duration11223344))

	do ..assertIsFalse(duration0.isShorterThan(duration0))
	do ..assertIsTrue(duration0.isShorterThan(duration11223344))
	do ..assertIsFalse(duration11223344.isShorterThan(duration0))

	do ..assertIsFalse(duration0.isLongerThan(duration0))
	do ..assertIsFalse(duration0.isLongerThan(duration11223344))
	do ..assertIsTrue(duration11223344.isLongerThan(duration0))

	//	Converting to

	do ..assertIsEqual(duration11223344.toDurationString(), "11:22:33:44")

	//	Converting from

	do ..assertIsDuration(duration11223344.fromDurationString("10:10:10:10"), 10, 10, 10, 10)


	write !, "runTest finished", !
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="assertIsDuration">
<FormalSpec>duration,day,hour,minute,second</FormalSpec>
<Implementation><![CDATA[
	do ..assertIsEqual(duration.getDays(), day)
	do ..assertIsEqual(duration.getHours(), hour)
	do ..assertIsEqual(duration.getMinutes(), minute)
	do ..assertIsEqual(duration.getSeconds(), second)
]]></Implementation>
</Method>
</Class>


<Class name="Base.Version">
<Description><![CDATA[
	
	Project Change History:

---	Date	---	By	---	What	-------------------------------------------

03.04.2010	Lem		Refactored InitializerAbstract, added VersionAbstract
					InitializerAbstract now uses VersionAbstract to get Version information

10.04.2010	Lem		DBLogger added (not yet finished)

11.04.2010	Lem		Added method setValue(value As %String) to class CodeAbstract

Version 1.4.0:

23.04.2010	Lem		DBLogger: GUI Development

24.04.2010	Lem		Further GUI Development
					Loggers can now be active or inactive

26.04.2010	Lem		Added class method find(value as %String) to class CodeAbstract

26.04.2010	Lem		Corrected a subtle error in Base.DateTime:
					addDays(days) returned wrong results when days < 0 and timePart = 0
]]></Description>
<Super>Base.VersionAbstract</Super>
<TimeChanged>61842,36917.265</TimeChanged>
<TimeCreated>61819,78187.734</TimeCreated>

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

]]></Content>
</UDLText>

<Parameter name="Project">
<Default>Base</Default>
</Parameter>

<Parameter name="SubProject">
<Default>Base</Default>
</Parameter>

<Parameter name="Version">
<Default>1.4.1</Default>
</Parameter>

<Parameter name="LastProjectChange">
<Default>26.04.2010</Default>
</Parameter>
</Class>


<Class name="Base.VersionAbstract">
<Description>
	
	Project Change History:

---	Date	---	By	---------	What	-------------------------

</Description>
<Abstract>1</Abstract>
<TimeChanged>61819,64791.296</TimeChanged>
<TimeCreated>61819,64776.5</TimeCreated>

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

]]></Content>
</UDLText>

<Parameter name="Project">
<Default>TBD</Default>
</Parameter>

<Parameter name="SubProject">
<Default>TBD</Default>
</Parameter>

<Parameter name="Version">
<Default>0.0.0</Default>
</Parameter>

<Parameter name="LastProjectChange">
<Default>dd.mm.yyyy</Default>
</Parameter>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

<Method name="getVersion">
<ClassMethod>1</ClassMethod>
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[	quit ..#Version
]]></Implementation>
</Method>

<Method name="getProject">
<ClassMethod>1</ClassMethod>
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[	quit ..#Project
]]></Implementation>
</Method>

<Method name="getSubProject">
<ClassMethod>1</ClassMethod>
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[	quit ..#SubProject
]]></Implementation>
</Method>

<Method name="getLastProjectChange">
<ClassMethod>1</ClassMethod>
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[	quit ..#LastProjectChange
]]></Implementation>
</Method>

<Method name="toString">
<ClassMethod>1</ClassMethod>
<ReturnType>%String</ReturnType>
<Implementation><![CDATA[	quit "Project: " _ ..#Project _ "/" _ ..#SubProject _ " Version: " _ ..#Version _ " Last Project Change: " _ ..#LastProjectChange
]]></Implementation>
</Method>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>

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

]]></Content>
</UDLText>
</Class>


<Routine name="DBLogger" type="INC" timestamp="61826,73444"><![CDATA[

#define DBLogDebug(%message)	do ##class(Base.DBLogger.LogRequest).log(##class(Base.DBLogger.LogLevel).Debug(), %message)
#define DBLogInfo(%message)		do ##class(Base.DBLogger.LogRequest).log(##class(Base.DBLogger.LogLevel).Info(), %message)
#define DBLogWarning(%message)	do ##class(Base.DBLogger.LogRequest).log(##class(Base.DBLogger.LogLevel).Warning(), %message)
#define DBLogError(%message)	do ##class(Base.DBLogger.LogRequest).log(##class(Base.DBLogger.LogLevel).Error(), %message)
#define DBLogFatal(%message)	do ##class(Base.DBLogger.LogRequest).log(##class(Base.DBLogger.LogLevel).Fatal(), %message)


]]></Routine>
</Export>
