29 #include <nsIAppStartupNotifier.h>
30 #include <nsICategoryManager.h>
31 #include <nsIConverterInputStream.h>
33 #include <nsIIOService.h>
34 #include <nsILocalFile.h>
35 #include <nsIProperties.h>
36 #include <nsIPropertyBag2.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>
49 #include <nsAutoPtr.h>
50 #include <nsComponentManagerUtils.h>
51 #include <nsNetUtil.h>
52 #include <nsServiceManagerUtils.h>
53 #include <nsWeakReference.h>
54 #include <nsXPCOMCID.h>
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"
66 #define PERMISSIONS_FILE 0644
67 #define PERMISSIONS_DIRECTORY 0755
69 #define CONVERTER_BUFFER_SIZE 8192
75 nsresult rv = aDirectory->Exists(&exists);
76 NS_ENSURE_SUCCESS(rv, rv);
83 NS_ENSURE_SUCCESS(rv, rv);
92 nsresult rv = aDirectory->IsDirectory(&isDirectory);
93 NS_ENSURE_SUCCESS(rv, PR_FALSE);
95 NS_ENSURE_TRUE(isDirectory, PR_FALSE);
98 rv = aDirectory->Exists(&exists);
99 NS_ENSURE_SUCCESS(rv, PR_FALSE);
101 NS_ENSURE_TRUE(exists, PR_FALSE);
103 nsCOMPtr<nsIFile> testFile;
104 rv = aDirectory->Clone(getter_AddRefs(testFile));
105 NS_ENSURE_SUCCESS(rv, PR_FALSE);
107 rv = testFile->Append(NS_LITERAL_STRING(
"libraryFactory.test"));
108 NS_ENSURE_SUCCESS(rv, PR_FALSE);
111 NS_ENSURE_SUCCESS(rv, PR_FALSE);
113 rv = testFile->Remove(PR_FALSE);
114 NS_ENSURE_SUCCESS(rv, PR_FALSE);
119 static already_AddRefed<nsILocalFile>
123 nsCOMPtr<nsIProperties> ds =
124 do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
125 NS_ENSURE_SUCCESS(rv, nsnull);
128 rv = ds->Get(
"ProfD", NS_GET_IID(nsILocalFile), (
void**)&file);
129 NS_ENSURE_SUCCESS(rv, nsnull);
131 rv = file->AppendRelativePath(NS_LITERAL_STRING(
"db"));
133 NS_WARNING(
"AppendRelativePath failed!");
147 const
char* aLoaderStr,
149 const nsModuleComponentInfo *aInfo)
152 nsCOMPtr<nsICategoryManager> categoryManager =
153 do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
154 NS_ENSURE_SUCCESS(rv, rv);
156 rv = categoryManager->AddCategoryEntry(APPSTARTUP_CATEGORY,
163 NS_ENSURE_SUCCESS(rv, rv);
172 PRBool success = mCreatedLibraries.Init();
173 NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
179 sbLocalDatabaseLibraryFactory::GetType(nsAString& aType)
186 sbLocalDatabaseLibraryFactory::GetContractID(nsACString& aContractID)
193 sbLocalDatabaseLibraryFactory::CreateLibrary(nsIPropertyBag2* aCreationParameters,
196 NS_ENSURE_ARG_POINTER(aCreationParameters);
197 NS_ENSURE_ARG_POINTER(_retval);
199 nsCOMPtr<nsILocalFile>
file;
202 NS_GET_IID(nsILocalFile),
203 getter_AddRefs(file));
205 NS_WARNING(
"You passed in a property bag with the wrong data!");
208 NS_ENSURE_TRUE(file, NS_ERROR_FAILURE);
211 NS_ENSURE_SUCCESS(rv, rv);
215 NS_ENSURE_SUCCESS(rv, rv);
219 NS_ENSURE_SUCCESS(rv, rv);
227 nsIPropertyBag2* aCreationParameters,
228 nsString aResourceGUID )
230 NS_ENSURE_ARG_POINTER(aDatabase);
231 NS_ENSURE_ARG_POINTER(_retval);
236 nsCOMPtr<nsIHashable> hashable = do_QueryInterface(aDatabase, &rv);
237 NS_ENSURE_SUCCESS(rv, rv);
241 nsCOMPtr<nsIIOService>
ioService = do_GetIOService(&rv);
242 NS_ENSURE_SUCCESS(rv, rv);
244 nsCOMPtr<nsIURI> databaseURI;
245 rv = NS_NewFileURI(getter_AddRefs(databaseURI), aDatabase, ioService);
246 NS_ENSURE_SUCCESS(rv, rv);
248 nsCOMPtr<nsIURL> databaseURL = do_QueryInterface(databaseURI, &rv);
249 NS_ENSURE_SUCCESS(rv, rv);
251 nsCAutoString utf8GUID;
252 rv = databaseURL->GetFileBaseName(utf8GUID);
253 NS_ENSURE_SUCCESS(rv, rv);
255 nsCOMPtr<nsIFile> databaseParent;
256 rv = aDatabase->GetParent(getter_AddRefs(databaseParent));
257 NS_ENSURE_SUCCESS(rv, rv);
259 nsCAutoString fileName;
260 rv = databaseURL->GetFileName(fileName);
261 NS_ENSURE_SUCCESS(rv, rv);
263 nsCOMPtr<nsIFile> escapedFile;
264 rv = databaseParent->Clone(getter_AddRefs(escapedFile));
265 NS_ENSURE_SUCCESS(rv, rv);
267 rv = escapedFile->Append(NS_ConvertUTF8toUTF16(fileName));
268 NS_ENSURE_SUCCESS(rv, rv);
274 rv = escapedFile->Exists(&exists);
275 NS_ENSURE_SUCCESS(rv, rv);
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);
284 if (existingLibrary) {
285 existingLibrary.swap(*_retval);
289 mCreatedLibraries.Remove(hashable);
295 rv = InitalizeLibrary(aDatabase, aResourceGUID);
296 NS_ENSURE_SUCCESS(rv, rv);
299 rv = UpdateLibrary(aDatabase);
300 NS_ENSURE_SUCCESS(rv, rv);
303 nsCOMPtr<nsIURI> databaseLocation;
304 rv = NS_NewFileURI(getter_AddRefs(databaseLocation), databaseParent,
306 NS_ENSURE_SUCCESS(rv, rv);
309 NS_ENSURE_TRUE(library, NS_ERROR_OUT_OF_MEMORY);
311 nsCOMPtr<nsIPropertyBag2> creationParams = aCreationParameters;
312 if (!creationParams) {
313 nsCOMPtr<nsIWritablePropertyBag2> bag =
315 NS_ENSURE_SUCCESS(rv, rv);
319 NS_ENSURE_SUCCESS(rv, rv);
321 creationParams = do_QueryInterface(bag, &rv);
322 NS_ENSURE_SUCCESS(rv, rv);
325 rv = library->Init(NS_ConvertUTF8toUTF16(utf8GUID), creationParams,
this,
327 NS_ENSURE_SUCCESS(rv, rv);
330 weakRef = do_GetWeakReference(NS_ISUPPORTS_CAST(
sbILibrary*, library),
332 NS_ENSURE_SUCCESS(rv, rv);
334 PRBool success = mCreatedLibraries.Put(hashable, weakRef);
335 NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
337 NS_ADDREF(*_retval = library);
342 sbLocalDatabaseLibraryFactory::InitalizeLibrary(nsIFile* aDatabaseFile,
343 const nsAString &aResourceGUID)
348 nsCOMPtr<nsIFile> parentDirectory;
349 rv = aDatabaseFile->GetParent(getter_AddRefs(parentDirectory));
350 NS_ENSURE_SUCCESS(rv, rv);
353 rv = parentDirectory->Exists(&parentExists);
354 NS_ENSURE_SUCCESS(rv, rv);
358 NS_ENSURE_SUCCESS(rv, rv);
362 NS_ENSURE_TRUE(parentIsWritable, NS_ERROR_FILE_ACCESS_DENIED);
365 nsCOMPtr<sbIDatabaseQuery> query =
367 NS_ENSURE_SUCCESS(rv, rv);
369 rv = query->SetAsyncQuery(PR_FALSE);
370 NS_ENSURE_SUCCESS(rv, rv);
372 rv = SetQueryDatabaseFile(query, aDatabaseFile);
373 NS_ENSURE_SUCCESS(rv, rv);
375 nsCOMPtr<nsIURI> schemaURI;
376 rv = NS_NewURI(getter_AddRefs(schemaURI), NS_LITERAL_CSTRING(
SCHEMA_URL));
377 NS_ENSURE_SUCCESS(rv, rv);
379 nsCOMPtr<nsIInputStream> input;
380 rv = NS_OpenURI(getter_AddRefs(input), schemaURI);
381 NS_ENSURE_SUCCESS(rv, rv);
383 nsCOMPtr<nsIConverterInputStream> converterStream =
384 do_CreateInstance(
"@mozilla.org/intl/converter-input-stream;1", &rv);
385 NS_ENSURE_SUCCESS(rv, rv);
387 rv = converterStream->Init(input,
390 nsIConverterInputStream::
391 DEFAULT_REPLACEMENT_CHARACTER);
392 NS_ENSURE_SUCCESS(rv, rv);
394 nsCOMPtr<nsIUnicharInputStream> unichar =
395 do_QueryInterface(converterStream, &rv);
396 NS_ENSURE_SUCCESS(rv, rv);
399 nsString response, result;
401 NS_ENSURE_SUCCESS(rv, rv);
402 NS_ASSERTION(read,
"Schema file zero bytes?");
404 response.Append(result);
406 NS_ENSURE_SUCCESS(rv, rv);
409 rv = unichar->Close();
410 NS_ENSURE_SUCCESS(rv, rv);
412 NS_NAMED_LITERAL_STRING(colonNewline,
";\n");
413 PRInt32 posStart = 0;
414 PRInt32 posEnd = response.Find(colonNewline, posStart);
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);
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);
439 rv = query->Execute(&dbOk);
440 NS_ENSURE_SUCCESS(rv, rv);
441 NS_ENSURE_TRUE(dbOk == 0, NS_ERROR_FAILURE);
443 nsString guid(aResourceGUID);
446 nsCOMPtr<nsIUUIDGenerator> uuidGen =
447 do_GetService(
"@mozilla.org/uuid-generator;1", &rv);
448 NS_ENSURE_SUCCESS(rv, rv);
451 rv = uuidGen->GenerateUUIDInPlace(&
id);
452 NS_ENSURE_SUCCESS(rv, rv);
454 char guidChars[NSID_LENGTH];
455 id.ToProvidedString(guidChars);
457 guid = NS_ConvertASCIItoUTF16(nsDependentCString(guidChars + 1,
462 nsCOMPtr<sbISQLInsertBuilder>
insert =
464 NS_ENSURE_SUCCESS(rv, rv);
466 rv = insert->SetIntoTableName(NS_LITERAL_STRING(
"library_metadata"));
467 NS_ENSURE_SUCCESS(rv, rv);
469 rv = insert->AddColumn(NS_LITERAL_STRING(
"name"));
470 NS_ENSURE_SUCCESS(rv, rv);
472 rv = insert->AddColumn(NS_LITERAL_STRING(
"value"));
473 NS_ENSURE_SUCCESS(rv, rv);
475 rv = insert->AddValueString(NS_LITERAL_STRING(
"resource-guid"));
476 NS_ENSURE_SUCCESS(rv, rv);
478 rv = insert->AddValueString(guid);
479 NS_ENSURE_SUCCESS(rv, rv);
482 rv = insert->ToString(sql);
483 NS_ENSURE_SUCCESS(rv, rv);
485 rv = query->ResetQuery();
486 NS_ENSURE_SUCCESS(rv, rv);
488 rv = query->AddQuery(sql);
489 NS_ENSURE_SUCCESS(rv, rv);
491 rv = query->Execute(&dbOk);
492 NS_ENSURE_SUCCESS(rv, rv);
493 NS_ENSURE_TRUE(dbOk == 0, NS_ERROR_FAILURE);
498 nsCOMPtr<nsIURI> fileURI;
499 rv = NS_NewFileURI(getter_AddRefs(fileURI), aDatabaseFile);
500 NS_ENSURE_SUCCESS(rv, rv);
503 rv = fileURI->GetSpec(uriSpec);
504 NS_ENSURE_SUCCESS(rv, rv);
508 NS_ENSURE_SUCCESS(rv, rv);
510 rv = insert->SetIntoTableName(NS_LITERAL_STRING(
"library_media_item"));
511 NS_ENSURE_SUCCESS(rv, rv);
513 rv = insert->AddColumn(NS_LITERAL_STRING(
"guid"));
514 NS_ENSURE_SUCCESS(rv, rv);
516 rv = insert->AddValueString(guid);
517 NS_ENSURE_SUCCESS(rv, rv);
519 rv = insert->AddColumn(NS_LITERAL_STRING(
"created"));
520 NS_ENSURE_SUCCESS(rv, rv);
522 rv = insert->AddValueString(now);
523 NS_ENSURE_SUCCESS(rv, rv);
525 rv = insert->AddColumn(NS_LITERAL_STRING(
"updated"));
526 NS_ENSURE_SUCCESS(rv, rv);
528 rv = insert->AddValueString(now);
529 NS_ENSURE_SUCCESS(rv, rv);
531 rv = insert->AddColumn(NS_LITERAL_STRING(
"content_url"));
532 NS_ENSURE_SUCCESS(rv, rv);
534 rv = insert->AddValueString(NS_ConvertUTF8toUTF16(uriSpec));
535 NS_ENSURE_SUCCESS(rv, rv);
537 rv = insert->AddColumn(NS_LITERAL_STRING(
"hidden"));
538 NS_ENSURE_SUCCESS(rv, rv);
540 rv = insert->AddValueLong(0);
541 NS_ENSURE_SUCCESS(rv, rv);
543 rv = insert->AddColumn(NS_LITERAL_STRING(
"is_list"));
544 NS_ENSURE_SUCCESS(rv, rv);
546 rv = insert->AddValueLong(0);
547 NS_ENSURE_SUCCESS(rv, rv);
549 rv = insert->ToString(sql);
550 NS_ENSURE_SUCCESS(rv, rv);
552 rv = query->ResetQuery();
553 NS_ENSURE_SUCCESS(rv, rv);
555 rv = query->AddQuery(sql);
556 NS_ENSURE_SUCCESS(rv, rv);
558 rv = query->Execute(&dbOk);
559 NS_ENSURE_SUCCESS(rv, rv);
560 NS_ENSURE_TRUE(dbOk == 0, NS_ERROR_FAILURE);
566 sbLocalDatabaseLibraryFactory::UpdateLibrary(nsIFile* aDatabaseFile)
571 nsCOMPtr<sbIDatabaseQuery> query =
573 NS_ENSURE_SUCCESS(rv, rv);
575 rv = query->SetAsyncQuery(PR_FALSE);
576 NS_ENSURE_SUCCESS(rv, rv);
578 rv = SetQueryDatabaseFile(query, aDatabaseFile);
579 NS_ENSURE_SUCCESS(rv, rv);
582 nsCOMPtr<sbISQLUpdateBuilder> update =
584 NS_ENSURE_SUCCESS(rv, rv);
586 rv = update->SetTableName(NS_LITERAL_STRING(
"library_media_item"));
587 NS_ENSURE_SUCCESS(rv, rv);
589 nsCOMPtr<nsIURI> fileURI;
590 rv = NS_NewFileURI(getter_AddRefs(fileURI), aDatabaseFile);
591 NS_ENSURE_SUCCESS(rv, rv);
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);
601 rv = update->ToString(sql);
602 NS_ENSURE_SUCCESS(rv, rv);
604 rv = query->AddQuery(sql);
605 NS_ENSURE_SUCCESS(rv, rv);
607 rv = query->Execute(&dbOk);
608 NS_ENSURE_SUCCESS(rv, rv);
609 NS_ENSURE_TRUE(dbOk == 0, NS_ERROR_FAILURE);
614 already_AddRefed<nsILocalFile>
618 NS_ENSURE_TRUE(file, nsnull);
620 nsAutoString filename(aGUID);
621 filename.AppendLiteral(
".db");
623 nsresult rv = file->AppendRelativePath(filename);
624 NS_ENSURE_SUCCESS(rv, nsnull);
626 nsILocalFile* _retval;
627 NS_ADDREF(_retval = file);
636 nsAutoString filename;
637 nsresult rv = aFile->GetLeafName(filename);
638 NS_ENSURE_SUCCESS(rv,);
640 aGUID.Assign(StringHead(filename, filename.Length() - 3));
644 sbLocalDatabaseLibraryFactory::SetQueryDatabaseFile
646 nsIFile* aDatabaseFile)
648 NS_ENSURE_ARG_POINTER(aQuery);
649 NS_ENSURE_ARG_POINTER(aDatabaseFile);
653 nsCOMPtr<nsIIOService>
ioService = do_GetIOService(&rv);
654 NS_ENSURE_SUCCESS(rv, rv);
659 nsCOMPtr<nsIURI> fileURI;
660 rv = NS_NewFileURI(getter_AddRefs(fileURI), aDatabaseFile, ioService);
661 NS_ENSURE_SUCCESS(rv, rv);
663 nsCOMPtr<nsIURL> fileURL = do_QueryInterface(fileURI, &rv);
664 NS_ENSURE_SUCCESS(rv, rv);
666 nsCAutoString fileBaseName;
667 rv = fileURL->GetFileBaseName(fileBaseName);
668 NS_ENSURE_SUCCESS(rv, rv);
670 rv = aQuery->SetDatabaseGUID(NS_ConvertUTF8toUTF16(fileBaseName));
671 NS_ENSURE_SUCCESS(rv, rv);
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.");
685 nsCOMPtr<nsIFile> parentDirectory;
686 rv = aDatabaseFile->GetParent(getter_AddRefs(parentDirectory));
687 NS_ENSURE_SUCCESS(rv, rv);
689 nsCOMPtr<nsIURI> parentURI;
690 rv = NS_NewFileURI(getter_AddRefs(parentURI), parentDirectory, ioService);
691 NS_ENSURE_SUCCESS(rv, rv);
693 rv = aQuery->SetDatabaseLocation(parentURI);
694 NS_ENSURE_SUCCESS(rv, rv);
#define SONGBIRD_DATABASEQUERY_CONTRACTID
#define SB_SQLBUILDER_UPDATE_CONTRACTID
NS_IMPL_ISUPPORTS1(sbDeviceCapabilitiesUtils, sbIDeviceCapabilitiesUtils) sbDeviceCapabilitiesUtils
void GetGUIDFromFile(nsILocalFile *aFile, nsAString &aGUID)
Factory for new library instances.
#define PROPERTY_KEY_DATABASEFILE
#define SB_SQLBUILDER_INSERT_CONTRACTID
#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.
#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())
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)
Songbird Database Object Definition.