зеркало из https://github.com/mozilla/gecko-dev.git
Backout d6efd06ceb84 (bug 828992) for assertions on a CLOSED TREE
This commit is contained in:
Родитель
34abe91f47
Коммит
3326161473
|
@ -52,29 +52,6 @@ using namespace mozilla::dom;
|
||||||
using namespace mozilla::dom::indexedDB::ipc;
|
using namespace mozilla::dom::indexedDB::ipc;
|
||||||
using mozilla::dom::quota::FileOutputStream;
|
using mozilla::dom::quota::FileOutputStream;
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
|
||||||
|
|
||||||
struct FileHandleData
|
|
||||||
{
|
|
||||||
nsString type;
|
|
||||||
nsString name;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BlobOrFileData
|
|
||||||
{
|
|
||||||
BlobOrFileData()
|
|
||||||
: tag(0), size(0), lastModifiedDate(UINT64_MAX)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
uint32_t tag;
|
|
||||||
uint64_t size;
|
|
||||||
nsString type;
|
|
||||||
nsString name;
|
|
||||||
uint64_t lastModifiedDate;
|
|
||||||
};
|
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
inline
|
inline
|
||||||
|
@ -651,187 +628,6 @@ ResolveMysteryBlob(nsIDOMBlob* aBlob, const nsString& aContentType,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
class MainThreadDeserializationTraits
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static JSObject* CreateAndWrapFileHandle(JSContext* aCx,
|
|
||||||
IDBDatabase* aDatabase,
|
|
||||||
StructuredCloneFile& aFile,
|
|
||||||
const FileHandleData& aData)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
|
|
||||||
nsRefPtr<FileInfo>& fileInfo = aFile.mFileInfo;
|
|
||||||
|
|
||||||
nsRefPtr<IDBFileHandle> fileHandle = IDBFileHandle::Create(aDatabase,
|
|
||||||
aData.name, aData.type, fileInfo.forget());
|
|
||||||
|
|
||||||
jsval wrappedFileHandle;
|
|
||||||
nsresult rv =
|
|
||||||
nsContentUtils::WrapNative(aCx, JS_GetGlobalForScopeChain(aCx),
|
|
||||||
static_cast<nsIDOMFileHandle*>(fileHandle),
|
|
||||||
&NS_GET_IID(nsIDOMFileHandle),
|
|
||||||
&wrappedFileHandle);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
NS_WARNING("Failed to wrap native!");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return JSVAL_TO_OBJECT(wrappedFileHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSObject* CreateAndWrapBlobOrFile(JSContext* aCx,
|
|
||||||
IDBDatabase* aDatabase,
|
|
||||||
StructuredCloneFile& aFile,
|
|
||||||
const BlobOrFileData& aData)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
|
|
||||||
MOZ_ASSERT(aData.tag == SCTAG_DOM_FILE ||
|
|
||||||
aData.tag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE ||
|
|
||||||
aData.tag == SCTAG_DOM_BLOB);
|
|
||||||
|
|
||||||
nsresult rv = NS_OK;
|
|
||||||
|
|
||||||
nsRefPtr<FileInfo>& fileInfo = aFile.mFileInfo;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> nativeFile;
|
|
||||||
if (!aFile.mFile) {
|
|
||||||
FileManager* fileManager = aDatabase->Manager();
|
|
||||||
NS_ASSERTION(fileManager, "This should never be null!");
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> directory = fileManager->GetDirectory();
|
|
||||||
if (!directory) {
|
|
||||||
NS_WARNING("Failed to get directory!");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
nativeFile = fileManager->GetFileForId(directory, fileInfo->Id());
|
|
||||||
if (!nativeFile) {
|
|
||||||
NS_WARNING("Failed to get file!");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aData.tag == SCTAG_DOM_BLOB) {
|
|
||||||
nsCOMPtr<nsIDOMBlob> domBlob;
|
|
||||||
if (aFile.mFile) {
|
|
||||||
if (!ResolveMysteryBlob(aFile.mFile, aData.type, aData.size)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
domBlob = aFile.mFile;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
domBlob = new nsDOMFileFile(aData.type, aData.size, nativeFile,
|
|
||||||
fileInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
jsval wrappedBlob;
|
|
||||||
rv =
|
|
||||||
nsContentUtils::WrapNative(aCx, JS_GetGlobalForScopeChain(aCx), domBlob,
|
|
||||||
&NS_GET_IID(nsIDOMBlob), &wrappedBlob);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
NS_WARNING("Failed to wrap native!");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return JSVAL_TO_OBJECT(wrappedBlob);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMFile> domFile;
|
|
||||||
if (aFile.mFile) {
|
|
||||||
if (!ResolveMysteryFile(aFile.mFile, aData.name, aData.type, aData.size,
|
|
||||||
aData.lastModifiedDate)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
domFile = do_QueryInterface(aFile.mFile);
|
|
||||||
NS_ASSERTION(domFile, "This should never fail!");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
domFile = new nsDOMFileFile(aData.name, aData.type, aData.size,
|
|
||||||
nativeFile, fileInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
jsval wrappedFile;
|
|
||||||
rv =
|
|
||||||
nsContentUtils::WrapNative(aCx, JS_GetGlobalForScopeChain(aCx), domFile,
|
|
||||||
&NS_GET_IID(nsIDOMFile), &wrappedFile);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
NS_WARNING("Failed to wrap native!");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return JSVAL_TO_OBJECT(wrappedFile);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class CreateIndexDeserializationTraits
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static JSObject* CreateAndWrapFileHandle(JSContext* aCx,
|
|
||||||
IDBDatabase* aDatabase,
|
|
||||||
StructuredCloneFile& aFile,
|
|
||||||
const FileHandleData& aData)
|
|
||||||
{
|
|
||||||
// FileHandle can't be used in index creation, so just make a dummy object.
|
|
||||||
return JS_NewObject(aCx, nullptr, nullptr, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSObject* CreateAndWrapBlobOrFile(JSContext* aCx,
|
|
||||||
IDBDatabase* aDatabase,
|
|
||||||
StructuredCloneFile& aFile,
|
|
||||||
const BlobOrFileData& aData)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(aData.tag == SCTAG_DOM_FILE ||
|
|
||||||
aData.tag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE ||
|
|
||||||
aData.tag == SCTAG_DOM_BLOB);
|
|
||||||
|
|
||||||
// The following properties are available for use in index creation
|
|
||||||
// Blob.size
|
|
||||||
// Blob.type
|
|
||||||
// File.name
|
|
||||||
// File.lastModifiedDate
|
|
||||||
|
|
||||||
JSObject* obj = JS_NewObject(aCx, nullptr, nullptr, nullptr);
|
|
||||||
if (!obj) {
|
|
||||||
NS_WARNING("Failed to create object!");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Technically these props go on the proto, but this detail won't change
|
|
||||||
// the results of index creation.
|
|
||||||
|
|
||||||
JSString* type =
|
|
||||||
JS_NewUCStringCopyN(aCx, aData.type.get(), aData.type.Length());
|
|
||||||
if (!type ||
|
|
||||||
!JS_DefineProperty(aCx, obj, "size",
|
|
||||||
JS_NumberValue((double)aData.size),
|
|
||||||
nullptr, nullptr, 0) ||
|
|
||||||
!JS_DefineProperty(aCx, obj, "type", STRING_TO_JSVAL(type),
|
|
||||||
nullptr, nullptr, 0)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aData.tag == SCTAG_DOM_BLOB) {
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSString* name =
|
|
||||||
JS_NewUCStringCopyN(aCx, aData.name.get(), aData.name.Length());
|
|
||||||
JSObject* date = JS_NewDateObjectMsec(aCx, aData.lastModifiedDate);
|
|
||||||
if (!name || !date ||
|
|
||||||
!JS_DefineProperty(aCx, obj, "name", STRING_TO_JSVAL(name),
|
|
||||||
nullptr, nullptr, 0) ||
|
|
||||||
!JS_DefineProperty(aCx, obj, "lastModifiedDate", OBJECT_TO_JSVAL(date),
|
|
||||||
nullptr, nullptr, 0)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
JSClass IDBObjectStore::sDummyPropJSClass = {
|
JSClass IDBObjectStore::sDummyPropJSClass = {
|
||||||
|
@ -1207,7 +1003,7 @@ IDBObjectStore::DeserializeValue(JSContext* aCx,
|
||||||
JSAutoRequest ar(aCx);
|
JSAutoRequest ar(aCx);
|
||||||
|
|
||||||
JSStructuredCloneCallbacks callbacks = {
|
JSStructuredCloneCallbacks callbacks = {
|
||||||
IDBObjectStore::StructuredCloneReadCallback<MainThreadDeserializationTraits>,
|
IDBObjectStore::StructuredCloneReadCallback,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr
|
nullptr
|
||||||
};
|
};
|
||||||
|
@ -1294,87 +1090,6 @@ StructuredCloneReadString(JSStructuredCloneReader* aReader,
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool
|
|
||||||
IDBObjectStore::ReadFileHandle(JSStructuredCloneReader* aReader,
|
|
||||||
FileHandleData* aRetval)
|
|
||||||
{
|
|
||||||
MOZ_STATIC_ASSERT(SCTAG_DOM_FILEHANDLE == 0xFFFF8004,
|
|
||||||
"Update me!");
|
|
||||||
MOZ_ASSERT(aReader && aRetval);
|
|
||||||
|
|
||||||
nsCString type;
|
|
||||||
if (!StructuredCloneReadString(aReader, type)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
CopyUTF8toUTF16(type, aRetval->type);
|
|
||||||
|
|
||||||
nsCString name;
|
|
||||||
if (!StructuredCloneReadString(aReader, name)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
CopyUTF8toUTF16(name, aRetval->name);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
bool
|
|
||||||
IDBObjectStore::ReadBlobOrFile(JSStructuredCloneReader* aReader,
|
|
||||||
uint32_t aTag,
|
|
||||||
BlobOrFileData* aRetval)
|
|
||||||
{
|
|
||||||
MOZ_STATIC_ASSERT(SCTAG_DOM_BLOB == 0xFFFF8001 &&
|
|
||||||
SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE == 0xFFFF8002 &&
|
|
||||||
SCTAG_DOM_FILE == 0xFFFF8005,
|
|
||||||
"Update me!");
|
|
||||||
MOZ_ASSERT(aReader && aRetval);
|
|
||||||
MOZ_ASSERT(aTag == SCTAG_DOM_FILE ||
|
|
||||||
aTag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE ||
|
|
||||||
aTag == SCTAG_DOM_FILE);
|
|
||||||
|
|
||||||
aRetval->tag = aTag;
|
|
||||||
|
|
||||||
// If it's not a FileHandle, it's a Blob or a File.
|
|
||||||
uint64_t size;
|
|
||||||
if (!JS_ReadBytes(aReader, &size, sizeof(uint64_t))) {
|
|
||||||
NS_WARNING("Failed to read size!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
aRetval->size = SwapBytes(size);
|
|
||||||
|
|
||||||
nsCString type;
|
|
||||||
if (!StructuredCloneReadString(aReader, type)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
CopyUTF8toUTF16(type, aRetval->type);
|
|
||||||
|
|
||||||
// Blobs are done.
|
|
||||||
if (aTag == SCTAG_DOM_BLOB) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ASSERTION(aTag == SCTAG_DOM_FILE ||
|
|
||||||
aTag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE, "Huh?!");
|
|
||||||
|
|
||||||
uint64_t lastModifiedDate = UINT64_MAX;
|
|
||||||
if (aTag != SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE &&
|
|
||||||
!JS_ReadBytes(aReader, &lastModifiedDate, sizeof(lastModifiedDate))) {
|
|
||||||
NS_WARNING("Failed to read lastModifiedDate");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
aRetval->lastModifiedDate = lastModifiedDate;
|
|
||||||
|
|
||||||
nsCString name;
|
|
||||||
if (!StructuredCloneReadString(aReader, name)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
CopyUTF8toUTF16(name, aRetval->name);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
template <class DeserializationTraits>
|
|
||||||
JSObject*
|
JSObject*
|
||||||
IDBObjectStore::StructuredCloneReadCallback(JSContext* aCx,
|
IDBObjectStore::StructuredCloneReadCallback(JSContext* aCx,
|
||||||
JSStructuredCloneReader* aReader,
|
JSStructuredCloneReader* aReader,
|
||||||
|
@ -1403,26 +1118,137 @@ IDBObjectStore::StructuredCloneReadCallback(JSContext* aCx,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
StructuredCloneFile& file = cloneReadInfo->mFiles[aData];
|
StructuredCloneFile& file = cloneReadInfo->mFiles[aData];
|
||||||
|
nsRefPtr<FileInfo>& fileInfo = file.mFileInfo;
|
||||||
IDBDatabase* database = cloneReadInfo->mDatabase;
|
IDBDatabase* database = cloneReadInfo->mDatabase;
|
||||||
|
|
||||||
if (aTag == SCTAG_DOM_FILEHANDLE) {
|
if (aTag == SCTAG_DOM_FILEHANDLE) {
|
||||||
FileHandleData data;
|
nsCString type;
|
||||||
if (!ReadFileHandle(aReader, &data)) {
|
if (!StructuredCloneReadString(aReader, type)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
NS_ConvertUTF8toUTF16 convType(type);
|
||||||
|
|
||||||
|
nsCString name;
|
||||||
|
if (!StructuredCloneReadString(aReader, name)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
NS_ConvertUTF8toUTF16 convName(name);
|
||||||
|
|
||||||
|
nsRefPtr<IDBFileHandle> fileHandle = IDBFileHandle::Create(database,
|
||||||
|
convName, convType, fileInfo.forget());
|
||||||
|
|
||||||
|
jsval wrappedFileHandle;
|
||||||
|
rv =
|
||||||
|
nsContentUtils::WrapNative(aCx, JS_GetGlobalForScopeChain(aCx),
|
||||||
|
static_cast<nsIDOMFileHandle*>(fileHandle),
|
||||||
|
&NS_GET_IID(nsIDOMFileHandle),
|
||||||
|
&wrappedFileHandle);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_WARNING("Failed to wrap native!");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DeserializationTraits::CreateAndWrapFileHandle(aCx, database,
|
return JSVAL_TO_OBJECT(wrappedFileHandle);
|
||||||
file, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BlobOrFileData data;
|
// If it's not a FileHandle, it's a Blob or a File.
|
||||||
if (!ReadBlobOrFile(aReader, aTag, &data)) {
|
uint64_t size;
|
||||||
|
if (!JS_ReadBytes(aReader, &size, sizeof(uint64_t))) {
|
||||||
|
NS_WARNING("Failed to read size!");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
size = SwapBytes(size);
|
||||||
|
|
||||||
|
nsCString type;
|
||||||
|
if (!StructuredCloneReadString(aReader, type)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
NS_ConvertUTF8toUTF16 convType(type);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIFile> nativeFile;
|
||||||
|
if (!file.mFile) {
|
||||||
|
FileManager* fileManager = database->Manager();
|
||||||
|
NS_ASSERTION(fileManager, "This should never be null!");
|
||||||
|
|
||||||
|
nsCOMPtr<nsIFile> directory = fileManager->GetDirectory();
|
||||||
|
if (!directory) {
|
||||||
|
NS_WARNING("Failed to get directory!");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DeserializationTraits::CreateAndWrapBlobOrFile(aCx, database,
|
nativeFile = fileManager->GetFileForId(directory, fileInfo->Id());
|
||||||
file, data);
|
if (!nativeFile) {
|
||||||
|
NS_WARNING("Failed to get file!");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aTag == SCTAG_DOM_BLOB) {
|
||||||
|
nsCOMPtr<nsIDOMBlob> domBlob;
|
||||||
|
if (file.mFile) {
|
||||||
|
if (!ResolveMysteryBlob(file.mFile, convType, size)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
domBlob = file.mFile;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
domBlob = new nsDOMFileFile(convType, size, nativeFile, fileInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
jsval wrappedBlob;
|
||||||
|
rv =
|
||||||
|
nsContentUtils::WrapNative(aCx, JS_GetGlobalForScopeChain(aCx), domBlob,
|
||||||
|
&NS_GET_IID(nsIDOMBlob), &wrappedBlob);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_WARNING("Failed to wrap native!");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSVAL_TO_OBJECT(wrappedBlob);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ASSERTION(aTag == SCTAG_DOM_FILE ||
|
||||||
|
aTag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE, "Huh?!");
|
||||||
|
|
||||||
|
uint64_t lastModifiedDate = UINT64_MAX;
|
||||||
|
if (aTag != SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE &&
|
||||||
|
!JS_ReadBytes(aReader, &lastModifiedDate, sizeof(lastModifiedDate))) {
|
||||||
|
NS_WARNING("Failed to read lastModifiedDate");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCString name;
|
||||||
|
if (!StructuredCloneReadString(aReader, name)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
NS_ConvertUTF8toUTF16 convName(name);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMFile> domFile;
|
||||||
|
if (file.mFile) {
|
||||||
|
if (!ResolveMysteryFile(file.mFile, convName, convType, size, lastModifiedDate)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
domFile = do_QueryInterface(file.mFile);
|
||||||
|
NS_ASSERTION(domFile, "This should never fail!");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
domFile = new nsDOMFileFile(convName, convType, size, nativeFile,
|
||||||
|
fileInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
jsval wrappedFile;
|
||||||
|
rv =
|
||||||
|
nsContentUtils::WrapNative(aCx, JS_GetGlobalForScopeChain(aCx), domFile,
|
||||||
|
&NS_GET_IID(nsIDOMFile), &wrappedFile);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_WARNING("Failed to wrap native!");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSVAL_TO_OBJECT(wrappedFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
const JSStructuredCloneCallbacks* runtimeCallbacks =
|
const JSStructuredCloneCallbacks* runtimeCallbacks =
|
||||||
|
@ -3803,7 +3629,7 @@ CreateIndexHelper::InsertDataFromObjectStore(mozIStorageConnection* aConnection)
|
||||||
JSAutoStructuredCloneBuffer& buffer = cloneReadInfo.mCloneBuffer;
|
JSAutoStructuredCloneBuffer& buffer = cloneReadInfo.mCloneBuffer;
|
||||||
|
|
||||||
JSStructuredCloneCallbacks callbacks = {
|
JSStructuredCloneCallbacks callbacks = {
|
||||||
IDBObjectStore::StructuredCloneReadCallback<CreateIndexDeserializationTraits>,
|
IDBObjectStore::StructuredCloneReadCallback,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr
|
nullptr
|
||||||
};
|
};
|
||||||
|
|
|
@ -44,9 +44,6 @@ struct IndexInfo;
|
||||||
struct IndexUpdateInfo;
|
struct IndexUpdateInfo;
|
||||||
struct ObjectStoreInfo;
|
struct ObjectStoreInfo;
|
||||||
|
|
||||||
struct FileHandleData;
|
|
||||||
struct BlobOrFileData;
|
|
||||||
|
|
||||||
class IDBObjectStore MOZ_FINAL : public nsIIDBObjectStore
|
class IDBObjectStore MOZ_FINAL : public nsIIDBObjectStore
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -101,7 +98,6 @@ public:
|
||||||
StructuredCloneWriteInfo& aCloneWriteInfo,
|
StructuredCloneWriteInfo& aCloneWriteInfo,
|
||||||
jsval aValue);
|
jsval aValue);
|
||||||
|
|
||||||
template <class DeserializationTraits>
|
|
||||||
static JSObject*
|
static JSObject*
|
||||||
StructuredCloneReadCallback(JSContext* aCx,
|
StructuredCloneReadCallback(JSContext* aCx,
|
||||||
JSStructuredCloneReader* aReader,
|
JSStructuredCloneReader* aReader,
|
||||||
|
@ -273,14 +269,6 @@ protected:
|
||||||
static void
|
static void
|
||||||
ClearStructuredCloneBuffer(JSAutoStructuredCloneBuffer& aBuffer);
|
ClearStructuredCloneBuffer(JSAutoStructuredCloneBuffer& aBuffer);
|
||||||
|
|
||||||
static bool
|
|
||||||
ReadFileHandle(JSStructuredCloneReader* aReader,
|
|
||||||
FileHandleData* aRetval);
|
|
||||||
|
|
||||||
static bool
|
|
||||||
ReadBlobOrFile(JSStructuredCloneReader* aReader,
|
|
||||||
uint32_t aTag,
|
|
||||||
BlobOrFileData* aRetval);
|
|
||||||
private:
|
private:
|
||||||
nsRefPtr<IDBTransaction> mTransaction;
|
nsRefPtr<IDBTransaction> mTransaction;
|
||||||
|
|
||||||
|
|
|
@ -141,7 +141,7 @@ GetJSValFromKeyPathString(JSContext* aCx,
|
||||||
// If the property doesn't exist, fall into below path of starting
|
// If the property doesn't exist, fall into below path of starting
|
||||||
// to define properties, if allowed.
|
// to define properties, if allowed.
|
||||||
if (aOptions == DoNotCreateProperties) {
|
if (aOptions == DoNotCreateProperties) {
|
||||||
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
targetObject = obj;
|
targetObject = obj;
|
||||||
|
|
|
@ -73,7 +73,6 @@ MOCHITEST_FILES = \
|
||||||
test_index_update_delete.html \
|
test_index_update_delete.html \
|
||||||
test_indexes.html \
|
test_indexes.html \
|
||||||
test_indexes_bad_values.html \
|
test_indexes_bad_values.html \
|
||||||
test_indexes_funny_things.html \
|
|
||||||
test_key_requirements.html \
|
test_key_requirements.html \
|
||||||
test_keys.html \
|
test_keys.html \
|
||||||
test_leaving_page.html \
|
test_leaving_page.html \
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
<!--
|
|
||||||
Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
-->
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Indexed Database Property Test</title>
|
|
||||||
|
|
||||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
|
||||||
|
|
||||||
<script type="text/javascript;version=1.7" src="unit/test_indexes_funny_things.js"></script>
|
|
||||||
<script type="text/javascript;version=1.7" src="helpers.js"></script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body onload="runTest();"></body>
|
|
||||||
|
|
||||||
</html>
|
|
|
@ -35,7 +35,6 @@ MOCHITEST_FILES = \
|
||||||
test_index_update_delete.js \
|
test_index_update_delete.js \
|
||||||
test_indexes.js \
|
test_indexes.js \
|
||||||
test_indexes_bad_values.js \
|
test_indexes_bad_values.js \
|
||||||
test_indexes_funny_things.js \
|
|
||||||
test_key_requirements.js \
|
test_key_requirements.js \
|
||||||
test_keys.js \
|
test_keys.js \
|
||||||
test_multientry.js \
|
test_multientry.js \
|
||||||
|
|
|
@ -7,7 +7,7 @@ var testGenerator = testSteps();
|
||||||
|
|
||||||
function testSteps()
|
function testSteps()
|
||||||
{
|
{
|
||||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
const name = this.window ? this.window ? window.location.pathname : "Splendid Test" : "Splendid Test";
|
||||||
|
|
||||||
const objectStoreName = "People";
|
const objectStoreName = "People";
|
||||||
|
|
||||||
|
|
|
@ -1,168 +0,0 @@
|
||||||
/**
|
|
||||||
* Any copyright is dedicated to the Public Domain.
|
|
||||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
*/
|
|
||||||
|
|
||||||
var testGenerator = testSteps();
|
|
||||||
|
|
||||||
function testSteps()
|
|
||||||
{
|
|
||||||
// Blob constructor is not implemented outside of windows yet (Bug 827723).
|
|
||||||
if (!this.window) {
|
|
||||||
finishTest();
|
|
||||||
yield;
|
|
||||||
}
|
|
||||||
|
|
||||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
|
||||||
|
|
||||||
const objectStoreName = "Things";
|
|
||||||
|
|
||||||
const blob1 = new Blob(["foo", "bar"], { type: "text/plain" });
|
|
||||||
const blob2 = new Blob(["foobazybar"], { type: "text/plain" });
|
|
||||||
const blob3 = new Blob(["2"], { type: "bogus/" });
|
|
||||||
const str = "The Book of Mozilla";
|
|
||||||
str.type = blob1;
|
|
||||||
const arr = [1, 2, 3, 4, 5];
|
|
||||||
|
|
||||||
const objectStoreData = [
|
|
||||||
{ key: "1", value: blob1},
|
|
||||||
{ key: "2", value: blob2},
|
|
||||||
{ key: "3", value: blob3},
|
|
||||||
{ key: "4", value: str},
|
|
||||||
{ key: "5", value: arr},
|
|
||||||
];
|
|
||||||
|
|
||||||
const indexData = [
|
|
||||||
{ name: "type", keyPath: "type", options: { } },
|
|
||||||
{ name: "length", keyPath: "length", options: { unique: true } }
|
|
||||||
];
|
|
||||||
|
|
||||||
const objectStoreDataTypeSort = [
|
|
||||||
{ key: "3", value: blob3},
|
|
||||||
{ key: "1", value: blob1},
|
|
||||||
{ key: "2", value: blob2},
|
|
||||||
];
|
|
||||||
|
|
||||||
const objectStoreDataLengthSort = [
|
|
||||||
{ key: "5", value: arr},
|
|
||||||
//{ key: "4", value: str},
|
|
||||||
];
|
|
||||||
|
|
||||||
let request = indexedDB.open(name, 1);
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
let event = yield;
|
|
||||||
let db = event.target.result;
|
|
||||||
|
|
||||||
let objectStore = db.createObjectStore(objectStoreName, { keyPath: null });
|
|
||||||
|
|
||||||
// First, add all our data to the object store.
|
|
||||||
let addedData = 0;
|
|
||||||
for (let i in objectStoreData) {
|
|
||||||
request = objectStore.add(objectStoreData[i].value,
|
|
||||||
objectStoreData[i].key);
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = function(event) {
|
|
||||||
if (++addedData == objectStoreData.length) {
|
|
||||||
testGenerator.send(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
event = yield;
|
|
||||||
// Now create the indexes.
|
|
||||||
for (let i in indexData) {
|
|
||||||
objectStore.createIndex(indexData[i].name, indexData[i].keyPath,
|
|
||||||
indexData[i].options);
|
|
||||||
}
|
|
||||||
is(objectStore.indexNames.length, indexData.length, "Good index count");
|
|
||||||
yield;
|
|
||||||
objectStore = db.transaction(objectStoreName)
|
|
||||||
.objectStore(objectStoreName);
|
|
||||||
|
|
||||||
// Check global properties to make sure they are correct.
|
|
||||||
is(objectStore.indexNames.length, indexData.length, "Good index count");
|
|
||||||
for (let i in indexData) {
|
|
||||||
let found = false;
|
|
||||||
for (let j = 0; j < objectStore.indexNames.length; j++) {
|
|
||||||
if (objectStore.indexNames.item(j) == indexData[i].name) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is(found, true, "objectStore has our index");
|
|
||||||
let index = objectStore.index(indexData[i].name);
|
|
||||||
is(index.name, indexData[i].name, "Correct name");
|
|
||||||
is(index.storeName, objectStore.name, "Correct store name");
|
|
||||||
is(index.keyPath, indexData[i].keyPath, "Correct keyPath");
|
|
||||||
is(index.unique, indexData[i].options.unique ? true : false,
|
|
||||||
"Correct unique value");
|
|
||||||
}
|
|
||||||
|
|
||||||
ok(true, "Test group 1");
|
|
||||||
|
|
||||||
let keyIndex = 0;
|
|
||||||
|
|
||||||
request = objectStore.index("type").openKeyCursor();
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = function (event) {
|
|
||||||
let cursor = event.target.result;
|
|
||||||
if (cursor) {
|
|
||||||
is(cursor.key, objectStoreDataTypeSort[keyIndex].value.type,
|
|
||||||
"Correct key");
|
|
||||||
is(cursor.primaryKey, objectStoreDataTypeSort[keyIndex].key,
|
|
||||||
"Correct primary key");
|
|
||||||
ok(!("value" in cursor), "No value");
|
|
||||||
|
|
||||||
cursor.continue();
|
|
||||||
|
|
||||||
is(cursor.key, objectStoreDataTypeSort[keyIndex].value.type,
|
|
||||||
"Correct key");
|
|
||||||
is(cursor.primaryKey, objectStoreDataTypeSort[keyIndex].key,
|
|
||||||
"Correct value");
|
|
||||||
ok(!("value" in cursor), "No value");
|
|
||||||
|
|
||||||
keyIndex++;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
testGenerator.next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
yield;
|
|
||||||
|
|
||||||
is(keyIndex, objectStoreDataTypeSort.length, "Saw all the expected keys");
|
|
||||||
|
|
||||||
ok(true, "Test group 2");
|
|
||||||
|
|
||||||
keyIndex = 0;
|
|
||||||
|
|
||||||
request = objectStore.index("length").openKeyCursor(null, "next");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = function (event) {
|
|
||||||
let cursor = event.target.result;
|
|
||||||
if (cursor) {
|
|
||||||
is(cursor.key, objectStoreDataLengthSort[keyIndex].value.length,
|
|
||||||
"Correct key");
|
|
||||||
is(cursor.primaryKey, objectStoreDataLengthSort[keyIndex].key,
|
|
||||||
"Correct value");
|
|
||||||
|
|
||||||
cursor.continue();
|
|
||||||
|
|
||||||
is(cursor.key, objectStoreDataLengthSort[keyIndex].value.length,
|
|
||||||
"Correct key");
|
|
||||||
is(cursor.primaryKey, objectStoreDataLengthSort[keyIndex].key,
|
|
||||||
"Correct value");
|
|
||||||
|
|
||||||
keyIndex++;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
testGenerator.next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
yield;
|
|
||||||
|
|
||||||
is(keyIndex, objectStoreDataLengthSort.length, "Saw all the expected keys");
|
|
||||||
|
|
||||||
finishTest();
|
|
||||||
yield;
|
|
||||||
}
|
|
|
@ -28,7 +28,6 @@ tail =
|
||||||
[test_index_update_delete.js]
|
[test_index_update_delete.js]
|
||||||
[test_indexes.js]
|
[test_indexes.js]
|
||||||
[test_indexes_bad_values.js]
|
[test_indexes_bad_values.js]
|
||||||
[test_indexes_funny_things.js]
|
|
||||||
[test_key_requirements.js]
|
[test_key_requirements.js]
|
||||||
[test_keys.js]
|
[test_keys.js]
|
||||||
[test_multientry.js]
|
[test_multientry.js]
|
||||||
|
|
Загрузка…
Ссылка в новой задаче