зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-i to m-c, a=merge
This commit is contained in:
Коммит
713c41b609
2
CLOBBER
2
CLOBBER
|
@ -22,4 +22,4 @@
|
||||||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||||
# don't change CLOBBER for WebIDL changes any more.
|
# don't change CLOBBER for WebIDL changes any more.
|
||||||
|
|
||||||
Bug 1061489: Updated moz.build requires CLOBBER
|
Bug 1047076: at least Windows needed a clobber for some unknown reason
|
||||||
|
|
|
@ -2253,6 +2253,15 @@ let E10SUINotification = {
|
||||||
CURRENT_NOTICE_COUNT: 0,
|
CURRENT_NOTICE_COUNT: 0,
|
||||||
|
|
||||||
checkStatus: function() {
|
checkStatus: function() {
|
||||||
|
let skipE10sChecks = false;
|
||||||
|
try {
|
||||||
|
skipE10sChecks = Services.prefs.getBoolPref("browser.tabs.remote.autostart.disabled-because-using-a11y");
|
||||||
|
} catch(e) {}
|
||||||
|
|
||||||
|
if (skipE10sChecks) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (Services.appinfo.browserTabsRemoteAutostart) {
|
if (Services.appinfo.browserTabsRemoteAutostart) {
|
||||||
let notice = 0;
|
let notice = 0;
|
||||||
try {
|
try {
|
||||||
|
@ -2263,13 +2272,22 @@ let E10SUINotification = {
|
||||||
if (!activationNoticeShown) {
|
if (!activationNoticeShown) {
|
||||||
this._showE10sActivatedNotice();
|
this._showE10sActivatedNotice();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// e10s doesn't work with accessibility, so we prompt to disable
|
||||||
|
// e10s if a11y is enabled, now or in the future.
|
||||||
|
Services.obs.addObserver(this, "a11y-init-or-shutdown", true);
|
||||||
|
if (Services.appinfo.accessibilityEnabled) {
|
||||||
|
this._showE10sAccessibilityWarning();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let e10sPromptShownCount = 0;
|
let e10sPromptShownCount = 0;
|
||||||
try {
|
try {
|
||||||
e10sPromptShownCount = Services.prefs.getIntPref("browser.displayedE10SPrompt");
|
e10sPromptShownCount = Services.prefs.getIntPref("browser.displayedE10SPrompt");
|
||||||
} catch(e) {}
|
} catch(e) {}
|
||||||
|
|
||||||
if (!Services.appinfo.inSafeMode && e10sPromptShownCount < 5) {
|
if (!Services.appinfo.inSafeMode &&
|
||||||
|
!Services.appinfo.accessibilityEnabled &&
|
||||||
|
e10sPromptShownCount < 5) {
|
||||||
Services.tm.mainThread.dispatch(() => {
|
Services.tm.mainThread.dispatch(() => {
|
||||||
try {
|
try {
|
||||||
this._showE10SPrompt();
|
this._showE10SPrompt();
|
||||||
|
@ -2282,6 +2300,14 @@ let E10SUINotification = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
|
||||||
|
|
||||||
|
observe: function(subject, topic, data) {
|
||||||
|
if (topic == "a11y-init-or-shutdown" && data == "1") {
|
||||||
|
this._showE10sAccessibilityWarning();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_showE10sActivatedNotice: function() {
|
_showE10sActivatedNotice: function() {
|
||||||
let win = RecentWindow.getMostRecentBrowserWindow();
|
let win = RecentWindow.getMostRecentBrowserWindow();
|
||||||
if (!win)
|
if (!win)
|
||||||
|
@ -2344,6 +2370,56 @@ let E10SUINotification = {
|
||||||
|
|
||||||
win.PopupNotifications.show(browser, "enable_e10s", promptMessage, null, mainAction, secondaryActions, options);
|
win.PopupNotifications.show(browser, "enable_e10s", promptMessage, null, mainAction, secondaryActions, options);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_warnedAboutAccessibility: false,
|
||||||
|
|
||||||
|
_showE10sAccessibilityWarning: function() {
|
||||||
|
Services.prefs.setBoolPref("browser.tabs.remote.autostart.disabled-because-using-a11y", true);
|
||||||
|
|
||||||
|
if (this._warnedAboutAccessibility) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._warnedAboutAccessibility = true;
|
||||||
|
|
||||||
|
let win = RecentWindow.getMostRecentBrowserWindow();
|
||||||
|
if (!win) {
|
||||||
|
// Just restart immediately.
|
||||||
|
Services.startup.quit(Services.startup.eAttemptQuit | Services.startup.eRestart);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let browser = win.gBrowser.selectedBrowser;
|
||||||
|
|
||||||
|
let promptMessage = "Multiprocess Nightly (e10s) does not yet support accessibility features. Multiprocessing will be disabled if you restart Firefox. Would you like to restart?";
|
||||||
|
let mainAction = {
|
||||||
|
label: "Disable and Restart",
|
||||||
|
accessKey: "R",
|
||||||
|
callback: function () {
|
||||||
|
// Restart the app
|
||||||
|
let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool);
|
||||||
|
Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart");
|
||||||
|
if (cancelQuit.data)
|
||||||
|
return; // somebody canceled our quit request
|
||||||
|
Services.startup.quit(Services.startup.eAttemptQuit | Services.startup.eRestart);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let secondaryActions = [
|
||||||
|
{
|
||||||
|
label: "Don't Disable",
|
||||||
|
accessKey: "D",
|
||||||
|
callback: function () {
|
||||||
|
Services.prefs.setBoolPref("browser.tabs.remote.autostart.disabled-because-using-a11y", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
let options = {
|
||||||
|
popupIconURL: "chrome://browser/skin/e10s-64@2x.png",
|
||||||
|
learnMoreURL: "https://wiki.mozilla.org/Electrolysis",
|
||||||
|
persistWhileVisible: true
|
||||||
|
};
|
||||||
|
|
||||||
|
win.PopupNotifications.show(browser, "a11y_enabled_with_e10s", promptMessage, null, mainAction, secondaryActions, options);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ support-files =
|
||||||
file_disableScript.html
|
file_disableScript.html
|
||||||
|
|
||||||
[test_bug995943.xul]
|
[test_bug995943.xul]
|
||||||
skip-if = os == "mac" && !debug # bug 1008481
|
|
||||||
[test_disableScript.xul]
|
[test_disableScript.xul]
|
||||||
[test_principal_jarprefix_origin_appid_appstatus.html]
|
[test_principal_jarprefix_origin_appid_appstatus.html]
|
||||||
# jarPrefix test doesn't work on Windows, see bug 776296.
|
# jarPrefix test doesn't work on Windows, see bug 776296.
|
||||||
|
|
|
@ -26,10 +26,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=995943
|
||||||
/** Test for CAPS file:// URI prefs. **/
|
/** Test for CAPS file:// URI prefs. **/
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
SimpleTest.requestCompleteLog();
|
SimpleTest.requestCompleteLog();
|
||||||
|
if (Services.appinfo.OS == "Darwin") // See bug 1067022
|
||||||
|
SimpleTest.expectAssertions(0, 1);
|
||||||
|
|
||||||
var profileDir = "file://" + Cc["@mozilla.org/file/directory_service;1"]
|
var rootdir = Services.appinfo.OS == "WINNT" ? "file:///C:" : "file:///";
|
||||||
.getService(Ci.nsIProperties)
|
|
||||||
.get("ProfD", Ci.nsILocalFile).path;
|
|
||||||
|
|
||||||
function checkLoadFileURI(domain, shouldLoad) {
|
function checkLoadFileURI(domain, shouldLoad) {
|
||||||
debug("Invoking checkLoadFileURI with domain: " + domain + ", shouldLoad: " + shouldLoad);
|
debug("Invoking checkLoadFileURI with domain: " + domain + ", shouldLoad: " + shouldLoad);
|
||||||
|
@ -45,7 +45,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=995943
|
||||||
}
|
}
|
||||||
$('ifr').addEventListener('load', l2);
|
$('ifr').addEventListener('load', l2);
|
||||||
try {
|
try {
|
||||||
window[0].wrappedJSObject.location = profileDir;
|
window[0].wrappedJSObject.location = rootdir;
|
||||||
debug("Successfully navigated for " + domain);
|
debug("Successfully navigated for " + domain);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ok(!shouldLoad && /denied|insecure/.test(e),
|
ok(!shouldLoad && /denied|insecure/.test(e),
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
|
#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
|
||||||
#include "nsWrapperCache.h"
|
#include "nsWrapperCache.h"
|
||||||
#include "nsCycleCollectionParticipant.h"
|
#include "nsCycleCollectionParticipant.h"
|
||||||
|
#include "nsWeakReference.h"
|
||||||
|
|
||||||
class nsDOMMultipartFile;
|
class nsDOMMultipartFile;
|
||||||
class nsIFile;
|
class nsIFile;
|
||||||
|
@ -64,6 +65,7 @@ class DOMFile MOZ_FINAL : public nsIDOMFile
|
||||||
, public nsIXHRSendable
|
, public nsIXHRSendable
|
||||||
, public nsIMutable
|
, public nsIMutable
|
||||||
, public nsIJSNativeInitializer
|
, public nsIJSNativeInitializer
|
||||||
|
, public nsSupportsWeakReference
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_NSIDOMBLOB
|
NS_DECL_NSIDOMBLOB
|
||||||
|
@ -190,9 +192,9 @@ public:
|
||||||
virtual nsresult GetMozLastModifiedDate(uint64_t* aDate) = 0;
|
virtual nsresult GetMozLastModifiedDate(uint64_t* aDate) = 0;
|
||||||
|
|
||||||
nsresult Slice(int64_t aStart, int64_t aEnd, const nsAString& aContentType,
|
nsresult Slice(int64_t aStart, int64_t aEnd, const nsAString& aContentType,
|
||||||
uint8_t aArgc, nsIDOMBlob **aBlob);
|
uint8_t aArgc, DOMFileImpl** aBlobImpl);
|
||||||
|
|
||||||
virtual already_AddRefed<nsIDOMBlob>
|
virtual already_AddRefed<DOMFileImpl>
|
||||||
CreateSlice(uint64_t aStart, uint64_t aLength,
|
CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||||
const nsAString& aContentType) = 0;
|
const nsAString& aContentType) = 0;
|
||||||
|
|
||||||
|
@ -321,7 +323,7 @@ public:
|
||||||
|
|
||||||
virtual nsresult GetMozLastModifiedDate(uint64_t* aDate) MOZ_OVERRIDE;
|
virtual nsresult GetMozLastModifiedDate(uint64_t* aDate) MOZ_OVERRIDE;
|
||||||
|
|
||||||
virtual already_AddRefed<nsIDOMBlob>
|
virtual already_AddRefed<DOMFileImpl>
|
||||||
CreateSlice(uint64_t aStart, uint64_t aLength,
|
CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||||
const nsAString& aContentType) MOZ_OVERRIDE;
|
const nsAString& aContentType) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
@ -464,7 +466,7 @@ public:
|
||||||
|
|
||||||
virtual nsresult GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE;
|
virtual nsresult GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE;
|
||||||
|
|
||||||
virtual already_AddRefed<nsIDOMBlob>
|
virtual already_AddRefed<DOMFileImpl>
|
||||||
CreateSlice(uint64_t aStart, uint64_t aLength,
|
CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||||
const nsAString& aContentType) MOZ_OVERRIDE;
|
const nsAString& aContentType) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
@ -551,7 +553,7 @@ public:
|
||||||
|
|
||||||
virtual nsresult GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE;
|
virtual nsresult GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE;
|
||||||
|
|
||||||
virtual already_AddRefed<nsIDOMBlob>
|
virtual already_AddRefed<DOMFileImpl>
|
||||||
CreateSlice(uint64_t aStart, uint64_t aLength,
|
CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||||
const nsAString& aContentType) MOZ_OVERRIDE;
|
const nsAString& aContentType) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
@ -573,7 +575,7 @@ private:
|
||||||
nsString mContentType;
|
nsString mContentType;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DOMFileImplFile MOZ_FINAL : public DOMFileImplBase
|
class DOMFileImplFile : public DOMFileImplBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
@ -690,6 +692,9 @@ public:
|
||||||
|
|
||||||
void SetPath(const nsAString& aFullPath);
|
void SetPath(const nsAString& aFullPath);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~DOMFileImplFile() {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Create slice
|
// Create slice
|
||||||
DOMFileImplFile(const DOMFileImplFile* aOther, uint64_t aStart,
|
DOMFileImplFile(const DOMFileImplFile* aOther, uint64_t aStart,
|
||||||
|
@ -719,9 +724,7 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~DOMFileImplFile() {}
|
virtual already_AddRefed<DOMFileImpl>
|
||||||
|
|
||||||
virtual already_AddRefed<nsIDOMBlob>
|
|
||||||
CreateSlice(uint64_t aStart, uint64_t aLength,
|
CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||||
const nsAString& aContentType) MOZ_OVERRIDE;
|
const nsAString& aContentType) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,7 @@ namespace mozilla {
|
||||||
class CSSStyleSheet;
|
class CSSStyleSheet;
|
||||||
class ErrorResult;
|
class ErrorResult;
|
||||||
class EventStates;
|
class EventStates;
|
||||||
|
class SVGAttrAnimationRuleProcessor;
|
||||||
|
|
||||||
namespace css {
|
namespace css {
|
||||||
class Loader;
|
class Loader;
|
||||||
|
@ -925,6 +926,16 @@ public:
|
||||||
return mStyleAttrStyleSheet;
|
return mStyleAttrStyleSheet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get this document's SVG Animation rule processor. May return null
|
||||||
|
* if there isn't one.
|
||||||
|
*/
|
||||||
|
mozilla::SVGAttrAnimationRuleProcessor*
|
||||||
|
GetSVGAttrAnimationRuleProcessor() const
|
||||||
|
{
|
||||||
|
return mSVGAttrAnimationRuleProcessor;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void SetScriptGlobalObject(nsIScriptGlobalObject* aGlobalObject) = 0;
|
virtual void SetScriptGlobalObject(nsIScriptGlobalObject* aGlobalObject) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2443,6 +2454,7 @@ protected:
|
||||||
nsRefPtr<mozilla::css::ImageLoader> mStyleImageLoader;
|
nsRefPtr<mozilla::css::ImageLoader> mStyleImageLoader;
|
||||||
nsRefPtr<nsHTMLStyleSheet> mAttrStyleSheet;
|
nsRefPtr<nsHTMLStyleSheet> mAttrStyleSheet;
|
||||||
nsRefPtr<nsHTMLCSSStyleSheet> mStyleAttrStyleSheet;
|
nsRefPtr<nsHTMLCSSStyleSheet> mStyleAttrStyleSheet;
|
||||||
|
nsRefPtr<mozilla::SVGAttrAnimationRuleProcessor> mSVGAttrAnimationRuleProcessor;
|
||||||
|
|
||||||
// The set of all object, embed, applet, video/audio elements or
|
// The set of all object, embed, applet, video/audio elements or
|
||||||
// nsIObjectLoadingContent or nsIDocumentActivity for which this is the
|
// nsIObjectLoadingContent or nsIDocumentActivity for which this is the
|
||||||
|
|
|
@ -1576,7 +1576,8 @@ Element::SetSMILOverrideStyleRule(css::StyleRule* aStyleRule,
|
||||||
if (doc) {
|
if (doc) {
|
||||||
nsCOMPtr<nsIPresShell> shell = doc->GetShell();
|
nsCOMPtr<nsIPresShell> shell = doc->GetShell();
|
||||||
if (shell) {
|
if (shell) {
|
||||||
shell->RestyleForAnimation(this, eRestyle_Self);
|
shell->RestyleForAnimation(this,
|
||||||
|
eRestyle_StyleAttribute | eRestyle_ChangeAnimationPhase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ DOMMultipartFileImpl::GetInternalStream(nsIInputStream** aStream)
|
||||||
return CallQueryInterface(stream, aStream);
|
return CallQueryInterface(stream, aStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<nsIDOMBlob>
|
already_AddRefed<DOMFileImpl>
|
||||||
DOMMultipartFileImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
|
DOMMultipartFileImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||||
const nsAString& aContentType)
|
const nsAString& aContentType)
|
||||||
{
|
{
|
||||||
|
@ -77,18 +77,17 @@ DOMMultipartFileImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||||
if (skipStart < l) {
|
if (skipStart < l) {
|
||||||
uint64_t upperBound = std::min<uint64_t>(l - skipStart, length);
|
uint64_t upperBound = std::min<uint64_t>(l - skipStart, length);
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMBlob> firstBlob;
|
nsRefPtr<DOMFileImpl> firstImpl;
|
||||||
rv = blobImpl->Slice(skipStart, skipStart + upperBound,
|
rv = blobImpl->Slice(skipStart, skipStart + upperBound, aContentType, 3,
|
||||||
aContentType, 3,
|
getter_AddRefs(firstImpl));
|
||||||
getter_AddRefs(firstBlob));
|
|
||||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||||
|
|
||||||
// Avoid wrapping a single blob inside an DOMMultipartFileImpl
|
// Avoid wrapping a single blob inside an DOMMultipartFileImpl
|
||||||
if (length == upperBound) {
|
if (length == upperBound) {
|
||||||
return firstBlob.forget();
|
return firstImpl.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
blobImpls.AppendElement(static_cast<DOMFile*>(firstBlob.get())->Impl());
|
blobImpls.AppendElement(firstImpl);
|
||||||
length -= upperBound;
|
length -= upperBound;
|
||||||
i++;
|
i++;
|
||||||
break;
|
break;
|
||||||
|
@ -105,12 +104,12 @@ DOMMultipartFileImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||||
|
|
||||||
if (length < l) {
|
if (length < l) {
|
||||||
nsCOMPtr<nsIDOMBlob> lastBlob;
|
nsRefPtr<DOMFileImpl> lastBlob;
|
||||||
rv = blobImpl->Slice(0, length, aContentType, 3,
|
rv = blobImpl->Slice(0, length, aContentType, 3,
|
||||||
getter_AddRefs(lastBlob));
|
getter_AddRefs(lastBlob));
|
||||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||||
|
|
||||||
blobImpls.AppendElement(static_cast<DOMFile*>(lastBlob.get())->Impl());
|
blobImpls.AppendElement(lastBlob);
|
||||||
} else {
|
} else {
|
||||||
blobImpls.AppendElement(blobImpl);
|
blobImpls.AppendElement(blobImpl);
|
||||||
}
|
}
|
||||||
|
@ -118,9 +117,9 @@ DOMMultipartFileImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||||
}
|
}
|
||||||
|
|
||||||
// we can create our blob now
|
// we can create our blob now
|
||||||
nsCOMPtr<nsIDOMBlob> blob =
|
nsRefPtr<DOMFileImpl> impl =
|
||||||
new DOMFile(new DOMMultipartFileImpl(blobImpls, aContentType));
|
new DOMMultipartFileImpl(blobImpls, aContentType);
|
||||||
return blob.forget();
|
return impl.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ nsresult
|
/* static */ nsresult
|
||||||
|
|
|
@ -78,7 +78,7 @@ public:
|
||||||
uint32_t aArgc,
|
uint32_t aArgc,
|
||||||
JS::Value* aArgv);
|
JS::Value* aArgv);
|
||||||
|
|
||||||
virtual already_AddRefed<nsIDOMBlob>
|
virtual already_AddRefed<DOMFileImpl>
|
||||||
CreateSlice(uint64_t aStart, uint64_t aLength,
|
CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||||
const nsAString& aContentType) MOZ_OVERRIDE;
|
const nsAString& aContentType) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
|
|
@ -147,6 +147,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMFile)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIXHRSendable)
|
NS_INTERFACE_MAP_ENTRY(nsIXHRSendable)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIMutable)
|
NS_INTERFACE_MAP_ENTRY(nsIMutable)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
|
NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(File, IsFile())
|
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(File, IsFile())
|
||||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(Blob, !(IsFile()))
|
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(Blob, !(IsFile()))
|
||||||
NS_INTERFACE_MAP_END
|
NS_INTERFACE_MAP_END
|
||||||
|
@ -298,7 +299,10 @@ already_AddRefed<nsIDOMBlob>
|
||||||
DOMFile::CreateSlice(uint64_t aStart, uint64_t aLength,
|
DOMFile::CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||||
const nsAString& aContentType)
|
const nsAString& aContentType)
|
||||||
{
|
{
|
||||||
return mImpl->CreateSlice(aStart, aLength, aContentType);
|
nsRefPtr<DOMFileImpl> impl =
|
||||||
|
mImpl->CreateSlice(aStart, aLength, aContentType);
|
||||||
|
nsRefPtr<DOMFile> slice = new DOMFile(impl);
|
||||||
|
return slice.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -400,7 +404,17 @@ DOMFile::Slice(int64_t aStart, int64_t aEnd,
|
||||||
nsIDOMBlob **aBlob)
|
nsIDOMBlob **aBlob)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mImpl);
|
MOZ_ASSERT(mImpl);
|
||||||
return mImpl->Slice(aStart, aEnd, aContentType, aArgc, aBlob);
|
nsRefPtr<DOMFileImpl> impl;
|
||||||
|
nsresult rv = mImpl->Slice(aStart, aEnd, aContentType, aArgc,
|
||||||
|
getter_AddRefs(impl));
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<DOMFile> blob = new DOMFile(impl);
|
||||||
|
blob.forget(aBlob);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -460,9 +474,9 @@ DOMFile::IsMemoryFile()
|
||||||
nsresult
|
nsresult
|
||||||
DOMFileImpl::Slice(int64_t aStart, int64_t aEnd,
|
DOMFileImpl::Slice(int64_t aStart, int64_t aEnd,
|
||||||
const nsAString& aContentType, uint8_t aArgc,
|
const nsAString& aContentType, uint8_t aArgc,
|
||||||
nsIDOMBlob **aBlob)
|
DOMFileImpl** aBlobImpl)
|
||||||
{
|
{
|
||||||
*aBlob = nullptr;
|
*aBlobImpl = nullptr;
|
||||||
|
|
||||||
// Truncate aStart and aEnd so that we stay within this file.
|
// Truncate aStart and aEnd so that we stay within this file.
|
||||||
uint64_t thisLength;
|
uint64_t thisLength;
|
||||||
|
@ -475,12 +489,15 @@ DOMFileImpl::Slice(int64_t aStart, int64_t aEnd,
|
||||||
|
|
||||||
ParseSize((int64_t)thisLength, aStart, aEnd);
|
ParseSize((int64_t)thisLength, aStart, aEnd);
|
||||||
|
|
||||||
// Create the new file
|
nsRefPtr<DOMFileImpl> impl =
|
||||||
nsCOMPtr<nsIDOMBlob> blob =
|
|
||||||
CreateSlice((uint64_t)aStart, (uint64_t)(aEnd - aStart), aContentType);
|
CreateSlice((uint64_t)aStart, (uint64_t)(aEnd - aStart), aContentType);
|
||||||
|
|
||||||
blob.forget(aBlob);
|
if (!impl) {
|
||||||
return *aBlob ? NS_OK : NS_ERROR_UNEXPECTED;
|
return NS_ERROR_UNEXPECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl.forget(aBlobImpl);
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -575,7 +592,7 @@ DOMFileImplBase::GetMozLastModifiedDate(uint64_t* aLastModifiedDate)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<nsIDOMBlob>
|
already_AddRefed<DOMFileImpl>
|
||||||
DOMFileImplBase::CreateSlice(uint64_t aStart, uint64_t aLength,
|
DOMFileImplBase::CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||||
const nsAString& aContentType)
|
const nsAString& aContentType)
|
||||||
{
|
{
|
||||||
|
@ -724,13 +741,13 @@ DOMFileImplBase::SetMutable(bool aMutable)
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// DOMFileImplFile implementation
|
// DOMFileImplFile implementation
|
||||||
|
|
||||||
already_AddRefed<nsIDOMBlob>
|
already_AddRefed<DOMFileImpl>
|
||||||
DOMFileImplFile::CreateSlice(uint64_t aStart, uint64_t aLength,
|
DOMFileImplFile::CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||||
const nsAString& aContentType)
|
const nsAString& aContentType)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIDOMBlob> blob =
|
nsRefPtr<DOMFileImpl> impl =
|
||||||
new DOMFile(new DOMFileImplFile(this, aStart, aLength, aContentType));
|
new DOMFileImplFile(this, aStart, aLength, aContentType);
|
||||||
return blob.forget();
|
return impl.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -832,7 +849,8 @@ DOMFileImplFile::GetMozLastModifiedDate(uint64_t* aLastModifiedDate)
|
||||||
const uint32_t sFileStreamFlags =
|
const uint32_t sFileStreamFlags =
|
||||||
nsIFileInputStream::CLOSE_ON_EOF |
|
nsIFileInputStream::CLOSE_ON_EOF |
|
||||||
nsIFileInputStream::REOPEN_ON_REWIND |
|
nsIFileInputStream::REOPEN_ON_REWIND |
|
||||||
nsIFileInputStream::DEFER_OPEN;
|
nsIFileInputStream::DEFER_OPEN |
|
||||||
|
nsIFileInputStream::SHARE_DELETE;
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
DOMFileImplFile::GetInternalStream(nsIInputStream** aStream)
|
DOMFileImplFile::GetInternalStream(nsIInputStream** aStream)
|
||||||
|
@ -857,13 +875,13 @@ DOMFileImplFile::SetPath(const nsAString& aPath)
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS_INHERITED0(DOMFileImplMemory, DOMFileImpl)
|
NS_IMPL_ISUPPORTS_INHERITED0(DOMFileImplMemory, DOMFileImpl)
|
||||||
|
|
||||||
already_AddRefed<nsIDOMBlob>
|
already_AddRefed<DOMFileImpl>
|
||||||
DOMFileImplMemory::CreateSlice(uint64_t aStart, uint64_t aLength,
|
DOMFileImplMemory::CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||||
const nsAString& aContentType)
|
const nsAString& aContentType)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIDOMBlob> blob =
|
nsRefPtr<DOMFileImpl> impl =
|
||||||
new DOMFile(new DOMFileImplMemory(this, aStart, aLength, aContentType));
|
new DOMFileImplMemory(this, aStart, aLength, aContentType);
|
||||||
return blob.forget();
|
return impl.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -982,17 +1000,17 @@ DOMFileImplMemory::DataOwner::EnsureMemoryReporterRegistered()
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS_INHERITED0(DOMFileImplTemporaryFileBlob, DOMFileImpl)
|
NS_IMPL_ISUPPORTS_INHERITED0(DOMFileImplTemporaryFileBlob, DOMFileImpl)
|
||||||
|
|
||||||
already_AddRefed<nsIDOMBlob>
|
already_AddRefed<DOMFileImpl>
|
||||||
DOMFileImplTemporaryFileBlob::CreateSlice(uint64_t aStart, uint64_t aLength,
|
DOMFileImplTemporaryFileBlob::CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||||
const nsAString& aContentType)
|
const nsAString& aContentType)
|
||||||
{
|
{
|
||||||
if (aStart + aLength > mLength)
|
if (aStart + aLength > mLength)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMBlob> blob =
|
nsRefPtr<DOMFileImpl> impl =
|
||||||
new DOMFile(new DOMFileImplTemporaryFileBlob(this, aStart + mStartPos,
|
new DOMFileImplTemporaryFileBlob(this, aStart + mStartPos, aLength,
|
||||||
aLength, aContentType));
|
aContentType);
|
||||||
return blob.forget();
|
return impl.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
|
|
@ -153,7 +153,6 @@
|
||||||
#include "mozAutoDocUpdate.h"
|
#include "mozAutoDocUpdate.h"
|
||||||
#include "nsGlobalWindow.h"
|
#include "nsGlobalWindow.h"
|
||||||
#include "mozilla/dom/EncodingUtils.h"
|
#include "mozilla/dom/EncodingUtils.h"
|
||||||
#include "mozilla/dom/quota/QuotaManager.h"
|
|
||||||
#include "nsDOMNavigationTiming.h"
|
#include "nsDOMNavigationTiming.h"
|
||||||
|
|
||||||
#include "nsSMILAnimationController.h"
|
#include "nsSMILAnimationController.h"
|
||||||
|
@ -168,6 +167,7 @@
|
||||||
#include "nsCSPService.h"
|
#include "nsCSPService.h"
|
||||||
#include "nsHTMLStyleSheet.h"
|
#include "nsHTMLStyleSheet.h"
|
||||||
#include "nsHTMLCSSStyleSheet.h"
|
#include "nsHTMLCSSStyleSheet.h"
|
||||||
|
#include "SVGAttrAnimationRuleProcessor.h"
|
||||||
#include "mozilla/dom/DOMImplementation.h"
|
#include "mozilla/dom/DOMImplementation.h"
|
||||||
#include "mozilla/dom/ShadowRoot.h"
|
#include "mozilla/dom/ShadowRoot.h"
|
||||||
#include "mozilla/dom/Comment.h"
|
#include "mozilla/dom/Comment.h"
|
||||||
|
@ -2449,6 +2449,11 @@ nsDocument::ResetStylesheetsToURI(nsIURI* aURI)
|
||||||
mStyleAttrStyleSheet = new nsHTMLCSSStyleSheet();
|
mStyleAttrStyleSheet = new nsHTMLCSSStyleSheet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mSVGAttrAnimationRuleProcessor) {
|
||||||
|
mSVGAttrAnimationRuleProcessor =
|
||||||
|
new mozilla::SVGAttrAnimationRuleProcessor();
|
||||||
|
}
|
||||||
|
|
||||||
// Now set up our style sets
|
// Now set up our style sets
|
||||||
nsCOMPtr<nsIPresShell> shell = GetShell();
|
nsCOMPtr<nsIPresShell> shell = GetShell();
|
||||||
if (shell) {
|
if (shell) {
|
||||||
|
@ -8511,13 +8516,6 @@ nsDocument::CanSavePresentation(nsIRequest *aNewRequest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we have running offline storage transactions
|
|
||||||
quota::QuotaManager* quotaManager =
|
|
||||||
win ? quota::QuotaManager::Get() : nullptr;
|
|
||||||
if (quotaManager && quotaManager->HasOpenTransactions(win)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef MOZ_MEDIA_NAVIGATOR
|
#ifdef MOZ_MEDIA_NAVIGATOR
|
||||||
// Check if we have active GetUserMedia use
|
// Check if we have active GetUserMedia use
|
||||||
if (MediaManager::Exists() && win &&
|
if (MediaManager::Exists() && win &&
|
||||||
|
@ -12169,6 +12167,12 @@ nsDocument::DocAddSizeOfExcludingThis(nsWindowSizes* aWindowSizes) const
|
||||||
mAttrStyleSheet->DOMSizeOfIncludingThis(aWindowSizes->mMallocSizeOf) :
|
mAttrStyleSheet->DOMSizeOfIncludingThis(aWindowSizes->mMallocSizeOf) :
|
||||||
0;
|
0;
|
||||||
|
|
||||||
|
aWindowSizes->mDOMOtherSize +=
|
||||||
|
mSVGAttrAnimationRuleProcessor ?
|
||||||
|
mSVGAttrAnimationRuleProcessor->DOMSizeOfIncludingThis(
|
||||||
|
aWindowSizes->mMallocSizeOf) :
|
||||||
|
0;
|
||||||
|
|
||||||
aWindowSizes->mDOMOtherSize +=
|
aWindowSizes->mDOMOtherSize +=
|
||||||
mStyledLinks.SizeOfExcludingThis(nullptr, aWindowSizes->mMallocSizeOf);
|
mStyledLinks.SizeOfExcludingThis(nullptr, aWindowSizes->mMallocSizeOf);
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,8 @@
|
||||||
#include "mozilla/dom/PermissionMessageUtils.h"
|
#include "mozilla/dom/PermissionMessageUtils.h"
|
||||||
#include "mozilla/dom/ScriptSettings.h"
|
#include "mozilla/dom/ScriptSettings.h"
|
||||||
#include "mozilla/dom/StructuredCloneUtils.h"
|
#include "mozilla/dom/StructuredCloneUtils.h"
|
||||||
#include "mozilla/dom/PBlobChild.h"
|
#include "mozilla/dom/ipc/BlobChild.h"
|
||||||
#include "mozilla/dom/PBlobParent.h"
|
#include "mozilla/dom/ipc/BlobParent.h"
|
||||||
#include "JavaScriptChild.h"
|
#include "JavaScriptChild.h"
|
||||||
#include "JavaScriptParent.h"
|
#include "JavaScriptParent.h"
|
||||||
#include "mozilla/dom/DOMStringList.h"
|
#include "mozilla/dom/DOMStringList.h"
|
||||||
|
|
|
@ -905,6 +905,12 @@ nsSVGElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
|
||||||
aRuleWalker->Forward(mContentStyleRule);
|
aRuleWalker->Forward(mContentStyleRule);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsSVGElement::WalkAnimatedContentStyleRules(nsRuleWalker* aRuleWalker)
|
||||||
|
{
|
||||||
// Update & walk the animated content style rule, to include style from
|
// Update & walk the animated content style rule, to include style from
|
||||||
// animated mapped attributes. But first, get nsPresContext to check
|
// animated mapped attributes. But first, get nsPresContext to check
|
||||||
// whether this is a "no-animation restyle". (This should match the check
|
// whether this is a "no-animation restyle". (This should match the check
|
||||||
|
@ -919,7 +925,8 @@ nsSVGElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
|
||||||
// want that to happen from SMIL-animated value of mapped attrs, so
|
// want that to happen from SMIL-animated value of mapped attrs, so
|
||||||
// ignore animated value for now, and request an animation restyle to
|
// ignore animated value for now, and request an animation restyle to
|
||||||
// get our animated value noticed.
|
// get our animated value noticed.
|
||||||
shell->RestyleForAnimation(this, eRestyle_Self);
|
shell->RestyleForAnimation(this,
|
||||||
|
eRestyle_SVGAttrAnimations | eRestyle_ChangeAnimationPhase);
|
||||||
} else {
|
} else {
|
||||||
// Ok, this is an animation restyle -- go ahead and update/walk the
|
// Ok, this is an animation restyle -- go ahead and update/walk the
|
||||||
// animated content style rule.
|
// animated content style rule.
|
||||||
|
@ -933,8 +940,6 @@ nsSVGElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
|
||||||
aRuleWalker->Forward(animContentStyleRule);
|
aRuleWalker->Forward(animContentStyleRule);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP_(bool)
|
NS_IMETHODIMP_(bool)
|
||||||
|
|
|
@ -113,6 +113,7 @@ public:
|
||||||
virtual bool IsNodeOfType(uint32_t aFlags) const MOZ_OVERRIDE;
|
virtual bool IsNodeOfType(uint32_t aFlags) const MOZ_OVERRIDE;
|
||||||
|
|
||||||
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) MOZ_OVERRIDE;
|
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) MOZ_OVERRIDE;
|
||||||
|
void WalkAnimatedContentStyleRules(nsRuleWalker* aRuleWalker);
|
||||||
|
|
||||||
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
|
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
|
|
@ -396,16 +396,15 @@ ArchiveZipFileImpl::Traverse(nsCycleCollectionTraversalCallback &cb)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mArchiveReader);
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mArchiveReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<nsIDOMBlob>
|
already_AddRefed<mozilla::dom::DOMFileImpl>
|
||||||
ArchiveZipFileImpl::CreateSlice(uint64_t aStart,
|
ArchiveZipFileImpl::CreateSlice(uint64_t aStart,
|
||||||
uint64_t aLength,
|
uint64_t aLength,
|
||||||
const nsAString& aContentType)
|
const nsAString& aContentType)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIDOMBlob> t =
|
nsRefPtr<DOMFileImpl> impl =
|
||||||
new DOMFile(new ArchiveZipFileImpl(mFilename, mContentType,
|
new ArchiveZipFileImpl(mFilename, mContentType, aStart, mLength, mCentral,
|
||||||
aStart, mLength, mCentral,
|
mArchiveReader);
|
||||||
mArchiveReader));
|
return impl.forget();
|
||||||
return t.forget();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS_INHERITED0(ArchiveZipFileImpl, DOMFileImpl)
|
NS_IMPL_ISUPPORTS_INHERITED0(ArchiveZipFileImpl, DOMFileImpl)
|
||||||
|
|
|
@ -71,9 +71,9 @@ protected:
|
||||||
MOZ_COUNT_DTOR(ArchiveZipFileImpl);
|
MOZ_COUNT_DTOR(ArchiveZipFileImpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual already_AddRefed<nsIDOMBlob> CreateSlice(uint64_t aStart,
|
virtual already_AddRefed<DOMFileImpl> CreateSlice(uint64_t aStart,
|
||||||
uint64_t aLength,
|
uint64_t aLength,
|
||||||
const nsAString& aContentType) MOZ_OVERRIDE;
|
const nsAString& aContentType) MOZ_OVERRIDE;
|
||||||
|
|
||||||
private: // Data
|
private: // Data
|
||||||
ZipCentral mCentral;
|
ZipCentral mCentral;
|
||||||
|
|
|
@ -100,6 +100,7 @@
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
|
using namespace mozilla::ipc;
|
||||||
using namespace mozilla::layers;
|
using namespace mozilla::layers;
|
||||||
using namespace mozilla::widget;
|
using namespace mozilla::widget;
|
||||||
using namespace mozilla::gfx;
|
using namespace mozilla::gfx;
|
||||||
|
@ -3004,30 +3005,65 @@ nsDOMWindowUtils::AreDialogsEnabled(bool* aResult)
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDOMWindowUtils::GetFileId(JS::Handle<JS::Value> aFile, JSContext* aCx,
|
nsDOMWindowUtils::GetFileId(JS::Handle<JS::Value> aFile, JSContext* aCx,
|
||||||
int64_t* aResult)
|
int64_t* _retval)
|
||||||
{
|
{
|
||||||
MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
|
MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
|
||||||
|
|
||||||
if (!aFile.isPrimitive()) {
|
if (aFile.isPrimitive()) {
|
||||||
JSObject* obj = aFile.toObjectOrNull();
|
*_retval = -1;
|
||||||
|
return NS_OK;
|
||||||
indexedDB::IDBMutableFile* mutableFile = nullptr;
|
|
||||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(IDBMutableFile, obj, mutableFile))) {
|
|
||||||
*aResult = mutableFile->GetFileId();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsISupports* nativeObj =
|
|
||||||
nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, obj);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(nativeObj);
|
|
||||||
if (blob) {
|
|
||||||
*aResult = blob->GetFileId();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*aResult = -1;
|
JSObject* obj = aFile.toObjectOrNull();
|
||||||
|
|
||||||
|
indexedDB::IDBMutableFile* mutableFile = nullptr;
|
||||||
|
if (NS_SUCCEEDED(UNWRAP_OBJECT(IDBMutableFile, obj, mutableFile))) {
|
||||||
|
*_retval = mutableFile->GetFileId();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsISupports* nativeObj =
|
||||||
|
nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, obj);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(nativeObj);
|
||||||
|
if (blob) {
|
||||||
|
*_retval = blob->GetFileId();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
*_retval = -1;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWindowUtils::GetFilePath(JS::HandleValue aFile, JSContext* aCx,
|
||||||
|
nsAString& _retval)
|
||||||
|
{
|
||||||
|
MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
|
||||||
|
|
||||||
|
if (aFile.isPrimitive()) {
|
||||||
|
_retval.Truncate();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSObject* obj = aFile.toObjectOrNull();
|
||||||
|
|
||||||
|
nsISupports* nativeObj =
|
||||||
|
nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, obj);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMFile> file = do_QueryInterface(nativeObj);
|
||||||
|
if (file) {
|
||||||
|
nsString filePath;
|
||||||
|
nsresult rv = file->GetMozFullPathInternal(filePath);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
_retval = filePath;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
_retval.Truncate();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -187,7 +187,6 @@
|
||||||
#include "mozilla/dom/MessagePort.h"
|
#include "mozilla/dom/MessagePort.h"
|
||||||
#include "mozilla/dom/MessagePortBinding.h"
|
#include "mozilla/dom/MessagePortBinding.h"
|
||||||
#include "mozilla/dom/indexedDB/IDBFactory.h"
|
#include "mozilla/dom/indexedDB/IDBFactory.h"
|
||||||
#include "mozilla/dom/quota/QuotaManager.h"
|
|
||||||
|
|
||||||
#include "mozilla/dom/StructuredCloneTags.h"
|
#include "mozilla/dom/StructuredCloneTags.h"
|
||||||
|
|
||||||
|
@ -1562,12 +1561,6 @@ nsGlobalWindow::FreeInnerObjects()
|
||||||
// Kill all of the workers for this window.
|
// Kill all of the workers for this window.
|
||||||
mozilla::dom::workers::CancelWorkersForWindow(this);
|
mozilla::dom::workers::CancelWorkersForWindow(this);
|
||||||
|
|
||||||
// Close all offline storages for this window.
|
|
||||||
quota::QuotaManager* quotaManager = quota::QuotaManager::Get();
|
|
||||||
if (quotaManager) {
|
|
||||||
quotaManager->AbortCloseStoragesForWindow(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
ClearAllTimeouts();
|
ClearAllTimeouts();
|
||||||
|
|
||||||
if (mIdleTimer) {
|
if (mIdleTimer) {
|
||||||
|
@ -10581,9 +10574,11 @@ GetIndexedDBEnabledForAboutURI(nsIURI *aURI)
|
||||||
return flags & nsIAboutModule::ENABLE_INDEXED_DB;
|
return flags & nsIAboutModule::ENABLE_INDEXED_DB;
|
||||||
}
|
}
|
||||||
|
|
||||||
indexedDB::IDBFactory*
|
mozilla::dom::indexedDB::IDBFactory*
|
||||||
nsGlobalWindow::GetIndexedDB(ErrorResult& aError)
|
nsGlobalWindow::GetIndexedDB(ErrorResult& aError)
|
||||||
{
|
{
|
||||||
|
using mozilla::dom::indexedDB::IDBFactory;
|
||||||
|
|
||||||
if (!mIndexedDB) {
|
if (!mIndexedDB) {
|
||||||
// If the document has the sandboxed origin flag set
|
// If the document has the sandboxed origin flag set
|
||||||
// don't allow access to indexedDB.
|
// don't allow access to indexedDB.
|
||||||
|
@ -10630,8 +10625,7 @@ nsGlobalWindow::GetIndexedDB(ErrorResult& aError)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This may be null if being created from a file.
|
// This may be null if being created from a file.
|
||||||
aError = indexedDB::IDBFactory::Create(this, nullptr,
|
aError = IDBFactory::CreateForWindow(this, getter_AddRefs(mIndexedDB));
|
||||||
getter_AddRefs(mIndexedDB));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mIndexedDB;
|
return mIndexedDB;
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#include "mozilla/unused.h"
|
#include "mozilla/unused.h"
|
||||||
#include "mozilla/dom/ContentParent.h"
|
#include "mozilla/dom/ContentParent.h"
|
||||||
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
||||||
|
#include "mozilla/dom/ipc/BlobChild.h"
|
||||||
|
#include "mozilla/dom/ipc/BlobParent.h"
|
||||||
#include "mozilla/ipc/UnixSocket.h"
|
#include "mozilla/ipc/UnixSocket.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
#include "BluetoothCommon.h"
|
#include "BluetoothCommon.h"
|
||||||
#include "BluetoothProfileManagerBase.h"
|
#include "BluetoothProfileManagerBase.h"
|
||||||
#include "mozilla/dom/ipc/Blob.h"
|
|
||||||
#include "nsAutoPtr.h"
|
#include "nsAutoPtr.h"
|
||||||
#include "nsClassHashtable.h"
|
#include "nsClassHashtable.h"
|
||||||
#include "nsIDOMFile.h"
|
#include "nsIDOMFile.h"
|
||||||
|
@ -17,7 +16,13 @@
|
||||||
#include "nsTObserverArray.h"
|
#include "nsTObserverArray.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
|
|
||||||
|
class nsIDOMBlob;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
class BlobChild;
|
||||||
|
class BlobParent;
|
||||||
|
}
|
||||||
namespace ipc {
|
namespace ipc {
|
||||||
class UnixSocketConsumer;
|
class UnixSocketConsumer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "ObexBase.h"
|
#include "ObexBase.h"
|
||||||
|
|
||||||
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
||||||
|
#include "mozilla/dom/ipc/BlobParent.h"
|
||||||
#include "mozilla/RefPtr.h"
|
#include "mozilla/RefPtr.h"
|
||||||
#include "mozilla/Services.h"
|
#include "mozilla/Services.h"
|
||||||
#include "mozilla/StaticPtr.h"
|
#include "mozilla/StaticPtr.h"
|
||||||
|
|
|
@ -11,14 +11,20 @@
|
||||||
#include "BluetoothProfileManagerBase.h"
|
#include "BluetoothProfileManagerBase.h"
|
||||||
#include "BluetoothSocketObserver.h"
|
#include "BluetoothSocketObserver.h"
|
||||||
#include "DeviceStorage.h"
|
#include "DeviceStorage.h"
|
||||||
#include "mozilla/dom/ipc/Blob.h"
|
|
||||||
#include "mozilla/ipc/UnixSocket.h"
|
#include "mozilla/ipc/UnixSocket.h"
|
||||||
#include "nsCOMArray.h"
|
#include "nsCOMArray.h"
|
||||||
|
|
||||||
|
class nsIDOMBlob;
|
||||||
class nsIOutputStream;
|
class nsIOutputStream;
|
||||||
class nsIInputStream;
|
class nsIInputStream;
|
||||||
class nsIVolumeMountLock;
|
class nsIVolumeMountLock;
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
class BlobParent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BEGIN_BLUETOOTH_NAMESPACE
|
BEGIN_BLUETOOTH_NAMESPACE
|
||||||
|
|
||||||
class BluetoothSocket;
|
class BluetoothSocket;
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "mozilla/ipc/DBusUtils.h"
|
#include "mozilla/ipc/DBusUtils.h"
|
||||||
#include "mozilla/ipc/RawDBusConnection.h"
|
#include "mozilla/ipc/RawDBusConnection.h"
|
||||||
#include "mozilla/LazyIdleThread.h"
|
#include "mozilla/LazyIdleThread.h"
|
||||||
|
#include "mozilla/Monitor.h"
|
||||||
#include "mozilla/Mutex.h"
|
#include "mozilla/Mutex.h"
|
||||||
#include "mozilla/NullPtr.h"
|
#include "mozilla/NullPtr.h"
|
||||||
#include "mozilla/StaticMutex.h"
|
#include "mozilla/StaticMutex.h"
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "ObexBase.h"
|
#include "ObexBase.h"
|
||||||
|
|
||||||
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
||||||
|
#include "mozilla/dom/ipc/BlobParent.h"
|
||||||
#include "mozilla/RefPtr.h"
|
#include "mozilla/RefPtr.h"
|
||||||
#include "mozilla/Services.h"
|
#include "mozilla/Services.h"
|
||||||
#include "mozilla/StaticPtr.h"
|
#include "mozilla/StaticPtr.h"
|
||||||
|
|
|
@ -11,14 +11,20 @@
|
||||||
#include "BluetoothProfileManagerBase.h"
|
#include "BluetoothProfileManagerBase.h"
|
||||||
#include "BluetoothSocketObserver.h"
|
#include "BluetoothSocketObserver.h"
|
||||||
#include "DeviceStorage.h"
|
#include "DeviceStorage.h"
|
||||||
#include "mozilla/dom/ipc/Blob.h"
|
|
||||||
#include "mozilla/ipc/UnixSocket.h"
|
#include "mozilla/ipc/UnixSocket.h"
|
||||||
#include "nsCOMArray.h"
|
#include "nsCOMArray.h"
|
||||||
|
|
||||||
|
class nsIDOMBlob;
|
||||||
class nsIOutputStream;
|
class nsIOutputStream;
|
||||||
class nsIInputStream;
|
class nsIInputStream;
|
||||||
class nsIVolumeMountLock;
|
class nsIVolumeMountLock;
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
class BlobParent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BEGIN_BLUETOOTH_NAMESPACE
|
BEGIN_BLUETOOTH_NAMESPACE
|
||||||
|
|
||||||
class BluetoothSocket;
|
class BluetoothSocket;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
#include "mozilla/dom/ContentChild.h"
|
#include "mozilla/dom/ContentChild.h"
|
||||||
|
#include "mozilla/dom/ipc/BlobChild.h"
|
||||||
|
|
||||||
#include "BluetoothChild.h"
|
#include "BluetoothChild.h"
|
||||||
#include "MainThreadUtils.h"
|
#include "MainThreadUtils.h"
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#include "mozilla/unused.h"
|
#include "mozilla/unused.h"
|
||||||
#include "mozilla/dom/ContentParent.h"
|
#include "mozilla/dom/ContentParent.h"
|
||||||
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
||||||
|
#include "mozilla/dom/ipc/BlobChild.h"
|
||||||
|
#include "mozilla/dom/ipc/BlobParent.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
#include "nsISettingsService.h"
|
#include "nsISettingsService.h"
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
#include "BluetoothCommon.h"
|
#include "BluetoothCommon.h"
|
||||||
#include "BluetoothProfileManagerBase.h"
|
#include "BluetoothProfileManagerBase.h"
|
||||||
#include "mozilla/dom/ipc/Blob.h"
|
|
||||||
#include "nsAutoPtr.h"
|
#include "nsAutoPtr.h"
|
||||||
#include "nsClassHashtable.h"
|
#include "nsClassHashtable.h"
|
||||||
#include "nsIDOMFile.h"
|
#include "nsIDOMFile.h"
|
||||||
|
@ -17,7 +16,13 @@
|
||||||
#include "nsTObserverArray.h"
|
#include "nsTObserverArray.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
|
|
||||||
|
class nsIDOMBlob;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
class BlobChild;
|
||||||
|
class BlobParent;
|
||||||
|
}
|
||||||
namespace ipc {
|
namespace ipc {
|
||||||
class UnixSocketConsumer;
|
class UnixSocketConsumer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "ObexBase.h"
|
#include "ObexBase.h"
|
||||||
|
|
||||||
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
||||||
|
#include "mozilla/dom/ipc/BlobParent.h"
|
||||||
#include "mozilla/RefPtr.h"
|
#include "mozilla/RefPtr.h"
|
||||||
#include "mozilla/Services.h"
|
#include "mozilla/Services.h"
|
||||||
#include "mozilla/StaticPtr.h"
|
#include "mozilla/StaticPtr.h"
|
||||||
|
|
|
@ -11,14 +11,20 @@
|
||||||
#include "BluetoothProfileManagerBase.h"
|
#include "BluetoothProfileManagerBase.h"
|
||||||
#include "BluetoothSocketObserver.h"
|
#include "BluetoothSocketObserver.h"
|
||||||
#include "DeviceStorage.h"
|
#include "DeviceStorage.h"
|
||||||
#include "mozilla/dom/ipc/Blob.h"
|
|
||||||
#include "mozilla/ipc/UnixSocket.h"
|
#include "mozilla/ipc/UnixSocket.h"
|
||||||
#include "nsCOMArray.h"
|
#include "nsCOMArray.h"
|
||||||
|
|
||||||
|
class nsIDOMBlob;
|
||||||
class nsIOutputStream;
|
class nsIOutputStream;
|
||||||
class nsIInputStream;
|
class nsIInputStream;
|
||||||
class nsIVolumeMountLock;
|
class nsIVolumeMountLock;
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
class BlobParent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BEGIN_BLUETOOTH_NAMESPACE
|
BEGIN_BLUETOOTH_NAMESPACE
|
||||||
|
|
||||||
class BluetoothSocket;
|
class BluetoothSocket;
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "ObexBase.h"
|
#include "ObexBase.h"
|
||||||
|
|
||||||
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
||||||
|
#include "mozilla/dom/ipc/BlobParent.h"
|
||||||
#include "mozilla/RefPtr.h"
|
#include "mozilla/RefPtr.h"
|
||||||
#include "mozilla/Services.h"
|
#include "mozilla/Services.h"
|
||||||
#include "mozilla/StaticPtr.h"
|
#include "mozilla/StaticPtr.h"
|
||||||
|
|
|
@ -11,14 +11,20 @@
|
||||||
#include "BluetoothProfileManagerBase.h"
|
#include "BluetoothProfileManagerBase.h"
|
||||||
#include "BluetoothSocketObserver.h"
|
#include "BluetoothSocketObserver.h"
|
||||||
#include "DeviceStorage.h"
|
#include "DeviceStorage.h"
|
||||||
#include "mozilla/dom/ipc/Blob.h"
|
|
||||||
#include "mozilla/ipc/UnixSocket.h"
|
#include "mozilla/ipc/UnixSocket.h"
|
||||||
#include "nsCOMArray.h"
|
#include "nsCOMArray.h"
|
||||||
|
|
||||||
|
class nsIDOMBlob;
|
||||||
class nsIOutputStream;
|
class nsIOutputStream;
|
||||||
class nsIInputStream;
|
class nsIInputStream;
|
||||||
class nsIVolumeMountLock;
|
class nsIVolumeMountLock;
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
class BlobParent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BEGIN_BLUETOOTH_NAMESPACE
|
BEGIN_BLUETOOTH_NAMESPACE
|
||||||
|
|
||||||
class BluetoothSocket;
|
class BluetoothSocket;
|
||||||
|
|
|
@ -7,15 +7,22 @@
|
||||||
#include "DataStoreDB.h"
|
#include "DataStoreDB.h"
|
||||||
|
|
||||||
#include "DataStoreCallbacks.h"
|
#include "DataStoreCallbacks.h"
|
||||||
|
#include "jsapi.h"
|
||||||
#include "mozilla/dom/IDBDatabaseBinding.h"
|
#include "mozilla/dom/IDBDatabaseBinding.h"
|
||||||
#include "mozilla/dom/IDBFactoryBinding.h"
|
#include "mozilla/dom/IDBFactoryBinding.h"
|
||||||
|
#include "mozilla/dom/IDBObjectStoreBinding.h"
|
||||||
#include "mozilla/dom/indexedDB/IDBDatabase.h"
|
#include "mozilla/dom/indexedDB/IDBDatabase.h"
|
||||||
#include "mozilla/dom/indexedDB/IDBEvents.h"
|
#include "mozilla/dom/indexedDB/IDBEvents.h"
|
||||||
#include "mozilla/dom/indexedDB/IDBFactory.h"
|
#include "mozilla/dom/indexedDB/IDBFactory.h"
|
||||||
#include "mozilla/dom/indexedDB/IDBIndex.h"
|
#include "mozilla/dom/indexedDB/IDBIndex.h"
|
||||||
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
|
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
|
||||||
#include "mozilla/dom/indexedDB/IDBRequest.h"
|
#include "mozilla/dom/indexedDB/IDBRequest.h"
|
||||||
|
#include "mozilla/dom/indexedDB/IDBTransaction.h"
|
||||||
|
#include "nsComponentManagerUtils.h"
|
||||||
|
#include "nsContentUtils.h"
|
||||||
#include "nsIDOMEvent.h"
|
#include "nsIDOMEvent.h"
|
||||||
|
#include "nsIPrincipal.h"
|
||||||
|
#include "nsIXPConnect.h"
|
||||||
|
|
||||||
#define DATASTOREDB_VERSION 1
|
#define DATASTOREDB_VERSION 1
|
||||||
#define DATASTOREDB_NAME "DataStoreDB"
|
#define DATASTOREDB_NAME "DataStoreDB"
|
||||||
|
@ -63,7 +70,9 @@ public:
|
||||||
MOZ_ASSERT(version.IsNull());
|
MOZ_ASSERT(version.IsNull());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return mDatabase->Close();
|
mDatabase->Close();
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -93,7 +102,36 @@ nsresult
|
||||||
DataStoreDB::CreateFactoryIfNeeded()
|
DataStoreDB::CreateFactoryIfNeeded()
|
||||||
{
|
{
|
||||||
if (!mFactory) {
|
if (!mFactory) {
|
||||||
nsresult rv = IDBFactory::Create(nullptr, getter_AddRefs(mFactory));
|
nsresult rv;
|
||||||
|
nsCOMPtr<nsIPrincipal> principal =
|
||||||
|
do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIXPConnect* xpc = nsContentUtils::XPConnect();
|
||||||
|
MOZ_ASSERT(xpc);
|
||||||
|
|
||||||
|
AutoSafeJSContext cx;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIXPConnectJSObjectHolder> globalHolder;
|
||||||
|
rv = xpc->CreateSandbox(cx, principal, getter_AddRefs(globalHolder));
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
JS::Rooted<JSObject*> global(cx, globalHolder->GetJSObject());
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return NS_ERROR_UNEXPECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The CreateSandbox call returns a proxy to the actual sandbox object. We
|
||||||
|
// don't need a proxy here.
|
||||||
|
global = js::UncheckedUnwrap(global);
|
||||||
|
|
||||||
|
JSAutoCompartment ac(cx, global);
|
||||||
|
|
||||||
|
rv = IDBFactory::CreateForDatastore(cx, global, getter_AddRefs(mFactory));
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -301,11 +339,7 @@ DataStoreDB::Delete()
|
||||||
mTransaction = nullptr;
|
mTransaction = nullptr;
|
||||||
|
|
||||||
if (mDatabase) {
|
if (mDatabase) {
|
||||||
rv = mDatabase->Close();
|
mDatabase->Close();
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
mDatabase = nullptr;
|
mDatabase = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,9 @@
|
||||||
#include "DataStoreCallbacks.h"
|
#include "DataStoreCallbacks.h"
|
||||||
#include "DataStoreService.h"
|
#include "DataStoreService.h"
|
||||||
#include "mozilla/dom/DataStoreBinding.h"
|
#include "mozilla/dom/DataStoreBinding.h"
|
||||||
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
|
|
||||||
#include "mozilla/dom/ToJSValue.h"
|
#include "mozilla/dom/ToJSValue.h"
|
||||||
|
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
|
||||||
|
#include "mozilla/dom/indexedDB/IDBRequest.h"
|
||||||
#include "nsIDOMEvent.h"
|
#include "nsIDOMEvent.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
#include "mozilla/dom/DOMError.h"
|
#include "mozilla/dom/DOMError.h"
|
||||||
#include "mozilla/dom/indexedDB/IDBCursor.h"
|
#include "mozilla/dom/indexedDB/IDBCursor.h"
|
||||||
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
|
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
|
||||||
|
#include "mozilla/dom/indexedDB/IDBRequest.h"
|
||||||
|
#include "mozilla/dom/indexedDB/IDBTransaction.h"
|
||||||
#include "mozilla/dom/PermissionMessageUtils.h"
|
#include "mozilla/dom/PermissionMessageUtils.h"
|
||||||
#include "mozilla/dom/Promise.h"
|
#include "mozilla/dom/Promise.h"
|
||||||
#include "mozilla/unused.h"
|
#include "mozilla/unused.h"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<!DOCTYPE HTML>
|
<!DOCTYPE HTML>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
@ -137,7 +137,7 @@
|
||||||
|
|
||||||
// Uninstall the apps
|
// Uninstall the apps
|
||||||
function() { uninstallApp(gApps[0]); },
|
function() { uninstallApp(gApps[0]); },
|
||||||
function() { uninstallApp(gApps[1]); },
|
function() { uninstallApp(gApps[1]); }
|
||||||
];
|
];
|
||||||
|
|
||||||
function runTest() {
|
function runTest() {
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "DeviceStorageFileDescriptor.h"
|
#include "DeviceStorageFileDescriptor.h"
|
||||||
#include "nsDeviceStorage.h"
|
#include "nsDeviceStorage.h"
|
||||||
#include "nsDOMFile.h"
|
#include "nsDOMFile.h"
|
||||||
#include "mozilla/dom/ipc/Blob.h"
|
#include "mozilla/dom/ipc/BlobChild.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "nsIMIMEService.h"
|
#include "nsIMIMEService.h"
|
||||||
#include "nsCExternalHandlerService.h"
|
#include "nsCExternalHandlerService.h"
|
||||||
#include "mozilla/unused.h"
|
#include "mozilla/unused.h"
|
||||||
#include "mozilla/dom/ipc/Blob.h"
|
#include "mozilla/dom/ipc/BlobParent.h"
|
||||||
#include "ContentParent.h"
|
#include "ContentParent.h"
|
||||||
#include "nsProxyRelease.h"
|
#include "nsProxyRelease.h"
|
||||||
#include "AppProcessChecker.h"
|
#include "AppProcessChecker.h"
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include "mozilla/dom/devicestorage/PDeviceStorageRequestChild.h"
|
#include "mozilla/dom/devicestorage/PDeviceStorageRequestChild.h"
|
||||||
#include "mozilla/dom/Directory.h"
|
#include "mozilla/dom/Directory.h"
|
||||||
#include "mozilla/dom/FileSystemUtils.h"
|
#include "mozilla/dom/FileSystemUtils.h"
|
||||||
#include "mozilla/dom/ipc/Blob.h"
|
#include "mozilla/dom/ipc/BlobChild.h"
|
||||||
#include "mozilla/dom/PBrowserChild.h"
|
#include "mozilla/dom/PBrowserChild.h"
|
||||||
#include "mozilla/dom/PermissionMessageUtils.h"
|
#include "mozilla/dom/PermissionMessageUtils.h"
|
||||||
#include "mozilla/dom/Promise.h"
|
#include "mozilla/dom/Promise.h"
|
||||||
|
|
|
@ -8,7 +8,9 @@
|
||||||
|
|
||||||
#include "FileHelper.h"
|
#include "FileHelper.h"
|
||||||
#include "MainThreadUtils.h"
|
#include "MainThreadUtils.h"
|
||||||
|
#include "mozilla/Assertions.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "mozilla/ipc/InputStreamParams.h"
|
||||||
#include "MutableFile.h"
|
#include "MutableFile.h"
|
||||||
#include "nsDebug.h"
|
#include "nsDebug.h"
|
||||||
#include "nsError.h"
|
#include "nsError.h"
|
||||||
|
@ -16,6 +18,10 @@
|
||||||
#include "nsISeekableStream.h"
|
#include "nsISeekableStream.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#include "nsXULAppAPI.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
|
@ -127,7 +133,8 @@ FileInputStreamWrapper::FileInputStreamWrapper(nsISupports* aFileStream,
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS_INHERITED(FileInputStreamWrapper,
|
NS_IMPL_ISUPPORTS_INHERITED(FileInputStreamWrapper,
|
||||||
FileStreamWrapper,
|
FileStreamWrapper,
|
||||||
nsIInputStream)
|
nsIInputStream,
|
||||||
|
nsIIPCSerializableInputStream)
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
FileInputStreamWrapper::Close()
|
FileInputStreamWrapper::Close()
|
||||||
|
@ -230,6 +237,26 @@ FileInputStreamWrapper::IsNonBlocking(bool* _retval)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FileInputStreamWrapper::Serialize(InputStreamParams& aParams,
|
||||||
|
FileDescriptorArray& /* aFDs */)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
nsCOMPtr<nsIInputStream> thisStream = do_QueryObject(this);
|
||||||
|
|
||||||
|
aParams = mozilla::ipc::SameProcessInputStreamParams(
|
||||||
|
reinterpret_cast<intptr_t>(thisStream.forget().take()));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
FileInputStreamWrapper::Deserialize(const InputStreamParams& /* aParams */,
|
||||||
|
const FileDescriptorArray& /* aFDs */)
|
||||||
|
{
|
||||||
|
MOZ_CRASH("Should never get here!");
|
||||||
|
}
|
||||||
|
|
||||||
FileOutputStreamWrapper::FileOutputStreamWrapper(nsISupports* aFileStream,
|
FileOutputStreamWrapper::FileOutputStreamWrapper(nsISupports* aFileStream,
|
||||||
FileHelper* aFileHelper,
|
FileHelper* aFileHelper,
|
||||||
uint64_t aOffset,
|
uint64_t aOffset,
|
||||||
|
|
|
@ -11,8 +11,13 @@
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsIInputStream.h"
|
#include "nsIInputStream.h"
|
||||||
#include "nsIOutputStream.h"
|
#include "nsIOutputStream.h"
|
||||||
|
#include "nsIIPCSerializableInputStream.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
namespace ipc {
|
||||||
|
class InputStreamParams;
|
||||||
|
} // namespace ipc
|
||||||
|
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
class FileHelper;
|
class FileHelper;
|
||||||
|
@ -46,11 +51,15 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileInputStreamWrapper : public FileStreamWrapper,
|
class FileInputStreamWrapper : public FileStreamWrapper,
|
||||||
public nsIInputStream
|
public nsIInputStream,
|
||||||
|
public nsIIPCSerializableInputStream
|
||||||
{
|
{
|
||||||
|
typedef mozilla::ipc::InputStreamParams InputStreamParams;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
NS_DECL_NSIINPUTSTREAM
|
NS_DECL_NSIINPUTSTREAM
|
||||||
|
NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
|
||||||
|
|
||||||
FileInputStreamWrapper(nsISupports* aFileStream,
|
FileInputStreamWrapper(nsISupports* aFileStream,
|
||||||
FileHelper* aFileHelper,
|
FileHelper* aFileHelper,
|
||||||
|
|
|
@ -28,6 +28,8 @@ UNIFIED_SOURCES += [
|
||||||
|
|
||||||
FAIL_ON_WARNINGS = True
|
FAIL_ON_WARNINGS = True
|
||||||
|
|
||||||
|
include('/ipc/chromium/chromium-config.mozbuild')
|
||||||
|
|
||||||
LOCAL_INCLUDES += [
|
LOCAL_INCLUDES += [
|
||||||
'../base',
|
'../base',
|
||||||
]
|
]
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
#include "mozilla/dom/FileSystemBase.h"
|
#include "mozilla/dom/FileSystemBase.h"
|
||||||
#include "mozilla/dom/FileSystemUtils.h"
|
#include "mozilla/dom/FileSystemUtils.h"
|
||||||
#include "mozilla/dom/Promise.h"
|
#include "mozilla/dom/Promise.h"
|
||||||
|
#include "mozilla/dom/ipc/BlobChild.h"
|
||||||
|
#include "mozilla/dom/ipc/BlobParent.h"
|
||||||
#include "nsDOMFile.h"
|
#include "nsDOMFile.h"
|
||||||
#include "nsIFile.h"
|
#include "nsIFile.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "mozilla/dom/FileSystemUtils.h"
|
#include "mozilla/dom/FileSystemUtils.h"
|
||||||
#include "mozilla/dom/Promise.h"
|
#include "mozilla/dom/Promise.h"
|
||||||
#include "mozilla/dom/PContent.h"
|
#include "mozilla/dom/PContent.h"
|
||||||
|
#include "mozilla/dom/ipc/BlobParent.h"
|
||||||
#include "mozilla/unused.h"
|
#include "mozilla/unused.h"
|
||||||
#include "nsDOMFile.h"
|
#include "nsDOMFile.h"
|
||||||
|
|
||||||
|
|
|
@ -10,13 +10,13 @@
|
||||||
#include "mozilla/ErrorResult.h"
|
#include "mozilla/ErrorResult.h"
|
||||||
#include "mozilla/dom/FileSystemRequestParent.h"
|
#include "mozilla/dom/FileSystemRequestParent.h"
|
||||||
#include "mozilla/dom/PFileSystemRequestChild.h"
|
#include "mozilla/dom/PFileSystemRequestChild.h"
|
||||||
#include "mozilla/dom/ipc/Blob.h"
|
|
||||||
|
|
||||||
class nsIDOMFile;
|
class nsIDOMFile;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
|
class BlobParent;
|
||||||
class FileSystemBase;
|
class FileSystemBase;
|
||||||
class FileSystemParams;
|
class FileSystemParams;
|
||||||
class Promise;
|
class Promise;
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
#include "mozilla/dom/FileSystemBase.h"
|
#include "mozilla/dom/FileSystemBase.h"
|
||||||
#include "mozilla/dom/FileSystemUtils.h"
|
#include "mozilla/dom/FileSystemUtils.h"
|
||||||
#include "mozilla/dom/Promise.h"
|
#include "mozilla/dom/Promise.h"
|
||||||
|
#include "mozilla/dom/ipc/BlobChild.h"
|
||||||
|
#include "mozilla/dom/ipc/BlobParent.h"
|
||||||
#include "nsDOMFile.h"
|
#include "nsDOMFile.h"
|
||||||
#include "nsIFile.h"
|
#include "nsIFile.h"
|
||||||
#include "nsStringGlue.h"
|
#include "nsStringGlue.h"
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include "mozilla/dom/FileSystemBase.h"
|
#include "mozilla/dom/FileSystemBase.h"
|
||||||
#include "mozilla/dom/FileSystemUtils.h"
|
#include "mozilla/dom/FileSystemUtils.h"
|
||||||
#include "mozilla/dom/Promise.h"
|
#include "mozilla/dom/Promise.h"
|
||||||
|
#include "mozilla/dom/ipc/BlobChild.h"
|
||||||
|
#include "mozilla/dom/ipc/BlobParent.h"
|
||||||
#include "nsDOMFile.h"
|
#include "nsDOMFile.h"
|
||||||
#include "nsIFile.h"
|
#include "nsIFile.h"
|
||||||
#include "nsStringGlue.h"
|
#include "nsStringGlue.h"
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,627 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef mozilla_dom_indexeddb_actorschild_h__
|
||||||
|
#define mozilla_dom_indexeddb_actorschild_h__
|
||||||
|
|
||||||
|
#include "js/RootingAPI.h"
|
||||||
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "mozilla/dom/indexedDB/PBackgroundIDBCursorChild.h"
|
||||||
|
#include "mozilla/dom/indexedDB/PBackgroundIDBDatabaseChild.h"
|
||||||
|
#include "mozilla/dom/indexedDB/PBackgroundIDBFactoryChild.h"
|
||||||
|
#include "mozilla/dom/indexedDB/PBackgroundIDBFactoryRequestChild.h"
|
||||||
|
#include "mozilla/dom/indexedDB/PBackgroundIDBRequestChild.h"
|
||||||
|
#include "mozilla/dom/indexedDB/PBackgroundIDBTransactionChild.h"
|
||||||
|
#include "mozilla/dom/indexedDB/PBackgroundIDBVersionChangeTransactionChild.h"
|
||||||
|
#include "nsAutoPtr.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsTArray.h"
|
||||||
|
|
||||||
|
class nsIEventTarget;
|
||||||
|
struct PRThread;
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace ipc {
|
||||||
|
|
||||||
|
class BackgroundChildImpl;
|
||||||
|
|
||||||
|
} // namespace ipc
|
||||||
|
|
||||||
|
namespace dom {
|
||||||
|
namespace indexedDB {
|
||||||
|
|
||||||
|
class FileInfo;
|
||||||
|
class IDBCursor;
|
||||||
|
class IDBDatabase;
|
||||||
|
class IDBFactory;
|
||||||
|
class IDBMutableFile;
|
||||||
|
class IDBOpenDBRequest;
|
||||||
|
class IDBRequest;
|
||||||
|
class IDBTransaction;
|
||||||
|
class Key;
|
||||||
|
class PBackgroundIDBFileChild;
|
||||||
|
class PermissionRequestChild;
|
||||||
|
class PermissionRequestParent;
|
||||||
|
class SerializedStructuredCloneReadInfo;
|
||||||
|
|
||||||
|
class BackgroundFactoryChild MOZ_FINAL
|
||||||
|
: public PBackgroundIDBFactoryChild
|
||||||
|
{
|
||||||
|
friend class mozilla::ipc::BackgroundChildImpl;
|
||||||
|
friend class IDBFactory;
|
||||||
|
|
||||||
|
IDBFactory* mFactory;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
nsCOMPtr<nsIEventTarget> mOwningThread;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public:
|
||||||
|
void
|
||||||
|
AssertIsOnOwningThread() const
|
||||||
|
#ifdef DEBUG
|
||||||
|
;
|
||||||
|
#else
|
||||||
|
{ }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
IDBFactory*
|
||||||
|
GetDOMObject() const
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
return mFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Only created by IDBFactory.
|
||||||
|
BackgroundFactoryChild(IDBFactory* aFactory);
|
||||||
|
|
||||||
|
// Only destroyed by mozilla::ipc::BackgroundChildImpl.
|
||||||
|
~BackgroundFactoryChild();
|
||||||
|
|
||||||
|
void
|
||||||
|
SendDeleteMeInternal();
|
||||||
|
|
||||||
|
// IPDL methods are only called by IPDL.
|
||||||
|
virtual void
|
||||||
|
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual PBackgroundIDBFactoryRequestChild*
|
||||||
|
AllocPBackgroundIDBFactoryRequestChild(const FactoryRequestParams& aParams)
|
||||||
|
MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
DeallocPBackgroundIDBFactoryRequestChild(
|
||||||
|
PBackgroundIDBFactoryRequestChild* aActor)
|
||||||
|
MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual PBackgroundIDBDatabaseChild*
|
||||||
|
AllocPBackgroundIDBDatabaseChild(const DatabaseSpec& aSpec,
|
||||||
|
PBackgroundIDBFactoryRequestChild* aRequest)
|
||||||
|
MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
DeallocPBackgroundIDBDatabaseChild(PBackgroundIDBDatabaseChild* aActor)
|
||||||
|
MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
bool
|
||||||
|
SendDeleteMe() MOZ_DELETE;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BackgroundDatabaseChild;
|
||||||
|
|
||||||
|
class BackgroundRequestChildBase
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
nsRefPtr<IDBRequest> mRequest;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool mActorDestroyed;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void
|
||||||
|
AssertIsOnOwningThread() const
|
||||||
|
#ifdef DEBUG
|
||||||
|
;
|
||||||
|
#else
|
||||||
|
{ }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
IDBRequest*
|
||||||
|
GetDOMObject() const
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
return mRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
IsActorDestroyed() const
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
return mActorDestroyed;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BackgroundRequestChildBase(IDBRequest* aRequest);
|
||||||
|
|
||||||
|
virtual
|
||||||
|
~BackgroundRequestChildBase();
|
||||||
|
|
||||||
|
void
|
||||||
|
NoteActorDestroyed();
|
||||||
|
};
|
||||||
|
|
||||||
|
class BackgroundFactoryRequestChild MOZ_FINAL
|
||||||
|
: public BackgroundRequestChildBase
|
||||||
|
, public PBackgroundIDBFactoryRequestChild
|
||||||
|
{
|
||||||
|
typedef mozilla::dom::quota::PersistenceType PersistenceType;
|
||||||
|
|
||||||
|
friend class IDBFactory;
|
||||||
|
friend class BackgroundFactoryChild;
|
||||||
|
friend class BackgroundDatabaseChild;
|
||||||
|
friend class PermissionRequestChild;
|
||||||
|
friend class PermissionRequestParent;
|
||||||
|
|
||||||
|
nsRefPtr<IDBFactory> mFactory;
|
||||||
|
const uint64_t mRequestedVersion;
|
||||||
|
const PersistenceType mPersistenceType;
|
||||||
|
const bool mIsDeleteOp;
|
||||||
|
|
||||||
|
public:
|
||||||
|
IDBOpenDBRequest*
|
||||||
|
GetOpenDBRequest() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Only created by IDBFactory.
|
||||||
|
BackgroundFactoryRequestChild(IDBFactory* aFactory,
|
||||||
|
IDBOpenDBRequest* aOpenRequest,
|
||||||
|
bool aIsDeleteOp,
|
||||||
|
uint64_t aRequestedVersion,
|
||||||
|
PersistenceType aPersistenceType);
|
||||||
|
|
||||||
|
// Only destroyed by BackgroundFactoryChild.
|
||||||
|
~BackgroundFactoryRequestChild();
|
||||||
|
|
||||||
|
bool
|
||||||
|
HandleResponse(nsresult aResponse);
|
||||||
|
|
||||||
|
bool
|
||||||
|
HandleResponse(const OpenDatabaseRequestResponse& aResponse);
|
||||||
|
|
||||||
|
bool
|
||||||
|
HandleResponse(const DeleteDatabaseRequestResponse& aResponse);
|
||||||
|
|
||||||
|
// IPDL methods are only called by IPDL.
|
||||||
|
virtual void
|
||||||
|
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
Recv__delete__(const FactoryRequestResponse& aResponse) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
RecvPermissionChallenge(const PrincipalInfo& aPrincipalInfo) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
RecvBlocked(const uint64_t& aCurrentVersion) MOZ_OVERRIDE;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BackgroundDatabaseChild MOZ_FINAL
|
||||||
|
: public PBackgroundIDBDatabaseChild
|
||||||
|
{
|
||||||
|
typedef mozilla::dom::quota::PersistenceType PersistenceType;
|
||||||
|
|
||||||
|
friend class BackgroundFactoryChild;
|
||||||
|
friend class BackgroundFactoryRequestChild;
|
||||||
|
friend class IDBDatabase;
|
||||||
|
|
||||||
|
nsAutoPtr<DatabaseSpec> mSpec;
|
||||||
|
nsRefPtr<IDBDatabase> mTemporaryStrongDatabase;
|
||||||
|
BackgroundFactoryRequestChild* mOpenRequestActor;
|
||||||
|
IDBDatabase* mDatabase;
|
||||||
|
|
||||||
|
PersistenceType mPersistenceType;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void
|
||||||
|
AssertIsOnOwningThread() const
|
||||||
|
{
|
||||||
|
static_cast<BackgroundFactoryChild*>(Manager())->AssertIsOnOwningThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
const DatabaseSpec*
|
||||||
|
Spec() const
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
return mSpec;
|
||||||
|
}
|
||||||
|
|
||||||
|
IDBDatabase*
|
||||||
|
GetDOMObject() const
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
return mDatabase;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Only constructed by BackgroundFactoryChild.
|
||||||
|
BackgroundDatabaseChild(const DatabaseSpec& aSpec,
|
||||||
|
BackgroundFactoryRequestChild* aOpenRequest);
|
||||||
|
|
||||||
|
// Only destroyed by BackgroundFactoryChild.
|
||||||
|
~BackgroundDatabaseChild();
|
||||||
|
|
||||||
|
void
|
||||||
|
SendDeleteMeInternal();
|
||||||
|
|
||||||
|
void
|
||||||
|
EnsureDOMObject();
|
||||||
|
|
||||||
|
void
|
||||||
|
ReleaseDOMObject();
|
||||||
|
|
||||||
|
// IPDL methods are only called by IPDL.
|
||||||
|
virtual void
|
||||||
|
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual PBackgroundIDBDatabaseFileChild*
|
||||||
|
AllocPBackgroundIDBDatabaseFileChild(
|
||||||
|
const BlobOrInputStream& aBlobOrInputStream)
|
||||||
|
MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
DeallocPBackgroundIDBDatabaseFileChild(
|
||||||
|
PBackgroundIDBDatabaseFileChild* aActor)
|
||||||
|
MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual PBackgroundIDBTransactionChild*
|
||||||
|
AllocPBackgroundIDBTransactionChild(
|
||||||
|
const nsTArray<nsString>& aObjectStoreNames,
|
||||||
|
const Mode& aMode)
|
||||||
|
MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
DeallocPBackgroundIDBTransactionChild(PBackgroundIDBTransactionChild* aActor)
|
||||||
|
MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual PBackgroundIDBVersionChangeTransactionChild*
|
||||||
|
AllocPBackgroundIDBVersionChangeTransactionChild(
|
||||||
|
const uint64_t& aCurrentVersion,
|
||||||
|
const uint64_t& aRequestedVersion,
|
||||||
|
const int64_t& aNextObjectStoreId,
|
||||||
|
const int64_t& aNextIndexId)
|
||||||
|
MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
RecvPBackgroundIDBVersionChangeTransactionConstructor(
|
||||||
|
PBackgroundIDBVersionChangeTransactionChild* aActor,
|
||||||
|
const uint64_t& aCurrentVersion,
|
||||||
|
const uint64_t& aRequestedVersion,
|
||||||
|
const int64_t& aNextObjectStoreId,
|
||||||
|
const int64_t& aNextIndexId)
|
||||||
|
MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
DeallocPBackgroundIDBVersionChangeTransactionChild(
|
||||||
|
PBackgroundIDBVersionChangeTransactionChild* aActor)
|
||||||
|
MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
RecvVersionChange(const uint64_t& aOldVersion,
|
||||||
|
const NullableVersion& aNewVersion)
|
||||||
|
MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
RecvInvalidate() MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
bool
|
||||||
|
SendDeleteMe() MOZ_DELETE;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BackgroundVersionChangeTransactionChild;
|
||||||
|
|
||||||
|
class BackgroundTransactionBase
|
||||||
|
{
|
||||||
|
friend class BackgroundVersionChangeTransactionChild;
|
||||||
|
|
||||||
|
// mTemporaryStrongTransaction is strong and is only valid until the end of
|
||||||
|
// NoteComplete() member function or until the NoteActorDestroyed() member
|
||||||
|
// function is called.
|
||||||
|
nsRefPtr<IDBTransaction> mTemporaryStrongTransaction;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// mTransaction is weak and is valid until the NoteActorDestroyed() member
|
||||||
|
// function is called.
|
||||||
|
IDBTransaction* mTransaction;
|
||||||
|
|
||||||
|
public:
|
||||||
|
#ifdef DEBUG
|
||||||
|
virtual void
|
||||||
|
AssertIsOnOwningThread() const = 0;
|
||||||
|
#else
|
||||||
|
void
|
||||||
|
AssertIsOnOwningThread() const
|
||||||
|
{ }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
IDBTransaction*
|
||||||
|
GetDOMObject() const
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
return mTransaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BackgroundTransactionBase();
|
||||||
|
BackgroundTransactionBase(IDBTransaction* aTransaction);
|
||||||
|
|
||||||
|
virtual
|
||||||
|
~BackgroundTransactionBase();
|
||||||
|
|
||||||
|
void
|
||||||
|
NoteActorDestroyed();
|
||||||
|
|
||||||
|
void
|
||||||
|
NoteComplete();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Only called by BackgroundVersionChangeTransactionChild.
|
||||||
|
void
|
||||||
|
SetDOMTransaction(IDBTransaction* aDOMObject);
|
||||||
|
};
|
||||||
|
|
||||||
|
class BackgroundTransactionChild MOZ_FINAL
|
||||||
|
: public BackgroundTransactionBase
|
||||||
|
, public PBackgroundIDBTransactionChild
|
||||||
|
{
|
||||||
|
friend class BackgroundDatabaseChild;
|
||||||
|
friend class IDBDatabase;
|
||||||
|
|
||||||
|
public:
|
||||||
|
#ifdef DEBUG
|
||||||
|
virtual void
|
||||||
|
AssertIsOnOwningThread() const MOZ_OVERRIDE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
SendDeleteMeInternal();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Only created by IDBDatabase.
|
||||||
|
BackgroundTransactionChild(IDBTransaction* aTransaction);
|
||||||
|
|
||||||
|
// Only destroyed by BackgroundDatabaseChild.
|
||||||
|
~BackgroundTransactionChild();
|
||||||
|
|
||||||
|
// IPDL methods are only called by IPDL.
|
||||||
|
virtual void
|
||||||
|
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
bool
|
||||||
|
RecvComplete(const nsresult& aResult) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual PBackgroundIDBRequestChild*
|
||||||
|
AllocPBackgroundIDBRequestChild(const RequestParams& aParams) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
DeallocPBackgroundIDBRequestChild(PBackgroundIDBRequestChild* aActor)
|
||||||
|
MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual PBackgroundIDBCursorChild*
|
||||||
|
AllocPBackgroundIDBCursorChild(const OpenCursorParams& aParams) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
DeallocPBackgroundIDBCursorChild(PBackgroundIDBCursorChild* aActor)
|
||||||
|
MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
bool
|
||||||
|
SendDeleteMe() MOZ_DELETE;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BackgroundVersionChangeTransactionChild MOZ_FINAL
|
||||||
|
: public BackgroundTransactionBase
|
||||||
|
, public PBackgroundIDBVersionChangeTransactionChild
|
||||||
|
{
|
||||||
|
friend class BackgroundDatabaseChild;
|
||||||
|
|
||||||
|
IDBOpenDBRequest* mOpenDBRequest;
|
||||||
|
|
||||||
|
public:
|
||||||
|
#ifdef DEBUG
|
||||||
|
virtual void
|
||||||
|
AssertIsOnOwningThread() const MOZ_OVERRIDE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
SendDeleteMeInternal();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Only created by BackgroundDatabaseChild.
|
||||||
|
BackgroundVersionChangeTransactionChild(IDBOpenDBRequest* aOpenDBRequest);
|
||||||
|
|
||||||
|
// Only destroyed by BackgroundDatabaseChild.
|
||||||
|
~BackgroundVersionChangeTransactionChild();
|
||||||
|
|
||||||
|
// Only called by BackgroundDatabaseChild.
|
||||||
|
void
|
||||||
|
SetDOMTransaction(IDBTransaction* aDOMObject)
|
||||||
|
{
|
||||||
|
BackgroundTransactionBase::SetDOMTransaction(aDOMObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPDL methods are only called by IPDL.
|
||||||
|
virtual void
|
||||||
|
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
bool
|
||||||
|
RecvComplete(const nsresult& aResult) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual PBackgroundIDBRequestChild*
|
||||||
|
AllocPBackgroundIDBRequestChild(const RequestParams& aParams) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
DeallocPBackgroundIDBRequestChild(PBackgroundIDBRequestChild* aActor)
|
||||||
|
MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual PBackgroundIDBCursorChild*
|
||||||
|
AllocPBackgroundIDBCursorChild(const OpenCursorParams& aParams) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
DeallocPBackgroundIDBCursorChild(PBackgroundIDBCursorChild* aActor)
|
||||||
|
MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
bool
|
||||||
|
SendDeleteMe() MOZ_DELETE;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BackgroundRequestChild MOZ_FINAL
|
||||||
|
: public BackgroundRequestChildBase
|
||||||
|
, public PBackgroundIDBRequestChild
|
||||||
|
{
|
||||||
|
friend class BackgroundTransactionChild;
|
||||||
|
friend class BackgroundVersionChangeTransactionChild;
|
||||||
|
|
||||||
|
nsRefPtr<IDBTransaction> mTransaction;
|
||||||
|
nsTArray<nsRefPtr<FileInfo>> mFileInfos;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BackgroundRequestChild(IDBRequest* aRequest);
|
||||||
|
|
||||||
|
void
|
||||||
|
HoldFileInfosUntilComplete(nsTArray<nsRefPtr<FileInfo>>& aFileInfos);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Only destroyed by BackgroundTransactionChild or
|
||||||
|
// BackgroundVersionChangeTransactionChild.
|
||||||
|
~BackgroundRequestChild();
|
||||||
|
|
||||||
|
void
|
||||||
|
MaybeFinishTransactionEarly();
|
||||||
|
|
||||||
|
bool
|
||||||
|
HandleResponse(nsresult aResponse);
|
||||||
|
|
||||||
|
bool
|
||||||
|
HandleResponse(const Key& aResponse);
|
||||||
|
|
||||||
|
bool
|
||||||
|
HandleResponse(const nsTArray<Key>& aResponse);
|
||||||
|
|
||||||
|
bool
|
||||||
|
HandleResponse(const SerializedStructuredCloneReadInfo& aResponse);
|
||||||
|
|
||||||
|
bool
|
||||||
|
HandleResponse(const nsTArray<SerializedStructuredCloneReadInfo>& aResponse);
|
||||||
|
|
||||||
|
bool
|
||||||
|
HandleResponse(JS::Handle<JS::Value> aResponse);
|
||||||
|
|
||||||
|
bool
|
||||||
|
HandleResponse(uint64_t aResponse);
|
||||||
|
|
||||||
|
// IPDL methods are only called by IPDL.
|
||||||
|
virtual void
|
||||||
|
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
Recv__delete__(const RequestResponse& aResponse) MOZ_OVERRIDE;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BackgroundCursorChild MOZ_FINAL
|
||||||
|
: public PBackgroundIDBCursorChild
|
||||||
|
{
|
||||||
|
friend class BackgroundTransactionChild;
|
||||||
|
friend class BackgroundVersionChangeTransactionChild;
|
||||||
|
|
||||||
|
class DelayedDeleteRunnable;
|
||||||
|
|
||||||
|
IDBRequest* mRequest;
|
||||||
|
IDBTransaction* mTransaction;
|
||||||
|
IDBObjectStore* mObjectStore;
|
||||||
|
IDBIndex* mIndex;
|
||||||
|
IDBCursor* mCursor;
|
||||||
|
|
||||||
|
// These are only set while a request is in progress.
|
||||||
|
nsRefPtr<IDBRequest> mStrongRequest;
|
||||||
|
nsRefPtr<IDBCursor> mStrongCursor;
|
||||||
|
|
||||||
|
Direction mDirection;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
PRThread* mOwningThread;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public:
|
||||||
|
BackgroundCursorChild(IDBRequest* aRequest,
|
||||||
|
IDBObjectStore* aObjectStore,
|
||||||
|
Direction aDirection);
|
||||||
|
|
||||||
|
BackgroundCursorChild(IDBRequest* aRequest,
|
||||||
|
IDBIndex* aIndex,
|
||||||
|
Direction aDirection);
|
||||||
|
|
||||||
|
void
|
||||||
|
AssertIsOnOwningThread() const
|
||||||
|
#ifdef DEBUG
|
||||||
|
;
|
||||||
|
#else
|
||||||
|
{ }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
SendContinueInternal(const CursorRequestParams& aParams);
|
||||||
|
|
||||||
|
void
|
||||||
|
SendDeleteMeInternal();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Only destroyed by BackgroundTransactionChild or
|
||||||
|
// BackgroundVersionChangeTransactionChild.
|
||||||
|
~BackgroundCursorChild();
|
||||||
|
|
||||||
|
void
|
||||||
|
HandleResponse(nsresult aResponse);
|
||||||
|
|
||||||
|
void
|
||||||
|
HandleResponse(const void_t& aResponse);
|
||||||
|
|
||||||
|
void
|
||||||
|
HandleResponse(const ObjectStoreCursorResponse& aResponse);
|
||||||
|
|
||||||
|
void
|
||||||
|
HandleResponse(const ObjectStoreKeyCursorResponse& aResponse);
|
||||||
|
|
||||||
|
void
|
||||||
|
HandleResponse(const IndexCursorResponse& aResponse);
|
||||||
|
|
||||||
|
void
|
||||||
|
HandleResponse(const IndexKeyCursorResponse& aResponse);
|
||||||
|
|
||||||
|
// IPDL methods are only called by IPDL.
|
||||||
|
virtual void
|
||||||
|
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
RecvResponse(const CursorResponse& aResponse) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
// Force callers to use SendContinueInternal.
|
||||||
|
bool
|
||||||
|
SendContinue(const CursorRequestParams& aParams) MOZ_DELETE;
|
||||||
|
|
||||||
|
bool
|
||||||
|
SendDeleteMe() MOZ_DELETE;
|
||||||
|
};
|
||||||
|
|
||||||
|
// XXX This doesn't belong here. However, we're not yet porting MutableFile
|
||||||
|
// stuff to PBackground so this is necessary for the time being.
|
||||||
|
void
|
||||||
|
DispatchMutableFileResult(IDBRequest* aRequest,
|
||||||
|
nsresult aResultCode,
|
||||||
|
IDBMutableFile* aMutableFile);
|
||||||
|
|
||||||
|
} // namespace indexedDB
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // mozilla_dom_indexeddb_actorschild_h__
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,67 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef mozilla_dom_indexeddb_actorsparent_h__
|
||||||
|
#define mozilla_dom_indexeddb_actorsparent_h__
|
||||||
|
|
||||||
|
template <class> struct already_AddRefed;
|
||||||
|
class nsCString;
|
||||||
|
class nsIPrincipal;
|
||||||
|
class nsPIDOMWindow;
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace ipc {
|
||||||
|
|
||||||
|
class PBackgroundParent;
|
||||||
|
|
||||||
|
} // namespace ipc
|
||||||
|
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
class TabParent;
|
||||||
|
|
||||||
|
namespace quota {
|
||||||
|
|
||||||
|
class Client;
|
||||||
|
|
||||||
|
} // namespace quota
|
||||||
|
|
||||||
|
namespace indexedDB {
|
||||||
|
|
||||||
|
class OptionalWindowId;
|
||||||
|
class PBackgroundIDBFactoryParent;
|
||||||
|
class PIndexedDBPermissionRequestParent;
|
||||||
|
|
||||||
|
PBackgroundIDBFactoryParent*
|
||||||
|
AllocPBackgroundIDBFactoryParent(mozilla::ipc::PBackgroundParent* aManager,
|
||||||
|
const OptionalWindowId& aOptionalWindowId);
|
||||||
|
|
||||||
|
bool
|
||||||
|
RecvPBackgroundIDBFactoryConstructor(mozilla::ipc::PBackgroundParent* aManager,
|
||||||
|
PBackgroundIDBFactoryParent* aActor,
|
||||||
|
const OptionalWindowId& aOptionalWindowId);
|
||||||
|
|
||||||
|
bool
|
||||||
|
DeallocPBackgroundIDBFactoryParent(PBackgroundIDBFactoryParent* aActor);
|
||||||
|
|
||||||
|
PIndexedDBPermissionRequestParent*
|
||||||
|
AllocPIndexedDBPermissionRequestParent(nsPIDOMWindow* aWindow,
|
||||||
|
nsIPrincipal* aPrincipal);
|
||||||
|
|
||||||
|
bool
|
||||||
|
RecvPIndexedDBPermissionRequestConstructor(
|
||||||
|
PIndexedDBPermissionRequestParent* aActor);
|
||||||
|
|
||||||
|
bool
|
||||||
|
DeallocPIndexedDBPermissionRequestParent(
|
||||||
|
PIndexedDBPermissionRequestParent* aActor);
|
||||||
|
|
||||||
|
already_AddRefed<mozilla::dom::quota::Client>
|
||||||
|
CreateQuotaClient();
|
||||||
|
|
||||||
|
} // namespace indexedDB
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // mozilla_dom_indexeddb_actorsparent_h__
|
|
@ -1,710 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* vim: set ts=2 et sw=2 tw=80: */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "base/basictypes.h"
|
|
||||||
|
|
||||||
#include "AsyncConnectionHelper.h"
|
|
||||||
|
|
||||||
#include "mozilla/dom/quota/QuotaManager.h"
|
|
||||||
#include "mozilla/storage.h"
|
|
||||||
#include "nsComponentManagerUtils.h"
|
|
||||||
#include "nsContentUtils.h"
|
|
||||||
#include "nsProxyRelease.h"
|
|
||||||
#include "nsThreadUtils.h"
|
|
||||||
#include "nsWrapperCacheInlines.h"
|
|
||||||
|
|
||||||
#include "IDBEvents.h"
|
|
||||||
#include "IDBTransaction.h"
|
|
||||||
#include "IndexedDatabaseManager.h"
|
|
||||||
#include "ProfilerHelpers.h"
|
|
||||||
#include "ReportInternalError.h"
|
|
||||||
#include "TransactionThreadPool.h"
|
|
||||||
|
|
||||||
#include "ipc/IndexedDBChild.h"
|
|
||||||
#include "ipc/IndexedDBParent.h"
|
|
||||||
|
|
||||||
using namespace mozilla;
|
|
||||||
USING_INDEXEDDB_NAMESPACE
|
|
||||||
using mozilla::dom::quota::QuotaManager;
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
IDBTransaction* gCurrentTransaction = nullptr;
|
|
||||||
|
|
||||||
const uint32_t kProgressHandlerGranularity = 1000;
|
|
||||||
|
|
||||||
class MOZ_STACK_CLASS TransactionPoolEventTarget : public StackBasedEventTarget
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
NS_DECL_NSIEVENTTARGET
|
|
||||||
|
|
||||||
explicit TransactionPoolEventTarget(IDBTransaction* aTransaction)
|
|
||||||
: mTransaction(aTransaction)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
private:
|
|
||||||
IDBTransaction* mTransaction;
|
|
||||||
};
|
|
||||||
|
|
||||||
// This inline is just so that we always clear aBuffers appropriately even if
|
|
||||||
// something fails.
|
|
||||||
inline
|
|
||||||
nsresult
|
|
||||||
ConvertCloneReadInfosToArrayInternal(
|
|
||||||
JSContext* aCx,
|
|
||||||
nsTArray<StructuredCloneReadInfo>& aReadInfos,
|
|
||||||
JS::MutableHandle<JS::Value> aResult)
|
|
||||||
{
|
|
||||||
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, 0));
|
|
||||||
if (!array) {
|
|
||||||
IDB_WARNING("Failed to make array!");
|
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!aReadInfos.IsEmpty()) {
|
|
||||||
if (!JS_SetArrayLength(aCx, array, uint32_t(aReadInfos.Length()))) {
|
|
||||||
IDB_WARNING("Failed to set array length!");
|
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t index = 0, count = aReadInfos.Length(); index < count;
|
|
||||||
index++) {
|
|
||||||
StructuredCloneReadInfo& readInfo = aReadInfos[index];
|
|
||||||
|
|
||||||
JS::Rooted<JS::Value> val(aCx);
|
|
||||||
if (!IDBObjectStore::DeserializeValue(aCx, readInfo, &val)) {
|
|
||||||
NS_WARNING("Failed to decode!");
|
|
||||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!JS_SetElement(aCx, array, index, val)) {
|
|
||||||
IDB_WARNING("Failed to set array element!");
|
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
aResult.setObject(*array);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
HelperBase::~HelperBase()
|
|
||||||
{
|
|
||||||
if (!NS_IsMainThread()) {
|
|
||||||
IDBRequest* request;
|
|
||||||
mRequest.forget(&request);
|
|
||||||
|
|
||||||
if (request) {
|
|
||||||
nsCOMPtr<nsIThread> mainThread;
|
|
||||||
NS_GetMainThread(getter_AddRefs(mainThread));
|
|
||||||
NS_WARN_IF_FALSE(mainThread, "Couldn't get the main thread!");
|
|
||||||
|
|
||||||
if (mainThread) {
|
|
||||||
NS_ProxyRelease(mainThread, static_cast<EventTarget*>(request));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
HelperBase::WrapNative(JSContext* aCx,
|
|
||||||
nsISupports* aNative,
|
|
||||||
JS::MutableHandle<JS::Value> aResult)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(aCx, "Null context!");
|
|
||||||
NS_ASSERTION(aNative, "Null pointer!");
|
|
||||||
NS_ASSERTION(aResult.address(), "Null pointer!");
|
|
||||||
NS_ASSERTION(mRequest, "Null request!");
|
|
||||||
|
|
||||||
nsresult rv = nsContentUtils::WrapNative(aCx, aNative, aResult);
|
|
||||||
IDB_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
HelperBase::ReleaseMainThreadObjects()
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
|
|
||||||
mRequest = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
AsyncConnectionHelper::AsyncConnectionHelper(IDBDatabase* aDatabase,
|
|
||||||
IDBRequest* aRequest)
|
|
||||||
: HelperBase(aRequest),
|
|
||||||
mDatabase(aDatabase),
|
|
||||||
mResultCode(NS_OK),
|
|
||||||
mDispatched(false)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
}
|
|
||||||
|
|
||||||
AsyncConnectionHelper::AsyncConnectionHelper(IDBTransaction* aTransaction,
|
|
||||||
IDBRequest* aRequest)
|
|
||||||
: HelperBase(aRequest),
|
|
||||||
mDatabase(aTransaction->mDatabase),
|
|
||||||
mTransaction(aTransaction),
|
|
||||||
mResultCode(NS_OK),
|
|
||||||
mDispatched(false)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
}
|
|
||||||
|
|
||||||
AsyncConnectionHelper::~AsyncConnectionHelper()
|
|
||||||
{
|
|
||||||
if (!NS_IsMainThread()) {
|
|
||||||
IDBDatabase* database;
|
|
||||||
mDatabase.forget(&database);
|
|
||||||
|
|
||||||
IDBTransaction* transaction;
|
|
||||||
mTransaction.forget(&transaction);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIThread> mainThread;
|
|
||||||
NS_GetMainThread(getter_AddRefs(mainThread));
|
|
||||||
NS_WARN_IF_FALSE(mainThread, "Couldn't get the main thread!");
|
|
||||||
|
|
||||||
if (mainThread) {
|
|
||||||
if (database) {
|
|
||||||
NS_ProxyRelease(mainThread, static_cast<IDBWrapperCache*>(database));
|
|
||||||
}
|
|
||||||
if (transaction) {
|
|
||||||
NS_ProxyRelease(mainThread, static_cast<IDBWrapperCache*>(transaction));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ASSERTION(!mOldProgressHandler, "Should not have anything here!");
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(AsyncConnectionHelper, nsIRunnable,
|
|
||||||
mozIStorageProgressHandler)
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
AsyncConnectionHelper::Run()
|
|
||||||
{
|
|
||||||
if (NS_IsMainThread()) {
|
|
||||||
PROFILER_MAIN_THREAD_LABEL("AsyncConnectionHelper", "Run",
|
|
||||||
js::ProfileEntry::Category::STORAGE);
|
|
||||||
|
|
||||||
if (mTransaction &&
|
|
||||||
mTransaction->IsAborted()) {
|
|
||||||
// Always fire a "error" event with ABORT_ERR if the transaction was
|
|
||||||
// aborted, even if the request succeeded or failed with another error.
|
|
||||||
mResultCode = NS_ERROR_DOM_INDEXEDDB_ABORT_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
IDBTransaction* oldTransaction = gCurrentTransaction;
|
|
||||||
gCurrentTransaction = mTransaction;
|
|
||||||
|
|
||||||
ChildProcessSendResult sendResult =
|
|
||||||
IndexedDatabaseManager::IsMainProcess() ?
|
|
||||||
MaybeSendResponseToChildProcess(mResultCode) :
|
|
||||||
Success_NotSent;
|
|
||||||
|
|
||||||
switch (sendResult) {
|
|
||||||
case Success_Sent: {
|
|
||||||
if (mRequest) {
|
|
||||||
mRequest->NotifyHelperSentResultsToChildProcess(NS_OK);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Success_NotSent: {
|
|
||||||
if (mRequest) {
|
|
||||||
nsresult rv = mRequest->NotifyHelperCompleted(this);
|
|
||||||
if (NS_SUCCEEDED(mResultCode) && NS_FAILED(rv)) {
|
|
||||||
mResultCode = rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
IDB_PROFILER_MARK("IndexedDB Request %llu: Running main thread "
|
|
||||||
"response (rv = %lu)",
|
|
||||||
"IDBRequest[%llu] MT Done",
|
|
||||||
mRequest->GetSerialNumber(), mResultCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call OnError if the database had an error or if the OnSuccess
|
|
||||||
// handler has an error.
|
|
||||||
if (NS_FAILED(mResultCode) ||
|
|
||||||
NS_FAILED((mResultCode = OnSuccess()))) {
|
|
||||||
OnError();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Success_ActorDisconnected: {
|
|
||||||
// Nothing needs to be done here.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Error: {
|
|
||||||
IDB_WARNING("MaybeSendResultsToChildProcess failed!");
|
|
||||||
mResultCode = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
|
||||||
if (mRequest) {
|
|
||||||
mRequest->NotifyHelperSentResultsToChildProcess(mResultCode);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
MOZ_CRASH("Unknown value for ChildProcessSendResult!");
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ASSERTION(gCurrentTransaction == mTransaction, "Should be unchanged!");
|
|
||||||
gCurrentTransaction = oldTransaction;
|
|
||||||
|
|
||||||
if (mDispatched && mTransaction) {
|
|
||||||
mTransaction->OnRequestFinished();
|
|
||||||
}
|
|
||||||
|
|
||||||
ReleaseMainThreadObjects();
|
|
||||||
|
|
||||||
NS_ASSERTION(!(mDatabase || mTransaction || mRequest), "Subclass didn't "
|
|
||||||
"call AsyncConnectionHelper::ReleaseMainThreadObjects!");
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
|
|
||||||
|
|
||||||
PROFILER_LABEL("AsyncConnectionHelper", "Run",
|
|
||||||
js::ProfileEntry::Category::STORAGE);
|
|
||||||
|
|
||||||
IDB_PROFILER_MARK_IF(mRequest,
|
|
||||||
"IndexedDB Request %llu: Beginning database work",
|
|
||||||
"IDBRequest[%llu] DT Start",
|
|
||||||
mRequest->GetSerialNumber());
|
|
||||||
|
|
||||||
nsresult rv = NS_OK;
|
|
||||||
nsCOMPtr<mozIStorageConnection> connection;
|
|
||||||
|
|
||||||
if (mTransaction) {
|
|
||||||
rv = mTransaction->GetOrCreateConnection(getter_AddRefs(connection));
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
NS_ASSERTION(connection, "This should never be null!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool setProgressHandler = false;
|
|
||||||
if (connection) {
|
|
||||||
rv = connection->SetProgressHandler(kProgressHandlerGranularity, this,
|
|
||||||
getter_AddRefs(mOldProgressHandler));
|
|
||||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "SetProgressHandler failed!");
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
setProgressHandler = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
bool hasSavepoint = false;
|
|
||||||
if (mDatabase) {
|
|
||||||
QuotaManager::SetCurrentWindow(mDatabase->GetOwner());
|
|
||||||
|
|
||||||
// Make the first savepoint.
|
|
||||||
if (mTransaction) {
|
|
||||||
if (!(hasSavepoint = mTransaction->StartSavepoint())) {
|
|
||||||
NS_WARNING("Failed to make savepoint!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mResultCode = DoDatabaseWork(connection);
|
|
||||||
|
|
||||||
if (mDatabase) {
|
|
||||||
// Release or roll back the savepoint depending on the error code.
|
|
||||||
if (hasSavepoint) {
|
|
||||||
NS_ASSERTION(mTransaction, "Huh?!");
|
|
||||||
if (NS_SUCCEEDED(mResultCode)) {
|
|
||||||
mTransaction->ReleaseSavepoint();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mTransaction->RollbackSavepoint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't unset this until we're sure that all SQLite activity has
|
|
||||||
// completed!
|
|
||||||
QuotaManager::SetCurrentWindow(nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// NS_ERROR_NOT_AVAILABLE is our special code for "database is invalidated"
|
|
||||||
// and we should fail with RECOVERABLE_ERR.
|
|
||||||
if (rv == NS_ERROR_NOT_AVAILABLE) {
|
|
||||||
mResultCode = NS_ERROR_DOM_INDEXEDDB_RECOVERABLE_ERR;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
IDB_REPORT_INTERNAL_ERR();
|
|
||||||
mResultCode = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (setProgressHandler) {
|
|
||||||
nsCOMPtr<mozIStorageProgressHandler> handler;
|
|
||||||
rv = connection->RemoveProgressHandler(getter_AddRefs(handler));
|
|
||||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "RemoveProgressHandler failed!");
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
NS_ASSERTION(SameCOMIdentity(handler, static_cast<nsIRunnable*>(this)),
|
|
||||||
"Mismatch!");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
IDB_PROFILER_MARK_IF(mRequest,
|
|
||||||
"IndexedDB Request %llu: Finished database work "
|
|
||||||
"(rv = %lu)",
|
|
||||||
"IDBRequest[%llu] DT Done", mRequest->GetSerialNumber(),
|
|
||||||
mResultCode);
|
|
||||||
|
|
||||||
return NS_DispatchToMainThread(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
AsyncConnectionHelper::OnProgress(mozIStorageConnection* aConnection,
|
|
||||||
bool* _retval)
|
|
||||||
{
|
|
||||||
if (mDatabase && mDatabase->IsInvalidated()) {
|
|
||||||
// Someone is trying to delete the database file. Exit lightningfast!
|
|
||||||
*_retval = true;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mOldProgressHandler) {
|
|
||||||
return mOldProgressHandler->OnProgress(aConnection, _retval);
|
|
||||||
}
|
|
||||||
|
|
||||||
*_retval = false;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
AsyncConnectionHelper::Dispatch(nsIEventTarget* aTarget)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
|
|
||||||
nsresult rv = Init();
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = aTarget->Dispatch(this, NS_DISPATCH_NORMAL);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (mTransaction) {
|
|
||||||
mTransaction->OnNewRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
mDispatched = true;
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
AsyncConnectionHelper::DispatchToTransactionPool()
|
|
||||||
{
|
|
||||||
NS_ASSERTION(mTransaction, "Only ok to call this with a transaction!");
|
|
||||||
TransactionPoolEventTarget target(mTransaction);
|
|
||||||
return Dispatch(&target);
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
void
|
|
||||||
AsyncConnectionHelper::SetCurrentTransaction(IDBTransaction* aTransaction)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
NS_ASSERTION(!aTransaction || !gCurrentTransaction,
|
|
||||||
"Stepping on another transaction!");
|
|
||||||
|
|
||||||
gCurrentTransaction = aTransaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
IDBTransaction*
|
|
||||||
AsyncConnectionHelper::GetCurrentTransaction()
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
|
|
||||||
return gCurrentTransaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
AsyncConnectionHelper::Init()
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<nsIDOMEvent>
|
|
||||||
AsyncConnectionHelper::CreateSuccessEvent(mozilla::dom::EventTarget* aOwner)
|
|
||||||
{
|
|
||||||
return CreateGenericEvent(mRequest, NS_LITERAL_STRING(SUCCESS_EVT_STR),
|
|
||||||
eDoesNotBubble, eNotCancelable);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
AsyncConnectionHelper::OnSuccess()
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
NS_ASSERTION(mRequest, "Null request!");
|
|
||||||
|
|
||||||
PROFILER_MAIN_THREAD_LABEL("AsyncConnectionHelper", "OnSuccess",
|
|
||||||
js::ProfileEntry::Category::STORAGE);
|
|
||||||
|
|
||||||
nsRefPtr<nsIDOMEvent> event = CreateSuccessEvent(mRequest);
|
|
||||||
if (!event) {
|
|
||||||
IDB_WARNING("Failed to create event!");
|
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool dummy;
|
|
||||||
nsresult rv = mRequest->DispatchEvent(event, &dummy);
|
|
||||||
IDB_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
|
|
||||||
WidgetEvent* internalEvent = event->GetInternalNSEvent();
|
|
||||||
NS_ASSERTION(internalEvent, "This should never be null!");
|
|
||||||
|
|
||||||
NS_ASSERTION(!mTransaction ||
|
|
||||||
mTransaction->IsOpen() ||
|
|
||||||
mTransaction->IsAborted(),
|
|
||||||
"How else can this be closed?!");
|
|
||||||
|
|
||||||
if (internalEvent->mFlags.mExceptionHasBeenRisen &&
|
|
||||||
mTransaction &&
|
|
||||||
mTransaction->IsOpen()) {
|
|
||||||
rv = mTransaction->Abort(NS_ERROR_DOM_INDEXEDDB_ABORT_ERR);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
AsyncConnectionHelper::OnError()
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
NS_ASSERTION(mRequest, "Null request!");
|
|
||||||
|
|
||||||
PROFILER_MAIN_THREAD_LABEL("AsyncConnectionHelper", "OnError",
|
|
||||||
js::ProfileEntry::Category::STORAGE);
|
|
||||||
|
|
||||||
// Make an error event and fire it at the target.
|
|
||||||
nsRefPtr<nsIDOMEvent> event =
|
|
||||||
CreateGenericEvent(mRequest, NS_LITERAL_STRING(ERROR_EVT_STR), eDoesBubble,
|
|
||||||
eCancelable);
|
|
||||||
if (!event) {
|
|
||||||
NS_ERROR("Failed to create event!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool doDefault;
|
|
||||||
nsresult rv = mRequest->DispatchEvent(event, &doDefault);
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
NS_ASSERTION(!mTransaction ||
|
|
||||||
mTransaction->IsOpen() ||
|
|
||||||
mTransaction->IsAborted(),
|
|
||||||
"How else can this be closed?!");
|
|
||||||
|
|
||||||
WidgetEvent* internalEvent = event->GetInternalNSEvent();
|
|
||||||
NS_ASSERTION(internalEvent, "This should never be null!");
|
|
||||||
|
|
||||||
if (internalEvent->mFlags.mExceptionHasBeenRisen &&
|
|
||||||
mTransaction &&
|
|
||||||
mTransaction->IsOpen() &&
|
|
||||||
NS_FAILED(mTransaction->Abort(NS_ERROR_DOM_INDEXEDDB_ABORT_ERR))) {
|
|
||||||
NS_WARNING("Failed to abort transaction!");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (doDefault &&
|
|
||||||
mTransaction &&
|
|
||||||
mTransaction->IsOpen() &&
|
|
||||||
NS_FAILED(mTransaction->Abort(mRequest))) {
|
|
||||||
NS_WARNING("Failed to abort transaction!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
NS_WARNING("DispatchEvent failed!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
AsyncConnectionHelper::GetSuccessResult(JSContext* aCx,
|
|
||||||
JS::MutableHandle<JS::Value> aVal)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
|
|
||||||
aVal.setUndefined();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
AsyncConnectionHelper::ReleaseMainThreadObjects()
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
|
|
||||||
mDatabase = nullptr;
|
|
||||||
mTransaction = nullptr;
|
|
||||||
|
|
||||||
HelperBase::ReleaseMainThreadObjects();
|
|
||||||
}
|
|
||||||
|
|
||||||
AsyncConnectionHelper::ChildProcessSendResult
|
|
||||||
AsyncConnectionHelper::MaybeSendResponseToChildProcess(nsresult aResultCode)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
|
|
||||||
|
|
||||||
// If there's no request, there could never have been an actor, and so there
|
|
||||||
// is nothing to do.
|
|
||||||
if (!mRequest) {
|
|
||||||
return Success_NotSent;
|
|
||||||
}
|
|
||||||
|
|
||||||
IDBTransaction* trans = GetCurrentTransaction();
|
|
||||||
// We may not have a transaction, e.g. for deleteDatabase
|
|
||||||
if (!trans) {
|
|
||||||
return Success_NotSent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Are we shutting down the child?
|
|
||||||
IndexedDBDatabaseParent* dbActor = trans->Database()->GetActorParent();
|
|
||||||
if (dbActor && dbActor->IsDisconnected()) {
|
|
||||||
return Success_ActorDisconnected;
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexedDBRequestParentBase* actor = mRequest->GetActorParent();
|
|
||||||
if (!actor) {
|
|
||||||
return Success_NotSent;
|
|
||||||
}
|
|
||||||
|
|
||||||
IDB_PROFILER_MARK("IndexedDB Request %llu: Sending response to child "
|
|
||||||
"process (rv = %lu)",
|
|
||||||
"IDBRequest[%llu] MT Done",
|
|
||||||
mRequest->GetSerialNumber(), aResultCode);
|
|
||||||
|
|
||||||
return SendResponseToChildProcess(aResultCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
AsyncConnectionHelper::OnParentProcessRequestComplete(
|
|
||||||
const ResponseValue& aResponseValue)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(!IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
|
|
||||||
|
|
||||||
if (aResponseValue.type() == ResponseValue::Tnsresult) {
|
|
||||||
NS_ASSERTION(NS_FAILED(aResponseValue.get_nsresult()), "Huh?");
|
|
||||||
SetError(aResponseValue.get_nsresult());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nsresult rv = UnpackResponseFromParentProcess(aResponseValue);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Run();
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
nsresult
|
|
||||||
AsyncConnectionHelper::ConvertToArrayAndCleanup(
|
|
||||||
JSContext* aCx,
|
|
||||||
nsTArray<StructuredCloneReadInfo>& aReadInfos,
|
|
||||||
JS::MutableHandle<JS::Value> aResult)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(aCx, "Null context!");
|
|
||||||
NS_ASSERTION(aResult.address(), "Null pointer!");
|
|
||||||
|
|
||||||
nsresult rv = ConvertCloneReadInfosToArrayInternal(aCx, aReadInfos, aResult);
|
|
||||||
|
|
||||||
for (uint32_t index = 0; index < aReadInfos.Length(); index++) {
|
|
||||||
aReadInfos[index].mCloneBuffer.clear();
|
|
||||||
}
|
|
||||||
aReadInfos.Clear();
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP_(MozExternalRefCountType)
|
|
||||||
StackBasedEventTarget::AddRef()
|
|
||||||
{
|
|
||||||
NS_NOTREACHED("Don't call me!");
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP_(MozExternalRefCountType)
|
|
||||||
StackBasedEventTarget::Release()
|
|
||||||
{
|
|
||||||
NS_NOTREACHED("Don't call me!");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
StackBasedEventTarget::QueryInterface(REFNSIID aIID,
|
|
||||||
void** aInstancePtr)
|
|
||||||
{
|
|
||||||
NS_NOTREACHED("Don't call me!");
|
|
||||||
return NS_NOINTERFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
ImmediateRunEventTarget::Dispatch(nsIRunnable* aRunnable,
|
|
||||||
uint32_t aFlags)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(aRunnable, "Null pointer!");
|
|
||||||
|
|
||||||
nsCOMPtr<nsIRunnable> runnable(aRunnable);
|
|
||||||
DebugOnly<nsresult> rv =
|
|
||||||
runnable->Run();
|
|
||||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
ImmediateRunEventTarget::IsOnCurrentThread(bool* aIsOnCurrentThread)
|
|
||||||
{
|
|
||||||
*aIsOnCurrentThread = true;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
TransactionPoolEventTarget::Dispatch(nsIRunnable* aRunnable,
|
|
||||||
uint32_t aFlags)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(aRunnable, "Null pointer!");
|
|
||||||
NS_ASSERTION(aFlags == NS_DISPATCH_NORMAL, "Unsupported!");
|
|
||||||
|
|
||||||
TransactionThreadPool* pool = TransactionThreadPool::GetOrCreate();
|
|
||||||
NS_ENSURE_TRUE(pool, NS_ERROR_UNEXPECTED);
|
|
||||||
|
|
||||||
nsresult rv = pool->Dispatch(mTransaction, aRunnable, false, nullptr);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
TransactionPoolEventTarget::IsOnCurrentThread(bool* aIsOnCurrentThread)
|
|
||||||
{
|
|
||||||
*aIsOnCurrentThread = false;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
NoDispatchEventTarget::Dispatch(nsIRunnable* aRunnable,
|
|
||||||
uint32_t aFlags)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIRunnable> runnable = aRunnable;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
NoDispatchEventTarget::IsOnCurrentThread(bool* aIsOnCurrentThread)
|
|
||||||
{
|
|
||||||
*aIsOnCurrentThread = true;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
|
@ -1,257 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* vim: set ts=2 et sw=2 tw=80: */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef mozilla_dom_indexeddb_asyncconnectionhelper_h__
|
|
||||||
#define mozilla_dom_indexeddb_asyncconnectionhelper_h__
|
|
||||||
|
|
||||||
// Only meant to be included in IndexedDB source files, not exported.
|
|
||||||
#include "DatabaseInfo.h"
|
|
||||||
#include "IndexedDatabase.h"
|
|
||||||
#include "IDBDatabase.h"
|
|
||||||
#include "IDBRequest.h"
|
|
||||||
|
|
||||||
#include "mozIStorageProgressHandler.h"
|
|
||||||
#include "nsIEventTarget.h"
|
|
||||||
#include "nsIRunnable.h"
|
|
||||||
|
|
||||||
class mozIStorageConnection;
|
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
|
||||||
|
|
||||||
class AutoSetCurrentTransaction;
|
|
||||||
class IDBTransaction;
|
|
||||||
|
|
||||||
namespace ipc {
|
|
||||||
class ResponseValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A common base class for AsyncConnectionHelper and OpenDatabaseHelper that
|
|
||||||
// IDBRequest can use.
|
|
||||||
class HelperBase : public nsIRunnable
|
|
||||||
{
|
|
||||||
friend class IDBRequest;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
virtual nsresult GetResultCode() = 0;
|
|
||||||
|
|
||||||
virtual nsresult GetSuccessResult(JSContext* aCx,
|
|
||||||
JS::MutableHandle<JS::Value> aVal) = 0;
|
|
||||||
|
|
||||||
IDBRequest* GetRequest() const
|
|
||||||
{
|
|
||||||
return mRequest;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
explicit HelperBase(IDBRequest* aRequest)
|
|
||||||
: mRequest(aRequest)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual ~HelperBase();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper to wrap a native into a jsval. Uses the global object of the request
|
|
||||||
* to parent the native.
|
|
||||||
*/
|
|
||||||
nsresult WrapNative(JSContext* aCx,
|
|
||||||
nsISupports* aNative,
|
|
||||||
JS::MutableHandle<JS::Value> aResult);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gives the subclass a chance to release any objects that must be released
|
|
||||||
* on the main thread, regardless of success or failure. Subclasses that
|
|
||||||
* implement this method *MUST* call the base class implementation as well.
|
|
||||||
*/
|
|
||||||
virtual void ReleaseMainThreadObjects();
|
|
||||||
|
|
||||||
nsRefPtr<IDBRequest> mRequest;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Must be subclassed. The subclass must implement DoDatabaseWork. It may then
|
|
||||||
* choose to implement OnSuccess and OnError depending on the needs of the
|
|
||||||
* subclass. If the default implementation of OnSuccess is desired then the
|
|
||||||
* subclass can implement GetSuccessResult to properly set the result of the
|
|
||||||
* success event. Call Dispatch to start the database operation. Must be created
|
|
||||||
* and Dispatched from the main thread only. Target thread may not be the main
|
|
||||||
* thread.
|
|
||||||
*/
|
|
||||||
class AsyncConnectionHelper : public HelperBase,
|
|
||||||
public mozIStorageProgressHandler
|
|
||||||
{
|
|
||||||
friend class AutoSetCurrentTransaction;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef ipc::ResponseValue ResponseValue;
|
|
||||||
|
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
|
||||||
NS_DECL_NSIRUNNABLE
|
|
||||||
NS_DECL_MOZISTORAGEPROGRESSHANDLER
|
|
||||||
|
|
||||||
virtual nsresult Dispatch(nsIEventTarget* aDatabaseThread);
|
|
||||||
|
|
||||||
// Only for transactions!
|
|
||||||
nsresult DispatchToTransactionPool();
|
|
||||||
|
|
||||||
void SetError(nsresult aErrorCode)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_FAILED(aErrorCode), "Not a failure code!");
|
|
||||||
mResultCode = aErrorCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
static IDBTransaction* GetCurrentTransaction();
|
|
||||||
|
|
||||||
bool HasTransaction() const
|
|
||||||
{
|
|
||||||
return !!mTransaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
IDBTransaction* GetTransaction() const
|
|
||||||
{
|
|
||||||
return mTransaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual nsresult GetResultCode() MOZ_OVERRIDE
|
|
||||||
{
|
|
||||||
return mResultCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ChildProcessSendResult
|
|
||||||
{
|
|
||||||
// The result was successfully sent to the child process
|
|
||||||
Success_Sent = 0,
|
|
||||||
|
|
||||||
// The result was not sent, because this is not an out-of-process request.
|
|
||||||
Success_NotSent,
|
|
||||||
|
|
||||||
// The result was not sent, because the actor has been disconnected
|
|
||||||
// (if the child process has shut down or crashed).
|
|
||||||
Success_ActorDisconnected,
|
|
||||||
|
|
||||||
// An error occurred.
|
|
||||||
Error
|
|
||||||
};
|
|
||||||
|
|
||||||
ChildProcessSendResult
|
|
||||||
MaybeSendResponseToChildProcess(nsresult aResultCode);
|
|
||||||
|
|
||||||
virtual nsresult OnParentProcessRequestComplete(
|
|
||||||
const ResponseValue& aResponseValue);
|
|
||||||
|
|
||||||
virtual nsresult
|
|
||||||
UnpackResponseFromParentProcess(const ResponseValue& aResponseValue) = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
AsyncConnectionHelper(IDBDatabase* aDatabase,
|
|
||||||
IDBRequest* aRequest);
|
|
||||||
|
|
||||||
AsyncConnectionHelper(IDBTransaction* aTransaction,
|
|
||||||
IDBRequest* aRequest);
|
|
||||||
|
|
||||||
virtual ~AsyncConnectionHelper();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is called on the main thread after Dispatch is called but before the
|
|
||||||
* runnable is actually dispatched to the database thread. Allows the subclass
|
|
||||||
* to initialize itself.
|
|
||||||
*/
|
|
||||||
virtual nsresult Init();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is run on the database thread.
|
|
||||||
*/
|
|
||||||
virtual nsresult DoDatabaseWork(mozIStorageConnection* aConnection) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function returns the event to be dispatched at the request when
|
|
||||||
* OnSuccess is called. A subclass can override this to fire an event other
|
|
||||||
* than "success" at the request.
|
|
||||||
*/
|
|
||||||
virtual already_AddRefed<nsIDOMEvent> CreateSuccessEvent(
|
|
||||||
mozilla::dom::EventTarget* aOwner);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is run on the main thread if DoDatabaseWork returned NS_OK.
|
|
||||||
* The default implementation fires a "success" DOM event with its target set
|
|
||||||
* to the request. Returning anything other than NS_OK from the OnSuccess
|
|
||||||
* callback will trigger the OnError callback.
|
|
||||||
*/
|
|
||||||
virtual nsresult OnSuccess();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is run on the main thread if DoDatabaseWork or OnSuccess
|
|
||||||
* returned an error code. The default implementation fires an "error" DOM
|
|
||||||
* event with its target set to the request.
|
|
||||||
*/
|
|
||||||
virtual void OnError();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function is called by the request on the main thread when script
|
|
||||||
* accesses the result property of the request.
|
|
||||||
*/
|
|
||||||
virtual nsresult GetSuccessResult(JSContext* aCx,
|
|
||||||
JS::MutableHandle<JS::Value> aVal) MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gives the subclass a chance to release any objects that must be released
|
|
||||||
* on the main thread, regardless of success or failure. Subclasses that
|
|
||||||
* implement this method *MUST* call the base class implementation as well.
|
|
||||||
*/
|
|
||||||
virtual void ReleaseMainThreadObjects() MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper to make a JS array object out of an array of clone buffers.
|
|
||||||
*/
|
|
||||||
static nsresult ConvertToArrayAndCleanup(
|
|
||||||
JSContext* aCx,
|
|
||||||
nsTArray<StructuredCloneReadInfo>& aReadInfos,
|
|
||||||
JS::MutableHandle<JS::Value> aResult);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This should only be called by AutoSetCurrentTransaction.
|
|
||||||
*/
|
|
||||||
static void SetCurrentTransaction(IDBTransaction* aTransaction);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows the subclass to send its results to the child process. Will only
|
|
||||||
* be called if all of the IPC infrastructure is available (there is an
|
|
||||||
* actor, the child is stil alive and hasn't begun shutting down).
|
|
||||||
*/
|
|
||||||
virtual ChildProcessSendResult
|
|
||||||
SendResponseToChildProcess(nsresult aResultCode) = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
nsRefPtr<IDBDatabase> mDatabase;
|
|
||||||
nsRefPtr<IDBTransaction> mTransaction;
|
|
||||||
|
|
||||||
private:
|
|
||||||
nsCOMPtr<mozIStorageProgressHandler> mOldProgressHandler;
|
|
||||||
nsresult mResultCode;
|
|
||||||
bool mDispatched;
|
|
||||||
};
|
|
||||||
|
|
||||||
class MOZ_STACK_CLASS StackBasedEventTarget : public nsIEventTarget
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
|
||||||
};
|
|
||||||
|
|
||||||
class MOZ_STACK_CLASS ImmediateRunEventTarget : public StackBasedEventTarget
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
NS_DECL_NSIEVENTTARGET
|
|
||||||
};
|
|
||||||
|
|
||||||
class MOZ_STACK_CLASS NoDispatchEventTarget : public StackBasedEventTarget
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
NS_DECL_NSIEVENTTARGET
|
|
||||||
};
|
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
|
||||||
|
|
||||||
#endif // mozilla_dom_indexeddb_asyncconnectionhelper_h__
|
|
|
@ -1,220 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* vim: set ts=2 et sw=2 tw=80: */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "CheckPermissionsHelper.h"
|
|
||||||
|
|
||||||
#include "nsIDOMWindow.h"
|
|
||||||
#include "nsILoadContext.h"
|
|
||||||
#include "nsIWebNavigation.h"
|
|
||||||
#include "nsIObserverService.h"
|
|
||||||
#include "nsIPermissionManager.h"
|
|
||||||
#include "nsIPrincipal.h"
|
|
||||||
#include "nsIScriptObjectPrincipal.h"
|
|
||||||
#include "nsIURI.h"
|
|
||||||
|
|
||||||
#include "CheckQuotaHelper.h"
|
|
||||||
#include "nsContentUtils.h"
|
|
||||||
#include "nsNetUtil.h"
|
|
||||||
#include "nsThreadUtils.h"
|
|
||||||
#include "mozilla/Services.h"
|
|
||||||
|
|
||||||
#include "IndexedDatabaseManager.h"
|
|
||||||
|
|
||||||
#define PERMISSION_INDEXEDDB "indexedDB"
|
|
||||||
#define TOPIC_PERMISSIONS_PROMPT "indexedDB-permissions-prompt"
|
|
||||||
#define TOPIC_PERMISSIONS_RESPONSE "indexedDB-permissions-response"
|
|
||||||
|
|
||||||
// This is a little confusing, but our default behavior (UNKNOWN_ACTION) is to
|
|
||||||
// allow access without a prompt. If the "indexedDB" permission is set to
|
|
||||||
// ALLOW_ACTION then we will issue a prompt before allowing access. Otherwise
|
|
||||||
// (DENY_ACTION) we deny access.
|
|
||||||
#define PERMISSION_ALLOWED nsIPermissionManager::UNKNOWN_ACTION
|
|
||||||
#define PERMISSION_DENIED nsIPermissionManager::DENY_ACTION
|
|
||||||
#define PERMISSION_PROMPT nsIPermissionManager::ALLOW_ACTION
|
|
||||||
|
|
||||||
USING_INDEXEDDB_NAMESPACE
|
|
||||||
using namespace mozilla::services;
|
|
||||||
using mozilla::dom::quota::CheckQuotaHelper;
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
inline
|
|
||||||
uint32_t
|
|
||||||
GetIndexedDBPermissions(nsIDOMWindow* aWindow)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
|
|
||||||
NS_ASSERTION(aWindow, "Chrome shouldn't check the permission!");
|
|
||||||
|
|
||||||
nsCOMPtr<nsIScriptObjectPrincipal> sop(do_QueryInterface(aWindow));
|
|
||||||
NS_ENSURE_TRUE(sop, nsIPermissionManager::DENY_ACTION);
|
|
||||||
|
|
||||||
NS_ASSERTION(!nsContentUtils::IsSystemPrincipal(sop->GetPrincipal()),
|
|
||||||
"Chrome windows shouldn't check the permission!");
|
|
||||||
|
|
||||||
nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(aWindow);
|
|
||||||
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(webNav);
|
|
||||||
if (loadContext && loadContext->UsePrivateBrowsing()) {
|
|
||||||
// TODO Support private browsing indexedDB?
|
|
||||||
NS_WARNING("IndexedDB may not be used while in private browsing mode!");
|
|
||||||
return PERMISSION_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIPermissionManager> permissionManager = GetPermissionManager();
|
|
||||||
NS_ENSURE_TRUE(permissionManager, PERMISSION_DENIED);
|
|
||||||
|
|
||||||
uint32_t permission;
|
|
||||||
nsresult rv =
|
|
||||||
permissionManager->TestPermissionFromPrincipal(sop->GetPrincipal(),
|
|
||||||
PERMISSION_INDEXEDDB,
|
|
||||||
&permission);
|
|
||||||
NS_ENSURE_SUCCESS(rv, PERMISSION_DENIED);
|
|
||||||
|
|
||||||
return permission;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(CheckPermissionsHelper, nsIRunnable,
|
|
||||||
nsIInterfaceRequestor,
|
|
||||||
nsIObserver)
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
CheckPermissionsHelper::Run()
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
|
|
||||||
uint32_t permission = mHasPrompted ?
|
|
||||||
mPromptResult :
|
|
||||||
GetIndexedDBPermissions(mWindow);
|
|
||||||
|
|
||||||
nsresult rv;
|
|
||||||
if (mHasPrompted) {
|
|
||||||
// Add permissions to the database, but only if we are in the parent
|
|
||||||
// process (if we are in the child process, we have already
|
|
||||||
// set the permission when the prompt was shown in the parent, as
|
|
||||||
// we cannot set the permission from the child).
|
|
||||||
if (permission != PERMISSION_PROMPT &&
|
|
||||||
IndexedDatabaseManager::IsMainProcess()) {
|
|
||||||
NS_ASSERTION(mWindow, "Null window!");
|
|
||||||
|
|
||||||
nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(mWindow);
|
|
||||||
NS_ASSERTION(sop, "Window didn't QI to nsIScriptObjectPrincipal!");
|
|
||||||
|
|
||||||
nsIPrincipal* windowPrincipal = sop->GetPrincipal();
|
|
||||||
NS_ASSERTION(windowPrincipal, "Null principal!");
|
|
||||||
|
|
||||||
nsCOMPtr<nsIPermissionManager> permissionManager = GetPermissionManager();
|
|
||||||
NS_ENSURE_STATE(permissionManager);
|
|
||||||
|
|
||||||
rv = permissionManager->AddFromPrincipal(windowPrincipal,
|
|
||||||
PERMISSION_INDEXEDDB, permission,
|
|
||||||
nsIPermissionManager::EXPIRE_NEVER,
|
|
||||||
0);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (permission == PERMISSION_PROMPT && mPromptAllowed) {
|
|
||||||
nsCOMPtr<nsIObserverService> obs = GetObserverService();
|
|
||||||
rv = obs->NotifyObservers(static_cast<nsIRunnable*>(this),
|
|
||||||
TOPIC_PERMISSIONS_PROMPT, nullptr);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<OpenDatabaseHelper> helper;
|
|
||||||
helper.swap(mHelper);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMWindow> window;
|
|
||||||
window.swap(mWindow);
|
|
||||||
|
|
||||||
if (permission == PERMISSION_ALLOWED) {
|
|
||||||
// If we're running from a window then we should check the quota permission
|
|
||||||
// as well. If we don't have a window then we're opening a chrome database
|
|
||||||
// and the quota will be unlimited already.
|
|
||||||
if (window) {
|
|
||||||
nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(window);
|
|
||||||
NS_ASSERTION(sop, "Window didn't QI to nsIScriptObjectPrincipal!");
|
|
||||||
|
|
||||||
nsIPrincipal* windowPrincipal = sop->GetPrincipal();
|
|
||||||
NS_ASSERTION(windowPrincipal, "Null principal!");
|
|
||||||
|
|
||||||
uint32_t quotaPermission =
|
|
||||||
CheckQuotaHelper::GetQuotaPermission(windowPrincipal);
|
|
||||||
|
|
||||||
if (quotaPermission == nsIPermissionManager::ALLOW_ACTION) {
|
|
||||||
helper->SetUnlimitedQuotaAllowed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return helper->DispatchToIOThread();
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ASSERTION(permission == PERMISSION_PROMPT ||
|
|
||||||
permission == PERMISSION_DENIED,
|
|
||||||
"Unknown permission!");
|
|
||||||
|
|
||||||
helper->SetError(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
|
|
||||||
|
|
||||||
return helper->RunImmediately();
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
CheckPermissionsHelper::GetInterface(const nsIID& aIID,
|
|
||||||
void** aResult)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
if (aIID.Equals(NS_GET_IID(nsIObserver))) {
|
|
||||||
return QueryInterface(aIID, aResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aIID.Equals(NS_GET_IID(nsIDOMWindow))) {
|
|
||||||
return mWindow->QueryInterface(aIID, aResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
*aResult = nullptr;
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
CheckPermissionsHelper::Observe(nsISupports* aSubject,
|
|
||||||
const char* aTopic,
|
|
||||||
const char16_t* aData)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
NS_ASSERTION(!strcmp(aTopic, TOPIC_PERMISSIONS_RESPONSE), "Bad topic!");
|
|
||||||
NS_ASSERTION(mPromptAllowed, "How did we get here?");
|
|
||||||
|
|
||||||
mHasPrompted = true;
|
|
||||||
|
|
||||||
nsresult rv;
|
|
||||||
uint32_t promptResult = nsDependentString(aData).ToInteger(&rv);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// Have to convert the permission we got from the user to our weird reversed
|
|
||||||
// permission type.
|
|
||||||
switch (promptResult) {
|
|
||||||
case nsIPermissionManager::ALLOW_ACTION:
|
|
||||||
mPromptResult = PERMISSION_ALLOWED;
|
|
||||||
break;
|
|
||||||
case nsIPermissionManager::DENY_ACTION:
|
|
||||||
mPromptResult = PERMISSION_DENIED;
|
|
||||||
break;
|
|
||||||
case nsIPermissionManager::UNKNOWN_ACTION:
|
|
||||||
mPromptResult = PERMISSION_PROMPT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
NS_NOTREACHED("Unknown permission type!");
|
|
||||||
mPromptResult = PERMISSION_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = NS_DispatchToCurrentThread(this);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* vim: set ts=2 et sw=2 tw=80: */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef mozilla_dom_indexeddb_checkpermissionshelper_h__
|
|
||||||
#define mozilla_dom_indexeddb_checkpermissionshelper_h__
|
|
||||||
|
|
||||||
// Only meant to be included in IndexedDB source files, not exported.
|
|
||||||
#include "OpenDatabaseHelper.h"
|
|
||||||
|
|
||||||
#include "nsIInterfaceRequestor.h"
|
|
||||||
#include "nsIObserver.h"
|
|
||||||
#include "nsIRunnable.h"
|
|
||||||
|
|
||||||
class nsIDOMWindow;
|
|
||||||
class nsIThread;
|
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
|
||||||
|
|
||||||
class CheckPermissionsHelper MOZ_FINAL : public nsIRunnable,
|
|
||||||
public nsIInterfaceRequestor,
|
|
||||||
public nsIObserver
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
|
||||||
NS_DECL_NSIRUNNABLE
|
|
||||||
NS_DECL_NSIINTERFACEREQUESTOR
|
|
||||||
NS_DECL_NSIOBSERVER
|
|
||||||
|
|
||||||
CheckPermissionsHelper(OpenDatabaseHelper* aHelper,
|
|
||||||
nsIDOMWindow* aWindow)
|
|
||||||
: mHelper(aHelper),
|
|
||||||
mWindow(aWindow),
|
|
||||||
// If we're trying to delete the database, we should never prompt the user.
|
|
||||||
// Anything that would prompt is translated to denied.
|
|
||||||
mPromptAllowed(!aHelper->mForDeletion),
|
|
||||||
mHasPrompted(false),
|
|
||||||
mPromptResult(0)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(aHelper, "Null pointer!");
|
|
||||||
NS_ASSERTION(aHelper->mPersistenceType == quota::PERSISTENCE_TYPE_PERSISTENT,
|
|
||||||
"Checking permission for non persistent databases?!");
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
~CheckPermissionsHelper() {}
|
|
||||||
|
|
||||||
nsRefPtr<OpenDatabaseHelper> mHelper;
|
|
||||||
nsCOMPtr<nsIDOMWindow> mWindow;
|
|
||||||
bool mPromptAllowed;
|
|
||||||
bool mHasPrompted;
|
|
||||||
uint32_t mPromptResult;
|
|
||||||
};
|
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
|
||||||
|
|
||||||
#endif // mozilla_dom_indexeddb_checkpermissionshelper_h__
|
|
|
@ -1,369 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* vim: set ts=2 et sw=2 tw=80: */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
||||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "Client.h"
|
|
||||||
|
|
||||||
#include "mozilla/dom/quota/QuotaManager.h"
|
|
||||||
#include "mozilla/dom/quota/UsageInfo.h"
|
|
||||||
#include "mozilla/dom/quota/Utilities.h"
|
|
||||||
|
|
||||||
#include "IDBDatabase.h"
|
|
||||||
#include "IndexedDatabaseManager.h"
|
|
||||||
#include "TransactionThreadPool.h"
|
|
||||||
#include "nsISimpleEnumerator.h"
|
|
||||||
|
|
||||||
USING_INDEXEDDB_NAMESPACE
|
|
||||||
using mozilla::dom::quota::AssertIsOnIOThread;
|
|
||||||
using mozilla::dom::quota::QuotaManager;
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
bool
|
|
||||||
GetDatabaseBaseFilename(const nsAString& aFilename,
|
|
||||||
nsAString& aDatabaseBaseFilename)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(!aFilename.IsEmpty(), "Bad argument!");
|
|
||||||
|
|
||||||
NS_NAMED_LITERAL_STRING(sqlite, ".sqlite");
|
|
||||||
|
|
||||||
if (!StringEndsWith(aFilename, sqlite)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
aDatabaseBaseFilename =
|
|
||||||
Substring(aFilename, 0, aFilename.Length() - sqlite.Length());
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
// This needs to be fully qualified to not confuse trace refcnt assertions.
|
|
||||||
NS_IMPL_ADDREF(mozilla::dom::indexedDB::Client)
|
|
||||||
NS_IMPL_RELEASE(mozilla::dom::indexedDB::Client)
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
Client::InitOrigin(PersistenceType aPersistenceType, const nsACString& aGroup,
|
|
||||||
const nsACString& aOrigin, UsageInfo* aUsageInfo)
|
|
||||||
{
|
|
||||||
AssertIsOnIOThread();
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> directory;
|
|
||||||
nsresult rv =
|
|
||||||
GetDirectory(aPersistenceType, aOrigin, getter_AddRefs(directory));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// We need to see if there are any files in the directory already. If they
|
|
||||||
// are database files then we need to cleanup stored files (if it's needed)
|
|
||||||
// and also get the usage.
|
|
||||||
|
|
||||||
nsAutoTArray<nsString, 20> subdirsToProcess;
|
|
||||||
nsAutoTArray<nsCOMPtr<nsIFile>, 20> unknownFiles;
|
|
||||||
nsTHashtable<nsStringHashKey> validSubdirs(20);
|
|
||||||
|
|
||||||
nsCOMPtr<nsISimpleEnumerator> entries;
|
|
||||||
rv = directory->GetDirectoryEntries(getter_AddRefs(entries));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
bool hasMore;
|
|
||||||
while (NS_SUCCEEDED((rv = entries->HasMoreElements(&hasMore))) &&
|
|
||||||
hasMore && (!aUsageInfo || !aUsageInfo->Canceled())) {
|
|
||||||
nsCOMPtr<nsISupports> entry;
|
|
||||||
rv = entries->GetNext(getter_AddRefs(entry));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> file = do_QueryInterface(entry);
|
|
||||||
NS_ENSURE_TRUE(file, NS_NOINTERFACE);
|
|
||||||
|
|
||||||
nsString leafName;
|
|
||||||
rv = file->GetLeafName(leafName);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (StringEndsWith(leafName, NS_LITERAL_STRING(".sqlite-journal"))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (leafName.EqualsLiteral(DSSTORE_FILE_NAME)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isDirectory;
|
|
||||||
rv = file->IsDirectory(&isDirectory);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (isDirectory) {
|
|
||||||
if (!validSubdirs.GetEntry(leafName)) {
|
|
||||||
subdirsToProcess.AppendElement(leafName);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsString dbBaseFilename;
|
|
||||||
if (!GetDatabaseBaseFilename(leafName, dbBaseFilename)) {
|
|
||||||
unknownFiles.AppendElement(file);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> fmDirectory;
|
|
||||||
rv = directory->Clone(getter_AddRefs(fmDirectory));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = fmDirectory->Append(dbBaseFilename);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = FileManager::InitDirectory(fmDirectory, file, aPersistenceType, aGroup,
|
|
||||||
aOrigin);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (aUsageInfo) {
|
|
||||||
int64_t fileSize;
|
|
||||||
rv = file->GetFileSize(&fileSize);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
NS_ASSERTION(fileSize >= 0, "Negative size?!");
|
|
||||||
|
|
||||||
aUsageInfo->AppendToDatabaseUsage(uint64_t(fileSize));
|
|
||||||
|
|
||||||
uint64_t usage;
|
|
||||||
rv = FileManager::GetUsage(fmDirectory, &usage);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
aUsageInfo->AppendToFileUsage(usage);
|
|
||||||
}
|
|
||||||
|
|
||||||
validSubdirs.PutEntry(dbBaseFilename);
|
|
||||||
}
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < subdirsToProcess.Length(); i++) {
|
|
||||||
const nsString& subdir = subdirsToProcess[i];
|
|
||||||
if (!validSubdirs.GetEntry(subdir)) {
|
|
||||||
NS_WARNING("Unknown subdirectory found!");
|
|
||||||
return NS_ERROR_UNEXPECTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < unknownFiles.Length(); i++) {
|
|
||||||
nsCOMPtr<nsIFile>& unknownFile = unknownFiles[i];
|
|
||||||
|
|
||||||
// Some temporary SQLite files could disappear, so we have to check if the
|
|
||||||
// unknown file still exists.
|
|
||||||
bool exists;
|
|
||||||
rv = unknownFile->Exists(&exists);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (exists) {
|
|
||||||
nsString leafName;
|
|
||||||
unknownFile->GetLeafName(leafName);
|
|
||||||
|
|
||||||
// The journal file may exists even after db has been correctly opened.
|
|
||||||
if (!StringEndsWith(leafName, NS_LITERAL_STRING(".sqlite-journal"))) {
|
|
||||||
NS_WARNING("Unknown file found!");
|
|
||||||
return NS_ERROR_UNEXPECTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
Client::GetUsageForOrigin(PersistenceType aPersistenceType,
|
|
||||||
const nsACString& aGroup, const nsACString& aOrigin,
|
|
||||||
UsageInfo* aUsageInfo)
|
|
||||||
{
|
|
||||||
AssertIsOnIOThread();
|
|
||||||
NS_ASSERTION(aUsageInfo, "Null pointer!");
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> directory;
|
|
||||||
nsresult rv =
|
|
||||||
GetDirectory(aPersistenceType, aOrigin, getter_AddRefs(directory));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = GetUsageForDirectoryInternal(directory, aUsageInfo, true);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Client::OnOriginClearCompleted(PersistenceType aPersistenceType,
|
|
||||||
const OriginOrPatternString& aOriginOrPattern)
|
|
||||||
{
|
|
||||||
AssertIsOnIOThread();
|
|
||||||
|
|
||||||
IndexedDatabaseManager* mgr = IndexedDatabaseManager::Get();
|
|
||||||
if (mgr) {
|
|
||||||
mgr->InvalidateFileManagers(aPersistenceType, aOriginOrPattern);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Client::ReleaseIOThreadObjects()
|
|
||||||
{
|
|
||||||
AssertIsOnIOThread();
|
|
||||||
|
|
||||||
IndexedDatabaseManager* mgr = IndexedDatabaseManager::Get();
|
|
||||||
if (mgr) {
|
|
||||||
mgr->InvalidateAllFileManagers();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Client::IsTransactionServiceActivated()
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
|
|
||||||
return !!TransactionThreadPool::Get();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Client::WaitForStoragesToComplete(nsTArray<nsIOfflineStorage*>& aStorages,
|
|
||||||
nsIRunnable* aCallback)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
NS_ASSERTION(!aStorages.IsEmpty(), "No storages to wait on!");
|
|
||||||
NS_ASSERTION(aCallback, "Passed null callback!");
|
|
||||||
|
|
||||||
TransactionThreadPool* pool = TransactionThreadPool::Get();
|
|
||||||
NS_ASSERTION(pool, "Should have checked if transaction service is active!");
|
|
||||||
|
|
||||||
nsTArray<nsRefPtr<IDBDatabase> > databases(aStorages.Length());
|
|
||||||
for (uint32_t index = 0; index < aStorages.Length(); index++) {
|
|
||||||
IDBDatabase* database = IDBDatabase::FromStorage(aStorages[index]);
|
|
||||||
if (!database) {
|
|
||||||
MOZ_CRASH();
|
|
||||||
}
|
|
||||||
|
|
||||||
databases.AppendElement(database);
|
|
||||||
}
|
|
||||||
|
|
||||||
pool->WaitForDatabasesToComplete(databases, aCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Client::AbortTransactionsForStorage(nsIOfflineStorage* aStorage)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
NS_ASSERTION(aStorage, "Passed null storage!");
|
|
||||||
|
|
||||||
TransactionThreadPool* pool = TransactionThreadPool::Get();
|
|
||||||
NS_ASSERTION(pool, "Should have checked if transaction service is active!");
|
|
||||||
|
|
||||||
IDBDatabase* database = IDBDatabase::FromStorage(aStorage);
|
|
||||||
NS_ASSERTION(database, "This shouldn't be null!");
|
|
||||||
|
|
||||||
pool->AbortTransactionsForDatabase(database);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Client::HasTransactionsForStorage(nsIOfflineStorage* aStorage)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
|
|
||||||
TransactionThreadPool* pool = TransactionThreadPool::Get();
|
|
||||||
NS_ASSERTION(pool, "Should have checked if transaction service is active!");
|
|
||||||
|
|
||||||
IDBDatabase* database = IDBDatabase::FromStorage(aStorage);
|
|
||||||
NS_ASSERTION(database, "This shouldn't be null!");
|
|
||||||
|
|
||||||
return pool->HasTransactionsForDatabase(database);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Client::ShutdownTransactionService()
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
|
|
||||||
TransactionThreadPool::Shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
Client::GetDirectory(PersistenceType aPersistenceType,
|
|
||||||
const nsACString& aOrigin, nsIFile** aDirectory)
|
|
||||||
{
|
|
||||||
QuotaManager* quotaManager = QuotaManager::Get();
|
|
||||||
NS_ASSERTION(quotaManager, "This should never fail!");
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> directory;
|
|
||||||
nsresult rv = quotaManager->GetDirectoryForOrigin(aPersistenceType, aOrigin,
|
|
||||||
getter_AddRefs(directory));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
NS_ASSERTION(directory, "What?");
|
|
||||||
|
|
||||||
rv = directory->Append(NS_LITERAL_STRING(IDB_DIRECTORY_NAME));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
directory.forget(aDirectory);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
Client::GetUsageForDirectoryInternal(nsIFile* aDirectory,
|
|
||||||
UsageInfo* aUsageInfo,
|
|
||||||
bool aDatabaseFiles)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(aDirectory, "Null pointer!");
|
|
||||||
NS_ASSERTION(aUsageInfo, "Null pointer!");
|
|
||||||
|
|
||||||
nsCOMPtr<nsISimpleEnumerator> entries;
|
|
||||||
nsresult rv = aDirectory->GetDirectoryEntries(getter_AddRefs(entries));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (!entries) {
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hasMore;
|
|
||||||
while (NS_SUCCEEDED((rv = entries->HasMoreElements(&hasMore))) &&
|
|
||||||
hasMore && !aUsageInfo->Canceled()) {
|
|
||||||
nsCOMPtr<nsISupports> entry;
|
|
||||||
rv = entries->GetNext(getter_AddRefs(entry));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> file(do_QueryInterface(entry));
|
|
||||||
NS_ASSERTION(file, "Don't know what this is!");
|
|
||||||
|
|
||||||
bool isDirectory;
|
|
||||||
rv = file->IsDirectory(&isDirectory);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (isDirectory) {
|
|
||||||
if (aDatabaseFiles) {
|
|
||||||
rv = GetUsageForDirectoryInternal(file, aUsageInfo, false);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nsString leafName;
|
|
||||||
rv = file->GetLeafName(leafName);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (!leafName.EqualsLiteral(JOURNAL_DIRECTORY_NAME)) {
|
|
||||||
NS_WARNING("Unknown directory found!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t fileSize;
|
|
||||||
rv = file->GetFileSize(&fileSize);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
NS_ASSERTION(fileSize >= 0, "Negative size?!");
|
|
||||||
|
|
||||||
if (aDatabaseFiles) {
|
|
||||||
aUsageInfo->AppendToDatabaseUsage(uint64_t(fileSize));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
aUsageInfo->AppendToFileUsage(uint64_t(fileSize));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
|
@ -1,97 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* vim: set ts=2 et sw=2 tw=80: */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
||||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef mozilla_dom_indexeddb_client_h__
|
|
||||||
#define mozilla_dom_indexeddb_client_h__
|
|
||||||
|
|
||||||
#include "IndexedDatabase.h"
|
|
||||||
|
|
||||||
#include "mozilla/dom/quota/Client.h"
|
|
||||||
|
|
||||||
#define JOURNAL_DIRECTORY_NAME "journals"
|
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
|
||||||
|
|
||||||
class Client : public mozilla::dom::quota::Client
|
|
||||||
{
|
|
||||||
typedef mozilla::dom::quota::OriginOrPatternString OriginOrPatternString;
|
|
||||||
typedef mozilla::dom::quota::PersistenceType PersistenceType;
|
|
||||||
typedef mozilla::dom::quota::UsageInfo UsageInfo;
|
|
||||||
|
|
||||||
public:
|
|
||||||
NS_IMETHOD_(MozExternalRefCountType)
|
|
||||||
AddRef() MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
NS_IMETHOD_(MozExternalRefCountType)
|
|
||||||
Release() MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
virtual Type
|
|
||||||
GetType() MOZ_OVERRIDE
|
|
||||||
{
|
|
||||||
return IDB;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual nsresult
|
|
||||||
InitOrigin(PersistenceType aPersistenceType,
|
|
||||||
const nsACString& aGroup,
|
|
||||||
const nsACString& aOrigin,
|
|
||||||
UsageInfo* aUsageInfo) MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
virtual nsresult
|
|
||||||
GetUsageForOrigin(PersistenceType aPersistenceType,
|
|
||||||
const nsACString& aGroup,
|
|
||||||
const nsACString& aOrigin,
|
|
||||||
UsageInfo* aUsageInfo) MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
virtual void
|
|
||||||
OnOriginClearCompleted(PersistenceType aPersistenceType,
|
|
||||||
const OriginOrPatternString& aOriginOrPattern)
|
|
||||||
MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
virtual void
|
|
||||||
ReleaseIOThreadObjects() MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
virtual bool
|
|
||||||
IsFileServiceUtilized() MOZ_OVERRIDE
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool
|
|
||||||
IsTransactionServiceActivated() MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
virtual void
|
|
||||||
WaitForStoragesToComplete(nsTArray<nsIOfflineStorage*>& aStorages,
|
|
||||||
nsIRunnable* aCallback) MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
virtual void
|
|
||||||
AbortTransactionsForStorage(nsIOfflineStorage* aStorage) MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
virtual bool
|
|
||||||
HasTransactionsForStorage(nsIOfflineStorage* aStorage) MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
virtual void
|
|
||||||
ShutdownTransactionService() MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
private:
|
|
||||||
~Client() {}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
GetDirectory(PersistenceType aPersistenceType, const nsACString& aOrigin,
|
|
||||||
nsIFile** aDirectory);
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
GetUsageForDirectoryInternal(nsIFile* aDirectory,
|
|
||||||
UsageInfo* aUsageInfo,
|
|
||||||
bool aDatabaseFiles);
|
|
||||||
|
|
||||||
nsAutoRefCnt mRefCnt;
|
|
||||||
NS_DECL_OWNINGTHREAD
|
|
||||||
};
|
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
|
||||||
|
|
||||||
#endif // mozilla_dom_indexeddb_client_h__
|
|
|
@ -1,269 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* vim: set ts=2 et sw=2 tw=80: */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "DatabaseInfo.h"
|
|
||||||
|
|
||||||
#include "nsDataHashtable.h"
|
|
||||||
#include "nsThreadUtils.h"
|
|
||||||
|
|
||||||
USING_INDEXEDDB_NAMESPACE
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
typedef nsDataHashtable<nsCStringHashKey, DatabaseInfo*>
|
|
||||||
DatabaseHash;
|
|
||||||
|
|
||||||
DatabaseHash* gDatabaseHash = nullptr;
|
|
||||||
|
|
||||||
PLDHashOperator
|
|
||||||
EnumerateObjectStoreNames(const nsAString& aKey,
|
|
||||||
ObjectStoreInfo* aData,
|
|
||||||
void* aUserArg)
|
|
||||||
{
|
|
||||||
nsTArray<nsString>* array = static_cast<nsTArray<nsString>*>(aUserArg);
|
|
||||||
if (!array->InsertElementSorted(aData->name)) {
|
|
||||||
NS_ERROR("Out of memory?");
|
|
||||||
return PL_DHASH_STOP;
|
|
||||||
}
|
|
||||||
return PL_DHASH_NEXT;
|
|
||||||
}
|
|
||||||
|
|
||||||
PLDHashOperator
|
|
||||||
CloneObjectStoreInfo(const nsAString& aKey,
|
|
||||||
ObjectStoreInfo* aData,
|
|
||||||
void* aUserArg)
|
|
||||||
{
|
|
||||||
ObjectStoreInfoHash* hash = static_cast<ObjectStoreInfoHash*>(aUserArg);
|
|
||||||
|
|
||||||
nsRefPtr<ObjectStoreInfo> newInfo(new ObjectStoreInfo(*aData));
|
|
||||||
|
|
||||||
hash->Put(aKey, newInfo);
|
|
||||||
|
|
||||||
return PL_DHASH_NEXT;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
DatabaseInfo::~DatabaseInfo()
|
|
||||||
{
|
|
||||||
// Clones are never in the hash.
|
|
||||||
if (!cloned) {
|
|
||||||
DatabaseInfo::Remove(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectStoreInfo::ObjectStoreInfo(ObjectStoreInfo& aOther)
|
|
||||||
: nextAutoIncrementId(aOther.nextAutoIncrementId),
|
|
||||||
comittedAutoIncrementId(aOther.comittedAutoIncrementId)
|
|
||||||
{
|
|
||||||
*static_cast<ObjectStoreInfoGuts*>(this) =
|
|
||||||
static_cast<ObjectStoreInfoGuts&>(aOther);
|
|
||||||
|
|
||||||
// Doesn't copy the refcount
|
|
||||||
MOZ_COUNT_CTOR(ObjectStoreInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
|
||||||
|
|
||||||
IndexInfo::IndexInfo()
|
|
||||||
: id(INT64_MIN),
|
|
||||||
keyPath(0),
|
|
||||||
unique(false),
|
|
||||||
multiEntry(false)
|
|
||||||
{
|
|
||||||
MOZ_COUNT_CTOR(IndexInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexInfo::IndexInfo(const IndexInfo& aOther)
|
|
||||||
: name(aOther.name),
|
|
||||||
id(aOther.id),
|
|
||||||
keyPath(aOther.keyPath),
|
|
||||||
unique(aOther.unique),
|
|
||||||
multiEntry(aOther.multiEntry)
|
|
||||||
{
|
|
||||||
MOZ_COUNT_CTOR(IndexInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexInfo::~IndexInfo()
|
|
||||||
{
|
|
||||||
MOZ_COUNT_DTOR(IndexInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectStoreInfo::ObjectStoreInfo()
|
|
||||||
: nextAutoIncrementId(0),
|
|
||||||
comittedAutoIncrementId(0)
|
|
||||||
{
|
|
||||||
MOZ_COUNT_CTOR(ObjectStoreInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectStoreInfo::~ObjectStoreInfo()
|
|
||||||
{
|
|
||||||
MOZ_COUNT_DTOR(ObjectStoreInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexUpdateInfo::IndexUpdateInfo()
|
|
||||||
: indexId(0),
|
|
||||||
indexUnique(false)
|
|
||||||
{
|
|
||||||
MOZ_COUNT_CTOR(IndexUpdateInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexUpdateInfo::IndexUpdateInfo(const IndexUpdateInfo& aOther)
|
|
||||||
: indexId(aOther.indexId),
|
|
||||||
indexUnique(aOther.indexUnique),
|
|
||||||
value(aOther.value)
|
|
||||||
{
|
|
||||||
MOZ_COUNT_CTOR(IndexUpdateInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexUpdateInfo::~IndexUpdateInfo()
|
|
||||||
{
|
|
||||||
MOZ_COUNT_DTOR(IndexUpdateInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* NS_BUILD_REFCNT_LOGGING */
|
|
||||||
|
|
||||||
// static
|
|
||||||
bool
|
|
||||||
DatabaseInfo::Get(const nsACString& aId,
|
|
||||||
DatabaseInfo** aInfo)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
NS_ASSERTION(!aId.IsEmpty(), "Bad id!");
|
|
||||||
|
|
||||||
if (gDatabaseHash &&
|
|
||||||
gDatabaseHash->Get(aId, aInfo)) {
|
|
||||||
NS_IF_ADDREF(*aInfo);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
bool
|
|
||||||
DatabaseInfo::Put(DatabaseInfo* aInfo)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
NS_ASSERTION(aInfo, "Null pointer!");
|
|
||||||
|
|
||||||
if (!gDatabaseHash) {
|
|
||||||
nsAutoPtr<DatabaseHash> databaseHash(new DatabaseHash());
|
|
||||||
gDatabaseHash = databaseHash.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gDatabaseHash->Get(aInfo->id, nullptr)) {
|
|
||||||
NS_ERROR("Already know about this database!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
gDatabaseHash->Put(aInfo->id, aInfo);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
void
|
|
||||||
DatabaseInfo::Remove(const nsACString& aId)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
|
|
||||||
if (gDatabaseHash) {
|
|
||||||
gDatabaseHash->Remove(aId);
|
|
||||||
|
|
||||||
if (!gDatabaseHash->Count()) {
|
|
||||||
delete gDatabaseHash;
|
|
||||||
gDatabaseHash = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
DatabaseInfo::GetObjectStoreNames(nsTArray<nsString>& aNames)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
|
|
||||||
aNames.Clear();
|
|
||||||
if (objectStoreHash) {
|
|
||||||
objectStoreHash->EnumerateRead(EnumerateObjectStoreNames, &aNames);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
DatabaseInfo::ContainsStoreName(const nsAString& aName)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
|
|
||||||
return objectStoreHash && objectStoreHash->Get(aName, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectStoreInfo*
|
|
||||||
DatabaseInfo::GetObjectStore(const nsAString& aName)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
|
|
||||||
if (objectStoreHash) {
|
|
||||||
return objectStoreHash->GetWeak(aName);
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
DatabaseInfo::PutObjectStore(ObjectStoreInfo* aInfo)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
NS_ASSERTION(aInfo, "Null pointer!");
|
|
||||||
|
|
||||||
if (!objectStoreHash) {
|
|
||||||
nsAutoPtr<ObjectStoreInfoHash> hash(new ObjectStoreInfoHash());
|
|
||||||
objectStoreHash = hash.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (objectStoreHash->Get(aInfo->name, nullptr)) {
|
|
||||||
NS_ERROR("Already have an entry for this objectstore!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
objectStoreHash->Put(aInfo->name, aInfo);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DatabaseInfo::RemoveObjectStore(const nsAString& aName)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
NS_ASSERTION(GetObjectStore(aName), "Don't know about this one!");
|
|
||||||
|
|
||||||
if (objectStoreHash) {
|
|
||||||
objectStoreHash->Remove(aName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<DatabaseInfo>
|
|
||||||
DatabaseInfo::Clone()
|
|
||||||
{
|
|
||||||
nsRefPtr<DatabaseInfo> dbInfo(new DatabaseInfo());
|
|
||||||
|
|
||||||
dbInfo->cloned = true;
|
|
||||||
dbInfo->name = name;
|
|
||||||
dbInfo->group = group;
|
|
||||||
dbInfo->origin = origin;
|
|
||||||
dbInfo->version = version;
|
|
||||||
dbInfo->persistenceType = persistenceType;
|
|
||||||
dbInfo->id = id;
|
|
||||||
dbInfo->filePath = filePath;
|
|
||||||
dbInfo->nextObjectStoreId = nextObjectStoreId;
|
|
||||||
dbInfo->nextIndexId = nextIndexId;
|
|
||||||
|
|
||||||
if (objectStoreHash) {
|
|
||||||
dbInfo->objectStoreHash = new ObjectStoreInfoHash();
|
|
||||||
objectStoreHash->EnumerateRead(CloneObjectStoreInfo,
|
|
||||||
dbInfo->objectStoreHash);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dbInfo.forget();
|
|
||||||
}
|
|
|
@ -1,203 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* vim: set ts=2 et sw=2 tw=80: */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef mozilla_dom_indexeddb_databaseinfo_h__
|
|
||||||
#define mozilla_dom_indexeddb_databaseinfo_h__
|
|
||||||
|
|
||||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
|
||||||
|
|
||||||
#include "mozilla/dom/quota/PersistenceType.h"
|
|
||||||
#include "nsRefPtrHashtable.h"
|
|
||||||
#include "nsHashKeys.h"
|
|
||||||
|
|
||||||
#include "mozilla/dom/indexedDB/Key.h"
|
|
||||||
#include "mozilla/dom/indexedDB/KeyPath.h"
|
|
||||||
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
|
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
|
||||||
|
|
||||||
class IndexedDBDatabaseChild;
|
|
||||||
struct ObjectStoreInfo;
|
|
||||||
|
|
||||||
typedef nsRefPtrHashtable<nsStringHashKey, ObjectStoreInfo>
|
|
||||||
ObjectStoreInfoHash;
|
|
||||||
|
|
||||||
struct DatabaseInfoGuts
|
|
||||||
{
|
|
||||||
typedef mozilla::dom::quota::PersistenceType PersistenceType;
|
|
||||||
|
|
||||||
DatabaseInfoGuts()
|
|
||||||
: nextObjectStoreId(1), nextIndexId(1)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
bool operator==(const DatabaseInfoGuts& aOther) const
|
|
||||||
{
|
|
||||||
return this->name == aOther.name &&
|
|
||||||
this->group == aOther.group &&
|
|
||||||
this->origin == aOther.origin &&
|
|
||||||
this->version == aOther.version &&
|
|
||||||
this->persistenceType == aOther.persistenceType &&
|
|
||||||
this->nextObjectStoreId == aOther.nextObjectStoreId &&
|
|
||||||
this->nextIndexId == aOther.nextIndexId;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Make sure to update ipc/SerializationHelpers.h when changing members here!
|
|
||||||
nsString name;
|
|
||||||
nsCString group;
|
|
||||||
nsCString origin;
|
|
||||||
uint64_t version;
|
|
||||||
PersistenceType persistenceType;
|
|
||||||
int64_t nextObjectStoreId;
|
|
||||||
int64_t nextIndexId;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DatabaseInfo MOZ_FINAL : public DatabaseInfoGuts
|
|
||||||
{
|
|
||||||
DatabaseInfo()
|
|
||||||
: cloned(false)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Private destructor, to discourage deletion outside of Release():
|
|
||||||
~DatabaseInfo();
|
|
||||||
|
|
||||||
public:
|
|
||||||
static bool Get(const nsACString& aId,
|
|
||||||
DatabaseInfo** aInfo);
|
|
||||||
|
|
||||||
static bool Put(DatabaseInfo* aInfo);
|
|
||||||
|
|
||||||
static void Remove(const nsACString& aId);
|
|
||||||
|
|
||||||
bool GetObjectStoreNames(nsTArray<nsString>& aNames);
|
|
||||||
bool ContainsStoreName(const nsAString& aName);
|
|
||||||
|
|
||||||
ObjectStoreInfo* GetObjectStore(const nsAString& aName);
|
|
||||||
|
|
||||||
bool PutObjectStore(ObjectStoreInfo* aInfo);
|
|
||||||
|
|
||||||
void RemoveObjectStore(const nsAString& aName);
|
|
||||||
|
|
||||||
already_AddRefed<DatabaseInfo> Clone();
|
|
||||||
|
|
||||||
nsCString id;
|
|
||||||
nsString filePath;
|
|
||||||
bool cloned;
|
|
||||||
|
|
||||||
nsAutoPtr<ObjectStoreInfoHash> objectStoreHash;
|
|
||||||
|
|
||||||
NS_INLINE_DECL_REFCOUNTING(DatabaseInfo)
|
|
||||||
};
|
|
||||||
|
|
||||||
struct IndexInfo
|
|
||||||
{
|
|
||||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
|
||||||
IndexInfo();
|
|
||||||
IndexInfo(const IndexInfo& aOther);
|
|
||||||
~IndexInfo();
|
|
||||||
#else
|
|
||||||
IndexInfo()
|
|
||||||
: id(INT64_MIN), keyPath(0), unique(false), multiEntry(false) { }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool operator==(const IndexInfo& aOther) const
|
|
||||||
{
|
|
||||||
return this->name == aOther.name &&
|
|
||||||
this->id == aOther.id &&
|
|
||||||
this->keyPath == aOther.keyPath &&
|
|
||||||
this->unique == aOther.unique &&
|
|
||||||
this->multiEntry == aOther.multiEntry;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Make sure to update ipc/SerializationHelpers.h when changing members here!
|
|
||||||
nsString name;
|
|
||||||
int64_t id;
|
|
||||||
KeyPath keyPath;
|
|
||||||
bool unique;
|
|
||||||
bool multiEntry;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ObjectStoreInfoGuts
|
|
||||||
{
|
|
||||||
ObjectStoreInfoGuts()
|
|
||||||
: id(0), keyPath(0), autoIncrement(false)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
bool operator==(const ObjectStoreInfoGuts& aOther) const
|
|
||||||
{
|
|
||||||
return this->name == aOther.name &&
|
|
||||||
this->id == aOther.id;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Make sure to update ipc/SerializationHelpers.h when changing members here!
|
|
||||||
|
|
||||||
// Constant members, can be gotten on any thread
|
|
||||||
nsString name;
|
|
||||||
int64_t id;
|
|
||||||
KeyPath keyPath;
|
|
||||||
bool autoIncrement;
|
|
||||||
|
|
||||||
// Main-thread only members. This must *not* be touched on the database
|
|
||||||
// thread.
|
|
||||||
nsTArray<IndexInfo> indexes;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ObjectStoreInfo MOZ_FINAL : public ObjectStoreInfoGuts
|
|
||||||
{
|
|
||||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
|
||||||
ObjectStoreInfo();
|
|
||||||
#else
|
|
||||||
ObjectStoreInfo()
|
|
||||||
: nextAutoIncrementId(0), comittedAutoIncrementId(0) { }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ObjectStoreInfo(ObjectStoreInfo& aOther);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Private destructor, to discourage deletion outside of Release():
|
|
||||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
|
||||||
~ObjectStoreInfo();
|
|
||||||
#else
|
|
||||||
~ObjectStoreInfo() {}
|
|
||||||
#endif
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Database-thread members. After the ObjectStoreInfo has been initialized,
|
|
||||||
// these can *only* be touced on the database thread.
|
|
||||||
int64_t nextAutoIncrementId;
|
|
||||||
int64_t comittedAutoIncrementId;
|
|
||||||
|
|
||||||
// This is threadsafe since the ObjectStoreInfos are created on the database
|
|
||||||
// thread but then only used from the main thread. Ideal would be if we
|
|
||||||
// could transfer ownership from the database thread to the main thread, but
|
|
||||||
// we don't have that ability yet.
|
|
||||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ObjectStoreInfo)
|
|
||||||
};
|
|
||||||
|
|
||||||
struct IndexUpdateInfo
|
|
||||||
{
|
|
||||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
|
||||||
IndexUpdateInfo();
|
|
||||||
IndexUpdateInfo(const IndexUpdateInfo& aOther);
|
|
||||||
~IndexUpdateInfo();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool operator==(const IndexUpdateInfo& aOther) const
|
|
||||||
{
|
|
||||||
return this->indexId == aOther.indexId &&
|
|
||||||
this->indexUnique == aOther.indexUnique &&
|
|
||||||
this->value == aOther.value;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Make sure to update ipc/SerializationHelpers.h when changing members here!
|
|
||||||
int64_t indexId;
|
|
||||||
bool indexUnique;
|
|
||||||
Key value;
|
|
||||||
};
|
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
|
||||||
|
|
||||||
#endif // mozilla_dom_indexeddb_databaseinfo_h__
|
|
|
@ -5,68 +5,113 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "FileInfo.h"
|
#include "FileInfo.h"
|
||||||
#include "nsThreadUtils.h"
|
|
||||||
#include "mozilla/dom/quota/QuotaManager.h"
|
|
||||||
|
|
||||||
USING_INDEXEDDB_NAMESPACE
|
#include "FileManager.h"
|
||||||
|
#include "IndexedDatabaseManager.h"
|
||||||
|
#include "mozilla/Assertions.h"
|
||||||
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "mozilla/Mutex.h"
|
||||||
|
#include "mozilla/dom/quota/QuotaManager.h"
|
||||||
|
#include "nsError.h"
|
||||||
|
#include "nsThreadUtils.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
namespace indexedDB {
|
||||||
|
|
||||||
|
using namespace mozilla::dom::quota;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class CleanupFileRunnable MOZ_FINAL : public nsIRunnable
|
template <typename IdType>
|
||||||
|
class FileInfoImpl MOZ_FINAL
|
||||||
|
: public FileInfo
|
||||||
{
|
{
|
||||||
~CleanupFileRunnable() {}
|
IdType mFileId;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
FileInfoImpl(FileManager* aFileManager, IdType aFileId)
|
||||||
NS_DECL_NSIRUNNABLE
|
: FileInfo(aFileManager)
|
||||||
|
, mFileId(aFileId)
|
||||||
CleanupFileRunnable(FileManager* aFileManager, int64_t aFileId);
|
{
|
||||||
|
MOZ_ASSERT(aFileManager);
|
||||||
|
MOZ_ASSERT(aFileId > 0);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
~FileInfoImpl()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual int64_t
|
||||||
|
Id() const MOZ_OVERRIDE
|
||||||
|
{
|
||||||
|
return int64_t(mFileId);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CleanupFileRunnable MOZ_FINAL
|
||||||
|
: public nsRunnable
|
||||||
|
{
|
||||||
nsRefPtr<FileManager> mFileManager;
|
nsRefPtr<FileManager> mFileManager;
|
||||||
int64_t mFileId;
|
int64_t mFileId;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void
|
||||||
|
DoCleanup(FileManager* aFileManager, int64_t aFileId);
|
||||||
|
|
||||||
|
CleanupFileRunnable(FileManager* aFileManager, int64_t aFileId)
|
||||||
|
: mFileManager(aFileManager)
|
||||||
|
, mFileId(aFileId)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aFileManager);
|
||||||
|
MOZ_ASSERT(aFileId > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
|
||||||
|
private:
|
||||||
|
~CleanupFileRunnable()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
NS_DECL_NSIRUNNABLE
|
||||||
};
|
};
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
|
FileInfo::FileInfo(FileManager* aFileManager)
|
||||||
|
: mFileManager(aFileManager)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aFileManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileInfo::~FileInfo()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
FileInfo*
|
FileInfo*
|
||||||
FileInfo::Create(FileManager* aFileManager, int64_t aId)
|
FileInfo::Create(FileManager* aFileManager, int64_t aId)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aId > 0, "Wrong id!");
|
MOZ_ASSERT(aFileManager);
|
||||||
|
MOZ_ASSERT(aId > 0);
|
||||||
|
|
||||||
if (aId <= INT16_MAX) {
|
if (aId <= INT16_MAX) {
|
||||||
return new FileInfo16(aFileManager, aId);
|
return new FileInfoImpl<int16_t>(aFileManager, aId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aId <= INT32_MAX) {
|
if (aId <= INT32_MAX) {
|
||||||
return new FileInfo32(aFileManager, aId);
|
return new FileInfoImpl<int32_t>(aFileManager, aId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new FileInfo64(aFileManager, aId);
|
return new FileInfoImpl<int64_t>(aFileManager, aId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FileInfo::GetReferences(int32_t* aRefCnt, int32_t* aDBRefCnt,
|
FileInfo::GetReferences(int32_t* aRefCnt,
|
||||||
|
int32_t* aDBRefCnt,
|
||||||
int32_t* aSliceRefCnt)
|
int32_t* aSliceRefCnt)
|
||||||
{
|
{
|
||||||
if (IndexedDatabaseManager::IsClosed()) {
|
MOZ_ASSERT(!IndexedDatabaseManager::IsClosed());
|
||||||
NS_ERROR("Shouldn't be called after shutdown!");
|
|
||||||
|
|
||||||
if (aRefCnt) {
|
|
||||||
*aRefCnt = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aDBRefCnt) {
|
|
||||||
*aDBRefCnt = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aSliceRefCnt) {
|
|
||||||
*aSliceRefCnt = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MutexAutoLock lock(IndexedDatabaseManager::FileMutex());
|
MutexAutoLock lock(IndexedDatabaseManager::FileMutex());
|
||||||
|
|
||||||
|
@ -84,14 +129,31 @@ FileInfo::GetReferences(int32_t* aRefCnt, int32_t* aDBRefCnt,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FileInfo::UpdateReferences(mozilla::ThreadSafeAutoRefCnt& aRefCount,
|
FileInfo::UpdateReferences(ThreadSafeAutoRefCnt& aRefCount,
|
||||||
int32_t aDelta, bool aClear)
|
int32_t aDelta,
|
||||||
|
bool aClear)
|
||||||
{
|
{
|
||||||
|
// XXX This can go away once DOM objects no longer hold FileInfo objects...
|
||||||
|
// Looking at you, IDBMutableFile...
|
||||||
if (IndexedDatabaseManager::IsClosed()) {
|
if (IndexedDatabaseManager::IsClosed()) {
|
||||||
NS_ERROR("Shouldn't be called after shutdown!");
|
MOZ_ASSERT(&aRefCount == &mRefCnt);
|
||||||
|
MOZ_ASSERT(aDelta == 1 || aDelta == -1);
|
||||||
|
MOZ_ASSERT(!aClear);
|
||||||
|
|
||||||
|
if (aDelta > 0) {
|
||||||
|
++aRefCount;
|
||||||
|
} else {
|
||||||
|
nsrefcnt count = --aRefCount;
|
||||||
|
if (!count) {
|
||||||
|
mRefCnt = 1;
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(!IndexedDatabaseManager::IsClosed());
|
||||||
|
|
||||||
bool needsCleanup;
|
bool needsCleanup;
|
||||||
{
|
{
|
||||||
MutexAutoLock lock(IndexedDatabaseManager::FileMutex());
|
MutexAutoLock lock(IndexedDatabaseManager::FileMutex());
|
||||||
|
@ -117,40 +179,52 @@ FileInfo::UpdateReferences(mozilla::ThreadSafeAutoRefCnt& aRefCount,
|
||||||
void
|
void
|
||||||
FileInfo::Cleanup()
|
FileInfo::Cleanup()
|
||||||
{
|
{
|
||||||
nsRefPtr<CleanupFileRunnable> cleaner =
|
int64_t id = Id();
|
||||||
new CleanupFileRunnable(mFileManager, Id());
|
|
||||||
|
|
||||||
// IndexedDatabaseManager is main-thread only.
|
// IndexedDatabaseManager is main-thread only.
|
||||||
if (!NS_IsMainThread()) {
|
if (!NS_IsMainThread()) {
|
||||||
NS_DispatchToMainThread(cleaner);
|
nsRefPtr<CleanupFileRunnable> cleaner =
|
||||||
|
new CleanupFileRunnable(mFileManager, id);
|
||||||
|
|
||||||
|
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(cleaner)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cleaner->Run();
|
CleanupFileRunnable::DoCleanup(mFileManager, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
CleanupFileRunnable::CleanupFileRunnable(FileManager* aFileManager,
|
// static
|
||||||
int64_t aFileId)
|
void
|
||||||
: mFileManager(aFileManager), mFileId(aFileId)
|
CleanupFileRunnable::DoCleanup(FileManager* aFileManager, int64_t aFileId)
|
||||||
{
|
{
|
||||||
}
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
MOZ_ASSERT(aFileManager);
|
||||||
|
MOZ_ASSERT(aFileId > 0);
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(CleanupFileRunnable,
|
if (NS_WARN_IF(QuotaManager::IsShuttingDown())) {
|
||||||
nsIRunnable)
|
return;
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
CleanupFileRunnable::Run()
|
|
||||||
{
|
|
||||||
if (mozilla::dom::quota::QuotaManager::IsShuttingDown()) {
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<IndexedDatabaseManager> mgr = IndexedDatabaseManager::Get();
|
nsRefPtr<IndexedDatabaseManager> mgr = IndexedDatabaseManager::Get();
|
||||||
MOZ_ASSERT(mgr);
|
MOZ_ASSERT(mgr);
|
||||||
|
|
||||||
if (NS_FAILED(mgr->AsyncDeleteFile(mFileManager, mFileId))) {
|
if (NS_FAILED(mgr->AsyncDeleteFile(aFileManager, aFileId))) {
|
||||||
NS_WARNING("Failed to delete file asynchronously!");
|
NS_WARNING("Failed to delete file asynchronously!");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS_INHERITED0(CleanupFileRunnable, nsRunnable)
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
CleanupFileRunnable::Run()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
DoCleanup(mFileManager, mFileId);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace indexedDB
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
|
@ -7,112 +7,88 @@
|
||||||
#ifndef mozilla_dom_indexeddb_fileinfo_h__
|
#ifndef mozilla_dom_indexeddb_fileinfo_h__
|
||||||
#define mozilla_dom_indexeddb_fileinfo_h__
|
#define mozilla_dom_indexeddb_fileinfo_h__
|
||||||
|
|
||||||
#include "IndexedDatabase.h"
|
#include "nsAutoPtr.h"
|
||||||
|
#include "nsISupportsImpl.h"
|
||||||
|
|
||||||
#include "FileManager.h"
|
namespace mozilla {
|
||||||
#include "IndexedDatabaseManager.h"
|
namespace dom {
|
||||||
|
namespace indexedDB {
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
class FileManager;
|
||||||
|
|
||||||
class FileInfo
|
class FileInfo
|
||||||
{
|
{
|
||||||
friend class FileManager;
|
friend class FileManager;
|
||||||
|
|
||||||
public:
|
|
||||||
explicit FileInfo(FileManager* aFileManager)
|
|
||||||
: mFileManager(aFileManager)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual ~FileInfo()
|
|
||||||
{ }
|
|
||||||
|
|
||||||
static
|
|
||||||
FileInfo* Create(FileManager* aFileManager, int64_t aId);
|
|
||||||
|
|
||||||
void AddRef()
|
|
||||||
{
|
|
||||||
if (IndexedDatabaseManager::IsClosed()) {
|
|
||||||
++mRefCnt;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
UpdateReferences(mRefCnt, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Release()
|
|
||||||
{
|
|
||||||
if (IndexedDatabaseManager::IsClosed()) {
|
|
||||||
nsrefcnt count = --mRefCnt;
|
|
||||||
if (count == 0) {
|
|
||||||
mRefCnt = 1;
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
UpdateReferences(mRefCnt, -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateDBRefs(int32_t aDelta)
|
|
||||||
{
|
|
||||||
UpdateReferences(mDBRefCnt, aDelta);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClearDBRefs()
|
|
||||||
{
|
|
||||||
UpdateReferences(mDBRefCnt, 0, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateSliceRefs(int32_t aDelta)
|
|
||||||
{
|
|
||||||
UpdateReferences(mSliceRefCnt, aDelta);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetReferences(int32_t* aRefCnt, int32_t* aDBRefCnt,
|
|
||||||
int32_t* aSliceRefCnt);
|
|
||||||
|
|
||||||
FileManager* Manager() const
|
|
||||||
{
|
|
||||||
return mFileManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual int64_t Id() const = 0;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void UpdateReferences(ThreadSafeAutoRefCnt& aRefCount, int32_t aDelta,
|
|
||||||
bool aClear = false);
|
|
||||||
void Cleanup();
|
|
||||||
|
|
||||||
ThreadSafeAutoRefCnt mRefCnt;
|
ThreadSafeAutoRefCnt mRefCnt;
|
||||||
ThreadSafeAutoRefCnt mDBRefCnt;
|
ThreadSafeAutoRefCnt mDBRefCnt;
|
||||||
ThreadSafeAutoRefCnt mSliceRefCnt;
|
ThreadSafeAutoRefCnt mSliceRefCnt;
|
||||||
|
|
||||||
nsRefPtr<FileManager> mFileManager;
|
nsRefPtr<FileManager> mFileManager;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static
|
||||||
|
FileInfo* Create(FileManager* aFileManager, int64_t aId);
|
||||||
|
|
||||||
|
explicit FileInfo(FileManager* aFileManager);
|
||||||
|
|
||||||
|
void
|
||||||
|
AddRef()
|
||||||
|
{
|
||||||
|
UpdateReferences(mRefCnt, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Release()
|
||||||
|
{
|
||||||
|
UpdateReferences(mRefCnt, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UpdateDBRefs(int32_t aDelta)
|
||||||
|
{
|
||||||
|
UpdateReferences(mDBRefCnt, aDelta);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ClearDBRefs()
|
||||||
|
{
|
||||||
|
UpdateReferences(mDBRefCnt, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UpdateSliceRefs(int32_t aDelta)
|
||||||
|
{
|
||||||
|
UpdateReferences(mSliceRefCnt, aDelta);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GetReferences(int32_t* aRefCnt, int32_t* aDBRefCnt, int32_t* aSliceRefCnt);
|
||||||
|
|
||||||
|
FileManager*
|
||||||
|
Manager() const
|
||||||
|
{
|
||||||
|
return mFileManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int64_t
|
||||||
|
Id() const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~FileInfo();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void
|
||||||
|
UpdateReferences(ThreadSafeAutoRefCnt& aRefCount,
|
||||||
|
int32_t aDelta,
|
||||||
|
bool aClear = false);
|
||||||
|
|
||||||
|
void
|
||||||
|
Cleanup();
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FILEINFO_SUBCLASS(_bits) \
|
} // namespace indexedDB
|
||||||
class FileInfo##_bits : public FileInfo \
|
} // namespace dom
|
||||||
{ \
|
} // namespace mozilla
|
||||||
public: \
|
|
||||||
FileInfo##_bits(FileManager* aFileManager, int##_bits##_t aId) \
|
|
||||||
: FileInfo(aFileManager), mId(aId) \
|
|
||||||
{ } \
|
|
||||||
\
|
|
||||||
virtual int64_t Id() const \
|
|
||||||
{ \
|
|
||||||
return mId; \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
private: \
|
|
||||||
int##_bits##_t mId; \
|
|
||||||
};
|
|
||||||
|
|
||||||
FILEINFO_SUBCLASS(16)
|
|
||||||
FILEINFO_SUBCLASS(32)
|
|
||||||
FILEINFO_SUBCLASS(64)
|
|
||||||
|
|
||||||
#undef FILEINFO_SUBCLASS
|
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
|
||||||
|
|
||||||
#endif // mozilla_dom_indexeddb_fileinfo_h__
|
#endif // mozilla_dom_indexeddb_fileinfo_h__
|
||||||
|
|
|
@ -1,433 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* vim: set ts=2 et sw=2 tw=80: */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "FileManager.h"
|
|
||||||
|
|
||||||
#include "mozIStorageConnection.h"
|
|
||||||
#include "mozIStorageStatement.h"
|
|
||||||
#include "nsIInputStream.h"
|
|
||||||
#include "nsISimpleEnumerator.h"
|
|
||||||
|
|
||||||
#include "mozilla/dom/quota/Utilities.h"
|
|
||||||
#include "mozStorageCID.h"
|
|
||||||
#include "mozStorageHelper.h"
|
|
||||||
|
|
||||||
#include "Client.h"
|
|
||||||
#include "FileInfo.h"
|
|
||||||
#include "IndexedDatabaseManager.h"
|
|
||||||
#include "OpenDatabaseHelper.h"
|
|
||||||
|
|
||||||
#include "IndexedDatabaseInlines.h"
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
USING_INDEXEDDB_NAMESPACE
|
|
||||||
using mozilla::dom::quota::AssertIsOnIOThread;
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
PLDHashOperator
|
|
||||||
EnumerateToTArray(const uint64_t& aKey,
|
|
||||||
FileInfo* aValue,
|
|
||||||
void* aUserArg)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(aValue, "Null pointer!");
|
|
||||||
NS_ASSERTION(aUserArg, "Null pointer!");
|
|
||||||
|
|
||||||
nsTArray<FileInfo*>* array =
|
|
||||||
static_cast<nsTArray<FileInfo*>*>(aUserArg);
|
|
||||||
|
|
||||||
array->AppendElement(aValue);
|
|
||||||
|
|
||||||
return PL_DHASH_NEXT;
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<nsIFile>
|
|
||||||
GetDirectoryFor(const nsAString& aDirectoryPath)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIFile> directory =
|
|
||||||
do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
|
|
||||||
NS_ENSURE_TRUE(directory, nullptr);
|
|
||||||
|
|
||||||
nsresult rv = directory->InitWithPath(aDirectoryPath);
|
|
||||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
|
||||||
|
|
||||||
return directory.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
FileManager::Init(nsIFile* aDirectory,
|
|
||||||
mozIStorageConnection* aConnection)
|
|
||||||
{
|
|
||||||
AssertIsOnIOThread();
|
|
||||||
NS_ASSERTION(aDirectory, "Null directory!");
|
|
||||||
NS_ASSERTION(aConnection, "Null connection!");
|
|
||||||
|
|
||||||
bool exists;
|
|
||||||
nsresult rv = aDirectory->Exists(&exists);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (exists) {
|
|
||||||
bool isDirectory;
|
|
||||||
rv = aDirectory->IsDirectory(&isDirectory);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
NS_ENSURE_TRUE(isDirectory, NS_ERROR_FAILURE);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rv = aDirectory->Create(nsIFile::DIRECTORY_TYPE, 0755);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = aDirectory->GetPath(mDirectoryPath);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> journalDirectory;
|
|
||||||
rv = aDirectory->Clone(getter_AddRefs(journalDirectory));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = journalDirectory->Append(NS_LITERAL_STRING(JOURNAL_DIRECTORY_NAME));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = journalDirectory->Exists(&exists);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (exists) {
|
|
||||||
bool isDirectory;
|
|
||||||
rv = journalDirectory->IsDirectory(&isDirectory);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
NS_ENSURE_TRUE(isDirectory, NS_ERROR_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = journalDirectory->GetPath(mJournalDirectoryPath);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsCOMPtr<mozIStorageStatement> stmt;
|
|
||||||
rv = aConnection->CreateStatement(NS_LITERAL_CSTRING(
|
|
||||||
"SELECT id, refcount "
|
|
||||||
"FROM file"
|
|
||||||
), getter_AddRefs(stmt));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
bool hasResult;
|
|
||||||
while (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
|
|
||||||
int64_t id;
|
|
||||||
rv = stmt->GetInt64(0, &id);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
int32_t refcount;
|
|
||||||
rv = stmt->GetInt32(1, &refcount);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
NS_ASSERTION(refcount, "This shouldn't happen!");
|
|
||||||
|
|
||||||
nsRefPtr<FileInfo> fileInfo = FileInfo::Create(this, id);
|
|
||||||
fileInfo->mDBRefCnt = refcount;
|
|
||||||
|
|
||||||
mFileInfos.Put(id, fileInfo);
|
|
||||||
|
|
||||||
mLastFileId = std::max(id, mLastFileId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
FileManager::Invalidate()
|
|
||||||
{
|
|
||||||
if (IndexedDatabaseManager::IsClosed()) {
|
|
||||||
NS_ERROR("Shouldn't be called after shutdown!");
|
|
||||||
return NS_ERROR_UNEXPECTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsTArray<FileInfo*> fileInfos;
|
|
||||||
{
|
|
||||||
MutexAutoLock lock(IndexedDatabaseManager::FileMutex());
|
|
||||||
|
|
||||||
NS_ASSERTION(!mInvalidated, "Invalidate more than once?!");
|
|
||||||
mInvalidated = true;
|
|
||||||
|
|
||||||
fileInfos.SetCapacity(mFileInfos.Count());
|
|
||||||
mFileInfos.EnumerateRead(EnumerateToTArray, &fileInfos);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < fileInfos.Length(); i++) {
|
|
||||||
FileInfo* fileInfo = fileInfos.ElementAt(i);
|
|
||||||
fileInfo->ClearDBRefs();
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<nsIFile>
|
|
||||||
FileManager::GetDirectory()
|
|
||||||
{
|
|
||||||
return GetDirectoryFor(mDirectoryPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<nsIFile>
|
|
||||||
FileManager::GetJournalDirectory()
|
|
||||||
{
|
|
||||||
return GetDirectoryFor(mJournalDirectoryPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<nsIFile>
|
|
||||||
FileManager::EnsureJournalDirectory()
|
|
||||||
{
|
|
||||||
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> journalDirectory = GetDirectoryFor(mJournalDirectoryPath);
|
|
||||||
NS_ENSURE_TRUE(journalDirectory, nullptr);
|
|
||||||
|
|
||||||
bool exists;
|
|
||||||
nsresult rv = journalDirectory->Exists(&exists);
|
|
||||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
|
||||||
|
|
||||||
if (exists) {
|
|
||||||
bool isDirectory;
|
|
||||||
rv = journalDirectory->IsDirectory(&isDirectory);
|
|
||||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
|
||||||
NS_ENSURE_TRUE(isDirectory, nullptr);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rv = journalDirectory->Create(nsIFile::DIRECTORY_TYPE, 0755);
|
|
||||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return journalDirectory.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<FileInfo>
|
|
||||||
FileManager::GetFileInfo(int64_t aId)
|
|
||||||
{
|
|
||||||
if (IndexedDatabaseManager::IsClosed()) {
|
|
||||||
NS_ERROR("Shouldn't be called after shutdown!");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileInfo* fileInfo = nullptr;
|
|
||||||
{
|
|
||||||
MutexAutoLock lock(IndexedDatabaseManager::FileMutex());
|
|
||||||
fileInfo = mFileInfos.Get(aId);
|
|
||||||
}
|
|
||||||
nsRefPtr<FileInfo> result = fileInfo;
|
|
||||||
return result.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<FileInfo>
|
|
||||||
FileManager::GetNewFileInfo()
|
|
||||||
{
|
|
||||||
if (IndexedDatabaseManager::IsClosed()) {
|
|
||||||
NS_ERROR("Shouldn't be called after shutdown!");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAutoPtr<FileInfo> fileInfo;
|
|
||||||
|
|
||||||
{
|
|
||||||
MutexAutoLock lock(IndexedDatabaseManager::FileMutex());
|
|
||||||
|
|
||||||
int64_t id = mLastFileId + 1;
|
|
||||||
|
|
||||||
fileInfo = FileInfo::Create(this, id);
|
|
||||||
|
|
||||||
mFileInfos.Put(id, fileInfo);
|
|
||||||
|
|
||||||
mLastFileId = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<FileInfo> result = fileInfo.forget();
|
|
||||||
return result.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
already_AddRefed<nsIFile>
|
|
||||||
FileManager::GetFileForId(nsIFile* aDirectory, int64_t aId)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(aDirectory, "Null pointer!");
|
|
||||||
|
|
||||||
nsAutoString id;
|
|
||||||
id.AppendInt(aId);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> file;
|
|
||||||
nsresult rv = aDirectory->Clone(getter_AddRefs(file));
|
|
||||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
|
||||||
|
|
||||||
rv = file->Append(id);
|
|
||||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
|
||||||
|
|
||||||
return file.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
nsresult
|
|
||||||
FileManager::InitDirectory(nsIFile* aDirectory,
|
|
||||||
nsIFile* aDatabaseFile,
|
|
||||||
PersistenceType aPersistenceType,
|
|
||||||
const nsACString& aGroup,
|
|
||||||
const nsACString& aOrigin)
|
|
||||||
{
|
|
||||||
AssertIsOnIOThread();
|
|
||||||
NS_ASSERTION(aDirectory, "Null directory!");
|
|
||||||
NS_ASSERTION(aDatabaseFile, "Null database file!");
|
|
||||||
|
|
||||||
bool exists;
|
|
||||||
nsresult rv = aDirectory->Exists(&exists);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (!exists) {
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isDirectory;
|
|
||||||
rv = aDirectory->IsDirectory(&isDirectory);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
NS_ENSURE_TRUE(isDirectory, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> journalDirectory;
|
|
||||||
rv = aDirectory->Clone(getter_AddRefs(journalDirectory));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = journalDirectory->Append(NS_LITERAL_STRING(JOURNAL_DIRECTORY_NAME));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = journalDirectory->Exists(&exists);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (exists) {
|
|
||||||
rv = journalDirectory->IsDirectory(&isDirectory);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
NS_ENSURE_TRUE(isDirectory, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
nsCOMPtr<nsISimpleEnumerator> entries;
|
|
||||||
rv = journalDirectory->GetDirectoryEntries(getter_AddRefs(entries));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
bool hasElements;
|
|
||||||
rv = entries->HasMoreElements(&hasElements);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (hasElements) {
|
|
||||||
nsCOMPtr<mozIStorageConnection> connection;
|
|
||||||
rv = OpenDatabaseHelper::CreateDatabaseConnection(aDatabaseFile,
|
|
||||||
aDirectory, NullString(), aPersistenceType, aGroup, aOrigin,
|
|
||||||
getter_AddRefs(connection));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
mozStorageTransaction transaction(connection, false);
|
|
||||||
|
|
||||||
rv = connection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
|
||||||
"CREATE VIRTUAL TABLE fs USING filesystem;"
|
|
||||||
));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsCOMPtr<mozIStorageStatement> stmt;
|
|
||||||
rv = connection->CreateStatement(NS_LITERAL_CSTRING(
|
|
||||||
"SELECT name, (name IN (SELECT id FROM file)) FROM fs "
|
|
||||||
"WHERE path = :path"
|
|
||||||
), getter_AddRefs(stmt));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsString path;
|
|
||||||
rv = journalDirectory->GetPath(path);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = stmt->BindStringByName(NS_LITERAL_CSTRING("path"), path);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
bool hasResult;
|
|
||||||
while (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
|
|
||||||
nsString name;
|
|
||||||
rv = stmt->GetString(0, name);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
int32_t flag = stmt->AsInt32(1);
|
|
||||||
|
|
||||||
if (!flag) {
|
|
||||||
nsCOMPtr<nsIFile> file;
|
|
||||||
rv = aDirectory->Clone(getter_AddRefs(file));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = file->Append(name);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (NS_FAILED(file->Remove(false))) {
|
|
||||||
NS_WARNING("Failed to remove orphaned file!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> journalFile;
|
|
||||||
rv = journalDirectory->Clone(getter_AddRefs(journalFile));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = journalFile->Append(name);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (NS_FAILED(journalFile->Remove(false))) {
|
|
||||||
NS_WARNING("Failed to remove journal file!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = connection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
|
||||||
"DROP TABLE fs;"
|
|
||||||
));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
transaction.Commit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
nsresult
|
|
||||||
FileManager::GetUsage(nsIFile* aDirectory, uint64_t* aUsage)
|
|
||||||
{
|
|
||||||
AssertIsOnIOThread();
|
|
||||||
|
|
||||||
bool exists;
|
|
||||||
nsresult rv = aDirectory->Exists(&exists);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (!exists) {
|
|
||||||
*aUsage = 0;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsISimpleEnumerator> entries;
|
|
||||||
rv = aDirectory->GetDirectoryEntries(getter_AddRefs(entries));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
uint64_t usage = 0;
|
|
||||||
|
|
||||||
bool hasMore;
|
|
||||||
while (NS_SUCCEEDED((rv = entries->HasMoreElements(&hasMore))) && hasMore) {
|
|
||||||
nsCOMPtr<nsISupports> entry;
|
|
||||||
rv = entries->GetNext(getter_AddRefs(entry));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> file = do_QueryInterface(entry);
|
|
||||||
NS_ENSURE_TRUE(file, NS_NOINTERFACE);
|
|
||||||
|
|
||||||
nsString leafName;
|
|
||||||
rv = file->GetLeafName(leafName);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (leafName.EqualsLiteral(JOURNAL_DIRECTORY_NAME)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t fileSize;
|
|
||||||
rv = file->GetFileSize(&fileSize);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
quota::IncrementUsage(&usage, uint64_t(fileSize));
|
|
||||||
}
|
|
||||||
|
|
||||||
*aUsage = usage;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
|
@ -7,21 +7,23 @@
|
||||||
#ifndef mozilla_dom_indexeddb_filemanager_h__
|
#ifndef mozilla_dom_indexeddb_filemanager_h__
|
||||||
#define mozilla_dom_indexeddb_filemanager_h__
|
#define mozilla_dom_indexeddb_filemanager_h__
|
||||||
|
|
||||||
#include "IndexedDatabase.h"
|
#include "mozilla/Attributes.h"
|
||||||
|
|
||||||
#include "nsIDOMFile.h"
|
|
||||||
#include "nsIFile.h"
|
|
||||||
|
|
||||||
#include "mozilla/dom/quota/PersistenceType.h"
|
#include "mozilla/dom/quota/PersistenceType.h"
|
||||||
#include "mozilla/dom/quota/StoragePrivilege.h"
|
#include "mozilla/dom/quota/StoragePrivilege.h"
|
||||||
#include "nsDataHashtable.h"
|
#include "nsDataHashtable.h"
|
||||||
|
#include "nsHashKeys.h"
|
||||||
|
#include "nsISupportsImpl.h"
|
||||||
|
|
||||||
|
class nsIFile;
|
||||||
class mozIStorageConnection;
|
class mozIStorageConnection;
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
namespace indexedDB {
|
||||||
|
|
||||||
class FileInfo;
|
class FileInfo;
|
||||||
|
|
||||||
|
// Implemented in ActorsParent.cpp.
|
||||||
class FileManager MOZ_FINAL
|
class FileManager MOZ_FINAL
|
||||||
{
|
{
|
||||||
friend class FileInfo;
|
friend class FileInfo;
|
||||||
|
@ -29,79 +31,6 @@ class FileManager MOZ_FINAL
|
||||||
typedef mozilla::dom::quota::PersistenceType PersistenceType;
|
typedef mozilla::dom::quota::PersistenceType PersistenceType;
|
||||||
typedef mozilla::dom::quota::StoragePrivilege StoragePrivilege;
|
typedef mozilla::dom::quota::StoragePrivilege StoragePrivilege;
|
||||||
|
|
||||||
public:
|
|
||||||
FileManager(PersistenceType aPersistenceType, const nsACString& aGroup,
|
|
||||||
const nsACString& aOrigin, StoragePrivilege aPrivilege,
|
|
||||||
const nsAString& aDatabaseName)
|
|
||||||
: mPersistenceType(aPersistenceType), mGroup(aGroup), mOrigin(aOrigin),
|
|
||||||
mPrivilege(aPrivilege), mDatabaseName(aDatabaseName), mLastFileId(0),
|
|
||||||
mInvalidated(false)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FileManager)
|
|
||||||
|
|
||||||
PersistenceType Type()
|
|
||||||
{
|
|
||||||
return mPersistenceType;
|
|
||||||
}
|
|
||||||
|
|
||||||
const nsACString& Group() const
|
|
||||||
{
|
|
||||||
return mGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
const nsACString& Origin() const
|
|
||||||
{
|
|
||||||
return mOrigin;
|
|
||||||
}
|
|
||||||
|
|
||||||
const StoragePrivilege& Privilege() const
|
|
||||||
{
|
|
||||||
return mPrivilege;
|
|
||||||
}
|
|
||||||
|
|
||||||
const nsAString& DatabaseName() const
|
|
||||||
{
|
|
||||||
return mDatabaseName;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Invalidated() const
|
|
||||||
{
|
|
||||||
return mInvalidated;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult Init(nsIFile* aDirectory,
|
|
||||||
mozIStorageConnection* aConnection);
|
|
||||||
|
|
||||||
nsresult Invalidate();
|
|
||||||
|
|
||||||
already_AddRefed<nsIFile> GetDirectory();
|
|
||||||
|
|
||||||
already_AddRefed<nsIFile> GetJournalDirectory();
|
|
||||||
|
|
||||||
already_AddRefed<nsIFile> EnsureJournalDirectory();
|
|
||||||
|
|
||||||
already_AddRefed<FileInfo> GetFileInfo(int64_t aId);
|
|
||||||
|
|
||||||
already_AddRefed<FileInfo> GetNewFileInfo();
|
|
||||||
|
|
||||||
static already_AddRefed<nsIFile> GetFileForId(nsIFile* aDirectory,
|
|
||||||
int64_t aId);
|
|
||||||
|
|
||||||
static nsresult InitDirectory(nsIFile* aDirectory,
|
|
||||||
nsIFile* aDatabaseFile,
|
|
||||||
PersistenceType aPersistenceType,
|
|
||||||
const nsACString& aGroup,
|
|
||||||
const nsACString& aOrigin);
|
|
||||||
|
|
||||||
static nsresult GetUsage(nsIFile* aDirectory, uint64_t* aUsage);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Private destructor, to discourage deletion outside of Release():
|
|
||||||
~FileManager()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PersistenceType mPersistenceType;
|
PersistenceType mPersistenceType;
|
||||||
nsCString mGroup;
|
nsCString mGroup;
|
||||||
nsCString mOrigin;
|
nsCString mOrigin;
|
||||||
|
@ -117,8 +46,92 @@ private:
|
||||||
nsDataHashtable<nsUint64HashKey, FileInfo*> mFileInfos;
|
nsDataHashtable<nsUint64HashKey, FileInfo*> mFileInfos;
|
||||||
|
|
||||||
bool mInvalidated;
|
bool mInvalidated;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static already_AddRefed<nsIFile>
|
||||||
|
GetFileForId(nsIFile* aDirectory, int64_t aId);
|
||||||
|
|
||||||
|
static nsresult
|
||||||
|
InitDirectory(nsIFile* aDirectory,
|
||||||
|
nsIFile* aDatabaseFile,
|
||||||
|
PersistenceType aPersistenceType,
|
||||||
|
const nsACString& aGroup,
|
||||||
|
const nsACString& aOrigin);
|
||||||
|
|
||||||
|
static nsresult
|
||||||
|
GetUsage(nsIFile* aDirectory, uint64_t* aUsage);
|
||||||
|
|
||||||
|
FileManager(PersistenceType aPersistenceType,
|
||||||
|
const nsACString& aGroup,
|
||||||
|
const nsACString& aOrigin,
|
||||||
|
StoragePrivilege aPrivilege,
|
||||||
|
const nsAString& aDatabaseName);
|
||||||
|
|
||||||
|
PersistenceType
|
||||||
|
Type() const
|
||||||
|
{
|
||||||
|
return mPersistenceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nsACString&
|
||||||
|
Group() const
|
||||||
|
{
|
||||||
|
return mGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nsACString&
|
||||||
|
Origin() const
|
||||||
|
{
|
||||||
|
return mOrigin;
|
||||||
|
}
|
||||||
|
|
||||||
|
const StoragePrivilege&
|
||||||
|
Privilege() const
|
||||||
|
{
|
||||||
|
return mPrivilege;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nsAString&
|
||||||
|
DatabaseName() const
|
||||||
|
{
|
||||||
|
return mDatabaseName;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Invalidated() const
|
||||||
|
{
|
||||||
|
return mInvalidated;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Init(nsIFile* aDirectory, mozIStorageConnection* aConnection);
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Invalidate();
|
||||||
|
|
||||||
|
already_AddRefed<nsIFile>
|
||||||
|
GetDirectory();
|
||||||
|
|
||||||
|
already_AddRefed<nsIFile>
|
||||||
|
GetJournalDirectory();
|
||||||
|
|
||||||
|
already_AddRefed<nsIFile>
|
||||||
|
EnsureJournalDirectory();
|
||||||
|
|
||||||
|
already_AddRefed<FileInfo>
|
||||||
|
GetFileInfo(int64_t aId);
|
||||||
|
|
||||||
|
already_AddRefed<FileInfo>
|
||||||
|
GetNewFileInfo();
|
||||||
|
|
||||||
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FileManager)
|
||||||
|
|
||||||
|
private:
|
||||||
|
~FileManager();
|
||||||
};
|
};
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
} // namespace indexedDB
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif // mozilla_dom_indexeddb_filemanager_h__
|
#endif // mozilla_dom_indexeddb_filemanager_h__
|
||||||
|
|
|
@ -7,39 +7,56 @@
|
||||||
#include "FileSnapshot.h"
|
#include "FileSnapshot.h"
|
||||||
|
|
||||||
#include "IDBFileHandle.h"
|
#include "IDBFileHandle.h"
|
||||||
|
#include "MainThreadUtils.h"
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
#include "nsDebug.h"
|
#include "mozilla/dom/MetadataHelper.h"
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#include "nsXULAppAPI.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
namespace indexedDB {
|
namespace indexedDB {
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS_INHERITED0(FileImplSnapshot, DOMFileImpl)
|
|
||||||
|
|
||||||
// Create as a stored file
|
// Create as a stored file
|
||||||
FileImplSnapshot::FileImplSnapshot(const nsAString& aName,
|
FileImplSnapshot::FileImplSnapshot(const nsAString& aName,
|
||||||
const nsAString& aContentType,
|
const nsAString& aContentType,
|
||||||
uint64_t aLength, nsIFile* aFile,
|
MetadataParameters* aMetadataParams,
|
||||||
|
nsIFile* aFile,
|
||||||
IDBFileHandle* aFileHandle,
|
IDBFileHandle* aFileHandle,
|
||||||
FileInfo* aFileInfo)
|
FileInfo* aFileInfo)
|
||||||
: DOMFileImplBase(aName, aContentType, aLength),
|
: DOMFileImplBase(aName,
|
||||||
mFile(aFile), mFileHandle(aFileHandle), mWholeFile(true)
|
aContentType,
|
||||||
|
aMetadataParams->Size(),
|
||||||
|
aMetadataParams->LastModified())
|
||||||
|
, mFile(aFile)
|
||||||
|
, mFileHandle(aFileHandle)
|
||||||
|
, mWholeFile(true)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mFile, "Null file!");
|
AssertSanity();
|
||||||
MOZ_ASSERT(mFileHandle, "Null file handle!");
|
MOZ_ASSERT(aMetadataParams);
|
||||||
|
MOZ_ASSERT(aMetadataParams->Size() != UINT64_MAX);
|
||||||
|
MOZ_ASSERT(aMetadataParams->LastModified() != INT64_MAX);
|
||||||
|
MOZ_ASSERT(aFile);
|
||||||
|
MOZ_ASSERT(aFileHandle);
|
||||||
|
MOZ_ASSERT(aFileInfo);
|
||||||
|
|
||||||
mFileInfos.AppendElement(aFileInfo);
|
mFileInfos.AppendElement(aFileInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create slice
|
// Create slice
|
||||||
FileImplSnapshot::FileImplSnapshot(const FileImplSnapshot* aOther,
|
FileImplSnapshot::FileImplSnapshot(const FileImplSnapshot* aOther,
|
||||||
uint64_t aStart, uint64_t aLength,
|
uint64_t aStart,
|
||||||
|
uint64_t aLength,
|
||||||
const nsAString& aContentType)
|
const nsAString& aContentType)
|
||||||
: DOMFileImplBase(aContentType, aOther->mStart + aStart, aLength),
|
: DOMFileImplBase(aContentType, aOther->mStart + aStart, aLength)
|
||||||
mFile(aOther->mFile), mFileHandle(aOther->mFileHandle),
|
, mFile(aOther->mFile)
|
||||||
mWholeFile(false)
|
, mFileHandle(aOther->mFileHandle)
|
||||||
|
, mWholeFile(false)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mFile, "Null file!");
|
AssertSanity();
|
||||||
MOZ_ASSERT(mFileHandle, "Null file handle!");
|
MOZ_ASSERT(aOther);
|
||||||
|
|
||||||
FileInfo* fileInfo;
|
FileInfo* fileInfo;
|
||||||
|
|
||||||
|
@ -57,9 +74,25 @@ FileImplSnapshot::~FileImplSnapshot()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
|
||||||
|
// static
|
||||||
|
void
|
||||||
|
FileImplSnapshot::AssertSanity()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // DEBUG
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS_INHERITED0(FileImplSnapshot, DOMFileImpl)
|
||||||
|
|
||||||
void
|
void
|
||||||
FileImplSnapshot::Unlink()
|
FileImplSnapshot::Unlink()
|
||||||
{
|
{
|
||||||
|
AssertSanity();
|
||||||
|
|
||||||
FileImplSnapshot* tmp = this;
|
FileImplSnapshot* tmp = this;
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFileHandle);
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFileHandle);
|
||||||
}
|
}
|
||||||
|
@ -67,43 +100,80 @@ FileImplSnapshot::Unlink()
|
||||||
void
|
void
|
||||||
FileImplSnapshot::Traverse(nsCycleCollectionTraversalCallback &cb)
|
FileImplSnapshot::Traverse(nsCycleCollectionTraversalCallback &cb)
|
||||||
{
|
{
|
||||||
|
AssertSanity();
|
||||||
|
|
||||||
FileImplSnapshot* tmp = this;
|
FileImplSnapshot* tmp = this;
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFileHandle);
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFileHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
FileImplSnapshot::IsCCed() const
|
||||||
|
{
|
||||||
|
AssertSanity();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
FileImplSnapshot::GetInternalStream(nsIInputStream** aStream)
|
FileImplSnapshot::GetInternalStream(nsIInputStream** aStream)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
AssertSanity();
|
||||||
|
|
||||||
nsresult rv = mFileHandle->OpenInputStream(mWholeFile, mStart, mLength,
|
nsresult rv = mFileHandle->OpenInputStream(mWholeFile, mStart, mLength,
|
||||||
aStream);
|
aStream);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
if (NS_FAILED(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<nsIDOMBlob>
|
already_AddRefed<DOMFileImpl>
|
||||||
FileImplSnapshot::CreateSlice(uint64_t aStart, uint64_t aLength,
|
FileImplSnapshot::CreateSlice(uint64_t aStart,
|
||||||
|
uint64_t aLength,
|
||||||
const nsAString& aContentType)
|
const nsAString& aContentType)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
AssertSanity();
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMBlob> t =
|
nsRefPtr<DOMFileImpl> impl =
|
||||||
new DOMFile(new FileImplSnapshot(this, aStart, aLength, aContentType));
|
new FileImplSnapshot(this, aStart, aLength, aContentType);
|
||||||
|
|
||||||
return t.forget();
|
return impl.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
FileImplSnapshot::GetMozFullPathInternal(nsAString& aFilename)
|
FileImplSnapshot::GetMozFullPathInternal(nsAString& aFilename)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
AssertSanity();
|
||||||
NS_ASSERTION(mIsFile, "Should only be called on files");
|
MOZ_ASSERT(mIsFile);
|
||||||
|
|
||||||
return mFile->GetPath(aFilename);
|
return mFile->GetPath(aFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
FileImplSnapshot::IsStoredFile() const
|
||||||
|
{
|
||||||
|
AssertSanity();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
FileImplSnapshot::IsWholeFile() const
|
||||||
|
{
|
||||||
|
AssertSanity();
|
||||||
|
|
||||||
|
return mWholeFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
FileImplSnapshot::IsSnapshot() const
|
||||||
|
{
|
||||||
|
AssertSanity();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace indexedDB
|
} // namespace indexedDB
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -10,26 +10,55 @@
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "nsAutoPtr.h"
|
#include "nsAutoPtr.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsCycleCollectionParticipant.h"
|
|
||||||
#include "nsDOMFile.h"
|
#include "nsDOMFile.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
|
class MetadataParameters;
|
||||||
|
|
||||||
namespace indexedDB {
|
namespace indexedDB {
|
||||||
|
|
||||||
class IDBFileHandle;
|
class IDBFileHandle;
|
||||||
|
|
||||||
class FileImplSnapshot : public DOMFileImplBase
|
class FileImplSnapshot MOZ_FINAL
|
||||||
|
: public DOMFileImplBase
|
||||||
{
|
{
|
||||||
public:
|
typedef mozilla::dom::MetadataParameters MetadataParameters;
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
|
||||||
|
|
||||||
|
nsCOMPtr<nsIFile> mFile;
|
||||||
|
nsRefPtr<IDBFileHandle> mFileHandle;
|
||||||
|
|
||||||
|
bool mWholeFile;
|
||||||
|
|
||||||
|
public:
|
||||||
// Create as a stored file
|
// Create as a stored file
|
||||||
FileImplSnapshot(const nsAString& aName, const nsAString& aContentType,
|
FileImplSnapshot(const nsAString& aName,
|
||||||
uint64_t aLength, nsIFile* aFile, IDBFileHandle* aFileHandle,
|
const nsAString& aContentType,
|
||||||
|
MetadataParameters* aMetadataParams,
|
||||||
|
nsIFile* aFile,
|
||||||
|
IDBFileHandle* aFileHandle,
|
||||||
FileInfo* aFileInfo);
|
FileInfo* aFileInfo);
|
||||||
|
|
||||||
// Overrides
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Create slice
|
||||||
|
FileImplSnapshot(const FileImplSnapshot* aOther,
|
||||||
|
uint64_t aStart,
|
||||||
|
uint64_t aLength,
|
||||||
|
const nsAString& aContentType);
|
||||||
|
|
||||||
|
~FileImplSnapshot();
|
||||||
|
|
||||||
|
static void
|
||||||
|
AssertSanity()
|
||||||
|
#ifdef DEBUG
|
||||||
|
;
|
||||||
|
#else
|
||||||
|
{ }
|
||||||
|
#endif
|
||||||
|
|
||||||
virtual nsresult
|
virtual nsresult
|
||||||
GetMozFullPathInternal(nsAString& aFullPath) MOZ_OVERRIDE;
|
GetMozFullPathInternal(nsAString& aFullPath) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
@ -43,45 +72,21 @@ public:
|
||||||
Traverse(nsCycleCollectionTraversalCallback &aCb) MOZ_OVERRIDE;
|
Traverse(nsCycleCollectionTraversalCallback &aCb) MOZ_OVERRIDE;
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
IsCCed() const MOZ_OVERRIDE
|
IsCCed() const MOZ_OVERRIDE;
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
virtual already_AddRefed<DOMFileImpl>
|
||||||
// Create slice
|
CreateSlice(uint64_t aStart,
|
||||||
FileImplSnapshot(const FileImplSnapshot* aOther, uint64_t aStart,
|
uint64_t aLength,
|
||||||
uint64_t aLength, const nsAString& aContentType);
|
|
||||||
|
|
||||||
virtual ~FileImplSnapshot();
|
|
||||||
|
|
||||||
virtual already_AddRefed<nsIDOMBlob>
|
|
||||||
CreateSlice(uint64_t aStart, uint64_t aLength,
|
|
||||||
const nsAString& aContentType) MOZ_OVERRIDE;
|
const nsAString& aContentType) MOZ_OVERRIDE;
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
IsStoredFile() const MOZ_OVERRIDE
|
IsStoredFile() const MOZ_OVERRIDE;
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
IsWholeFile() const MOZ_OVERRIDE
|
IsWholeFile() const MOZ_OVERRIDE;
|
||||||
{
|
|
||||||
return mWholeFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
IsSnapshot() const MOZ_OVERRIDE
|
IsSnapshot() const MOZ_OVERRIDE;
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
nsCOMPtr<nsIFile> mFile;
|
|
||||||
nsRefPtr<IDBFileHandle> mFileHandle;
|
|
||||||
|
|
||||||
bool mWholeFile;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace indexedDB
|
} // namespace indexedDB
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -7,59 +7,38 @@
|
||||||
#ifndef mozilla_dom_indexeddb_idbcursor_h__
|
#ifndef mozilla_dom_indexeddb_idbcursor_h__
|
||||||
#define mozilla_dom_indexeddb_idbcursor_h__
|
#define mozilla_dom_indexeddb_idbcursor_h__
|
||||||
|
|
||||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
#include "IndexedDatabase.h"
|
||||||
|
#include "js/RootingAPI.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/dom/IDBCursorBinding.h"
|
#include "mozilla/dom/IDBCursorBinding.h"
|
||||||
#include "mozilla/ErrorResult.h"
|
#include "mozilla/dom/indexedDB/Key.h"
|
||||||
|
#include "nsAutoPtr.h"
|
||||||
#include "nsCycleCollectionParticipant.h"
|
#include "nsCycleCollectionParticipant.h"
|
||||||
#include "nsWrapperCache.h"
|
#include "nsWrapperCache.h"
|
||||||
|
|
||||||
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
|
|
||||||
#include "mozilla/dom/indexedDB/Key.h"
|
|
||||||
|
|
||||||
class nsIRunnable;
|
|
||||||
class nsIScriptContext;
|
|
||||||
class nsPIDOMWindow;
|
class nsPIDOMWindow;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
class ErrorResult;
|
||||||
|
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
class OwningIDBObjectStoreOrIDBIndex;
|
class OwningIDBObjectStoreOrIDBIndex;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
namespace indexedDB {
|
||||||
|
|
||||||
class ContinueHelper;
|
class BackgroundCursorChild;
|
||||||
class ContinueObjectStoreHelper;
|
|
||||||
class ContinueIndexHelper;
|
|
||||||
class ContinueIndexObjectHelper;
|
|
||||||
class IDBIndex;
|
class IDBIndex;
|
||||||
|
class IDBObjectStore;
|
||||||
class IDBRequest;
|
class IDBRequest;
|
||||||
class IDBTransaction;
|
class IDBTransaction;
|
||||||
class IndexedDBCursorChild;
|
|
||||||
class IndexedDBCursorParent;
|
|
||||||
|
|
||||||
class IDBCursor MOZ_FINAL : public nsISupports,
|
class IDBCursor MOZ_FINAL
|
||||||
public nsWrapperCache
|
: public nsISupports
|
||||||
|
, public nsWrapperCache
|
||||||
{
|
{
|
||||||
friend class ContinueHelper;
|
|
||||||
friend class ContinueObjectStoreHelper;
|
|
||||||
friend class ContinueIndexHelper;
|
|
||||||
friend class ContinueIndexObjectHelper;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
|
||||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBCursor)
|
|
||||||
|
|
||||||
enum Type
|
|
||||||
{
|
|
||||||
OBJECTSTORE = 0,
|
|
||||||
OBJECTSTOREKEY,
|
|
||||||
INDEXKEY,
|
|
||||||
INDEXOBJECT
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Direction
|
enum Direction
|
||||||
{
|
{
|
||||||
NEXT = 0,
|
NEXT = 0,
|
||||||
|
@ -71,112 +50,84 @@ public:
|
||||||
DIRECTION_INVALID
|
DIRECTION_INVALID
|
||||||
};
|
};
|
||||||
|
|
||||||
// For OBJECTSTORE cursors.
|
private:
|
||||||
static
|
enum Type
|
||||||
already_AddRefed<IDBCursor>
|
{
|
||||||
Create(IDBRequest* aRequest,
|
Type_ObjectStore,
|
||||||
IDBTransaction* aTransaction,
|
Type_ObjectStoreKey,
|
||||||
IDBObjectStore* aObjectStore,
|
Type_Index,
|
||||||
Direction aDirection,
|
Type_IndexKey,
|
||||||
const Key& aRangeKey,
|
};
|
||||||
const nsACString& aContinueQuery,
|
|
||||||
const nsACString& aContinueToQuery,
|
|
||||||
const Key& aKey,
|
|
||||||
StructuredCloneReadInfo&& aCloneReadInfo);
|
|
||||||
|
|
||||||
// For OBJECTSTOREKEY cursors.
|
nsRefPtr<IDBObjectStore> mSourceObjectStore;
|
||||||
static
|
nsRefPtr<IDBIndex> mSourceIndex;
|
||||||
already_AddRefed<IDBCursor>
|
nsRefPtr<IDBTransaction> mTransaction;
|
||||||
Create(IDBRequest* aRequest,
|
|
||||||
IDBTransaction* aTransaction,
|
BackgroundCursorChild* mBackgroundActor;
|
||||||
IDBObjectStore* aObjectStore,
|
|
||||||
|
JS::Heap<JSObject*> mScriptOwner;
|
||||||
|
|
||||||
|
// These are cycle-collected!
|
||||||
|
JS::Heap<JS::Value> mCachedKey;
|
||||||
|
JS::Heap<JS::Value> mCachedPrimaryKey;
|
||||||
|
JS::Heap<JS::Value> mCachedValue;
|
||||||
|
|
||||||
|
Key mKey;
|
||||||
|
Key mPrimaryKey;
|
||||||
|
StructuredCloneReadInfo mCloneInfo;
|
||||||
|
|
||||||
|
const Type mType;
|
||||||
|
const Direction mDirection;
|
||||||
|
|
||||||
|
bool mHaveCachedKey : 1;
|
||||||
|
bool mHaveCachedPrimaryKey : 1;
|
||||||
|
bool mHaveCachedValue : 1;
|
||||||
|
bool mRooted : 1;
|
||||||
|
bool mContinueCalled : 1;
|
||||||
|
bool mHaveValue : 1;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static already_AddRefed<IDBCursor>
|
||||||
|
Create(IDBObjectStore* aObjectStore,
|
||||||
|
BackgroundCursorChild* aBackgroundActor,
|
||||||
|
Direction aDirection,
|
||||||
|
const Key& aKey,
|
||||||
|
StructuredCloneReadInfo&& aCloneInfo);
|
||||||
|
|
||||||
|
static already_AddRefed<IDBCursor>
|
||||||
|
Create(IDBObjectStore* aObjectStore,
|
||||||
|
BackgroundCursorChild* aBackgroundActor,
|
||||||
Direction aDirection,
|
Direction aDirection,
|
||||||
const Key& aRangeKey,
|
|
||||||
const nsACString& aContinueQuery,
|
|
||||||
const nsACString& aContinueToQuery,
|
|
||||||
const Key& aKey);
|
const Key& aKey);
|
||||||
|
|
||||||
// For INDEXKEY cursors.
|
static already_AddRefed<IDBCursor>
|
||||||
static
|
Create(IDBIndex* aIndex,
|
||||||
already_AddRefed<IDBCursor>
|
BackgroundCursorChild* aBackgroundActor,
|
||||||
Create(IDBRequest* aRequest,
|
|
||||||
IDBTransaction* aTransaction,
|
|
||||||
IDBIndex* aIndex,
|
|
||||||
Direction aDirection,
|
Direction aDirection,
|
||||||
const Key& aRangeKey,
|
|
||||||
const nsACString& aContinueQuery,
|
|
||||||
const nsACString& aContinueToQuery,
|
|
||||||
const Key& aKey,
|
const Key& aKey,
|
||||||
const Key& aObjectKey);
|
const Key& aPrimaryKey,
|
||||||
|
StructuredCloneReadInfo&& aCloneInfo);
|
||||||
|
|
||||||
// For INDEXOBJECT cursors.
|
static already_AddRefed<IDBCursor>
|
||||||
static
|
Create(IDBIndex* aIndex,
|
||||||
already_AddRefed<IDBCursor>
|
BackgroundCursorChild* aBackgroundActor,
|
||||||
Create(IDBRequest* aRequest,
|
|
||||||
IDBTransaction* aTransaction,
|
|
||||||
IDBIndex* aIndex,
|
|
||||||
Direction aDirection,
|
Direction aDirection,
|
||||||
const Key& aRangeKey,
|
|
||||||
const nsACString& aContinueQuery,
|
|
||||||
const nsACString& aContinueToQuery,
|
|
||||||
const Key& aKey,
|
const Key& aKey,
|
||||||
const Key& aObjectKey,
|
const Key& aPrimaryKey);
|
||||||
StructuredCloneReadInfo&& aCloneReadInfo);
|
|
||||||
|
|
||||||
IDBTransaction* Transaction() const
|
|
||||||
{
|
|
||||||
return mTransaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
IDBRequest* Request() const
|
|
||||||
{
|
|
||||||
return mRequest;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Direction
|
static Direction
|
||||||
ConvertDirection(IDBCursorDirection aDirection);
|
ConvertDirection(IDBCursorDirection aDirection);
|
||||||
|
|
||||||
void
|
void
|
||||||
SetActor(IndexedDBCursorChild* aActorChild)
|
AssertIsOnOwningThread() const
|
||||||
{
|
#ifdef DEBUG
|
||||||
NS_ASSERTION(!aActorChild || !mActorChild, "Shouldn't have more than one!");
|
;
|
||||||
mActorChild = aActorChild;
|
#else
|
||||||
}
|
{ }
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
nsPIDOMWindow*
|
||||||
SetActor(IndexedDBCursorParent* aActorParent)
|
GetParentObject() const;
|
||||||
{
|
|
||||||
NS_ASSERTION(!aActorParent || !mActorParent,
|
|
||||||
"Shouldn't have more than one!");
|
|
||||||
mActorParent = aActorParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexedDBCursorChild*
|
|
||||||
GetActorChild() const
|
|
||||||
{
|
|
||||||
return mActorChild;
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexedDBCursorParent*
|
|
||||||
GetActorParent() const
|
|
||||||
{
|
|
||||||
return mActorParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ContinueInternal(const Key& aKey, int32_t aCount,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
|
|
||||||
// nsWrapperCache
|
|
||||||
virtual JSObject*
|
|
||||||
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
// WebIDL
|
|
||||||
IDBTransaction*
|
|
||||||
GetParentObject() const
|
|
||||||
{
|
|
||||||
return mTransaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
GetSource(OwningIDBObjectStoreOrIDBIndex& aSource) const;
|
GetSource(OwningIDBObjectStoreOrIDBIndex& aSource) const;
|
||||||
|
@ -185,80 +136,79 @@ public:
|
||||||
GetDirection() const;
|
GetDirection() const;
|
||||||
|
|
||||||
void
|
void
|
||||||
GetKey(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
|
GetKey(JSContext* aCx,
|
||||||
|
JS::MutableHandle<JS::Value> aResult,
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
||||||
void
|
void
|
||||||
GetPrimaryKey(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
|
GetPrimaryKey(JSContext* aCx,
|
||||||
|
JS::MutableHandle<JS::Value> aResult,
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
void
|
||||||
Update(JSContext* aCx, JS::Handle<JS::Value> aValue, ErrorResult& aRv);
|
GetValue(JSContext* aCx,
|
||||||
|
JS::MutableHandle<JS::Value> aResult,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
void
|
||||||
|
Continue(JSContext* aCx, JS::Handle<JS::Value> aKey, ErrorResult& aRv);
|
||||||
|
|
||||||
void
|
void
|
||||||
Advance(uint32_t aCount, ErrorResult& aRv);
|
Advance(uint32_t aCount, ErrorResult& aRv);
|
||||||
|
|
||||||
void
|
already_AddRefed<IDBRequest>
|
||||||
Continue(JSContext* aCx, JS::Handle<JS::Value> aKey, ErrorResult& aRv);
|
Update(JSContext* aCx, JS::Handle<JS::Value> aValue, ErrorResult& aRv);
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
already_AddRefed<IDBRequest>
|
||||||
Delete(JSContext* aCx, ErrorResult& aRv);
|
Delete(JSContext* aCx, ErrorResult& aRv);
|
||||||
|
|
||||||
void
|
void
|
||||||
GetValue(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
|
Reset();
|
||||||
ErrorResult& aRv);
|
|
||||||
|
void
|
||||||
|
Reset(Key&& aKey, StructuredCloneReadInfo&& aValue);
|
||||||
|
|
||||||
|
void
|
||||||
|
Reset(Key&& aKey);
|
||||||
|
|
||||||
|
void
|
||||||
|
Reset(Key&& aKey, Key&& aPrimaryKey, StructuredCloneReadInfo&& aValue);
|
||||||
|
|
||||||
|
void
|
||||||
|
Reset(Key&& aKey, Key&& aPrimaryKey);
|
||||||
|
|
||||||
|
void
|
||||||
|
ClearBackgroundActor()
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
mBackgroundActor = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||||
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBCursor)
|
||||||
|
|
||||||
|
// nsWrapperCache
|
||||||
|
virtual JSObject*
|
||||||
|
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
IDBCursor(Type aType,
|
||||||
|
IDBObjectStore* aSourceObjectStore,
|
||||||
|
IDBIndex* aSourceIndex,
|
||||||
|
IDBTransaction* aTransaction,
|
||||||
|
BackgroundCursorChild* aBackgroundActor,
|
||||||
|
Direction aDirection,
|
||||||
|
const Key& aKey);
|
||||||
|
|
||||||
protected:
|
|
||||||
IDBCursor();
|
|
||||||
~IDBCursor();
|
~IDBCursor();
|
||||||
|
|
||||||
void DropJSObjects();
|
void
|
||||||
|
DropJSObjects();
|
||||||
static
|
|
||||||
already_AddRefed<IDBCursor>
|
|
||||||
CreateCommon(IDBRequest* aRequest,
|
|
||||||
IDBTransaction* aTransaction,
|
|
||||||
IDBObjectStore* aObjectStore,
|
|
||||||
Direction aDirection,
|
|
||||||
const Key& aRangeKey,
|
|
||||||
const nsACString& aContinueQuery,
|
|
||||||
const nsACString& aContinueToQuery);
|
|
||||||
|
|
||||||
nsRefPtr<IDBRequest> mRequest;
|
|
||||||
nsRefPtr<IDBTransaction> mTransaction;
|
|
||||||
nsRefPtr<IDBObjectStore> mObjectStore;
|
|
||||||
nsRefPtr<IDBIndex> mIndex;
|
|
||||||
|
|
||||||
JS::Heap<JSObject*> mScriptOwner;
|
|
||||||
|
|
||||||
Type mType;
|
|
||||||
Direction mDirection;
|
|
||||||
nsCString mContinueQuery;
|
|
||||||
nsCString mContinueToQuery;
|
|
||||||
|
|
||||||
// These are cycle-collected!
|
|
||||||
JS::Heap<JS::Value> mCachedKey;
|
|
||||||
JS::Heap<JS::Value> mCachedPrimaryKey;
|
|
||||||
JS::Heap<JS::Value> mCachedValue;
|
|
||||||
|
|
||||||
Key mRangeKey;
|
|
||||||
|
|
||||||
Key mKey;
|
|
||||||
Key mObjectKey;
|
|
||||||
StructuredCloneReadInfo mCloneReadInfo;
|
|
||||||
Key mContinueToKey;
|
|
||||||
|
|
||||||
IndexedDBCursorChild* mActorChild;
|
|
||||||
IndexedDBCursorParent* mActorParent;
|
|
||||||
|
|
||||||
bool mHaveCachedKey;
|
|
||||||
bool mHaveCachedPrimaryKey;
|
|
||||||
bool mHaveCachedValue;
|
|
||||||
bool mRooted;
|
|
||||||
bool mContinueCalled;
|
|
||||||
bool mHaveValue;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
} // namespace indexedDB
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif // mozilla_dom_indexeddb_idbcursor_h__
|
#endif // mozilla_dom_indexeddb_idbcursor_h__
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -7,274 +7,302 @@
|
||||||
#ifndef mozilla_dom_indexeddb_idbdatabase_h__
|
#ifndef mozilla_dom_indexeddb_idbdatabase_h__
|
||||||
#define mozilla_dom_indexeddb_idbdatabase_h__
|
#define mozilla_dom_indexeddb_idbdatabase_h__
|
||||||
|
|
||||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
|
||||||
|
|
||||||
#include "nsIDocument.h"
|
|
||||||
#include "nsIOfflineStorage.h"
|
|
||||||
|
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/DOMEventTargetHelper.h"
|
|
||||||
#include "mozilla/dom/IDBObjectStoreBinding.h"
|
|
||||||
#include "mozilla/dom/IDBTransactionBinding.h"
|
#include "mozilla/dom/IDBTransactionBinding.h"
|
||||||
#include "mozilla/dom/quota/PersistenceType.h"
|
#include "mozilla/dom/StorageTypeBinding.h"
|
||||||
|
|
||||||
#include "mozilla/dom/indexedDB/FileManager.h"
|
|
||||||
#include "mozilla/dom/indexedDB/IDBRequest.h"
|
|
||||||
#include "mozilla/dom/indexedDB/IDBWrapperCache.h"
|
#include "mozilla/dom/indexedDB/IDBWrapperCache.h"
|
||||||
|
#include "mozilla/dom/quota/PersistenceType.h"
|
||||||
|
#include "nsAutoPtr.h"
|
||||||
|
#include "nsDataHashtable.h"
|
||||||
|
#include "nsHashKeys.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
#include "nsTHashtable.h"
|
||||||
|
|
||||||
class nsIScriptContext;
|
class nsIDocument;
|
||||||
|
class nsIDOMBlob;
|
||||||
|
class nsIWeakReference;
|
||||||
class nsPIDOMWindow;
|
class nsPIDOMWindow;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
class ErrorResult;
|
||||||
class EventChainPostVisitor;
|
class EventChainPostVisitor;
|
||||||
|
|
||||||
namespace dom {
|
namespace dom {
|
||||||
class nsIContentParent;
|
|
||||||
namespace quota {
|
|
||||||
class Client;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
class DOMStringList;
|
||||||
|
struct IDBObjectStoreParameters;
|
||||||
|
template <typename> class Sequence;
|
||||||
|
|
||||||
class AsyncConnectionHelper;
|
namespace indexedDB {
|
||||||
struct DatabaseInfo;
|
|
||||||
|
class BackgroundDatabaseChild;
|
||||||
|
class DatabaseSpec;
|
||||||
|
class FileManager;
|
||||||
class IDBFactory;
|
class IDBFactory;
|
||||||
class IDBIndex;
|
class IDBMutableFile;
|
||||||
class IDBObjectStore;
|
class IDBObjectStore;
|
||||||
|
class IDBRequest;
|
||||||
class IDBTransaction;
|
class IDBTransaction;
|
||||||
class IndexedDatabaseManager;
|
class PBackgroundIDBDatabaseFileChild;
|
||||||
class IndexedDBDatabaseChild;
|
|
||||||
class IndexedDBDatabaseParent;
|
|
||||||
struct ObjectStoreInfoGuts;
|
|
||||||
|
|
||||||
class IDBDatabase MOZ_FINAL : public IDBWrapperCache,
|
class IDBDatabase MOZ_FINAL
|
||||||
public nsIOfflineStorage
|
: public IDBWrapperCache
|
||||||
{
|
{
|
||||||
friend class AsyncConnectionHelper;
|
typedef mozilla::dom::StorageType StorageType;
|
||||||
friend class IndexedDatabaseManager;
|
typedef mozilla::dom::quota::PersistenceType PersistenceType;
|
||||||
friend class IndexedDBDatabaseParent;
|
|
||||||
friend class IndexedDBDatabaseChild;
|
|
||||||
|
|
||||||
public:
|
class Observer;
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
friend class Observer;
|
||||||
NS_DECL_NSIOFFLINESTORAGE
|
|
||||||
|
|
||||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBDatabase, IDBWrapperCache)
|
|
||||||
|
|
||||||
static already_AddRefed<IDBDatabase>
|
|
||||||
Create(IDBWrapperCache* aOwnerCache,
|
|
||||||
IDBFactory* aFactory,
|
|
||||||
already_AddRefed<DatabaseInfo> aDatabaseInfo,
|
|
||||||
const nsACString& aASCIIOrigin,
|
|
||||||
FileManager* aFileManager,
|
|
||||||
mozilla::dom::nsIContentParent* aContentParent);
|
|
||||||
|
|
||||||
static IDBDatabase*
|
|
||||||
FromStorage(nsIOfflineStorage* aStorage);
|
|
||||||
|
|
||||||
// nsIDOMEventTarget
|
|
||||||
virtual nsresult PostHandleEvent(
|
|
||||||
EventChainPostVisitor& aVisitor) MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
DatabaseInfo* Info() const
|
|
||||||
{
|
|
||||||
return mDatabaseInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
const nsString& Name() const
|
|
||||||
{
|
|
||||||
return mName;
|
|
||||||
}
|
|
||||||
|
|
||||||
const nsString& FilePath() const
|
|
||||||
{
|
|
||||||
return mFilePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<nsIDocument> GetOwnerDocument()
|
|
||||||
{
|
|
||||||
if (!GetOwner()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDocument> doc = GetOwner()->GetExtantDoc();
|
|
||||||
return doc.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Whether or not the database has been invalidated. If it has then no further
|
|
||||||
// transactions for this database will be allowed to run. This function may be
|
|
||||||
// called on any thread.
|
|
||||||
bool IsInvalidated() const
|
|
||||||
{
|
|
||||||
return mInvalidated;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisconnectFromActorParent();
|
|
||||||
|
|
||||||
void CloseInternal(bool aIsDead);
|
|
||||||
|
|
||||||
void EnterSetVersionTransaction();
|
|
||||||
void ExitSetVersionTransaction();
|
|
||||||
|
|
||||||
// Called when a versionchange transaction is aborted to reset the
|
|
||||||
// DatabaseInfo.
|
|
||||||
void RevertToPreviousState();
|
|
||||||
|
|
||||||
FileManager* Manager() const
|
|
||||||
{
|
|
||||||
return mFileManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SetActor(IndexedDBDatabaseChild* aActorChild)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(!aActorChild || !mActorChild, "Shouldn't have more than one!");
|
|
||||||
mActorChild = aActorChild;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SetActor(IndexedDBDatabaseParent* aActorParent)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(!aActorParent || !mActorParent,
|
|
||||||
"Shouldn't have more than one!");
|
|
||||||
mActorParent = aActorParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexedDBDatabaseChild*
|
|
||||||
GetActorChild() const
|
|
||||||
{
|
|
||||||
return mActorChild;
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexedDBDatabaseParent*
|
|
||||||
GetActorParent() const
|
|
||||||
{
|
|
||||||
return mActorParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
mozilla::dom::nsIContentParent*
|
|
||||||
GetContentParent() const
|
|
||||||
{
|
|
||||||
return mContentParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<IDBObjectStore>
|
|
||||||
CreateObjectStoreInternal(IDBTransaction* aTransaction,
|
|
||||||
const ObjectStoreInfoGuts& aInfo,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
|
|
||||||
IDBFactory*
|
|
||||||
Factory() const
|
|
||||||
{
|
|
||||||
return mFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
// nsWrapperCache
|
|
||||||
virtual JSObject*
|
|
||||||
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
// WebIDL
|
|
||||||
nsPIDOMWindow*
|
|
||||||
GetParentObject() const
|
|
||||||
{
|
|
||||||
return GetOwner();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
GetName(nsString& aName) const
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
aName.Assign(mName);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t
|
|
||||||
Version() const;
|
|
||||||
|
|
||||||
already_AddRefed<mozilla::dom::DOMStringList>
|
|
||||||
GetObjectStoreNames(ErrorResult& aRv) const;
|
|
||||||
|
|
||||||
already_AddRefed<IDBObjectStore>
|
|
||||||
CreateObjectStore(JSContext* aCx, const nsAString& aName,
|
|
||||||
const IDBObjectStoreParameters& aOptionalParameters,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
|
|
||||||
void
|
|
||||||
DeleteObjectStore(const nsAString& name, ErrorResult& aRv);
|
|
||||||
|
|
||||||
already_AddRefed<indexedDB::IDBTransaction>
|
|
||||||
Transaction(const nsAString& aStoreName, IDBTransactionMode aMode,
|
|
||||||
ErrorResult& aRv)
|
|
||||||
{
|
|
||||||
Sequence<nsString> list;
|
|
||||||
list.AppendElement(aStoreName);
|
|
||||||
return Transaction(list, aMode, aRv);
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<indexedDB::IDBTransaction>
|
|
||||||
Transaction(const Sequence<nsString>& aStoreNames, IDBTransactionMode aMode,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
|
|
||||||
IMPL_EVENT_HANDLER(abort)
|
|
||||||
IMPL_EVENT_HANDLER(error)
|
|
||||||
IMPL_EVENT_HANDLER(versionchange)
|
|
||||||
|
|
||||||
mozilla::dom::StorageType
|
|
||||||
Storage() const
|
|
||||||
{
|
|
||||||
return PersistenceTypeToStorage(mPersistenceType);
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
|
||||||
CreateMutableFile(const nsAString& aName, const Optional<nsAString>& aType,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
|
||||||
MozCreateFileHandle(const nsAString& aName, const Optional<nsAString>& aType,
|
|
||||||
ErrorResult& aRv)
|
|
||||||
{
|
|
||||||
return CreateMutableFile(aName, aType, aRv);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void LastRelease() MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
private:
|
|
||||||
explicit IDBDatabase(IDBWrapperCache* aOwnerCache);
|
|
||||||
~IDBDatabase();
|
|
||||||
|
|
||||||
void OnUnlink();
|
|
||||||
void InvalidateInternal(bool aIsDead);
|
|
||||||
|
|
||||||
// The factory must be kept alive when IndexedDB is used in multiple
|
// The factory must be kept alive when IndexedDB is used in multiple
|
||||||
// processes. If it dies then the entire actor tree will be destroyed with it
|
// processes. If it dies then the entire actor tree will be destroyed with it
|
||||||
// and the world will explode.
|
// and the world will explode.
|
||||||
nsRefPtr<IDBFactory> mFactory;
|
nsRefPtr<IDBFactory> mFactory;
|
||||||
|
|
||||||
nsRefPtr<DatabaseInfo> mDatabaseInfo;
|
nsAutoPtr<DatabaseSpec> mSpec;
|
||||||
|
|
||||||
// Set to a copy of the existing DatabaseInfo when starting a versionchange
|
// Normally null except during a versionchange transaction.
|
||||||
// transaction.
|
nsAutoPtr<DatabaseSpec> mPreviousSpec;
|
||||||
nsRefPtr<DatabaseInfo> mPreviousDatabaseInfo;
|
|
||||||
nsCString mDatabaseId;
|
|
||||||
nsString mName;
|
|
||||||
nsString mFilePath;
|
|
||||||
nsCString mASCIIOrigin;
|
|
||||||
|
|
||||||
nsRefPtr<FileManager> mFileManager;
|
nsRefPtr<FileManager> mFileManager;
|
||||||
|
|
||||||
IndexedDBDatabaseChild* mActorChild;
|
BackgroundDatabaseChild* mBackgroundActor;
|
||||||
IndexedDBDatabaseParent* mActorParent;
|
|
||||||
|
|
||||||
mozilla::dom::nsIContentParent* mContentParent;
|
nsTHashtable<nsPtrHashKey<IDBTransaction>> mTransactions;
|
||||||
|
|
||||||
nsRefPtr<mozilla::dom::quota::Client> mQuotaClient;
|
nsDataHashtable<nsISupportsHashKey, PBackgroundIDBDatabaseFileChild*>
|
||||||
|
mFileActors;
|
||||||
|
|
||||||
|
nsTHashtable<nsISupportsHashKey> mReceivedBlobs;
|
||||||
|
|
||||||
|
nsRefPtr<Observer> mObserver;
|
||||||
|
|
||||||
|
// Weak refs, IDBMutableFile strongly owns this IDBDatabase object.
|
||||||
|
nsTArray<IDBMutableFile*> mLiveMutableFiles;
|
||||||
|
|
||||||
bool mInvalidated;
|
|
||||||
bool mRegistered;
|
|
||||||
bool mClosed;
|
bool mClosed;
|
||||||
bool mRunningVersionChange;
|
bool mInvalidated;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static already_AddRefed<IDBDatabase>
|
||||||
|
Create(IDBWrapperCache* aOwnerCache,
|
||||||
|
IDBFactory* aFactory,
|
||||||
|
BackgroundDatabaseChild* aActor,
|
||||||
|
DatabaseSpec* aSpec);
|
||||||
|
|
||||||
|
void
|
||||||
|
AssertIsOnOwningThread() const
|
||||||
|
#ifdef DEBUG
|
||||||
|
;
|
||||||
|
#else
|
||||||
|
{ }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const nsString&
|
||||||
|
Name() const;
|
||||||
|
|
||||||
|
void
|
||||||
|
GetName(nsAString& aName) const
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
aName = Name();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t
|
||||||
|
Version() const;
|
||||||
|
|
||||||
|
already_AddRefed<nsIDocument>
|
||||||
|
GetOwnerDocument() const;
|
||||||
|
|
||||||
|
void
|
||||||
|
Close()
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
CloseInternal();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
IsClosed() const
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
return mClosed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Invalidate();
|
||||||
|
|
||||||
|
// Whether or not the database has been invalidated. If it has then no further
|
||||||
|
// transactions for this database will be allowed to run.
|
||||||
|
bool
|
||||||
|
IsInvalidated() const
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
return mInvalidated;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
EnterSetVersionTransaction(uint64_t aNewVersion);
|
||||||
|
|
||||||
|
void
|
||||||
|
ExitSetVersionTransaction();
|
||||||
|
|
||||||
|
// Called when a versionchange transaction is aborted to reset the
|
||||||
|
// DatabaseInfo.
|
||||||
|
void
|
||||||
|
RevertToPreviousState();
|
||||||
|
|
||||||
|
IDBFactory*
|
||||||
|
Factory() const
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
return mFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RegisterTransaction(IDBTransaction* aTransaction);
|
||||||
|
|
||||||
|
void
|
||||||
|
UnregisterTransaction(IDBTransaction* aTransaction);
|
||||||
|
|
||||||
|
void
|
||||||
|
AbortTransactions();
|
||||||
|
|
||||||
|
PBackgroundIDBDatabaseFileChild*
|
||||||
|
GetOrCreateFileActorForBlob(nsIDOMBlob* aBlob);
|
||||||
|
|
||||||
|
void
|
||||||
|
NoteFinishedFileActor(PBackgroundIDBDatabaseFileChild* aFileActor);
|
||||||
|
|
||||||
|
void
|
||||||
|
NoteReceivedBlob(nsIDOMBlob* aBlob);
|
||||||
|
|
||||||
|
void
|
||||||
|
DelayedMaybeExpireFileActors();
|
||||||
|
|
||||||
|
// XXX This doesn't really belong here... It's only needed for IDBMutableFile
|
||||||
|
// serialization and should be removed someday.
|
||||||
|
nsresult
|
||||||
|
GetQuotaInfo(nsACString& aOrigin, PersistenceType* aPersistenceType);
|
||||||
|
|
||||||
|
void
|
||||||
|
NoteLiveMutableFile(IDBMutableFile* aMutableFile);
|
||||||
|
|
||||||
|
void
|
||||||
|
NoteFinishedMutableFile(IDBMutableFile* aMutableFile);
|
||||||
|
|
||||||
|
nsPIDOMWindow*
|
||||||
|
GetParentObject() const;
|
||||||
|
|
||||||
|
already_AddRefed<DOMStringList>
|
||||||
|
ObjectStoreNames() const;
|
||||||
|
|
||||||
|
already_AddRefed<IDBObjectStore>
|
||||||
|
CreateObjectStore(JSContext* aCx,
|
||||||
|
const nsAString& aName,
|
||||||
|
const IDBObjectStoreParameters& aOptionalParameters,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
void
|
||||||
|
DeleteObjectStore(const nsAString& name, ErrorResult& aRv);
|
||||||
|
|
||||||
|
already_AddRefed<IDBTransaction>
|
||||||
|
Transaction(const nsAString& aStoreName,
|
||||||
|
IDBTransactionMode aMode,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
already_AddRefed<IDBTransaction>
|
||||||
|
Transaction(const Sequence<nsString>& aStoreNames,
|
||||||
|
IDBTransactionMode aMode,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
StorageType
|
||||||
|
Storage() const;
|
||||||
|
|
||||||
|
IMPL_EVENT_HANDLER(abort)
|
||||||
|
IMPL_EVENT_HANDLER(error)
|
||||||
|
IMPL_EVENT_HANDLER(versionchange)
|
||||||
|
|
||||||
|
already_AddRefed<IDBRequest>
|
||||||
|
CreateMutableFile(const nsAString& aName,
|
||||||
|
const Optional<nsAString>& aType,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
already_AddRefed<IDBRequest>
|
||||||
|
MozCreateFileHandle(const nsAString& aName,
|
||||||
|
const Optional<nsAString>& aType,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
return CreateMutableFile(aName, aType, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ClearBackgroundActor()
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
mBackgroundActor = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const DatabaseSpec*
|
||||||
|
Spec() const
|
||||||
|
{
|
||||||
|
return mSpec;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBDatabase, IDBWrapperCache)
|
||||||
|
|
||||||
|
// nsIDOMEventTarget
|
||||||
|
virtual void
|
||||||
|
LastRelease() MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual nsresult
|
||||||
|
PostHandleEvent(EventChainPostVisitor& aVisitor) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
// nsWrapperCache
|
||||||
|
virtual JSObject*
|
||||||
|
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
IDBDatabase(IDBWrapperCache* aOwnerCache,
|
||||||
|
IDBFactory* aFactory,
|
||||||
|
BackgroundDatabaseChild* aActor,
|
||||||
|
DatabaseSpec* aSpec);
|
||||||
|
|
||||||
|
~IDBDatabase();
|
||||||
|
|
||||||
|
void
|
||||||
|
CloseInternal();
|
||||||
|
|
||||||
|
void
|
||||||
|
InvalidateInternal();
|
||||||
|
|
||||||
|
bool
|
||||||
|
RunningVersionChangeTransaction() const
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
return !!mPreviousSpec;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RefreshSpec(bool aMayDelete);
|
||||||
|
|
||||||
|
void
|
||||||
|
ExpireFileActors(bool aExpireAll);
|
||||||
|
|
||||||
|
void
|
||||||
|
InvalidateMutableFiles();
|
||||||
};
|
};
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
} // namespace indexedDB
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif // mozilla_dom_indexeddb_idbdatabase_h__
|
#endif // mozilla_dom_indexeddb_idbdatabase_h__
|
||||||
|
|
|
@ -6,49 +6,45 @@
|
||||||
|
|
||||||
#include "IDBEvents.h"
|
#include "IDBEvents.h"
|
||||||
|
|
||||||
#include "nsJSON.h"
|
#include "mozilla/ErrorResult.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "mozilla/dom/EventTarget.h"
|
||||||
|
#include "mozilla/dom/IDBVersionChangeEventBinding.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
|
||||||
#include "IDBRequest.h"
|
using namespace mozilla;
|
||||||
#include "IDBTransaction.h"
|
|
||||||
|
|
||||||
USING_INDEXEDDB_NAMESPACE
|
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
|
using namespace mozilla::dom::indexedDB;
|
||||||
|
|
||||||
namespace {
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
namespace indexedDB {
|
||||||
|
|
||||||
class EventFiringRunnable : public nsRunnable
|
const char16_t* kAbortEventType = MOZ_UTF16("abort");
|
||||||
{
|
const char16_t* kBlockedEventType = MOZ_UTF16("blocked");
|
||||||
public:
|
const char16_t* kCompleteEventType = MOZ_UTF16("complete");
|
||||||
EventFiringRunnable(EventTarget* aTarget,
|
const char16_t* kErrorEventType = MOZ_UTF16("error");
|
||||||
nsIDOMEvent* aEvent)
|
const char16_t* kSuccessEventType = MOZ_UTF16("success");
|
||||||
: mTarget(aTarget), mEvent(aEvent)
|
const char16_t* kUpgradeNeededEventType = MOZ_UTF16("upgradeneeded");
|
||||||
{ }
|
const char16_t* kVersionChangeEventType = MOZ_UTF16("versionchange");
|
||||||
|
|
||||||
NS_IMETHOD Run() {
|
|
||||||
bool dummy;
|
|
||||||
return mTarget->DispatchEvent(mEvent, &dummy);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
nsCOMPtr<EventTarget> mTarget;
|
|
||||||
nsCOMPtr<nsIDOMEvent> mEvent;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
already_AddRefed<nsIDOMEvent>
|
already_AddRefed<nsIDOMEvent>
|
||||||
mozilla::dom::indexedDB::CreateGenericEvent(mozilla::dom::EventTarget* aOwner,
|
CreateGenericEvent(EventTarget* aOwner,
|
||||||
const nsAString& aType,
|
const nsDependentString& aType,
|
||||||
Bubbles aBubbles,
|
Bubbles aBubbles,
|
||||||
Cancelable aCancelable)
|
Cancelable aCancelable)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIDOMEvent> event;
|
nsCOMPtr<nsIDOMEvent> event;
|
||||||
NS_NewDOMEvent(getter_AddRefs(event), aOwner, nullptr, nullptr);
|
nsresult rv = NS_NewDOMEvent(getter_AddRefs(event), aOwner, nullptr, nullptr);
|
||||||
nsresult rv = event->InitEvent(aType,
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
aBubbles == eDoesBubble ? true : false,
|
return nullptr;
|
||||||
aCancelable == eCancelable ? true : false);
|
}
|
||||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
|
||||||
|
rv = event->InitEvent(aType,
|
||||||
|
aBubbles == eDoesBubble ? true : false,
|
||||||
|
aCancelable == eCancelable ? true : false);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
event->SetTrusted(true);
|
event->SetTrusted(true);
|
||||||
|
|
||||||
|
@ -57,37 +53,39 @@ mozilla::dom::indexedDB::CreateGenericEvent(mozilla::dom::EventTarget* aOwner,
|
||||||
|
|
||||||
// static
|
// static
|
||||||
already_AddRefed<IDBVersionChangeEvent>
|
already_AddRefed<IDBVersionChangeEvent>
|
||||||
IDBVersionChangeEvent::CreateInternal(mozilla::dom::EventTarget* aOwner,
|
IDBVersionChangeEvent::CreateInternal(EventTarget* aOwner,
|
||||||
const nsAString& aType,
|
const nsAString& aType,
|
||||||
uint64_t aOldVersion,
|
uint64_t aOldVersion,
|
||||||
uint64_t aNewVersion)
|
Nullable<uint64_t> aNewVersion)
|
||||||
{
|
{
|
||||||
nsRefPtr<IDBVersionChangeEvent> event(new IDBVersionChangeEvent(aOwner));
|
nsRefPtr<IDBVersionChangeEvent> event =
|
||||||
|
new IDBVersionChangeEvent(aOwner, aOldVersion);
|
||||||
|
if (!aNewVersion.IsNull()) {
|
||||||
|
event->mNewVersion.SetValue(aNewVersion.Value());
|
||||||
|
}
|
||||||
|
|
||||||
nsresult rv = event->InitEvent(aType, false, false);
|
nsresult rv = event->InitEvent(aType, false, false);
|
||||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
event->SetTrusted(true);
|
event->SetTrusted(true);
|
||||||
|
|
||||||
event->mOldVersion = aOldVersion;
|
|
||||||
event->mNewVersion = aNewVersion;
|
|
||||||
|
|
||||||
return event.forget();
|
return event.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
already_AddRefed<IDBVersionChangeEvent>
|
||||||
already_AddRefed<nsIRunnable>
|
IDBVersionChangeEvent::Constructor(const GlobalObject& aGlobal,
|
||||||
IDBVersionChangeEvent::CreateRunnableInternal(mozilla::dom::EventTarget* aTarget,
|
const nsAString& aType,
|
||||||
const nsAString& aType,
|
const IDBVersionChangeEventInit& aOptions,
|
||||||
uint64_t aOldVersion,
|
ErrorResult& aRv)
|
||||||
uint64_t aNewVersion)
|
|
||||||
{
|
{
|
||||||
nsRefPtr<Event> event =
|
nsCOMPtr<EventTarget> target = do_QueryInterface(aGlobal.GetAsSupports());
|
||||||
CreateInternal(aTarget, aType, aOldVersion, aNewVersion);
|
|
||||||
NS_ENSURE_TRUE(event, nullptr);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIRunnable> runnable(new EventFiringRunnable(aTarget, event));
|
return CreateInternal(target,
|
||||||
return runnable.forget();
|
aType,
|
||||||
|
aOptions.mOldVersion,
|
||||||
|
aOptions.mNewVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_ADDREF_INHERITED(IDBVersionChangeEvent, Event)
|
NS_IMPL_ADDREF_INHERITED(IDBVersionChangeEvent, Event)
|
||||||
|
@ -96,3 +94,13 @@ NS_IMPL_RELEASE_INHERITED(IDBVersionChangeEvent, Event)
|
||||||
NS_INTERFACE_MAP_BEGIN(IDBVersionChangeEvent)
|
NS_INTERFACE_MAP_BEGIN(IDBVersionChangeEvent)
|
||||||
NS_INTERFACE_MAP_ENTRY(IDBVersionChangeEvent)
|
NS_INTERFACE_MAP_ENTRY(IDBVersionChangeEvent)
|
||||||
NS_INTERFACE_MAP_END_INHERITING(Event)
|
NS_INTERFACE_MAP_END_INHERITING(Event)
|
||||||
|
|
||||||
|
JSObject*
|
||||||
|
IDBVersionChangeEvent::WrapObject(JSContext* aCx)
|
||||||
|
{
|
||||||
|
return IDBVersionChangeEventBinding::Wrap(aCx, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace indexedDB
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
|
@ -7,28 +7,28 @@
|
||||||
#ifndef mozilla_dom_indexeddb_idbevents_h__
|
#ifndef mozilla_dom_indexeddb_idbevents_h__
|
||||||
#define mozilla_dom_indexeddb_idbevents_h__
|
#define mozilla_dom_indexeddb_idbevents_h__
|
||||||
|
|
||||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
#include "js/RootingAPI.h"
|
||||||
|
#include "mozilla/dom/BindingDeclarations.h"
|
||||||
#include "nsIRunnable.h"
|
|
||||||
|
|
||||||
#include "mozilla/dom/Event.h"
|
#include "mozilla/dom/Event.h"
|
||||||
#include "mozilla/dom/Nullable.h"
|
#include "mozilla/dom/Nullable.h"
|
||||||
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
|
|
||||||
#include "mozilla/dom/IDBVersionChangeEventBinding.h"
|
|
||||||
|
|
||||||
#define SUCCESS_EVT_STR "success"
|
|
||||||
#define ERROR_EVT_STR "error"
|
|
||||||
#define COMPLETE_EVT_STR "complete"
|
|
||||||
#define ABORT_EVT_STR "abort"
|
|
||||||
#define VERSIONCHANGE_EVT_STR "versionchange"
|
|
||||||
#define BLOCKED_EVT_STR "blocked"
|
|
||||||
#define UPGRADENEEDED_EVT_STR "upgradeneeded"
|
|
||||||
|
|
||||||
#define IDBVERSIONCHANGEEVENT_IID \
|
#define IDBVERSIONCHANGEEVENT_IID \
|
||||||
{ 0x3b65d4c3, 0x73ad, 0x492e, \
|
{0x3b65d4c3, 0x73ad, 0x492e, {0xb1, 0x2d, 0x15, 0xf9, 0xda, 0xc2, 0x08, 0x4b}}
|
||||||
{ 0xb1, 0x2d, 0x15, 0xf9, 0xda, 0xc2, 0x08, 0x4b } }
|
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
class nsAString;
|
||||||
|
class nsDependentString;
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
class ErrorResult;
|
||||||
|
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
class EventTarget;
|
||||||
|
class GlobalObject;
|
||||||
|
struct IDBVersionChangeEventInit;
|
||||||
|
|
||||||
|
namespace indexedDB {
|
||||||
|
|
||||||
enum Bubbles {
|
enum Bubbles {
|
||||||
eDoesNotBubble,
|
eDoesNotBubble,
|
||||||
|
@ -40,125 +40,94 @@ enum Cancelable {
|
||||||
eCancelable
|
eCancelable
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern const char16_t* kAbortEventType;
|
||||||
|
extern const char16_t* kBlockedEventType;
|
||||||
|
extern const char16_t* kCompleteEventType;
|
||||||
|
extern const char16_t* kErrorEventType;
|
||||||
|
extern const char16_t* kSuccessEventType;
|
||||||
|
extern const char16_t* kUpgradeNeededEventType;
|
||||||
|
extern const char16_t* kVersionChangeEventType;
|
||||||
|
|
||||||
already_AddRefed<nsIDOMEvent>
|
already_AddRefed<nsIDOMEvent>
|
||||||
CreateGenericEvent(mozilla::dom::EventTarget* aOwner,
|
CreateGenericEvent(EventTarget* aOwner,
|
||||||
const nsAString& aType,
|
const nsDependentString& aType,
|
||||||
Bubbles aBubbles,
|
Bubbles aBubbles,
|
||||||
Cancelable aCancelable);
|
Cancelable aCancelable);
|
||||||
|
|
||||||
class IDBVersionChangeEvent : public Event
|
class IDBVersionChangeEvent MOZ_FINAL : public Event
|
||||||
{
|
{
|
||||||
public:
|
uint64_t mOldVersion;
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
Nullable<uint64_t> mNewVersion;
|
||||||
NS_FORWARD_TO_EVENT
|
|
||||||
NS_DECLARE_STATIC_IID_ACCESSOR(IDBVERSIONCHANGEEVENT_IID)
|
|
||||||
|
|
||||||
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE
|
public:
|
||||||
|
static already_AddRefed<IDBVersionChangeEvent>
|
||||||
|
Create(EventTarget* aOwner,
|
||||||
|
const nsDependentString& aName,
|
||||||
|
uint64_t aOldVersion,
|
||||||
|
uint64_t aNewVersion)
|
||||||
{
|
{
|
||||||
return mozilla::dom::IDBVersionChangeEventBinding::Wrap(aCx, this);
|
Nullable<uint64_t> newVersion(aNewVersion);
|
||||||
|
return CreateInternal(aOwner, aName, aOldVersion, newVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
static already_AddRefed<IDBVersionChangeEvent>
|
||||||
|
Create(EventTarget* aOwner,
|
||||||
|
const nsDependentString& aName,
|
||||||
|
uint64_t aOldVersion)
|
||||||
|
{
|
||||||
|
Nullable<uint64_t> newVersion(0);
|
||||||
|
newVersion.SetNull();
|
||||||
|
return CreateInternal(aOwner, aName, aOldVersion, newVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
static already_AddRefed<IDBVersionChangeEvent>
|
static already_AddRefed<IDBVersionChangeEvent>
|
||||||
Constructor(const GlobalObject& aGlobal,
|
Constructor(const GlobalObject& aGlobal,
|
||||||
const nsAString& aType,
|
const nsAString& aType,
|
||||||
const IDBVersionChangeEventInit& aOptions,
|
const IDBVersionChangeEventInit& aOptions,
|
||||||
ErrorResult& aRv)
|
ErrorResult& aRv);
|
||||||
{
|
|
||||||
uint64_t newVersion = 0;
|
|
||||||
if (!aOptions.mNewVersion.IsNull()) {
|
|
||||||
newVersion = aOptions.mNewVersion.Value();
|
|
||||||
}
|
|
||||||
nsCOMPtr<EventTarget> target = do_QueryInterface(aGlobal.GetAsSupports());
|
|
||||||
return CreateInternal(target, aType, aOptions.mOldVersion, newVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t OldVersion()
|
uint64_t
|
||||||
|
OldVersion() const
|
||||||
{
|
{
|
||||||
return mOldVersion;
|
return mOldVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
mozilla::dom::Nullable<uint64_t> GetNewVersion()
|
Nullable<uint64_t>
|
||||||
|
GetNewVersion() const
|
||||||
{
|
{
|
||||||
return mNewVersion
|
return mNewVersion;
|
||||||
? mozilla::dom::Nullable<uint64_t>(mNewVersion)
|
|
||||||
: mozilla::dom::Nullable<uint64_t>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static already_AddRefed<Event>
|
NS_DECLARE_STATIC_IID_ACCESSOR(IDBVERSIONCHANGEEVENT_IID)
|
||||||
Create(mozilla::dom::EventTarget* aOwner,
|
|
||||||
int64_t aOldVersion,
|
|
||||||
int64_t aNewVersion)
|
|
||||||
{
|
|
||||||
return CreateInternal(aOwner,
|
|
||||||
NS_LITERAL_STRING(VERSIONCHANGE_EVT_STR),
|
|
||||||
aOldVersion, aNewVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static already_AddRefed<Event>
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
CreateBlocked(mozilla::dom::EventTarget* aOwner,
|
NS_FORWARD_TO_EVENT
|
||||||
uint64_t aOldVersion,
|
|
||||||
uint64_t aNewVersion)
|
|
||||||
{
|
|
||||||
return CreateInternal(aOwner, NS_LITERAL_STRING(BLOCKED_EVT_STR),
|
|
||||||
aOldVersion, aNewVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static already_AddRefed<Event>
|
virtual JSObject*
|
||||||
CreateUpgradeNeeded(mozilla::dom::EventTarget* aOwner,
|
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||||
uint64_t aOldVersion,
|
|
||||||
uint64_t aNewVersion)
|
|
||||||
{
|
|
||||||
return CreateInternal(aOwner,
|
|
||||||
NS_LITERAL_STRING(UPGRADENEEDED_EVT_STR),
|
|
||||||
aOldVersion, aNewVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static already_AddRefed<nsIRunnable>
|
private:
|
||||||
CreateRunnable(mozilla::dom::EventTarget* aTarget,
|
IDBVersionChangeEvent(EventTarget* aOwner, uint64_t aOldVersion)
|
||||||
uint64_t aOldVersion,
|
|
||||||
uint64_t aNewVersion)
|
|
||||||
{
|
|
||||||
return CreateRunnableInternal(aTarget,
|
|
||||||
NS_LITERAL_STRING(VERSIONCHANGE_EVT_STR),
|
|
||||||
aOldVersion, aNewVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
static already_AddRefed<nsIRunnable>
|
|
||||||
CreateBlockedRunnable(mozilla::dom::EventTarget* aTarget,
|
|
||||||
uint64_t aOldVersion,
|
|
||||||
uint64_t aNewVersion)
|
|
||||||
{
|
|
||||||
return CreateRunnableInternal(aTarget,
|
|
||||||
NS_LITERAL_STRING(BLOCKED_EVT_STR),
|
|
||||||
aOldVersion, aNewVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
explicit IDBVersionChangeEvent(mozilla::dom::EventTarget* aOwner)
|
|
||||||
: Event(aOwner, nullptr, nullptr)
|
: Event(aOwner, nullptr, nullptr)
|
||||||
|
, mOldVersion(aOldVersion)
|
||||||
{
|
{
|
||||||
SetIsDOMBinding();
|
SetIsDOMBinding();
|
||||||
}
|
}
|
||||||
virtual ~IDBVersionChangeEvent() { }
|
|
||||||
|
~IDBVersionChangeEvent()
|
||||||
|
{ }
|
||||||
|
|
||||||
static already_AddRefed<IDBVersionChangeEvent>
|
static already_AddRefed<IDBVersionChangeEvent>
|
||||||
CreateInternal(mozilla::dom::EventTarget* aOwner,
|
CreateInternal(EventTarget* aOwner,
|
||||||
const nsAString& aType,
|
const nsAString& aName,
|
||||||
uint64_t aOldVersion,
|
uint64_t aOldVersion,
|
||||||
uint64_t aNewVersion);
|
Nullable<uint64_t> aNewVersion);
|
||||||
|
|
||||||
static already_AddRefed<nsIRunnable>
|
|
||||||
CreateRunnableInternal(mozilla::dom::EventTarget* aOwner,
|
|
||||||
const nsAString& aType,
|
|
||||||
uint64_t aOldVersion,
|
|
||||||
uint64_t aNewVersion);
|
|
||||||
|
|
||||||
uint64_t mOldVersion;
|
|
||||||
uint64_t mNewVersion;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_DEFINE_STATIC_IID_ACCESSOR(IDBVersionChangeEvent, IDBVERSIONCHANGEEVENT_IID)
|
NS_DEFINE_STATIC_IID_ACCESSOR(IDBVersionChangeEvent, IDBVERSIONCHANGEEVENT_IID)
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
} // namespace indexedDB
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif // mozilla_dom_indexeddb_idbevents_h__
|
#endif // mozilla_dom_indexeddb_idbevents_h__
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -7,219 +7,203 @@
|
||||||
#ifndef mozilla_dom_indexeddb_idbfactory_h__
|
#ifndef mozilla_dom_indexeddb_idbfactory_h__
|
||||||
#define mozilla_dom_indexeddb_idbfactory_h__
|
#define mozilla_dom_indexeddb_idbfactory_h__
|
||||||
|
|
||||||
#include "mozilla/dom/BindingDeclarations.h" // for Optional
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/dom/StorageTypeBinding.h"
|
#include "mozilla/dom/StorageTypeBinding.h"
|
||||||
#include "mozilla/dom/quota/PersistenceType.h"
|
#include "nsAutoPtr.h"
|
||||||
#include "mozilla/dom/quota/StoragePrivilege.h"
|
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsCycleCollectionParticipant.h"
|
#include "nsCycleCollectionParticipant.h"
|
||||||
|
#include "nsISupports.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
#include "nsTArray.h"
|
||||||
#include "nsWrapperCache.h"
|
#include "nsWrapperCache.h"
|
||||||
|
|
||||||
class mozIStorageConnection;
|
|
||||||
class nsIFile;
|
|
||||||
class nsIFileURL;
|
|
||||||
class nsIPrincipal;
|
class nsIPrincipal;
|
||||||
class nsPIDOMWindow;
|
class nsPIDOMWindow;
|
||||||
template<typename> class nsRefPtr;
|
struct PRThread;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
class ErrorResult;
|
class ErrorResult;
|
||||||
|
|
||||||
|
namespace ipc {
|
||||||
|
|
||||||
|
class PBackgroundChild;
|
||||||
|
class PrincipalInfo;
|
||||||
|
|
||||||
|
} // namespace ipc
|
||||||
|
|
||||||
namespace dom {
|
namespace dom {
|
||||||
class nsIContentParent;
|
|
||||||
struct IDBOpenDBOptions;
|
struct IDBOpenDBOptions;
|
||||||
|
class TabChild;
|
||||||
|
|
||||||
namespace indexedDB {
|
namespace indexedDB {
|
||||||
|
|
||||||
struct DatabaseInfo;
|
class BackgroundFactoryChild;
|
||||||
class IDBDatabase;
|
class FactoryRequestParams;
|
||||||
class IDBOpenDBRequest;
|
class IDBOpenDBRequest;
|
||||||
class IndexedDBChild;
|
|
||||||
class IndexedDBParent;
|
|
||||||
|
|
||||||
struct ObjectStoreInfo;
|
class IDBFactory MOZ_FINAL
|
||||||
|
: public nsISupports
|
||||||
class IDBFactory MOZ_FINAL : public nsISupports,
|
, public nsWrapperCache
|
||||||
public nsWrapperCache
|
|
||||||
{
|
{
|
||||||
typedef mozilla::dom::nsIContentParent nsIContentParent;
|
typedef mozilla::dom::StorageType StorageType;
|
||||||
typedef mozilla::dom::quota::PersistenceType PersistenceType;
|
typedef mozilla::ipc::PBackgroundChild PBackgroundChild;
|
||||||
typedef nsTArray<nsRefPtr<ObjectStoreInfo> > ObjectStoreInfoArray;
|
typedef mozilla::ipc::PrincipalInfo PrincipalInfo;
|
||||||
typedef mozilla::dom::quota::StoragePrivilege StoragePrivilege;
|
|
||||||
|
|
||||||
public:
|
class BackgroundCreateCallback;
|
||||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
struct PendingRequestInfo;
|
||||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBFactory)
|
|
||||||
|
|
||||||
// Called when using IndexedDB from a window in a different process.
|
nsAutoPtr<PrincipalInfo> mPrincipalInfo;
|
||||||
static nsresult Create(nsPIDOMWindow* aWindow,
|
|
||||||
const nsACString& aGroup,
|
|
||||||
const nsACString& aASCIIOrigin,
|
|
||||||
nsIContentParent* aContentParent,
|
|
||||||
IDBFactory** aFactory);
|
|
||||||
|
|
||||||
// Called when using IndexedDB from a window in the current process.
|
|
||||||
static nsresult Create(nsPIDOMWindow* aWindow,
|
|
||||||
nsIContentParent* aContentParent,
|
|
||||||
IDBFactory** aFactory)
|
|
||||||
{
|
|
||||||
return Create(aWindow, EmptyCString(), EmptyCString(), aContentParent,
|
|
||||||
aFactory);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called when using IndexedDB from a JS component or a JSM in the current
|
|
||||||
// process.
|
|
||||||
static nsresult Create(JSContext* aCx,
|
|
||||||
JS::Handle<JSObject*> aOwningObject,
|
|
||||||
nsIContentParent* aContentParent,
|
|
||||||
IDBFactory** aFactory);
|
|
||||||
|
|
||||||
// Called when using IndexedDB from a JS component or a JSM in a different
|
|
||||||
// process or from a C++ component.
|
|
||||||
static nsresult Create(nsIContentParent* aContentParent,
|
|
||||||
IDBFactory** aFactory);
|
|
||||||
|
|
||||||
static already_AddRefed<nsIFileURL>
|
|
||||||
GetDatabaseFileURL(nsIFile* aDatabaseFile,
|
|
||||||
PersistenceType aPersistenceType,
|
|
||||||
const nsACString& aGroup,
|
|
||||||
const nsACString& aOrigin);
|
|
||||||
|
|
||||||
static already_AddRefed<mozIStorageConnection>
|
|
||||||
GetConnection(const nsAString& aDatabaseFilePath,
|
|
||||||
PersistenceType aPersistenceType,
|
|
||||||
const nsACString& aGroup,
|
|
||||||
const nsACString& aOrigin);
|
|
||||||
|
|
||||||
static nsresult
|
|
||||||
SetDefaultPragmas(mozIStorageConnection* aConnection);
|
|
||||||
|
|
||||||
static nsresult
|
|
||||||
LoadDatabaseInformation(mozIStorageConnection* aConnection,
|
|
||||||
const nsACString& aDatabaseId,
|
|
||||||
uint64_t* aVersion,
|
|
||||||
ObjectStoreInfoArray& aObjectStores);
|
|
||||||
|
|
||||||
static nsresult
|
|
||||||
SetDatabaseMetadata(DatabaseInfo* aDatabaseInfo,
|
|
||||||
uint64_t aVersion,
|
|
||||||
ObjectStoreInfoArray& aObjectStores);
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
OpenInternal(const nsAString& aName,
|
|
||||||
int64_t aVersion,
|
|
||||||
PersistenceType aPersistenceType,
|
|
||||||
const nsACString& aGroup,
|
|
||||||
const nsACString& aASCIIOrigin,
|
|
||||||
StoragePrivilege aStoragePrivilege,
|
|
||||||
bool aDeleting,
|
|
||||||
IDBOpenDBRequest** _retval);
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
OpenInternal(const nsAString& aName,
|
|
||||||
int64_t aVersion,
|
|
||||||
PersistenceType aPersistenceType,
|
|
||||||
bool aDeleting,
|
|
||||||
IDBOpenDBRequest** _retval)
|
|
||||||
{
|
|
||||||
return OpenInternal(aName, aVersion, aPersistenceType, mGroup, mASCIIOrigin,
|
|
||||||
mPrivilege, aDeleting, _retval);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SetActor(IndexedDBChild* aActorChild)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(!aActorChild || !mActorChild, "Shouldn't have more than one!");
|
|
||||||
mActorChild = aActorChild;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SetActor(IndexedDBParent* aActorParent)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(!aActorParent || !mActorParent, "Shouldn't have more than one!");
|
|
||||||
mActorParent = aActorParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
const nsCString&
|
|
||||||
GetASCIIOrigin() const
|
|
||||||
{
|
|
||||||
return mASCIIOrigin;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
FromIPC()
|
|
||||||
{
|
|
||||||
return !!mContentParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// nsWrapperCache
|
|
||||||
virtual JSObject*
|
|
||||||
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
// WebIDL
|
|
||||||
nsPIDOMWindow*
|
|
||||||
GetParentObject() const
|
|
||||||
{
|
|
||||||
return mWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<IDBOpenDBRequest>
|
|
||||||
Open(const nsAString& aName, uint64_t aVersion, ErrorResult& aRv)
|
|
||||||
{
|
|
||||||
return Open(nullptr, aName, Optional<uint64_t>(aVersion),
|
|
||||||
Optional<mozilla::dom::StorageType>(), false, aRv);
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<IDBOpenDBRequest>
|
|
||||||
Open(const nsAString& aName, const IDBOpenDBOptions& aOptions,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
|
|
||||||
already_AddRefed<IDBOpenDBRequest>
|
|
||||||
DeleteDatabase(const nsAString& aName, const IDBOpenDBOptions& aOptions,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
|
|
||||||
int16_t
|
|
||||||
Cmp(JSContext* aCx, JS::Handle<JS::Value> aFirst,
|
|
||||||
JS::Handle<JS::Value> aSecond, ErrorResult& aRv);
|
|
||||||
|
|
||||||
already_AddRefed<IDBOpenDBRequest>
|
|
||||||
OpenForPrincipal(nsIPrincipal* aPrincipal, const nsAString& aName,
|
|
||||||
uint64_t aVersion, ErrorResult& aRv);
|
|
||||||
|
|
||||||
already_AddRefed<IDBOpenDBRequest>
|
|
||||||
OpenForPrincipal(nsIPrincipal* aPrincipal, const nsAString& aName,
|
|
||||||
const IDBOpenDBOptions& aOptions, ErrorResult& aRv);
|
|
||||||
|
|
||||||
already_AddRefed<IDBOpenDBRequest>
|
|
||||||
DeleteForPrincipal(nsIPrincipal* aPrincipal, const nsAString& aName,
|
|
||||||
const IDBOpenDBOptions& aOptions, ErrorResult& aRv);
|
|
||||||
|
|
||||||
private:
|
|
||||||
IDBFactory();
|
|
||||||
~IDBFactory();
|
|
||||||
|
|
||||||
already_AddRefed<IDBOpenDBRequest>
|
|
||||||
Open(nsIPrincipal* aPrincipal, const nsAString& aName,
|
|
||||||
const Optional<uint64_t>& aVersion,
|
|
||||||
const Optional<mozilla::dom::StorageType>& aStorageType, bool aDelete,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
|
|
||||||
nsCString mGroup;
|
|
||||||
nsCString mASCIIOrigin;
|
|
||||||
StoragePrivilege mPrivilege;
|
|
||||||
PersistenceType mDefaultPersistenceType;
|
|
||||||
|
|
||||||
// If this factory lives on a window then mWindow must be non-null. Otherwise
|
// If this factory lives on a window then mWindow must be non-null. Otherwise
|
||||||
// mOwningObject must be non-null.
|
// mOwningObject must be non-null.
|
||||||
nsCOMPtr<nsPIDOMWindow> mWindow;
|
nsCOMPtr<nsPIDOMWindow> mWindow;
|
||||||
JS::Heap<JSObject*> mOwningObject;
|
JS::Heap<JSObject*> mOwningObject;
|
||||||
|
|
||||||
IndexedDBChild* mActorChild;
|
// This will only be set if the factory belongs to a window in a child
|
||||||
IndexedDBParent* mActorParent;
|
// process.
|
||||||
|
nsRefPtr<TabChild> mTabChild;
|
||||||
|
|
||||||
mozilla::dom::nsIContentParent* mContentParent;
|
nsTArray<nsAutoPtr<PendingRequestInfo>> mPendingRequests;
|
||||||
|
|
||||||
|
BackgroundFactoryChild* mBackgroundActor;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
PRThread* mOwningThread;
|
||||||
|
#endif
|
||||||
|
|
||||||
bool mRootedOwningObject;
|
bool mRootedOwningObject;
|
||||||
|
bool mBackgroundActorFailed;
|
||||||
|
bool mPrivateBrowsingMode;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static nsresult
|
||||||
|
CreateForWindow(nsPIDOMWindow* aWindow,
|
||||||
|
IDBFactory** aFactory);
|
||||||
|
|
||||||
|
static nsresult
|
||||||
|
CreateForChromeJS(JSContext* aCx,
|
||||||
|
JS::Handle<JSObject*> aOwningObject,
|
||||||
|
IDBFactory** aFactory);
|
||||||
|
|
||||||
|
static nsresult
|
||||||
|
CreateForDatastore(JSContext* aCx,
|
||||||
|
JS::Handle<JSObject*> aOwningObject,
|
||||||
|
IDBFactory** aFactory);
|
||||||
|
|
||||||
|
void
|
||||||
|
AssertIsOnOwningThread() const
|
||||||
|
#ifdef DEBUG
|
||||||
|
;
|
||||||
|
#else
|
||||||
|
{ }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
SetBackgroundActor(BackgroundFactoryChild* aBackgroundActor);
|
||||||
|
|
||||||
|
void
|
||||||
|
ClearBackgroundActor()
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
mBackgroundActor = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsPIDOMWindow*
|
||||||
|
GetParentObject() const
|
||||||
|
{
|
||||||
|
return mWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
TabChild*
|
||||||
|
GetTabChild() const
|
||||||
|
{
|
||||||
|
return mTabChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrincipalInfo*
|
||||||
|
GetPrincipalInfo() const
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
return mPrincipalInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<IDBOpenDBRequest>
|
||||||
|
Open(const nsAString& aName,
|
||||||
|
uint64_t aVersion,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
already_AddRefed<IDBOpenDBRequest>
|
||||||
|
Open(const nsAString& aName,
|
||||||
|
const IDBOpenDBOptions& aOptions,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
already_AddRefed<IDBOpenDBRequest>
|
||||||
|
DeleteDatabase(const nsAString& aName,
|
||||||
|
const IDBOpenDBOptions& aOptions,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
int16_t
|
||||||
|
Cmp(JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aFirst,
|
||||||
|
JS::Handle<JS::Value> aSecond,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
already_AddRefed<IDBOpenDBRequest>
|
||||||
|
OpenForPrincipal(nsIPrincipal* aPrincipal,
|
||||||
|
const nsAString& aName,
|
||||||
|
uint64_t aVersion,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
already_AddRefed<IDBOpenDBRequest>
|
||||||
|
OpenForPrincipal(nsIPrincipal* aPrincipal,
|
||||||
|
const nsAString& aName,
|
||||||
|
const IDBOpenDBOptions& aOptions,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
already_AddRefed<IDBOpenDBRequest>
|
||||||
|
DeleteForPrincipal(nsIPrincipal* aPrincipal,
|
||||||
|
const nsAString& aName,
|
||||||
|
const IDBOpenDBOptions& aOptions,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||||
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBFactory)
|
||||||
|
|
||||||
|
// nsWrapperCache
|
||||||
|
virtual JSObject*
|
||||||
|
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
IDBFactory();
|
||||||
|
~IDBFactory();
|
||||||
|
|
||||||
|
static nsresult
|
||||||
|
CreateForJSInternal(JSContext* aCx,
|
||||||
|
JS::Handle<JSObject*> aOwningObject,
|
||||||
|
nsAutoPtr<PrincipalInfo>& aPrincipalInfo,
|
||||||
|
IDBFactory** aFactory);
|
||||||
|
|
||||||
|
already_AddRefed<IDBOpenDBRequest>
|
||||||
|
OpenInternal(nsIPrincipal* aPrincipal,
|
||||||
|
const nsAString& aName,
|
||||||
|
const Optional<uint64_t>& aVersion,
|
||||||
|
const Optional<StorageType>& aStorageType,
|
||||||
|
bool aDeleting,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
BackgroundActorCreated(PBackgroundChild* aBackgroundActor);
|
||||||
|
|
||||||
|
void
|
||||||
|
BackgroundActorFailed();
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
InitiateRequest(IDBOpenDBRequest* aRequest,
|
||||||
|
const FactoryRequestParams& aParams);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace indexedDB
|
} // namespace indexedDB
|
||||||
|
|
|
@ -16,16 +16,16 @@
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
#include "nsWidgetsCID.h"
|
#include "nsWidgetsCID.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
namespace indexedDB {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
NS_DEFINE_CID(kAppShellCID2, NS_APPSHELL_CID);
|
NS_DEFINE_CID(kAppShellCID2, NS_APPSHELL_CID);
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace dom {
|
|
||||||
namespace indexedDB {
|
|
||||||
|
|
||||||
IDBFileHandle::IDBFileHandle(FileMode aMode,
|
IDBFileHandle::IDBFileHandle(FileMode aMode,
|
||||||
RequestMode aRequestMode,
|
RequestMode aRequestMode,
|
||||||
IDBMutableFile* aMutableFile)
|
IDBMutableFile* aMutableFile)
|
||||||
|
@ -158,10 +158,10 @@ IDBFileHandle::OnCompleteOrAbort(bool aAborted)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIDOMEvent> event;
|
nsCOMPtr<nsIDOMEvent> event;
|
||||||
if (aAborted) {
|
if (aAborted) {
|
||||||
event = CreateGenericEvent(this, NS_LITERAL_STRING(ABORT_EVT_STR),
|
event = CreateGenericEvent(this, nsDependentString(kAbortEventType),
|
||||||
eDoesBubble, eNotCancelable);
|
eDoesBubble, eNotCancelable);
|
||||||
} else {
|
} else {
|
||||||
event = CreateGenericEvent(this, NS_LITERAL_STRING(COMPLETE_EVT_STR),
|
event = CreateGenericEvent(this, nsDependentString(kCompleteEventType),
|
||||||
eDoesNotBubble, eNotCancelable);
|
eDoesNotBubble, eNotCancelable);
|
||||||
}
|
}
|
||||||
if (NS_WARN_IF(!event)) {
|
if (NS_WARN_IF(!event)) {
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -7,245 +7,207 @@
|
||||||
#ifndef mozilla_dom_indexeddb_idbindex_h__
|
#ifndef mozilla_dom_indexeddb_idbindex_h__
|
||||||
#define mozilla_dom_indexeddb_idbindex_h__
|
#define mozilla_dom_indexeddb_idbindex_h__
|
||||||
|
|
||||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
#include "js/RootingAPI.h"
|
||||||
|
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/dom/IDBCursorBinding.h"
|
#include "mozilla/dom/IDBCursorBinding.h"
|
||||||
#include "mozilla/ErrorResult.h"
|
#include "nsAutoPtr.h"
|
||||||
#include "nsCycleCollectionParticipant.h"
|
#include "nsCycleCollectionParticipant.h"
|
||||||
|
#include "nsISupports.h"
|
||||||
|
#include "nsTArrayForwardDeclare.h"
|
||||||
#include "nsWrapperCache.h"
|
#include "nsWrapperCache.h"
|
||||||
|
|
||||||
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
|
|
||||||
#include "mozilla/dom/indexedDB/IDBRequest.h"
|
|
||||||
#include "mozilla/dom/indexedDB/KeyPath.h"
|
|
||||||
|
|
||||||
class nsIScriptContext;
|
|
||||||
class nsPIDOMWindow;
|
class nsPIDOMWindow;
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
namespace mozilla {
|
||||||
|
|
||||||
|
class ErrorResult;
|
||||||
|
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
template <typename> class Sequence;
|
||||||
|
|
||||||
|
namespace indexedDB {
|
||||||
|
|
||||||
class AsyncConnectionHelper;
|
|
||||||
class IDBCursor;
|
|
||||||
class IDBKeyRange;
|
|
||||||
class IDBObjectStore;
|
class IDBObjectStore;
|
||||||
class IDBRequest;
|
class IDBRequest;
|
||||||
class IndexedDBIndexChild;
|
class IndexMetadata;
|
||||||
class IndexedDBIndexParent;
|
|
||||||
class Key;
|
class Key;
|
||||||
|
class KeyPath;
|
||||||
|
|
||||||
struct IndexInfo;
|
class IDBIndex MOZ_FINAL
|
||||||
|
: public nsISupports
|
||||||
class IDBIndex MOZ_FINAL : public nsISupports,
|
, public nsWrapperCache
|
||||||
public nsWrapperCache
|
|
||||||
{
|
{
|
||||||
|
nsRefPtr<IDBObjectStore> mObjectStore;
|
||||||
|
|
||||||
|
JS::Heap<JS::Value> mCachedKeyPath;
|
||||||
|
|
||||||
|
// This normally points to the IndexMetadata owned by the parent IDBDatabase
|
||||||
|
// object. However, if this index is part of a versionchange transaction and
|
||||||
|
// it gets deleted then the metadata is copied into mDeletedMetadata and
|
||||||
|
// mMetadata is set to point at mDeletedMetadata.
|
||||||
|
const IndexMetadata* mMetadata;
|
||||||
|
nsAutoPtr<IndexMetadata> mDeletedMetadata;
|
||||||
|
|
||||||
|
const int64_t mId;
|
||||||
|
bool mRooted;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBIndex)
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBIndex)
|
||||||
|
|
||||||
static already_AddRefed<IDBIndex>
|
static already_AddRefed<IDBIndex>
|
||||||
Create(IDBObjectStore* aObjectStore,
|
Create(IDBObjectStore* aObjectStore, const IndexMetadata& aMetadata);
|
||||||
const IndexInfo* aIndexInfo,
|
|
||||||
bool aCreating);
|
|
||||||
|
|
||||||
IDBObjectStore* ObjectStore()
|
int64_t
|
||||||
|
Id() const
|
||||||
{
|
{
|
||||||
return mObjectStore;
|
AssertIsOnOwningThread();
|
||||||
}
|
|
||||||
|
|
||||||
const int64_t Id() const
|
|
||||||
{
|
|
||||||
return mId;
|
return mId;
|
||||||
}
|
}
|
||||||
|
|
||||||
const nsString& Name() const
|
const nsString&
|
||||||
{
|
Name() const;
|
||||||
return mName;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsUnique() const
|
bool
|
||||||
{
|
Unique() const;
|
||||||
return mUnique;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsMultiEntry() const
|
bool
|
||||||
{
|
MultiEntry() const;
|
||||||
return mMultiEntry;
|
|
||||||
}
|
|
||||||
|
|
||||||
const KeyPath& GetKeyPath() const
|
const KeyPath&
|
||||||
{
|
GetKeyPath() const;
|
||||||
return mKeyPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SetActor(IndexedDBIndexChild* aActorChild)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(!aActorChild || !mActorChild, "Shouldn't have more than one!");
|
|
||||||
mActorChild = aActorChild;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SetActor(IndexedDBIndexParent* aActorParent)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(!aActorParent || !mActorParent,
|
|
||||||
"Shouldn't have more than one!");
|
|
||||||
mActorParent = aActorParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexedDBIndexChild*
|
|
||||||
GetActorChild() const
|
|
||||||
{
|
|
||||||
return mActorChild;
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexedDBIndexParent*
|
|
||||||
GetActorParent() const
|
|
||||||
{
|
|
||||||
return mActorParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
|
||||||
GetInternal(IDBKeyRange* aKeyRange,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
|
||||||
GetKeyInternal(IDBKeyRange* aKeyRange,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
|
||||||
GetAllInternal(IDBKeyRange* aKeyRange,
|
|
||||||
uint32_t aLimit,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
|
||||||
GetAllKeysInternal(IDBKeyRange* aKeyRange,
|
|
||||||
uint32_t aLimit,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
|
||||||
CountInternal(IDBKeyRange* aKeyRange,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
|
|
||||||
nsresult OpenCursorFromChildProcess(
|
|
||||||
IDBRequest* aRequest,
|
|
||||||
size_t aDirection,
|
|
||||||
const Key& aKey,
|
|
||||||
const Key& aObjectKey,
|
|
||||||
IDBCursor** _retval);
|
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
|
||||||
OpenKeyCursorInternal(IDBKeyRange* aKeyRange,
|
|
||||||
size_t aDirection,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
|
|
||||||
nsresult OpenCursorInternal(IDBKeyRange* aKeyRange,
|
|
||||||
size_t aDirection,
|
|
||||||
IDBRequest** _retval);
|
|
||||||
|
|
||||||
nsresult OpenCursorFromChildProcess(
|
|
||||||
IDBRequest* aRequest,
|
|
||||||
size_t aDirection,
|
|
||||||
const Key& aKey,
|
|
||||||
const Key& aObjectKey,
|
|
||||||
const SerializedStructuredCloneReadInfo& aCloneInfo,
|
|
||||||
nsTArray<StructuredCloneFile>& aBlobs,
|
|
||||||
IDBCursor** _retval);
|
|
||||||
|
|
||||||
// nsWrapperCache
|
|
||||||
virtual JSObject*
|
|
||||||
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
// WebIDL
|
|
||||||
IDBObjectStore*
|
|
||||||
GetParentObject() const
|
|
||||||
{
|
|
||||||
return mObjectStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
GetName(nsString& aName) const
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
aName.Assign(mName);
|
|
||||||
}
|
|
||||||
|
|
||||||
IDBObjectStore*
|
IDBObjectStore*
|
||||||
ObjectStore() const
|
ObjectStore() const
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
AssertIsOnOwningThread();
|
||||||
return mObjectStore;
|
return mObjectStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsPIDOMWindow*
|
||||||
|
GetParentObject() const;
|
||||||
|
|
||||||
void
|
void
|
||||||
GetKeyPath(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
|
GetName(nsString& aName) const
|
||||||
|
{
|
||||||
|
aName = Name();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GetKeyPath(JSContext* aCx,
|
||||||
|
JS::MutableHandle<JS::Value> aResult,
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
||||||
bool
|
already_AddRefed<IDBRequest>
|
||||||
MultiEntry() const
|
OpenCursor(JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aRange,
|
||||||
|
IDBCursorDirection aDirection,
|
||||||
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
AssertIsOnOwningThread();
|
||||||
return mMultiEntry;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
return OpenCursorInternal(/* aKeysOnly */ false, aCx, aRange, aDirection,
|
||||||
Unique() const
|
aRv);
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
return mUnique;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
already_AddRefed<IDBRequest>
|
||||||
OpenCursor(JSContext* aCx, JS::Handle<JS::Value> aRange,
|
OpenKeyCursor(JSContext* aCx,
|
||||||
IDBCursorDirection aDirection, ErrorResult& aRv);
|
JS::Handle<JS::Value> aRange,
|
||||||
|
IDBCursorDirection aDirection,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
return OpenCursorInternal(/* aKeysOnly */ true, aCx, aRange, aDirection,
|
||||||
|
aRv);
|
||||||
|
}
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
already_AddRefed<IDBRequest>
|
||||||
OpenKeyCursor(JSContext* aCx, JS::Handle<JS::Value> aRange,
|
Get(JSContext* aCx, JS::Handle<JS::Value> aKey, ErrorResult& aRv)
|
||||||
IDBCursorDirection aDirection, ErrorResult& aRv);
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
return GetInternal(/* aKeyOnly */ false, aCx, aKey, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
already_AddRefed<IDBRequest>
|
||||||
Get(JSContext* aCx, JS::Handle<JS::Value> aKey, ErrorResult& aRv);
|
GetKey(JSContext* aCx, JS::Handle<JS::Value> aKey, ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
return GetInternal(/* aKeyOnly */ true, aCx, aKey, aRv);
|
||||||
GetKey(JSContext* aCx, JS::Handle<JS::Value> aKey, ErrorResult& aRv);
|
}
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
already_AddRefed<IDBRequest>
|
||||||
Count(JSContext* aCx, JS::Handle<JS::Value> aKey,
|
Count(JSContext* aCx, JS::Handle<JS::Value> aKey,
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
||||||
void
|
already_AddRefed<IDBRequest>
|
||||||
GetStoreName(nsString& aStoreName) const
|
GetAll(JSContext* aCx, JS::Handle<JS::Value> aKey,
|
||||||
|
const Optional<uint32_t>& aLimit, ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
AssertIsOnOwningThread();
|
||||||
mObjectStore->GetName(aStoreName);
|
|
||||||
|
return GetAllInternal(/* aKeysOnly */ false, aCx, aKey, aLimit, aRv);
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
|
||||||
GetAll(JSContext* aCx, JS::Handle<JS::Value> aKey,
|
|
||||||
const Optional<uint32_t>& aLimit, ErrorResult& aRv);
|
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
already_AddRefed<IDBRequest>
|
||||||
GetAllKeys(JSContext* aCx, JS::Handle<JS::Value> aKey,
|
GetAllKeys(JSContext* aCx, JS::Handle<JS::Value> aKey,
|
||||||
const Optional<uint32_t>& aLimit, ErrorResult& aRv);
|
const Optional<uint32_t>& aLimit, ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
return GetAllInternal(/* aKeysOnly */ true, aCx, aKey, aLimit, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RefreshMetadata(bool aMayDelete);
|
||||||
|
|
||||||
|
void
|
||||||
|
NoteDeletion();
|
||||||
|
|
||||||
|
void
|
||||||
|
AssertIsOnOwningThread() const
|
||||||
|
#ifdef DEBUG
|
||||||
|
;
|
||||||
|
#else
|
||||||
|
{ }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// nsWrapperCache
|
||||||
|
virtual JSObject*
|
||||||
|
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IDBIndex();
|
IDBIndex(IDBObjectStore* aObjectStore, const IndexMetadata* aMetadata);
|
||||||
|
|
||||||
~IDBIndex();
|
~IDBIndex();
|
||||||
|
|
||||||
nsRefPtr<IDBObjectStore> mObjectStore;
|
already_AddRefed<IDBRequest>
|
||||||
|
GetInternal(bool aKeyOnly,
|
||||||
|
JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aKey,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
int64_t mId;
|
already_AddRefed<IDBRequest>
|
||||||
nsString mName;
|
GetAllInternal(bool aKeysOnly,
|
||||||
KeyPath mKeyPath;
|
JSContext* aCx,
|
||||||
JS::Heap<JS::Value> mCachedKeyPath;
|
JS::Handle<JS::Value> aKey,
|
||||||
|
const Optional<uint32_t>& aLimit,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
IndexedDBIndexChild* mActorChild;
|
already_AddRefed<IDBRequest>
|
||||||
IndexedDBIndexParent* mActorParent;
|
OpenCursorInternal(bool aKeysOnly,
|
||||||
|
JSContext* aCx,
|
||||||
bool mUnique;
|
JS::Handle<JS::Value> aRange,
|
||||||
bool mMultiEntry;
|
IDBCursorDirection aDirection,
|
||||||
bool mRooted;
|
ErrorResult& aRv);
|
||||||
};
|
};
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
} // namespace indexedDB
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif // mozilla_dom_indexeddb_idbindex_h__
|
#endif // mozilla_dom_indexeddb_idbindex_h__
|
||||||
|
|
|
@ -4,30 +4,21 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "base/basictypes.h"
|
|
||||||
|
|
||||||
#include "IDBKeyRange.h"
|
#include "IDBKeyRange.h"
|
||||||
|
|
||||||
#include "nsIXPConnect.h"
|
|
||||||
|
|
||||||
#include "nsJSUtils.h"
|
|
||||||
#include "nsThreadUtils.h"
|
|
||||||
#include "nsContentUtils.h"
|
|
||||||
#include "nsDOMClassInfoID.h"
|
|
||||||
#include "Key.h"
|
#include "Key.h"
|
||||||
|
#include "mozilla/ErrorResult.h"
|
||||||
|
#include "mozilla/dom/BindingUtils.h"
|
||||||
#include "mozilla/dom/IDBKeyRangeBinding.h"
|
#include "mozilla/dom/IDBKeyRangeBinding.h"
|
||||||
#include "mozilla/dom/indexedDB/PIndexedDBIndex.h"
|
#include "mozilla/dom/indexedDB/PBackgroundIDBSharedTypes.h"
|
||||||
#include "mozilla/dom/indexedDB/PIndexedDBObjectStore.h"
|
|
||||||
|
|
||||||
using namespace mozilla;
|
namespace mozilla {
|
||||||
using namespace mozilla::dom;
|
namespace dom {
|
||||||
USING_INDEXEDDB_NAMESPACE
|
namespace indexedDB {
|
||||||
using namespace mozilla::dom::indexedDB::ipc;
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
inline nsresult
|
nsresult
|
||||||
GetKeyFromJSVal(JSContext* aCx,
|
GetKeyFromJSVal(JSContext* aCx,
|
||||||
JS::Handle<JS::Value> aVal,
|
JS::Handle<JS::Value> aVal,
|
||||||
Key& aKey,
|
Key& aKey,
|
||||||
|
@ -35,8 +26,7 @@ GetKeyFromJSVal(JSContext* aCx,
|
||||||
{
|
{
|
||||||
nsresult rv = aKey.SetFromJSVal(aCx, aVal);
|
nsresult rv = aKey.SetFromJSVal(aCx, aVal);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
NS_ASSERTION(NS_ERROR_GET_MODULE(rv) == NS_ERROR_MODULE_DOM_INDEXEDDB,
|
MOZ_ASSERT(NS_ERROR_GET_MODULE(rv) == NS_ERROR_MODULE_DOM_INDEXEDDB);
|
||||||
"Bad error code!");
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +39,42 @@ GetKeyFromJSVal(JSContext* aCx,
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
|
IDBKeyRange::IDBKeyRange(nsISupports* aGlobal,
|
||||||
|
bool aLowerOpen,
|
||||||
|
bool aUpperOpen,
|
||||||
|
bool aIsOnly)
|
||||||
|
: mGlobal(aGlobal)
|
||||||
|
, mCachedLowerVal(JSVAL_VOID)
|
||||||
|
, mCachedUpperVal(JSVAL_VOID)
|
||||||
|
, mLowerOpen(aLowerOpen)
|
||||||
|
, mUpperOpen(aUpperOpen)
|
||||||
|
, mIsOnly(aIsOnly)
|
||||||
|
, mHaveCachedLowerVal(false)
|
||||||
|
, mHaveCachedUpperVal(false)
|
||||||
|
, mRooted(false)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
mOwningThread = PR_GetCurrentThread();
|
||||||
|
#endif
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
IDBKeyRange::~IDBKeyRange()
|
||||||
|
{
|
||||||
|
DropJSObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
|
||||||
|
void
|
||||||
|
IDBKeyRange::AssertIsOnOwningThread() const
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mOwningThread);
|
||||||
|
MOZ_ASSERT(PR_GetCurrentThread() == mOwningThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // DEBUG
|
||||||
|
|
||||||
// static
|
// static
|
||||||
nsresult
|
nsresult
|
||||||
IDBKeyRange::FromJSVal(JSContext* aCx,
|
IDBKeyRange::FromJSVal(JSContext* aCx,
|
||||||
|
@ -87,9 +113,8 @@ IDBKeyRange::FromJSVal(JSContext* aCx,
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
template <class T>
|
|
||||||
already_AddRefed<IDBKeyRange>
|
already_AddRefed<IDBKeyRange>
|
||||||
IDBKeyRange::FromSerializedKeyRange(const T& aKeyRange)
|
IDBKeyRange::FromSerialized(const SerializedKeyRange& aKeyRange)
|
||||||
{
|
{
|
||||||
nsRefPtr<IDBKeyRange> keyRange =
|
nsRefPtr<IDBKeyRange> keyRange =
|
||||||
new IDBKeyRange(nullptr, aKeyRange.lowerOpen(), aKeyRange.upperOpen(),
|
new IDBKeyRange(nullptr, aKeyRange.lowerOpen(), aKeyRange.upperOpen(),
|
||||||
|
@ -101,12 +126,11 @@ IDBKeyRange::FromSerializedKeyRange(const T& aKeyRange)
|
||||||
return keyRange.forget();
|
return keyRange.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void
|
void
|
||||||
IDBKeyRange::ToSerializedKeyRange(T& aKeyRange)
|
IDBKeyRange::ToSerialized(SerializedKeyRange& aKeyRange) const
|
||||||
{
|
{
|
||||||
aKeyRange.lowerOpen() = IsLowerOpen();
|
aKeyRange.lowerOpen() = LowerOpen();
|
||||||
aKeyRange.upperOpen() = IsUpperOpen();
|
aKeyRange.upperOpen() = UpperOpen();
|
||||||
aKeyRange.isOnly() = IsOnly();
|
aKeyRange.isOnly() = IsOnly();
|
||||||
|
|
||||||
aKeyRange.lower() = Lower();
|
aKeyRange.lower() = Lower();
|
||||||
|
@ -115,6 +139,76 @@ IDBKeyRange::ToSerializedKeyRange(T& aKeyRange)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IDBKeyRange::GetBindingClause(const nsACString& aKeyColumnName,
|
||||||
|
nsACString& _retval) const
|
||||||
|
{
|
||||||
|
NS_NAMED_LITERAL_CSTRING(andStr, " AND ");
|
||||||
|
NS_NAMED_LITERAL_CSTRING(spacecolon, " :");
|
||||||
|
NS_NAMED_LITERAL_CSTRING(lowerKey, "lower_key");
|
||||||
|
|
||||||
|
if (IsOnly()) {
|
||||||
|
// Both keys are set and they're equal.
|
||||||
|
_retval = andStr + aKeyColumnName + NS_LITERAL_CSTRING(" =") +
|
||||||
|
spacecolon + lowerKey;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAutoCString clause;
|
||||||
|
|
||||||
|
if (!Lower().IsUnset()) {
|
||||||
|
// Lower key is set.
|
||||||
|
clause.Append(andStr + aKeyColumnName);
|
||||||
|
clause.AppendLiteral(" >");
|
||||||
|
if (!LowerOpen()) {
|
||||||
|
clause.Append('=');
|
||||||
|
}
|
||||||
|
clause.Append(spacecolon + lowerKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Upper().IsUnset()) {
|
||||||
|
// Upper key is set.
|
||||||
|
clause.Append(andStr + aKeyColumnName);
|
||||||
|
clause.AppendLiteral(" <");
|
||||||
|
if (!UpperOpen()) {
|
||||||
|
clause.Append('=');
|
||||||
|
}
|
||||||
|
clause.Append(spacecolon + NS_LITERAL_CSTRING("upper_key"));
|
||||||
|
}
|
||||||
|
|
||||||
|
_retval = clause;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
IDBKeyRange::BindToStatement(mozIStorageStatement* aStatement) const
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aStatement);
|
||||||
|
|
||||||
|
NS_NAMED_LITERAL_CSTRING(lowerKey, "lower_key");
|
||||||
|
|
||||||
|
if (IsOnly()) {
|
||||||
|
return Lower().BindToStatement(aStatement, lowerKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
if (!Lower().IsUnset()) {
|
||||||
|
rv = Lower().BindToStatement(aStatement, lowerKey);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Upper().IsUnset()) {
|
||||||
|
rv = Upper().BindToStatement(aStatement, NS_LITERAL_CSTRING("upper_key"));
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBKeyRange)
|
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBKeyRange)
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBKeyRange)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBKeyRange)
|
||||||
|
@ -145,19 +239,14 @@ IDBKeyRange::DropJSObjects()
|
||||||
if (!mRooted) {
|
if (!mRooted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mCachedLowerVal = JS::UndefinedValue();
|
mCachedLowerVal.setUndefined();
|
||||||
mCachedUpperVal = JS::UndefinedValue();
|
mCachedUpperVal.setUndefined();
|
||||||
mHaveCachedLowerVal = false;
|
mHaveCachedLowerVal = false;
|
||||||
mHaveCachedUpperVal = false;
|
mHaveCachedUpperVal = false;
|
||||||
mRooted = false;
|
mRooted = false;
|
||||||
mozilla::DropJSObjects(this);
|
mozilla::DropJSObjects(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
IDBKeyRange::~IDBKeyRange()
|
|
||||||
{
|
|
||||||
DropJSObjects();
|
|
||||||
}
|
|
||||||
|
|
||||||
JSObject*
|
JSObject*
|
||||||
IDBKeyRange::WrapObject(JSContext* aCx)
|
IDBKeyRange::WrapObject(JSContext* aCx)
|
||||||
{
|
{
|
||||||
|
@ -168,7 +257,7 @@ void
|
||||||
IDBKeyRange::GetLower(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
|
IDBKeyRange::GetLower(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
|
||||||
ErrorResult& aRv)
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
if (!mHaveCachedLowerVal) {
|
if (!mHaveCachedLowerVal) {
|
||||||
if (!mRooted) {
|
if (!mRooted) {
|
||||||
|
@ -192,7 +281,7 @@ void
|
||||||
IDBKeyRange::GetUpper(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
|
IDBKeyRange::GetUpper(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
|
||||||
ErrorResult& aRv)
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
if (!mHaveCachedUpperVal) {
|
if (!mHaveCachedUpperVal) {
|
||||||
if (!mRooted) {
|
if (!mRooted) {
|
||||||
|
@ -215,10 +304,9 @@ IDBKeyRange::GetUpper(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
|
||||||
// static
|
// static
|
||||||
already_AddRefed<IDBKeyRange>
|
already_AddRefed<IDBKeyRange>
|
||||||
IDBKeyRange::Only(const GlobalObject& aGlobal,
|
IDBKeyRange::Only(const GlobalObject& aGlobal,
|
||||||
JS::Handle<JS::Value> aValue, ErrorResult& aRv)
|
JS::Handle<JS::Value> aValue,
|
||||||
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
|
|
||||||
nsRefPtr<IDBKeyRange> keyRange =
|
nsRefPtr<IDBKeyRange> keyRange =
|
||||||
new IDBKeyRange(aGlobal.GetAsSupports(), false, false, true);
|
new IDBKeyRange(aGlobal.GetAsSupports(), false, false, true);
|
||||||
|
|
||||||
|
@ -233,11 +321,10 @@ IDBKeyRange::Only(const GlobalObject& aGlobal,
|
||||||
// static
|
// static
|
||||||
already_AddRefed<IDBKeyRange>
|
already_AddRefed<IDBKeyRange>
|
||||||
IDBKeyRange::LowerBound(const GlobalObject& aGlobal,
|
IDBKeyRange::LowerBound(const GlobalObject& aGlobal,
|
||||||
JS::Handle<JS::Value> aValue, bool aOpen,
|
JS::Handle<JS::Value> aValue,
|
||||||
|
bool aOpen,
|
||||||
ErrorResult& aRv)
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
|
|
||||||
nsRefPtr<IDBKeyRange> keyRange =
|
nsRefPtr<IDBKeyRange> keyRange =
|
||||||
new IDBKeyRange(aGlobal.GetAsSupports(), aOpen, true, false);
|
new IDBKeyRange(aGlobal.GetAsSupports(), aOpen, true, false);
|
||||||
|
|
||||||
|
@ -252,11 +339,10 @@ IDBKeyRange::LowerBound(const GlobalObject& aGlobal,
|
||||||
// static
|
// static
|
||||||
already_AddRefed<IDBKeyRange>
|
already_AddRefed<IDBKeyRange>
|
||||||
IDBKeyRange::UpperBound(const GlobalObject& aGlobal,
|
IDBKeyRange::UpperBound(const GlobalObject& aGlobal,
|
||||||
JS::Handle<JS::Value> aValue, bool aOpen,
|
JS::Handle<JS::Value> aValue,
|
||||||
|
bool aOpen,
|
||||||
ErrorResult& aRv)
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
|
|
||||||
nsRefPtr<IDBKeyRange> keyRange =
|
nsRefPtr<IDBKeyRange> keyRange =
|
||||||
new IDBKeyRange(aGlobal.GetAsSupports(), true, aOpen, false);
|
new IDBKeyRange(aGlobal.GetAsSupports(), true, aOpen, false);
|
||||||
|
|
||||||
|
@ -271,11 +357,12 @@ IDBKeyRange::UpperBound(const GlobalObject& aGlobal,
|
||||||
// static
|
// static
|
||||||
already_AddRefed<IDBKeyRange>
|
already_AddRefed<IDBKeyRange>
|
||||||
IDBKeyRange::Bound(const GlobalObject& aGlobal,
|
IDBKeyRange::Bound(const GlobalObject& aGlobal,
|
||||||
JS::Handle<JS::Value> aLower, JS::Handle<JS::Value> aUpper,
|
JS::Handle<JS::Value> aLower,
|
||||||
bool aLowerOpen, bool aUpperOpen, ErrorResult& aRv)
|
JS::Handle<JS::Value> aUpper,
|
||||||
|
bool aLowerOpen,
|
||||||
|
bool aUpperOpen,
|
||||||
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
|
|
||||||
nsRefPtr<IDBKeyRange> keyRange =
|
nsRefPtr<IDBKeyRange> keyRange =
|
||||||
new IDBKeyRange(aGlobal.GetAsSupports(), aLowerOpen, aUpperOpen, false);
|
new IDBKeyRange(aGlobal.GetAsSupports(), aLowerOpen, aUpperOpen, false);
|
||||||
|
|
||||||
|
@ -298,9 +385,6 @@ IDBKeyRange::Bound(const GlobalObject& aGlobal,
|
||||||
return keyRange.forget();
|
return keyRange.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Explicitly instantiate for all our key range types... Grumble.
|
} // namespace indexedDB
|
||||||
template already_AddRefed<IDBKeyRange>
|
} // namespace dom
|
||||||
IDBKeyRange::FromSerializedKeyRange<KeyRange> (const KeyRange& aKeyRange);
|
} // namespace mozilla
|
||||||
|
|
||||||
template void
|
|
||||||
IDBKeyRange::ToSerializedKeyRange<KeyRange> (KeyRange& aKeyRange);
|
|
||||||
|
|
|
@ -7,144 +7,137 @@
|
||||||
#ifndef mozilla_dom_indexeddb_idbkeyrange_h__
|
#ifndef mozilla_dom_indexeddb_idbkeyrange_h__
|
||||||
#define mozilla_dom_indexeddb_idbkeyrange_h__
|
#define mozilla_dom_indexeddb_idbkeyrange_h__
|
||||||
|
|
||||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
#include "js/RootingAPI.h"
|
||||||
|
#include "js/Value.h"
|
||||||
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/dom/indexedDB/Key.h"
|
#include "mozilla/dom/indexedDB/Key.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
#include "nsISupports.h"
|
|
||||||
|
|
||||||
#include "mozilla/ErrorResult.h"
|
|
||||||
#include "nsCycleCollectionParticipant.h"
|
#include "nsCycleCollectionParticipant.h"
|
||||||
|
#include "nsISupports.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
|
||||||
class mozIStorageStatement;
|
class mozIStorageStatement;
|
||||||
|
struct PRThread;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
class ErrorResult;
|
||||||
|
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
class GlobalObject;
|
class GlobalObject;
|
||||||
} // namespace dom
|
|
||||||
} // namespace mozilla
|
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
namespace indexedDB {
|
||||||
|
|
||||||
namespace ipc {
|
class SerializedKeyRange;
|
||||||
class KeyRange;
|
|
||||||
} // namespace ipc
|
|
||||||
|
|
||||||
class IDBKeyRange MOZ_FINAL : public nsISupports
|
class IDBKeyRange MOZ_FINAL
|
||||||
|
: public nsISupports
|
||||||
{
|
{
|
||||||
|
nsCOMPtr<nsISupports> mGlobal;
|
||||||
|
Key mLower;
|
||||||
|
Key mUpper;
|
||||||
|
JS::Heap<JS::Value> mCachedLowerVal;
|
||||||
|
JS::Heap<JS::Value> mCachedUpperVal;
|
||||||
|
|
||||||
|
const bool mLowerOpen : 1;
|
||||||
|
const bool mUpperOpen : 1;
|
||||||
|
const bool mIsOnly : 1;
|
||||||
|
bool mHaveCachedLowerVal : 1;
|
||||||
|
bool mHaveCachedUpperVal : 1;
|
||||||
|
bool mRooted : 1;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
PRThread* mOwningThread;
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBKeyRange)
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBKeyRange)
|
||||||
|
|
||||||
static nsresult FromJSVal(JSContext* aCx,
|
static nsresult
|
||||||
JS::Handle<JS::Value> aVal,
|
FromJSVal(JSContext* aCx,
|
||||||
IDBKeyRange** aKeyRange);
|
JS::Handle<JS::Value> aVal,
|
||||||
|
IDBKeyRange** aKeyRange);
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static already_AddRefed<IDBKeyRange>
|
static already_AddRefed<IDBKeyRange>
|
||||||
FromSerializedKeyRange(const T& aKeyRange);
|
FromSerialized(const SerializedKeyRange& aKeyRange);
|
||||||
|
|
||||||
const Key& Lower() const
|
static already_AddRefed<IDBKeyRange>
|
||||||
|
Only(const GlobalObject& aGlobal,
|
||||||
|
JS::Handle<JS::Value> aValue,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
static already_AddRefed<IDBKeyRange>
|
||||||
|
LowerBound(const GlobalObject& aGlobal,
|
||||||
|
JS::Handle<JS::Value> aValue,
|
||||||
|
bool aOpen,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
static already_AddRefed<IDBKeyRange>
|
||||||
|
UpperBound(const GlobalObject& aGlobal,
|
||||||
|
JS::Handle<JS::Value> aValue,
|
||||||
|
bool aOpen,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
static already_AddRefed<IDBKeyRange>
|
||||||
|
Bound(const GlobalObject& aGlobal,
|
||||||
|
JS::Handle<JS::Value> aLower,
|
||||||
|
JS::Handle<JS::Value> aUpper,
|
||||||
|
bool aLowerOpen,
|
||||||
|
bool aUpperOpen,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
void
|
||||||
|
AssertIsOnOwningThread() const
|
||||||
|
#ifdef DEBUG
|
||||||
|
;
|
||||||
|
#else
|
||||||
|
{ }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
ToSerialized(SerializedKeyRange& aKeyRange) const;
|
||||||
|
|
||||||
|
const Key&
|
||||||
|
Lower() const
|
||||||
{
|
{
|
||||||
return mLower;
|
return mLower;
|
||||||
}
|
}
|
||||||
|
|
||||||
Key& Lower()
|
Key&
|
||||||
|
Lower()
|
||||||
{
|
{
|
||||||
return mLower;
|
return mLower;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Key& Upper() const
|
const Key&
|
||||||
|
Upper() const
|
||||||
{
|
{
|
||||||
return mIsOnly ? mLower : mUpper;
|
return mIsOnly ? mLower : mUpper;
|
||||||
}
|
}
|
||||||
|
|
||||||
Key& Upper()
|
Key&
|
||||||
|
Upper()
|
||||||
{
|
{
|
||||||
return mIsOnly ? mLower : mUpper;
|
return mIsOnly ? mLower : mUpper;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove these in favour of LowerOpen() / UpperOpen(), bug 900578.
|
bool
|
||||||
bool IsLowerOpen() const
|
IsOnly() const
|
||||||
{
|
|
||||||
return mLowerOpen;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsUpperOpen() const
|
|
||||||
{
|
|
||||||
return mUpperOpen;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsOnly() const
|
|
||||||
{
|
{
|
||||||
return mIsOnly;
|
return mIsOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetBindingClause(const nsACString& aKeyColumnName,
|
void
|
||||||
nsACString& _retval) const
|
GetBindingClause(const nsACString& aKeyColumnName,
|
||||||
{
|
nsACString& _retval) const;
|
||||||
NS_NAMED_LITERAL_CSTRING(andStr, " AND ");
|
|
||||||
NS_NAMED_LITERAL_CSTRING(spacecolon, " :");
|
|
||||||
NS_NAMED_LITERAL_CSTRING(lowerKey, "lower_key");
|
|
||||||
|
|
||||||
if (IsOnly()) {
|
nsresult
|
||||||
// Both keys are set and they're equal.
|
BindToStatement(mozIStorageStatement* aStatement) const;
|
||||||
_retval = andStr + aKeyColumnName + NS_LITERAL_CSTRING(" =") +
|
|
||||||
spacecolon + lowerKey;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nsAutoCString clause;
|
|
||||||
|
|
||||||
if (!Lower().IsUnset()) {
|
void
|
||||||
// Lower key is set.
|
DropJSObjects();
|
||||||
clause.Append(andStr + aKeyColumnName);
|
|
||||||
clause.AppendLiteral(" >");
|
|
||||||
if (!IsLowerOpen()) {
|
|
||||||
clause.Append('=');
|
|
||||||
}
|
|
||||||
clause.Append(spacecolon + lowerKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Upper().IsUnset()) {
|
|
||||||
// Upper key is set.
|
|
||||||
clause.Append(andStr + aKeyColumnName);
|
|
||||||
clause.AppendLiteral(" <");
|
|
||||||
if (!IsUpperOpen()) {
|
|
||||||
clause.Append('=');
|
|
||||||
}
|
|
||||||
clause.Append(spacecolon + NS_LITERAL_CSTRING("upper_key"));
|
|
||||||
}
|
|
||||||
|
|
||||||
_retval = clause;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult BindToStatement(mozIStorageStatement* aStatement) const
|
|
||||||
{
|
|
||||||
NS_NAMED_LITERAL_CSTRING(lowerKey, "lower_key");
|
|
||||||
|
|
||||||
if (IsOnly()) {
|
|
||||||
return Lower().BindToStatement(aStatement, lowerKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
if (!Lower().IsUnset()) {
|
|
||||||
rv = Lower().BindToStatement(aStatement, lowerKey);
|
|
||||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Upper().IsUnset()) {
|
|
||||||
rv = Upper().BindToStatement(aStatement, NS_LITERAL_CSTRING("upper_key"));
|
|
||||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void ToSerializedKeyRange(T& aKeyRange);
|
|
||||||
|
|
||||||
void DropJSObjects();
|
|
||||||
|
|
||||||
// WebIDL
|
// WebIDL
|
||||||
JSObject*
|
JSObject*
|
||||||
|
@ -176,48 +169,17 @@ public:
|
||||||
return mUpperOpen;
|
return mUpperOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
static already_AddRefed<IDBKeyRange>
|
|
||||||
Only(const GlobalObject& aGlobal,
|
|
||||||
JS::Handle<JS::Value> aValue, ErrorResult& aRv);
|
|
||||||
|
|
||||||
static already_AddRefed<IDBKeyRange>
|
|
||||||
LowerBound(const GlobalObject& aGlobal,
|
|
||||||
JS::Handle<JS::Value> aValue, bool aOpen, ErrorResult& aRv);
|
|
||||||
|
|
||||||
static already_AddRefed<IDBKeyRange>
|
|
||||||
UpperBound(const GlobalObject& aGlobal,
|
|
||||||
JS::Handle<JS::Value> aValue, bool aOpen, ErrorResult& aRv);
|
|
||||||
|
|
||||||
static already_AddRefed<IDBKeyRange>
|
|
||||||
Bound(const GlobalObject& aGlobal,
|
|
||||||
JS::Handle<JS::Value> aLower, JS::Handle<JS::Value> aUpper,
|
|
||||||
bool aLowerOpen, bool aUpperOpen, ErrorResult& aRv);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IDBKeyRange(nsISupports* aGlobal,
|
IDBKeyRange(nsISupports* aGlobal,
|
||||||
bool aLowerOpen,
|
bool aLowerOpen,
|
||||||
bool aUpperOpen,
|
bool aUpperOpen,
|
||||||
bool aIsOnly)
|
bool aIsOnly);
|
||||||
: mGlobal(aGlobal), mCachedLowerVal(JSVAL_VOID), mCachedUpperVal(JSVAL_VOID),
|
|
||||||
mLowerOpen(aLowerOpen), mUpperOpen(aUpperOpen), mIsOnly(aIsOnly),
|
|
||||||
mHaveCachedLowerVal(false), mHaveCachedUpperVal(false), mRooted(false)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
~IDBKeyRange();
|
~IDBKeyRange();
|
||||||
|
|
||||||
nsCOMPtr<nsISupports> mGlobal;
|
|
||||||
Key mLower;
|
|
||||||
Key mUpper;
|
|
||||||
JS::Heap<JS::Value> mCachedLowerVal;
|
|
||||||
JS::Heap<JS::Value> mCachedUpperVal;
|
|
||||||
const bool mLowerOpen;
|
|
||||||
const bool mUpperOpen;
|
|
||||||
const bool mIsOnly;
|
|
||||||
bool mHaveCachedLowerVal;
|
|
||||||
bool mHaveCachedUpperVal;
|
|
||||||
bool mRooted;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
} // namespace indexedDB
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif // mozilla_dom_indexeddb_idbkeyrange_h__
|
#endif // mozilla_dom_indexeddb_idbkeyrange_h__
|
||||||
|
|
|
@ -6,26 +6,36 @@
|
||||||
|
|
||||||
#include "IDBMutableFile.h"
|
#include "IDBMutableFile.h"
|
||||||
|
|
||||||
#include "nsIDOMFile.h"
|
#include "FileSnapshot.h"
|
||||||
|
#include "FileInfo.h"
|
||||||
|
#include "IDBDatabase.h"
|
||||||
|
#include "IDBFactory.h"
|
||||||
|
#include "IDBFileHandle.h"
|
||||||
|
#include "IDBFileRequest.h"
|
||||||
|
#include "IndexedDatabaseManager.h"
|
||||||
|
#include "MainThreadUtils.h"
|
||||||
|
#include "mozilla/Assertions.h"
|
||||||
#include "mozilla/ErrorResult.h"
|
#include "mozilla/ErrorResult.h"
|
||||||
#include "mozilla/dom/FileService.h"
|
#include "mozilla/dom/FileService.h"
|
||||||
#include "mozilla/dom/IDBMutableFileBinding.h"
|
#include "mozilla/dom/IDBMutableFileBinding.h"
|
||||||
#include "mozilla/dom/MetadataHelper.h"
|
#include "mozilla/dom/MetadataHelper.h"
|
||||||
|
#include "mozilla/dom/indexedDB/PBackgroundIDBSharedTypes.h"
|
||||||
#include "mozilla/dom/quota/FileStreams.h"
|
#include "mozilla/dom/quota/FileStreams.h"
|
||||||
#include "mozilla/dom/quota/QuotaManager.h"
|
#include "mozilla/dom/quota/QuotaManager.h"
|
||||||
|
#include "mozilla/ipc/BackgroundUtils.h"
|
||||||
|
#include "mozilla/ipc/PBackgroundSharedTypes.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsDebug.h"
|
#include "nsDebug.h"
|
||||||
#include "nsError.h"
|
#include "nsError.h"
|
||||||
|
#include "nsIDOMFile.h"
|
||||||
|
#include "nsIPrincipal.h"
|
||||||
|
|
||||||
#include "FileSnapshot.h"
|
namespace mozilla {
|
||||||
#include "IDBDatabase.h"
|
namespace dom {
|
||||||
#include "IDBFileHandle.h"
|
namespace indexedDB {
|
||||||
#include "IDBFileRequest.h"
|
|
||||||
|
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom::quota;
|
||||||
USING_INDEXEDDB_NAMESPACE
|
using namespace mozilla::ipc;
|
||||||
USING_QUOTA_NAMESPACE
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -48,7 +58,6 @@ public:
|
||||||
ReleaseObjects() MOZ_OVERRIDE
|
ReleaseObjects() MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
mMutableFile = nullptr;
|
mMutableFile = nullptr;
|
||||||
|
|
||||||
MetadataHelper::ReleaseObjects();
|
MetadataHelper::ReleaseObjects();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,109 +65,213 @@ private:
|
||||||
nsRefPtr<IDBMutableFile> mMutableFile;
|
nsRefPtr<IDBMutableFile> mMutableFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline
|
|
||||||
already_AddRefed<nsIFile>
|
already_AddRefed<nsIFile>
|
||||||
GetFileFor(FileInfo* aFileInfo)
|
GetFileFor(FileInfo* aFileInfo)
|
||||||
|
|
||||||
{
|
{
|
||||||
FileManager* fileManager = aFileInfo->Manager();
|
MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess());
|
||||||
nsCOMPtr<nsIFile> directory = fileManager->GetDirectory();
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
NS_ENSURE_TRUE(directory, nullptr);
|
MOZ_ASSERT(aFileInfo);
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> file = fileManager->GetFileForId(directory,
|
FileManager* fileManager = aFileInfo->Manager();
|
||||||
aFileInfo->Id());
|
MOZ_ASSERT(fileManager);
|
||||||
NS_ENSURE_TRUE(file, nullptr);
|
|
||||||
|
nsCOMPtr<nsIFile> directory = fileManager->GetDirectory();
|
||||||
|
if (NS_WARN_IF(!directory)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIFile> file =
|
||||||
|
fileManager->GetFileForId(directory, aFileInfo->Id());
|
||||||
|
if (NS_WARN_IF(!file)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return file.forget();
|
return file.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
namespace mozilla {
|
IDBMutableFile::IDBMutableFile(IDBDatabase* aDatabase,
|
||||||
namespace dom {
|
const nsAString& aName,
|
||||||
namespace indexedDB {
|
const nsAString& aType,
|
||||||
|
already_AddRefed<FileInfo> aFileInfo,
|
||||||
IDBMutableFile::IDBMutableFile(IDBDatabase* aOwner)
|
const nsACString& aGroup,
|
||||||
: DOMEventTargetHelper(aOwner)
|
const nsACString& aOrigin,
|
||||||
|
const nsACString& aStorageId,
|
||||||
|
PersistenceType aPersistenceType,
|
||||||
|
already_AddRefed<nsIFile> aFile)
|
||||||
|
: DOMEventTargetHelper(aDatabase)
|
||||||
|
, mDatabase(aDatabase)
|
||||||
|
, mFileInfo(aFileInfo)
|
||||||
|
, mGroup(aGroup)
|
||||||
|
, mOrigin(aOrigin)
|
||||||
|
, mPersistenceType(aPersistenceType)
|
||||||
|
, mInvalidated(false)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess());
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
MOZ_ASSERT(mDatabase);
|
||||||
|
MOZ_ASSERT(mFileInfo);
|
||||||
|
|
||||||
|
mName = aName;
|
||||||
|
mType = aType;
|
||||||
|
mFile = aFile;
|
||||||
|
mStorageId = aStorageId;
|
||||||
|
mFileName.AppendInt(mFileInfo->Id());
|
||||||
|
|
||||||
|
MOZ_ASSERT(mFile);
|
||||||
|
|
||||||
|
mDatabase->NoteLiveMutableFile(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
IDBMutableFile::~IDBMutableFile()
|
IDBMutableFile::~IDBMutableFile()
|
||||||
{
|
{
|
||||||
|
// XXX This is always in the main process but it sometimes happens too late in
|
||||||
|
// shutdown and the IndexedDatabaseManager has already been torn down.
|
||||||
|
// MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess());
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
if (mDatabase) {
|
||||||
|
mDatabase->NoteFinishedMutableFile(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(IDBMutableFile, DOMEventTargetHelper,
|
|
||||||
mDatabase)
|
|
||||||
|
|
||||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBMutableFile)
|
|
||||||
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
|
||||||
|
|
||||||
NS_IMPL_ADDREF_INHERITED(IDBMutableFile, DOMEventTargetHelper)
|
|
||||||
NS_IMPL_RELEASE_INHERITED(IDBMutableFile, DOMEventTargetHelper)
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
already_AddRefed<IDBMutableFile>
|
already_AddRefed<IDBMutableFile>
|
||||||
IDBMutableFile::Create(const nsAString& aName,
|
IDBMutableFile::Create(IDBDatabase* aDatabase,
|
||||||
|
const nsAString& aName,
|
||||||
const nsAString& aType,
|
const nsAString& aType,
|
||||||
IDBDatabase* aDatabase,
|
|
||||||
already_AddRefed<FileInfo> aFileInfo)
|
already_AddRefed<FileInfo> aFileInfo)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess());
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
nsRefPtr<FileInfo> fileInfo(aFileInfo);
|
nsRefPtr<FileInfo> fileInfo(aFileInfo);
|
||||||
NS_ASSERTION(fileInfo, "Null pointer!");
|
MOZ_ASSERT(fileInfo);
|
||||||
|
|
||||||
nsRefPtr<IDBMutableFile> newFile = new IDBMutableFile(aDatabase);
|
PrincipalInfo* principalInfo = aDatabase->Factory()->GetPrincipalInfo();
|
||||||
|
MOZ_ASSERT(principalInfo);
|
||||||
|
|
||||||
newFile->mName = aName;
|
nsCOMPtr<nsIPrincipal> principal = PrincipalInfoToPrincipal(*principalInfo);
|
||||||
newFile->mType = aType;
|
if (NS_WARN_IF(!principal)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
newFile->mFile = GetFileFor(fileInfo);
|
nsCString group;
|
||||||
NS_ENSURE_TRUE(newFile->mFile, nullptr);
|
nsCString origin;
|
||||||
|
if (NS_WARN_IF(NS_FAILED(QuotaManager::GetInfoFromPrincipal(principal,
|
||||||
|
&group,
|
||||||
|
&origin,
|
||||||
|
nullptr,
|
||||||
|
nullptr)))) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
newFile->mStorageId = aDatabase->Id();
|
const DatabaseSpec* spec = aDatabase->Spec();
|
||||||
newFile->mFileName.AppendInt(fileInfo->Id());
|
MOZ_ASSERT(spec);
|
||||||
|
|
||||||
newFile->mDatabase = aDatabase;
|
PersistenceType persistenceType = spec->metadata().persistenceType();
|
||||||
fileInfo.swap(newFile->mFileInfo);
|
|
||||||
|
nsCString storageId;
|
||||||
|
QuotaManager::GetStorageId(persistenceType,
|
||||||
|
origin,
|
||||||
|
Client::IDB,
|
||||||
|
aDatabase->Name(),
|
||||||
|
storageId);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIFile> file = GetFileFor(fileInfo);
|
||||||
|
if (NS_WARN_IF(!file)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<IDBMutableFile> newFile =
|
||||||
|
new IDBMutableFile(aDatabase,
|
||||||
|
aName,
|
||||||
|
aType,
|
||||||
|
fileInfo.forget(),
|
||||||
|
group,
|
||||||
|
origin,
|
||||||
|
storageId,
|
||||||
|
persistenceType,
|
||||||
|
file.forget());
|
||||||
|
|
||||||
return newFile.forget();
|
return newFile.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IDBMutableFile::Invalidate()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
MOZ_ASSERT(!mInvalidated);
|
||||||
|
|
||||||
|
mInvalidated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMPL_ADDREF_INHERITED(IDBMutableFile, DOMEventTargetHelper)
|
||||||
|
NS_IMPL_RELEASE_INHERITED(IDBMutableFile, DOMEventTargetHelper)
|
||||||
|
|
||||||
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBMutableFile)
|
||||||
|
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBMutableFile)
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBMutableFile,
|
||||||
|
DOMEventTargetHelper)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDatabase)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBMutableFile,
|
||||||
|
DOMEventTargetHelper)
|
||||||
|
MOZ_ASSERT(tmp->mDatabase);
|
||||||
|
tmp->mDatabase->NoteFinishedMutableFile(tmp);
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDatabase)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||||
|
|
||||||
bool
|
bool
|
||||||
IDBMutableFile::IsInvalid()
|
IDBMutableFile::IsInvalid()
|
||||||
{
|
{
|
||||||
return mDatabase->IsInvalidated();
|
return mInvalidated;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIOfflineStorage*
|
nsIOfflineStorage*
|
||||||
IDBMutableFile::Storage()
|
IDBMutableFile::Storage()
|
||||||
{
|
{
|
||||||
return mDatabase;
|
MOZ_CRASH("Don't call me!");
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<nsISupports>
|
already_AddRefed<nsISupports>
|
||||||
IDBMutableFile::CreateStream(bool aReadOnly)
|
IDBMutableFile::CreateStream(bool aReadOnly)
|
||||||
{
|
{
|
||||||
PersistenceType persistenceType = mDatabase->Type();
|
MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess());
|
||||||
const nsACString& group = mDatabase->Group();
|
|
||||||
const nsACString& origin = mDatabase->Origin();
|
|
||||||
|
|
||||||
nsCOMPtr<nsISupports> result;
|
nsCOMPtr<nsISupports> result;
|
||||||
|
|
||||||
if (aReadOnly) {
|
if (aReadOnly) {
|
||||||
nsRefPtr<FileInputStream> stream =
|
nsRefPtr<FileInputStream> stream =
|
||||||
FileInputStream::Create(persistenceType, group, origin, mFile, -1, -1,
|
FileInputStream::Create(mPersistenceType,
|
||||||
|
mGroup,
|
||||||
|
mOrigin,
|
||||||
|
mFile,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
nsIFileInputStream::DEFER_OPEN);
|
nsIFileInputStream::DEFER_OPEN);
|
||||||
result = NS_ISUPPORTS_CAST(nsIFileInputStream*, stream);
|
result = NS_ISUPPORTS_CAST(nsIFileInputStream*, stream);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
nsRefPtr<FileStream> stream =
|
nsRefPtr<FileStream> stream =
|
||||||
FileStream::Create(persistenceType, group, origin, mFile, -1, -1,
|
FileStream::Create(mPersistenceType,
|
||||||
|
mGroup,
|
||||||
|
mOrigin,
|
||||||
|
mFile,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
nsIFileStream::DEFER_OPEN);
|
nsIFileStream::DEFER_OPEN);
|
||||||
result = NS_ISUPPORTS_CAST(nsIFileStream*, stream);
|
result = NS_ISUPPORTS_CAST(nsIFileStream*, stream);
|
||||||
}
|
}
|
||||||
NS_ENSURE_TRUE(result, nullptr);
|
|
||||||
|
if (NS_WARN_IF(!result)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return result.forget();
|
return result.forget();
|
||||||
}
|
}
|
||||||
|
@ -166,33 +279,37 @@ IDBMutableFile::CreateStream(bool aReadOnly)
|
||||||
void
|
void
|
||||||
IDBMutableFile::SetThreadLocals()
|
IDBMutableFile::SetThreadLocals()
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess());
|
||||||
MOZ_ASSERT(mDatabase->GetOwner(), "Should have owner!");
|
MOZ_ASSERT(mDatabase->GetOwner(), "Should have owner!");
|
||||||
|
|
||||||
QuotaManager::SetCurrentWindow(mDatabase->GetOwner());
|
QuotaManager::SetCurrentWindow(mDatabase->GetOwner());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
IDBMutableFile::UnsetThreadLocals()
|
IDBMutableFile::UnsetThreadLocals()
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess());
|
||||||
|
|
||||||
QuotaManager::SetCurrentWindow(nullptr);
|
QuotaManager::SetCurrentWindow(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<nsIDOMFile>
|
|
||||||
IDBMutableFile::CreateFileObject(IDBFileHandle* aFileHandle, uint32_t aFileSize)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIDOMFile> fileSnapshot = new DOMFile(
|
|
||||||
new FileImplSnapshot(mName, mType, aFileSize, mFile, aFileHandle,
|
|
||||||
mFileInfo));
|
|
||||||
|
|
||||||
return fileSnapshot.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
// virtual
|
|
||||||
JSObject*
|
JSObject*
|
||||||
IDBMutableFile::WrapObject(JSContext* aCx)
|
IDBMutableFile::WrapObject(JSContext* aCx)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess());
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
return IDBMutableFileBinding::Wrap(aCx, this);
|
return IDBMutableFileBinding::Wrap(aCx, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IDBDatabase*
|
||||||
|
IDBMutableFile::Database() const
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
return mDatabase;
|
||||||
|
}
|
||||||
|
|
||||||
already_AddRefed<IDBFileHandle>
|
already_AddRefed<IDBFileHandle>
|
||||||
IDBMutableFile::Open(FileMode aMode, ErrorResult& aError)
|
IDBMutableFile::Open(FileMode aMode, ErrorResult& aError)
|
||||||
{
|
{
|
||||||
|
@ -213,6 +330,31 @@ IDBMutableFile::Open(FileMode aMode, ErrorResult& aError)
|
||||||
return fileHandle.forget();
|
return fileHandle.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
IDBMutableFile::GetFileId() const
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
MOZ_ASSERT(mFileInfo);
|
||||||
|
|
||||||
|
return mFileInfo->Id();
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<nsIDOMFile>
|
||||||
|
IDBMutableFile::CreateFileObject(IDBFileHandle* aFileHandle,
|
||||||
|
MetadataParameters* aMetadataParams)
|
||||||
|
{
|
||||||
|
nsRefPtr<DOMFileImpl> impl =
|
||||||
|
new FileImplSnapshot(mName,
|
||||||
|
mType,
|
||||||
|
aMetadataParams,
|
||||||
|
mFile,
|
||||||
|
aFileHandle,
|
||||||
|
mFileInfo);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMFile> fileSnapshot = new DOMFile(impl);
|
||||||
|
return fileSnapshot.forget();
|
||||||
|
}
|
||||||
|
|
||||||
already_AddRefed<DOMRequest>
|
already_AddRefed<DOMRequest>
|
||||||
IDBMutableFile::GetFile(ErrorResult& aError)
|
IDBMutableFile::GetFile(ErrorResult& aError)
|
||||||
{
|
{
|
||||||
|
@ -227,10 +369,11 @@ IDBMutableFile::GetFile(ErrorResult& aError)
|
||||||
IDBFileHandle::Create(FileMode::Readonly, FileHandleBase::PARALLEL, this);
|
IDBFileHandle::Create(FileMode::Readonly, FileHandleBase::PARALLEL, this);
|
||||||
|
|
||||||
nsRefPtr<IDBFileRequest> request =
|
nsRefPtr<IDBFileRequest> request =
|
||||||
IDBFileRequest::Create(GetOwner(), fileHandle, /* aWrapAsDOMRequest */
|
IDBFileRequest::Create(GetOwner(),
|
||||||
true);
|
fileHandle,
|
||||||
|
/* aWrapAsDOMRequest */ true);
|
||||||
|
|
||||||
nsRefPtr<MetadataParameters> params = new MetadataParameters(true, false);
|
nsRefPtr<MetadataParameters> params = new MetadataParameters(true, true);
|
||||||
|
|
||||||
nsRefPtr<GetFileHelper> helper =
|
nsRefPtr<GetFileHelper> helper =
|
||||||
new GetFileHelper(fileHandle, request, params, this);
|
new GetFileHelper(fileHandle, request, params, this);
|
||||||
|
@ -244,10 +387,6 @@ IDBMutableFile::GetFile(ErrorResult& aError)
|
||||||
return request.forget();
|
return request.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace indexedDB
|
|
||||||
} // namespace dom
|
|
||||||
} // namespace mozilla
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
GetFileHelper::GetSuccessResult(JSContext* aCx,
|
GetFileHelper::GetSuccessResult(JSContext* aCx,
|
||||||
JS::MutableHandle<JS::Value> aVal)
|
JS::MutableHandle<JS::Value> aVal)
|
||||||
|
@ -257,7 +396,7 @@ GetFileHelper::GetSuccessResult(JSContext* aCx,
|
||||||
auto fileHandle = static_cast<IDBFileHandle*>(mFileHandle.get());
|
auto fileHandle = static_cast<IDBFileHandle*>(mFileHandle.get());
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMFile> domFile =
|
nsCOMPtr<nsIDOMFile> domFile =
|
||||||
mMutableFile->CreateFileObject(fileHandle, mParams->Size());
|
mMutableFile->CreateFileObject(fileHandle, mParams);
|
||||||
|
|
||||||
nsresult rv =
|
nsresult rv =
|
||||||
nsContentUtils::WrapNative(aCx, domFile, &NS_GET_IID(nsIDOMFile), aVal);
|
nsContentUtils::WrapNative(aCx, domFile, &NS_GET_IID(nsIDOMFile), aVal);
|
||||||
|
@ -267,3 +406,7 @@ GetFileHelper::GetSuccessResult(JSContext* aCx,
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace indexedDB
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
|
@ -8,13 +8,13 @@
|
||||||
#define mozilla_dom_indexeddb_idbmutablefile_h__
|
#define mozilla_dom_indexeddb_idbmutablefile_h__
|
||||||
|
|
||||||
#include "js/TypeDecls.h"
|
#include "js/TypeDecls.h"
|
||||||
#include "MainThreadUtils.h"
|
#include "mozilla/Atomics.h"
|
||||||
#include "mozilla/Assertions.h"
|
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/dom/FileModeBinding.h"
|
#include "mozilla/dom/FileModeBinding.h"
|
||||||
#include "mozilla/dom/indexedDB/FileInfo.h"
|
|
||||||
#include "mozilla/dom/MutableFile.h"
|
|
||||||
#include "mozilla/DOMEventTargetHelper.h"
|
#include "mozilla/DOMEventTargetHelper.h"
|
||||||
|
#include "mozilla/dom/FileModeBinding.h"
|
||||||
|
#include "mozilla/dom/MutableFile.h"
|
||||||
|
#include "mozilla/dom/quota/PersistenceType.h"
|
||||||
#include "nsAutoPtr.h"
|
#include "nsAutoPtr.h"
|
||||||
#include "nsCycleCollectionParticipant.h"
|
#include "nsCycleCollectionParticipant.h"
|
||||||
|
|
||||||
|
@ -28,23 +28,39 @@ class ErrorResult;
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
class DOMRequest;
|
class DOMRequest;
|
||||||
|
class MetadataParameters;
|
||||||
|
|
||||||
namespace indexedDB {
|
namespace indexedDB {
|
||||||
|
|
||||||
|
class FileInfo;
|
||||||
class IDBDatabase;
|
class IDBDatabase;
|
||||||
class IDBFileHandle;
|
class IDBFileHandle;
|
||||||
|
|
||||||
class IDBMutableFile MOZ_FINAL : public DOMEventTargetHelper,
|
class IDBMutableFile MOZ_FINAL
|
||||||
public MutableFileBase
|
: public DOMEventTargetHelper
|
||||||
|
, public MutableFileBase
|
||||||
{
|
{
|
||||||
|
typedef mozilla::dom::MetadataParameters MetadataParameters;
|
||||||
|
typedef mozilla::dom::quota::PersistenceType PersistenceType;
|
||||||
|
|
||||||
|
nsString mName;
|
||||||
|
nsString mType;
|
||||||
|
|
||||||
|
nsRefPtr<IDBDatabase> mDatabase;
|
||||||
|
nsRefPtr<FileInfo> mFileInfo;
|
||||||
|
|
||||||
|
const nsCString mGroup;
|
||||||
|
const nsCString mOrigin;
|
||||||
|
const PersistenceType mPersistenceType;
|
||||||
|
|
||||||
|
Atomic<bool> mInvalidated;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
|
||||||
|
|
||||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBMutableFile, DOMEventTargetHelper)
|
|
||||||
|
|
||||||
static already_AddRefed<IDBMutableFile>
|
static already_AddRefed<IDBMutableFile>
|
||||||
Create(const nsAString& aName, const nsAString& aType,
|
Create(IDBDatabase* aDatabase,
|
||||||
IDBDatabase* aDatabase, already_AddRefed<FileInfo> aFileInfo);
|
const nsAString& aName,
|
||||||
|
const nsAString& aType,
|
||||||
|
already_AddRefed<FileInfo> aFileInfo);
|
||||||
|
|
||||||
const nsAString&
|
const nsAString&
|
||||||
Name() const
|
Name() const
|
||||||
|
@ -59,10 +75,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t
|
int64_t
|
||||||
GetFileId() const
|
GetFileId() const;
|
||||||
{
|
|
||||||
return mFileInfo->Id();
|
|
||||||
}
|
|
||||||
|
|
||||||
FileInfo*
|
FileInfo*
|
||||||
GetFileInfo() const
|
GetFileInfo() const
|
||||||
|
@ -70,6 +83,16 @@ public:
|
||||||
return mFileInfo;
|
return mFileInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
already_AddRefed<nsIDOMFile>
|
||||||
|
CreateFileObject(IDBFileHandle* aFileHandle,
|
||||||
|
MetadataParameters* aMetadataParams);
|
||||||
|
|
||||||
|
void
|
||||||
|
Invalidate();
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBMutableFile, DOMEventTargetHelper)
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
IsInvalid() MOZ_OVERRIDE;
|
IsInvalid() MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
@ -85,9 +108,6 @@ public:
|
||||||
virtual void
|
virtual void
|
||||||
UnsetThreadLocals() MOZ_OVERRIDE;
|
UnsetThreadLocals() MOZ_OVERRIDE;
|
||||||
|
|
||||||
already_AddRefed<nsIDOMFile>
|
|
||||||
CreateFileObject(IDBFileHandle* aFileHandle, uint32_t aFileSize);
|
|
||||||
|
|
||||||
// nsWrapperCache
|
// nsWrapperCache
|
||||||
virtual JSObject*
|
virtual JSObject*
|
||||||
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||||
|
@ -112,12 +132,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
IDBDatabase*
|
IDBDatabase*
|
||||||
Database()
|
Database() const;
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
|
|
||||||
return mDatabase;
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<IDBFileHandle>
|
already_AddRefed<IDBFileHandle>
|
||||||
Open(FileMode aMode, ErrorResult& aError);
|
Open(FileMode aMode, ErrorResult& aError);
|
||||||
|
@ -129,14 +144,17 @@ public:
|
||||||
IMPL_EVENT_HANDLER(error)
|
IMPL_EVENT_HANDLER(error)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit IDBMutableFile(IDBDatabase* aOwner);
|
IDBMutableFile(IDBDatabase* aDatabase,
|
||||||
|
const nsAString& aName,
|
||||||
|
const nsAString& aType,
|
||||||
|
already_AddRefed<FileInfo> aFileInfo,
|
||||||
|
const nsACString& aGroup,
|
||||||
|
const nsACString& aOrigin,
|
||||||
|
const nsACString& aStorageId,
|
||||||
|
PersistenceType aPersistenceType,
|
||||||
|
already_AddRefed<nsIFile> aFile);
|
||||||
|
|
||||||
~IDBMutableFile();
|
~IDBMutableFile();
|
||||||
|
|
||||||
nsString mName;
|
|
||||||
nsString mType;
|
|
||||||
|
|
||||||
nsRefPtr<IDBDatabase> mDatabase;
|
|
||||||
nsRefPtr<FileInfo> mFileInfo;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace indexedDB
|
} // namespace indexedDB
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -7,61 +7,68 @@
|
||||||
#ifndef mozilla_dom_indexeddb_idbobjectstore_h__
|
#ifndef mozilla_dom_indexeddb_idbobjectstore_h__
|
||||||
#define mozilla_dom_indexeddb_idbobjectstore_h__
|
#define mozilla_dom_indexeddb_idbobjectstore_h__
|
||||||
|
|
||||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
#include "js/RootingAPI.h"
|
||||||
|
|
||||||
#include "js/TypeDecls.h"
|
|
||||||
#include "mozilla/dom/IDBCursorBinding.h"
|
#include "mozilla/dom/IDBCursorBinding.h"
|
||||||
#include "mozilla/dom/IDBIndexBinding.h"
|
#include "mozilla/dom/IDBIndexBinding.h"
|
||||||
#include "mozilla/dom/IDBObjectStoreBinding.h"
|
#include "nsAutoPtr.h"
|
||||||
#include "nsCycleCollectionParticipant.h"
|
#include "nsCycleCollectionParticipant.h"
|
||||||
#include "MainThreadUtils.h"
|
#include "nsISupports.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
#include "nsTArray.h"
|
||||||
|
#include "nsWrapperCache.h"
|
||||||
|
|
||||||
#include "mozilla/dom/indexedDB/IDBRequest.h"
|
struct JSClass;
|
||||||
#include "mozilla/dom/indexedDB/IDBTransaction.h"
|
|
||||||
#include "mozilla/dom/indexedDB/KeyPath.h"
|
|
||||||
|
|
||||||
class nsIDOMBlob;
|
|
||||||
class nsIScriptContext;
|
|
||||||
class nsPIDOMWindow;
|
class nsPIDOMWindow;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
class ErrorResult;
|
||||||
|
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
|
class DOMStringList;
|
||||||
class nsIContentParent;
|
class nsIContentParent;
|
||||||
class PBlobChild;
|
template <typename> class Sequence;
|
||||||
class PBlobParent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
namespace indexedDB {
|
||||||
|
|
||||||
class AsyncConnectionHelper;
|
|
||||||
class FileManager;
|
class FileManager;
|
||||||
class IDBCursor;
|
|
||||||
class IDBKeyRange;
|
class IDBKeyRange;
|
||||||
class IDBRequest;
|
class IDBRequest;
|
||||||
class IndexedDBObjectStoreChild;
|
class IDBTransaction;
|
||||||
class IndexedDBObjectStoreParent;
|
class IndexUpdateInfo;
|
||||||
class Key;
|
class Key;
|
||||||
|
class KeyPath;
|
||||||
|
class ObjectStoreSpec;
|
||||||
|
struct StructuredCloneFile;
|
||||||
|
struct StructuredCloneReadInfo;
|
||||||
|
|
||||||
struct IndexInfo;
|
class IDBObjectStore MOZ_FINAL
|
||||||
struct IndexUpdateInfo;
|
: public nsISupports
|
||||||
struct ObjectStoreInfo;
|
, public nsWrapperCache
|
||||||
|
|
||||||
struct MutableFileData;
|
|
||||||
struct BlobOrFileData;
|
|
||||||
|
|
||||||
class IDBObjectStore MOZ_FINAL : public nsISupports,
|
|
||||||
public nsWrapperCache
|
|
||||||
{
|
{
|
||||||
|
static const JSClass sDummyPropJSClass;
|
||||||
|
|
||||||
|
nsRefPtr<IDBTransaction> mTransaction;
|
||||||
|
JS::Heap<JS::Value> mCachedKeyPath;
|
||||||
|
|
||||||
|
// This normally points to the ObjectStoreSpec owned by the parent IDBDatabase
|
||||||
|
// object. However, if this objectStore is part of a versionchange transaction
|
||||||
|
// and it gets deleted then the spec is copied into mDeletedSpec and mSpec is
|
||||||
|
// set to point at mDeletedSpec.
|
||||||
|
const ObjectStoreSpec* mSpec;
|
||||||
|
nsAutoPtr<ObjectStoreSpec> mDeletedSpec;
|
||||||
|
|
||||||
|
nsTArray<nsRefPtr<IDBIndex>> mIndexes;
|
||||||
|
|
||||||
|
const int64_t mId;
|
||||||
|
bool mRooted;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
struct StructuredCloneWriteInfo;
|
||||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBObjectStore)
|
|
||||||
|
|
||||||
static already_AddRefed<IDBObjectStore>
|
static already_AddRefed<IDBObjectStore>
|
||||||
Create(IDBTransaction* aTransaction,
|
Create(IDBTransaction* aTransaction, const ObjectStoreSpec& aSpec);
|
||||||
ObjectStoreInfo* aInfo,
|
|
||||||
const nsACString& aDatabaseId,
|
|
||||||
bool aCreating);
|
|
||||||
|
|
||||||
static nsresult
|
static nsresult
|
||||||
AppendIndexUpdateInfo(int64_t aIndexID,
|
AppendIndexUpdateInfo(int64_t aIndexID,
|
||||||
|
@ -72,214 +79,62 @@ public:
|
||||||
JS::Handle<JS::Value> aObject,
|
JS::Handle<JS::Value> aObject,
|
||||||
nsTArray<IndexUpdateInfo>& aUpdateInfoArray);
|
nsTArray<IndexUpdateInfo>& aUpdateInfoArray);
|
||||||
|
|
||||||
static nsresult
|
|
||||||
UpdateIndexes(IDBTransaction* aTransaction,
|
|
||||||
int64_t aObjectStoreId,
|
|
||||||
const Key& aObjectStoreKey,
|
|
||||||
bool aOverwrite,
|
|
||||||
int64_t aObjectDataId,
|
|
||||||
const nsTArray<IndexUpdateInfo>& aUpdateInfoArray);
|
|
||||||
|
|
||||||
static nsresult
|
|
||||||
GetStructuredCloneReadInfoFromStatement(mozIStorageStatement* aStatement,
|
|
||||||
uint32_t aDataIndex,
|
|
||||||
uint32_t aFileIdsIndex,
|
|
||||||
IDBDatabase* aDatabase,
|
|
||||||
StructuredCloneReadInfo& aInfo);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ClearCloneReadInfo(StructuredCloneReadInfo& aReadInfo);
|
ClearCloneReadInfo(StructuredCloneReadInfo& aReadInfo);
|
||||||
|
|
||||||
static void
|
|
||||||
ClearCloneWriteInfo(StructuredCloneWriteInfo& aWriteInfo);
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
DeserializeValue(JSContext* aCx,
|
DeserializeValue(JSContext* aCx,
|
||||||
StructuredCloneReadInfo& aCloneReadInfo,
|
StructuredCloneReadInfo& aCloneReadInfo,
|
||||||
JS::MutableHandle<JS::Value> aValue);
|
JS::MutableHandle<JS::Value> aValue);
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
SerializeValue(JSContext* aCx,
|
DeserializeIndexValue(JSContext* aCx,
|
||||||
StructuredCloneWriteInfo& aCloneWriteInfo,
|
StructuredCloneReadInfo& aCloneReadInfo,
|
||||||
JS::Handle<JS::Value> aValue);
|
JS::MutableHandle<JS::Value> aValue);
|
||||||
|
|
||||||
template <class DeserializationTraits>
|
static const JSClass*
|
||||||
static JSObject*
|
DummyPropClass()
|
||||||
StructuredCloneReadCallback(JSContext* aCx,
|
|
||||||
JSStructuredCloneReader* aReader,
|
|
||||||
uint32_t aTag,
|
|
||||||
uint32_t aData,
|
|
||||||
void* aClosure);
|
|
||||||
static bool
|
|
||||||
StructuredCloneWriteCallback(JSContext* aCx,
|
|
||||||
JSStructuredCloneWriter* aWriter,
|
|
||||||
JS::Handle<JSObject*> aObj,
|
|
||||||
void* aClosure);
|
|
||||||
|
|
||||||
static nsresult
|
|
||||||
ConvertFileIdsToArray(const nsAString& aFileIds,
|
|
||||||
nsTArray<int64_t>& aResult);
|
|
||||||
|
|
||||||
// Called only in the main process.
|
|
||||||
static nsresult
|
|
||||||
ConvertBlobsToActors(nsIContentParent* aContentParent,
|
|
||||||
FileManager* aFileManager,
|
|
||||||
const nsTArray<StructuredCloneFile>& aFiles,
|
|
||||||
InfallibleTArray<PBlobParent*>& aActors);
|
|
||||||
|
|
||||||
// Called only in the child process.
|
|
||||||
static void
|
|
||||||
ConvertActorsToBlobs(const InfallibleTArray<PBlobChild*>& aActors,
|
|
||||||
nsTArray<StructuredCloneFile>& aFiles);
|
|
||||||
|
|
||||||
const nsString& Name() const
|
|
||||||
{
|
{
|
||||||
return mName;
|
return &sDummyPropJSClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsAutoIncrement() const
|
void
|
||||||
{
|
AssertIsOnOwningThread() const
|
||||||
return mAutoIncrement;
|
#ifdef DEBUG
|
||||||
}
|
;
|
||||||
|
#else
|
||||||
|
{ }
|
||||||
|
#endif
|
||||||
|
|
||||||
bool IsWriteAllowed() const
|
int64_t
|
||||||
|
Id() const
|
||||||
{
|
{
|
||||||
return mTransaction->IsWriteAllowed();
|
AssertIsOnOwningThread();
|
||||||
}
|
|
||||||
|
|
||||||
int64_t Id() const
|
|
||||||
{
|
|
||||||
NS_ASSERTION(mId != INT64_MIN, "Don't ask for this yet!");
|
|
||||||
return mId;
|
return mId;
|
||||||
}
|
}
|
||||||
|
|
||||||
const KeyPath& GetKeyPath() const
|
const nsString&
|
||||||
{
|
Name() const;
|
||||||
return mKeyPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool HasValidKeyPath() const
|
bool
|
||||||
{
|
AutoIncrement() const;
|
||||||
return mKeyPath.IsValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
IDBTransaction* Transaction()
|
const KeyPath&
|
||||||
{
|
GetKeyPath() const;
|
||||||
return mTransaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectStoreInfo* Info()
|
bool
|
||||||
{
|
HasValidKeyPath() const;
|
||||||
return mInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
nsPIDOMWindow*
|
||||||
SetActor(IndexedDBObjectStoreChild* aActorChild)
|
GetParentObject() const;
|
||||||
{
|
|
||||||
NS_ASSERTION(!aActorChild || !mActorChild, "Shouldn't have more than one!");
|
|
||||||
mActorChild = aActorChild;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SetActor(IndexedDBObjectStoreParent* aActorParent)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(!aActorParent || !mActorParent,
|
|
||||||
"Shouldn't have more than one!");
|
|
||||||
mActorParent = aActorParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexedDBObjectStoreChild*
|
|
||||||
GetActorChild() const
|
|
||||||
{
|
|
||||||
return mActorChild;
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexedDBObjectStoreParent*
|
|
||||||
GetActorParent() const
|
|
||||||
{
|
|
||||||
return mActorParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<IDBIndex>
|
|
||||||
CreateIndexInternal(const IndexInfo& aInfo,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
|
|
||||||
nsresult AddOrPutInternal(
|
|
||||||
const SerializedStructuredCloneWriteInfo& aCloneWriteInfo,
|
|
||||||
const Key& aKey,
|
|
||||||
const InfallibleTArray<IndexUpdateInfo>& aUpdateInfoArray,
|
|
||||||
const nsTArray<nsCOMPtr<nsIDOMBlob> >& aBlobs,
|
|
||||||
bool aOverwrite,
|
|
||||||
IDBRequest** _retval);
|
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
|
||||||
GetInternal(IDBKeyRange* aKeyRange,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
|
||||||
GetAllInternal(IDBKeyRange* aKeyRange,
|
|
||||||
uint32_t aLimit,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
|
||||||
GetAllKeysInternal(IDBKeyRange* aKeyRange,
|
|
||||||
uint32_t aLimit,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
|
||||||
DeleteInternal(IDBKeyRange* aKeyRange,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
|
||||||
CountInternal(IDBKeyRange* aKeyRange,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
|
||||||
OpenCursorInternal(IDBKeyRange* aKeyRange,
|
|
||||||
size_t aDirection,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
|
||||||
OpenKeyCursorInternal(IDBKeyRange* aKeyRange,
|
|
||||||
size_t aDirection,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
OpenCursorFromChildProcess(
|
|
||||||
IDBRequest* aRequest,
|
|
||||||
size_t aDirection,
|
|
||||||
const Key& aKey,
|
|
||||||
const SerializedStructuredCloneReadInfo& aCloneInfo,
|
|
||||||
nsTArray<StructuredCloneFile>& aBlobs,
|
|
||||||
IDBCursor** _retval);
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
OpenCursorFromChildProcess(IDBRequest* aRequest,
|
|
||||||
size_t aDirection,
|
|
||||||
const Key& aKey,
|
|
||||||
IDBCursor** _retval);
|
|
||||||
|
|
||||||
void
|
|
||||||
SetInfo(ObjectStoreInfo* aInfo);
|
|
||||||
|
|
||||||
static const JSClass sDummyPropJSClass;
|
|
||||||
|
|
||||||
// nsWrapperCache
|
|
||||||
virtual JSObject*
|
|
||||||
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
// WebIDL
|
|
||||||
IDBTransaction*
|
|
||||||
GetParentObject() const
|
|
||||||
{
|
|
||||||
return mTransaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
GetName(nsString& aName) const
|
GetName(nsString& aName) const
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
AssertIsOnOwningThread();
|
||||||
aName.Assign(mName);
|
|
||||||
|
aName = Name();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -287,38 +142,38 @@ public:
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
||||||
already_AddRefed<DOMStringList>
|
already_AddRefed<DOMStringList>
|
||||||
GetIndexNames(ErrorResult& aRv);
|
IndexNames();
|
||||||
|
|
||||||
IDBTransaction*
|
IDBTransaction*
|
||||||
Transaction() const
|
Transaction() const
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
return mTransaction;
|
return mTransaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
AutoIncrement() const
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
return mAutoIncrement;
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
already_AddRefed<IDBRequest>
|
||||||
Put(JSContext* aCx, JS::Handle<JS::Value> aValue,
|
Add(JSContext* aCx,
|
||||||
JS::Handle<JS::Value> aKey, ErrorResult& aRv)
|
JS::Handle<JS::Value> aValue,
|
||||||
|
JS::Handle<JS::Value> aKey,
|
||||||
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
AssertIsOnOwningThread();
|
||||||
return AddOrPut(aCx, aValue, aKey, true, aRv);
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
|
||||||
Add(JSContext* aCx, JS::Handle<JS::Value> aValue,
|
|
||||||
JS::Handle<JS::Value> aKey, ErrorResult& aRv)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
return AddOrPut(aCx, aValue, aKey, false, aRv);
|
return AddOrPut(aCx, aValue, aKey, false, aRv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
already_AddRefed<IDBRequest>
|
||||||
|
Put(JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aValue,
|
||||||
|
JS::Handle<JS::Value> aKey,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
return AddOrPut(aCx, aValue, aKey, true, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
already_AddRefed<IDBRequest>
|
||||||
Delete(JSContext* aCx, JS::Handle<JS::Value> aKey, ErrorResult& aRv);
|
Delete(JSContext* aCx, JS::Handle<JS::Value> aKey, ErrorResult& aRv);
|
||||||
|
|
||||||
|
@ -328,18 +183,19 @@ public:
|
||||||
already_AddRefed<IDBRequest>
|
already_AddRefed<IDBRequest>
|
||||||
Clear(ErrorResult& aRv);
|
Clear(ErrorResult& aRv);
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
already_AddRefed<IDBIndex>
|
||||||
OpenCursor(JSContext* aCx, JS::Handle<JS::Value> aRange,
|
CreateIndex(JSContext* aCx,
|
||||||
IDBCursorDirection aDirection, ErrorResult& aRv);
|
const nsAString& aName,
|
||||||
|
const nsAString& aKeyPath,
|
||||||
|
const IDBIndexParameters& aOptionalParameters,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
already_AddRefed<IDBIndex>
|
already_AddRefed<IDBIndex>
|
||||||
CreateIndex(JSContext* aCx, const nsAString& aName, const nsAString& aKeyPath,
|
CreateIndex(JSContext* aCx,
|
||||||
const IDBIndexParameters& aOptionalParameters, ErrorResult& aRv);
|
const nsAString& aName,
|
||||||
|
|
||||||
already_AddRefed<IDBIndex>
|
|
||||||
CreateIndex(JSContext* aCx, const nsAString& aName,
|
|
||||||
const Sequence<nsString>& aKeyPath,
|
const Sequence<nsString>& aKeyPath,
|
||||||
const IDBIndexParameters& aOptionalParameters, ErrorResult& aRv);
|
const IDBIndexParameters& aOptionalParameters,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
already_AddRefed<IDBIndex>
|
already_AddRefed<IDBIndex>
|
||||||
Index(const nsAString& aName, ErrorResult &aRv);
|
Index(const nsAString& aName, ErrorResult &aRv);
|
||||||
|
@ -348,70 +204,116 @@ public:
|
||||||
DeleteIndex(const nsAString& aIndexName, ErrorResult& aRv);
|
DeleteIndex(const nsAString& aIndexName, ErrorResult& aRv);
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
already_AddRefed<IDBRequest>
|
||||||
Count(JSContext* aCx, JS::Handle<JS::Value> aKey,
|
Count(JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aKey,
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
already_AddRefed<IDBRequest>
|
||||||
GetAll(JSContext* aCx, JS::Handle<JS::Value> aKey,
|
GetAll(JSContext* aCx,
|
||||||
const Optional<uint32_t>& aLimit, ErrorResult& aRv);
|
JS::Handle<JS::Value> aKey,
|
||||||
|
const Optional<uint32_t>& aLimit,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
return GetAllInternal(/* aKeysOnly */ false, aCx, aKey, aLimit, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
already_AddRefed<IDBRequest>
|
||||||
GetAllKeys(JSContext* aCx, JS::Handle<JS::Value> aKey,
|
GetAllKeys(JSContext* aCx,
|
||||||
const Optional<uint32_t>& aLimit, ErrorResult& aRv);
|
JS::Handle<JS::Value> aKey,
|
||||||
|
const Optional<uint32_t>& aLimit,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
return GetAllInternal(/* aKeysOnly */ true, aCx, aKey, aLimit, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
already_AddRefed<IDBRequest>
|
||||||
OpenKeyCursor(JSContext* aCx, JS::Handle<JS::Value> aRange,
|
OpenCursor(JSContext* aCx,
|
||||||
IDBCursorDirection aDirection, ErrorResult& aRv);
|
JS::Handle<JS::Value> aRange,
|
||||||
|
IDBCursorDirection aDirection,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
return OpenCursorInternal(/* aKeysOnly */ false, aCx, aRange, aDirection,
|
||||||
|
aRv);
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<IDBRequest>
|
||||||
|
OpenKeyCursor(JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aRange,
|
||||||
|
IDBCursorDirection aDirection,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
return OpenCursorInternal(/* aKeysOnly */ true, aCx, aRange, aDirection,
|
||||||
|
aRv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RefreshSpec(bool aMayDelete);
|
||||||
|
|
||||||
|
const ObjectStoreSpec&
|
||||||
|
Spec() const;
|
||||||
|
|
||||||
|
void
|
||||||
|
NoteDeletion();
|
||||||
|
|
||||||
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||||
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBObjectStore)
|
||||||
|
|
||||||
|
// nsWrapperCache
|
||||||
|
virtual JSObject*
|
||||||
|
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
IDBObjectStore(IDBTransaction* aTransaction, const ObjectStoreSpec* aSpec);
|
||||||
|
|
||||||
protected:
|
|
||||||
IDBObjectStore();
|
|
||||||
~IDBObjectStore();
|
~IDBObjectStore();
|
||||||
|
|
||||||
nsresult GetAddInfo(JSContext* aCx,
|
nsresult
|
||||||
JS::Handle<JS::Value> aValue,
|
GetAddInfo(JSContext* aCx,
|
||||||
JS::Handle<JS::Value> aKeyVal,
|
JS::Handle<JS::Value> aValue,
|
||||||
StructuredCloneWriteInfo& aCloneWriteInfo,
|
JS::Handle<JS::Value> aKeyVal,
|
||||||
Key& aKey,
|
StructuredCloneWriteInfo& aCloneWriteInfo,
|
||||||
nsTArray<IndexUpdateInfo>& aUpdateInfoArray);
|
Key& aKey,
|
||||||
|
nsTArray<IndexUpdateInfo>& aUpdateInfoArray);
|
||||||
|
|
||||||
already_AddRefed<IDBRequest>
|
already_AddRefed<IDBRequest>
|
||||||
AddOrPut(JSContext* aCx, JS::Handle<JS::Value> aValue,
|
AddOrPut(JSContext* aCx,
|
||||||
JS::Handle<JS::Value> aKey, bool aOverwrite,
|
JS::Handle<JS::Value> aValue,
|
||||||
|
JS::Handle<JS::Value> aKey,
|
||||||
|
bool aOverwrite,
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
already_AddRefed<IDBRequest>
|
||||||
|
GetAllInternal(bool aKeysOnly,
|
||||||
|
JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aKey,
|
||||||
|
const Optional<uint32_t>& aLimit,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
already_AddRefed<IDBIndex>
|
already_AddRefed<IDBIndex>
|
||||||
CreateIndex(JSContext* aCx, const nsAString& aName, KeyPath& aKeyPath,
|
CreateIndexInternal(JSContext* aCx,
|
||||||
const IDBIndexParameters& aOptionalParameters, ErrorResult& aRv);
|
const nsAString& aName,
|
||||||
|
const KeyPath& aKeyPath,
|
||||||
|
const IDBIndexParameters& aOptionalParameters,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
static void
|
already_AddRefed<IDBRequest>
|
||||||
ClearStructuredCloneBuffer(JSAutoStructuredCloneBuffer& aBuffer);
|
OpenCursorInternal(bool aKeysOnly,
|
||||||
|
JSContext* aCx,
|
||||||
static bool
|
JS::Handle<JS::Value> aRange,
|
||||||
ReadMutableFile(JSStructuredCloneReader* aReader,
|
IDBCursorDirection aDirection,
|
||||||
MutableFileData* aRetval);
|
ErrorResult& aRv);
|
||||||
|
|
||||||
static bool
|
|
||||||
ReadBlobOrFile(JSStructuredCloneReader* aReader,
|
|
||||||
uint32_t aTag,
|
|
||||||
BlobOrFileData* aRetval);
|
|
||||||
private:
|
|
||||||
nsRefPtr<IDBTransaction> mTransaction;
|
|
||||||
|
|
||||||
int64_t mId;
|
|
||||||
nsString mName;
|
|
||||||
KeyPath mKeyPath;
|
|
||||||
JS::Heap<JS::Value> mCachedKeyPath;
|
|
||||||
bool mRooted;
|
|
||||||
bool mAutoIncrement;
|
|
||||||
nsCString mDatabaseId;
|
|
||||||
nsRefPtr<ObjectStoreInfo> mInfo;
|
|
||||||
|
|
||||||
nsTArray<nsRefPtr<IDBIndex> > mCreatedIndexes;
|
|
||||||
|
|
||||||
IndexedDBObjectStoreChild* mActorChild;
|
|
||||||
IndexedDBObjectStoreParent* mActorParent;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
} // namespace indexedDB
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif // mozilla_dom_indexeddb_idbobjectstore_h__
|
#endif // mozilla_dom_indexeddb_idbobjectstore_h__
|
||||||
|
|
|
@ -6,78 +6,88 @@
|
||||||
|
|
||||||
#include "IDBRequest.h"
|
#include "IDBRequest.h"
|
||||||
|
|
||||||
#include "nsIScriptContext.h"
|
#include "BackgroundChildImpl.h"
|
||||||
|
|
||||||
#include "mozilla/ContentEvents.h"
|
|
||||||
#include "mozilla/EventDispatcher.h"
|
|
||||||
#include "mozilla/dom/ErrorEventBinding.h"
|
|
||||||
#include "mozilla/dom/IDBOpenDBRequestBinding.h"
|
|
||||||
#include "mozilla/dom/ScriptSettings.h"
|
|
||||||
#include "mozilla/dom/UnionTypes.h"
|
|
||||||
#include "nsComponentManagerUtils.h"
|
|
||||||
#include "nsDOMClassInfoID.h"
|
|
||||||
#include "nsDOMJSUtils.h"
|
|
||||||
#include "nsContentUtils.h"
|
|
||||||
#include "nsJSUtils.h"
|
|
||||||
#include "nsPIDOMWindow.h"
|
|
||||||
#include "nsString.h"
|
|
||||||
#include "nsThreadUtils.h"
|
|
||||||
#include "nsWrapperCacheInlines.h"
|
|
||||||
|
|
||||||
#include "AsyncConnectionHelper.h"
|
|
||||||
#include "IDBCursor.h"
|
#include "IDBCursor.h"
|
||||||
|
#include "IDBDatabase.h"
|
||||||
#include "IDBEvents.h"
|
#include "IDBEvents.h"
|
||||||
#include "IDBFactory.h"
|
#include "IDBFactory.h"
|
||||||
#include "IDBIndex.h"
|
#include "IDBIndex.h"
|
||||||
#include "IDBObjectStore.h"
|
#include "IDBObjectStore.h"
|
||||||
#include "IDBTransaction.h"
|
#include "IDBTransaction.h"
|
||||||
|
#include "mozilla/ContentEvents.h"
|
||||||
|
#include "mozilla/ErrorResult.h"
|
||||||
|
#include "mozilla/EventDispatcher.h"
|
||||||
|
#include "mozilla/dom/ErrorEventBinding.h"
|
||||||
|
#include "mozilla/dom/IDBOpenDBRequestBinding.h"
|
||||||
|
#include "mozilla/dom/ScriptSettings.h"
|
||||||
|
#include "mozilla/dom/UnionTypes.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsContentUtils.h"
|
||||||
|
#include "nsIScriptContext.h"
|
||||||
|
#include "nsJSUtils.h"
|
||||||
|
#include "nsPIDOMWindow.h"
|
||||||
|
#include "nsString.h"
|
||||||
#include "ReportInternalError.h"
|
#include "ReportInternalError.h"
|
||||||
|
|
||||||
namespace {
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
namespace indexedDB {
|
||||||
|
|
||||||
#ifdef MOZ_ENABLE_PROFILER_SPS
|
using namespace mozilla::ipc;
|
||||||
uint64_t gNextRequestSerialNumber = 1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
USING_INDEXEDDB_NAMESPACE
|
|
||||||
using mozilla::dom::OwningIDBObjectStoreOrIDBIndexOrIDBCursor;
|
|
||||||
using mozilla::dom::ErrorEventInit;
|
|
||||||
using namespace mozilla;
|
|
||||||
|
|
||||||
IDBRequest::IDBRequest(IDBDatabase* aDatabase)
|
IDBRequest::IDBRequest(IDBDatabase* aDatabase)
|
||||||
: IDBWrapperCache(aDatabase),
|
: IDBWrapperCache(aDatabase)
|
||||||
mResultVal(JSVAL_VOID),
|
|
||||||
mActorParent(nullptr),
|
|
||||||
#ifdef MOZ_ENABLE_PROFILER_SPS
|
|
||||||
mSerialNumber(gNextRequestSerialNumber++),
|
|
||||||
#endif
|
|
||||||
mErrorCode(NS_OK),
|
|
||||||
mLineNo(0),
|
|
||||||
mHaveResultOrErrorCode(false)
|
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
MOZ_ASSERT(aDatabase);
|
||||||
|
aDatabase->AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
InitMembers();
|
||||||
}
|
}
|
||||||
|
|
||||||
IDBRequest::IDBRequest(nsPIDOMWindow* aOwner)
|
IDBRequest::IDBRequest(nsPIDOMWindow* aOwner)
|
||||||
: IDBWrapperCache(aOwner),
|
: IDBWrapperCache(aOwner)
|
||||||
mResultVal(JSVAL_VOID),
|
|
||||||
mActorParent(nullptr),
|
|
||||||
#ifdef MOZ_ENABLE_PROFILER_SPS
|
|
||||||
mSerialNumber(gNextRequestSerialNumber++),
|
|
||||||
#endif
|
|
||||||
mErrorCode(NS_OK),
|
|
||||||
mLineNo(0),
|
|
||||||
mHaveResultOrErrorCode(false)
|
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
InitMembers();
|
||||||
}
|
}
|
||||||
|
|
||||||
IDBRequest::~IDBRequest()
|
IDBRequest::~IDBRequest()
|
||||||
{
|
{
|
||||||
mResultVal = JSVAL_VOID;
|
AssertIsOnOwningThread();
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
|
||||||
|
void
|
||||||
|
IDBRequest::AssertIsOnOwningThread() const
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mOwningThread);
|
||||||
|
MOZ_ASSERT(PR_GetCurrentThread() == mOwningThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // DEBUG
|
||||||
|
|
||||||
|
void
|
||||||
|
IDBRequest::InitMembers()
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
mOwningThread = PR_GetCurrentThread();
|
||||||
|
#endif
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
mResultVal.setUndefined();
|
||||||
|
mErrorCode = NS_OK;
|
||||||
|
mLineNo = 0;
|
||||||
|
mHaveResultOrErrorCode = false;
|
||||||
|
|
||||||
|
#ifdef MOZ_ENABLE_PROFILER_SPS
|
||||||
|
{
|
||||||
|
BackgroundChildImpl::ThreadLocal* threadLocal =
|
||||||
|
BackgroundChildImpl::GetThreadLocalForCurrentThread();
|
||||||
|
MOZ_ASSERT(threadLocal);
|
||||||
|
|
||||||
|
mSerialNumber = threadLocal->mNextRequestSerialNumber++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
@ -85,16 +95,15 @@ already_AddRefed<IDBRequest>
|
||||||
IDBRequest::Create(IDBDatabase* aDatabase,
|
IDBRequest::Create(IDBDatabase* aDatabase,
|
||||||
IDBTransaction* aTransaction)
|
IDBTransaction* aTransaction)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
MOZ_ASSERT(aDatabase);
|
||||||
nsRefPtr<IDBRequest> request(new IDBRequest(aDatabase));
|
aDatabase->AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
nsRefPtr<IDBRequest> request = new IDBRequest(aDatabase);
|
||||||
|
|
||||||
request->mTransaction = aTransaction;
|
request->mTransaction = aTransaction;
|
||||||
request->SetScriptOwner(aDatabase->GetScriptOwner());
|
request->SetScriptOwner(aDatabase->GetScriptOwner());
|
||||||
|
|
||||||
if (!aDatabase->Factory()->FromIPC()) {
|
request->CaptureCaller();
|
||||||
request->CaptureCaller();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return request.forget();
|
return request.forget();
|
||||||
}
|
}
|
||||||
|
@ -105,6 +114,9 @@ IDBRequest::Create(IDBObjectStore* aSourceAsObjectStore,
|
||||||
IDBDatabase* aDatabase,
|
IDBDatabase* aDatabase,
|
||||||
IDBTransaction* aTransaction)
|
IDBTransaction* aTransaction)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(aSourceAsObjectStore);
|
||||||
|
aSourceAsObjectStore->AssertIsOnOwningThread();
|
||||||
|
|
||||||
nsRefPtr<IDBRequest> request = Create(aDatabase, aTransaction);
|
nsRefPtr<IDBRequest> request = Create(aDatabase, aTransaction);
|
||||||
|
|
||||||
request->mSourceAsObjectStore = aSourceAsObjectStore;
|
request->mSourceAsObjectStore = aSourceAsObjectStore;
|
||||||
|
@ -118,6 +130,9 @@ IDBRequest::Create(IDBIndex* aSourceAsIndex,
|
||||||
IDBDatabase* aDatabase,
|
IDBDatabase* aDatabase,
|
||||||
IDBTransaction* aTransaction)
|
IDBTransaction* aTransaction)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(aSourceAsIndex);
|
||||||
|
aSourceAsIndex->AssertIsOnOwningThread();
|
||||||
|
|
||||||
nsRefPtr<IDBRequest> request = Create(aDatabase, aTransaction);
|
nsRefPtr<IDBRequest> request = Create(aDatabase, aTransaction);
|
||||||
|
|
||||||
request->mSourceAsIndex = aSourceAsIndex;
|
request->mSourceAsIndex = aSourceAsIndex;
|
||||||
|
@ -125,31 +140,24 @@ IDBRequest::Create(IDBIndex* aSourceAsIndex,
|
||||||
return request.forget();
|
return request.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
void
|
void
|
||||||
IDBRequest::AssertSourceIsCorrect() const
|
IDBRequest::GetSource(
|
||||||
|
Nullable<OwningIDBObjectStoreOrIDBIndexOrIDBCursor>& aSource) const
|
||||||
{
|
{
|
||||||
// At most one of mSourceAs* is allowed to be non-null. Check that by
|
AssertIsOnOwningThread();
|
||||||
// summing the double negation of each one and asserting the sum is at most
|
|
||||||
// 1.
|
|
||||||
|
|
||||||
MOZ_ASSERT(!!mSourceAsObjectStore + !!mSourceAsIndex + !!mSourceAsCursor <= 1);
|
MOZ_ASSERT_IF(mSourceAsObjectStore, !mSourceAsIndex);
|
||||||
}
|
MOZ_ASSERT_IF(mSourceAsIndex, !mSourceAsObjectStore);
|
||||||
#endif
|
MOZ_ASSERT_IF(mSourceAsCursor, mSourceAsObjectStore || mSourceAsIndex);
|
||||||
|
|
||||||
void
|
// Always check cursor first since cursor requests hold both the cursor and
|
||||||
IDBRequest::GetSource(Nullable<OwningIDBObjectStoreOrIDBIndexOrIDBCursor>& aSource) const
|
// the objectStore or index the cursor came from.
|
||||||
{
|
if (mSourceAsCursor) {
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
aSource.SetValue().SetAsIDBCursor() = mSourceAsCursor;
|
||||||
|
} else if (mSourceAsObjectStore) {
|
||||||
AssertSourceIsCorrect();
|
|
||||||
|
|
||||||
if (mSourceAsObjectStore) {
|
|
||||||
aSource.SetValue().SetAsIDBObjectStore() = mSourceAsObjectStore;
|
aSource.SetValue().SetAsIDBObjectStore() = mSourceAsObjectStore;
|
||||||
} else if (mSourceAsIndex) {
|
} else if (mSourceAsIndex) {
|
||||||
aSource.SetValue().SetAsIDBIndex() = mSourceAsIndex;
|
aSource.SetValue().SetAsIDBIndex() = mSourceAsIndex;
|
||||||
} else if (mSourceAsCursor) {
|
|
||||||
aSource.SetValue().SetAsIDBCursor() = mSourceAsCursor;
|
|
||||||
} else {
|
} else {
|
||||||
aSource.SetNull();
|
aSource.SetNull();
|
||||||
}
|
}
|
||||||
|
@ -158,116 +166,63 @@ IDBRequest::GetSource(Nullable<OwningIDBObjectStoreOrIDBIndexOrIDBCursor>& aSour
|
||||||
void
|
void
|
||||||
IDBRequest::Reset()
|
IDBRequest::Reset()
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
AssertIsOnOwningThread();
|
||||||
mResultVal = JSVAL_VOID;
|
|
||||||
|
mResultVal.setUndefined();
|
||||||
mHaveResultOrErrorCode = false;
|
mHaveResultOrErrorCode = false;
|
||||||
mError = nullptr;
|
mError = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
IDBRequest::NotifyHelperCompleted(HelperBase* aHelper)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
NS_ASSERTION(!mHaveResultOrErrorCode, "Already called!");
|
|
||||||
NS_ASSERTION(mResultVal.isUndefined(), "Should be undefined!");
|
|
||||||
|
|
||||||
mHaveResultOrErrorCode = true;
|
|
||||||
|
|
||||||
nsresult rv = aHelper->GetResultCode();
|
|
||||||
|
|
||||||
// If the request failed then set the error code and return.
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
SetError(rv);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// See if our window is still valid. If not then we're going to pretend that
|
|
||||||
// we never completed.
|
|
||||||
if (NS_FAILED(CheckInnerWindowCorrectness())) {
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise we need to get the result from the helper.
|
|
||||||
AutoJSAPI jsapi;
|
|
||||||
Maybe<JSAutoCompartment> ac;
|
|
||||||
if (GetScriptOwner()) {
|
|
||||||
// If we have a script owner we want the SafeJSContext and then to enter
|
|
||||||
// the script owner's compartment.
|
|
||||||
jsapi.Init();
|
|
||||||
ac.emplace(jsapi.cx(), GetScriptOwner());
|
|
||||||
} else {
|
|
||||||
// Otherwise our owner is a window and we use that to initialize.
|
|
||||||
if (!jsapi.InitWithLegacyErrorReporting(GetOwner())) {
|
|
||||||
IDB_WARNING("Failed to initialise AutoJSAPI!");
|
|
||||||
rv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
|
||||||
SetError(rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
JSContext* cx = jsapi.cx();
|
|
||||||
|
|
||||||
AssertIsRooted();
|
|
||||||
|
|
||||||
JS::Rooted<JS::Value> value(cx);
|
|
||||||
rv = aHelper->GetSuccessResult(cx, &value);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
NS_WARNING("GetSuccessResult failed!");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
mError = nullptr;
|
|
||||||
mResultVal = value;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SetError(rv);
|
|
||||||
mResultVal = JSVAL_VOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
IDBRequest::NotifyHelperSentResultsToChildProcess(nsresult aRv)
|
IDBRequest::DispatchNonTransactionError(nsresult aErrorCode)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
AssertIsOnOwningThread();
|
||||||
NS_ASSERTION(!mHaveResultOrErrorCode, "Already called!");
|
MOZ_ASSERT(NS_FAILED(aErrorCode));
|
||||||
NS_ASSERTION(mResultVal.isUndefined(), "Should be undefined!");
|
MOZ_ASSERT(NS_ERROR_GET_MODULE(aErrorCode) == NS_ERROR_MODULE_DOM_INDEXEDDB);
|
||||||
|
|
||||||
// See if our window is still valid. If not then we're going to pretend that
|
SetError(aErrorCode);
|
||||||
// we never completed.
|
|
||||||
if (NS_FAILED(CheckInnerWindowCorrectness())) {
|
// Make an error event and fire it at the target.
|
||||||
|
nsCOMPtr<nsIDOMEvent> event =
|
||||||
|
CreateGenericEvent(this,
|
||||||
|
nsDependentString(kErrorEventType),
|
||||||
|
eDoesBubble,
|
||||||
|
eCancelable);
|
||||||
|
if (NS_WARN_IF(!event)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mHaveResultOrErrorCode = true;
|
bool ignored;
|
||||||
|
NS_WARN_IF(NS_FAILED(DispatchEvent(event, &ignored)));
|
||||||
if (NS_FAILED(aRv)) {
|
|
||||||
SetError(aRv);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
IDBRequest::SetError(nsresult aRv)
|
IDBRequest::SetError(nsresult aRv)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_FAILED(aRv), "Er, what?");
|
AssertIsOnOwningThread();
|
||||||
NS_ASSERTION(!mError, "Already have an error?");
|
MOZ_ASSERT(NS_FAILED(aRv));
|
||||||
|
MOZ_ASSERT(NS_ERROR_GET_MODULE(aRv) == NS_ERROR_MODULE_DOM_INDEXEDDB);
|
||||||
|
MOZ_ASSERT(!mError);
|
||||||
|
|
||||||
mHaveResultOrErrorCode = true;
|
mHaveResultOrErrorCode = true;
|
||||||
mError = new mozilla::dom::DOMError(GetOwner(), aRv);
|
mError = new DOMError(GetOwner(), aRv);
|
||||||
mErrorCode = aRv;
|
mErrorCode = aRv;
|
||||||
|
|
||||||
mResultVal = JSVAL_VOID;
|
mResultVal.setUndefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
IDBRequest::GetErrorCode() const
|
IDBRequest::GetErrorCode() const
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
AssertIsOnOwningThread();
|
||||||
NS_ASSERTION(mHaveResultOrErrorCode, "Don't call me yet!");
|
MOZ_ASSERT(mHaveResultOrErrorCode);
|
||||||
|
|
||||||
return mErrorCode;
|
return mErrorCode;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
#endif // DEBUG
|
||||||
|
|
||||||
void
|
void
|
||||||
IDBRequest::CaptureCaller()
|
IDBRequest::CaptureCaller()
|
||||||
|
@ -277,7 +232,6 @@ IDBRequest::CaptureCaller()
|
||||||
const char* filename = nullptr;
|
const char* filename = nullptr;
|
||||||
uint32_t lineNo = 0;
|
uint32_t lineNo = 0;
|
||||||
if (!nsJSUtils::GetCallingLocation(cx, &filename, &lineNo)) {
|
if (!nsJSUtils::GetCallingLocation(cx, &filename, &lineNo)) {
|
||||||
NS_WARNING("Failed to get caller.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,16 +246,25 @@ IDBRequest::FillScriptErrorEvent(ErrorEventInit& aEventInit) const
|
||||||
aEventInit.mFilename = mFilename;
|
aEventInit.mFilename = mFilename;
|
||||||
}
|
}
|
||||||
|
|
||||||
mozilla::dom::IDBRequestReadyState
|
IDBRequestReadyState
|
||||||
IDBRequest::ReadyState() const
|
IDBRequest::ReadyState() const
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
if (IsPending()) {
|
return IsPending() ?
|
||||||
return IDBRequestReadyState::Pending;
|
IDBRequestReadyState::Pending :
|
||||||
}
|
IDBRequestReadyState::Done;
|
||||||
|
}
|
||||||
|
|
||||||
return IDBRequestReadyState::Done;
|
void
|
||||||
|
IDBRequest::SetSource(IDBCursor* aSource)
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
MOZ_ASSERT(aSource);
|
||||||
|
MOZ_ASSERT(mSourceAsObjectStore || mSourceAsIndex);
|
||||||
|
MOZ_ASSERT(!mSourceAsCursor);
|
||||||
|
|
||||||
|
mSourceAsCursor = aSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSObject*
|
JSObject*
|
||||||
|
@ -314,21 +277,72 @@ void
|
||||||
IDBRequest::GetResult(JS::MutableHandle<JS::Value> aResult,
|
IDBRequest::GetResult(JS::MutableHandle<JS::Value> aResult,
|
||||||
ErrorResult& aRv) const
|
ErrorResult& aRv) const
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
if (!mHaveResultOrErrorCode) {
|
if (!mHaveResultOrErrorCode) {
|
||||||
// XXX Need a real error code here.
|
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::ExposeValueToActiveJS(mResultVal);
|
JS::ExposeValueToActiveJS(mResultVal);
|
||||||
aResult.set(mResultVal);
|
aResult.set(mResultVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
mozilla::dom::DOMError*
|
void
|
||||||
IDBRequest::GetError(mozilla::ErrorResult& aRv)
|
IDBRequest::SetResultCallback(ResultCallback* aCallback)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
AssertIsOnOwningThread();
|
||||||
|
MOZ_ASSERT(aCallback);
|
||||||
|
MOZ_ASSERT(!mHaveResultOrErrorCode);
|
||||||
|
MOZ_ASSERT(mResultVal.isUndefined());
|
||||||
|
MOZ_ASSERT(!mError);
|
||||||
|
|
||||||
|
// See if our window is still valid.
|
||||||
|
if (NS_WARN_IF(NS_FAILED(CheckInnerWindowCorrectness()))) {
|
||||||
|
IDB_REPORT_INTERNAL_ERR();
|
||||||
|
SetError(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoJSAPI autoJS;
|
||||||
|
Maybe<JSAutoCompartment> ac;
|
||||||
|
|
||||||
|
if (GetScriptOwner()) {
|
||||||
|
// If we have a script owner we want the SafeJSContext and then to enter the
|
||||||
|
// script owner's compartment.
|
||||||
|
autoJS.Init();
|
||||||
|
ac.emplace(autoJS.cx(), GetScriptOwner());
|
||||||
|
} else {
|
||||||
|
// Otherwise our owner is a window and we use that to initialize.
|
||||||
|
MOZ_ASSERT(GetOwner());
|
||||||
|
if (!autoJS.InitWithLegacyErrorReporting(GetOwner())) {
|
||||||
|
IDB_WARNING("Failed to initialize AutoJSAPI!");
|
||||||
|
SetError(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JSContext* cx = autoJS.cx();
|
||||||
|
|
||||||
|
AssertIsRooted();
|
||||||
|
|
||||||
|
JS::Rooted<JS::Value> result(cx);
|
||||||
|
nsresult rv = aCallback->GetResult(cx, &result);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
SetError(rv);
|
||||||
|
mResultVal.setUndefined();
|
||||||
|
} else {
|
||||||
|
mError = nullptr;
|
||||||
|
mResultVal = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
mHaveResultOrErrorCode = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DOMError*
|
||||||
|
IDBRequest::GetError(ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
if (!mHaveResultOrErrorCode) {
|
if (!mHaveResultOrErrorCode) {
|
||||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||||
|
@ -351,7 +365,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBRequest, IDBWrapperCache)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBRequest, IDBWrapperCache)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBRequest, IDBWrapperCache)
|
||||||
tmp->mResultVal = JSVAL_VOID;
|
tmp->mResultVal.setUndefined();
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourceAsObjectStore)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourceAsObjectStore)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourceAsIndex)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourceAsIndex)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourceAsCursor)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourceAsCursor)
|
||||||
|
@ -374,41 +388,60 @@ NS_IMPL_RELEASE_INHERITED(IDBRequest, IDBWrapperCache)
|
||||||
nsresult
|
nsresult
|
||||||
IDBRequest::PreHandleEvent(EventChainPreVisitor& aVisitor)
|
IDBRequest::PreHandleEvent(EventChainPreVisitor& aVisitor)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
aVisitor.mCanHandle = true;
|
aVisitor.mCanHandle = true;
|
||||||
aVisitor.mParentTarget = mTransaction;
|
aVisitor.mParentTarget = mTransaction;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
IDBOpenDBRequest::IDBOpenDBRequest(nsPIDOMWindow* aOwner)
|
IDBOpenDBRequest::IDBOpenDBRequest(IDBFactory* aFactory, nsPIDOMWindow* aOwner)
|
||||||
: IDBRequest(aOwner)
|
: IDBRequest(aOwner)
|
||||||
|
, mFactory(aFactory)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
AssertIsOnOwningThread();
|
||||||
|
MOZ_ASSERT(aFactory);
|
||||||
|
|
||||||
|
// aOwner may be null.
|
||||||
}
|
}
|
||||||
|
|
||||||
IDBOpenDBRequest::~IDBOpenDBRequest()
|
IDBOpenDBRequest::~IDBOpenDBRequest()
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
AssertIsOnOwningThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
already_AddRefed<IDBOpenDBRequest>
|
already_AddRefed<IDBOpenDBRequest>
|
||||||
IDBOpenDBRequest::Create(IDBFactory* aFactory,
|
IDBOpenDBRequest::CreateForWindow(IDBFactory* aFactory,
|
||||||
nsPIDOMWindow* aOwner,
|
nsPIDOMWindow* aOwner,
|
||||||
JS::Handle<JSObject*> aScriptOwner)
|
JS::Handle<JSObject*> aScriptOwner)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
MOZ_ASSERT(aFactory);
|
||||||
NS_ASSERTION(aFactory, "Null pointer!");
|
aFactory->AssertIsOnOwningThread();
|
||||||
|
MOZ_ASSERT(aOwner);
|
||||||
|
MOZ_ASSERT(aScriptOwner);
|
||||||
|
|
||||||
nsRefPtr<IDBOpenDBRequest> request = new IDBOpenDBRequest(aOwner);
|
nsRefPtr<IDBOpenDBRequest> request = new IDBOpenDBRequest(aFactory, aOwner);
|
||||||
|
request->CaptureCaller();
|
||||||
|
|
||||||
request->SetScriptOwner(aScriptOwner);
|
request->SetScriptOwner(aScriptOwner);
|
||||||
request->mFactory = aFactory;
|
|
||||||
|
|
||||||
if (!aFactory->FromIPC()) {
|
return request.forget();
|
||||||
request->CaptureCaller();
|
}
|
||||||
}
|
|
||||||
|
// static
|
||||||
|
already_AddRefed<IDBOpenDBRequest>
|
||||||
|
IDBOpenDBRequest::CreateForJS(IDBFactory* aFactory,
|
||||||
|
JS::Handle<JSObject*> aScriptOwner)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aFactory);
|
||||||
|
aFactory->AssertIsOnOwningThread();
|
||||||
|
MOZ_ASSERT(aScriptOwner);
|
||||||
|
|
||||||
|
nsRefPtr<IDBOpenDBRequest> request = new IDBOpenDBRequest(aFactory, nullptr);
|
||||||
|
request->CaptureCaller();
|
||||||
|
|
||||||
|
request->SetScriptOwner(aScriptOwner);
|
||||||
|
|
||||||
return request.forget();
|
return request.forget();
|
||||||
}
|
}
|
||||||
|
@ -416,10 +449,9 @@ IDBOpenDBRequest::Create(IDBFactory* aFactory,
|
||||||
void
|
void
|
||||||
IDBOpenDBRequest::SetTransaction(IDBTransaction* aTransaction)
|
IDBOpenDBRequest::SetTransaction(IDBTransaction* aTransaction)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
NS_ASSERTION(!aTransaction || !mTransaction,
|
MOZ_ASSERT(!aTransaction || !mTransaction);
|
||||||
"Shouldn't have a transaction here!");
|
|
||||||
|
|
||||||
mTransaction = aTransaction;
|
mTransaction = aTransaction;
|
||||||
}
|
}
|
||||||
|
@ -445,11 +477,20 @@ NS_IMPL_RELEASE_INHERITED(IDBOpenDBRequest, IDBRequest)
|
||||||
nsresult
|
nsresult
|
||||||
IDBOpenDBRequest::PostHandleEvent(EventChainPostVisitor& aVisitor)
|
IDBOpenDBRequest::PostHandleEvent(EventChainPostVisitor& aVisitor)
|
||||||
{
|
{
|
||||||
|
// XXX Fix me!
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
return IndexedDatabaseManager::FireWindowOnError(GetOwner(), aVisitor);
|
return IndexedDatabaseManager::FireWindowOnError(GetOwner(), aVisitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSObject*
|
JSObject*
|
||||||
IDBOpenDBRequest::WrapObject(JSContext* aCx)
|
IDBOpenDBRequest::WrapObject(JSContext* aCx)
|
||||||
{
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
return IDBOpenDBRequestBinding::Wrap(aCx, this);
|
return IDBOpenDBRequestBinding::Wrap(aCx, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace indexedDB
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
|
@ -7,72 +7,98 @@
|
||||||
#ifndef mozilla_dom_indexeddb_idbrequest_h__
|
#ifndef mozilla_dom_indexeddb_idbrequest_h__
|
||||||
#define mozilla_dom_indexeddb_idbrequest_h__
|
#define mozilla_dom_indexeddb_idbrequest_h__
|
||||||
|
|
||||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
#include "js/RootingAPI.h"
|
||||||
|
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/EventForwards.h"
|
#include "mozilla/EventForwards.h"
|
||||||
#include "mozilla/dom/DOMError.h"
|
|
||||||
#include "mozilla/dom/IDBRequestBinding.h"
|
#include "mozilla/dom/IDBRequestBinding.h"
|
||||||
#include "mozilla/ErrorResult.h"
|
|
||||||
#include "nsCycleCollectionParticipant.h"
|
|
||||||
#include "nsWrapperCache.h"
|
|
||||||
|
|
||||||
#include "mozilla/dom/indexedDB/IDBWrapperCache.h"
|
#include "mozilla/dom/indexedDB/IDBWrapperCache.h"
|
||||||
|
#include "nsAutoPtr.h"
|
||||||
|
#include "nsCycleCollectionParticipant.h"
|
||||||
|
|
||||||
class nsIScriptContext;
|
|
||||||
class nsPIDOMWindow;
|
class nsPIDOMWindow;
|
||||||
|
struct PRThread;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
class EventChainPostVisitor;
|
|
||||||
class EventChainPreVisitor;
|
class ErrorResult;
|
||||||
|
|
||||||
namespace dom {
|
namespace dom {
|
||||||
class OwningIDBObjectStoreOrIDBIndexOrIDBCursor;
|
|
||||||
|
class DOMError;
|
||||||
struct ErrorEventInit;
|
struct ErrorEventInit;
|
||||||
}
|
template <typename> struct Nullable;
|
||||||
}
|
class OwningIDBObjectStoreOrIDBIndexOrIDBCursor;
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
namespace indexedDB {
|
||||||
|
|
||||||
class HelperBase;
|
|
||||||
class IDBCursor;
|
class IDBCursor;
|
||||||
|
class IDBDatabase;
|
||||||
class IDBFactory;
|
class IDBFactory;
|
||||||
class IDBIndex;
|
class IDBIndex;
|
||||||
class IDBObjectStore;
|
class IDBObjectStore;
|
||||||
class IDBTransaction;
|
class IDBTransaction;
|
||||||
class IndexedDBRequestParentBase;
|
|
||||||
|
|
||||||
class IDBRequest : public IDBWrapperCache
|
class IDBRequest
|
||||||
|
: public IDBWrapperCache
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
|
// mSourceAsObjectStore and mSourceAsIndex are exclusive and one must always
|
||||||
|
// be set. mSourceAsCursor is sometimes set also.
|
||||||
|
nsRefPtr<IDBObjectStore> mSourceAsObjectStore;
|
||||||
|
nsRefPtr<IDBIndex> mSourceAsIndex;
|
||||||
|
nsRefPtr<IDBCursor> mSourceAsCursor;
|
||||||
|
|
||||||
|
nsRefPtr<IDBTransaction> mTransaction;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
PRThread* mOwningThread;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
JS::Heap<JS::Value> mResultVal;
|
||||||
|
nsRefPtr<DOMError> mError;
|
||||||
|
|
||||||
|
nsString mFilename;
|
||||||
|
#ifdef MOZ_ENABLE_PROFILER_SPS
|
||||||
|
uint64_t mSerialNumber;
|
||||||
|
#endif
|
||||||
|
nsresult mErrorCode;
|
||||||
|
uint32_t mLineNo;
|
||||||
|
bool mHaveResultOrErrorCode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
class ResultCallback;
|
||||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(IDBRequest,
|
|
||||||
IDBWrapperCache)
|
|
||||||
|
|
||||||
static
|
static already_AddRefed<IDBRequest>
|
||||||
already_AddRefed<IDBRequest> Create(IDBDatabase* aDatabase,
|
Create(IDBDatabase* aDatabase, IDBTransaction* aTransaction);
|
||||||
IDBTransaction* aTransaction);
|
|
||||||
|
|
||||||
static
|
static already_AddRefed<IDBRequest>
|
||||||
already_AddRefed<IDBRequest> Create(IDBObjectStore* aSource,
|
Create(IDBObjectStore* aSource,
|
||||||
IDBDatabase* aDatabase,
|
IDBDatabase* aDatabase,
|
||||||
IDBTransaction* aTransaction);
|
IDBTransaction* aTransaction);
|
||||||
|
|
||||||
static
|
static already_AddRefed<IDBRequest>
|
||||||
already_AddRefed<IDBRequest> Create(IDBIndex* aSource,
|
Create(IDBIndex* aSource,
|
||||||
IDBDatabase* aDatabase,
|
IDBDatabase* aDatabase,
|
||||||
IDBTransaction* aTransaction);
|
IDBTransaction* aTransaction);
|
||||||
|
|
||||||
// nsIDOMEventTarget
|
// nsIDOMEventTarget
|
||||||
virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
|
virtual nsresult
|
||||||
|
PreHandleEvent(EventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
|
||||||
|
|
||||||
void GetSource(Nullable<OwningIDBObjectStoreOrIDBIndexOrIDBCursor>& aSource) const;
|
void
|
||||||
|
GetSource(Nullable<OwningIDBObjectStoreOrIDBIndexOrIDBCursor>& aSource) const;
|
||||||
|
|
||||||
void Reset();
|
void
|
||||||
|
Reset();
|
||||||
|
|
||||||
nsresult NotifyHelperCompleted(HelperBase* aHelper);
|
void
|
||||||
void NotifyHelperSentResultsToChildProcess(nsresult aRv);
|
DispatchNonTransactionError(nsresult aErrorCode);
|
||||||
|
|
||||||
void SetError(nsresult aRv);
|
void
|
||||||
|
SetResultCallback(ResultCallback* aCallback);
|
||||||
|
|
||||||
|
void
|
||||||
|
SetError(nsresult aRv);
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
GetErrorCode() const
|
GetErrorCode() const
|
||||||
|
@ -84,25 +110,11 @@ public:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DOMError* GetError(ErrorResult& aRv);
|
DOMError*
|
||||||
|
GetError(ErrorResult& aRv);
|
||||||
|
|
||||||
void
|
void
|
||||||
SetActor(IndexedDBRequestParentBase* aActorParent)
|
FillScriptErrorEvent(ErrorEventInit& aEventInit) const;
|
||||||
{
|
|
||||||
NS_ASSERTION(!aActorParent || !mActorParent,
|
|
||||||
"Shouldn't have more than one!");
|
|
||||||
mActorParent = aActorParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexedDBRequestParentBase*
|
|
||||||
GetActorParent() const
|
|
||||||
{
|
|
||||||
return mActorParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CaptureCaller();
|
|
||||||
|
|
||||||
void FillScriptErrorEvent(ErrorEventInit& aEventInit) const;
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
IsPending() const
|
IsPending() const
|
||||||
|
@ -118,11 +130,6 @@ public:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// nsWrapperCache
|
|
||||||
virtual JSObject*
|
|
||||||
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
// WebIDL
|
|
||||||
nsPIDOMWindow*
|
nsPIDOMWindow*
|
||||||
GetParentObject() const
|
GetParentObject() const
|
||||||
{
|
{
|
||||||
|
@ -142,66 +149,87 @@ public:
|
||||||
IDBTransaction*
|
IDBTransaction*
|
||||||
GetTransaction() const
|
GetTransaction() const
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
return mTransaction;
|
return mTransaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
IDBRequestReadyState
|
IDBRequestReadyState
|
||||||
ReadyState() const;
|
ReadyState() const;
|
||||||
|
|
||||||
|
void
|
||||||
|
SetSource(IDBCursor* aSource);
|
||||||
|
|
||||||
IMPL_EVENT_HANDLER(success);
|
IMPL_EVENT_HANDLER(success);
|
||||||
IMPL_EVENT_HANDLER(error);
|
IMPL_EVENT_HANDLER(error);
|
||||||
|
|
||||||
|
void
|
||||||
|
AssertIsOnOwningThread() const
|
||||||
|
#ifdef DEBUG
|
||||||
|
;
|
||||||
|
#else
|
||||||
|
{ }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(IDBRequest,
|
||||||
|
IDBWrapperCache)
|
||||||
|
|
||||||
|
// nsWrapperCache
|
||||||
|
virtual JSObject*
|
||||||
|
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit IDBRequest(IDBDatabase* aDatabase);
|
explicit IDBRequest(IDBDatabase* aDatabase);
|
||||||
explicit IDBRequest(nsPIDOMWindow* aOwner);
|
explicit IDBRequest(nsPIDOMWindow* aOwner);
|
||||||
~IDBRequest();
|
~IDBRequest();
|
||||||
|
|
||||||
// At most one of these three fields can be non-null.
|
void
|
||||||
nsRefPtr<IDBObjectStore> mSourceAsObjectStore;
|
InitMembers();
|
||||||
nsRefPtr<IDBIndex> mSourceAsIndex;
|
|
||||||
nsRefPtr<IDBCursor> mSourceAsCursor;
|
|
||||||
|
|
||||||
// Check that the above condition holds.
|
void
|
||||||
#ifdef DEBUG
|
ConstructResult();
|
||||||
void AssertSourceIsCorrect() const;
|
|
||||||
#else
|
|
||||||
void AssertSourceIsCorrect() const {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nsRefPtr<IDBTransaction> mTransaction;
|
void
|
||||||
|
CaptureCaller();
|
||||||
JS::Heap<JS::Value> mResultVal;
|
|
||||||
nsRefPtr<mozilla::dom::DOMError> mError;
|
|
||||||
IndexedDBRequestParentBase* mActorParent;
|
|
||||||
nsString mFilename;
|
|
||||||
#ifdef MOZ_ENABLE_PROFILER_SPS
|
|
||||||
uint64_t mSerialNumber;
|
|
||||||
#endif
|
|
||||||
nsresult mErrorCode;
|
|
||||||
uint32_t mLineNo;
|
|
||||||
bool mHaveResultOrErrorCode;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class IDBOpenDBRequest : public IDBRequest
|
class NS_NO_VTABLE IDBRequest::ResultCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
virtual nsresult
|
||||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBOpenDBRequest, IDBRequest)
|
GetResult(JSContext* aCx, JS::MutableHandle<JS::Value> aResult) = 0;
|
||||||
|
|
||||||
static
|
protected:
|
||||||
already_AddRefed<IDBOpenDBRequest>
|
ResultCallback()
|
||||||
Create(IDBFactory* aFactory,
|
{ }
|
||||||
nsPIDOMWindow* aOwner,
|
};
|
||||||
JS::Handle<JSObject*> aScriptOwner);
|
|
||||||
|
|
||||||
void SetTransaction(IDBTransaction* aTransaction);
|
class IDBOpenDBRequest MOZ_FINAL
|
||||||
|
: public IDBRequest
|
||||||
|
{
|
||||||
|
// Only touched on the owning thread.
|
||||||
|
nsRefPtr<IDBFactory> mFactory;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static already_AddRefed<IDBOpenDBRequest>
|
||||||
|
CreateForWindow(IDBFactory* aFactory,
|
||||||
|
nsPIDOMWindow* aOwner,
|
||||||
|
JS::Handle<JSObject*> aScriptOwner);
|
||||||
|
|
||||||
|
static already_AddRefed<IDBOpenDBRequest>
|
||||||
|
CreateForJS(IDBFactory* aFactory,
|
||||||
|
JS::Handle<JSObject*> aScriptOwner);
|
||||||
|
|
||||||
|
void
|
||||||
|
SetTransaction(IDBTransaction* aTransaction);
|
||||||
|
|
||||||
// nsIDOMEventTarget
|
// nsIDOMEventTarget
|
||||||
virtual nsresult PostHandleEvent(
|
virtual nsresult
|
||||||
EventChainPostVisitor& aVisitor) MOZ_OVERRIDE;
|
PostHandleEvent(EventChainPostVisitor& aVisitor) MOZ_OVERRIDE;
|
||||||
|
|
||||||
DOMError* GetError(ErrorResult& aRv)
|
DOMError*
|
||||||
|
GetError(ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
return IDBRequest::GetError(aRv);
|
return IDBRequest::GetError(aRv);
|
||||||
}
|
}
|
||||||
|
@ -212,22 +240,24 @@ public:
|
||||||
return mFactory;
|
return mFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IMPL_EVENT_HANDLER(blocked);
|
||||||
|
IMPL_EVENT_HANDLER(upgradeneeded);
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBOpenDBRequest, IDBRequest)
|
||||||
|
|
||||||
// nsWrapperCache
|
// nsWrapperCache
|
||||||
virtual JSObject*
|
virtual JSObject*
|
||||||
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||||
|
|
||||||
// WebIDL
|
private:
|
||||||
IMPL_EVENT_HANDLER(blocked);
|
IDBOpenDBRequest(IDBFactory* aFactory, nsPIDOMWindow* aOwner);
|
||||||
IMPL_EVENT_HANDLER(upgradeneeded);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
explicit IDBOpenDBRequest(nsPIDOMWindow* aOwner);
|
|
||||||
~IDBOpenDBRequest();
|
~IDBOpenDBRequest();
|
||||||
|
|
||||||
// Only touched on the main thread.
|
|
||||||
nsRefPtr<IDBFactory> mFactory;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
} // namespace indexedDB
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif // mozilla_dom_indexeddb_idbrequest_h__
|
#endif // mozilla_dom_indexeddb_idbrequest_h__
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -8,71 +8,48 @@
|
||||||
#define mozilla_dom_indexeddb_idbtransaction_h__
|
#define mozilla_dom_indexeddb_idbtransaction_h__
|
||||||
|
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
|
||||||
|
|
||||||
#include "mozIStorageConnection.h"
|
|
||||||
#include "mozIStorageStatement.h"
|
|
||||||
#include "mozIStorageFunction.h"
|
|
||||||
#include "mozilla/dom/DOMError.h"
|
|
||||||
#include "nsIRunnable.h"
|
|
||||||
|
|
||||||
#include "nsAutoPtr.h"
|
|
||||||
#include "nsClassHashtable.h"
|
|
||||||
#include "nsHashKeys.h"
|
|
||||||
#include "nsInterfaceHashtable.h"
|
|
||||||
#include "nsRefPtrHashtable.h"
|
|
||||||
|
|
||||||
#include "mozilla/dom/IDBTransactionBinding.h"
|
#include "mozilla/dom/IDBTransactionBinding.h"
|
||||||
#include "mozilla/dom/indexedDB/IDBDatabase.h"
|
|
||||||
#include "mozilla/dom/indexedDB/IDBWrapperCache.h"
|
#include "mozilla/dom/indexedDB/IDBWrapperCache.h"
|
||||||
#include "mozilla/dom/indexedDB/FileInfo.h"
|
#include "nsAutoPtr.h"
|
||||||
|
#include "nsCycleCollectionParticipant.h"
|
||||||
|
#include "nsIRunnable.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
#include "nsTArray.h"
|
||||||
|
|
||||||
class nsIThread;
|
class nsIDOMBlob;
|
||||||
class nsPIDOMWindow;
|
class nsPIDOMWindow;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
class ErrorResult;
|
||||||
class EventChainPreVisitor;
|
class EventChainPreVisitor;
|
||||||
} // namespace mozilla
|
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
namespace dom {
|
||||||
|
|
||||||
class AsyncConnectionHelper;
|
class DOMError;
|
||||||
class CommitHelper;
|
class DOMStringList;
|
||||||
|
class PBlobChild;
|
||||||
|
|
||||||
|
namespace indexedDB {
|
||||||
|
|
||||||
|
class BackgroundCursorChild;
|
||||||
|
class BackgroundRequestChild;
|
||||||
|
class BackgroundTransactionChild;
|
||||||
|
class BackgroundVersionChangeTransactionChild;
|
||||||
|
class IDBDatabase;
|
||||||
|
class IDBObjectStore;
|
||||||
class IDBRequest;
|
class IDBRequest;
|
||||||
class IndexedDBDatabaseChild;
|
class IndexMetadata;
|
||||||
class IndexedDBTransactionChild;
|
class ObjectStoreSpec;
|
||||||
class IndexedDBTransactionParent;
|
class OpenCursorParams;
|
||||||
struct ObjectStoreInfo;
|
class PBackgroundIDBDatabaseFileChild;
|
||||||
class TransactionThreadPool;
|
class RequestParams;
|
||||||
class UpdateRefcountFunction;
|
|
||||||
|
|
||||||
class IDBTransactionListener
|
class IDBTransaction MOZ_FINAL
|
||||||
|
: public IDBWrapperCache
|
||||||
|
, public nsIRunnable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_IMETHOD_(MozExternalRefCountType) AddRef() = 0;
|
|
||||||
NS_IMETHOD_(MozExternalRefCountType) Release() = 0;
|
|
||||||
|
|
||||||
// Called just before dispatching the final events on the transaction.
|
|
||||||
virtual nsresult NotifyTransactionPreComplete(IDBTransaction* aTransaction) = 0;
|
|
||||||
// Called just after dispatching the final events on the transaction.
|
|
||||||
virtual nsresult NotifyTransactionPostComplete(IDBTransaction* aTransaction) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class IDBTransaction : public IDBWrapperCache,
|
|
||||||
public nsIRunnable
|
|
||||||
{
|
|
||||||
friend class AsyncConnectionHelper;
|
|
||||||
friend class CommitHelper;
|
|
||||||
friend class IndexedDBDatabaseChild;
|
|
||||||
friend class ThreadObserver;
|
|
||||||
friend class TransactionThreadPool;
|
|
||||||
|
|
||||||
public:
|
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
|
||||||
NS_DECL_NSIRUNNABLE
|
|
||||||
|
|
||||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBTransaction, IDBWrapperCache)
|
|
||||||
|
|
||||||
enum Mode
|
enum Mode
|
||||||
{
|
{
|
||||||
READ_ONLY = 0,
|
READ_ONLY = 0,
|
||||||
|
@ -91,156 +68,184 @@ public:
|
||||||
DONE
|
DONE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsRefPtr<IDBDatabase> mDatabase;
|
||||||
|
nsRefPtr<DOMError> mError;
|
||||||
|
nsTArray<nsString> mObjectStoreNames;
|
||||||
|
nsTArray<nsRefPtr<IDBObjectStore>> mObjectStores;
|
||||||
|
nsTArray<nsRefPtr<IDBObjectStore>> mDeletedObjectStores;
|
||||||
|
|
||||||
|
// Tagged with mMode. If mMode is VERSION_CHANGE then mBackgroundActor will be
|
||||||
|
// a BackgroundVersionChangeTransactionChild. Otherwise it will be a
|
||||||
|
// BackgroundTransactionChild.
|
||||||
|
union {
|
||||||
|
BackgroundTransactionChild* mNormalBackgroundActor;
|
||||||
|
BackgroundVersionChangeTransactionChild* mVersionChangeBackgroundActor;
|
||||||
|
} mBackgroundActor;
|
||||||
|
|
||||||
|
|
||||||
|
// Only used for VERSION_CHANGE transactions.
|
||||||
|
int64_t mNextObjectStoreId;
|
||||||
|
int64_t mNextIndexId;
|
||||||
|
|
||||||
|
#ifdef MOZ_ENABLE_PROFILER_SPS
|
||||||
|
uint64_t mSerialNumber;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
nsresult mAbortCode;
|
||||||
|
uint32_t mPendingRequestCount;
|
||||||
|
|
||||||
|
ReadyState mReadyState;
|
||||||
|
Mode mMode;
|
||||||
|
|
||||||
|
bool mCreating;
|
||||||
|
bool mAbortedByScript;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
bool mSentCommitOrAbort;
|
||||||
|
bool mFiredCompleteOrAbort;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public:
|
||||||
|
static already_AddRefed<IDBTransaction>
|
||||||
|
CreateVersionChange(IDBDatabase* aDatabase,
|
||||||
|
BackgroundVersionChangeTransactionChild* aActor,
|
||||||
|
int64_t aNextObjectStoreId,
|
||||||
|
int64_t aNextIndexId);
|
||||||
|
|
||||||
static already_AddRefed<IDBTransaction>
|
static already_AddRefed<IDBTransaction>
|
||||||
Create(IDBDatabase* aDatabase,
|
Create(IDBDatabase* aDatabase,
|
||||||
const Sequence<nsString>& aObjectStoreNames,
|
const nsTArray<nsString>& aObjectStoreNames,
|
||||||
Mode aMode,
|
Mode aMode);
|
||||||
bool aDispatchDelayed)
|
|
||||||
|
static IDBTransaction*
|
||||||
|
GetCurrent();
|
||||||
|
|
||||||
|
void
|
||||||
|
AssertIsOnOwningThread() const
|
||||||
|
#ifdef DEBUG
|
||||||
|
;
|
||||||
|
#else
|
||||||
|
{ }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
SetBackgroundActor(BackgroundTransactionChild* aBackgroundActor);
|
||||||
|
|
||||||
|
void
|
||||||
|
ClearBackgroundActor()
|
||||||
{
|
{
|
||||||
return CreateInternal(aDatabase, aObjectStoreNames, aMode, aDispatchDelayed,
|
AssertIsOnOwningThread();
|
||||||
false);
|
|
||||||
|
if (mMode == VERSION_CHANGE) {
|
||||||
|
mBackgroundActor.mVersionChangeBackgroundActor = nullptr;
|
||||||
|
} else {
|
||||||
|
mBackgroundActor.mNormalBackgroundActor = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// nsIDOMEventTarget
|
void
|
||||||
virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
|
StartRequest(BackgroundRequestChild* aBackgroundActor,
|
||||||
|
const RequestParams& aParams);
|
||||||
|
|
||||||
void OnNewRequest();
|
void
|
||||||
void OnRequestFinished();
|
OpenCursor(BackgroundCursorChild* aBackgroundActor,
|
||||||
void OnRequestDisconnected();
|
const OpenCursorParams& aParams);
|
||||||
|
|
||||||
void RemoveObjectStore(const nsAString& aName);
|
void
|
||||||
|
RefreshSpec(bool aMayDelete);
|
||||||
|
|
||||||
void SetTransactionListener(IDBTransactionListener* aListener);
|
void
|
||||||
|
OnNewRequest();
|
||||||
|
|
||||||
bool StartSavepoint();
|
void
|
||||||
nsresult ReleaseSavepoint();
|
OnRequestFinished();
|
||||||
void RollbackSavepoint();
|
|
||||||
|
|
||||||
// Only meant to be called on mStorageThread!
|
bool
|
||||||
nsresult GetOrCreateConnection(mozIStorageConnection** aConnection);
|
IsOpen() const;
|
||||||
|
|
||||||
already_AddRefed<mozIStorageStatement>
|
bool
|
||||||
GetCachedStatement(const nsACString& aQuery);
|
IsFinished() const
|
||||||
|
|
||||||
template<int N>
|
|
||||||
already_AddRefed<mozIStorageStatement>
|
|
||||||
GetCachedStatement(const char (&aQuery)[N])
|
|
||||||
{
|
|
||||||
return GetCachedStatement(NS_LITERAL_CSTRING(aQuery));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsOpen() const;
|
|
||||||
|
|
||||||
bool IsFinished() const
|
|
||||||
{
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
return mReadyState > LOADING;
|
return mReadyState > LOADING;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsWriteAllowed() const
|
bool
|
||||||
|
IsWriteAllowed() const
|
||||||
{
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
return mMode == READ_WRITE || mMode == VERSION_CHANGE;
|
return mMode == READ_WRITE || mMode == VERSION_CHANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsAborted() const
|
bool
|
||||||
|
IsAborted() const
|
||||||
{
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
return NS_FAILED(mAbortCode);
|
return NS_FAILED(mAbortCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 'Get' prefix is to avoid name collisions with the enum
|
// 'Get' prefix is to avoid name collisions with the enum
|
||||||
Mode GetMode()
|
Mode
|
||||||
|
GetMode() const
|
||||||
{
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
return mMode;
|
return mMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
IDBDatabase* Database()
|
IDBDatabase*
|
||||||
|
Database() const
|
||||||
{
|
{
|
||||||
NS_ASSERTION(mDatabase, "This should never be null!");
|
AssertIsOnOwningThread();
|
||||||
return mDatabase;
|
return mDatabase;
|
||||||
}
|
}
|
||||||
|
|
||||||
DatabaseInfo* DBInfo() const
|
|
||||||
{
|
|
||||||
return mDatabaseInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<IDBObjectStore>
|
|
||||||
GetOrCreateObjectStore(const nsAString& aName,
|
|
||||||
ObjectStoreInfo* aObjectStoreInfo,
|
|
||||||
bool aCreating);
|
|
||||||
|
|
||||||
already_AddRefed<FileInfo> GetFileInfo(nsIDOMBlob* aBlob);
|
|
||||||
void AddFileInfo(nsIDOMBlob* aBlob, FileInfo* aFileInfo);
|
|
||||||
|
|
||||||
void ClearCreatedFileInfos();
|
|
||||||
|
|
||||||
void
|
|
||||||
SetActor(IndexedDBTransactionChild* aActorChild)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(!aActorChild || !mActorChild, "Shouldn't have more than one!");
|
|
||||||
mActorChild = aActorChild;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SetActor(IndexedDBTransactionParent* aActorParent)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(!aActorParent || !mActorParent,
|
|
||||||
"Shouldn't have more than one!");
|
|
||||||
mActorParent = aActorParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexedDBTransactionChild*
|
|
||||||
GetActorChild() const
|
|
||||||
{
|
|
||||||
return mActorChild;
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexedDBTransactionParent*
|
|
||||||
GetActorParent() const
|
|
||||||
{
|
|
||||||
return mActorParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
Abort(IDBRequest* aRequest);
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
Abort(nsresult aAbortCode);
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
GetAbortCode() const
|
|
||||||
{
|
|
||||||
return mAbortCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef MOZ_ENABLE_PROFILER_SPS
|
|
||||||
uint64_t
|
|
||||||
GetSerialNumber() const
|
|
||||||
{
|
|
||||||
return mSerialNumber;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// nsWrapperCache
|
|
||||||
virtual JSObject*
|
|
||||||
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
// WebIDL
|
|
||||||
nsPIDOMWindow*
|
|
||||||
GetParentObject() const
|
|
||||||
{
|
|
||||||
return GetOwner();
|
|
||||||
}
|
|
||||||
|
|
||||||
IDBTransactionMode
|
|
||||||
GetMode(ErrorResult& aRv) const;
|
|
||||||
|
|
||||||
IDBDatabase*
|
IDBDatabase*
|
||||||
Db() const
|
Db() const
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
return Database();
|
||||||
return mDatabase;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const nsTArray<nsString>&
|
||||||
|
ObjectStoreNamesInternal() const
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
return mObjectStoreNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<IDBObjectStore>
|
||||||
|
CreateObjectStore(const ObjectStoreSpec& aSpec);
|
||||||
|
|
||||||
|
void
|
||||||
|
DeleteObjectStore(int64_t aObjectStoreId);
|
||||||
|
|
||||||
|
void
|
||||||
|
CreateIndex(IDBObjectStore* aObjectStore, const IndexMetadata& aMetadata);
|
||||||
|
|
||||||
|
void
|
||||||
|
DeleteIndex(IDBObjectStore* aObjectStore, int64_t aIndexId);
|
||||||
|
|
||||||
|
void
|
||||||
|
Abort(IDBRequest* aRequest);
|
||||||
|
|
||||||
|
void
|
||||||
|
Abort(nsresult aAbortCode);
|
||||||
|
|
||||||
|
#ifdef MOZ_ENABLE_PROFILER_SPS
|
||||||
|
uint32_t
|
||||||
|
GetSerialNumber() const
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
return mSerialNumber;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
nsPIDOMWindow*
|
||||||
|
GetParentObject() const;
|
||||||
|
|
||||||
|
IDBTransactionMode
|
||||||
|
GetMode(ErrorResult& aRv) const;
|
||||||
|
|
||||||
DOMError*
|
DOMError*
|
||||||
GetError() const;
|
GetError() const;
|
||||||
|
|
||||||
|
@ -248,255 +253,56 @@ public:
|
||||||
ObjectStore(const nsAString& aName, ErrorResult& aRv);
|
ObjectStore(const nsAString& aName, ErrorResult& aRv);
|
||||||
|
|
||||||
void
|
void
|
||||||
Abort(ErrorResult& aRv)
|
Abort(ErrorResult& aRv);
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
aRv = AbortInternal(NS_ERROR_DOM_INDEXEDDB_ABORT_ERR, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
IMPL_EVENT_HANDLER(abort)
|
IMPL_EVENT_HANDLER(abort)
|
||||||
IMPL_EVENT_HANDLER(complete)
|
IMPL_EVENT_HANDLER(complete)
|
||||||
IMPL_EVENT_HANDLER(error)
|
IMPL_EVENT_HANDLER(error)
|
||||||
|
|
||||||
already_AddRefed<DOMStringList>
|
already_AddRefed<DOMStringList>
|
||||||
GetObjectStoreNames(ErrorResult& aRv);
|
ObjectStoreNames();
|
||||||
|
|
||||||
|
void
|
||||||
|
FireCompleteOrAbortEvents(nsresult aResult);
|
||||||
|
|
||||||
|
// Only for VERSION_CHANGE transactions.
|
||||||
|
int64_t
|
||||||
|
NextObjectStoreId();
|
||||||
|
|
||||||
|
// Only for VERSION_CHANGE transactions.
|
||||||
|
int64_t
|
||||||
|
NextIndexId();
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
NS_DECL_NSIRUNNABLE
|
||||||
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBTransaction, IDBWrapperCache)
|
||||||
|
|
||||||
|
// nsWrapperCache
|
||||||
|
virtual JSObject*
|
||||||
|
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
// nsIDOMEventTarget
|
||||||
|
virtual nsresult
|
||||||
|
PreHandleEvent(EventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsresult
|
IDBTransaction(IDBDatabase* aDatabase,
|
||||||
AbortInternal(nsresult aAbortCode,
|
const nsTArray<nsString>& aObjectStoreNames,
|
||||||
already_AddRefed<mozilla::dom::DOMError> aError);
|
Mode aMode);
|
||||||
|
|
||||||
// Should only be called directly through IndexedDBDatabaseChild.
|
|
||||||
static already_AddRefed<IDBTransaction>
|
|
||||||
CreateInternal(IDBDatabase* aDatabase,
|
|
||||||
const Sequence<nsString>& aObjectStoreNames,
|
|
||||||
Mode aMode,
|
|
||||||
bool aDispatchDelayed,
|
|
||||||
bool aIsVersionChangeTransactionChild);
|
|
||||||
|
|
||||||
explicit IDBTransaction(IDBDatabase* aDatabase);
|
|
||||||
~IDBTransaction();
|
~IDBTransaction();
|
||||||
|
|
||||||
nsresult CommitOrRollback();
|
void
|
||||||
|
AbortInternal(nsresult aAbortCode, already_AddRefed<DOMError> aError);
|
||||||
|
|
||||||
nsRefPtr<IDBDatabase> mDatabase;
|
void
|
||||||
nsRefPtr<DatabaseInfo> mDatabaseInfo;
|
SendCommit();
|
||||||
nsRefPtr<DOMError> mError;
|
|
||||||
nsTArray<nsString> mObjectStoreNames;
|
|
||||||
ReadyState mReadyState;
|
|
||||||
Mode mMode;
|
|
||||||
uint32_t mPendingRequests;
|
|
||||||
|
|
||||||
nsInterfaceHashtable<nsCStringHashKey, mozIStorageStatement>
|
void
|
||||||
mCachedStatements;
|
SendAbort(nsresult aResultCode);
|
||||||
|
|
||||||
nsRefPtr<IDBTransactionListener> mListener;
|
|
||||||
|
|
||||||
// Only touched on the database thread.
|
|
||||||
nsCOMPtr<mozIStorageConnection> mConnection;
|
|
||||||
|
|
||||||
// Only touched on the database thread.
|
|
||||||
uint32_t mSavepointCount;
|
|
||||||
|
|
||||||
nsTArray<nsRefPtr<IDBObjectStore> > mCreatedObjectStores;
|
|
||||||
nsTArray<nsRefPtr<IDBObjectStore> > mDeletedObjectStores;
|
|
||||||
|
|
||||||
nsRefPtr<UpdateRefcountFunction> mUpdateFileRefcountFunction;
|
|
||||||
nsRefPtrHashtable<nsISupportsHashKey, FileInfo> mCreatedFileInfos;
|
|
||||||
|
|
||||||
IndexedDBTransactionChild* mActorChild;
|
|
||||||
IndexedDBTransactionParent* mActorParent;
|
|
||||||
|
|
||||||
nsresult mAbortCode;
|
|
||||||
#ifdef MOZ_ENABLE_PROFILER_SPS
|
|
||||||
uint64_t mSerialNumber;
|
|
||||||
#endif
|
|
||||||
bool mCreating;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
bool mFiredCompleteOrAbort;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CommitHelper MOZ_FINAL : public nsIRunnable
|
} // namespace indexedDB
|
||||||
{
|
} // namespace dom
|
||||||
public:
|
} // namespace mozilla
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
|
||||||
NS_DECL_NSIRUNNABLE
|
|
||||||
|
|
||||||
CommitHelper(IDBTransaction* aTransaction,
|
|
||||||
IDBTransactionListener* aListener,
|
|
||||||
const nsTArray<nsRefPtr<IDBObjectStore> >& mUpdatedObjectStores);
|
|
||||||
CommitHelper(IDBTransaction* aTransaction,
|
|
||||||
nsresult aAbortCode);
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
bool AddDoomedObject(nsCOMPtr<T>& aCOMPtr)
|
|
||||||
{
|
|
||||||
if (aCOMPtr) {
|
|
||||||
if (!mDoomedObjects.AppendElement(do_QueryInterface(aCOMPtr))) {
|
|
||||||
NS_ERROR("Out of memory!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
aCOMPtr = nullptr;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
~CommitHelper();
|
|
||||||
|
|
||||||
// Writes new autoincrement counts to database
|
|
||||||
nsresult WriteAutoIncrementCounts();
|
|
||||||
|
|
||||||
// Updates counts after a successful commit
|
|
||||||
void CommitAutoIncrementCounts();
|
|
||||||
|
|
||||||
// Reverts counts when a transaction is aborted
|
|
||||||
void RevertAutoIncrementCounts();
|
|
||||||
|
|
||||||
nsRefPtr<IDBTransaction> mTransaction;
|
|
||||||
nsRefPtr<IDBTransactionListener> mListener;
|
|
||||||
nsCOMPtr<mozIStorageConnection> mConnection;
|
|
||||||
nsRefPtr<UpdateRefcountFunction> mUpdateFileRefcountFunction;
|
|
||||||
nsAutoTArray<nsCOMPtr<nsISupports>, 10> mDoomedObjects;
|
|
||||||
nsAutoTArray<nsRefPtr<IDBObjectStore>, 10> mAutoIncrementObjectStores;
|
|
||||||
|
|
||||||
nsresult mAbortCode;
|
|
||||||
};
|
|
||||||
|
|
||||||
class UpdateRefcountFunction MOZ_FINAL : public mozIStorageFunction
|
|
||||||
{
|
|
||||||
~UpdateRefcountFunction()
|
|
||||||
{ }
|
|
||||||
|
|
||||||
public:
|
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
|
||||||
NS_DECL_MOZISTORAGEFUNCTION
|
|
||||||
|
|
||||||
explicit UpdateRefcountFunction(FileManager* aFileManager)
|
|
||||||
: mFileManager(aFileManager), mInSavepoint(false)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
void StartSavepoint()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(!mInSavepoint);
|
|
||||||
MOZ_ASSERT(!mSavepointEntriesIndex.Count());
|
|
||||||
|
|
||||||
mInSavepoint = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReleaseSavepoint()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(mInSavepoint);
|
|
||||||
|
|
||||||
mSavepointEntriesIndex.Clear();
|
|
||||||
|
|
||||||
mInSavepoint = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RollbackSavepoint()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(mInSavepoint);
|
|
||||||
|
|
||||||
mInSavepoint = false;
|
|
||||||
|
|
||||||
mSavepointEntriesIndex.EnumerateRead(RollbackSavepointCallback, nullptr);
|
|
||||||
|
|
||||||
mSavepointEntriesIndex.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClearFileInfoEntries()
|
|
||||||
{
|
|
||||||
mFileInfoEntries.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult WillCommit(mozIStorageConnection* aConnection);
|
|
||||||
void DidCommit();
|
|
||||||
void DidAbort();
|
|
||||||
|
|
||||||
private:
|
|
||||||
class FileInfoEntry
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit FileInfoEntry(FileInfo* aFileInfo)
|
|
||||||
: mFileInfo(aFileInfo), mDelta(0), mSavepointDelta(0)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
~FileInfoEntry()
|
|
||||||
{ }
|
|
||||||
|
|
||||||
nsRefPtr<FileInfo> mFileInfo;
|
|
||||||
int32_t mDelta;
|
|
||||||
int32_t mSavepointDelta;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum UpdateType {
|
|
||||||
eIncrement,
|
|
||||||
eDecrement
|
|
||||||
};
|
|
||||||
|
|
||||||
class DatabaseUpdateFunction
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
DatabaseUpdateFunction(mozIStorageConnection* aConnection,
|
|
||||||
UpdateRefcountFunction* aFunction)
|
|
||||||
: mConnection(aConnection), mFunction(aFunction), mErrorCode(NS_OK)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
bool Update(int64_t aId, int32_t aDelta);
|
|
||||||
nsresult ErrorCode()
|
|
||||||
{
|
|
||||||
return mErrorCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
nsresult UpdateInternal(int64_t aId, int32_t aDelta);
|
|
||||||
|
|
||||||
nsCOMPtr<mozIStorageConnection> mConnection;
|
|
||||||
nsCOMPtr<mozIStorageStatement> mUpdateStatement;
|
|
||||||
nsCOMPtr<mozIStorageStatement> mSelectStatement;
|
|
||||||
nsCOMPtr<mozIStorageStatement> mInsertStatement;
|
|
||||||
|
|
||||||
UpdateRefcountFunction* mFunction;
|
|
||||||
|
|
||||||
nsresult mErrorCode;
|
|
||||||
};
|
|
||||||
|
|
||||||
nsresult ProcessValue(mozIStorageValueArray* aValues,
|
|
||||||
int32_t aIndex,
|
|
||||||
UpdateType aUpdateType);
|
|
||||||
|
|
||||||
nsresult CreateJournals();
|
|
||||||
|
|
||||||
nsresult RemoveJournals(const nsTArray<int64_t>& aJournals);
|
|
||||||
|
|
||||||
static PLDHashOperator
|
|
||||||
DatabaseUpdateCallback(const uint64_t& aKey,
|
|
||||||
FileInfoEntry* aValue,
|
|
||||||
void* aUserArg);
|
|
||||||
|
|
||||||
static PLDHashOperator
|
|
||||||
FileInfoUpdateCallback(const uint64_t& aKey,
|
|
||||||
FileInfoEntry* aValue,
|
|
||||||
void* aUserArg);
|
|
||||||
|
|
||||||
static PLDHashOperator
|
|
||||||
RollbackSavepointCallback(const uint64_t& aKey,
|
|
||||||
FileInfoEntry* aValue,
|
|
||||||
void* aUserArg);
|
|
||||||
|
|
||||||
FileManager* mFileManager;
|
|
||||||
nsClassHashtable<nsUint64HashKey, FileInfoEntry> mFileInfoEntries;
|
|
||||||
nsDataHashtable<nsUint64HashKey, FileInfoEntry*> mSavepointEntriesIndex;
|
|
||||||
|
|
||||||
nsTArray<int64_t> mJournalsToCreateBeforeCommit;
|
|
||||||
nsTArray<int64_t> mJournalsToRemoveAfterCommit;
|
|
||||||
nsTArray<int64_t> mJournalsToRemoveAfterAbort;
|
|
||||||
|
|
||||||
bool mInSavepoint;
|
|
||||||
};
|
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
|
||||||
|
|
||||||
#endif // mozilla_dom_indexeddb_idbtransaction_h__
|
#endif // mozilla_dom_indexeddb_idbtransaction_h__
|
||||||
|
|
|
@ -5,9 +5,19 @@
|
||||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "IDBWrapperCache.h"
|
#include "IDBWrapperCache.h"
|
||||||
#include "nsCycleCollector.h"
|
|
||||||
|
|
||||||
USING_INDEXEDDB_NAMESPACE
|
#include "mozilla/HoldDropJSObjects.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsIScriptGlobalObject.h"
|
||||||
|
#include "nsPIDOMWindow.h"
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#include "nsCycleCollector.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
namespace indexedDB {
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBWrapperCache)
|
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBWrapperCache)
|
||||||
|
|
||||||
|
@ -38,6 +48,14 @@ NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
||||||
NS_IMPL_ADDREF_INHERITED(IDBWrapperCache, DOMEventTargetHelper)
|
NS_IMPL_ADDREF_INHERITED(IDBWrapperCache, DOMEventTargetHelper)
|
||||||
NS_IMPL_RELEASE_INHERITED(IDBWrapperCache, DOMEventTargetHelper)
|
NS_IMPL_RELEASE_INHERITED(IDBWrapperCache, DOMEventTargetHelper)
|
||||||
|
|
||||||
|
IDBWrapperCache::IDBWrapperCache(DOMEventTargetHelper* aOwner)
|
||||||
|
: DOMEventTargetHelper(aOwner), mScriptOwner(nullptr)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
IDBWrapperCache::IDBWrapperCache(nsPIDOMWindow* aOwner)
|
||||||
|
: DOMEventTargetHelper(aOwner), mScriptOwner(nullptr)
|
||||||
|
{ }
|
||||||
|
|
||||||
IDBWrapperCache::~IDBWrapperCache()
|
IDBWrapperCache::~IDBWrapperCache()
|
||||||
{
|
{
|
||||||
mScriptOwner = nullptr;
|
mScriptOwner = nullptr;
|
||||||
|
@ -48,7 +66,7 @@ IDBWrapperCache::~IDBWrapperCache()
|
||||||
void
|
void
|
||||||
IDBWrapperCache::SetScriptOwner(JSObject* aScriptOwner)
|
IDBWrapperCache::SetScriptOwner(JSObject* aScriptOwner)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(aScriptOwner, "This should never be null!");
|
MOZ_ASSERT(aScriptOwner);
|
||||||
|
|
||||||
mScriptOwner = aScriptOwner;
|
mScriptOwner = aScriptOwner;
|
||||||
mozilla::HoldJSObjects(this);
|
mozilla::HoldJSObjects(this);
|
||||||
|
@ -62,3 +80,7 @@ IDBWrapperCache::AssertIsRooted() const
|
||||||
"Why aren't we rooted?!");
|
"Why aren't we rooted?!");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
} // namespace indexedDB
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
|
@ -7,47 +7,51 @@
|
||||||
#ifndef mozilla_dom_indexeddb_idbwrappercache_h__
|
#ifndef mozilla_dom_indexeddb_idbwrappercache_h__
|
||||||
#define mozilla_dom_indexeddb_idbwrappercache_h__
|
#define mozilla_dom_indexeddb_idbwrappercache_h__
|
||||||
|
|
||||||
|
#include "js/RootingAPI.h"
|
||||||
#include "mozilla/DOMEventTargetHelper.h"
|
#include "mozilla/DOMEventTargetHelper.h"
|
||||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
#include "nsCycleCollectionParticipant.h"
|
||||||
|
#include "nsWrapperCache.h"
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
class nsPIDOMWindow;
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
namespace indexedDB {
|
||||||
|
|
||||||
class IDBWrapperCache : public DOMEventTargetHelper
|
class IDBWrapperCache : public DOMEventTargetHelper
|
||||||
{
|
{
|
||||||
|
JS::Heap<JSObject*> mScriptOwner;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(IDBWrapperCache,
|
||||||
IDBWrapperCache,
|
DOMEventTargetHelper)
|
||||||
DOMEventTargetHelper)
|
|
||||||
|
|
||||||
JSObject* GetScriptOwner() const
|
JSObject*
|
||||||
|
GetScriptOwner() const
|
||||||
{
|
{
|
||||||
return mScriptOwner;
|
return mScriptOwner;
|
||||||
}
|
}
|
||||||
void SetScriptOwner(JSObject* aScriptOwner);
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SetScriptOwner(JSObject* aScriptOwner);
|
||||||
|
|
||||||
|
void AssertIsRooted() const
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void AssertIsRooted() const;
|
;
|
||||||
#else
|
#else
|
||||||
inline void AssertIsRooted() const
|
{ }
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit IDBWrapperCache(DOMEventTargetHelper* aOwner)
|
explicit IDBWrapperCache(DOMEventTargetHelper* aOwner);
|
||||||
: DOMEventTargetHelper(aOwner), mScriptOwner(nullptr)
|
explicit IDBWrapperCache(nsPIDOMWindow* aOwner);
|
||||||
{ }
|
|
||||||
explicit IDBWrapperCache(nsPIDOMWindow* aOwner)
|
|
||||||
: DOMEventTargetHelper(aOwner), mScriptOwner(nullptr)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual ~IDBWrapperCache();
|
virtual ~IDBWrapperCache();
|
||||||
|
|
||||||
private:
|
|
||||||
JS::Heap<JSObject*> mScriptOwner;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
} // namespace indexedDB
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif // mozilla_dom_indexeddb_idbwrappercache_h__
|
#endif // mozilla_dom_indexeddb_idbwrappercache_h__
|
||||||
|
|
|
@ -9,148 +9,70 @@
|
||||||
|
|
||||||
#include "nsIProgrammingLanguage.h"
|
#include "nsIProgrammingLanguage.h"
|
||||||
|
|
||||||
#include "mozilla/Attributes.h"
|
|
||||||
#include "js/StructuredClone.h"
|
#include "js/StructuredClone.h"
|
||||||
#include "nsAutoPtr.h"
|
#include "nsAutoPtr.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsDebug.h"
|
|
||||||
#include "nsError.h"
|
|
||||||
#include "nsString.h"
|
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
#include "nsIInputStream.h"
|
|
||||||
|
|
||||||
#define BEGIN_INDEXEDDB_NAMESPACE \
|
|
||||||
namespace mozilla { namespace dom { namespace indexedDB {
|
|
||||||
|
|
||||||
#define END_INDEXEDDB_NAMESPACE \
|
|
||||||
} /* namespace indexedDB */ } /* namepsace dom */ } /* namespace mozilla */
|
|
||||||
|
|
||||||
#define USING_INDEXEDDB_NAMESPACE \
|
|
||||||
using namespace mozilla::dom::indexedDB;
|
|
||||||
|
|
||||||
class nsIDOMBlob;
|
class nsIDOMBlob;
|
||||||
|
class nsIInputStream;
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
namespace indexedDB {
|
||||||
|
|
||||||
class FileInfo;
|
class FileInfo;
|
||||||
class IDBDatabase;
|
class IDBDatabase;
|
||||||
class IDBTransaction;
|
class IDBTransaction;
|
||||||
|
class SerializedStructuredCloneReadInfo;
|
||||||
|
class SerializedStructuredCloneWriteInfo;
|
||||||
|
|
||||||
struct StructuredCloneFile
|
struct StructuredCloneFile
|
||||||
{
|
{
|
||||||
bool operator==(const StructuredCloneFile& aOther) const
|
|
||||||
{
|
|
||||||
return this->mFile == aOther.mFile &&
|
|
||||||
this->mFileInfo == aOther.mFileInfo &&
|
|
||||||
this->mInputStream == aOther.mInputStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMBlob> mFile;
|
nsCOMPtr<nsIDOMBlob> mFile;
|
||||||
nsRefPtr<FileInfo> mFileInfo;
|
nsRefPtr<FileInfo> mFileInfo;
|
||||||
nsCOMPtr<nsIInputStream> mInputStream;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SerializedStructuredCloneReadInfo;
|
// In IndexedDatabaseInlines.h
|
||||||
|
inline
|
||||||
|
StructuredCloneFile();
|
||||||
|
|
||||||
|
// In IndexedDatabaseInlines.h
|
||||||
|
inline
|
||||||
|
~StructuredCloneFile();
|
||||||
|
|
||||||
|
// In IndexedDatabaseInlines.h
|
||||||
|
inline bool
|
||||||
|
operator==(const StructuredCloneFile& aOther) const;
|
||||||
|
};
|
||||||
|
|
||||||
struct StructuredCloneReadInfo
|
struct StructuredCloneReadInfo
|
||||||
{
|
{
|
||||||
// In IndexedDatabaseInlines.h
|
nsTArray<uint8_t> mData;
|
||||||
inline StructuredCloneReadInfo();
|
|
||||||
|
|
||||||
inline StructuredCloneReadInfo&
|
|
||||||
operator=(StructuredCloneReadInfo&& aCloneReadInfo);
|
|
||||||
|
|
||||||
// In IndexedDatabaseInlines.h
|
|
||||||
inline bool
|
|
||||||
SetFromSerialized(const SerializedStructuredCloneReadInfo& aOther);
|
|
||||||
|
|
||||||
JSAutoStructuredCloneBuffer mCloneBuffer;
|
|
||||||
nsTArray<StructuredCloneFile> mFiles;
|
nsTArray<StructuredCloneFile> mFiles;
|
||||||
IDBDatabase* mDatabase;
|
IDBDatabase* mDatabase;
|
||||||
};
|
|
||||||
|
|
||||||
struct SerializedStructuredCloneReadInfo
|
|
||||||
{
|
|
||||||
SerializedStructuredCloneReadInfo()
|
|
||||||
: data(nullptr), dataLength(0)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
bool
|
|
||||||
operator==(const SerializedStructuredCloneReadInfo& aOther) const
|
|
||||||
{
|
|
||||||
return this->data == aOther.data &&
|
|
||||||
this->dataLength == aOther.dataLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
SerializedStructuredCloneReadInfo&
|
|
||||||
operator=(const StructuredCloneReadInfo& aOther)
|
|
||||||
{
|
|
||||||
data = aOther.mCloneBuffer.data();
|
|
||||||
dataLength = aOther.mCloneBuffer.nbytes();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure to update ipc/SerializationHelpers.h when changing members here!
|
|
||||||
uint64_t* data;
|
|
||||||
size_t dataLength;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SerializedStructuredCloneWriteInfo;
|
|
||||||
|
|
||||||
struct StructuredCloneWriteInfo
|
|
||||||
{
|
|
||||||
// In IndexedDatabaseInlines.h
|
|
||||||
inline StructuredCloneWriteInfo();
|
|
||||||
inline StructuredCloneWriteInfo(StructuredCloneWriteInfo&& aCloneWriteInfo);
|
|
||||||
|
|
||||||
bool operator==(const StructuredCloneWriteInfo& aOther) const
|
|
||||||
{
|
|
||||||
return this->mCloneBuffer.nbytes() == aOther.mCloneBuffer.nbytes() &&
|
|
||||||
this->mCloneBuffer.data() == aOther.mCloneBuffer.data() &&
|
|
||||||
this->mFiles == aOther.mFiles &&
|
|
||||||
this->mTransaction == aOther.mTransaction &&
|
|
||||||
this->mOffsetToKeyProp == aOther.mOffsetToKeyProp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// In IndexedDatabaseInlines.h
|
|
||||||
inline bool
|
|
||||||
SetFromSerialized(const SerializedStructuredCloneWriteInfo& aOther);
|
|
||||||
|
|
||||||
|
// XXX Remove!
|
||||||
JSAutoStructuredCloneBuffer mCloneBuffer;
|
JSAutoStructuredCloneBuffer mCloneBuffer;
|
||||||
nsTArray<StructuredCloneFile> mFiles;
|
|
||||||
IDBTransaction* mTransaction;
|
// In IndexedDatabaseInlines.h
|
||||||
uint64_t mOffsetToKeyProp;
|
inline
|
||||||
|
StructuredCloneReadInfo();
|
||||||
|
|
||||||
|
// In IndexedDatabaseInlines.h
|
||||||
|
inline
|
||||||
|
~StructuredCloneReadInfo();
|
||||||
|
|
||||||
|
// In IndexedDatabaseInlines.h
|
||||||
|
inline StructuredCloneReadInfo&
|
||||||
|
operator=(StructuredCloneReadInfo&& aOther);
|
||||||
|
|
||||||
|
// In IndexedDatabaseInlines.h
|
||||||
|
inline
|
||||||
|
StructuredCloneReadInfo(SerializedStructuredCloneReadInfo&& aOther);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SerializedStructuredCloneWriteInfo
|
} // namespace indexedDB
|
||||||
{
|
} // namespace dom
|
||||||
SerializedStructuredCloneWriteInfo()
|
} // namespace mozilla
|
||||||
: data(nullptr), dataLength(0), offsetToKeyProp(0)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
bool
|
|
||||||
operator==(const SerializedStructuredCloneWriteInfo& aOther) const
|
|
||||||
{
|
|
||||||
return this->data == aOther.data &&
|
|
||||||
this->dataLength == aOther.dataLength &&
|
|
||||||
this->offsetToKeyProp == aOther.offsetToKeyProp;
|
|
||||||
}
|
|
||||||
|
|
||||||
SerializedStructuredCloneWriteInfo&
|
|
||||||
operator=(const StructuredCloneWriteInfo& aOther)
|
|
||||||
{
|
|
||||||
data = aOther.mCloneBuffer.data();
|
|
||||||
dataLength = aOther.mCloneBuffer.nbytes();
|
|
||||||
offsetToKeyProp = aOther.mOffsetToKeyProp;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure to update ipc/SerializationHelpers.h when changing members here!
|
|
||||||
uint64_t* data;
|
|
||||||
size_t dataLength;
|
|
||||||
uint64_t offsetToKeyProp;
|
|
||||||
};
|
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
|
||||||
|
|
||||||
#endif // mozilla_dom_indexeddb_indexeddatabase_h__
|
#endif // mozilla_dom_indexeddb_indexeddatabase_h__
|
||||||
|
|
|
@ -11,48 +11,55 @@
|
||||||
#error Must include IndexedDatabase.h first
|
#error Must include IndexedDatabase.h first
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
#include "FileInfo.h"
|
||||||
|
#include "mozilla/dom/indexedDB/PBackgroundIDBSharedTypes.h"
|
||||||
|
#include "nsIDOMFile.h"
|
||||||
|
#include "nsIInputStream.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
namespace indexedDB {
|
||||||
|
|
||||||
inline
|
inline
|
||||||
StructuredCloneWriteInfo::StructuredCloneWriteInfo()
|
StructuredCloneFile::StructuredCloneFile()
|
||||||
: mTransaction(nullptr),
|
|
||||||
mOffsetToKeyProp(0)
|
|
||||||
{
|
{
|
||||||
|
MOZ_COUNT_CTOR(StructuredCloneFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
StructuredCloneWriteInfo::StructuredCloneWriteInfo(
|
StructuredCloneFile::~StructuredCloneFile()
|
||||||
StructuredCloneWriteInfo&& aCloneWriteInfo)
|
|
||||||
: mCloneBuffer(Move(aCloneWriteInfo.mCloneBuffer))
|
|
||||||
, mTransaction(aCloneWriteInfo.mTransaction)
|
|
||||||
, mOffsetToKeyProp(aCloneWriteInfo.mOffsetToKeyProp)
|
|
||||||
{
|
{
|
||||||
mFiles.SwapElements(aCloneWriteInfo.mFiles);
|
MOZ_COUNT_DTOR(StructuredCloneFile);
|
||||||
aCloneWriteInfo.mTransaction = nullptr;
|
|
||||||
aCloneWriteInfo.mOffsetToKeyProp = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
StructuredCloneWriteInfo::SetFromSerialized(
|
StructuredCloneFile::operator==(const StructuredCloneFile& aOther) const
|
||||||
const SerializedStructuredCloneWriteInfo& aOther)
|
|
||||||
{
|
{
|
||||||
if (!aOther.dataLength) {
|
return this->mFile == aOther.mFile &&
|
||||||
mCloneBuffer.clear();
|
this->mFileInfo == aOther.mFileInfo;
|
||||||
}
|
|
||||||
else if (!mCloneBuffer.copy(aOther.data, aOther.dataLength)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
mFiles.Clear();
|
|
||||||
mOffsetToKeyProp = aOther.offsetToKeyProp;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
StructuredCloneReadInfo::StructuredCloneReadInfo()
|
StructuredCloneReadInfo::StructuredCloneReadInfo()
|
||||||
: mDatabase(nullptr)
|
: mDatabase(nullptr)
|
||||||
{
|
{
|
||||||
|
MOZ_COUNT_CTOR(StructuredCloneReadInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
StructuredCloneReadInfo::StructuredCloneReadInfo(
|
||||||
|
SerializedStructuredCloneReadInfo&& aCloneReadInfo)
|
||||||
|
: mData(Move(aCloneReadInfo.data()))
|
||||||
|
, mDatabase(nullptr)
|
||||||
|
{
|
||||||
|
MOZ_COUNT_CTOR(StructuredCloneReadInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
StructuredCloneReadInfo::~StructuredCloneReadInfo()
|
||||||
|
{
|
||||||
|
MOZ_COUNT_DTOR(StructuredCloneReadInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline StructuredCloneReadInfo&
|
inline StructuredCloneReadInfo&
|
||||||
|
@ -60,6 +67,7 @@ StructuredCloneReadInfo::operator=(StructuredCloneReadInfo&& aCloneReadInfo)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(&aCloneReadInfo != this);
|
MOZ_ASSERT(&aCloneReadInfo != this);
|
||||||
|
|
||||||
|
mData = Move(aCloneReadInfo.mData);
|
||||||
mCloneBuffer = Move(aCloneReadInfo.mCloneBuffer);
|
mCloneBuffer = Move(aCloneReadInfo.mCloneBuffer);
|
||||||
mFiles.Clear();
|
mFiles.Clear();
|
||||||
mFiles.SwapElements(aCloneReadInfo.mFiles);
|
mFiles.SwapElements(aCloneReadInfo.mFiles);
|
||||||
|
@ -68,45 +76,8 @@ StructuredCloneReadInfo::operator=(StructuredCloneReadInfo&& aCloneReadInfo)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
} // namespace indexedDB
|
||||||
bool
|
} // namespace dom
|
||||||
StructuredCloneReadInfo::SetFromSerialized(
|
} // namespace mozilla
|
||||||
const SerializedStructuredCloneReadInfo& aOther)
|
|
||||||
{
|
|
||||||
if (aOther.dataLength &&
|
|
||||||
!mCloneBuffer.copy(aOther.data, aOther.dataLength)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
mFiles.Clear();
|
#endif // IndexedDatabaseInlines_h
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
AppendConditionClause(const nsACString& aColumnName,
|
|
||||||
const nsACString& aArgName,
|
|
||||||
bool aLessThan,
|
|
||||||
bool aEquals,
|
|
||||||
nsACString& aResult)
|
|
||||||
{
|
|
||||||
aResult += NS_LITERAL_CSTRING(" AND ") + aColumnName +
|
|
||||||
NS_LITERAL_CSTRING(" ");
|
|
||||||
|
|
||||||
if (aLessThan) {
|
|
||||||
aResult.Append('<');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
aResult.Append('>');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aEquals) {
|
|
||||||
aResult.Append('=');
|
|
||||||
}
|
|
||||||
|
|
||||||
aResult += NS_LITERAL_CSTRING(" :") + aArgName;
|
|
||||||
}
|
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -16,12 +16,16 @@
|
||||||
#include "mozilla/ClearOnShutdown.h"
|
#include "mozilla/ClearOnShutdown.h"
|
||||||
#include "mozilla/CondVar.h"
|
#include "mozilla/CondVar.h"
|
||||||
#include "mozilla/ContentEvents.h"
|
#include "mozilla/ContentEvents.h"
|
||||||
|
#include "mozilla/dom/ContentChild.h"
|
||||||
#include "mozilla/dom/ErrorEventBinding.h"
|
#include "mozilla/dom/ErrorEventBinding.h"
|
||||||
|
#include "mozilla/dom/PBlobChild.h"
|
||||||
#include "mozilla/dom/quota/OriginOrPatternString.h"
|
#include "mozilla/dom/quota/OriginOrPatternString.h"
|
||||||
#include "mozilla/dom/quota/QuotaManager.h"
|
#include "mozilla/dom/quota/QuotaManager.h"
|
||||||
#include "mozilla/dom/quota/Utilities.h"
|
#include "mozilla/dom/quota/Utilities.h"
|
||||||
#include "mozilla/dom/TabContext.h"
|
#include "mozilla/dom/TabContext.h"
|
||||||
#include "mozilla/EventDispatcher.h"
|
#include "mozilla/EventDispatcher.h"
|
||||||
|
#include "mozilla/ipc/BackgroundChild.h"
|
||||||
|
#include "mozilla/ipc/PBackgroundChild.h"
|
||||||
#include "mozilla/Services.h"
|
#include "mozilla/Services.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "mozilla/storage.h"
|
#include "mozilla/storage.h"
|
||||||
|
@ -53,12 +57,11 @@
|
||||||
#define LOW_DISK_SPACE_DATA_FULL "full"
|
#define LOW_DISK_SPACE_DATA_FULL "full"
|
||||||
#define LOW_DISK_SPACE_DATA_FREE "free"
|
#define LOW_DISK_SPACE_DATA_FREE "free"
|
||||||
|
|
||||||
USING_INDEXEDDB_NAMESPACE
|
namespace mozilla {
|
||||||
using namespace mozilla;
|
namespace dom {
|
||||||
using namespace mozilla::dom;
|
namespace indexedDB {
|
||||||
USING_QUOTA_NAMESPACE
|
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
using namespace mozilla::dom::quota;
|
||||||
|
|
||||||
class FileManagerInfo
|
class FileManagerInfo
|
||||||
{
|
{
|
||||||
|
@ -103,14 +106,15 @@ private:
|
||||||
nsTArray<nsRefPtr<FileManager> > mTemporaryStorageFileManagers;
|
nsTArray<nsRefPtr<FileManager> > mTemporaryStorageFileManagers;
|
||||||
};
|
};
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
const char kTestingPref[] = "dom.indexedDB.testing";
|
||||||
|
|
||||||
mozilla::StaticRefPtr<IndexedDatabaseManager> gDBManager;
|
mozilla::StaticRefPtr<IndexedDatabaseManager> gDBManager;
|
||||||
|
|
||||||
mozilla::Atomic<bool> gInitialized(false);
|
mozilla::Atomic<bool> gInitialized(false);
|
||||||
mozilla::Atomic<bool> gClosed(false);
|
mozilla::Atomic<bool> gClosed(false);
|
||||||
|
mozilla::Atomic<bool> gTestingMode(false);
|
||||||
|
|
||||||
class AsyncDeleteFileRunnable MOZ_FINAL : public nsIRunnable
|
class AsyncDeleteFileRunnable MOZ_FINAL : public nsIRunnable
|
||||||
{
|
{
|
||||||
|
@ -183,6 +187,16 @@ struct MOZ_STACK_CLASS InvalidateInfo
|
||||||
const nsACString& pattern;
|
const nsACString& pattern;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
TestingPrefChangedCallback(const char* aPrefName, void* aClosure)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
MOZ_ASSERT(!strcmp(aPrefName, kTestingPref));
|
||||||
|
MOZ_ASSERT(!aClosure);
|
||||||
|
|
||||||
|
gTestingMode = Preferences::GetBool(aPrefName);
|
||||||
|
}
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
IndexedDatabaseManager::IndexedDatabaseManager()
|
IndexedDatabaseManager::IndexedDatabaseManager()
|
||||||
|
@ -281,6 +295,9 @@ IndexedDatabaseManager::Init()
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Preferences::RegisterCallbackAndCall(TestingPrefChangedCallback,
|
||||||
|
kTestingPref);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,6 +310,8 @@ IndexedDatabaseManager::Destroy()
|
||||||
NS_ERROR("Shutdown more than once?!");
|
NS_ERROR("Shutdown more than once?!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Preferences::UnregisterCallback(TestingPrefChangedCallback, kTestingPref);
|
||||||
|
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,7 +333,7 @@ IndexedDatabaseManager::FireWindowOnError(nsPIDOMWindow* aOwner,
|
||||||
nsresult rv = aVisitor.mDOMEvent->GetType(type);
|
nsresult rv = aVisitor.mDOMEvent->GetType(type);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
if (!type.EqualsLiteral(ERROR_EVT_STR)) {
|
if (nsDependentString(kErrorEventType) != type) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -425,8 +444,9 @@ IndexedDatabaseManager::DefineIndexedDB(JSContext* aCx,
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<IDBFactory> factory;
|
nsRefPtr<IDBFactory> factory;
|
||||||
if (NS_FAILED(IDBFactory::Create(aCx, aGlobal, nullptr,
|
if (NS_FAILED(IDBFactory::CreateForChromeJS(aCx,
|
||||||
getter_AddRefs(factory)))) {
|
aGlobal,
|
||||||
|
getter_AddRefs(factory)))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,6 +491,16 @@ IndexedDatabaseManager::InLowDiskSpaceMode()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool
|
||||||
|
IndexedDatabaseManager::InTestingMode()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(gDBManager,
|
||||||
|
"InTestingMode() called before indexedDB has been initialized!");
|
||||||
|
|
||||||
|
return gTestingMode;
|
||||||
|
}
|
||||||
|
|
||||||
already_AddRefed<FileManager>
|
already_AddRefed<FileManager>
|
||||||
IndexedDatabaseManager::GetFileManager(PersistenceType aPersistenceType,
|
IndexedDatabaseManager::GetFileManager(PersistenceType aPersistenceType,
|
||||||
const nsACString& aOrigin,
|
const nsACString& aOrigin,
|
||||||
|
@ -626,13 +656,38 @@ IndexedDatabaseManager::BlockAndGetFileReferences(
|
||||||
int32_t* aSliceRefCnt,
|
int32_t* aSliceRefCnt,
|
||||||
bool* aResult)
|
bool* aResult)
|
||||||
{
|
{
|
||||||
nsRefPtr<GetFileReferencesHelper> helper =
|
if (NS_WARN_IF(!InTestingMode())) {
|
||||||
new GetFileReferencesHelper(aPersistenceType, aOrigin, aDatabaseName,
|
return NS_ERROR_UNEXPECTED;
|
||||||
aFileId);
|
}
|
||||||
|
|
||||||
nsresult rv = helper->DispatchAndReturnFileReferences(aRefCnt, aDBRefCnt,
|
if (IsMainProcess()) {
|
||||||
aSliceRefCnt, aResult);
|
nsRefPtr<GetFileReferencesHelper> helper =
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
new GetFileReferencesHelper(aPersistenceType, aOrigin, aDatabaseName,
|
||||||
|
aFileId);
|
||||||
|
|
||||||
|
nsresult rv =
|
||||||
|
helper->DispatchAndReturnFileReferences(aRefCnt, aDBRefCnt,
|
||||||
|
aSliceRefCnt, aResult);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ContentChild* contentChild = ContentChild::GetSingleton();
|
||||||
|
if (NS_WARN_IF(!contentChild)) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!contentChild->SendGetFileReferences(aPersistenceType,
|
||||||
|
nsCString(aOrigin),
|
||||||
|
nsString(aDatabaseName),
|
||||||
|
aFileId,
|
||||||
|
aRefCnt,
|
||||||
|
aDBRefCnt,
|
||||||
|
aSliceRefCnt,
|
||||||
|
aResult)) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -886,3 +941,7 @@ GetFileReferencesHelper::Run()
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace indexedDB
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
#ifndef mozilla_dom_indexeddb_indexeddatabasemanager_h__
|
#ifndef mozilla_dom_indexeddb_indexeddatabasemanager_h__
|
||||||
#define mozilla_dom_indexeddb_indexeddatabasemanager_h__
|
#define mozilla_dom_indexeddb_indexeddatabasemanager_h__
|
||||||
|
|
||||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
|
||||||
|
|
||||||
#include "nsIObserver.h"
|
#include "nsIObserver.h"
|
||||||
|
|
||||||
#include "js/TypeDecls.h"
|
#include "js/TypeDecls.h"
|
||||||
|
@ -21,16 +19,20 @@
|
||||||
class nsPIDOMWindow;
|
class nsPIDOMWindow;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
class EventChainPostVisitor;
|
|
||||||
namespace dom {
|
|
||||||
class TabContext;
|
|
||||||
namespace quota {
|
|
||||||
class OriginOrPatternString;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
class EventChainPostVisitor;
|
||||||
|
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
class TabContext;
|
||||||
|
|
||||||
|
namespace quota {
|
||||||
|
|
||||||
|
class OriginOrPatternString;
|
||||||
|
|
||||||
|
} // namespace quota
|
||||||
|
|
||||||
|
namespace indexedDB {
|
||||||
|
|
||||||
class FileManager;
|
class FileManager;
|
||||||
class FileManagerInfo;
|
class FileManagerInfo;
|
||||||
|
@ -75,6 +77,9 @@ public:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static bool
|
||||||
|
InTestingMode();
|
||||||
|
|
||||||
already_AddRefed<FileManager>
|
already_AddRefed<FileManager>
|
||||||
GetFileManager(PersistenceType aPersistenceType,
|
GetFileManager(PersistenceType aPersistenceType,
|
||||||
const nsACString& aOrigin,
|
const nsACString& aOrigin,
|
||||||
|
@ -160,6 +165,8 @@ private:
|
||||||
static mozilla::Atomic<bool> sLowDiskSpaceMode;
|
static mozilla::Atomic<bool> sLowDiskSpaceMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
} // namespace indexedDB
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif /* mozilla_dom_indexeddb_indexeddatabasemanager_h__ */
|
#endif // mozilla_dom_indexeddb_indexeddatabasemanager_h__
|
||||||
|
|
|
@ -4,19 +4,23 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "mozilla/FloatingPoint.h"
|
|
||||||
|
|
||||||
#include "Key.h"
|
#include "Key.h"
|
||||||
#include "ReportInternalError.h"
|
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include "js/Value.h"
|
||||||
#include "jsfriendapi.h"
|
#include "jsfriendapi.h"
|
||||||
|
#include "mozilla/Endian.h"
|
||||||
|
#include "mozilla/FloatingPoint.h"
|
||||||
|
#include "mozIStorageStatement.h"
|
||||||
#include "nsAlgorithm.h"
|
#include "nsAlgorithm.h"
|
||||||
#include "nsJSUtils.h"
|
#include "nsJSUtils.h"
|
||||||
|
#include "ReportInternalError.h"
|
||||||
#include "xpcpublic.h"
|
#include "xpcpublic.h"
|
||||||
#include "mozilla/Endian.h"
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
USING_INDEXEDDB_NAMESPACE
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
namespace indexedDB {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Here's how we encode keys:
|
Here's how we encode keys:
|
||||||
|
@ -262,6 +266,14 @@ Key::DecodeJSValInternal(const unsigned char*& aPos, const unsigned char* aEnd,
|
||||||
#define TWO_BYTE_ADJUST (-0x7F)
|
#define TWO_BYTE_ADJUST (-0x7F)
|
||||||
#define THREE_BYTE_SHIFT 6
|
#define THREE_BYTE_SHIFT 6
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Key::EncodeJSVal(JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aVal,
|
||||||
|
uint8_t aTypeOffset)
|
||||||
|
{
|
||||||
|
return EncodeJSValInternal(aCx, aVal, aTypeOffset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Key::EncodeString(const nsAString& aString, uint8_t aTypeOffset)
|
Key::EncodeString(const nsAString& aString, uint8_t aTypeOffset)
|
||||||
{
|
{
|
||||||
|
@ -314,6 +326,17 @@ Key::EncodeString(const nsAString& aString, uint8_t aTypeOffset)
|
||||||
NS_ASSERTION(buffer == mBuffer.EndReading(), "Wrote wrong number of bytes");
|
NS_ASSERTION(buffer == mBuffer.EndReading(), "Wrote wrong number of bytes");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
nsresult
|
||||||
|
Key::DecodeJSVal(const unsigned char*& aPos,
|
||||||
|
const unsigned char* aEnd,
|
||||||
|
JSContext* aCx,
|
||||||
|
uint8_t aTypeOffset,
|
||||||
|
JS::MutableHandle<JS::Value> aVal)
|
||||||
|
{
|
||||||
|
return DecodeJSValInternal(aPos, aEnd, aCx, aTypeOffset, aVal, 0);
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void
|
void
|
||||||
Key::DecodeString(const unsigned char*& aPos, const unsigned char* aEnd,
|
Key::DecodeString(const unsigned char*& aPos, const unsigned char* aEnd,
|
||||||
|
@ -428,3 +451,108 @@ Key::DecodeNumber(const unsigned char*& aPos, const unsigned char* aEnd)
|
||||||
|
|
||||||
return pun.d;
|
return pun.d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Key::BindToStatement(mozIStorageStatement* aStatement,
|
||||||
|
const nsACString& aParamName) const
|
||||||
|
{
|
||||||
|
nsresult rv = aStatement->BindBlobByName(aParamName,
|
||||||
|
reinterpret_cast<const uint8_t*>(mBuffer.get()), mBuffer.Length());
|
||||||
|
|
||||||
|
return NS_SUCCEEDED(rv) ? NS_OK : NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Key::SetFromStatement(mozIStorageStatement* aStatement,
|
||||||
|
uint32_t aIndex)
|
||||||
|
{
|
||||||
|
uint8_t* data;
|
||||||
|
uint32_t dataLength = 0;
|
||||||
|
|
||||||
|
nsresult rv = aStatement->GetBlob(aIndex, &dataLength, &data);
|
||||||
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
|
||||||
|
mBuffer.Adopt(
|
||||||
|
reinterpret_cast<char*>(const_cast<uint8_t*>(data)), dataLength);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Key::SetFromJSVal(JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aVal)
|
||||||
|
{
|
||||||
|
mBuffer.Truncate();
|
||||||
|
|
||||||
|
if (aVal.isNull() || aVal.isUndefined()) {
|
||||||
|
Unset();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv = EncodeJSVal(aCx, aVal, 0);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
Unset();
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
TrimBuffer();
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Key::ToJSVal(JSContext* aCx,
|
||||||
|
JS::MutableHandle<JS::Value> aVal) const
|
||||||
|
{
|
||||||
|
if (IsUnset()) {
|
||||||
|
aVal.setUndefined();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned char* pos = BufferStart();
|
||||||
|
nsresult rv = DecodeJSVal(pos, BufferEnd(), aCx, 0, aVal);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(pos >= BufferEnd());
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Key::ToJSVal(JSContext* aCx,
|
||||||
|
JS::Heap<JS::Value>& aVal) const
|
||||||
|
{
|
||||||
|
JS::Rooted<JS::Value> value(aCx);
|
||||||
|
nsresult rv = ToJSVal(aCx, &value);
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
aVal = value;
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Key::AppendItem(JSContext* aCx, bool aFirstOfArray, JS::Handle<JS::Value> aVal)
|
||||||
|
{
|
||||||
|
nsresult rv = EncodeJSVal(aCx, aVal, aFirstOfArray ? eMaxType : 0);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
Unset();
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
|
||||||
|
void
|
||||||
|
Key::Assert(bool aCondition) const
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aCondition);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // DEBUG
|
||||||
|
|
||||||
|
} // namespace indexedDB
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
|
@ -7,84 +7,91 @@
|
||||||
#ifndef mozilla_dom_indexeddb_key_h__
|
#ifndef mozilla_dom_indexeddb_key_h__
|
||||||
#define mozilla_dom_indexeddb_key_h__
|
#define mozilla_dom_indexeddb_key_h__
|
||||||
|
|
||||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
#include "js/RootingAPI.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
|
||||||
#include "mozIStorageStatement.h"
|
class mozIStorageStatement;
|
||||||
|
|
||||||
#include "js/Value.h"
|
|
||||||
|
|
||||||
namespace IPC {
|
namespace IPC {
|
||||||
template <typename T> struct ParamTraits;
|
|
||||||
|
template <typename> struct ParamTraits;
|
||||||
|
|
||||||
} // namespace IPC
|
} // namespace IPC
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
namespace indexedDB {
|
||||||
|
|
||||||
class Key
|
class Key
|
||||||
{
|
{
|
||||||
friend struct IPC::ParamTraits<Key>;
|
friend struct IPC::ParamTraits<Key>;
|
||||||
|
|
||||||
|
nsCString mBuffer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Key()
|
Key()
|
||||||
{
|
{
|
||||||
Unset();
|
Unset();
|
||||||
}
|
}
|
||||||
|
|
||||||
Key& operator=(const nsAString& aString)
|
Key&
|
||||||
|
operator=(const nsAString& aString)
|
||||||
{
|
{
|
||||||
SetFromString(aString);
|
SetFromString(aString);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Key& operator=(int64_t aInt)
|
Key&
|
||||||
|
operator=(int64_t aInt)
|
||||||
{
|
{
|
||||||
SetFromInteger(aInt);
|
SetFromInteger(aInt);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const Key& aOther) const
|
bool
|
||||||
|
operator==(const Key& aOther) const
|
||||||
{
|
{
|
||||||
NS_ASSERTION(!mBuffer.IsVoid() && !aOther.mBuffer.IsVoid(),
|
Assert(!mBuffer.IsVoid() && !aOther.mBuffer.IsVoid());
|
||||||
"Don't compare unset keys!");
|
|
||||||
|
|
||||||
return mBuffer.Equals(aOther.mBuffer);
|
return mBuffer.Equals(aOther.mBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const Key& aOther) const
|
bool
|
||||||
|
operator!=(const Key& aOther) const
|
||||||
{
|
{
|
||||||
NS_ASSERTION(!mBuffer.IsVoid() && !aOther.mBuffer.IsVoid(),
|
Assert(!mBuffer.IsVoid() && !aOther.mBuffer.IsVoid());
|
||||||
"Don't compare unset keys!");
|
|
||||||
|
|
||||||
return !mBuffer.Equals(aOther.mBuffer);
|
return !mBuffer.Equals(aOther.mBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<(const Key& aOther) const
|
bool
|
||||||
|
operator<(const Key& aOther) const
|
||||||
{
|
{
|
||||||
NS_ASSERTION(!mBuffer.IsVoid() && !aOther.mBuffer.IsVoid(),
|
Assert(!mBuffer.IsVoid() && !aOther.mBuffer.IsVoid());
|
||||||
"Don't compare unset keys!");
|
|
||||||
|
|
||||||
return Compare(mBuffer, aOther.mBuffer) < 0;
|
return Compare(mBuffer, aOther.mBuffer) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator>(const Key& aOther) const
|
bool
|
||||||
|
operator>(const Key& aOther) const
|
||||||
{
|
{
|
||||||
NS_ASSERTION(!mBuffer.IsVoid() && !aOther.mBuffer.IsVoid(),
|
Assert(!mBuffer.IsVoid() && !aOther.mBuffer.IsVoid());
|
||||||
"Don't compare unset keys!");
|
|
||||||
|
|
||||||
return Compare(mBuffer, aOther.mBuffer) > 0;
|
return Compare(mBuffer, aOther.mBuffer) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<=(const Key& aOther) const
|
bool
|
||||||
|
operator<=(const Key& aOther) const
|
||||||
{
|
{
|
||||||
NS_ASSERTION(!mBuffer.IsVoid() && !aOther.mBuffer.IsVoid(),
|
Assert(!mBuffer.IsVoid() && !aOther.mBuffer.IsVoid());
|
||||||
"Don't compare unset keys!");
|
|
||||||
|
|
||||||
return Compare(mBuffer, aOther.mBuffer) <= 0;
|
return Compare(mBuffer, aOther.mBuffer) <= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator>=(const Key& aOther) const
|
bool
|
||||||
|
operator>=(const Key& aOther) const
|
||||||
{
|
{
|
||||||
NS_ASSERTION(!mBuffer.IsVoid() && !aOther.mBuffer.IsVoid(),
|
Assert(!mBuffer.IsVoid() && !aOther.mBuffer.IsVoid());
|
||||||
"Don't compare unset keys!");
|
|
||||||
|
|
||||||
return Compare(mBuffer, aOther.mBuffer) >= 0;
|
return Compare(mBuffer, aOther.mBuffer) >= 0;
|
||||||
}
|
}
|
||||||
|
@ -95,169 +102,114 @@ public:
|
||||||
mBuffer.SetIsVoid(true);
|
mBuffer.SetIsVoid(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsUnset() const
|
bool
|
||||||
|
IsUnset() const
|
||||||
{
|
{
|
||||||
return mBuffer.IsVoid();
|
return mBuffer.IsVoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsFloat() const
|
bool
|
||||||
|
IsFloat() const
|
||||||
{
|
{
|
||||||
return !IsUnset() && mBuffer.First() == eFloat;
|
return !IsUnset() && mBuffer.First() == eFloat;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsDate() const
|
bool
|
||||||
|
IsDate() const
|
||||||
{
|
{
|
||||||
return !IsUnset() && mBuffer.First() == eDate;
|
return !IsUnset() && mBuffer.First() == eDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsString() const
|
bool
|
||||||
|
IsString() const
|
||||||
{
|
{
|
||||||
return !IsUnset() && mBuffer.First() == eString;
|
return !IsUnset() && mBuffer.First() == eString;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsArray() const
|
bool
|
||||||
|
IsArray() const
|
||||||
{
|
{
|
||||||
return !IsUnset() && mBuffer.First() >= eArray;
|
return !IsUnset() && mBuffer.First() >= eArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
double ToFloat() const
|
double
|
||||||
|
ToFloat() const
|
||||||
{
|
{
|
||||||
NS_ASSERTION(IsFloat(), "Why'd you call this?");
|
Assert(IsFloat());
|
||||||
const unsigned char* pos = BufferStart();
|
const unsigned char* pos = BufferStart();
|
||||||
double res = DecodeNumber(pos, BufferEnd());
|
double res = DecodeNumber(pos, BufferEnd());
|
||||||
NS_ASSERTION(pos >= BufferEnd(), "Should consume whole buffer");
|
Assert(pos >= BufferEnd());
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
double ToDateMsec() const
|
double
|
||||||
|
ToDateMsec() const
|
||||||
{
|
{
|
||||||
NS_ASSERTION(IsDate(), "Why'd you call this?");
|
Assert(IsDate());
|
||||||
const unsigned char* pos = BufferStart();
|
const unsigned char* pos = BufferStart();
|
||||||
double res = DecodeNumber(pos, BufferEnd());
|
double res = DecodeNumber(pos, BufferEnd());
|
||||||
NS_ASSERTION(pos >= BufferEnd(), "Should consume whole buffer");
|
Assert(pos >= BufferEnd());
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToString(nsString& aString) const
|
void
|
||||||
|
ToString(nsString& aString) const
|
||||||
{
|
{
|
||||||
NS_ASSERTION(IsString(), "Why'd you call this?");
|
Assert(IsString());
|
||||||
const unsigned char* pos = BufferStart();
|
const unsigned char* pos = BufferStart();
|
||||||
DecodeString(pos, BufferEnd(), aString);
|
DecodeString(pos, BufferEnd(), aString);
|
||||||
NS_ASSERTION(pos >= BufferEnd(), "Should consume whole buffer");
|
Assert(pos >= BufferEnd());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetFromString(const nsAString& aString)
|
void
|
||||||
|
SetFromString(const nsAString& aString)
|
||||||
{
|
{
|
||||||
mBuffer.Truncate();
|
mBuffer.Truncate();
|
||||||
EncodeString(aString, 0);
|
EncodeString(aString, 0);
|
||||||
TrimBuffer();
|
TrimBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetFromInteger(int64_t aInt)
|
void
|
||||||
|
SetFromInteger(int64_t aInt)
|
||||||
{
|
{
|
||||||
mBuffer.Truncate();
|
mBuffer.Truncate();
|
||||||
EncodeNumber(double(aInt), eFloat);
|
EncodeNumber(double(aInt), eFloat);
|
||||||
TrimBuffer();
|
TrimBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult SetFromJSVal(JSContext* aCx,
|
nsresult
|
||||||
JS::Handle<JS::Value> aVal)
|
SetFromJSVal(JSContext* aCx, JS::Handle<JS::Value> aVal);
|
||||||
{
|
|
||||||
mBuffer.Truncate();
|
|
||||||
|
|
||||||
if (aVal.isNull() || aVal.isUndefined()) {
|
nsresult
|
||||||
Unset();
|
ToJSVal(JSContext* aCx, JS::MutableHandle<JS::Value> aVal) const;
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult rv = EncodeJSVal(aCx, aVal, 0);
|
nsresult
|
||||||
if (NS_FAILED(rv)) {
|
ToJSVal(JSContext* aCx, JS::Heap<JS::Value>& aVal) const;
|
||||||
Unset();
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
TrimBuffer();
|
|
||||||
|
|
||||||
return NS_OK;
|
nsresult
|
||||||
}
|
AppendItem(JSContext* aCx, bool aFirstOfArray, JS::Handle<JS::Value> aVal);
|
||||||
|
|
||||||
nsresult ToJSVal(JSContext* aCx,
|
void
|
||||||
JS::MutableHandle<JS::Value> aVal) const
|
FinishArray()
|
||||||
{
|
|
||||||
if (IsUnset()) {
|
|
||||||
aVal.setUndefined();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned char* pos = BufferStart();
|
|
||||||
nsresult rv = DecodeJSVal(pos, BufferEnd(), aCx, 0, aVal);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
NS_ASSERTION(pos >= BufferEnd(),
|
|
||||||
"Didn't consume whole buffer");
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult ToJSVal(JSContext* aCx,
|
|
||||||
JS::Heap<JS::Value>& aVal) const
|
|
||||||
{
|
|
||||||
JS::Rooted<JS::Value> value(aCx);
|
|
||||||
nsresult rv = ToJSVal(aCx, &value);
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
aVal = value;
|
|
||||||
}
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult AppendItem(JSContext* aCx,
|
|
||||||
bool aFirstOfArray,
|
|
||||||
JS::Handle<JS::Value> aVal)
|
|
||||||
{
|
|
||||||
nsresult rv = EncodeJSVal(aCx, aVal, aFirstOfArray ? eMaxType : 0);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
Unset();
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FinishArray()
|
|
||||||
{
|
{
|
||||||
TrimBuffer();
|
TrimBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
const nsCString& GetBuffer() const
|
const nsCString&
|
||||||
|
GetBuffer() const
|
||||||
{
|
{
|
||||||
return mBuffer;
|
return mBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult BindToStatement(mozIStorageStatement* aStatement,
|
nsresult
|
||||||
const nsACString& aParamName) const
|
BindToStatement(mozIStorageStatement* aStatement,
|
||||||
{
|
const nsACString& aParamName) const;
|
||||||
nsresult rv = aStatement->BindBlobByName(aParamName,
|
|
||||||
reinterpret_cast<const uint8_t*>(mBuffer.get()), mBuffer.Length());
|
|
||||||
|
|
||||||
return NS_SUCCEEDED(rv) ? NS_OK : NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
nsresult
|
||||||
}
|
SetFromStatement(mozIStorageStatement* aStatement, uint32_t aIndex);
|
||||||
|
|
||||||
nsresult SetFromStatement(mozIStorageStatement* aStatement,
|
static int16_t
|
||||||
uint32_t aIndex)
|
CompareKeys(Key& aFirst, Key& aSecond)
|
||||||
{
|
|
||||||
uint8_t* data;
|
|
||||||
uint32_t dataLength = 0;
|
|
||||||
|
|
||||||
nsresult rv = aStatement->GetBlob(aIndex, &dataLength, &data);
|
|
||||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
|
|
||||||
mBuffer.Adopt(
|
|
||||||
reinterpret_cast<char*>(const_cast<uint8_t*>(data)), dataLength);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
int16_t CompareKeys(Key& aFirst, Key& aSecond)
|
|
||||||
{
|
{
|
||||||
int32_t result = Compare(aFirst.mBuffer, aSecond.mBuffer);
|
int32_t result = Compare(aFirst.mBuffer, aSecond.mBuffer);
|
||||||
|
|
||||||
|
@ -273,12 +225,14 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const unsigned char* BufferStart() const
|
const unsigned char*
|
||||||
|
BufferStart() const
|
||||||
{
|
{
|
||||||
return reinterpret_cast<const unsigned char*>(mBuffer.BeginReading());
|
return reinterpret_cast<const unsigned char*>(mBuffer.BeginReading());
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned char* BufferEnd() const
|
const unsigned char*
|
||||||
|
BufferEnd() const
|
||||||
{
|
{
|
||||||
return reinterpret_cast<const unsigned char*>(mBuffer.EndReading());
|
return reinterpret_cast<const unsigned char*>(mBuffer.EndReading());
|
||||||
}
|
}
|
||||||
|
@ -294,7 +248,8 @@ private:
|
||||||
|
|
||||||
// Encoding helper. Trims trailing zeros off of mBuffer as a post-processing
|
// Encoding helper. Trims trailing zeros off of mBuffer as a post-processing
|
||||||
// step.
|
// step.
|
||||||
void TrimBuffer()
|
void
|
||||||
|
TrimBuffer()
|
||||||
{
|
{
|
||||||
const char* end = mBuffer.EndReading() - 1;
|
const char* end = mBuffer.EndReading() - 1;
|
||||||
while (!*end) {
|
while (!*end) {
|
||||||
|
@ -305,41 +260,57 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encoding functions. These append the encoded value to the end of mBuffer
|
// Encoding functions. These append the encoded value to the end of mBuffer
|
||||||
inline nsresult EncodeJSVal(JSContext* aCx, JS::Handle<JS::Value> aVal,
|
nsresult
|
||||||
uint8_t aTypeOffset)
|
EncodeJSVal(JSContext* aCx, JS::Handle<JS::Value> aVal, uint8_t aTypeOffset);
|
||||||
{
|
|
||||||
return EncodeJSValInternal(aCx, aVal, aTypeOffset, 0);
|
void
|
||||||
}
|
EncodeString(const nsAString& aString, uint8_t aTypeOffset);
|
||||||
void EncodeString(const nsAString& aString, uint8_t aTypeOffset);
|
|
||||||
void EncodeNumber(double aFloat, uint8_t aType);
|
void
|
||||||
|
EncodeNumber(double aFloat, uint8_t aType);
|
||||||
|
|
||||||
// Decoding functions. aPos points into mBuffer and is adjusted to point
|
// Decoding functions. aPos points into mBuffer and is adjusted to point
|
||||||
// past the consumed value.
|
// past the consumed value.
|
||||||
static inline nsresult DecodeJSVal(const unsigned char*& aPos,
|
static nsresult
|
||||||
const unsigned char* aEnd, JSContext* aCx,
|
DecodeJSVal(const unsigned char*& aPos,
|
||||||
uint8_t aTypeOffset, JS::MutableHandle<JS::Value> aVal)
|
const unsigned char* aEnd,
|
||||||
{
|
JSContext* aCx,
|
||||||
return DecodeJSValInternal(aPos, aEnd, aCx, aTypeOffset, aVal, 0);
|
uint8_t aTypeOffset,
|
||||||
}
|
JS::MutableHandle<JS::Value> aVal);
|
||||||
|
|
||||||
static void DecodeString(const unsigned char*& aPos,
|
static void
|
||||||
const unsigned char* aEnd,
|
DecodeString(const unsigned char*& aPos,
|
||||||
nsString& aString);
|
const unsigned char* aEnd,
|
||||||
static double DecodeNumber(const unsigned char*& aPos,
|
nsString& aString);
|
||||||
const unsigned char* aEnd);
|
|
||||||
|
|
||||||
nsCString mBuffer;
|
static double
|
||||||
|
DecodeNumber(const unsigned char*& aPos, const unsigned char* aEnd);
|
||||||
|
|
||||||
private:
|
nsresult
|
||||||
nsresult EncodeJSValInternal(JSContext* aCx, JS::Handle<JS::Value> aVal,
|
EncodeJSValInternal(JSContext* aCx,
|
||||||
uint8_t aTypeOffset, uint16_t aRecursionDepth);
|
JS::Handle<JS::Value> aVal,
|
||||||
|
uint8_t aTypeOffset,
|
||||||
|
uint16_t aRecursionDepth);
|
||||||
|
|
||||||
static nsresult DecodeJSValInternal(const unsigned char*& aPos,
|
static nsresult
|
||||||
const unsigned char* aEnd,
|
DecodeJSValInternal(const unsigned char*& aPos,
|
||||||
JSContext* aCx, uint8_t aTypeOffset,
|
const unsigned char* aEnd,
|
||||||
JS::MutableHandle<JS::Value> aVal, uint16_t aRecursionDepth);
|
JSContext* aCx,
|
||||||
|
uint8_t aTypeOffset,
|
||||||
|
JS::MutableHandle<JS::Value> aVal,
|
||||||
|
uint16_t aRecursionDepth);
|
||||||
|
|
||||||
|
void
|
||||||
|
Assert(bool aCondition) const
|
||||||
|
#ifdef DEBUG
|
||||||
|
;
|
||||||
|
#else
|
||||||
|
{ }
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
} // namespace indexedDB
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif /* mozilla_dom_indexeddb_key_h__ */
|
#endif // mozilla_dom_indexeddb_key_h__
|
||||||
|
|
|
@ -15,7 +15,9 @@
|
||||||
|
|
||||||
#include "mozilla/dom/BindingDeclarations.h"
|
#include "mozilla/dom/BindingDeclarations.h"
|
||||||
|
|
||||||
USING_INDEXEDDB_NAMESPACE
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
namespace indexedDB {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -178,8 +180,9 @@ GetJSValFromKeyPathString(JSContext* aCx,
|
||||||
obj = dummy;
|
obj = dummy;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
JS::Rooted<JSObject*> dummy(aCx, JS_NewObject(aCx, &IDBObjectStore::sDummyPropJSClass,
|
JS::Rooted<JSObject*> dummy(aCx,
|
||||||
JS::NullPtr(), JS::NullPtr()));
|
JS_NewObject(aCx, IDBObjectStore::DummyPropClass(), JS::NullPtr(),
|
||||||
|
JS::NullPtr()));
|
||||||
if (!dummy) {
|
if (!dummy) {
|
||||||
IDB_REPORT_INTERNAL_ERR();
|
IDB_REPORT_INTERNAL_ERR();
|
||||||
rv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
rv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
|
@ -569,3 +572,7 @@ KeyPath::IsAllowedForObjectStore(bool aAutoIncrement) const
|
||||||
// Everything else is ok.
|
// Everything else is ok.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace indexedDB
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
|
@ -7,16 +7,28 @@
|
||||||
#ifndef mozilla_dom_indexeddb_keypath_h__
|
#ifndef mozilla_dom_indexeddb_keypath_h__
|
||||||
#define mozilla_dom_indexeddb_keypath_h__
|
#define mozilla_dom_indexeddb_keypath_h__
|
||||||
|
|
||||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
|
||||||
|
|
||||||
#include "mozilla/dom/BindingDeclarations.h"
|
#include "mozilla/dom/BindingDeclarations.h"
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
namespace indexedDB {
|
||||||
|
|
||||||
|
class IndexMetadata;
|
||||||
class Key;
|
class Key;
|
||||||
|
class ObjectStoreMetadata;
|
||||||
|
|
||||||
class KeyPath
|
class KeyPath
|
||||||
{
|
{
|
||||||
|
// This private constructor is only to be used by IPDL-generated classes.
|
||||||
|
friend class IndexMetadata;
|
||||||
|
friend class ObjectStoreMetadata;
|
||||||
|
|
||||||
|
KeyPath()
|
||||||
|
: mType(NONEXISTENT)
|
||||||
|
{
|
||||||
|
MOZ_COUNT_CTOR(KeyPath);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum KeyPathType {
|
enum KeyPathType {
|
||||||
NONEXISTENT,
|
NONEXISTENT,
|
||||||
|
@ -105,6 +117,8 @@ public:
|
||||||
nsTArray<nsString> mStrings;
|
nsTArray<nsString> mStrings;
|
||||||
};
|
};
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
} // namespace indexedDB
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif /* mozilla_dom_indexeddb_keypath_h__ */
|
#endif // mozilla_dom_indexeddb_keypath_h__
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,175 +0,0 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef mozilla_dom_indexeddb_opendatabasehelper_h__
|
|
||||||
#define mozilla_dom_indexeddb_opendatabasehelper_h__
|
|
||||||
|
|
||||||
#include "AsyncConnectionHelper.h"
|
|
||||||
|
|
||||||
#include "nsIRunnable.h"
|
|
||||||
|
|
||||||
#include "mozilla/dom/quota/StoragePrivilege.h"
|
|
||||||
|
|
||||||
#include "DatabaseInfo.h"
|
|
||||||
#include "IDBDatabase.h"
|
|
||||||
#include "IDBRequest.h"
|
|
||||||
|
|
||||||
class mozIStorageConnection;
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace dom {
|
|
||||||
class nsIContentParent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
|
||||||
|
|
||||||
class CheckPermissionsHelper;
|
|
||||||
|
|
||||||
class OpenDatabaseHelper : public HelperBase
|
|
||||||
{
|
|
||||||
friend class CheckPermissionsHelper;
|
|
||||||
|
|
||||||
typedef mozilla::dom::quota::PersistenceType PersistenceType;
|
|
||||||
typedef mozilla::dom::quota::StoragePrivilege StoragePrivilege;
|
|
||||||
|
|
||||||
~OpenDatabaseHelper() {}
|
|
||||||
|
|
||||||
public:
|
|
||||||
OpenDatabaseHelper(IDBOpenDBRequest* aRequest,
|
|
||||||
const nsAString& aName,
|
|
||||||
const nsACString& aGroup,
|
|
||||||
const nsACString& aASCIIOrigin,
|
|
||||||
uint64_t aRequestedVersion,
|
|
||||||
PersistenceType aPersistenceType,
|
|
||||||
bool aForDeletion,
|
|
||||||
mozilla::dom::nsIContentParent* aContentParent,
|
|
||||||
StoragePrivilege aPrivilege)
|
|
||||||
: HelperBase(aRequest), mOpenDBRequest(aRequest), mName(aName),
|
|
||||||
mGroup(aGroup), mASCIIOrigin(aASCIIOrigin),
|
|
||||||
mRequestedVersion(aRequestedVersion), mPersistenceType(aPersistenceType),
|
|
||||||
mForDeletion(aForDeletion), mPrivilege(aPrivilege),
|
|
||||||
mContentParent(aContentParent), mCurrentVersion(0), mLastObjectStoreId(0),
|
|
||||||
mLastIndexId(0), mState(eCreated), mResultCode(NS_OK),
|
|
||||||
mLoadDBMetadata(false),
|
|
||||||
mTrackingQuota(aPrivilege != mozilla::dom::quota::Chrome)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(!aForDeletion || !aRequestedVersion,
|
|
||||||
"Can't be for deletion and request a version!");
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
|
||||||
NS_DECL_NSIRUNNABLE
|
|
||||||
|
|
||||||
nsresult Init();
|
|
||||||
|
|
||||||
nsresult WaitForOpenAllowed();
|
|
||||||
nsresult Dispatch(nsIEventTarget* aDatabaseThread);
|
|
||||||
nsresult DispatchToIOThread();
|
|
||||||
nsresult RunImmediately();
|
|
||||||
|
|
||||||
void SetError(nsresult rv)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_FAILED(rv), "Why are you telling me?");
|
|
||||||
mResultCode = rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual nsresult GetResultCode() MOZ_OVERRIDE
|
|
||||||
{
|
|
||||||
return mResultCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult NotifySetVersionFinished();
|
|
||||||
nsresult NotifyDeleteFinished();
|
|
||||||
void BlockDatabase();
|
|
||||||
|
|
||||||
const nsACString& Id() const
|
|
||||||
{
|
|
||||||
return mDatabaseId;
|
|
||||||
}
|
|
||||||
|
|
||||||
IDBDatabase* Database() const
|
|
||||||
{
|
|
||||||
NS_ASSERTION(mDatabase, "Calling at the wrong time!");
|
|
||||||
return mDatabase;
|
|
||||||
}
|
|
||||||
|
|
||||||
const StoragePrivilege& Privilege() const
|
|
||||||
{
|
|
||||||
return mPrivilege;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
nsresult CreateDatabaseConnection(nsIFile* aDBFile,
|
|
||||||
nsIFile* aFMDirectory,
|
|
||||||
const nsAString& aName,
|
|
||||||
PersistenceType aPersistenceType,
|
|
||||||
const nsACString& aGroup,
|
|
||||||
const nsACString& aOrigin,
|
|
||||||
mozIStorageConnection** aConnection);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Methods only called on the main thread
|
|
||||||
nsresult EnsureSuccessResult();
|
|
||||||
nsresult StartSetVersion();
|
|
||||||
nsresult StartDelete();
|
|
||||||
virtual nsresult GetSuccessResult(JSContext* aCx,
|
|
||||||
JS::MutableHandle<JS::Value> aVal) MOZ_OVERRIDE;
|
|
||||||
void DispatchSuccessEvent();
|
|
||||||
void DispatchErrorEvent();
|
|
||||||
virtual void ReleaseMainThreadObjects() MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
// Called by CheckPermissionsHelper on the main thread before dispatch.
|
|
||||||
void SetUnlimitedQuotaAllowed()
|
|
||||||
{
|
|
||||||
mTrackingQuota = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Methods only called on the DB thread
|
|
||||||
nsresult DoDatabaseWork();
|
|
||||||
|
|
||||||
// In-params.
|
|
||||||
nsRefPtr<IDBOpenDBRequest> mOpenDBRequest;
|
|
||||||
nsString mName;
|
|
||||||
nsCString mGroup;
|
|
||||||
nsCString mASCIIOrigin;
|
|
||||||
uint64_t mRequestedVersion;
|
|
||||||
PersistenceType mPersistenceType;
|
|
||||||
bool mForDeletion;
|
|
||||||
StoragePrivilege mPrivilege;
|
|
||||||
nsCString mDatabaseId;
|
|
||||||
mozilla::dom::nsIContentParent* mContentParent;
|
|
||||||
|
|
||||||
// Out-params.
|
|
||||||
nsTArray<nsRefPtr<ObjectStoreInfo> > mObjectStores;
|
|
||||||
uint64_t mCurrentVersion;
|
|
||||||
nsString mDatabaseFilePath;
|
|
||||||
int64_t mLastObjectStoreId;
|
|
||||||
int64_t mLastIndexId;
|
|
||||||
nsRefPtr<IDBDatabase> mDatabase;
|
|
||||||
|
|
||||||
// State variables
|
|
||||||
enum OpenDatabaseState {
|
|
||||||
eCreated = 0, // Not yet dispatched to the DB thread
|
|
||||||
eOpenPending, // Waiting for open allowed/open allowed
|
|
||||||
eDBWork, // Waiting to do/doing work on the DB thread
|
|
||||||
eFiringEvents, // Waiting to fire/firing events on the main thread
|
|
||||||
eSetVersionPending, // Waiting on a SetVersionHelper
|
|
||||||
eSetVersionCompleted, // SetVersionHelper is done
|
|
||||||
eDeletePending, // Waiting on a DeleteDatabaseHelper
|
|
||||||
eDeleteCompleted, // DeleteDatabaseHelper is done
|
|
||||||
};
|
|
||||||
OpenDatabaseState mState;
|
|
||||||
nsresult mResultCode;
|
|
||||||
|
|
||||||
nsRefPtr<FileManager> mFileManager;
|
|
||||||
|
|
||||||
nsRefPtr<DatabaseInfo> mDBInfo;
|
|
||||||
bool mLoadDBMetadata;
|
|
||||||
bool mTrackingQuota;
|
|
||||||
};
|
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
|
||||||
|
|
||||||
#endif // mozilla_dom_indexeddb_opendatabasehelper_h__
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
include protocol PBackgroundIDBTransaction;
|
||||||
|
include protocol PBackgroundIDBVersionChangeTransaction;
|
||||||
|
include protocol PBlob;
|
||||||
|
|
||||||
|
include PBackgroundIDBSharedTypes;
|
||||||
|
|
||||||
|
include "mozilla/dom/indexedDB/SerializationHelpers.h";
|
||||||
|
|
||||||
|
using struct mozilla::void_t
|
||||||
|
from "ipc/IPCMessageUtils.h";
|
||||||
|
|
||||||
|
using class mozilla::dom::indexedDB::Key
|
||||||
|
from "mozilla/dom/indexedDB/Key.h";
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
namespace indexedDB {
|
||||||
|
|
||||||
|
struct ContinueParams
|
||||||
|
{
|
||||||
|
Key key;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AdvanceParams
|
||||||
|
{
|
||||||
|
uint32_t count;
|
||||||
|
};
|
||||||
|
|
||||||
|
union CursorRequestParams
|
||||||
|
{
|
||||||
|
ContinueParams;
|
||||||
|
AdvanceParams;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ObjectStoreCursorResponse
|
||||||
|
{
|
||||||
|
Key key;
|
||||||
|
SerializedStructuredCloneReadInfo cloneInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ObjectStoreKeyCursorResponse
|
||||||
|
{
|
||||||
|
Key key;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IndexCursorResponse
|
||||||
|
{
|
||||||
|
Key key;
|
||||||
|
Key objectKey;
|
||||||
|
SerializedStructuredCloneReadInfo cloneInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IndexKeyCursorResponse
|
||||||
|
{
|
||||||
|
Key key;
|
||||||
|
Key objectKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
union CursorResponse
|
||||||
|
{
|
||||||
|
void_t;
|
||||||
|
nsresult;
|
||||||
|
ObjectStoreCursorResponse;
|
||||||
|
ObjectStoreKeyCursorResponse;
|
||||||
|
IndexCursorResponse;
|
||||||
|
IndexKeyCursorResponse;
|
||||||
|
};
|
||||||
|
|
||||||
|
protocol PBackgroundIDBCursor
|
||||||
|
{
|
||||||
|
manager PBackgroundIDBTransaction or PBackgroundIDBVersionChangeTransaction;
|
||||||
|
|
||||||
|
parent:
|
||||||
|
DeleteMe();
|
||||||
|
|
||||||
|
Continue(CursorRequestParams params);
|
||||||
|
|
||||||
|
child:
|
||||||
|
__delete__();
|
||||||
|
|
||||||
|
Response(CursorResponse response);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace indexedDB
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
|
@ -0,0 +1,72 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
include protocol PBackgroundIDBDatabaseFile;
|
||||||
|
include protocol PBackgroundIDBFactory;
|
||||||
|
include protocol PBackgroundIDBTransaction;
|
||||||
|
include protocol PBackgroundIDBVersionChangeTransaction;
|
||||||
|
include protocol PBlob;
|
||||||
|
|
||||||
|
include InputStreamParams;
|
||||||
|
include PBackgroundIDBSharedTypes;
|
||||||
|
|
||||||
|
include "mozilla/dom/indexedDB/SerializationHelpers.h";
|
||||||
|
|
||||||
|
using struct mozilla::null_t
|
||||||
|
from "ipc/IPCMessageUtils.h";
|
||||||
|
|
||||||
|
using mozilla::dom::indexedDB::IDBTransaction::Mode
|
||||||
|
from "mozilla/dom/indexedDB/IDBTransaction.h";
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
namespace indexedDB {
|
||||||
|
|
||||||
|
union NullableVersion
|
||||||
|
{
|
||||||
|
null_t;
|
||||||
|
uint64_t;
|
||||||
|
};
|
||||||
|
|
||||||
|
union BlobOrInputStream
|
||||||
|
{
|
||||||
|
PBlob;
|
||||||
|
InputStreamParams;
|
||||||
|
};
|
||||||
|
|
||||||
|
protocol PBackgroundIDBDatabase
|
||||||
|
{
|
||||||
|
manager PBackgroundIDBFactory;
|
||||||
|
|
||||||
|
manages PBackgroundIDBDatabaseFile;
|
||||||
|
manages PBackgroundIDBTransaction;
|
||||||
|
manages PBackgroundIDBVersionChangeTransaction;
|
||||||
|
|
||||||
|
parent:
|
||||||
|
DeleteMe();
|
||||||
|
|
||||||
|
Blocked();
|
||||||
|
|
||||||
|
Close();
|
||||||
|
|
||||||
|
PBackgroundIDBDatabaseFile(BlobOrInputStream blobOrInputStream);
|
||||||
|
|
||||||
|
PBackgroundIDBTransaction(nsString[] objectStoreNames, Mode mode);
|
||||||
|
|
||||||
|
child:
|
||||||
|
__delete__();
|
||||||
|
|
||||||
|
VersionChange(uint64_t oldVersion, NullableVersion newVersion);
|
||||||
|
|
||||||
|
Invalidate();
|
||||||
|
|
||||||
|
PBackgroundIDBVersionChangeTransaction(uint64_t currentVersion,
|
||||||
|
uint64_t requestedVersion,
|
||||||
|
int64_t nextObjectStoreId,
|
||||||
|
int64_t nextIndexId);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace indexedDB
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче