Click here to Skip to main content
15,897,518 members
Home / Discussions / ATL / WTL / STL
   

ATL / WTL / STL

 
GeneralRe: WTL COM? Pin
Kuryn15-Dec-07 18:12
Kuryn15-Dec-07 18:12 
GeneralRe: WTL COM? Pin
George L. Jackson16-Dec-07 14:23
George L. Jackson16-Dec-07 14:23 
AnswerRe: WTL COM? Pin
led mike18-Dec-07 5:29
led mike18-Dec-07 5:29 
AnswerRe: WTL COM? Pin
Michael Dunn5-Jan-08 20:36
sitebuilderMichael Dunn5-Jan-08 20:36 
GeneralWindows Service Help [modified] Pin
narayanagvs10-Dec-07 19:02
narayanagvs10-Dec-07 19:02 
GeneralRe: Windows Service Help Pin
myshketer11-Dec-07 21:21
myshketer11-Dec-07 21:21 
GeneralRe: Windows Service Help Pin
led mike12-Dec-07 6:29
led mike12-Dec-07 6:29 
GeneralSeeking advice on proper use of some c/c++ stuff, on my code. [modified] Pin
Dexterus6-Dec-07 0:49
Dexterus6-Dec-07 0:49 
I've very recently started to build an app that works with some db items and having seen something sort of like it in php, tried to implement a DB -> object class.
But seeing that I'm kind of ... erm, let's say noobish and used pointers extensively in the class I've decided to try and get some feedback on if the code has some glaring big bad problems from my coding practices side that might let it work ok for 1 example or 2 but that could turn very ugly in some circumstances.
Background:
1. This will act as a base class, each table in the db will implement a new class actualyl defining values for field names, field <-> attribute, links to other objects etc.
2. Will be in a multithreaded app but while different instances will be used in different threads, 1 instance won't be simultaneously used in 2 threads, at least that's what I believe atm.
3. Connection pointer is global, kept alive forever if needed.
4. Not even close to finished, not even current methods, still some error checking to do and possibly more.

So, all I want is if possible some pointers to stuff I terribly messed up and should avoid doing in my code from now on. Basicly learned all from C/C++ on my own from my own code, with what php experience I had and the 6-7 years of experience doing algorithms in pascal, so my approach to solid programming didn't even include threads, avoiding memory "destruction", pointers and all the nice stuff c/c++ on windows has to offer.

Next post should possibly contain 2 more listings, this class' header and a derived class.

DBItem.cpp
<code>// Included all generally needed stuff here
#include "stdafx.h"
#include "DBItem.h"
#include "DB_Obj1.h"

DBItem::DBItem(int nId, _ConnectionPtr  pConnectionGeneral)
{
	pConnDB = pConnectionGeneral;
	pRstDB.CreateInstance(__uuidof(Recordset));
	nIid = nId;
}

DBItem::~DBItem()
{
	pRstDB->Close();
	pRstDB.Release();
	pRstDB.Detach();

	ds.mAttr.clear();
	ds.mAttrFields.clear();
	ds.mAttrLoaded.clear();
	ds.mAttrModified.clear();
	ds.mDeps.clear();
	ds.mLinks.clear();
	ds.sIdField.~basic_string();
	ds.sTableName.~basic_string();
	ds.sTittleAttr.~basic_string();
	ds.sTreeLink.~basic_string();

	while (!mMessages.empty())
	{
		mMessages.pop();
	}
}

 /**
 *	Loads object's attributes from DB to ds.mAttr, as variants.
 *      Sets Loaded flag
 */
BOOL DBItem::Load()
{
	char *sztempQuery;
	string sQuery, sFldName;
	int i;
	FieldPtr pField;

	FormLoadQuery(&sztempQuery);
	sQuery = sztempQuery;
	free(sztempQuery);

	if (ExecuteQuery(sQuery))
	{
		for (i = 0; i < pRstDB->Fields->Count; i++)
		{
			pField = pRstDB->Fields->GetItem(_variant_t((long)i, VT_I4));
			sFldName = pField->Name;
			ds.mAttr[ds.mAttrFields[sFldName]] = pField->Value;
			ds.mAttrLoaded[ds.mAttrFields[sFldName]] = TRUE;
		}
	}
	else
	{
		AddMessage(DB_ERROR, "Error while executing load query. Check previous message!");
		return FALSE;
	}

	return TRUE;
}

 /**
 *	Returns a variant attribute. Loads the attributes is requested one isn't loaded, just so we won't load too early
 *	or too much
 */
_variant_t DBItem::GetAttr(string sAttr)
{
	_variant_t vAttr;

	if (nIid == 0)
	{
		vAttr.vt = VT_NULL;
		return vAttr;
	}

	if (!ds.mAttrLoaded[sAttr])
	{
		if (!Load())
		{
			vAttr.vt = VT_NULL;
		}
		else
		{
			vAttr = ds.mAttr[sAttr];
		}
	}
	else
	{
		vAttr = ds.mAttr[sAttr];
	}

	return vAttr;
}

 /**
 *	Tries to execute sQuery on the ADO connection object. Fills pRstDB
 *	Exceptions will fail it and push a massage describing themselves onto message stack.
 */
BOOL DBItem::ExecuteQuery(string sQuery)
{
	try
	{
		pRstDB = pConnDB->Execute(sQuery.c_str(), NULL, adCmdText);
	}
	catch (_com_error &e)
	{
		AddMessage(DB_EXCEPTION, "Exception in DBItem::ExecuteQuery(), Class '" + GetClass() + "', ID " + ToString(nIid) + " Error: " + (string)e.ErrorMessage());
		return FALSE;
	}

	return TRUE;
}

 /**
 *	Pushes a message to the object's message stack. Errors, Exceptions, Infos, we'll see about others
 *	TODO: pop message
 */
void DBItem::AddMessage(int nMsgType, string sMessage)
{
	string stempMessage;

	stempMessage = ToString(nMsgType) + sMessage;
	mMessages.push(stempMessage);
}

 /**
 *	Returns a string containing objects name, as defined by ds.sTittleAttr
 *	TODO: Treat case where there's no such thing as ds.sTittleAttr
 */
string DBItem::GetName()
{
	_variant_t vVar;
	string stempName = "";

	vVar = GetAttr(ds.sTittleAttr);
	try
	{
		stempName =  vVar.operator _bstr_t().operator const char *();
	}
	catch (_com_error &e)
	{
		AddMessage(DB_EXCEPTION, "Exception in DBItem::GetName(), Class '" + GetClass() + "', ID " + ToString(nIid) + " Error: " + (string)e.ErrorMessage());
		stempName = "";
	}
	return stempName;
}

/*
 *	Returns a pointer to the instance of the type and ID specified by attribute's value, hopefully (it does!!!)
 *
 */
DBItem *DBItem::GetObject(string sAttr)
{
	DBItem *mliInstance;
	_variant_t vIdAttr;
	unsigned long dInstId;

	vIdAttr = GetAttr(sAttr);
	dInstId = vIdAttr.operator long();

	mliInstance = GetInstance(ds.mLinks[sAttr], dInstId);

	return mliInstance;
}

 /**
 *	Returns a DBIList pointer to a vector containing pointers to object instances masked as DBItem
 *	Have to remember to delete each instance and possibly the vector in the place of use
 *	To use, iterate through vector, cast to required class, they're all hiding as base class DBItem.
 */
DBIList *DBItem::GetInstances()
{
	DBIList *pVector;
	DBItem *mliInstance;
	char *sztempQuery;
	string sQuery;
	unsigned long ulID, ulCount;
	long i;
	FieldPtr pField;

	// Query to get all IDs
	FormGetIDsQuery(&sztempQuery);
	sQuery = sztempQuery;
	free(sztempQuery);

	if (ExecuteQuery(sQuery))
	{
		// Get number of instances to init our little vector container
		ulCount = pRstDB->Fields->Count;
		pVector = new DBIList(ulCount);
		for (i = 0; i < pRstDB->Fields->Count; i++)
		{
			pField = pRstDB->Fields->GetItem(_variant_t((long)i, VT_I4));
			// Get each ID value
			ulID = pField->Value.ulVal;
			// Instantiate
			mliInstance = GetInstance(GetClass(), ulID);
			// Push pointer in vector
			pVector->push_back(mliInstance);
		}
		// Return a pointer to our filled vector.
		return pVector;
	}
	else
	{
		AddMessage(DB_ERROR, "Error while executing ID query. Check previous message!");
		return NULL;
	}
}

 /**
 *	Returns current object's base class name. Should be overidden by all classes deriving from this.
 */
string DBItem::GetClass()
{
	return (string)"DBItem";
}

 /**
 *	Returns a pointer to a specific item type instance, posing as a base item instance, hopefully
 *	Given a class name and database ID
 */
DBItem *DBItem::GetInstance(string sClassName, unsigned long nId)
{	

	if (sClassName == "DB_Obj1")
		return new DB_Obj1(nId, pConnDB);

	return NULL;
}

 /**
 *	Fills *szQuery with the query needed to get all the object's attributes
 */
void DBItem::FormLoadQuery(char **szQuery)
{
	string stempQuery;

	stempQuery = "SELECT * FROM ";
	stempQuery += ds.sTableName;
	stempQuery += " WHERE ";
	stempQuery += ds.sIdField;
	stempQuery += "=";
	stempQuery += ToString(nIid);

	*szQuery = (char *) malloc(stempQuery.length() + 1);
	if (*szQuery == NULL)
	{
		
	}
	else
	{
		memset(*szQuery, 0, stempQuery.length() + 1);
		memcpy(*szQuery, stempQuery.c_str(), stempQuery.length());
	}
}

 /**
 *	Fills *szQuery with the query needed to get all the current class' instance IDs
 */
void DBItem::FormGetIDsQuery(char **szQuery)
{
	string stempQuery;

	stempQuery = "SELECT "
	stempQuery += ds.sIdField;
	stempQuery += " FROM ";
	stempQuery += ds.sTableName;

	*szQuery = (char *) malloc(stempQuery.length() + 1);
	if (*szQuery == NULL)
	{
		
	}
	else
	{
		memset(*szQuery, 0, stempQuery.length() + 1);
		memcpy(*szQuery, stempQuery.c_str(), stempQuery.length());
	}
}

 /**
 *	Converts input int to string representation
 */
string DBItem::ToString(int nConvertable)
{
	string stempConvert;
	char *sztempConvert;

	sztempConvert = (char *) malloc(16);
	memset(sztempConvert, 0, 16);

	_itoa(nConvertable, sztempConvert, 10);

	stempConvert = sztempConvert;
	free(sztempConvert);

	return stempConvert;
}

 /**
 *	Converts input long to string representation
 */
string DBItem::ToString(long nConvertable)
{
	string stempConvert;
	char *sztempConvert;

	sztempConvert = (char *) malloc(16);
	memset(sztempConvert, 0, 16);

	_ltoa(nConvertable, sztempConvert, 10);

	stempConvert = sztempConvert;
	free(sztempConvert);

	return stempConvert;
}
</code>


modified on Friday, December 07, 2007 4:27:26 AM

GeneralRe: Seeking advice on proper use of some c/c++ stuff, on my code. [modified] Pin
Dexterus6-Dec-07 0:52
Dexterus6-Dec-07 0:52 
GeneralVista's Explorer toolbar control Pin
yarp5-Dec-07 23:31
yarp5-Dec-07 23:31 
GeneralRe: Vista's Explorer toolbar control Pin
Michael Dunn6-Jan-08 11:20
sitebuilderMichael Dunn6-Jan-08 11:20 
GeneralRe: Vista's Explorer toolbar control Pin
yarp6-Jan-08 19:18
yarp6-Jan-08 19:18 
QuestionProlem with rich edit control. ITextService's TxGetNaturalSize doesnt give me the right value.. [modified] Pin
Arif Siddiquee5-Dec-07 1:25
Arif Siddiquee5-Dec-07 1:25 
QuestionContextMenu HWND in a Shell Extension Dll Pin
Jeffrey Walton30-Nov-07 23:45
Jeffrey Walton30-Nov-07 23:45 
GeneralRe: ContextMenu HWND in a Shell Extension Dll Pin
Michael Dunn6-Jan-08 11:22
sitebuilderMichael Dunn6-Jan-08 11:22 
QuestionC++ String split Pin
Mustafa Ismail Mustafa30-Nov-07 0:22
Mustafa Ismail Mustafa30-Nov-07 0:22 
AnswerRe: C++ String split Pin
Stuart Dootson30-Nov-07 3:36
professionalStuart Dootson30-Nov-07 3:36 
JokeRe: C++ String split Pin
Florin Crişan30-Nov-07 4:00
Florin Crişan30-Nov-07 4:00 
GeneralRe: C++ String split Pin
Mustafa Ismail Mustafa30-Nov-07 7:25
Mustafa Ismail Mustafa30-Nov-07 7:25 
AnswerRe: C++ String split Pin
Florin Crişan5-Dec-07 5:59
Florin Crişan5-Dec-07 5:59 
GeneralRe: C++ String split Pin
Mustafa Ismail Mustafa5-Dec-07 9:38
Mustafa Ismail Mustafa5-Dec-07 9:38 
GeneralRe: C++ String split Pin
Stuart Dootson5-Dec-07 20:19
professionalStuart Dootson5-Dec-07 20:19 
GeneralRe: C++ String split Pin
Mustafa Ismail Mustafa5-Dec-07 23:49
Mustafa Ismail Mustafa5-Dec-07 23:49 
AnswerRe: C++ String split Pin
Florin Crişan6-Dec-07 3:11
Florin Crişan6-Dec-07 3:11 
AnswerRe: C++ String split Pin
Florin Crişan30-Nov-07 3:46
Florin Crişan30-Nov-07 3:46 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.