sbSongkickDBService.cpp
Go to the documentation of this file.
1 /*
2  *=BEGIN SONGBIRD GPL
3  *
4  * This file is part of the Songbird web player.
5  *
6  * Copyright(c) 2005-2010 POTI, Inc.
7  * http://www.songbirdnest.com
8  *
9  * This file may be licensed under the terms of of the
10  * GNU General Public License Version 2 (the ``GPL'').
11  *
12  * Software distributed under the License is distributed
13  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
14  * express or implied. See the GPL for the specific language
15  * governing rights and limitations.
16  *
17  * You should have received a copy of the GPL along with this
18  * program. If not, go to http://www.gnu.org/licenses/gpl.html
19  * or write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  *
22  *=END SONGBIRD GPL
23  */
24 
25 #include "sbSongkickDBService.h"
26 
27 #include <sbIDatabaseResult.h>
28 
29 #include <nsAutoLock.h>
30 #include <nsICategoryManager.h>
31 #include <nsComponentManagerUtils.h>
32 #include <nsIFile.h>
33 #include <nsIIOService.h>
34 #include <nsIMutableArray.h>
35 #include <nsIObserverService.h>
36 #include <nsIProperties.h>
37 #include <nsIRunnable.h>
38 #include <nsIThread.h>
39 #include <nsIThreadManager.h>
40 #include <nsIThreadPool.h>
41 #include <nsIURI.h>
42 #include <nsNetUtil.h>
43 #include <nsServiceManagerUtils.h>
44 #include <nsThreadUtils.h>
45 
46 #include <list>
47 
48 
49 //==============================================================================
50 // String escaping utility functions
51 //==============================================================================
52 
53 nsString c2h( PRUnichar dec )
54 {
55  char dig1 = (dec&0xF0)>>4;
56  char dig2 = (dec&0x0F);
57  if ( 0<= dig1 && dig1<= 9) dig1+=48; //0,48inascii
58  if (10<= dig1 && dig1<=15) dig1+=97-10; //a,97inascii
59  if ( 0<= dig2 && dig2<= 9) dig2+=48;
60  if (10<= dig2 && dig2<=15) dig2+=97-10;
61 
62  nsString r;
63  r.Append(dig1);
64  r.Append(dig2);
65  return r;
66 }
67 
68 //based on javascript encodeURIComponent()
69 nsString encodeURIComponent(const nsString &c)
70 {
71  nsString escaped;
72  int max = c.Length();
73  for (int i=0; i<max; i++) {
74  if ((48 <= c[i] && c[i] <= 57) ||//0-9
75  (65 <= c[i] && c[i] <= 90) ||//abc...xyz
76  (97 <= c[i] && c[i] <= 122) || //ABC...XYZ
77  (c[i]=='~' || c[i]=='!' || c[i]=='*' || c[i]=='(' || c[i]==')' || c[i]=='\'')
78  )
79  {
80  escaped.Append(c[i]);
81  }
82  else {
83  escaped.AppendLiteral("%");
84  escaped.Append( c2h(c[i]) );//converts char 255 to string "ff"
85  }
86  }
87  return escaped;
88 }
89 
90 
91 //==============================================================================
92 // sbSongkickResultEnumerator
93 //==============================================================================
94 
96 {
97 public:
100 
102  NS_DECL_NSISIMPLEENUMERATOR
103 
104  nsresult Init(sbIDatabaseResult *aResult,
105  sbIDatabaseQuery *aQuery);
106 
107 protected:
108  typedef std::list<nsRefPtr<sbSongkickConcertInfo> > sbConcertInfoList;
109  typedef sbConcertInfoList::const_iterator sbConcertInfoListIter;
110 
111  static nsresult ContainsConcertList(const nsAString & aID,
112  const sbConcertInfoList & aConcertList,
113  PRBool *aHasEntry);
114 
117 };
118 
119 
121 
123 {
124 }
125 
127 {
128 }
129 
130 nsresult
132  sbIDatabaseQuery *aQuery)
133 {
134  NS_ENSURE_ARG_POINTER(aResult);
135  NS_ENSURE_ARG_POINTER(aQuery);
136 
137  // Convert all the values in the result to the concert interface type.
138  nsresult rv;
139  PRUint32 rowCount = 0;
140  rv = aResult->GetRowCount(&rowCount);
141  NS_ENSURE_SUCCESS(rv, rv);
142 
143  for (PRUint32 i = 0; i < rowCount; i++) {
144  nsString id;
145  rv = aResult->GetRowCellByColumn(i, NS_LITERAL_STRING("id"), id);
146  NS_ENSURE_SUCCESS(rv, rv);
147 
148  // If this record has already been recorded, just continue.
149  PRBool hasRecord = PR_FALSE;
150  rv = ContainsConcertList(id, mConcertInfoList, &hasRecord);
151  if (NS_FAILED(rv) || hasRecord) {
152  continue;
153  }
154 
155  nsString artistName;
156  rv = aResult->GetRowCellByColumn(i, NS_LITERAL_STRING("name"), artistName);
157  NS_ENSURE_SUCCESS(rv, rv);
158  artistName = encodeURIComponent(artistName);
159 
160  nsString artistURL;
161  rv = aResult->GetRowCellByColumn(i, NS_LITERAL_STRING("artistURL"), artistURL);
162  NS_ENSURE_SUCCESS(rv, rv);
163 
164  nsString ts;
165  rv = aResult->GetRowCellByColumn(i, NS_LITERAL_STRING("timestamp"), ts);
166  NS_ENSURE_SUCCESS(rv, rv);
167 
168  nsString venue;
169  rv = aResult->GetRowCellByColumn(i, NS_LITERAL_STRING("venue"), venue);
170  NS_ENSURE_SUCCESS(rv, rv);
171  venue = encodeURIComponent(venue);
172 
173  nsString city;
174  rv = aResult->GetRowCellByColumn(i, NS_LITERAL_STRING("city"), city);
175  NS_ENSURE_SUCCESS(rv, rv);
176 
177  nsString title;
178  rv = aResult->GetRowCellByColumn(i, NS_LITERAL_STRING("title"), title);
179  NS_ENSURE_SUCCESS(rv, rv);
180  title = encodeURIComponent(title);
181 
182  nsString url;
183  rv = aResult->GetRowCellByColumn(i, NS_LITERAL_STRING("concertURL"), url);
184  NS_ENSURE_SUCCESS(rv, rv);
185 
186  nsString lib;
187  rv = aResult->GetRowCellByColumn(i, NS_LITERAL_STRING("libraryArtist"), lib);
188  NS_ENSURE_SUCCESS(rv, rv);
189 
190  nsString venueURL;
191  rv = aResult->GetRowCellByColumn(i, NS_LITERAL_STRING("venueURL"), venueURL);
192  NS_ENSURE_SUCCESS(rv, rv);
193 
194  nsString tickets;
195  rv = aResult->GetRowCellByColumn(i, NS_LITERAL_STRING("tickets"), tickets);
196  NS_ENSURE_SUCCESS(rv, rv);
197 
198  // Now lookup the playing at artists.
199  rv = aQuery->ResetQuery();
200  NS_ENSURE_SUCCESS(rv, rv);
201 
202  nsString stmt;
203  stmt.AppendLiteral(
204  "select * from artists join playing_at on playing_at.concertid=");
205  stmt.Append(id);
206  stmt.AppendLiteral(" and playing_at.artistid = artists.ROWID");
207 
208  rv = aQuery->AddQuery(stmt);
209  NS_ENSURE_SUCCESS(rv, rv);
210 
211  PRInt32 queryResult;
212  rv = aQuery->Execute(&queryResult);
213  NS_ENSURE_SUCCESS(rv, rv);
214  NS_ENSURE_TRUE(queryResult == 0, NS_ERROR_FAILURE);
215 
216  nsCOMPtr<sbIDatabaseResult> playingAtResult;
217  rv = aQuery->GetResultObject(getter_AddRefs(playingAtResult));
218  NS_ENSURE_SUCCESS(rv, rv);
219 
220  PRUint32 playingAtCount = 0;
221  rv = playingAtResult->GetRowCount(&playingAtCount);
222  NS_ENSURE_SUCCESS(rv, rv);
223 
224  nsCOMPtr<nsIMutableArray> artistConcertInfoArray =
225  do_CreateInstance("@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
226  NS_ENSURE_SUCCESS(rv, rv);
227 
228  for (PRUint32 i = 0; i < playingAtCount; i++) {
229  nsRefPtr<sbSongkickArtistConcertInfo> curArtistInfo =
231  NS_ENSURE_TRUE(curArtistInfo, NS_ERROR_OUT_OF_MEMORY);
232 
233  nsString artistName;
234  playingAtResult->GetRowCellByColumn(
235  i, NS_LITERAL_STRING("name"), artistName);
236  artistName = encodeURIComponent(artistName);
237 
238  nsString artistURL;
239  playingAtResult->GetRowCellByColumn(
240  i, NS_LITERAL_STRING("artistURL"), artistURL);
241 
242  rv = curArtistInfo->Init(artistName, artistURL);
243  NS_ENSURE_SUCCESS(rv, rv);
244 
245  rv = artistConcertInfoArray->AppendElement(curArtistInfo, PR_FALSE);
246  NS_ENSURE_SUCCESS(rv, rv);
247  }
248 
249  nsRefPtr<sbSongkickConcertInfo> curInfo =
250  new sbSongkickConcertInfo();
251  NS_ENSURE_TRUE(curInfo, NS_ERROR_OUT_OF_MEMORY);
252 
253  rv = curInfo->Init(artistName,
254  artistURL,
255  id,
256  ts,
257  venue,
258  city,
259  title,
260  url,
261  venueURL,
262  tickets,
263  artistConcertInfoArray,
264  lib);
265  NS_ENSURE_SUCCESS(rv, rv);
266 
267  mConcertInfoList.push_back(curInfo);
268  }
269 
270  // Set the iter position
272  return NS_OK;
273 }
274 
275 /* static */ nsresult
277  const nsAString & aID,
278  const sbConcertInfoList & aConcertList,
279  PRBool *aHasEntry)
280 {
281  NS_ENSURE_ARG_POINTER(aHasEntry);
282  *aHasEntry = PR_FALSE;
283 
284  sbConcertInfoListIter begin = aConcertList.begin();
285  sbConcertInfoListIter end = aConcertList.end();
287  for (next = begin; next != end && !*aHasEntry; ++next) {
288  if ((*next)->mID.Equals(aID)) {
289  *aHasEntry = PR_TRUE;
290  }
291  }
292 
293  return NS_OK;
294 }
295 
296 NS_IMETHODIMP
297 sbSongkickResultEnumerator::HasMoreElements(PRBool *aHasMore)
298 {
299  NS_ENSURE_ARG_POINTER(aHasMore);
300  *aHasMore = mConcertInfoListIter != mConcertInfoList.end();
301  return NS_OK;
302 }
303 
304 NS_IMETHODIMP
305 sbSongkickResultEnumerator::GetNext(nsISupports **aOutNext)
306 {
307  NS_ENSURE_ARG_POINTER(aOutNext);
308 
309  nsresult rv;
310  nsCOMPtr<nsISupports> curConcertInfo =
311  do_QueryInterface(*mConcertInfoListIter++, &rv);
312 
313  curConcertInfo.forget(aOutNext);
314  return NS_OK;
315 }
316 
317 
318 //==============================================================================
319 // sbSongkickDBInfo
320 //==============================================================================
321 
322 class sbSongkickDBInfo : public nsIRunnable
323 {
324  friend class sbSongkickDBService;
325 
326 public:
328  virtual ~sbSongkickDBInfo();
329 
331  NS_DECL_NSIRUNNABLE
332 
333  nsresult Init(sbSongkickDBService *aDBService);
334 
335 protected:
336  nsresult LoadGotLocationInfo();
337  nsresult LoadLocationCountryInfo();
338  nsresult LoadLocationStateInfo();
339  nsresult LoadLocationCityInfo();
340 
341  // Shared members:
343  nsCOMPtr<nsIMutableArray> mCountriesProps;
344  nsCOMPtr<nsIMutableArray> mStateProps;
345  nsCOMPtr<nsIMutableArray> mCityProps;
346 
347 private:
348  nsCOMPtr<sbIDatabaseQuery> mDBQuery;
349  nsRefPtr<sbSongkickDBService> mDBService;
350 };
351 
352 
354 
356  : mGotLocationInfo(PR_FALSE)
357 {
358 }
359 
361 {
362 }
363 
364 nsresult
366 {
367  NS_ENSURE_ARG_POINTER(aService);
368  mDBService = aService;
369 
370  nsresult rv;
372  do_CreateInstance("@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
373  NS_ENSURE_SUCCESS(rv, rv);
374 
375  mStateProps =
376  do_CreateInstance("@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
377  NS_ENSURE_SUCCESS(rv, rv);
378 
379  mCityProps =
380  do_CreateInstance("@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
381  NS_ENSURE_SUCCESS(rv, rv);
382 
383  return NS_OK;
384 }
385 
386 NS_IMETHODIMP
387 sbSongkickDBInfo::Run()
388 {
389  NS_ENSURE_TRUE(mDBService, NS_ERROR_UNEXPECTED);
390 
391  nsresult rv;
392  rv = mDBService->GetDatabaseQuery(getter_AddRefs(mDBQuery));
393  if (rv == NS_ERROR_NOT_AVAILABLE) {
394  // set an active flag...?
395  return NS_OK;
396  }
397  NS_ENSURE_SUCCESS(rv, rv);
398 
399  rv = LoadGotLocationInfo();
400  NS_ENSURE_SUCCESS(rv, rv);
401 
403  NS_ENSURE_SUCCESS(rv, rv);
404 
405  rv = LoadLocationStateInfo();
406  NS_ENSURE_SUCCESS(rv, rv);
407 
408  rv = LoadLocationCityInfo();
409  NS_ENSURE_SUCCESS(rv, rv);
410 
411  return NS_OK;
412 }
413 
414 nsresult
416 {
417  nsresult rv;
418  rv = mDBQuery->ResetQuery();
419  NS_ENSURE_SUCCESS(rv, rv);
420 
421  nsString stmt;
422  stmt.AssignLiteral("select count(*) from cities");
423 
424  rv = mDBQuery->AddQuery(stmt);
425  NS_ENSURE_SUCCESS(rv, rv);
426 
427  PRInt32 queryResult;
428  rv = mDBQuery->Execute(&queryResult);
429  NS_ENSURE_SUCCESS(rv, rv);
430  NS_ENSURE_TRUE(queryResult == 0, NS_ERROR_FAILURE);
431 
432  nsCOMPtr<sbIDatabaseResult> results;
433  rv = mDBQuery->GetResultObject(getter_AddRefs(results));
434  NS_ENSURE_SUCCESS(rv, rv);
435 
436  nsString rowCountStr;
437  rv = results->GetRowCell(0, 0, rowCountStr);
438  NS_ENSURE_SUCCESS(rv, rv);
439 
440  PRUint32 rowCount = rowCountStr.ToInteger(&rv);
441  NS_ENSURE_SUCCESS(rv, rv);
442 
443  mGotLocationInfo = rowCount > 0;
444 
445  return NS_OK;
446 }
447 
448 nsresult
450 {
451  nsresult rv;
452  rv = mDBQuery->ResetQuery();
453  NS_ENSURE_SUCCESS(rv, rv);
454 
455  rv = mDBQuery->AddQuery(NS_LITERAL_STRING("select * from countries"));
456  NS_ENSURE_SUCCESS(rv, rv);
457 
458  PRInt32 queryResult;
459  rv = mDBQuery->Execute(&queryResult);
460  NS_ENSURE_SUCCESS(rv, rv);
461  NS_ENSURE_TRUE(queryResult == 0, NS_ERROR_FAILURE);
462 
463  nsCOMPtr<sbIDatabaseResult> results;
464  rv = mDBQuery->GetResultObject(getter_AddRefs(results));
465  NS_ENSURE_SUCCESS(rv, rv);
466 
467  PRUint32 rowCount = 0;
468  rv = results->GetRowCount(&rowCount);
469  NS_ENSURE_SUCCESS(rv, rv);
470 
471  for (PRUint32 i = 0; i < rowCount; i++) {
472  nsString id, name;
473  rv = results->GetRowCellByColumn(i, NS_LITERAL_STRING("id"), id);
474  NS_ENSURE_SUCCESS(rv, rv);
475  rv = results->GetRowCellByColumn(i, NS_LITERAL_STRING("name"), name);
476  NS_ENSURE_SUCCESS(rv, rv);
477 
478  nsRefPtr<sbSongkickProperty> curProp = new sbSongkickProperty();
479  NS_ENSURE_TRUE(curProp, NS_ERROR_OUT_OF_MEMORY);
480 
481  rv = curProp->Init(name, id, EmptyString());
482  NS_ENSURE_SUCCESS(rv, rv);
483 
484  rv = mCountriesProps->AppendElement(curProp, PR_FALSE);
485  NS_ENSURE_SUCCESS(rv, rv);
486  }
487 
488  return NS_OK;
489 }
490 
491 nsresult
493 {
494  nsresult rv;
495  rv = mDBQuery->ResetQuery();
496  NS_ENSURE_SUCCESS(rv, rv);
497 
498  rv = mDBQuery->AddQuery(NS_LITERAL_STRING("select * from states"));
499  NS_ENSURE_SUCCESS(rv, rv);
500 
501  PRInt32 queryResult;
502  rv = mDBQuery->Execute(&queryResult);
503  NS_ENSURE_SUCCESS(rv, rv);
504  NS_ENSURE_TRUE(queryResult == 0, NS_ERROR_FAILURE);
505 
506  nsCOMPtr<sbIDatabaseResult> results;
507  rv = mDBQuery->GetResultObject(getter_AddRefs(results));
508  NS_ENSURE_SUCCESS(rv, rv);
509 
510  PRUint32 rowCount = 0;
511  rv = results->GetRowCount(&rowCount);
512  NS_ENSURE_SUCCESS(rv, rv);
513 
514  for (PRUint32 i = 0; i < rowCount; i++) {
515  nsString id, name, country;
516  rv = results->GetRowCellByColumn(i, NS_LITERAL_STRING("id"), id);
517  NS_ENSURE_SUCCESS(rv, rv);
518  rv = results->GetRowCellByColumn(i, NS_LITERAL_STRING("name"), name);
519  NS_ENSURE_SUCCESS(rv, rv);
520  rv = results->GetRowCellByColumn(i, NS_LITERAL_STRING("country"), country);
521  NS_ENSURE_SUCCESS(rv, rv);
522 
523  nsRefPtr<sbSongkickProperty> curProp = new sbSongkickProperty();
524  NS_ENSURE_TRUE(curProp, NS_ERROR_OUT_OF_MEMORY);
525 
526  rv = curProp->Init(name, id, country);
527  NS_ENSURE_SUCCESS(rv, rv);
528 
529  rv = mStateProps->AppendElement(curProp, PR_FALSE);
530  NS_ENSURE_SUCCESS(rv, rv);
531  }
532 
533  return NS_OK;
534 }
535 
536 nsresult
538 {
539  nsresult rv;
540  rv = mDBQuery->ResetQuery();
541  NS_ENSURE_SUCCESS(rv, rv);
542 
543  rv = mDBQuery->AddQuery(NS_LITERAL_STRING("select * from cities"));
544  NS_ENSURE_SUCCESS(rv, rv);
545 
546  PRInt32 queryResult;
547  rv = mDBQuery->Execute(&queryResult);
548  NS_ENSURE_SUCCESS(rv, rv);
549  NS_ENSURE_TRUE(queryResult == 0, NS_ERROR_FAILURE);
550 
551  nsCOMPtr<sbIDatabaseResult> results;
552  rv = mDBQuery->GetResultObject(getter_AddRefs(results));
553  NS_ENSURE_SUCCESS(rv, rv);
554 
555  PRUint32 rowCount = 0;
556  rv = results->GetRowCount(&rowCount);
557  NS_ENSURE_SUCCESS(rv, rv);
558 
559  for (PRUint32 i = 0; i < rowCount; i++) {
560  nsString id, name, state;
561  rv = results->GetRowCellByColumn(i, NS_LITERAL_STRING("id"), id);
562  NS_ENSURE_SUCCESS(rv, rv);
563  rv = results->GetRowCellByColumn(i, NS_LITERAL_STRING("name"), name);
564  NS_ENSURE_SUCCESS(rv, rv);
565  rv = results->GetRowCellByColumn(i, NS_LITERAL_STRING("state"), state);
566  NS_ENSURE_SUCCESS(rv, rv);
567 
568  nsRefPtr<sbSongkickProperty> curProp = new sbSongkickProperty();
569  NS_ENSURE_TRUE(curProp, NS_ERROR_OUT_OF_MEMORY);
570 
571  rv = curProp->Init(name, id, state);
572  NS_ENSURE_SUCCESS(rv, rv);
573 
574  rv = mCityProps->AppendElement(curProp, PR_FALSE);
575  NS_ENSURE_SUCCESS(rv, rv);
576  }
577 
578  return NS_OK;
579 }
580 
581 //==============================================================================
582 // sbSongkickQuery
583 //==============================================================================
584 
585 class sbSongkickQuery : public nsIRunnable
586 {
587 public:
588  sbSongkickQuery();
589  virtual ~sbSongkickQuery();
590 
592  NS_DECL_NSIRUNNABLE
593 
594  nsresult Init(const nsAString & aQueryStmt,
595  sbSongkickDBService *aDBService,
596  sbISongkickEnumeratorCallback *aCallback);
597 
598  void RunEnumCallbackStart();
599  void RunEnumCallbackEnd();
600 
601 private:
602  nsCOMPtr<sbISongkickEnumeratorCallback> mCallback;
603  nsCOMPtr<nsIThread> mCallingThread;
604  nsRefPtr<sbSongkickResultEnumerator> mResultsEnum;
605  nsRefPtr<sbSongkickDBService> mDBService;
606  nsString mQueryStmt;
607 };
608 
609 
611 
613 {
614 }
615 
617 {
618 }
619 
620 NS_IMETHODIMP
621 sbSongkickQuery::Run()
622 {
623  NS_ENSURE_TRUE(mDBService, NS_ERROR_UNEXPECTED);
624 
625  // First, notify the enum callback of enumeration start.
626  nsresult rv;
627  nsCOMPtr<nsIRunnable> runnable =
628  NS_NEW_RUNNABLE_METHOD(sbSongkickQuery, this, RunEnumCallbackStart);
629  NS_ENSURE_TRUE(runnable, NS_ERROR_FAILURE);
630  rv = mCallingThread->Dispatch(runnable, NS_DISPATCH_SYNC);
631 
632  // Setup the database query.
633  nsCOMPtr<sbIDatabaseQuery> db;
634  rv = mDBService->GetDatabaseQuery(getter_AddRefs(db));
635  NS_ENSURE_SUCCESS(rv, rv);
636 
637  rv = db->AddQuery(mQueryStmt);
638  NS_ENSURE_SUCCESS(rv, rv);
639  {
640  // Try and save deadlocking the database...
641  nsAutoLock lock(mDBService->mQueryRunningLock);
642 
643  // Phew, finally send of the query.
644  PRInt32 queryResult;
645  rv = db->Execute(&queryResult);
646  NS_ENSURE_SUCCESS(rv, rv);
647  NS_ENSURE_TRUE(queryResult == 0, NS_ERROR_FAILURE);
648  }
649 
650  // Convert any results into the appropriate type.
651  nsCOMPtr<sbIDatabaseResult> results;
652  rv = db->GetResultObject(getter_AddRefs(results));
653  NS_ENSURE_SUCCESS(rv, rv);
654 
655  // Create another db query for lookup up playing at data while enumerating
656  // through the current results.
657  nsCOMPtr<sbIDatabaseQuery> artistDB;
658  rv = mDBService->GetDatabaseQuery(getter_AddRefs(artistDB));
659  NS_ENSURE_SUCCESS(rv, rv);
660 
661  mResultsEnum = new sbSongkickResultEnumerator();
662  NS_ENSURE_TRUE(mResultsEnum, NS_ERROR_OUT_OF_MEMORY);
663  rv = mResultsEnum->Init(results, artistDB);
664  NS_ENSURE_SUCCESS(rv, rv);
665 
666  // Finally, notify the listener of enumeration end.
667  runnable =
668  NS_NEW_RUNNABLE_METHOD(sbSongkickQuery, this, RunEnumCallbackEnd);
669  NS_ENSURE_TRUE(runnable, NS_ERROR_FAILURE);
670  rv = mCallingThread->Dispatch(runnable, NS_DISPATCH_SYNC);
671  NS_ENSURE_SUCCESS(rv, rv);
672 
673  return NS_OK;
674 }
675 
676 nsresult
677 sbSongkickQuery::Init(const nsAString & aQueryStmt,
678  sbSongkickDBService *aDBService,
680 {
681  NS_ENSURE_ARG_POINTER(aCallback);
682  NS_ENSURE_ARG_POINTER(aDBService);
683 
684  mQueryStmt = aQueryStmt;
685  mDBService = aDBService;
686  mCallback = aCallback;
687 
688  // Grap a reference to the calling thread.
689  nsresult rv;
690  nsCOMPtr<nsIThreadManager> threadMgr =
691  do_GetService("@mozilla.org/thread-manager;1", &rv);
692  NS_ENSURE_SUCCESS(rv, rv);
693  rv = threadMgr->GetCurrentThread(getter_AddRefs(mCallingThread));
694  NS_ENSURE_SUCCESS(rv, rv);
695 
696  return NS_OK;
697 }
698 
699 void
701 {
702  NS_ENSURE_TRUE(mCallback, /* void */);
703  mCallback->OnEnumerationStart();
704 }
705 
706 void
708 {
709  NS_ENSURE_TRUE(mCallback, /* void */);
710 
711  nsresult rv;
712  nsCOMPtr<nsISimpleEnumerator> outEnum = do_QueryInterface(
713  NS_ISUPPORTS_CAST(nsISimpleEnumerator*, mResultsEnum),
714  &rv);
715  NS_ENSURE_SUCCESS(rv, /* void */);
716 
717  mCallback->OnEnumerationEnd(outEnum);
718 }
719 
720 //==============================================================================
721 // sbSongkickCountQuery
722 //==============================================================================
723 
724 class sbSongkickCountQuery : public nsIRunnable
725 {
726 public:
728  virtual ~sbSongkickCountQuery();
729 
731  NS_DECL_NSIRUNNABLE
732 
733  nsresult Init(const nsAString & aQueryStmt,
734  sbSongkickDBService *aDBService,
736 
737  void RunEnumCountCallback();
738 
739 private:
740  nsCOMPtr<sbISongkickConcertCountCallback> mCallback;
741  nsCOMPtr<nsIThread> mCallingThread;
742  nsRefPtr<sbSongkickDBService> mDBService;
743  nsString mQueryStmt;
744  PRUint32 mCount;
745 };
746 
747 
749 
751  : mCount(0)
752 {
753 }
754 
756 {
757 }
758 
759 nsresult
760 sbSongkickCountQuery::Init(const nsAString & aQueryStmt,
761  sbSongkickDBService *aDBService,
763 {
764  NS_ENSURE_ARG_POINTER(aCallback);
765  NS_ENSURE_ARG_POINTER(aDBService);
766 
767  mDBService = aDBService;
768  mCallback = aCallback;
769  mQueryStmt = aQueryStmt;
770 
771  // Grab a reference to the calling thread.
772  nsresult rv;
773  rv = NS_GetCurrentThread(getter_AddRefs(mCallingThread));
774  NS_ENSURE_SUCCESS(rv, rv);
775 
776  return NS_OK;
777 }
778 
779 NS_IMETHODIMP
780 sbSongkickCountQuery::Run()
781 {
782  nsresult rv;
783 
784  // Setup the database query.
785  nsCOMPtr<sbIDatabaseQuery> db;
786  rv = mDBService->GetDatabaseQuery(getter_AddRefs(db));
787  NS_ENSURE_SUCCESS(rv, rv);
788 
789  rv = db->AddQuery(mQueryStmt);
790  NS_ENSURE_SUCCESS(rv, rv);
791 
792  // Phew, finally send of the query.
793  PRInt32 queryResult;
794  rv = db->Execute(&queryResult);
795  NS_ENSURE_SUCCESS(rv, rv);
796  NS_ENSURE_TRUE(queryResult == 0, NS_ERROR_FAILURE);
797 
798  // Convert any results into the appropriate type.
799  nsCOMPtr<sbIDatabaseResult> results;
800  rv = db->GetResultObject(getter_AddRefs(results));
801  NS_ENSURE_SUCCESS(rv, rv);
802 
803  nsString rowCountStr;
804  rv = results->GetRowCell(0, 0, rowCountStr);
805  NS_ENSURE_SUCCESS(rv, rv);
806 
807  mCount = rowCountStr.ToInteger(&rv);
808  NS_ENSURE_SUCCESS(rv, rv);
809 
810  nsCOMPtr<nsIRunnable> runnable =
811  NS_NEW_RUNNABLE_METHOD(sbSongkickCountQuery, this, RunEnumCountCallback);
812  NS_ENSURE_TRUE(runnable, NS_ERROR_FAILURE);
813  rv = mCallingThread->Dispatch(runnable, NS_DISPATCH_SYNC);
814  NS_ENSURE_SUCCESS(rv, rv);
815 
816  return NS_OK;
817 }
818 
819 void
821 {
822  NS_ENSURE_TRUE(mCallback, /* void */);
823  mCallback->OnConcertCountEnd(mCount);
824 }
825 
826 //==============================================================================
827 // sbSongkickDBService
828 //==============================================================================
829 
831 
833  : mQueryRunningLock(
834  nsAutoLock::NewLock("sbSongkickDBService::mQueryRunningLock"))
835 {
836  NS_ASSERTION(mQueryRunningLock, "Failed to create mQueryRunningLock");
837 }
838 
840 {
841  if (mQueryRunningLock) {
842  nsAutoLock::DestroyLock(mQueryRunningLock);
843  }
844 }
845 
846 nsresult
848 {
849  // Preload some data on a background thread.
850  nsresult rv;
851  mDBInfo = new sbSongkickDBInfo();
852  rv = mDBInfo->Init(this);
853  NS_ENSURE_SUCCESS(rv, rv);
854 
855  nsCOMPtr<nsIObserverService> observerService =
856  do_GetService("@mozilla.org/observer-service;1", &rv);
857  NS_ENSURE_SUCCESS(rv, rv);
858 
859  rv = observerService->AddObserver(this,
860  "final-ui-startup",
861  PR_FALSE);
862  NS_ENSURE_SUCCESS(rv, rv);
863 
864  return NS_OK;
865 }
866 
867 nsresult
869 {
870  NS_ENSURE_TRUE(mDBInfo, NS_ERROR_UNEXPECTED);
871 
872  // Start data lookup.
873  nsresult rv;
874  nsCOMPtr<nsIThreadPool> threadPoolService =
875  do_GetService("@songbirdnest.com/Songbird/ThreadPoolService;1", &rv);
876  NS_ENSURE_SUCCESS(rv, rv);
877 
878  rv = threadPoolService->Dispatch(mDBInfo, NS_DISPATCH_NORMAL);
879  NS_ENSURE_SUCCESS(rv, rv);
880 
881  return NS_OK;
882 }
883 
884 nsresult
886 {
887  NS_ENSURE_ARG_POINTER(aOutDBQuery);
888 
889  // Setup the database query.
890  nsresult rv;
891  nsCOMPtr<nsIIOService> ioService =
892  do_GetService("@mozilla.org/network/io-service;1", &rv);
893  NS_ENSURE_SUCCESS(rv, rv);
894 
895  nsCOMPtr<nsIProperties> dirService =
896  do_GetService("@mozilla.org/file/directory_service;1", &rv);
897  NS_ENSURE_SUCCESS(rv, rv);
898 
899  nsCOMPtr<nsIFile> profileFile;
900  rv = dirService->Get("ProfD",
901  NS_GET_IID(nsIFile),
902  getter_AddRefs(profileFile));
903 
904  // Ensure that the database has been created first.
905  nsCOMPtr<nsIFile> dbFile;
906  rv = profileFile->Clone(getter_AddRefs(dbFile));
907  NS_ENSURE_SUCCESS(rv, rv);
908 
909  rv = dbFile->Append(NS_LITERAL_STRING("concerts.db"));
910  NS_ENSURE_SUCCESS(rv, rv);
911 
912  PRBool exists = PR_FALSE;
913  rv = dbFile->Exists(&exists);
914  NS_ENSURE_SUCCESS(rv, rv);
915 
916  if (!exists) {
917  return NS_ERROR_NOT_AVAILABLE;
918  }
919 
920  nsCOMPtr<nsIURI> dbLocationURI;
921  rv = NS_NewFileURI(getter_AddRefs(dbLocationURI),
922  profileFile,
923  ioService);
924  NS_ENSURE_SUCCESS(rv, rv);
925 
926  nsCOMPtr<sbIDatabaseQuery> db =
927  do_CreateInstance("@songbirdnest.com/Songbird/DatabaseQuery;1", &rv);
928  NS_ENSURE_SUCCESS(rv, rv);
929  rv = db->SetDatabaseLocation(dbLocationURI);
930  NS_ENSURE_SUCCESS(rv, rv);
931  rv = db->SetDatabaseGUID(NS_LITERAL_STRING("concerts"));
932  NS_ENSURE_SUCCESS(rv, rv);
933 
934  db.forget(aOutDBQuery);
935  return NS_OK;
936 }
937 
938 //------------------------------------------------------------------------------
939 // XPCOM Startup Registration
940 
941 /* static */ NS_METHOD
942 sbSongkickDBService::RegisterSelf(nsIComponentManager *aCompMgr,
943  nsIFile *aPath,
944  const char *aLoaderStr,
945  const char *aType,
946  const nsModuleComponentInfo *aInfo)
947 {
948  NS_ENSURE_ARG_POINTER(aCompMgr);
949  NS_ENSURE_ARG_POINTER(aPath);
950  NS_ENSURE_ARG_POINTER(aLoaderStr);
951  NS_ENSURE_ARG_POINTER(aType);
952  NS_ENSURE_ARG_POINTER(aInfo);
953 
954  nsresult rv = NS_ERROR_UNEXPECTED;
955  nsCOMPtr<nsICategoryManager> catMgr =
956  do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
957  NS_ENSURE_SUCCESS(rv, rv);
958 
959  rv = catMgr->AddCategoryEntry("app-startup",
961  "service,"
963  PR_TRUE, PR_TRUE, nsnull);
964  NS_ENSURE_SUCCESS(rv, rv);
965 
966  return NS_OK;
967 }
968 
969 //------------------------------------------------------------------------------
970 // sbPISongkickDBService
971 
972 NS_IMETHODIMP
973 sbSongkickDBService::GetHasLocationInfo(PRBool *aOutHasLocationInfo)
974 {
975  NS_ENSURE_ARG_POINTER(aOutHasLocationInfo);
976  NS_ENSURE_TRUE(mDBInfo, NS_ERROR_UNEXPECTED);
977 
978  *aOutHasLocationInfo = mDBInfo->mGotLocationInfo;
979  return NS_OK;
980 }
981 
982 NS_IMETHODIMP
983 sbSongkickDBService::GetLocationCountries(nsIArray **aOutArray)
984 {
985  NS_ENSURE_ARG_POINTER(aOutArray);
986  NS_ENSURE_TRUE(mDBInfo, NS_ERROR_NOT_AVAILABLE);
987 
988  NS_IF_ADDREF(*aOutArray = mDBInfo->mCountriesProps);
989  return NS_OK;
990 }
991 
992 NS_IMETHODIMP
993 sbSongkickDBService::ReloadLocationInfo(void)
994 {
995  NS_ENSURE_TRUE(mDBInfo, NS_ERROR_UNEXPECTED);
996  nsresult rv;
997 
998  rv = LookupDBInfo();
999  NS_ENSURE_SUCCESS(rv, rv);
1000 
1001  return NS_OK;
1002 }
1003 
1004 NS_IMETHODIMP
1005 sbSongkickDBService::GetLocationStates(const nsAString & aCountry,
1006  nsIArray **aOutArray)
1007 {
1008  NS_ENSURE_ARG_POINTER(aOutArray);
1009 
1010  // The state information is stored without a filter. Create an array
1011  // that has a subset of the state information based on the country.
1012  nsresult rv;
1013  nsCOMPtr<nsIMutableArray> statesArray =
1014  do_CreateInstance("@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
1015 
1016  nsCOMPtr<nsISimpleEnumerator> statesEnum;
1017  rv = mDBInfo->mStateProps->Enumerate(getter_AddRefs(statesEnum));
1018  NS_ENSURE_SUCCESS(rv, rv);
1019 
1020  PRBool hasMore = PR_FALSE;
1021  while (NS_SUCCEEDED(statesEnum->HasMoreElements(&hasMore)) && hasMore) {
1022  nsCOMPtr<nsISupports> curItem;
1023  rv = statesEnum->GetNext(getter_AddRefs(curItem));
1024  NS_ENSURE_SUCCESS(rv, rv);
1025 
1026  nsCOMPtr<sbISongkickProperty> curProp =
1027  do_QueryInterface(curItem, &rv);
1028  NS_ENSURE_SUCCESS(rv, rv);
1029 
1030  nsString curCountry;
1031  rv = curProp->GetKey(curCountry);
1032  NS_ENSURE_SUCCESS(rv, rv);
1033 
1034  if (curCountry.Equals(aCountry)) {
1035  rv = statesArray->AppendElement(curProp, PR_FALSE);
1036  NS_ENSURE_SUCCESS(rv, rv);
1037  }
1038  }
1039 
1040  rv = CallQueryInterface(statesArray, aOutArray);
1041  NS_ENSURE_SUCCESS(rv, rv);
1042 
1043  return NS_OK;
1044 }
1045 
1046 NS_IMETHODIMP
1047 sbSongkickDBService::GetLocationCities(const nsAString & aState,
1048  nsIArray **aOutArray)
1049 {
1050  NS_ENSURE_ARG_POINTER(aOutArray);
1051 
1052  // The state information is stored without a filter. Create an array
1053  // that has a subset of the state information based on the country.
1054  nsresult rv;
1055  nsCOMPtr<nsIMutableArray> citiesArray =
1056  do_CreateInstance("@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
1057 
1058  nsCOMPtr<nsISimpleEnumerator> cityEnum;
1059  rv = mDBInfo->mCityProps->Enumerate(getter_AddRefs(cityEnum));
1060  NS_ENSURE_SUCCESS(rv, rv);
1061 
1062  PRBool hasMore = PR_FALSE;
1063  while (NS_SUCCEEDED(cityEnum->HasMoreElements(&hasMore)) && hasMore) {
1064  nsCOMPtr<nsISupports> curItem;
1065  rv = cityEnum->GetNext(getter_AddRefs(curItem));
1066  NS_ENSURE_SUCCESS(rv, rv);
1067 
1068  nsCOMPtr<sbISongkickProperty> curProp =
1069  do_QueryInterface(curItem, &rv);
1070  NS_ENSURE_SUCCESS(rv, rv);
1071 
1072  nsString curState;
1073  rv = curProp->GetKey(curState);
1074  NS_ENSURE_SUCCESS(rv, rv);
1075 
1076  if (curState.Equals(aState)) {
1077  rv = citiesArray->AppendElement(curProp, PR_FALSE);
1078  NS_ENSURE_SUCCESS(rv, rv);
1079  }
1080  }
1081 
1082  rv = CallQueryInterface(citiesArray, aOutArray);
1083  NS_ENSURE_SUCCESS(rv, rv);
1084 
1085  return NS_OK;
1086 }
1087 
1088 NS_IMETHODIMP
1089 sbSongkickDBService::StartAristConcertLookup(
1090  PRBool aFilter,
1091  sbISongkickEnumeratorCallback *aCallback)
1092 {
1093  NS_ENSURE_ARG_POINTER(aCallback);
1094 
1095  nsString stmt;
1096  stmt.AppendLiteral("SELECT * FROM playing_at");
1097  stmt.AppendLiteral(" JOIN artists ON playing_at.artistid = artists.ROWID");
1098  stmt.AppendLiteral(" JOIN concerts ON playing_at.concertid = concerts.id");
1099  if (aFilter) {
1100  stmt.AppendLiteral(" WHERE playing_at.libraryArtist = 1");
1101  }
1102  stmt.AppendLiteral(" ORDER BY artists.name COLLATE NOCASE");
1103 
1104  nsRefPtr<sbSongkickQuery> skQuery = new sbSongkickQuery();
1105  NS_ENSURE_TRUE(skQuery, NS_ERROR_OUT_OF_MEMORY);
1106 
1107  nsresult rv;
1108  rv = skQuery->Init(stmt, this, aCallback);
1109  NS_ENSURE_SUCCESS(rv, rv);
1110 
1111  nsCOMPtr<nsIThreadPool> threadPoolService =
1112  do_GetService("@songbirdnest.com/Songbird/ThreadPoolService;1", &rv);
1113  NS_ENSURE_SUCCESS(rv, rv);
1114 
1115  rv = threadPoolService->Dispatch(skQuery, NS_DISPATCH_NORMAL);
1116  NS_ENSURE_SUCCESS(rv, rv);
1117 
1118  return NS_OK;
1119 }
1120 
1121 NS_IMETHODIMP
1122 sbSongkickDBService::StartConcertLookup(
1123  const nsAString & aSort,
1124  PRBool aFilter,
1125  sbISongkickEnumeratorCallback *aCallback)
1126 {
1127  NS_ENSURE_ARG_POINTER(aCallback);
1128 
1129  nsString stmt;
1130  stmt.AppendLiteral("SELECT * FROM concerts");
1131  stmt.AppendLiteral(" JOIN playing_at ON playing_at.concertid = concerts.id");
1132  stmt.AppendLiteral(" JOIN artists ON playing_at.artistid = artists.ROWID");
1133 
1134  if (aFilter) {
1135  stmt.AppendLiteral(" WHERE playing_at.anyLibraryArtist = 1");
1136  }
1137 
1138  // Figure out the sort key
1139  stmt.AppendLiteral(" ORDER BY ");
1140  if (aSort.EqualsLiteral("date")) {
1141  stmt.AppendLiteral("timestamp");
1142  }
1143  else if (aSort.EqualsLiteral("venue")) {
1144  stmt.AppendLiteral("venue");
1145  }
1146  else {
1147  // Fallback to 'title' (this includes aSort == "title").
1148  stmt.AppendLiteral("title");
1149  }
1150 
1151  nsRefPtr<sbSongkickQuery> skQuery = new sbSongkickQuery();
1152  NS_ENSURE_TRUE(skQuery, NS_ERROR_OUT_OF_MEMORY);
1153 
1154  nsresult rv;
1155  rv = skQuery->Init(stmt, this, aCallback);
1156  NS_ENSURE_SUCCESS(rv, rv);
1157 
1158  nsCOMPtr<nsIThreadPool> threadPoolService =
1159  do_GetService("@songbirdnest.com/Songbird/ThreadPoolService;1", &rv);
1160  NS_ENSURE_SUCCESS(rv, rv);
1161 
1162  rv = threadPoolService->Dispatch(skQuery, NS_DISPATCH_NORMAL);
1163  NS_ENSURE_SUCCESS(rv, rv);
1164 
1165  return NS_OK;
1166 }
1167 
1168 NS_IMETHODIMP
1169 sbSongkickDBService::StartConcertCountLookup(
1170  PRBool aFilter,
1171  PRBool aGroupByArtist,
1172  const nsAString & aDateProperty,
1173  const nsAString & aCeilingProperty,
1175 {
1176  NS_ENSURE_ARG_POINTER(aCallback);
1177 
1178  nsresult rv;
1179 
1180  nsString stmt;
1181  if (aGroupByArtist) {
1182  stmt.AppendLiteral("SELECT COUNT(distinct concertid) FROM playing_at");
1183  stmt.AppendLiteral(" JOIN concerts ON playing_at.concertid = concerts.id");
1184  stmt.AppendLiteral(" WHERE concerts.timestamp >= ");
1185  stmt.Append(aDateProperty);
1186  if (aFilter) {
1187  stmt.AppendLiteral(" AND playing_at.libraryArtist = 1");
1188  }
1189  }
1190  else {
1191  stmt.AppendLiteral("SELECT COUNT(distinct id) FROM playing_at");
1192  stmt.AppendLiteral(" JOIN concerts ON playing_at.concertid = concerts.id");
1193  stmt.AppendLiteral(" WHERE concerts.timestamp >= ");
1194  stmt.Append(aDateProperty);
1195  stmt.AppendLiteral(" AND concerts.timestamp < ");
1196  stmt.Append(aCeilingProperty);
1197  if (aFilter) {
1198  stmt.AppendLiteral(" AND playing_at.anyLibraryArtist = 1");
1199  }
1200  }
1201 
1202  nsRefPtr<sbSongkickCountQuery> skQuery = new sbSongkickCountQuery();
1203  NS_ENSURE_TRUE(skQuery, NS_ERROR_OUT_OF_MEMORY);
1204 
1205  rv = skQuery->Init(stmt, this, aCallback);
1206  NS_ENSURE_SUCCESS(rv, rv);
1207 
1208  nsCOMPtr<nsIThreadPool> threadPoolService =
1209  do_GetService("@songbirdnest.com/Songbird/ThreadPoolService;1", &rv);
1210  NS_ENSURE_SUCCESS(rv, rv);
1211 
1212  rv = threadPoolService->Dispatch(skQuery, NS_DISPATCH_NORMAL);
1213  NS_ENSURE_SUCCESS(rv, rv);
1214 
1215  return NS_OK;
1216 }
1217 
1218 //------------------------------------------------------------------------------
1219 // nsIObserver
1220 
1221 NS_IMETHODIMP
1222 sbSongkickDBService::Observe(nsISupports *aSubject,
1223  const char *aTopic,
1224  const PRUnichar *aData)
1225 {
1226  NS_ENSURE_ARG_POINTER(aTopic);
1227 
1228  if (strcmp(aTopic, "final-ui-startup") == 0) {
1229  nsresult rv;
1230  nsCOMPtr<nsIObserverService> observerService =
1231  do_GetService("@mozilla.org/observer-service;1", &rv);
1232  NS_ENSURE_SUCCESS(rv, rv);
1233 
1234  rv = observerService->RemoveObserver(this, aTopic);
1235  NS_ENSURE_SUCCESS(rv, rv);
1236 
1237  rv = LookupDBInfo();
1238  NS_ENSURE_SUCCESS(rv, rv);
1239  }
1240 
1241  return NS_OK;
1242 }
1243 
1244 
1245 //==============================================================================
1246 // sbSongkickConcertInfo
1247 //==============================================================================
1248 
1250 
1252 {
1253 }
1254 
1256 {
1257 }
1258 
1259 nsresult
1260 sbSongkickConcertInfo::Init(const nsAString & aArtistname,
1261  const nsAString & aArtistURL,
1262  const nsAString & aID,
1263  const nsAString & aTS,
1264  const nsAString & aVenue,
1265  const nsAString & aCity,
1266  const nsAString & aTitle,
1267  const nsAString & aURL,
1268  const nsAString & aVenueURL,
1269  const nsAString & aTickets,
1270  nsIArray *aArtistsConcertInfo,
1271  const nsAString & aLibartist)
1272 {
1273  mArtistname = aArtistname;
1274  mArtistURL = aArtistURL;
1275  mID = aID;
1276  mTS = aTS;
1277  mVenue = aVenue;
1278  mCity = aCity;
1279  mTitle = aTitle;
1280  mURL = aURL;
1281  mVenueURL = aVenueURL;
1282  mTickets = aTickets;
1283  mArtistConcertInfoArray = aArtistsConcertInfo;
1284  mLibArtist = aLibartist;
1285  return NS_OK;
1286 }
1287 
1288 NS_IMETHODIMP
1289 sbSongkickConcertInfo::GetArtistname(nsAString & aArtistname)
1290 {
1291  aArtistname = mArtistname;
1292  return NS_OK;
1293 }
1294 
1295 NS_IMETHODIMP
1296 sbSongkickConcertInfo::GetArtisturl(nsAString & aArtisturl)
1297 {
1298  aArtisturl = mArtistURL;
1299  return NS_OK;
1300 }
1301 
1302 NS_IMETHODIMP
1303 sbSongkickConcertInfo::GetId(nsAString & aId)
1304 {
1305  aId = mID;
1306  return NS_OK;
1307 }
1308 
1309 NS_IMETHODIMP
1310 sbSongkickConcertInfo::GetTs(nsAString & aTs)
1311 {
1312  aTs = mTS;
1313  return NS_OK;
1314 }
1315 
1316 NS_IMETHODIMP
1317 sbSongkickConcertInfo::GetVenue(nsAString & aVenue)
1318 {
1319  aVenue = mVenue;
1320  return NS_OK;
1321 }
1322 
1323 NS_IMETHODIMP
1324 sbSongkickConcertInfo::GetCity(nsAString & aCity)
1325 {
1326  aCity = mCity;
1327  return NS_OK;
1328 }
1329 
1330 NS_IMETHODIMP
1331 sbSongkickConcertInfo::GetTitle(nsAString & aTitle)
1332 {
1333  aTitle = mTitle;
1334  return NS_OK;
1335 }
1336 
1337 NS_IMETHODIMP
1338 sbSongkickConcertInfo::GetUrl(nsAString & aUrl)
1339 {
1340  aUrl = mURL;
1341  return NS_OK;
1342 }
1343 
1344 NS_IMETHODIMP
1345 sbSongkickConcertInfo::GetVenueURL(nsAString & aVenueURL)
1346 {
1347  aVenueURL = mVenueURL;
1348  return NS_OK;
1349 }
1350 
1351 NS_IMETHODIMP
1352 sbSongkickConcertInfo::GetTickets(nsAString & aTickets)
1353 {
1354  aTickets = mTickets;
1355  return NS_OK;
1356 }
1357 
1358 NS_IMETHODIMP
1359 sbSongkickConcertInfo::GetArtistsConcertInfo(nsIArray **aArtistsConcertInfo)
1360 {
1361  NS_ENSURE_ARG_POINTER(aArtistsConcertInfo);
1362  NS_IF_ADDREF(*aArtistsConcertInfo = mArtistConcertInfoArray);
1363  return NS_OK;
1364 }
1365 
1366 NS_IMETHODIMP
1367 sbSongkickConcertInfo::GetLibartist(nsAString & aLibartist)
1368 {
1369  mLibArtist = aLibartist;
1370  return NS_OK;
1371 }
1372 
1373 //==============================================================================
1374 // sbSongkickArtistConcertInfo
1375 //==============================================================================
1376 
1379 
1381 {
1382 }
1383 
1385 {
1386 }
1387 
1388 nsresult
1389 sbSongkickArtistConcertInfo::Init(const nsAString & aArtistName,
1390  const nsAString & aArtistURL)
1391 {
1392  mArtistName = aArtistName;
1393  mArtistURL = aArtistURL;
1394  return NS_OK;
1395 }
1396 
1397 NS_IMETHODIMP
1398 sbSongkickArtistConcertInfo::GetArtistname(nsAString & aArtistname)
1399 {
1400  aArtistname = mArtistName;
1401  return NS_OK;
1402 }
1403 
1404 NS_IMETHODIMP
1405 sbSongkickArtistConcertInfo::GetArtisturl(nsAString & aArtisturl)
1406 {
1407  aArtisturl = mArtistURL;
1408  return NS_OK;
1409 }
1410 
1411 //==============================================================================
1412 // sbSongkickProperty
1413 //==============================================================================
1414 
1416 
1418 {
1419 }
1420 
1422 {
1423 }
1424 
1425 nsresult
1427  const nsAString & aID,
1428  const nsAString & aKey)
1429 {
1430  mName = aName;
1431  mID = aID;
1432  mKey = aKey;
1433  return NS_OK;
1434 }
1435 
1436 NS_IMETHODIMP
1437 sbSongkickProperty::GetName(nsAString & aName)
1438 {
1439  aName = mName;
1440  return NS_OK;
1441 }
1442 
1443 NS_IMETHODIMP
1444 sbSongkickProperty::GetId(nsAString & aID)
1445 {
1446  aID = mID;
1447  return NS_OK;
1448 }
1449 
1450 NS_IMETHODIMP
1451 sbSongkickProperty::GetKey(nsAString & aKey)
1452 {
1453  aKey = mKey;
1454  return NS_OK;
1455 }
1456 
nsCOMPtr< nsIMutableArray > mStateProps
return NS_OK
_updateCookies aPath
nsString encodeURIComponent(const nsString &c)
static nsCOMPtr< nsIObserverService > observerService
Definition: UnityProxy.cpp:6
static nsresult ContainsConcertList(const nsAString &aID, const sbConcertInfoList &aConcertList, PRBool *aHasEntry)
NS_DECL_ISUPPORTS NS_DECL_SBISONGKICKPROPERTY nsresult Init(const nsAString &aName, const nsAString &aID, const nsAString &aKey)
menuItem id
Definition: FeedWriter.js:971
nsresult LoadLocationCountryInfo()
nsresult LoadLocationStateInfo()
nsresult GetDatabaseQuery(sbIDatabaseQuery **aOutDBQuery)
NS_DECL_ISUPPORTS NS_DECL_SBISONGKICKARTISTCONCERTINFO nsresult Init(const nsAString &aArtistName, const nsAString &aArtistURL)
NS_DECL_ISUPPORTS NS_DECL_NSISIMPLEENUMERATOR nsresult Init(sbIDatabaseResult *aResult, sbIDatabaseQuery *aQuery)
NS_DECL_ISUPPORTS NS_DECL_NSIRUNNABLE nsresult Init(const nsAString &aQueryStmt, sbSongkickDBService *aDBService, sbISongkickEnumeratorCallback *aCallback)
var ioService
NS_DECL_ISUPPORTS NS_DECL_NSIRUNNABLE nsresult Init(const nsAString &aQueryStmt, sbSongkickDBService *aDBService, sbISongkickConcertCountCallback *aCallback)
nsCOMPtr< nsIArray > mArtistConcertInfoArray
NS_IMPL_THREADSAFE_ISUPPORTS1(sbSongkickArtistConcertInfo, sbISongkickArtistConcertInfo) sbSongkickArtistConcertInfo
NS_DECL_ISUPPORTS NS_DECL_NSIRUNNABLE nsresult Init(sbSongkickDBService *aDBService)
NS_DECL_ISUPPORTS NS_DECL_SBPISONGKICKDBSERVICE static NS_DECL_NSIOBSERVER NS_METHOD RegisterSelf(nsIComponentManager *aCompMgr, nsIFile *aPath, const char *aLoaderStr, const char *aType, const nsModuleComponentInfo *aInfo)
#define SONGBIRD_SONGKICKDBSERVICE_CLASSNAME
nsCOMPtr< nsIMutableArray > mCityProps
An object containing the results of a database SELECT query.
_updateCookies aName
function url(spec)
StringArrayEnumerator prototype hasMore
sbConcertInfoList::const_iterator sbConcertInfoListIter
nsString c2h(PRUnichar dec)
An object responsible for executing SQL queries on the database.
sbConcertInfoListIter mConcertInfoListIter
std::list< nsRefPtr< sbSongkickConcertInfo > > sbConcertInfoList
restoreWindow aState
#define SONGBIRD_SONGKICKDBSERVICE_CONTRACTID
NS_DECL_ISUPPORTS NS_DECL_SBISONGKICKCONCERTINFO nsresult Init(const nsAString &aArtistname, const nsAString &aArtistURL, const nsAString &aID, const nsAString &aTS, const nsAString &aVenue, const nsAString &aCity, const nsAString &aTitle, const nsAString &aURL, const nsAString &aVenueURL, const nsAString &aTickets, nsIArray *aArtistsConcertInfo, const nsAString &aLibartist)
_getSelectedPageStyle s i
nsCOMPtr< nsIMutableArray > mCountriesProps
_updateTextAndScrollDataForFrame aData
function next()