Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit 78980f3

Browse files
committed
Bug 661877 - Enable storing files in IndexedDB. r=bent
1 parent f6866f0 commit 78980f3

56 files changed

Lines changed: 5410 additions & 536 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

browser/base/content/pageinfo/permissions.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ function onIndexedDBClear()
226226
initIndexedDBRow();
227227
}
228228

229-
function onIndexedDBUsageCallback(uri, usage)
229+
function onIndexedDBUsageCallback(uri, usage, fileUsage)
230230
{
231231
if (!uri.equals(gPermURI)) {
232232
throw new Error("Callback received for bad URI: " + uri);

content/base/public/nsDOMFile.h

Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@
5353
#include "nsIXMLHttpRequest.h"
5454
#include "prmem.h"
5555
#include "nsAutoPtr.h"
56+
#include "mozilla/dom/indexedDB/FileInfo.h"
57+
#include "mozilla/dom/indexedDB/FileManager.h"
58+
#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
5659

5760
#include "mozilla/GuardObjects.h"
5861

@@ -67,12 +70,13 @@ class nsIBlobBuilder;
6770

6871
nsresult NS_NewBlobBuilder(nsISupports* *aSupports);
6972

73+
using namespace mozilla::dom;
74+
7075
class nsDOMFileBase : public nsIDOMFile,
7176
public nsIXHRSendable,
7277
public nsIMutable
7378
{
7479
public:
75-
7680
nsDOMFileBase(const nsAString& aName, const nsAString& aContentType,
7781
PRUint64 aLength)
7882
: mIsFile(true), mImmutable(false), mContentType(aContentType),
@@ -119,13 +123,31 @@ class nsDOMFileBase : public nsIDOMFile,
119123
return mLength == PR_UINT64_MAX;
120124
}
121125

126+
virtual bool IsStoredFile()
127+
{
128+
return false;
129+
}
130+
131+
virtual bool IsWholeFile()
132+
{
133+
NS_NOTREACHED("Should only be called on dom blobs backed by files!");
134+
return false;
135+
}
136+
137+
indexedDB::FileInfo*
138+
GetFileInfoInternal(indexedDB::FileManager* aFileManager,
139+
PRUint32 aStartIndex);
140+
122141
bool mIsFile;
123142
bool mImmutable;
124143
nsString mContentType;
125144
nsString mName;
126145

127146
PRUint64 mStart;
128147
PRUint64 mLength;
148+
149+
// Protected by IndexedDatabaseManager::FileMutex()
150+
nsTArray<nsRefPtr<indexedDB::FileInfo> > mFileInfos;
129151
};
130152

131153
class nsDOMFileFile : public nsDOMFileBase,
@@ -135,7 +157,7 @@ class nsDOMFileFile : public nsDOMFileBase,
135157
// Create as a file
136158
nsDOMFileFile(nsIFile *aFile)
137159
: nsDOMFileBase(EmptyString(), EmptyString(), PR_UINT64_MAX),
138-
mFile(aFile), mWholeFile(true)
160+
mFile(aFile), mWholeFile(true), mStoredFile(false)
139161
{
140162
NS_ASSERTION(mFile, "must have file");
141163
// Lazily get the content type and size
@@ -147,16 +169,37 @@ class nsDOMFileFile : public nsDOMFileBase,
147169
nsDOMFileFile(nsIFile *aFile, const nsAString& aContentType,
148170
nsISupports *aCacheToken = nsnull)
149171
: nsDOMFileBase(aContentType, PR_UINT64_MAX),
150-
mFile(aFile), mWholeFile(true),
172+
mFile(aFile), mWholeFile(true), mStoredFile(false),
151173
mCacheToken(aCacheToken)
152174
{
153175
NS_ASSERTION(mFile, "must have file");
154176
}
155177

178+
// Create as a stored file
179+
nsDOMFileFile(const nsAString& aName, const nsAString& aContentType,
180+
PRUint64 aLength, nsIFile* aFile,
181+
indexedDB::FileInfo* aFileInfo)
182+
: nsDOMFileBase(aName, aContentType, aLength),
183+
mFile(aFile), mWholeFile(true), mStoredFile(true)
184+
{
185+
NS_ASSERTION(mFile, "must have file");
186+
mFileInfos.AppendElement(aFileInfo);
187+
}
188+
189+
// Create as a stored blob
190+
nsDOMFileFile(const nsAString& aContentType, PRUint64 aLength,
191+
nsIFile* aFile, indexedDB::FileInfo* aFileInfo)
192+
: nsDOMFileBase(aContentType, aLength),
193+
mFile(aFile), mWholeFile(true), mStoredFile(true)
194+
{
195+
NS_ASSERTION(mFile, "must have file");
196+
mFileInfos.AppendElement(aFileInfo);
197+
}
198+
156199
// Create as a file to be later initialized
157200
nsDOMFileFile()
158201
: nsDOMFileBase(EmptyString(), EmptyString(), PR_UINT64_MAX),
159-
mWholeFile(true)
202+
mWholeFile(true), mStoredFile(false)
160203
{
161204
// Lazily get the content type and size
162205
mContentType.SetIsVoid(true);
@@ -188,17 +231,47 @@ class nsDOMFileFile : public nsDOMFileBase,
188231
const nsAString& aContentType)
189232
: nsDOMFileBase(aContentType, aOther->mStart + aStart, aLength),
190233
mFile(aOther->mFile), mWholeFile(false),
191-
mCacheToken(aOther->mCacheToken)
234+
mStoredFile(aOther->mStoredFile), mCacheToken(aOther->mCacheToken)
192235
{
193236
NS_ASSERTION(mFile, "must have file");
194237
mImmutable = aOther->mImmutable;
238+
239+
if (mStoredFile) {
240+
indexedDB::FileInfo* fileInfo;
241+
242+
if (!indexedDB::IndexedDatabaseManager::IsClosed()) {
243+
indexedDB::IndexedDatabaseManager::FileMutex().Lock();
244+
}
245+
246+
NS_ASSERTION(!aOther->mFileInfos.IsEmpty(),
247+
"A stored file must have at least one file info!");
248+
249+
fileInfo = aOther->mFileInfos.ElementAt(0);
250+
251+
if (!indexedDB::IndexedDatabaseManager::IsClosed()) {
252+
indexedDB::IndexedDatabaseManager::FileMutex().Unlock();
253+
}
254+
255+
mFileInfos.AppendElement(fileInfo);
256+
}
195257
}
196258
virtual already_AddRefed<nsIDOMBlob>
197259
CreateSlice(PRUint64 aStart, PRUint64 aLength,
198260
const nsAString& aContentType);
199261

262+
virtual bool IsStoredFile()
263+
{
264+
return mStoredFile;
265+
}
266+
267+
virtual bool IsWholeFile()
268+
{
269+
return mWholeFile;
270+
}
271+
200272
nsCOMPtr<nsIFile> mFile;
201273
bool mWholeFile;
274+
bool mStoredFile;
202275
nsCOMPtr<nsISupports> mCacheToken;
203276
};
204277

content/base/public/nsIDOMFile.idl

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,28 @@
3939

4040
%{C++
4141
#include "jsapi.h"
42+
43+
namespace mozilla {
44+
namespace dom {
45+
namespace indexedDB {
46+
class FileInfo;
47+
class FileManager;
48+
}
49+
}
50+
}
51+
4252
%}
4353

54+
[ptr] native FileInfo(mozilla::dom::indexedDB::FileInfo);
55+
[ptr] native FileManager(mozilla::dom::indexedDB::FileManager);
56+
4457
interface nsIDOMFileError;
4558
interface nsIInputStream;
4659
interface nsIURI;
4760
interface nsIPrincipal;
4861
interface nsIDOMBlob;
4962

50-
[scriptable, builtinclass, uuid(d5237f31-443a-460b-9e42-449a135346f0)]
63+
[scriptable, builtinclass, uuid(f62c6887-e3bc-495a-802c-287e12e969a0)]
5164
interface nsIDOMBlob : nsISupports
5265
{
5366
readonly attribute unsigned long long size;
@@ -61,6 +74,18 @@ interface nsIDOMBlob : nsISupports
6174
[optional_argc] nsIDOMBlob mozSlice([optional] in long long start,
6275
[optional] in long long end,
6376
[optional] in DOMString contentType);
77+
78+
// Get internal id of stored file. Returns -1 if it is not a stored file.
79+
// Intended only for testing. It can be called on any thread.
80+
[notxpcom] long long getFileId();
81+
82+
// Called when the blob was successfully stored in a database or when
83+
// the blob is initialized from a database. It can be called on any thread.
84+
[notxpcom] void addFileInfo(in FileInfo aFileInfo);
85+
86+
// Called before the blob is stored in a database to decide if it can be
87+
// shared or needs to be copied. It can be called on any thread.
88+
[notxpcom] FileInfo getFileInfo(in FileManager aFileManager);
6489
};
6590

6691
[scriptable, builtinclass, uuid(b096ef67-7b77-47f8-8e70-5d8ee36416bf)]

content/base/src/nsDOMFile.cpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,76 @@ nsDOMFileBase::GetInternalUrl(nsIPrincipal* aPrincipal, nsAString& aURL)
298298
return NS_OK;
299299
}
300300

301+
NS_IMETHODIMP_(PRInt64)
302+
nsDOMFileBase::GetFileId()
303+
{
304+
PRInt64 id = -1;
305+
306+
if (IsStoredFile() && IsWholeFile()) {
307+
if (!indexedDB::IndexedDatabaseManager::IsClosed()) {
308+
indexedDB::IndexedDatabaseManager::FileMutex().Lock();
309+
}
310+
311+
NS_ASSERTION(!mFileInfos.IsEmpty(),
312+
"A stored file must have at least one file info!");
313+
314+
nsRefPtr<indexedDB::FileInfo>& fileInfo = mFileInfos.ElementAt(0);
315+
if (fileInfo) {
316+
id = fileInfo->Id();
317+
}
318+
319+
if (!indexedDB::IndexedDatabaseManager::IsClosed()) {
320+
indexedDB::IndexedDatabaseManager::FileMutex().Unlock();
321+
}
322+
}
323+
324+
return id;
325+
}
326+
327+
NS_IMETHODIMP_(void)
328+
nsDOMFileBase::AddFileInfo(indexedDB::FileInfo* aFileInfo)
329+
{
330+
if (indexedDB::IndexedDatabaseManager::IsClosed()) {
331+
NS_ERROR("Shouldn't be called after shutdown!");
332+
return;
333+
}
334+
335+
nsRefPtr<indexedDB::FileInfo> fileInfo = aFileInfo;
336+
337+
MutexAutoLock lock(indexedDB::IndexedDatabaseManager::FileMutex());
338+
339+
NS_ASSERTION(!mFileInfos.Contains(aFileInfo),
340+
"Adding the same file info agan?!");
341+
342+
nsRefPtr<indexedDB::FileInfo>* element = mFileInfos.AppendElement();
343+
element->swap(fileInfo);
344+
}
345+
346+
NS_IMETHODIMP_(indexedDB::FileInfo*)
347+
nsDOMFileBase::GetFileInfo(indexedDB::FileManager* aFileManager)
348+
{
349+
if (indexedDB::IndexedDatabaseManager::IsClosed()) {
350+
NS_ERROR("Shouldn't be called after shutdown!");
351+
return nsnull;
352+
}
353+
354+
// A slice created from a stored file must keep the file info alive.
355+
// However, we don't support sharing of slices yet, so the slice must be
356+
// copied again. That's why we have to ignore the first file info.
357+
PRUint32 startIndex = IsStoredFile() && !IsWholeFile() ? 1 : 0;
358+
359+
MutexAutoLock lock(indexedDB::IndexedDatabaseManager::FileMutex());
360+
361+
for (PRUint32 i = startIndex; i < mFileInfos.Length(); i++) {
362+
nsRefPtr<indexedDB::FileInfo>& fileInfo = mFileInfos.ElementAt(i);
363+
if (fileInfo->Manager() == aFileManager) {
364+
return fileInfo;
365+
}
366+
}
367+
368+
return nsnull;
369+
}
370+
301371
NS_IMETHODIMP
302372
nsDOMFileBase::GetSendInfo(nsIInputStream** aBody,
303373
nsACString& aContentType,

db/sqlite3/README.MOZILLA

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ To move to a new version:
1111

1212
Simply copy the sqlite3.h and sqlite3.c files from the amalgamation of sqlite.
1313

14-
Also copy test_quota.c from the full source package.
14+
Also copy test_quota.h and test_quota.c from the full source package.
1515

1616
Be sure to update SQLITE_VERSION accordingly in $(topsrcdir)/configure.in as
1717
well as the version number at the top of this file.

db/sqlite3/src/sqlite.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ EXPORTS
181181
sqlite3_vfs_unregister
182182
sqlite3_vfs_register
183183
sqlite3_vmprintf
184+
sqlite3_win32_utf8_to_mbcs
184185
#ifdef SQLITE_DEBUG
185186
sqlite3_mutex_held
186187
sqlite3_mutex_notheld

0 commit comments

Comments
 (0)