#include <atldbcli.h>
#include <cassert>
#include <iostream>
#include <sstream>
#include <string>
const std::string globalDataPath("d:/Data"); // the directory must exist
const std::string globalTableName("data");
const std::string globalProviderStr("VFPOLEDB.1"); // MS Visual FoxPro OLE DB
using namespace std;
/*! \brief Buffer and accessors for OLE DB Consumer Templates.
*/
class CBasicDataAccessor
{
public:
long code; //!< key field of the record
char notes[51]; //!< some text
BEGIN_ACCESSOR_MAP(CBasicDataAccessor, 1)
BEGIN_ACCESSOR(0, false) // simple, non-automatic
COLUMN_ENTRY(1, code)
COLUMN_ENTRY(2, notes)
END_ACCESSOR()
END_ACCESSOR_MAP()
inline void ClearRecord()
{
code = 0;
ZeroMemory(notes, sizeof(notes));
}
};
/*! \brief Main body.
*/
int main()
{
// Init the COM.
HRESULT hr = ::CoInitialize(NULL);
assert(SUCCEEDED(hr));
// Open the data source and the session.
CDataSource ds;
CSession session;
CDBPropSet propSet(DBPROPSET_DBINIT);
propSet.AddProperty(DBPROP_INIT_DATASOURCE, globalDataPath.c_str());
hr = ds.Open(globalProviderStr.c_str(), &propSet);
if (SUCCEEDED(hr))
{
hr = session.Open(ds);
assert(SUCCEEDED(hr));
}
// Create the data table.
CCommand<> cmd; // No accessor neccessary.
string SQL_COMMAND(
"CREATE TABLE data CODEPAGE=1250"
"(Code Integer NOT NULL, UNIQUE Code FOR NOT DELETED() TAG xCode,"
" Notes Char(50)\n)"
);
hr = cmd.Open(session, SQL_COMMAND.c_str());
assert(SUCCEEDED(hr));
cmd.Close();
cmd.ReleaseCommand();
// The table object with accessors.
CTable<CAccessor<CBasicDataAccessor> > table;
// Properties for inserting, deleting, ane changing the existing record.
CDBPropSet ps(DBPROPSET_ROWSET);
ps.AddProperty(DBPROP_IRowsetChange, true);
ps.AddProperty(DBPROP_UPDATABILITY,
DBPROPVAL_UP_CHANGE | DBPROPVAL_UP_INSERT | DBPROPVAL_UP_DELETE);
// Open the table and search for the record.
hr = table.Open(session, globalTableName.c_str(), &ps);
assert(SUCCEEDED(hr));
// Insert some records
table.ClearRecord();
for (int i = 0; i < 10; ++i)
{
table.code = i;
string s("some text");
strncpy_s(table.notes, s.c_str(), sizeof(table.notes));
hr = table.Insert();
assert(SUCCEEDED(hr));
}
// Search for the record with code equal to 5.
// Brute force here... How it should be done correctly?
// How can I use the index via CTable<> ?
long code = 5;
hr = table.MoveFirst();
table.GetData(0);
while (SUCCEEDED(hr) && table.code != code)
{
hr = table.MoveNext();
table.GetData(0);
}
// Delete the record.
hr = table.Delete();
assert(SUCCEEDED(hr));
// Insert the record with the same code. It is physically placed
// at a different place.
table.ClearRecord();
table.code = code;
string s = "some other text";
strncpy_s(table.notes, s.c_str(), sizeof(table.notes));
assert(SUCCEEDED(hr));
hr = table.Insert();
assert(SUCCEEDED(hr));
// How to find the active record with the code to be deleted
// again? It must be related to the usage of index probably.
// Is it possible with CTable object at all?
??? What code should I put here?
// Delete the record.
hr = table.Delete();
assert(SUCCEEDED(hr));
// Close the table object.
table.Close();
// Close the session and the data source objects.
session.Close();
ds.Close();
// Finish the work with COM.
::CoUninitialize();
return 0;
}
Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.
When asked, what has been your best career decision?
Deciding to stick with EE.
Being involved with EE helped me to grow personally and professionally.
Connect with Certified Experts to gain insight and support on specific technology challenges including:
We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE