List:MySQL++« Previous MessageNext Message »
From:Joel Fielder Date:April 13 2007 4:32pm
Subject:Passing functors into query
View as plain text  
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

Thread
Passing functors into queryJoel Fielder13 Apr
  • Re: Passing functors into queryWarren Young19 Jun
    • RE: Passing functors into queryJoel Fielder19 Jun
      • Re: Passing functors into queryWarren Young19 Jun
        • RE: Passing functors into queryJoel Fielder19 Jun
          • Re: Passing functors into queryWarren Young20 Jun
            • RE: Passing functors into queryJoel Fielder20 Jun
              • Re: Passing functors into queryWarren Young20 Jun
                • RE: Passing functors into queryJoel Fielder21 Jun