LCOV - code coverage report
Current view: directory - dom/indexedDB - FileManager.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 128 56 43.8 %
Date: 2012-06-02 Functions: 8 4 50.0 %

       1                 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* vim: set ts=2 et sw=2 tw=80: */
       3                 : /* ***** BEGIN LICENSE BLOCK *****
       4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       5                 :  *
       6                 :  * The contents of this file are subject to the Mozilla Public License Version
       7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       8                 :  * the License. You may obtain a copy of the License at
       9                 :  * http://www.mozilla.org/MPL/
      10                 :  *
      11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      13                 :  * for the specific language governing rights and limitations under the
      14                 :  * License.
      15                 :  *
      16                 :  * The Original Code is Indexed Database.
      17                 :  *
      18                 :  * The Initial Developer of the Original Code is
      19                 :  * The Mozilla Foundation.
      20                 :  * Portions created by the Initial Developer are Copyright (C) 2011
      21                 :  * the Initial Developer. All Rights Reserved.
      22                 :  *
      23                 :  * Contributor(s):
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      27                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : #include "FileManager.h"
      40                 : 
      41                 : #include "mozIStorageConnection.h"
      42                 : #include "mozIStorageServiceQuotaManagement.h"
      43                 : #include "mozIStorageStatement.h"
      44                 : #include "nsISimpleEnumerator.h"
      45                 : 
      46                 : #include "mozStorageCID.h"
      47                 : #include "mozStorageHelper.h"
      48                 : #include "nsContentUtils.h"
      49                 : 
      50                 : #include "FileInfo.h"
      51                 : #include "IndexedDatabaseManager.h"
      52                 : 
      53                 : USING_INDEXEDDB_NAMESPACE
      54                 : 
      55                 : namespace {
      56                 : 
      57                 : PLDHashOperator
      58               0 : EnumerateToTArray(const PRUint64& aKey,
      59                 :                   FileInfo* aValue,
      60                 :                   void* aUserArg)
      61                 : {
      62               0 :   NS_ASSERTION(aValue, "Null pointer!");
      63               0 :   NS_ASSERTION(aUserArg, "Null pointer!");
      64                 : 
      65                 :   nsTArray<FileInfo*>* array =
      66               0 :     static_cast<nsTArray<FileInfo*>*>(aUserArg);
      67                 : 
      68               0 :   array->AppendElement(aValue);
      69                 : 
      70               0 :   return PL_DHASH_NEXT;
      71                 : }
      72                 : 
      73                 : } // anonymous namespace
      74                 : 
      75                 : nsresult
      76              52 : FileManager::Init(nsIFile* aDirectory,
      77                 :                   mozIStorageConnection* aConnection)
      78                 : {
      79              52 :   NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
      80                 : 
      81              52 :   NS_ENSURE_TRUE(mFileInfos.Init(), NS_ERROR_OUT_OF_MEMORY);
      82                 : 
      83                 :   bool exists;
      84              52 :   nsresult rv = aDirectory->Exists(&exists);
      85              52 :   NS_ENSURE_SUCCESS(rv, rv);
      86                 : 
      87              52 :   if (exists) {
      88                 :     bool isDirectory;
      89               0 :     rv = aDirectory->IsDirectory(&isDirectory);
      90               0 :     NS_ENSURE_SUCCESS(rv, rv);
      91               0 :     NS_ENSURE_TRUE(isDirectory, NS_ERROR_FAILURE);
      92                 :   }
      93                 :   else {
      94              52 :     rv = aDirectory->Create(nsIFile::DIRECTORY_TYPE, 0755);
      95              52 :     NS_ENSURE_SUCCESS(rv, rv);
      96                 :   }
      97                 : 
      98             104 :   mozStorageTransaction transaction(aConnection, false);
      99                 : 
     100              52 :   rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
     101                 :     "CREATE VIRTUAL TABLE fs USING filesystem;"
     102              52 :   ));
     103              52 :   NS_ENSURE_SUCCESS(rv, rv);
     104                 : 
     105             104 :   nsCOMPtr<mozIStorageStatement> stmt;
     106              52 :   rv = aConnection->CreateStatement(NS_LITERAL_CSTRING(
     107                 :     "SELECT name, (name IN (SELECT id FROM file)) FROM fs "
     108                 :     "WHERE path = :path"
     109             104 :   ), getter_AddRefs(stmt));
     110              52 :   NS_ENSURE_SUCCESS(rv, rv);
     111                 : 
     112             104 :   nsString path;
     113              52 :   rv = aDirectory->GetPath(path);
     114              52 :   NS_ENSURE_SUCCESS(rv, rv);
     115                 : 
     116              52 :   rv = stmt->BindStringByName(NS_LITERAL_CSTRING("path"), path);
     117              52 :   NS_ENSURE_SUCCESS(rv, rv);
     118                 : 
     119                 :   nsCOMPtr<mozIStorageServiceQuotaManagement> ss =
     120             104 :     do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID);
     121              52 :   NS_ENSURE_TRUE(ss, NS_ERROR_FAILURE);
     122                 : 
     123                 :   bool hasResult;
     124             104 :   while (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
     125               0 :     nsString name;
     126               0 :     rv = stmt->GetString(0, name);
     127               0 :     NS_ENSURE_SUCCESS(rv, rv);
     128                 : 
     129               0 :     PRInt32 flag = stmt->AsInt32(1);
     130                 : 
     131               0 :     nsCOMPtr<nsIFile> file;
     132               0 :     rv = aDirectory->Clone(getter_AddRefs(file));
     133               0 :     NS_ENSURE_SUCCESS(rv, rv);
     134                 : 
     135               0 :     rv = file->Append(name);
     136               0 :     NS_ENSURE_SUCCESS(rv, rv);
     137                 : 
     138               0 :     if (flag) {
     139               0 :       rv = ss->UpdateQuotaInformationForFile(file);
     140               0 :       NS_ENSURE_SUCCESS(rv, rv);
     141                 :     }
     142                 :     else {
     143               0 :       rv = file->Remove(false);
     144               0 :       if (NS_FAILED(rv)) {
     145               0 :         NS_WARNING("Failed to remove orphaned file!");
     146                 :       }
     147                 :     }
     148                 :   }
     149                 : 
     150              52 :   rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
     151                 :     "DROP TABLE fs;"
     152              52 :   ));
     153              52 :   NS_ENSURE_SUCCESS(rv, rv);
     154                 : 
     155              52 :   rv = aDirectory->GetPath(mDirectoryPath);
     156              52 :   NS_ENSURE_SUCCESS(rv, rv);
     157                 : 
     158              52 :   transaction.Commit();
     159              52 :   return NS_OK;
     160                 : }
     161                 : 
     162                 : nsresult
     163              52 : FileManager::Load(mozIStorageConnection* aConnection)
     164                 : {
     165              52 :   NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
     166                 : 
     167             104 :   nsCOMPtr<mozIStorageStatement> stmt;
     168              52 :   nsresult rv = aConnection->CreateStatement(NS_LITERAL_CSTRING(
     169                 :     "SELECT id, refcount "
     170                 :     "FROM file"
     171             104 :   ), getter_AddRefs(stmt));
     172              52 :   NS_ENSURE_SUCCESS(rv, rv);
     173                 : 
     174                 :   bool hasResult;
     175             104 :   while (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
     176                 :     PRInt64 id;
     177               0 :     rv = stmt->GetInt64(0, &id);
     178               0 :     NS_ENSURE_SUCCESS(rv, rv);
     179                 : 
     180                 :     PRInt32 refcount;
     181               0 :     rv = stmt->GetInt32(1, &refcount);
     182               0 :     NS_ENSURE_SUCCESS(rv, rv);
     183                 : 
     184               0 :     NS_ASSERTION(refcount, "This shouldn't happen!");
     185                 : 
     186               0 :     nsRefPtr<FileInfo> fileInfo = FileInfo::Create(this, id);
     187               0 :     fileInfo->mDBRefCnt = refcount;
     188                 : 
     189               0 :     if (!mFileInfos.Put(id, fileInfo)) {
     190               0 :       NS_WARNING("Out of memory?");
     191               0 :       return NS_ERROR_OUT_OF_MEMORY;
     192                 :     }
     193                 : 
     194               0 :     mLastFileId = NS_MAX(id, mLastFileId);
     195                 :   }
     196                 : 
     197              52 :   mLoaded = true;
     198                 : 
     199              52 :   return NS_OK;
     200                 : }
     201                 : 
     202                 : nsresult
     203              52 : FileManager::Invalidate()
     204                 : {
     205              52 :   if (IndexedDatabaseManager::IsClosed()) {
     206               0 :     NS_ERROR("Shouldn't be called after shutdown!");
     207               0 :     return NS_ERROR_UNEXPECTED;
     208                 :   }
     209                 : 
     210             104 :   nsTArray<FileInfo*> fileInfos;
     211                 :   {
     212             104 :     MutexAutoLock lock(IndexedDatabaseManager::FileMutex());
     213                 : 
     214              52 :     NS_ASSERTION(!mInvalidated, "Invalidate more than once?!");
     215              52 :     mInvalidated = true;
     216                 : 
     217              52 :     fileInfos.SetCapacity(mFileInfos.Count());
     218              52 :     mFileInfos.EnumerateRead(EnumerateToTArray, &fileInfos);
     219                 :   }
     220                 : 
     221              52 :   for (PRUint32 i = 0; i < fileInfos.Length(); i++) {
     222               0 :     FileInfo* fileInfo = fileInfos.ElementAt(i);
     223               0 :     fileInfo->ClearDBRefs();
     224                 :   }
     225                 : 
     226              52 :   return NS_OK;
     227                 : }
     228                 : 
     229                 : already_AddRefed<nsIFile>
     230            1837 : FileManager::GetDirectory()
     231                 : {
     232                 :   nsCOMPtr<nsILocalFile> directory =
     233            3674 :     do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
     234            1837 :   NS_ENSURE_TRUE(directory, nsnull);
     235                 : 
     236            1837 :   nsresult rv = directory->InitWithPath(mDirectoryPath);
     237            1837 :   NS_ENSURE_SUCCESS(rv, nsnull);
     238                 : 
     239            1837 :   return directory.forget();
     240                 : }
     241                 : 
     242                 : already_AddRefed<FileInfo>
     243               0 : FileManager::GetFileInfo(PRInt64 aId)
     244                 : {
     245               0 :   if (IndexedDatabaseManager::IsClosed()) {
     246               0 :     NS_ERROR("Shouldn't be called after shutdown!");
     247               0 :     return nsnull;
     248                 :   }
     249                 : 
     250               0 :   FileInfo* fileInfo = nsnull;
     251                 :   {
     252               0 :     MutexAutoLock lock(IndexedDatabaseManager::FileMutex());
     253               0 :     fileInfo = mFileInfos.Get(aId);
     254                 :   }
     255               0 :   nsRefPtr<FileInfo> result = fileInfo;
     256               0 :   return result.forget();
     257                 : }
     258                 : 
     259                 : already_AddRefed<FileInfo>
     260               0 : FileManager::GetNewFileInfo()
     261                 : {
     262               0 :   if (IndexedDatabaseManager::IsClosed()) {
     263               0 :     NS_ERROR("Shouldn't be called after shutdown!");
     264               0 :     return nsnull;
     265                 :   }
     266                 : 
     267               0 :   nsAutoPtr<FileInfo> fileInfo;
     268                 : 
     269                 :   {
     270               0 :     MutexAutoLock lock(IndexedDatabaseManager::FileMutex());
     271                 : 
     272               0 :     PRInt64 id = mLastFileId + 1;
     273                 : 
     274               0 :     fileInfo = FileInfo::Create(this, id);
     275                 : 
     276               0 :     if (!mFileInfos.Put(id, fileInfo)) {
     277               0 :       NS_WARNING("Out of memory?");
     278               0 :       return nsnull;
     279                 :     }
     280                 : 
     281               0 :     mLastFileId = id;
     282                 :   }
     283                 : 
     284               0 :   nsRefPtr<FileInfo> result = fileInfo.forget();
     285               0 :   return result.forget();
     286                 : }
     287                 : 
     288                 : already_AddRefed<nsIFile>
     289               0 : FileManager::GetFileForId(nsIFile* aDirectory, PRInt64 aId)
     290                 : {
     291               0 :   NS_ASSERTION(aDirectory, "Null pointer!");
     292                 : 
     293               0 :   nsAutoString id;
     294               0 :   id.AppendInt(aId);
     295                 : 
     296               0 :   nsCOMPtr<nsIFile> file;
     297               0 :   nsresult rv = aDirectory->Clone(getter_AddRefs(file));
     298               0 :   NS_ENSURE_SUCCESS(rv, nsnull);
     299                 : 
     300               0 :   rv = file->Append(id);
     301               0 :   NS_ENSURE_SUCCESS(rv, nsnull);
     302                 : 
     303               0 :   return file.forget();
     304                 : }

Generated by: LCOV version 1.7