//----------------------------------------------------------------------------//
// dbstep_t3.cpp - This example shows a more advanced object/relational
// mapping between classes NewsRecord (table News) and NewsAuthor
// (table Authors).
// A simple join is made between tables and the result is mapped onto
// class NewsRecord.
//----------------------------------------------------------------------------//
#include <iostream>
#ifdef __BORLANDC__
#include <conio.h>
#endif
#include "dbstep_test.h"
// this class is mapped with table 'News' in database
// and must be derived from DBSTEP::Record
class NewsRecord: public DBSTEP::Record
{
// output operator
friend std::ostream& operator << (std::ostream& os, const NewsRecord& nr);
protected:
// virtual method to map fields
virtual void addFields();
int id;
int author_id;
DBSTEP::Datetime newsdate;
std::string title;
std::string summary;
// these fields are filleb by method joinSelect
std::string name;
std::string email;
public:
NewsRecord(DBSTEP::Db* db_ptr);
virtual ~NewsRecord();
// method for setting fields
void setFields(int p_author_id,
DBSTEP::Datetime p_newsdate, std::string title,
std::string summary);
// selects that joins table News and table Authors
bool joinSelect();
};
// method for setting fields
void NewsRecord::setFields(int p_author_id,
DBSTEP::Datetime p_newsdate, std::string p_title,
std::string p_summary)
{
id=0; // id is auto-increment
author_id=p_author_id;
newsdate = p_newsdate;
title=p_title;
summary=p_summary;
}
// output operator
std::ostream& operator << (std::ostream& os, const NewsRecord& nr)
{
os << "Title: " << nr.title << " ("
<< nr.newsdate.getDay() << "/"
<< nr.newsdate.getMonth() << "/"
<< nr.newsdate.getYear()
<< ") Author:"
<< nr.name << " ("
<< nr.email << ")";
return os;
}
// the constructor sets table name and calls mapping method 'addFiels()'
NewsRecord::NewsRecord(DBSTEP::Db* db_ptr):
DBSTEP::Record(db_ptr, "News")
{
addFields();
}
NewsRecord::~NewsRecord()
{ }
// this method maps fields and class variables
void NewsRecord::addFields()
{
addField("id", id, DBSTEP_ALLOP_FIELD | DBSTEP_PRIMARY_KEY | DBSTEP_AUTOINC_FIELD);
addField("author_id", author_id);
addField("newsdate", newsdate);
addField("title", title);
addField("summary", summary);
// these fields are read-only and are filled with a SQL join
// with Authors table
addField("name", name, DBSTEP_SELECT_FIELD);
addField("email", email, DBSTEP_SELECT_FIELD);
}
bool NewsRecord::joinSelect()
{
DBSTEP::Query q(db_ptr);
// we use 'AS' for each field to make sqlite happy
q = "SELECT n.id AS id, n.newsdate AS newsdate, n.title AS title, \
n.summary AS summary, \
a.email AS email, a.name AS name \
FROM News n, Authors a \
WHERE a.id = n.author_id \
ORDER BY n.id";
return select(&q);
}
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
// this class is mapped with table 'Authors' in database
// and must be derived from DBSTEP::Record
class AuthorRecord: public DBSTEP::Record
{
protected:
// virtual method to map fields
virtual void addFields();
int id;
std::string name;
std::string email;
public:
AuthorRecord(DBSTEP::Db* db_ptr);
virtual ~AuthorRecord();
// method for setting fields
void setFields(int p_id, std::string p_name,
std::string p_email);
};
// the constructor sets table name and calls mappin method 'addFiels()'
AuthorRecord::AuthorRecord(DBSTEP::Db* db_ptr):
DBSTEP::Record(db_ptr, "Authors")
{
addFields();
}
AuthorRecord::~AuthorRecord()
{ }
void AuthorRecord::setFields(int p_id, std::string p_name,
std::string p_email)
{
id=p_id;
name=p_name;
email = p_email;
}
// this method maps fields and class variables
void AuthorRecord::addFields()
{
addField("id", id, DBSTEP_ALLOP_FIELD | DBSTEP_PRIMARY_KEY);
addField("name", name);
addField("email", email);
}
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
int main (int argc, char** argv)
{
// here we get driver code
int drv=getDriver(argc, argv);
// init parameter map
DBSTEP::StringMapType param_map;
try
{
if (drv == DBSTEP_FBIRD)
param_map ["dbname"] = "dbstep_test.gdb";
else
{
param_map ["dbname"] = "dbstep_test";
param_map ["host"] = "localhost";
param_map ["user"] = "dbstep_user";
param_map ["password"] = "dbstep_test";
}
param_map ["autocommit"] = "0";
// new database object
DBSTEP::Db db(drv);
// opens connection
db.openConnection(param_map);
{
AuthorRecord a(&db);
a.setQueryMode(DBSTEP_QUERY_EXEC_PREPARED);
a.setFields(1, "Pippo", "pippo@foo.bar");
a.insert();
a.setFields(2, "Pluto", "pluto@foo.bar");
a.insert();
NewsRecord n(&db);
NewsRecord n2(&db);
n.setQueryMode(DBSTEP_QUERY_EXEC_PREPARED);
n2.setQueryMode(DBSTEP_QUERY_EXEC_PREPARED);
n.setFields(2, DBSTEP::Datetime(2001, 3, 6, 12, 12, 11),
"Title1", "Summary1");
n.insert();
n.setFields(1, DBSTEP::Datetime(2001, 11, 6, 0, 0, 0),
"Title2", "Summary2");
n.insert();
n.setFields(1, DBSTEP::Datetime(2001, 1, 5, 0, 0, 0),
"Title3", "Summary3");
n.insert();
std::cout << "\nJoin SELECT\n";
n.joinSelect();
n2.joinSelect();
while (n.next())
{
while (n2.next())
std::cout << n2 << std::endl;
std::cout << n << std::endl;
}
// cleanup
n.removeAll();
a.removeAll();
std::cout.flush();
}
db.closeConnection();
}
catch (errException e)
{
std::cout << "\nERROR: " << DBSTEP::Params::instance()->getErrManager()->first()->getName() << std::endl;
}
// cleans up
DBSTEP::Params::instance()->dispose();
#ifdef __BORLANDC__
getch();
#endif
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1