Seeking advice on proper use of some c/c++ stuff, on my code. [modified]
-
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
// 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; f
-
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
// 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; f
As posted earlier, 2 more listings, header for class and derived class. DBItem.h
#define DB_ERROR 1 #define DB_EXCEPTION 2 class DBItem; typedef pair<string, string> ssPair; typedef vector<DBItem*> DBIList; struct DataStructure { map<string, _variant_t> mAttr; map<string, BOOL> mAttrLoaded; map<string, BOOL> mAttrModified; map<string, string> mAttrFields;// field, attr name; map<string, string> mLinks;// attr, link class map<string, ssPair> mDeps; // depends string sIdField; string sTableName; string sTittleAttr; string sTreeLink; }; class DBItem { public: DBItem(int nId, _ConnectionPtr pConnectionGeneral = NULL); virtual ~DBItem(); _variant_t GetAttr(string sAttr); string GetName(); DBItem *GetObject(string sAttr); DBIList *GetInstances(); virtual string GetClass(); protected: DBItem *GetInstance(string sClassName, unsigned long nId); DataStructure ds; private: _ConnectionPtr pConnDB; _RecordsetPtr pRstDB; int nIid; stack<string> mMessages; BOOL bNoLogging; BOOL Load(); void FormLoadQuery(char **szQuery); void FormGetIDsQuery(char **szQuery); BOOL ExecuteQuery(string sQuery); void AddMessage(int nMsgType, string sMessage); string ToString(int nConvertable); string ToString(long nConvertable); };
DB_Obj1.cpp
#include "stdafx.h" #include "DB_Obj1.h" DB_Obj1::DB_Obj1(int nId, _ConnectionPtr pConnectionGeneral) : DBItem(nId, pConnectionGeneral) { _variant_t vtNull; vtNull.vt = VT_NULL; // Init attributes as NULL (the variant way) ds.mAttr["Id"] = vtNull; ds.mAttr["Name"] = vtNull; ds.mAttr["State"] = vtNull; // Set Table Field <=> Attribute correspondence ds.mAttrFields["IdObj"] = "Id"; ds.mAttrFields["ObjName"] = "Name"; ds.mAttrFields["CurrentState"] = "State"; // Init attributes as not load and not modified // TODO: Implement uses for this :D ds.mAttrLoaded["Id"] = ds.mAttrLoaded["Name"] = ds.mAttrLoaded["State"] = ds.mAttrModified["Id"] = ds.mAttrModified["Name"] = ds.mAttrModified["State"] = FALSE; // Set internal links to other Item Types, as in attributes that represent another object, via an ID ds.mLinks["State"] = "DB_StateObj"; // Set dependencies. What other object types link to me basicly. Should support dependency types // and enforcing them on deletes, inserts ds.mDeps["someone_depends_on_me_somehow"] = make_pair((string)"