Accounting Software
Small Business Software Estimating Software
Inventory SoftwareInventory Control SoftwareInventory Tracking SoftwareInventory Management SoftwareConstruction Management SoftwareProject Management SoftwareBusiness Management Software

Data Iterators (Source Code)

Link to: header | other data directory

Copyright Turtle Creek Software 1996-2006. All Rights Reserved.

Comments

DB_Iterator

This class iterates thru database objects for the Goldenseal job cost accounting software,
project management software, construction estimating software
and construction project estimating software.

We usually call this via DB_File::DoForEachObject

This is a raw database function that goes deep into the Neo data
management. It's not very reliable, so we have mostly replaced this
with our own record management code. If you need to look at objects,
consider using DB_ListManager::GetIDArray or some other turtle code

SUPERCLASS = CNeoIndexIterator

Source Code

/*********************************************************************************

Func_AddID

fill in an id array with the ids of the objects in this iterator

*********************************************************************************/
static void *Func_AddID(const CNeoCollection *xNode, const short xOffset,
const NeoLockType /*xLock*/,
void *array)
{
// get the id from the node
DBid id;
if (xOffset < 0) // it is a persistent object
{
xNode->GetMemberValue(tag_id, type_long, &id);
}
else // it is a node
{
xNode->getEntryValue(xOffset, tag_id, type_long, &id);
}
// stuff the id into the array
TCS_FailNILMsg(array, TCS_GetErrString(errID_BadArray));
((TObjectIDArray *)array)->Append(id);

// we want to keep going, so always return nil here,
// otherwise DoUntil will terminate
return nil;
}
/*********************************************************************************

Func_AddInfo

fill in an object info array with the ids of the objects in this iterator

*********************************************************************************/
static void *Func_AddInfo(const CNeoCollection *xNode, const short xOffset,
const NeoLockType /*xLock*/, void *array)
{
// get the id values from the node
DBid id = 0;
UInt8 classID = 0;

if (xOffset < 0) // it is already persistent object
{
xNode->GetMemberValue(tag_id, type_long, &id);
xNode->GetMemberValue(tag_classid, type_uchar, &classID);
}
else // it is a node
{
// fetch the object from the node
CNeoPersist *object = xNode->getObject(xOffset);

if (object)
{
// do we need a watcher?

object->GetMemberValue(tag_id, type_long, &id);
object->GetMemberValue(tag_classid, type_uchar, &classID);
}
}
// fill the struct
SObjectInfo info;
info.itemID = id;
info.classID = classID;
info.transactionType = 0;

// stuff the struct into the array
TCS_FailNILMsg(array, TCS_GetErrString(errID_BadArray));
((TObjectInfoArray *)array)->Append(info);

// we want to keep going, so always return nil here,
// otherwise DoUntil will terminate
return nil;
}
/*********************************************************************************

Func_AddFullInfo TCS 2/29/00

fill in a full object info array with the ids of the objects in this iterator.
Use this when dealing with objects with a class ID of over 255

*********************************************************************************/
static void *Func_AddFullInfo(const CNeoCollection *xNode, const short xOffset,
const NeoLockType /*xLock*/, void *array)
{


// get the id values from the node
DBid id = 0;
DBid classID = 0;
if (xOffset < 0) // it is already persistent object
{
xNode->GetMemberValue(tag_id, type_long, &id);
xNode->GetMemberValue(tag_classid, type_long, &classID);
}
else // it is a node
{
// fetch the object from the node
CNeoPersist *object = xNode->getObject(xOffset);

if (object)
{
// do we need a watcher?

object->GetMemberValue(tag_id, type_long, &id);
object->GetMemberValue(tag_classid, type_long, &classID);
}
}
// fill the struct
SFullObjectInfo info;
info.itemID = id;
info.classID = classID;

// stuff the struct into the array
TCS_FailNILMsg(array, TCS_GetErrString(errID_BadArray));
((TFullObjectInfoArray *)array)->Append(info);

// we want to keep going, so always return nil here,
// otherwise DoUntil will terminate
return nil;
}
/*********************************************************************************

Func_AddReportInfo

fill in an object info array with the ids of the objects in this iterator

*********************************************************************************/
static void *Func_AddReportInfo(const CNeoCollection *xNode, const short xOffset,
const NeoLockType /*xLock*/, void *array)
{
// get the id values from the node
DBid id = 0;
DBid classID = 0;
if (xOffset < 0) // it is already persistent object
{
xNode->GetMemberValue(tag_id, type_long, &id);
xNode->GetMemberValue(tag_classid, type_long, &classID);
}
else // it is a node
{
// fetch the object from the node
CNeoPersist *object = xNode->getObject(xOffset);

if (object)
{
// do we need a watcher?

object->GetMemberValue(tag_id, type_long, &id);
object->GetMemberValue(tag_classid, type_long, &classID);
}
}
// fill the struct
SReportRowInfo info;
CReportTable::InitializeRowInfo(info, rowtype_data);
info.itemID = id;
info.classID = classID;

// stuff the struct into the array
TCS_FailNILMsg(array, TCS_GetErrString(errID_BadArray));
((TReportRowArray *)array)->Append(info);

// we want to keep going, so always return nil here,
// otherwise DoUntil will terminate
return nil;
}
/*********************************************************************************

Func_ApplyNameFunc TCS removed 1/27/04

apply a name function

*********************************************************************************/
/*static void *Func_ApplyNameFunc(const CNeoCollection *xNode, const short xOffset,
const NeoLockType xLock, void *funcInfo)
{
CTextString objectName;
DBid id;

if (xOffset < 0)
{ // the node refers to an actual object, we can get
// the cstring directly
xNode->GetMemberValue(tag_name, type_cstring, &objectName);
xNode->GetMemberValue(tag_id, type_long, &id);
}
else
{ // there is an offset, get the data from the node entry
// corresponding to the current object. Here we need to get
// a char * because the node is an index and may not know
// about our cstrings
char *namePtr;

xNode->getEntryValue(xOffset, tag_name, kNeoStringPtrType, &namePtr);
xNode->getEntryValue(xOffset, tag_id, type_long, &id);
// set the value of name from namePtr. This does an implicit
// strcpy which is rather inefficient...but we can optimize later
objectName = namePtr;
}
// call the name info function to do its thing
SNameFuncInfo *nameFuncInfo = (SNameFuncInfo *)funcInfo;
(nameFuncInfo->func)(&objectName, id, nameFuncInfo->param1,
nameFuncInfo->param2, nameFuncInfo->param3,
nameFuncInfo->param4, nameFuncInfo->param5,
nameFuncInfo->param6);
// we want to keep going, so always return nil here,
// otherwise DoUntil will terminate
return nil;
}*//*********************************************************************************
Func_ApplyMenuNameFunc TCS 10/8/98 removed 1/27/04
apply a name function using the artificially constructed menu name
*********************************************************************************/
/*static void *Func_ApplyMenuNameFunc(const CNeoCollection *xNode, const short xOffset,
const NeoLockType xLock,
void *funcInfo)
{
CTextString objectName;
DBid id;

if (xOffset < 0)
{ // the node refers to an actual object, we can get
// the cstring directly
xNode->GetMemberValue(tag_menuname, type_cstring, &objectName);
xNode->GetMemberValue(tag_id, type_long, &id);
}
else
{ // there is an offset, get the data from the node entry
// corresponding to the current object. Here we need to get
// a char * because the node is an index and may not know
// about our cstrings
char *namePtr;

xNode->getEntryValue(xOffset, tag_menuname, kNeoStringPtrType, &namePtr);
xNode->getEntryValue(xOffset, tag_id, type_long, &id);
// set the value of name from namePtr. This does an implicit
// strcpy which is rather inefficient...but we can optimize later
objectName = namePtr;
}
// call the name info function to do its thing
SNameFuncInfo *nameFuncInfo = (SNameFuncInfo *)funcInfo;
(nameFuncInfo->func)(&objectName, id, nameFuncInfo->param1,
nameFuncInfo->param2, nameFuncInfo->param3,
nameFuncInfo->param4);
// we want to keep going, so always return nil here,
// otherwise DoUntil will terminate
return nil;
}*/
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

*CountFunc

uses DoUntil to get an object count of all objects in this iterator.
*********************************************************************************/
static void *CountFunc(const CNeoCollection */*xNode*/,
const short /*xOffset*/,
const NeoLockType /*xLock*/, void *xParam)
{
TCS_FailNILMsg(xParam, TCS_GetErrString(errID_BadPointer));

(*((SInt32 *)xParam))++;
return nil;
}
/*********************************************************************************

DeleteIteratorAnTCSey

remove the given iterator as well as its key
*********************************************************************************/
void DeleteIteratorAnTCSey(DB_Iterator *&iterator)
{
// sanity check
TCS_FailNILMsg(iterator, TCS_GetErrString(errID_BadIterator));
// let's see if the iterator has a key

CNeoSelect *key = iterator->getKey();
if (key != nil)
{ // it has a key we must delete it
TCS_Forget(key); // TCS rev 11/5/00
iterator->setKey(nil);
}
// now we delete the iterator and set it to nil
TCS_Forget(iterator);
}

#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

CreateIDArray

create an array of id numbers from the given iterator

*********************************************************************************/
void DB_Iterator::CreateIDArray(TObjectIDArray &array)
{
// changes 1/22/98
NeoTestFunc1 iterFunc = NeoNewTestFunc1(Func_AddID);
// CProcPtrWatcher funcWatch((UniversalProcPtr*) iterFunc);

// sanity check
TCS_FailNILMsg(iterFunc, TCS_GetErrString(errID_BadFunction));

// call the Neo doUntil method to walk the iterator's entries and fill in each id
doUntil(iterFunc, &array);

// tidy up TCS 12/6/00
TCS_DisposeRoutine(iterFunc);
}

/*********************************************************************************

CreateFullInfoArray 2/29/00
create an array of full object info structs from the given iterator

*********************************************************************************/
void DB_Iterator::CreateFullInfoArray(TFullObjectInfoArray &array)
{
NeoTestFunc1 iterFunc = NeoNewTestFunc1(Func_AddFullInfo); // bugfix TCS 10/11/01

// sanity check
TCS_FailNILMsg(iterFunc, TCS_GetErrString(errID_BadFunction));

// call the Neo doUntil method to walk the iterator's entries and fill in each id
doUntil(iterFunc, &array);

// tidy up TCS 12/6/00
TCS_DisposeRoutine(iterFunc);
}

/*********************************************************************************

CreateInfoArray 9/29/98
create an array of object info structs from the given iterator

*********************************************************************************/
void DB_Iterator::CreateInfoArray(TObjectInfoArray &array)
{
NeoTestFunc1 iterFunc = NeoNewTestFunc1(Func_AddInfo);

// sanity check
TCS_FailNILMsg(iterFunc, TCS_GetErrString(errID_BadFunction));

// call the Neo doUntil method to walk the iterator's entries and fill in each id
doUntil(iterFunc, &array);

// tidy up TCS 12/6/00
TCS_DisposeRoutine(iterFunc);
}

/*********************************************************************************

CreateReportInfoArray 6/24/99
create an array of report info structs

*********************************************************************************/
void DB_Iterator::CreateReportInfoArray(TReportRowArray &array)
{
NeoTestFunc1 iterFunc = NeoNewTestFunc1(Func_AddReportInfo);

// sanity check
TCS_FailNILMsg(iterFunc, TCS_GetErrString(errID_BadFunction));

// call the Neo doUntil method to walk the iterator's entries and fill in each id
doUntil(iterFunc, &array);

// tidy up TCS 12/6/00
TCS_DisposeRoutine(iterFunc);
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

DoForEach

apply the function func to each object in the iterator
*********************************************************************************/
void DB_Iterator::DoForEach(ActionFunc func, void *param1, void *param2,
void *param3, void *param4,
void *param5, void *param6)
{
// sanity check
TCS_FailNILMsg(func, TCS_GetErrString(errID_BadFunction));
SInt32 counter = 0;

// loop through the objects in the iterator
DB_PersistentObject *object = GetCurrentObject();
while (object != nil)
{
// set the object as needed, so it won't be deleted right away.
// the watcher below will remove the reference.
object->Needed();

// wrap the object in a watcher so that it is properly
// dereferenced at the end of this scope
{
DB_ObjectWatcher watcher(object);

// apply the function
(*func)(object, param1, param2, param3, param4, param5, param6);

// do a memory purge occasionally TCS 12/28/02
counter++;
if (counter % 200 == 199)
gDBFile->SaveAllAndPurge();
}

// move to the next object
object = GetNextObject();
}
}