1 /*
2  * This source file is part of libRocket, the HTML/CSS Interface Middleware
3  *
4  * For the latest information, see http://www.librocket.com
5  *
6  * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24  * THE SOFTWARE.
25  *
26  */
27 
28 #include "../../Include/Rocket/Controls/DataQuery.h"
29 #include "../../Include/Rocket/Controls/DataSource.h"
30 #include <algorithm>
31 
32 namespace Rocket {
33 namespace Controls {
34 
35 class DataQuerySort
36 {
37 	public:
DataQuerySort(const Rocket::Core::StringList & _order_parameters)38 		DataQuerySort(const Rocket::Core::StringList& _order_parameters)
39 		{
40 			order_parameters = _order_parameters;
41 		}
42 
operator ()(const Rocket::Core::StringList & ROCKET_UNUSED_PARAMETER (left),const Rocket::Core::StringList & ROCKET_UNUSED_PARAMETER (right))43 		bool operator()(const Rocket::Core::StringList& ROCKET_UNUSED_PARAMETER(left), const Rocket::Core::StringList& ROCKET_UNUSED_PARAMETER(right))
44 		{
45 			ROCKET_UNUSED(left);
46 			ROCKET_UNUSED(right);
47 
48 			return false;
49 		}
50 
51 	private:
52 		Rocket::Core::StringList order_parameters;
53 };
54 
55 
56 
DataQuery(DataSource * data_source,const Rocket::Core::String & table,const Rocket::Core::String & _fields,int offset,int limit,const Rocket::Core::String & order)57 DataQuery::DataQuery(DataSource* data_source, const Rocket::Core::String& table, const Rocket::Core::String& _fields, int offset, int limit, const Rocket::Core::String& order)
58 {
59 	ExecuteQuery(data_source, table, _fields, offset, limit, order);
60 }
61 
62 
63 
DataQuery()64 DataQuery::DataQuery()
65 {
66 	data_source = NULL;
67 	table = "";
68 	offset = -1;
69 	limit = -1;
70 }
71 
72 
73 
~DataQuery()74 DataQuery::~DataQuery()
75 {
76 }
77 
78 
79 
ExecuteQuery(DataSource * _data_source,const Rocket::Core::String & _table,const Rocket::Core::String & _fields,int _offset,int _limit,const Rocket::Core::String & order)80 void DataQuery::ExecuteQuery(DataSource* _data_source, const Rocket::Core::String& _table, const Rocket::Core::String& _fields, int _offset, int _limit, const Rocket::Core::String& order)
81 {
82 	data_source = _data_source;
83 	table = _table;
84 	offset = _offset;
85 	limit = _limit;
86 
87 	// Set up the field list and field index cache.
88 	Rocket::Core::StringUtilities::ExpandString(fields, _fields);
89 	for (size_t i = 0; i < fields.size(); i++)
90 	{
91 		field_indices[fields[i]] = i;
92 	}
93 
94 	// Initialise the row pointer.
95 	current_row = -1;
96 
97 	// If limit is -1, then we fetch to the end of the data source.
98 	if (limit == -1)
99 	{
100 		limit = data_source->GetNumRows(table) - offset;
101 	}
102 
103 	if (!order.Empty())
104 	{
105 		// Fetch the rows from offset to limit.
106 		rows.resize(limit);
107 		for (int i = 0; i < limit; i++)
108 		{
109 			data_source->GetRow(rows[i], table, offset + i, fields);
110 		}
111 
112 		// Now sort the rows, based on the ordering requirements.
113 		Rocket::Core::StringList order_parameters;
114 		Rocket::Core::StringUtilities::ExpandString(order_parameters, order);
115 		sort(rows.begin(), rows.end(), DataQuerySort(order_parameters));
116 	}
117 }
118 
119 
120 
NextRow()121 bool DataQuery::NextRow()
122 {
123 	current_row++;
124 
125 	if (current_row >= limit)
126 	{
127 		return false;
128 	}
129 
130 	LoadRow();
131 	return true;
132 }
133 
134 
135 
IsFieldSet(const Rocket::Core::String & field) const136 bool DataQuery::IsFieldSet(const Rocket::Core::String& field) const
137 {
138 	FieldIndices::const_iterator itr = field_indices.find(field);
139 	if (itr == field_indices.end() || (*itr).second >= (int)rows[current_row].size())
140 	{
141 		return false;
142 	}
143 
144 	return true;
145 }
146 
147 
148 
LoadRow()149 void DataQuery::LoadRow()
150 {
151 	ROCKET_ASSERT(current_row <= (int)rows.size());
152 	if (current_row >= (int)rows.size())
153 	{
154 		rows.push_back(Rocket::Core::StringList());
155 		data_source->GetRow(rows[current_row], table, offset + current_row, fields);
156 	}
157 }
158 
159 }
160 }
161