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