DatabaseResult.cpp
Go to the documentation of this file.
1 /*
2  //
3 // BEGIN SONGBIRD GPL
4 //
5 // This file is part of the Songbird web player.
6 //
7 // Copyright(c) 2005-2008 POTI, Inc.
8 // http://songbirdnest.com
9 //
10 // This file may be licensed under the terms of of the
11 // GNU General Public License Version 2 (the "GPL").
12 //
13 // Software distributed under the License is distributed
14 // on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
15 // express or implied. See the GPL for the specific language
16 // governing rights and limitations.
17 //
18 // You should have received a copy of the GPL along with this
19 // program. If not, go to http://www.gnu.org/licenses/gpl.html
20 // or write to the Free Software Foundation, Inc.,
21 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 //
23 // END SONGBIRD GPL
24 //
25  */
26 
32 #include "DatabaseResult.h"
33 #include <prmem.h>
34 #include <nsMemory.h>
35 
36 #include <nsStringGlue.h>
37 
38 #include <prlog.h>
39 
40 /*
41  * To log this module, set the following environment variable:
42  * NSPR_LOG_MODULES=sbDatabaseResult:5
43  */
44 #ifdef PR_LOGGING
45 static PRLogModuleInfo* gDatabaseResultLog = nsnull;
46 #define LOG(args) PR_LOG(gDatabaseResultLog, PR_LOG_DEBUG, args)
47 #else
48 #define LOG(args) /* nothing */
49 #endif
50 
51 static inline
52 void IfLock(PRLock *aLock)
53 {
54  if(NS_UNLIKELY(aLock)) {
55  PR_Lock(aLock);
56  }
57 }
58 
59 static inline
60 void IfUnlock(PRLock *aLock)
61 {
62  if(NS_UNLIKELY(aLock)) {
63  PR_Unlock(aLock);
64  }
65 }
66 
67 // CLASSES ====================================================================
68 //=============================================================================
69 // CDatabaseQuery Class
70 //=============================================================================
71 //-----------------------------------------------------------------------------
72 /* Implementation file */
74 
75 //-----------------------------------------------------------------------------
76 CDatabaseResult::CDatabaseResult(PRBool aRequiresLocking)
77 : m_RequiresLocking(aRequiresLocking)
78 , m_pLock(nsnull)
79 {
80 #ifdef PR_LOGGING
81  if(!gDatabaseResultLog)
82  gDatabaseResultLog = PR_NewLogModule("sbDatabaseResult");
83 #endif
84 
85  if(NS_UNLIKELY(m_RequiresLocking))
86  {
87  m_pLock = PR_NewLock();
88  NS_ASSERTION(m_pLock, "CDatabaseResult.m_pColumnNamesLock failed");
89  }
90 } //ctor
91 
92 //-----------------------------------------------------------------------------
94 {
96  PR_DestroyLock(m_pLock);
97 } //dtor
98 
99 //-----------------------------------------------------------------------------
100 /* PRInt32 GetColumnCount (); */
101 NS_IMETHODIMP CDatabaseResult::GetColumnCount(PRUint32 *_retval)
102 {
103  NS_ENSURE_ARG_POINTER(_retval);
104  if(NS_UNLIKELY(m_RequiresLocking)) {
105  IfLock(m_pLock);
106  *_retval = m_ColumnNames.size();
107  IfUnlock(m_pLock);
108  }
109  else {
110  *_retval = m_ColumnNames.size();
111  }
112  return NS_OK;
113 } //GetColumnCount
114 
115 //-----------------------------------------------------------------------------
116 /* wstring GetColumnName (in PRInt32 dbColumn); */
117 NS_IMETHODIMP CDatabaseResult::GetColumnName(PRUint32 dbColumn, nsAString &_retval)
118 {
119  if(NS_UNLIKELY(m_RequiresLocking)) {
120  IfLock(m_pLock);
121  if(dbColumn < m_ColumnNames.size()) {
122  _retval = m_ColumnNames[dbColumn];
123  }
124  IfUnlock(m_pLock);
125  }
126  else if(dbColumn < m_ColumnNames.size()) {
127  _retval = m_ColumnNames[dbColumn];
128  }
129 
130  return NS_OK;
131 } //GetColumnName
132 
133 //-----------------------------------------------------------------------------
134 /* wstring GetColumnName (in PRInt32 dbColumn); */
135 NS_IMETHODIMP CDatabaseResult::GetColumnIndex(const nsAString &aColumnName, PRUint32 *_retval)
136 {
137  NS_ENSURE_ARG_POINTER(_retval);
138  *_retval = GetColumnIndexFromName(aColumnName);
139  return NS_OK;
140 } //GetColumnIndex
141 
142 
143 //-----------------------------------------------------------------------------
144 /* PRInt32 GetRowCount (); */
145 NS_IMETHODIMP CDatabaseResult::GetRowCount(PRUint32 *_retval)
146 {
147  NS_ENSURE_ARG_POINTER(_retval);
148  if(NS_UNLIKELY(m_RequiresLocking)) {
149  IfLock(m_pLock);
150  *_retval = m_RowCells.size();
151  IfUnlock(m_pLock);
152  }
153  else {
154  *_retval = m_RowCells.size();
155  }
156 
157  return NS_OK;
158 } //GetRowCount
159 
160 //-----------------------------------------------------------------------------
161 /* wstring GetRowCell (in PRInt32 dbRow, in PRInt32 dbCell); */
162 NS_IMETHODIMP CDatabaseResult::GetRowCell(PRUint32 dbRow, PRUint32 dbCell, nsAString &_retval)
163 {
164  if(NS_UNLIKELY(m_RequiresLocking)) {
165  IfLock(m_pLock);
166  if(dbRow < m_RowCells.size() && dbCell < m_RowCells[dbRow].size()) {
167  _retval = m_RowCells[dbRow][dbCell];
168  }
169  IfUnlock(m_pLock);
170  }
171  else if(dbRow < m_RowCells.size() && dbCell < m_RowCells[dbRow].size()) {
172  _retval = m_RowCells[dbRow][dbCell];
173  }
174 
175  return NS_OK;
176 } //GetRowCell
177 
178 //-----------------------------------------------------------------------------
179 /* wstring GetRowCellByColumn (in PRInt32 dbRow, in wstring dbColumn); */
180 NS_IMETHODIMP CDatabaseResult::GetRowCellByColumn(PRUint32 dbRow, const nsAString &dbColumn, nsAString &_retval)
181 {
182  PRUint32 dbCell = GetColumnIndexFromName(dbColumn);
183  return GetRowCell(dbRow, dbCell, _retval);
184 } //GetRowCellByColumn
185 
186 //-----------------------------------------------------------------------------
187 /* wstring GetColumnNamePtr (in PRInt32 dbColumn); */
188 NS_IMETHODIMP CDatabaseResult::GetColumnNamePtr(PRUint32 dbColumn, PRUnichar **_retval)
189 {
190  if(NS_UNLIKELY(m_RequiresLocking)) {
191  IfLock(m_pLock);
192  if(dbColumn < m_ColumnNames.size()) {
193  *_retval = const_cast<PRUnichar *>(m_ColumnNames[dbColumn].BeginReading());
194  }
195  else {
196  *_retval = nsnull;
197  }
198  IfUnlock(m_pLock);
199  }
200  else if(dbColumn < m_ColumnNames.size()) {
201  *_retval = const_cast<PRUnichar *>(m_ColumnNames[dbColumn].BeginReading());
202  }
203  else {
204  *_retval = nsnull;
205  }
206 
207  return NS_OK;
208 } //GetColumnName
209 
210 //-----------------------------------------------------------------------------
211 /* wstring GetRowCellPtr (in PRInt32 dbRow, in PRInt32 dbCell); */
212 NS_IMETHODIMP CDatabaseResult::GetRowCellPtr(PRUint32 dbRow, PRUint32 dbCell, PRUnichar **_retval)
213 {
214  if(NS_UNLIKELY(m_RequiresLocking)) {
215  IfLock(m_pLock);
216  if(dbRow < m_RowCells.size() && dbCell < m_RowCells[dbRow].size()) {
217  *_retval = const_cast<PRUnichar *>(m_RowCells[dbRow][dbCell].BeginReading());
218  }
219  else {
220  *_retval = nsnull;
221  }
222  IfUnlock(m_pLock);
223  }
224  else if(dbRow < m_RowCells.size() && dbCell < m_RowCells[dbRow].size()) {
225  *_retval = const_cast<PRUnichar *>(m_RowCells[dbRow][dbCell].BeginReading());
226  }
227  else {
228  *_retval = nsnull;
229  }
230 
231  return NS_OK;
232 } //GetRowCell
233 
234 //-----------------------------------------------------------------------------
235 /* noscript wstring GetRowCellByColumnPtr (in PRInt32 dbRow, in wstring dbColumn); */
236 NS_IMETHODIMP CDatabaseResult::GetRowCellByColumnPtr(PRUint32 dbRow, const nsAString &dbColumn, PRUnichar **_retval)
237 {
238  PRUint32 dbCell = GetColumnIndexFromName(dbColumn);
239  return GetRowCellPtr(dbRow, dbCell, _retval);
240 } //GetRowCellByColumnPtr
241 
242 //-----------------------------------------------------------------------------
243 NS_IMETHODIMP CDatabaseResult::ClearResultSet()
244 {
245  if(NS_UNLIKELY(m_RequiresLocking)) {
246  IfLock(m_pLock);
247 
248  m_ColumnNames.clear();
249  m_RowCells.clear();
250  m_ColumnResolveMap.clear();
251 
252  IfUnlock(m_pLock);
253  }
254  else {
255  m_ColumnNames.clear();
256  m_RowCells.clear();
257  m_ColumnResolveMap.clear();
258  }
259 
260  return NS_OK;
261 } //ClearResultSet
262 
263 //-----------------------------------------------------------------------------
264 nsresult CDatabaseResult::AddRow(const std::vector<nsString> &vCellValues)
265 {
266  if(NS_UNLIKELY(m_RequiresLocking)) {
267  IfLock(m_pLock);
268  m_RowCells.push_back(vCellValues);
269  IfUnlock(m_pLock);
270  }
271  else {
272  m_RowCells.push_back(vCellValues);
273  }
274 
275  return NS_OK;
276 } //AddRow
277 
278 //-----------------------------------------------------------------------------
279 nsresult CDatabaseResult::DeleteRow(PRUint32 dbRow)
280 {
281  if(NS_UNLIKELY(m_RequiresLocking)) {
282  IfLock(m_pLock);
283  if(dbRow < m_RowCells.size()) {
284  dbrowcells_t::iterator itRows = m_RowCells.begin();
285  itRows += dbRow;
286 
287  if(itRows != m_RowCells.end())
288  m_RowCells.erase(itRows);
289  }
290  IfUnlock(m_pLock);
291  }
292  else if(dbRow < m_RowCells.size()) {
293  dbrowcells_t::iterator itRows = m_RowCells.begin();
294  itRows += dbRow;
295 
296  if(itRows != m_RowCells.end())
297  m_RowCells.erase(itRows);
298  }
299 
300  return NS_OK;
301 } //DeleteRow
302 
303 //-----------------------------------------------------------------------------
304 nsresult CDatabaseResult::SetColumnNames(const std::vector<nsString> &vColumnNames)
305 {
306  if(NS_UNLIKELY(m_RequiresLocking)) {
307  IfLock(m_pLock);
308  m_ColumnNames = vColumnNames;
309  IfUnlock(m_pLock);
310  }
311  else {
312  m_ColumnNames = vColumnNames;
313  }
314 
315  return NS_OK;
316 } //SetColumnNames
317 
318 //-----------------------------------------------------------------------------
319 nsresult CDatabaseResult::SetColumnName(PRUint32 dbColumn, const nsString &strColumnName)
320 {
321  if(NS_UNLIKELY(m_RequiresLocking)) {
322  IfLock(m_pLock);
323  m_ColumnNames[dbColumn] = strColumnName;
324  IfUnlock(m_pLock);
325  }
326  else {
327  m_ColumnNames[dbColumn] = strColumnName;
328  }
329 
330  return NS_OK;
331 } //SetColumnName
332 
333 //-----------------------------------------------------------------------------
334 nsresult CDatabaseResult::SetRowCell(PRUint32 dbRow, PRUint32 dbCell, const nsString &strCellValue)
335 {
336  if(NS_UNLIKELY(m_RequiresLocking)) {
337  IfLock(m_pLock);
338  m_RowCells[dbRow][dbCell] = strCellValue;
339  IfUnlock(m_pLock);
340  }
341  else {
342  m_RowCells[dbRow][dbCell] = strCellValue;
343  }
344 
345  return NS_OK;
346 } //SetRowCell
347 
348 //-----------------------------------------------------------------------------
349 nsresult CDatabaseResult::SetRowCells(PRUint32 dbRow, const std::vector<nsString> &vCellValues)
350 {
351  if(NS_UNLIKELY(m_RequiresLocking)) {
352  IfLock(m_pLock);
353  m_RowCells[dbRow] = vCellValues;
354  IfUnlock(m_pLock);
355  }
356  else {
357  m_RowCells[dbRow] = vCellValues;
358  }
359 
360  return NS_OK;
361 } //SetRowCells
362 
363 //-----------------------------------------------------------------------------
364 PRUint32 CDatabaseResult::GetColumnIndexFromName(const nsAString &strColumnName)
365 {
367  PRUint32 retval = (PRUint32)-1;
368 
369  if(NS_UNLIKELY(m_RequiresLocking)) {
370  IfLock(m_pLock);
371 
372  dbcolumnresolvemap_t::const_iterator itColumnIndex =
373  m_ColumnResolveMap.find(nsString(strColumnName));
374 
375  if(itColumnIndex != m_ColumnResolveMap.end())
376  retval = itColumnIndex->second;
377 
378  IfUnlock(m_pLock);
379  }
380  else {
381  dbcolumnresolvemap_t::const_iterator itColumnIndex =
382  m_ColumnResolveMap.find(nsString(strColumnName));
383 
384  if(itColumnIndex != m_ColumnResolveMap.end())
385  retval = itColumnIndex->second;
386  }
387 
388  return retval;
389 } //GetColumnIndexFromName
390 
391 //-----------------------------------------------------------------------------
393 {
394  if(NS_UNLIKELY(m_RequiresLocking)) {
395  IfLock(m_pLock);
396 
397  if(m_ColumnNames.size() != m_ColumnResolveMap.size() ||
398  m_ColumnResolveMap.size() == 0) {
399  m_ColumnResolveMap.clear();
400 
401  PRUint32 nSize = m_ColumnNames.size();
402  for(PRUint32 i = 0; i < nSize; i++) {
403  m_ColumnResolveMap.insert(std::make_pair<nsString, PRUint32>(m_ColumnNames[i], i));
404  }
405  }
406 
407  IfUnlock(m_pLock);
408  }
409  else if(m_ColumnNames.size() != m_ColumnResolveMap.size() ||
410  m_ColumnResolveMap.size() == 0) {
411  m_ColumnResolveMap.clear();
412 
413  PRUint32 nSize = m_ColumnNames.size();
414  for(PRUint32 i = 0; i < nSize; i++) {
415  m_ColumnResolveMap.insert(std::make_pair<nsString, PRUint32>(m_ColumnNames[i], i));
416  }
417  }
418 }
return NS_OK
dbrowcells_t m_RowCells
dbcolumnresolvemap_t m_ColumnResolveMap
nsresult SetColumnName(PRUint32 dbColumn, const nsString &strColumnName)
nsresult SetColumnNames(const std::vector< nsString > &vColumnNames)
Songbird Database Object Definition.
virtual ~CDatabaseResult()
nsresult SetRowCell(PRUint32 dbRow, PRUint32 dbCell, const nsString &strCellValue)
void RebuildColumnResolveMap()
NS_IMPL_THREADSAFE_ISUPPORTS1(sbDeviceCapsCompatibility, sbIDeviceCapsCompatibility) sbDeviceCapsCompatibility
nsresult DeleteRow(PRUint32 dbRow)
nsresult SetRowCells(PRUint32 dbRow, const std::vector< nsString > &vCellValues)
NS_DECL_ISUPPORTS NS_DECL_SBIDATABASERESULT nsresult AddRow(const std::vector< nsString > &vCellValues)
An object containing the results of a database SELECT query.
PRPackedBool m_RequiresLocking
static void IfLock(PRLock *aLock)
static void IfUnlock(PRLock *aLock)
_getSelectedPageStyle s i
dbcolumnnames_t m_ColumnNames
PRUint32 GetColumnIndexFromName(const nsAString &strColumnName)