sbLocalDatabaseLibraryFactory.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 
28 
29 #include <nsIAppStartupNotifier.h>
30 #include <nsICategoryManager.h>
31 #include <nsIConverterInputStream.h>
32 #include <nsIFile.h>
33 #include <nsIIOService.h>
34 #include <nsILocalFile.h>
35 #include <nsIProperties.h>
36 #include <nsIPropertyBag2.h>
37 #include <nsIURI.h>
38 #include <nsIURL.h>
39 #include <nsIInputStream.h>
40 #include <nsIUnicharInputStream.h>
41 #include <nsIUUIDGenerator.h>
42 #include <nsIWritablePropertyBag2.h>
43 #include <sbIDatabaseResult.h>
44 #include <sbILibrary.h>
45 #include <sbILocalDatabasePropertyCache.h>
46 #include <sbISQLBuilder.h>
47 
48 #include <DatabaseQuery.h>
49 #include <nsAutoPtr.h>
50 #include <nsComponentManagerUtils.h>
51 #include <nsNetUtil.h>
52 #include <nsServiceManagerUtils.h>
53 #include <nsWeakReference.h>
54 #include <nsXPCOMCID.h>
55 #include "sbLocalDatabaseCID.h"
56 #include "sbLocalDatabaseLibrary.h"
57 #include <sbSQLBuilderCID.h>
58 
59 #define DEFAULT_LIBRARY_NAME NS_LITERAL_STRING("defaultlibrary.db")
60 #define SB_PROPERTYBAG_CONTRACTID "@songbirdnest.com/moz/xpcom/sbpropertybag;1"
61 #define PROPERTY_KEY_DATABASEFILE "databaseFile"
62 #define SCHEMA_URL "chrome://songbird/content/library/localdatabase/schema.sql"
63 #define SB_NAMEKEY_LIBRARY \
64  "&chrome://songbird/locale/songbird.properties#servicesource.library"
65 
66 #define PERMISSIONS_FILE 0644
67 #define PERMISSIONS_DIRECTORY 0755
68 
69 #define CONVERTER_BUFFER_SIZE 8192
70 
71 static nsresult
72 CreateDirectory(nsIFile* aDirectory)
73 {
74  PRBool exists;
75  nsresult rv = aDirectory->Exists(&exists);
76  NS_ENSURE_SUCCESS(rv, rv);
77 
78  if (exists) {
79  return NS_OK;
80  }
81 
82  rv = aDirectory->Create(nsIFile::DIRECTORY_TYPE, PERMISSIONS_DIRECTORY);
83  NS_ENSURE_SUCCESS(rv, rv);
84 
85  return NS_OK;
86 }
87 
88 static PRBool
89 IsDirectoryWritable(nsIFile* aDirectory)
90 {
91  PRBool isDirectory;
92  nsresult rv = aDirectory->IsDirectory(&isDirectory);
93  NS_ENSURE_SUCCESS(rv, PR_FALSE);
94 
95  NS_ENSURE_TRUE(isDirectory, PR_FALSE);
96 
97  PRBool exists;
98  rv = aDirectory->Exists(&exists);
99  NS_ENSURE_SUCCESS(rv, PR_FALSE);
100 
101  NS_ENSURE_TRUE(exists, PR_FALSE);
102 
103  nsCOMPtr<nsIFile> testFile;
104  rv = aDirectory->Clone(getter_AddRefs(testFile));
105  NS_ENSURE_SUCCESS(rv, PR_FALSE);
106 
107  rv = testFile->Append(NS_LITERAL_STRING("libraryFactory.test"));
108  NS_ENSURE_SUCCESS(rv, PR_FALSE);
109 
110  rv = testFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, PERMISSIONS_FILE);
111  NS_ENSURE_SUCCESS(rv, PR_FALSE);
112 
113  rv = testFile->Remove(PR_FALSE);
114  NS_ENSURE_SUCCESS(rv, PR_FALSE);
115 
116  return PR_TRUE;
117 }
118 
119 static already_AddRefed<nsILocalFile>
121 {
122  nsresult rv;
123  nsCOMPtr<nsIProperties> ds =
124  do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
125  NS_ENSURE_SUCCESS(rv, nsnull);
126 
127  nsILocalFile* file;
128  rv = ds->Get("ProfD", NS_GET_IID(nsILocalFile), (void**)&file);
129  NS_ENSURE_SUCCESS(rv, nsnull);
130 
131  rv = file->AppendRelativePath(NS_LITERAL_STRING("db"));
132  if (NS_FAILED(rv)) {
133  NS_WARNING("AppendRelativePath failed!");
134 
135  NS_RELEASE(file);
136  return nsnull;
137  }
138 
139  return file;
140 }
141 
143 
144 /*static*/ NS_METHOD
145 sbLocalDatabaseLibraryFactory::RegisterSelf(nsIComponentManager* aCompMgr,
146  nsIFile* aPath,
147  const char* aLoaderStr,
148  const char* aType,
149  const nsModuleComponentInfo *aInfo)
150 {
151  nsresult rv;
152  nsCOMPtr<nsICategoryManager> categoryManager =
153  do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
154  NS_ENSURE_SUCCESS(rv, rv);
155 
156  rv = categoryManager->AddCategoryEntry(APPSTARTUP_CATEGORY,
158  "service,"
160  PR_TRUE,
161  PR_TRUE,
162  nsnull);
163  NS_ENSURE_SUCCESS(rv, rv);
164 
165  return NS_OK;
166 }
167 
168 
169 nsresult
171 {
172  PRBool success = mCreatedLibraries.Init();
173  NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
174 
175  return NS_OK;
176 }
177 
178 NS_IMETHODIMP
179 sbLocalDatabaseLibraryFactory::GetType(nsAString& aType)
180 {
181  aType.AssignLiteral(SB_LOCALDATABASE_LIBRARYFACTORY_TYPE);
182  return NS_OK;
183 }
184 
185 NS_IMETHODIMP
186 sbLocalDatabaseLibraryFactory::GetContractID(nsACString& aContractID)
187 {
188  aContractID.AssignLiteral(SB_LOCALDATABASE_LIBRARYFACTORY_CONTRACTID);
189  return NS_OK;
190 }
191 
192 NS_IMETHODIMP
193 sbLocalDatabaseLibraryFactory::CreateLibrary(nsIPropertyBag2* aCreationParameters,
194  sbILibrary** _retval)
195 {
196  NS_ENSURE_ARG_POINTER(aCreationParameters);
197  NS_ENSURE_ARG_POINTER(_retval);
198 
199  nsCOMPtr<nsILocalFile> file;
200  nsresult rv =
201  aCreationParameters->GetPropertyAsInterface(NS_LITERAL_STRING(PROPERTY_KEY_DATABASEFILE),
202  NS_GET_IID(nsILocalFile),
203  getter_AddRefs(file));
204  if (NS_FAILED(rv)) {
205  NS_WARNING("You passed in a property bag with the wrong data!");
206 
207  file = GetDBFolder();
208  NS_ENSURE_TRUE(file, NS_ERROR_FAILURE);
209 
210  rv = file->AppendRelativePath(DEFAULT_LIBRARY_NAME);
211  NS_ENSURE_SUCCESS(rv, rv);
212  }
213 
214  rv = CreateLibraryFromDatabase(file, _retval, aCreationParameters);
215  NS_ENSURE_SUCCESS(rv, rv);
216 
217  // set a default name
218  rv = (*_retval)->SetName(NS_LITERAL_STRING(SB_NAMEKEY_LIBRARY));
219  NS_ENSURE_SUCCESS(rv, rv);
220 
221  return NS_OK;
222 }
223 
224 nsresult
226  sbILibrary** _retval,
227  nsIPropertyBag2* aCreationParameters,
228  nsString aResourceGUID /* = EmptyString() */)
229 {
230  NS_ENSURE_ARG_POINTER(aDatabase);
231  NS_ENSURE_ARG_POINTER(_retval);
232 
233  nsresult rv;
234 
235  // Get a unique value for this database file.
236  nsCOMPtr<nsIHashable> hashable = do_QueryInterface(aDatabase, &rv);
237  NS_ENSURE_SUCCESS(rv, rv);
238 
239  // We have to copy the file name escaping logic from when we actually create
240  // the database, otherwise we end up re-initizliaing the database over and over.
241  nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
242  NS_ENSURE_SUCCESS(rv, rv);
243 
244  nsCOMPtr<nsIURI> databaseURI;
245  rv = NS_NewFileURI(getter_AddRefs(databaseURI), aDatabase, ioService);
246  NS_ENSURE_SUCCESS(rv, rv);
247 
248  nsCOMPtr<nsIURL> databaseURL = do_QueryInterface(databaseURI, &rv);
249  NS_ENSURE_SUCCESS(rv, rv);
250 
251  nsCAutoString utf8GUID;
252  rv = databaseURL->GetFileBaseName(utf8GUID);
253  NS_ENSURE_SUCCESS(rv, rv);
254 
255  nsCOMPtr<nsIFile> databaseParent;
256  rv = aDatabase->GetParent(getter_AddRefs(databaseParent));
257  NS_ENSURE_SUCCESS(rv, rv);
258 
259  nsCAutoString fileName;
260  rv = databaseURL->GetFileName(fileName);
261  NS_ENSURE_SUCCESS(rv, rv);
262 
263  nsCOMPtr<nsIFile> escapedFile;
264  rv = databaseParent->Clone(getter_AddRefs(escapedFile));
265  NS_ENSURE_SUCCESS(rv, rv);
266 
267  rv = escapedFile->Append(NS_ConvertUTF8toUTF16(fileName));
268  NS_ENSURE_SUCCESS(rv, rv);
269 
270  // On Windows, if the file does not exist, its hashcode is different from when it does.
271  // If we ever attempt to get the hash code while it doesn't exist, the
272  // nsLocalFile caches the hash code and stays incorrect.
273  PRBool exists;
274  rv = escapedFile->Exists(&exists);
275  NS_ENSURE_SUCCESS(rv, rv);
276 
277  // See if we've already created this library. If we have (and it is still
278  // alive) just return it.
279  nsCOMPtr<nsIWeakReference> weakRef;
280  if (exists && mCreatedLibraries.Get(hashable, getter_AddRefs(weakRef))) {
281  nsCOMPtr<sbILibrary> existingLibrary = do_QueryReferent(weakRef, &rv);
282  NS_ENSURE_SUCCESS(rv, rv);
283 
284  if (existingLibrary) {
285  existingLibrary.swap(*_retval);
286  return NS_OK;
287  }
288 
289  mCreatedLibraries.Remove(hashable);
290  }
291 
292  // If the database file does not exist, create and initalize it. Otherwise,
293  // update it.
294  if (!exists) {
295  rv = InitalizeLibrary(aDatabase, aResourceGUID);
296  NS_ENSURE_SUCCESS(rv, rv);
297  }
298  else {
299  rv = UpdateLibrary(aDatabase);
300  NS_ENSURE_SUCCESS(rv, rv);
301  }
302 
303  nsCOMPtr<nsIURI> databaseLocation;
304  rv = NS_NewFileURI(getter_AddRefs(databaseLocation), databaseParent,
305  ioService);
306  NS_ENSURE_SUCCESS(rv, rv);
307 
308  nsRefPtr<sbLocalDatabaseLibrary> library(new sbLocalDatabaseLibrary());
309  NS_ENSURE_TRUE(library, NS_ERROR_OUT_OF_MEMORY);
310 
311  nsCOMPtr<nsIPropertyBag2> creationParams = aCreationParameters;
312  if (!creationParams) {
313  nsCOMPtr<nsIWritablePropertyBag2> bag =
314  do_CreateInstance(SB_PROPERTYBAG_CONTRACTID, &rv);
315  NS_ENSURE_SUCCESS(rv, rv);
316 
317  rv = bag->SetPropertyAsInterface(NS_LITERAL_STRING(PROPERTY_KEY_DATABASEFILE),
318  aDatabase);
319  NS_ENSURE_SUCCESS(rv, rv);
320 
321  creationParams = do_QueryInterface(bag, &rv);
322  NS_ENSURE_SUCCESS(rv, rv);
323  }
324 
325  rv = library->Init(NS_ConvertUTF8toUTF16(utf8GUID), creationParams, this,
326  databaseLocation);
327  NS_ENSURE_SUCCESS(rv, rv);
328 
329  // Add this library to our table of created libraries.
330  weakRef = do_GetWeakReference(NS_ISUPPORTS_CAST(sbILibrary*, library),
331  &rv);
332  NS_ENSURE_SUCCESS(rv, rv);
333 
334  PRBool success = mCreatedLibraries.Put(hashable, weakRef);
335  NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
336 
337  NS_ADDREF(*_retval = library);
338  return NS_OK;
339 }
340 
341 nsresult
342 sbLocalDatabaseLibraryFactory::InitalizeLibrary(nsIFile* aDatabaseFile,
343  const nsAString &aResourceGUID)
344 {
345  nsresult rv;
346  PRInt32 dbOk;
347 
348  nsCOMPtr<nsIFile> parentDirectory;
349  rv = aDatabaseFile->GetParent(getter_AddRefs(parentDirectory));
350  NS_ENSURE_SUCCESS(rv, rv);
351 
352  PRBool parentExists;
353  rv = parentDirectory->Exists(&parentExists);
354  NS_ENSURE_SUCCESS(rv, rv);
355 
356  if (!parentExists) {
357  rv = CreateDirectory(parentDirectory);
358  NS_ENSURE_SUCCESS(rv, rv);
359  }
360 
361  PRBool parentIsWritable = IsDirectoryWritable(parentDirectory);
362  NS_ENSURE_TRUE(parentIsWritable, NS_ERROR_FILE_ACCESS_DENIED);
363 
364  // Now that we know we have appropriate permissions make a new query.
365  nsCOMPtr<sbIDatabaseQuery> query =
366  do_CreateInstance(SONGBIRD_DATABASEQUERY_CONTRACTID, &rv);
367  NS_ENSURE_SUCCESS(rv, rv);
368 
369  rv = query->SetAsyncQuery(PR_FALSE);
370  NS_ENSURE_SUCCESS(rv, rv);
371 
372  rv = SetQueryDatabaseFile(query, aDatabaseFile);
373  NS_ENSURE_SUCCESS(rv, rv);
374 
375  nsCOMPtr<nsIURI> schemaURI;
376  rv = NS_NewURI(getter_AddRefs(schemaURI), NS_LITERAL_CSTRING(SCHEMA_URL));
377  NS_ENSURE_SUCCESS(rv, rv);
378 
379  nsCOMPtr<nsIInputStream> input;
380  rv = NS_OpenURI(getter_AddRefs(input), schemaURI);
381  NS_ENSURE_SUCCESS(rv, rv);
382 
383  nsCOMPtr<nsIConverterInputStream> converterStream =
384  do_CreateInstance("@mozilla.org/intl/converter-input-stream;1", &rv);
385  NS_ENSURE_SUCCESS(rv, rv);
386 
387  rv = converterStream->Init(input,
388  "UTF-8",
390  nsIConverterInputStream::
391  DEFAULT_REPLACEMENT_CHARACTER);
392  NS_ENSURE_SUCCESS(rv, rv);
393 
394  nsCOMPtr<nsIUnicharInputStream> unichar =
395  do_QueryInterface(converterStream, &rv);
396  NS_ENSURE_SUCCESS(rv, rv);
397 
398  PRUint32 read;
399  nsString response, result;
400  rv = unichar->ReadString(PR_UINT32_MAX, result, &read);
401  NS_ENSURE_SUCCESS(rv, rv);
402  NS_ASSERTION(read, "Schema file zero bytes?");
403  while (read > 0) {
404  response.Append(result);
405  rv = unichar->ReadString(PR_UINT32_MAX, result, &read);
406  NS_ENSURE_SUCCESS(rv, rv);
407  }
408 
409  rv = unichar->Close();
410  NS_ENSURE_SUCCESS(rv, rv);
411 
412  NS_NAMED_LITERAL_STRING(colonNewline, ";\n");
413  PRInt32 posStart = 0;
414  PRInt32 posEnd = response.Find(colonNewline, posStart);
415 
416  /* If the SQL file has CRLF endings, posEnd is -1, and no queries are added
417  * This is more important issue now since we use git, which, by default,
418  * can convert line endings when checking out a branch on windows
419  */
420  if (posEnd < 0) {
421  // Try again, looking for ";\r\n"
422  NS_NAMED_LITERAL_STRING(colonCRNewline, ";\r\n");
423  posEnd = response.Find(colonCRNewline, posStart);
424  while (posEnd >= 0) {
425  rv = query->AddQuery(Substring(response, posStart, posEnd - posStart));
426  NS_ENSURE_SUCCESS(rv, rv);
427  posStart = posEnd + 3;
428  posEnd = response.Find(colonCRNewline, posStart);
429  }
430  } else {
431  while (posEnd >= 0) {
432  rv = query->AddQuery(Substring(response, posStart, posEnd - posStart));
433  NS_ENSURE_SUCCESS(rv, rv);
434  posStart = posEnd + 2;
435  posEnd = response.Find(colonNewline, posStart);
436  }
437  }
438 
439  rv = query->Execute(&dbOk);
440  NS_ENSURE_SUCCESS(rv, rv);
441  NS_ENSURE_TRUE(dbOk == 0, NS_ERROR_FAILURE);
442 
443  nsString guid(aResourceGUID);
444  if(guid.IsEmpty()) {
445  // Create a resource guid for this database.
446  nsCOMPtr<nsIUUIDGenerator> uuidGen =
447  do_GetService("@mozilla.org/uuid-generator;1", &rv);
448  NS_ENSURE_SUCCESS(rv, rv);
449 
450  nsID id;
451  rv = uuidGen->GenerateUUIDInPlace(&id);
452  NS_ENSURE_SUCCESS(rv, rv);
453 
454  char guidChars[NSID_LENGTH];
455  id.ToProvidedString(guidChars);
456 
457  guid = NS_ConvertASCIItoUTF16(nsDependentCString(guidChars + 1,
458  NSID_LENGTH - 3));
459  }
460 
461  // Insert the guid into the database.
462  nsCOMPtr<sbISQLInsertBuilder> insert =
463  do_CreateInstance(SB_SQLBUILDER_INSERT_CONTRACTID, &rv);
464  NS_ENSURE_SUCCESS(rv, rv);
465 
466  rv = insert->SetIntoTableName(NS_LITERAL_STRING("library_metadata"));
467  NS_ENSURE_SUCCESS(rv, rv);
468 
469  rv = insert->AddColumn(NS_LITERAL_STRING("name"));
470  NS_ENSURE_SUCCESS(rv, rv);
471 
472  rv = insert->AddColumn(NS_LITERAL_STRING("value"));
473  NS_ENSURE_SUCCESS(rv, rv);
474 
475  rv = insert->AddValueString(NS_LITERAL_STRING("resource-guid"));
476  NS_ENSURE_SUCCESS(rv, rv);
477 
478  rv = insert->AddValueString(guid);
479  NS_ENSURE_SUCCESS(rv, rv);
480 
481  nsAutoString sql;
482  rv = insert->ToString(sql);
483  NS_ENSURE_SUCCESS(rv, rv);
484 
485  rv = query->ResetQuery();
486  NS_ENSURE_SUCCESS(rv, rv);
487 
488  rv = query->AddQuery(sql);
489  NS_ENSURE_SUCCESS(rv, rv);
490 
491  rv = query->Execute(&dbOk);
492  NS_ENSURE_SUCCESS(rv, rv);
493  NS_ENSURE_TRUE(dbOk == 0, NS_ERROR_FAILURE);
494 
495  nsString now;
497 
498  nsCOMPtr<nsIURI> fileURI;
499  rv = NS_NewFileURI(getter_AddRefs(fileURI), aDatabaseFile);
500  NS_ENSURE_SUCCESS(rv, rv);
501 
502  nsCString uriSpec;
503  rv = fileURI->GetSpec(uriSpec);
504  NS_ENSURE_SUCCESS(rv, rv);
505 
506  // Add the default library media item properties
507  insert = do_CreateInstance(SB_SQLBUILDER_INSERT_CONTRACTID, &rv);
508  NS_ENSURE_SUCCESS(rv, rv);
509 
510  rv = insert->SetIntoTableName(NS_LITERAL_STRING("library_media_item"));
511  NS_ENSURE_SUCCESS(rv, rv);
512 
513  rv = insert->AddColumn(NS_LITERAL_STRING("guid"));
514  NS_ENSURE_SUCCESS(rv, rv);
515 
516  rv = insert->AddValueString(guid);
517  NS_ENSURE_SUCCESS(rv, rv);
518 
519  rv = insert->AddColumn(NS_LITERAL_STRING("created"));
520  NS_ENSURE_SUCCESS(rv, rv);
521 
522  rv = insert->AddValueString(now);
523  NS_ENSURE_SUCCESS(rv, rv);
524 
525  rv = insert->AddColumn(NS_LITERAL_STRING("updated"));
526  NS_ENSURE_SUCCESS(rv, rv);
527 
528  rv = insert->AddValueString(now);
529  NS_ENSURE_SUCCESS(rv, rv);
530 
531  rv = insert->AddColumn(NS_LITERAL_STRING("content_url"));
532  NS_ENSURE_SUCCESS(rv, rv);
533 
534  rv = insert->AddValueString(NS_ConvertUTF8toUTF16(uriSpec));
535  NS_ENSURE_SUCCESS(rv, rv);
536 
537  rv = insert->AddColumn(NS_LITERAL_STRING("hidden"));
538  NS_ENSURE_SUCCESS(rv, rv);
539 
540  rv = insert->AddValueLong(0);
541  NS_ENSURE_SUCCESS(rv, rv);
542 
543  rv = insert->AddColumn(NS_LITERAL_STRING("is_list"));
544  NS_ENSURE_SUCCESS(rv, rv);
545 
546  rv = insert->AddValueLong(0);
547  NS_ENSURE_SUCCESS(rv, rv);
548 
549  rv = insert->ToString(sql);
550  NS_ENSURE_SUCCESS(rv, rv);
551 
552  rv = query->ResetQuery();
553  NS_ENSURE_SUCCESS(rv, rv);
554 
555  rv = query->AddQuery(sql);
556  NS_ENSURE_SUCCESS(rv, rv);
557 
558  rv = query->Execute(&dbOk);
559  NS_ENSURE_SUCCESS(rv, rv);
560  NS_ENSURE_TRUE(dbOk == 0, NS_ERROR_FAILURE);
561 
562  return NS_OK;
563 }
564 
565 nsresult
566 sbLocalDatabaseLibraryFactory::UpdateLibrary(nsIFile* aDatabaseFile)
567 {
568  nsresult rv;
569  PRInt32 dbOk;
570 
571  nsCOMPtr<sbIDatabaseQuery> query =
572  do_CreateInstance(SONGBIRD_DATABASEQUERY_CONTRACTID, &rv);
573  NS_ENSURE_SUCCESS(rv, rv);
574 
575  rv = query->SetAsyncQuery(PR_FALSE);
576  NS_ENSURE_SUCCESS(rv, rv);
577 
578  rv = SetQueryDatabaseFile(query, aDatabaseFile);
579  NS_ENSURE_SUCCESS(rv, rv);
580 
581  // Update some library media item properties
582  nsCOMPtr<sbISQLUpdateBuilder> update =
583  do_CreateInstance(SB_SQLBUILDER_UPDATE_CONTRACTID, &rv);
584  NS_ENSURE_SUCCESS(rv, rv);
585 
586  rv = update->SetTableName(NS_LITERAL_STRING("library_media_item"));
587  NS_ENSURE_SUCCESS(rv, rv);
588 
589  nsCOMPtr<nsIURI> fileURI;
590  rv = NS_NewFileURI(getter_AddRefs(fileURI), aDatabaseFile);
591  NS_ENSURE_SUCCESS(rv, rv);
592 
593  nsCAutoString uriSpec;
594  rv = fileURI->GetSpec(uriSpec);
595  NS_ENSURE_SUCCESS(rv, rv);
596  rv = update->AddAssignmentString(NS_LITERAL_STRING("content_url"),
597  NS_ConvertUTF8toUTF16(uriSpec));
598  NS_ENSURE_SUCCESS(rv, rv);
599 
600  nsAutoString sql;
601  rv = update->ToString(sql);
602  NS_ENSURE_SUCCESS(rv, rv);
603 
604  rv = query->AddQuery(sql);
605  NS_ENSURE_SUCCESS(rv, rv);
606 
607  rv = query->Execute(&dbOk);
608  NS_ENSURE_SUCCESS(rv, rv);
609  NS_ENSURE_TRUE(dbOk == 0, NS_ERROR_FAILURE);
610 
611  return NS_OK;
612 }
613 
614 already_AddRefed<nsILocalFile>
616 {
617  nsCOMPtr<nsILocalFile> file = GetDBFolder();
618  NS_ENSURE_TRUE(file, nsnull);
619 
620  nsAutoString filename(aGUID);
621  filename.AppendLiteral(".db");
622 
623  nsresult rv = file->AppendRelativePath(filename);
624  NS_ENSURE_SUCCESS(rv, nsnull);
625 
626  nsILocalFile* _retval;
627  NS_ADDREF(_retval = file);
628 
629  return _retval;
630 }
631 
632 void
634  nsAString& aGUID)
635 {
636  nsAutoString filename;
637  nsresult rv = aFile->GetLeafName(filename);
638  NS_ENSURE_SUCCESS(rv,);
639 
640  aGUID.Assign(StringHead(filename, filename.Length() - 3));
641 }
642 
643 nsresult
644 sbLocalDatabaseLibraryFactory::SetQueryDatabaseFile
645  (sbIDatabaseQuery* aQuery,
646  nsIFile* aDatabaseFile)
647 {
648  NS_ENSURE_ARG_POINTER(aQuery);
649  NS_ENSURE_ARG_POINTER(aDatabaseFile);
650 
651  nsresult rv;
652 
653  nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
654  NS_ENSURE_SUCCESS(rv, rv);
655 
656  // Figure out a GUID based on the filename. All our database files use the
657  // '.db' extension, so if someone requests another extension then that's just
658  // too bad.
659  nsCOMPtr<nsIURI> fileURI;
660  rv = NS_NewFileURI(getter_AddRefs(fileURI), aDatabaseFile, ioService);
661  NS_ENSURE_SUCCESS(rv, rv);
662 
663  nsCOMPtr<nsIURL> fileURL = do_QueryInterface(fileURI, &rv);
664  NS_ENSURE_SUCCESS(rv, rv);
665 
666  nsCAutoString fileBaseName;
667  rv = fileURL->GetFileBaseName(fileBaseName);
668  NS_ENSURE_SUCCESS(rv, rv);
669 
670  rv = aQuery->SetDatabaseGUID(NS_ConvertUTF8toUTF16(fileBaseName));
671  NS_ENSURE_SUCCESS(rv, rv);
672 
673 #ifdef DEBUG
674  // Warn anyone if they passed in an extension other than '.db'.
675  nsCAutoString fileExtension;
676  rv = fileURL->GetFileExtension(fileExtension);
677  if (NS_SUCCEEDED(rv)) {
678  if (!fileExtension.IsEmpty() &&
679  !fileExtension.Equals("db", CaseInsensitiveCompare)) {
680  NS_WARNING("All database files are forced to use the '.db' extension.");
681  }
682  }
683 #endif
684  // Set the parent directory as the location for the library database file.
685  nsCOMPtr<nsIFile> parentDirectory;
686  rv = aDatabaseFile->GetParent(getter_AddRefs(parentDirectory));
687  NS_ENSURE_SUCCESS(rv, rv);
688 
689  nsCOMPtr<nsIURI> parentURI;
690  rv = NS_NewFileURI(getter_AddRefs(parentURI), parentDirectory, ioService);
691  NS_ENSURE_SUCCESS(rv, rv);
692 
693  rv = aQuery->SetDatabaseLocation(parentURI);
694  NS_ENSURE_SUCCESS(rv, rv);
695 
696  return NS_OK;
697 }
698 
return NS_OK
_updateCookies aPath
#define SONGBIRD_DATABASEQUERY_CONTRACTID
Definition: DatabaseQuery.h:63
#define SB_SQLBUILDER_UPDATE_CONTRACTID
menuItem id
Definition: FeedWriter.js:971
NS_IMPL_ISUPPORTS1(sbDeviceCapabilitiesUtils, sbIDeviceCapabilitiesUtils) sbDeviceCapabilitiesUtils
#define PERMISSIONS_FILE
void GetGUIDFromFile(nsILocalFile *aFile, nsAString &aGUID)
Factory for new library instances.
#define PROPERTY_KEY_DATABASEFILE
#define SB_SQLBUILDER_INSERT_CONTRACTID
var ioService
#define SB_LOCALDATABASE_LIBRARYFACTORY_CONTRACTID
#define DEFAULT_LIBRARY_NAME
static already_AddRefed< nsILocalFile > GetDBFolder()
#define SB_LOCALDATABASE_LIBRARYFACTORY_DESCRIPTION
already_AddRefed< nsILocalFile > GetFileForGUID(const nsAString &aGUID)
function insert(dbq, size, name)
Media library abstraction.
Definition: sbILibrary.idl:82
const PR_UINT32_MAX
Definition: httpd.js:55
#define CONVERTER_BUFFER_SIZE
#define SB_PROPERTYBAG_CONTRACTID
static PRBool IsDirectoryWritable(nsIFile *aDirectory)
#define PERMISSIONS_DIRECTORY
An object responsible for executing SQL queries on the database.
#define SB_LOCALDATABASE_LIBRARYFACTORY_TYPE
nsresult CreateLibraryFromDatabase(nsIFile *aDatabase, sbILibrary **_retval, nsIPropertyBag2 *aCreationParameters=nsnull, nsString aResourceGUID=EmptyString())
function now()
static void GetNowString(nsAString &_retval)
Make a string of the current time in milliseconds.
#define SB_NAMEKEY_LIBRARY
native sbLocalDatabaseLibrary(sbLocalDatabaseLibrary)
static nsresult CreateDirectory(nsIFile *aDirectory)
var file
Songbird Database Object Definition.