diff options
| -rw-r--r-- | project2/common/aggregate.cpp | 24 | ||||
| -rw-r--r-- | project2/common/aggregate.h | 36 | ||||
| -rw-r--r-- | project2/common/aggregates/distinct.cpp | 28 | ||||
| -rw-r--r-- | project2/common/aggregates/max.cpp | 27 | ||||
| -rw-r--r-- | project2/common/aggregates/min.cpp | 32 | ||||
| -rw-r--r-- | project2/common/rowView.cpp | 20 | ||||
| -rw-r--r-- | project2/common/rowView.h | 5 | ||||
| -rw-r--r-- | project2/common/variables.cpp | 2 | 
8 files changed, 173 insertions, 1 deletions
| diff --git a/project2/common/aggregate.cpp b/project2/common/aggregate.cpp new file mode 100644 index 0000000..1bb453b --- /dev/null +++ b/project2/common/aggregate.cpp @@ -0,0 +1,24 @@ +#include "aggregate.h" + +Aggregate::Aggregate(ScriptNodePtr s) : +	SourceObject(s), +	value(s, "value") +{ +} + +ValueAggregate::ValueAggregate(ScriptNodePtr s) : +	Aggregate(s) +{ +} + +SetAggregate::SetAggregate(ScriptNodePtr s) : +	Aggregate(s) +{ +} + +void +Aggregate::pushValue() const +{ +	pushValue(value()); +} + diff --git a/project2/common/aggregate.h b/project2/common/aggregate.h new file mode 100644 index 0000000..18ad6a5 --- /dev/null +++ b/project2/common/aggregate.h @@ -0,0 +1,36 @@ +#ifndef AGGREGATE_H +#define AGGREGATE_H + +#include "scripts.h" +#include <boost/function.hpp> + +class Aggregate : public SourceObject { +	public: +		Aggregate(ScriptNodePtr); + +		virtual void reset() const = 0; +		void pushValue() const; +	protected: +		virtual void pushValue(const VariableType &) const = 0; +	private: +		Variable value; +}; + +class ValueAggregate : public Aggregate { +	public: +		ValueAggregate(ScriptNodePtr); + +		virtual VariableType resultValue() const = 0; +}; +typedef boost::intrusive_ptr<const ValueAggregate> ValueAggregateCPtr; + +class SetAggregate : public Aggregate { +	public: +		typedef boost::function1<void, VariableType> UseAgg; +		SetAggregate(ScriptNodePtr); + +		virtual void onResultValues(const UseAgg &) const = 0; +}; +typedef boost::intrusive_ptr<const SetAggregate> SetAggregateCPtr; + +#endif diff --git a/project2/common/aggregates/distinct.cpp b/project2/common/aggregates/distinct.cpp new file mode 100644 index 0000000..85e69c2 --- /dev/null +++ b/project2/common/aggregates/distinct.cpp @@ -0,0 +1,28 @@ +#include "../aggregate.h" +#include <boost/foreach.hpp> + +class Distinct : public SetAggregate { +	public: +		Distinct(ScriptNodePtr s) : +			SetAggregate(s) +		{ +		} +		void reset() const +		{ +			result.clear(); +		} +		void pushValue(const VariableType & v) const +		{ +			result.insert(v); +		} +		void onResultValues(const SetAggregate::UseAgg & u) const +		{ +			BOOST_FOREACH(const VariableType & v, result) { +				u(v); +			} +		} +	private: +		mutable std::set<VariableType> result; +}; + +DECLARE_LOADER("distinct", Distinct); diff --git a/project2/common/aggregates/max.cpp b/project2/common/aggregates/max.cpp new file mode 100644 index 0000000..a6e528a --- /dev/null +++ b/project2/common/aggregates/max.cpp @@ -0,0 +1,27 @@ +#include "../aggregate.h" + +class Max : public ValueAggregate { +	public: +		Max(ScriptNodePtr s) : ValueAggregate(s) { } + +		void reset() const +		{ +			result = VariableType(); +		} +		void pushValue(const VariableType & v) const +		{ +			if (result < v) { +				result = v; +			} +		} +		VariableType resultValue() const +		{ +			return result; +		} +	private: +		mutable VariableType result; +}; + +DECLARE_LOADER("max", Max); + + diff --git a/project2/common/aggregates/min.cpp b/project2/common/aggregates/min.cpp new file mode 100644 index 0000000..14c63ae --- /dev/null +++ b/project2/common/aggregates/min.cpp @@ -0,0 +1,32 @@ +#include "../aggregate.h" + +class Min : public ValueAggregate { +	public: +		Min(ScriptNodePtr s) : +			ValueAggregate(s), +			first(true) +		{ +		} +		void reset() const +		{ +			result = VariableType(); +			first = true; +		} +		void pushValue(const VariableType & v) const +		{ +			if (first || v < result) { +				result = v; +			} +			first = false; +		} +		VariableType resultValue() const +		{ +			return result; +		} +	private: +		mutable VariableType result; +		mutable bool first; +}; + +DECLARE_LOADER("min", Min); + diff --git a/project2/common/rowView.cpp b/project2/common/rowView.cpp index 0f25a30..749651e 100644 --- a/project2/common/rowView.cpp +++ b/project2/common/rowView.cpp @@ -20,6 +20,8 @@ RowView::RowView(ScriptNodePtr p) :  		viewColumns.insert(Columns::value_type(node->get_name(), Variable(node)));  	}  	p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&subViews)); +	p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&valueAggregates)); +	p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&setAggregates));  }  RowView::~RowView() @@ -46,6 +48,12 @@ RowView::rowReady(const RowState * rs) const  	}  	executeChildren();  	presenter->finishRow(); +	BOOST_FOREACH(SetAggregateCPtr s, setAggregates) { +		s->pushValue(); +	} +	BOOST_FOREACH(ValueAggregateCPtr a, valueAggregates) { +		a->pushValue(); +	}  }  void @@ -53,8 +61,20 @@ RowView::execute(const MultiRowSetPresenter * p) const  {  	presenter = p;  	presenter->addNewRowSet(rootName()); +  	ScopeObject pres(boost::bind(&MultiRowSetPresenter::finishRowSet, p));  	RowProcessor::execute(); + +	BOOST_FOREACH(SetAggregateCPtr s, setAggregates) { +		presenter->addNewRowSet(s->name); +		ScopeObject pres(boost::bind(&MultiRowSetPresenter::finishRowSet, p)); +		s->onResultValues(boost::bind(&MultiRowSetPresenter::addNamedValue, p, "value", _1)); +		s->reset(); +	} +	BOOST_FOREACH(ValueAggregateCPtr a, valueAggregates) { +		presenter->addNamedValue(a->name, a->resultValue()); +		a->reset(); +	}  }  void diff --git a/project2/common/rowView.h b/project2/common/rowView.h index 4b90884..40ec8a9 100644 --- a/project2/common/rowView.h +++ b/project2/common/rowView.h @@ -4,6 +4,7 @@  #include <boost/intrusive_ptr.hpp>  #include "rowProcessor.h"  #include "view.h" +#include "aggregate.h"  /// Project2 component to create output based on a records in a row set  class RowView : public View, public RowProcessor { @@ -25,6 +26,10 @@ class RowView : public View, public RowProcessor {  		void executeChildren() const;  		typedef ANONSTORAGEOF(View) SubViews;  		SubViews subViews; +		typedef ANONSTORAGEOF(ValueAggregate) ValueAggregates; +		ValueAggregates valueAggregates; +		typedef ANONSTORAGEOF(SetAggregate) SetAggregates; +		SetAggregates setAggregates;  		mutable const MultiRowSetPresenter * presenter;  }; diff --git a/project2/common/variables.cpp b/project2/common/variables.cpp index 8b4ce38..de0690b 100644 --- a/project2/common/variables.cpp +++ b/project2/common/variables.cpp @@ -165,7 +165,7 @@ class compi : public boost::static_visitor<bool> {  		compi(const S & s) : _s(s) { }  		bool operator()(const S & t) const  		{ -			return _s < t; +			return t < _s;  		}  		template <class T>  		bool operator()(const T &) const | 
