RowFormatter - progressive and bulk formatting modes

This commit is contained in:
Aleksandar Fabijanic
2009-11-01 15:58:32 +00:00
parent 65ad81c363
commit 05131182b8
9 changed files with 182 additions and 37 deletions

View File

@@ -358,6 +358,9 @@ public:
/// Copies the column names to the target output stream. /// Copies the column names to the target output stream.
/// Copied string is formatted by the current RowFormatter. /// Copied string is formatted by the current RowFormatter.
void formatNames() const;
/// Formats names using the current RowFormatter.
std::ostream& copyValues(std::ostream& os, std::ostream& copyValues(std::ostream& os,
std::size_t offset = 0, std::size_t offset = 0,
std::size_t length = RowIterator::POSITION_END) const; std::size_t length = RowIterator::POSITION_END) const;
@@ -369,6 +372,14 @@ public:
/// cause RangeException to be thrown. /// cause RangeException to be thrown.
/// Copied string is formatted by the current RowFormatter. /// Copied string is formatted by the current RowFormatter.
void formatValues(std::size_t offset, std::size_t length) const;
/// Formats values using the current RowFormatter.
/// The data set to be formatted is starting at the specified offset
/// from the recordset beginning. The number of rows to be copied
/// is specified by length argument.
/// An invalid combination of offset/length arguments shall
/// cause RangeException to be thrown.
std::ostream& copy(std::ostream& os, std::ostream& copy(std::ostream& os,
std::size_t offset = 0, std::size_t offset = 0,
std::size_t length = RowIterator::POSITION_END) const; std::size_t length = RowIterator::POSITION_END) const;
@@ -622,6 +633,12 @@ inline const RowFilter* RecordSet::getFilter() const
} }
inline void RecordSet::formatNames() const
{
(*_pBegin)->formatNames();
}
/* TODO /* TODO
namespace Keywords { namespace Keywords {

View File

@@ -195,10 +195,16 @@ public:
/// Resets the sorting criteria to field 0 only. /// Resets the sorting criteria to field 0 only.
const std::string& namesToString() const; const std::string& namesToString() const;
/// Converts the row names to string. /// Converts the column names to string.
void formatNames() const;
/// Fomats the column names.
const std::string& valuesToString() const; const std::string& valuesToString() const;
/// Converts the row values to string. /// Converts the row values to string and returns the formated string.
void formatValues() const;
/// Fomats the row values.
bool operator == (const Row& other) const; bool operator == (const Row& other) const;
/// Equality operator. /// Equality operator.
@@ -243,12 +249,12 @@ private:
bool isEqualSize(const Row& other) const; bool isEqualSize(const Row& other) const;
bool isEqualType(const Row& other) const; bool isEqualType(const Row& other) const;
NameVecPtr _pNames; NameVecPtr _pNames;
ValueVec _values; ValueVec _values;
SortMapPtr _pSortMap; SortMapPtr _pSortMap;
RowFormatterPtr _pFormatter; mutable RowFormatterPtr _pFormatter;
mutable std::string _nameStr; mutable std::string _nameStr;
mutable std::string _valueStr; mutable std::string _valueStr;
}; };
@@ -319,6 +325,12 @@ inline const std::string& Row::valuesToString() const
} }
inline void Row::formatValues() const
{
return _pFormatter->formatValues(values());
}
} } // namespace Poco::Data } } // namespace Poco::Data

View File

@@ -71,6 +71,23 @@ class Data_API RowFormatter
/// Statement always has the ownership of the row formatter and shares /// Statement always has the ownership of the row formatter and shares
/// it with rows through RecordSet. /// it with rows through RecordSet.
/// ///
/// To accomodate for various formatting needs, a formatter can operate in two modes:
///
/// - progressive: formatted individual row strings are gemerated and returned from each
/// call to formatValues;
/// std::string& formatNames(const NameVecPtr, std::string&) and
/// std::string& formatValues(const ValueVec&, std::string&) member calls should be
/// used in this case; this is the default mode
///
/// - bulk: formatted resulting string is accumulated internally and obtained at
/// the end of iteration via toString() member function;
/// void formatNames(const NameVecPtr) and
/// void formatValues(const ValueVec&) member calls should be used in this case
///
/// When formatter is used in conjunction with Row/RecordSet, the formatting members corresponding
/// to the formater mode are expected to be implemented. If a call is propagated to this parent
/// class, the functions do nothing or silently return empty string respectively.
///
{ {
public: public:
typedef std::vector<std::string> NameVec; typedef std::vector<std::string> NameVec;
@@ -79,17 +96,39 @@ public:
static const int INVALID_ROW_COUNT = -1; static const int INVALID_ROW_COUNT = -1;
RowFormatter(const std::string& prefix = "", const std::string& postfix = ""); enum Mode
{
FORMAT_PROGRESSIVE,
FORMAT_BULK
};
RowFormatter(const std::string& prefix = "",
const std::string& postfix = "",
Mode mode = FORMAT_PROGRESSIVE);
/// Creates the RowFormatter and sets the prefix and postfix to specified values. /// Creates the RowFormatter and sets the prefix and postfix to specified values.
virtual ~RowFormatter(); virtual ~RowFormatter();
/// Destroys the RowFormatter. /// Destroys the RowFormatter.
virtual std::string& formatNames(const NameVecPtr pNames, std::string& formattedNames) const = 0; virtual std::string& formatNames(const NameVecPtr pNames, std::string& formattedNames);
/// Formats the row field names. /// Should be implemented to format the row fields names and return the formatted string.
/// The default implementation clears the names string and returns it.
virtual std::string& formatValues(const ValueVec& vals, std::string& formattedValues) const = 0; virtual void formatNames(const NameVecPtr pNames);
/// Formats the row values. /// Should be implemented to format the row fields names.
/// The default implementation does nothing.
virtual std::string& formatValues(const ValueVec& vals, std::string& formattedValues);
/// Should be implemented to format the row fields values and return the formatted string.
/// The default implementation clears the values string and returns it.
virtual void formatValues(const ValueVec& vals);
/// Should be implemented to format the row fields values.
/// The default implementation does nothing.
virtual const std::string& toString();
/// Throws NotImplementedException. Formatters operating in bulk mode should
/// implement this member function to return valid pointer to the formatted result.
virtual int rowCount() const; virtual int rowCount() const;
/// Returns INVALID_ROW_COUNT. Must be implemented by inheriting classes /// Returns INVALID_ROW_COUNT. Must be implemented by inheriting classes
@@ -113,18 +152,25 @@ public:
/// Resets the formatter by setting prefix and postfix /// Resets the formatter by setting prefix and postfix
/// to empty strings and row count to INVALID_ROW_COUNT. /// to empty strings and row count to INVALID_ROW_COUNT.
Mode getMode() const;
/// Returns the formater mode.
void setMode(Mode mode);
/// Sets the fromatter mode.
protected: protected:
void setPrefix(const std::string& prefix) const; void setPrefix(const std::string& prefix);
/// Sets the prefix for the formatter. /// Sets the prefix for the formatter.
void setPostfix(const std::string& postfix) const; void setPostfix(const std::string& postfix);
/// Sets the postfix for the formatter /// Sets the postfix for the formatter
private: private:
mutable std::string _prefix; mutable std::string _prefix;
mutable std::string _postfix; mutable std::string _postfix;
Mode _mode;
int _totalRowCount; int _totalRowCount;
}; };
@@ -150,13 +196,13 @@ inline void RowFormatter::setTotalRowCount(int count)
} }
inline void RowFormatter::setPrefix(const std::string& prefix) const inline void RowFormatter::setPrefix(const std::string& prefix)
{ {
_prefix = prefix; _prefix = prefix;
} }
inline void RowFormatter::setPostfix(const std::string& postfix) const inline void RowFormatter::setPostfix(const std::string& postfix)
{ {
_postfix = postfix; _postfix = postfix;
} }
@@ -174,6 +220,18 @@ inline const std::string& RowFormatter::postfix() const
} }
inline RowFormatter::Mode RowFormatter::getMode() const
{
return _mode;
}
inline void RowFormatter::setMode(Mode mode)
{
_mode = mode;
}
namespace Keywords { namespace Keywords {

View File

@@ -73,10 +73,10 @@ public:
void swap(SimpleRowFormatter& other); void swap(SimpleRowFormatter& other);
/// Swaps the row formatter with another one. /// Swaps the row formatter with another one.
std::string& formatNames(const NameVecPtr pNames, std::string& formattedNames) const; std::string& formatNames(const NameVecPtr pNames, std::string& formattedNames);
/// Formats the row field names. /// Formats the row field names.
std::string& formatValues(const ValueVec& vals, std::string& formattedValues) const; std::string& formatValues(const ValueVec& vals, std::string& formattedValues);
/// Formats the row values. /// Formats the row values.
int rowCount() const; int rowCount() const;
@@ -90,7 +90,7 @@ public:
private: private:
std::streamsize _colWidth; std::streamsize _colWidth;
mutable int _rowCount; int _rowCount;
}; };

View File

@@ -63,7 +63,7 @@ public:
setPostfix(os.str()); setPostfix(os.str());
} }
std::string& formatNames(const NameVecPtr pNames, std::string& formattedNames) const std::string& formatNames(const NameVecPtr pNames, std::string& formattedNames)
{ {
std::ostringstream str; std::ostringstream str;
@@ -76,7 +76,7 @@ public:
return formattedNames = str.str(); return formattedNames = str.str();
} }
std::string& formatValues(const ValueVec& vals, std::string& formattedValues) const std::string& formatValues(const ValueVec& vals, std::string& formattedValues)
{ {
std::ostringstream str; std::ostringstream str;

View File

@@ -329,26 +329,40 @@ std::ostream& RecordSet::copyNames(std::ostream& os) const
std::ostream& RecordSet::copyValues(std::ostream& os, std::size_t offset, std::size_t length) const std::ostream& RecordSet::copyValues(std::ostream& os, std::size_t offset, std::size_t length) const
{ {
RowIterator itBegin = *_pBegin + offset; RowIterator it = *_pBegin + offset;
RowIterator itEnd = (RowIterator::POSITION_END != length) ? itBegin + length : *_pEnd; RowIterator end = (RowIterator::POSITION_END != length) ? it + length : *_pEnd;
std::string val; std::copy(it, end, std::ostream_iterator<Row>(os));
for (; itBegin != itEnd; ++itBegin)
{
val = itBegin->valuesToString();
if (!val.empty()) os << val;
}
return os; return os;
} }
void RecordSet::formatValues(std::size_t offset, std::size_t length) const
{
RowIterator it = *_pBegin + offset;
RowIterator end = (RowIterator::POSITION_END != length) ? it + length : *_pEnd;
std::string val;
for (; it != end; ++it) it->formatValues();
}
std::ostream& RecordSet::copy(std::ostream& os, std::size_t offset, std::size_t length) const std::ostream& RecordSet::copy(std::ostream& os, std::size_t offset, std::size_t length) const
{ {
RowFormatter& rf = const_cast<RowFormatter&>((*_pBegin)->getFormatter()); RowFormatter& rf = const_cast<RowFormatter&>((*_pBegin)->getFormatter());
rf.setTotalRowCount(getTotalRowCount()); rf.setTotalRowCount(getTotalRowCount());
os << rf.prefix(); if (RowFormatter::FORMAT_PROGRESSIVE == rf.getMode())
copyNames(os); {
copyValues(os, offset, length); os << rf.prefix();
os << rf.postfix(); copyNames(os);
copyValues(os, offset, length);
os << rf.postfix();
}
else
{
formatNames();
formatValues(offset, length);
os << rf.toString();
}
return os; return os;
} }

View File

@@ -398,4 +398,13 @@ const std::string& Row::namesToString() const
} }
void Row::formatNames() const
{
if (!_pNames)
throw NullPointerException();
return _pFormatter->formatNames(names());
}
} } // namespace Poco::Data } } // namespace Poco::Data

View File

@@ -43,9 +43,12 @@ namespace Poco {
namespace Data { namespace Data {
RowFormatter::RowFormatter(const std::string& prefix, const std::string& postfix): RowFormatter::RowFormatter(const std::string& prefix,
const std::string& postfix,
Mode mode):
_prefix(prefix), _prefix(prefix),
_postfix(postfix), _postfix(postfix),
_mode(mode),
_totalRowCount(0) _totalRowCount(0)
{ {
} }
@@ -56,6 +59,38 @@ RowFormatter::~RowFormatter()
} }
std::string& RowFormatter::formatNames(const NameVecPtr pNames, std::string& formattedNames)
{
formattedNames.clear();
return formattedNames;
}
void RowFormatter::formatNames(const NameVecPtr pNames)
{
return;
}
std::string& RowFormatter::formatValues(const ValueVec& vals, std::string& formattedValues)
{
formattedValues.clear();
return formattedValues;
}
void RowFormatter::formatValues(const ValueVec& vals)
{
return;
}
const std::string& RowFormatter::toString()
{
throw NotImplementedException("RowFormatter::toString()");
}
void RowFormatter::reset() void RowFormatter::reset()
{ {
_prefix = ""; _prefix = "";

View File

@@ -79,7 +79,7 @@ void SimpleRowFormatter::swap(SimpleRowFormatter& other)
} }
std::string& SimpleRowFormatter::formatNames(const NameVecPtr pNames, std::string& formattedNames) const std::string& SimpleRowFormatter::formatNames(const NameVecPtr pNames, std::string& formattedNames)
{ {
_rowCount = 0; _rowCount = 0;
@@ -98,7 +98,7 @@ std::string& SimpleRowFormatter::formatNames(const NameVecPtr pNames, std::strin
} }
std::string& SimpleRowFormatter::formatValues(const ValueVec& vals, std::string& formattedValues) const std::string& SimpleRowFormatter::formatValues(const ValueVec& vals, std::string& formattedValues)
{ {
std::ostringstream str; std::ostringstream str;