[prev in list] [next in list] [prev in thread] [next in thread] 

List:       mysql-plusplus
Subject:    Passing functors into query
From:       "Joel Fielder" <joel.fielder () switchplane ! com>
Date:       2007-04-13 16:32:41
Message-ID: 0d1f01c77de9$5d4a9790$0500a8c0 () joel
[Download RAW message or body]

Hello,

Quite often, I have code like this:

query << "select whatever";
query.storein(wherever);

for(it = wherever.begin(); it != wherever.end(); ++it)
{
	DoSomething(*it);
}

I thought it would be cool to be able to do this instead:

query << "select whatever";
query.for_each(DoSomething());

A trivial example, say I want to display all records and show how many
records there were:

query << "select whatever";
int n = query.for_each(DisplayAndCount());
std::cout n << " rows" << std::endl;

Or

query << "select whatever";
DisplayAndCount x = query.for_each(DisplayAndCount());
x.DisplayCount();

Or even

query << "select whatever";
query.for_each(DisplayAndCount()).DisplayCount();

Where DisplayAndCount is defined as:

struct DisplayAndCount
{
	DisplayAndCount()
	: m_rows(0)
	{
	}
	
	void operator()(const mysqlpp::Row& row)
	{
		std::cout << row["field"] << std::endl;
		++m_rows;
	}
	
	operator unsigned int() const
	{
		return m_rows;
	}	

	void DisplayCount() const
	{
		std::cout << m_rows << " row(s) found" << std::endl;
	}	
	
private:
	unsigned int m_rows;		
};

This functionality could be added to the library (without breaking
ABI???) by adding the following into Query (plus appropriate versions
mirroring the storein functions):

template<typename _Function>
_Function for_each(_Function __f, const char* s)
{	
	mysqlpp::ResUse result = use(s);
	while (1) {
		MYSQL_ROW d = mysql_fetch_row(result.raw_result());
		if (!d)
				break;
		mysqlpp::Row row(d, &result,
mysql_fetch_lengths(result.raw_result()),true);
		if (!row)
				break;
		__f(row);
	}
	
	return __f;
}

You could also then refactor storein to delegate to for_each:

return Query.for_each(StoreIn(container),sql);

template <typename _Container>
struct StoreInH
{
	StoreInH(_Container& con)
	: m_con(con)
	{
		m_con.clear();
	}
	
	void operator()(mysqlpp::Row& row)
	{
		m_con.push_back(typename _Container::value_type(row));	
	}
	
private:
	_Container& m_con;
};

template <typename _Container>
StoreInH<_Container> StoreIn(_Container& con)
{
	return StoreInH<_Container>(con);
}

I've found this useful, maybe others would too.

Joel


-- 
MySQL++ Mailing List
For list archives: http://lists.mysql.com/plusplus
To unsubscribe:    http://lists.mysql.com/plusplus?unsub=mysql-plusplus@progressive-comp.com

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic