Bug 694145 - 'IndexedDB: various methods should accept both keys and KeyRanges'. r=sicking.

--HG--
extra : transplant_source : R%0C%DA%D7%EF%8D3U%7DQ%1A%05%1A3%94%1E%F8%B0%A3k
This commit is contained in:
Ben Turner 2011-11-03 08:59:17 -07:00
Родитель d30ecd2ae0
Коммит 5f2127324d
10 изменённых файлов: 2059 добавлений и 330 удалений

Просмотреть файл

@ -67,8 +67,9 @@ public:
GetKeyHelper(IDBTransaction* aTransaction,
IDBRequest* aRequest,
IDBIndex* aIndex,
const Key& aKey)
: AsyncConnectionHelper(aTransaction, aRequest), mIndex(aIndex), mKey(aKey)
IDBKeyRange* aKeyRange)
: AsyncConnectionHelper(aTransaction, aRequest), mIndex(aIndex),
mKeyRange(aKeyRange)
{ }
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
@ -78,12 +79,16 @@ public:
void ReleaseMainThreadObjects()
{
mIndex = nsnull;
mKeyRange = nsnull;
AsyncConnectionHelper::ReleaseMainThreadObjects();
}
protected:
// In-params.
nsRefPtr<IDBIndex> mIndex;
nsRefPtr<IDBKeyRange> mKeyRange;
// Out-params.
Key mKey;
};
@ -93,8 +98,8 @@ public:
GetHelper(IDBTransaction* aTransaction,
IDBRequest* aRequest,
IDBIndex* aIndex,
const Key& aKey)
: GetKeyHelper(aTransaction, aRequest, aIndex, aKey)
IDBKeyRange* aKeyRange)
: GetKeyHelper(aTransaction, aRequest, aIndex, aKeyRange)
{ }
~GetHelper()
@ -106,6 +111,12 @@ public:
nsresult GetSuccessResult(JSContext* aCx,
jsval* aVal);
void ReleaseMainThreadObjects()
{
IDBObjectStore::ClearStructuredCloneBuffer(mCloneBuffer);
GetKeyHelper::ReleaseMainThreadObjects();
}
protected:
JSAutoStructuredCloneBuffer mCloneBuffer;
};
@ -116,9 +127,9 @@ public:
GetAllKeysHelper(IDBTransaction* aTransaction,
IDBRequest* aRequest,
IDBIndex* aIndex,
const Key& aKey,
IDBKeyRange* aKeyRange,
const PRUint32 aLimit)
: GetKeyHelper(aTransaction, aRequest, aIndex, aKey), mLimit(aLimit)
: GetKeyHelper(aTransaction, aRequest, aIndex, aKeyRange), mLimit(aLimit)
{ }
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
@ -136,9 +147,9 @@ public:
GetAllHelper(IDBTransaction* aTransaction,
IDBRequest* aRequest,
IDBIndex* aIndex,
const Key& aKey,
IDBKeyRange* aKeyRange,
const PRUint32 aLimit)
: GetKeyHelper(aTransaction, aRequest, aIndex, aKey), mLimit(aLimit)
: GetKeyHelper(aTransaction, aRequest, aIndex, aKeyRange), mLimit(aLimit)
{ }
~GetAllHelper()
@ -154,6 +165,9 @@ public:
void ReleaseMainThreadObjects()
{
for (PRUint32 index = 0; index < mCloneBuffers.Length(); index++) {
IDBObjectStore::ClearStructuredCloneBuffer(mCloneBuffers[index]);
}
GetKeyHelper::ReleaseMainThreadObjects();
}
@ -404,17 +418,20 @@ IDBIndex::Get(const jsval& aKey,
return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
}
Key key;
nsresult rv = key.SetFromJSVal(aCx, aKey);
if (NS_FAILED(rv)) {
return rv;
nsRefPtr<IDBKeyRange> keyRange;
nsresult rv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
NS_ENSURE_SUCCESS(rv, rv);
if (!keyRange) {
// Must specify a key or keyRange for get().
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
}
nsRefPtr<IDBRequest> request = GenerateRequest(this);
NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
nsRefPtr<GetHelper> helper =
new GetHelper(transaction, request, this, key);
new GetHelper(transaction, request, this, keyRange);
rv = helper->DispatchToTransactionPool();
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
@ -434,17 +451,20 @@ IDBIndex::GetKey(const jsval& aKey,
return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
}
Key key;
nsresult rv = key.SetFromJSVal(aCx, aKey);
if (NS_FAILED(rv)) {
return rv;
nsRefPtr<IDBKeyRange> keyRange;
nsresult rv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
NS_ENSURE_SUCCESS(rv, rv);
if (!keyRange) {
// Must specify a key or keyRange for get().
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
}
nsRefPtr<IDBRequest> request = GenerateRequest(this);
NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
nsRefPtr<GetKeyHelper> helper =
new GetKeyHelper(transaction, request, this, key);
new GetKeyHelper(transaction, request, this, keyRange);
rv = helper->DispatchToTransactionPool();
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
@ -467,9 +487,12 @@ IDBIndex::GetAll(const jsval& aKey,
return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
}
Key key;
if (aOptionalArgCount && NS_FAILED(key.SetFromJSVal(aCx, aKey))) {
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
nsresult rv;
nsRefPtr<IDBKeyRange> keyRange;
if (aOptionalArgCount) {
rv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
NS_ENSURE_SUCCESS(rv, rv);
}
if (aOptionalArgCount < 2) {
@ -480,9 +503,9 @@ IDBIndex::GetAll(const jsval& aKey,
NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
nsRefPtr<GetAllHelper> helper =
new GetAllHelper(transaction, request, this, key, aLimit);
new GetAllHelper(transaction, request, this, keyRange, aLimit);
nsresult rv = helper->DispatchToTransactionPool();
rv = helper->DispatchToTransactionPool();
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
request.forget(_retval);
@ -505,9 +528,10 @@ IDBIndex::GetAllKeys(const jsval& aKey,
nsresult rv;
Key key;
if (aOptionalArgCount && NS_FAILED(key.SetFromJSVal(aCx, aKey))) {
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
nsRefPtr<IDBKeyRange> keyRange;
if (aOptionalArgCount) {
rv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
NS_ENSURE_SUCCESS(rv, rv);
}
if (aOptionalArgCount < 2) {
@ -518,7 +542,7 @@ IDBIndex::GetAllKeys(const jsval& aKey,
NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
nsRefPtr<GetAllKeysHelper> helper =
new GetAllKeysHelper(transaction, request, this, key, aLimit);
new GetAllKeysHelper(transaction, request, this, keyRange, aLimit);
rv = helper->DispatchToTransactionPool();
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
@ -653,28 +677,56 @@ IDBIndex::Count(const jsval& aKey,
}
nsresult
GetKeyHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
GetKeyHelper::DoDatabaseWork(mozIStorageConnection* /* aConnection */)
{
NS_ASSERTION(aConnection, "Passed a null connection!");
NS_ASSERTION(mKeyRange, "Must have a key range here!");
nsCOMPtr<mozIStorageStatement> stmt =
mTransaction->IndexGetStatement(mIndex->IsUnique(),
mIndex->IsAutoIncrement());
nsCString keyColumn;
nsCString indexTable;
if (mIndex->IsAutoIncrement()) {
keyColumn.AssignLiteral("ai_object_data_id");
if (mIndex->IsUnique()) {
indexTable.AssignLiteral("ai_unique_index_data");
}
else {
indexTable.AssignLiteral("ai_index_data");
}
}
else {
keyColumn.AssignLiteral("object_data_key");
if (mIndex->IsUnique()) {
indexTable.AssignLiteral("unique_index_data");
}
else {
indexTable.AssignLiteral("index_data");
}
}
nsCString keyRangeClause;
mKeyRange->GetBindingClause(NS_LITERAL_CSTRING("value"), keyRangeClause);
NS_ASSERTION(!keyRangeClause.IsEmpty(), "Huh?!");
NS_NAMED_LITERAL_CSTRING(indexId, "index_id");
nsCString query = NS_LITERAL_CSTRING("SELECT ") + keyColumn +
NS_LITERAL_CSTRING(" FROM ") + indexTable +
NS_LITERAL_CSTRING(" WHERE ") + indexId +
NS_LITERAL_CSTRING(" = :") + indexId + keyRangeClause +
NS_LITERAL_CSTRING(" LIMIT 1");
nsCOMPtr<mozIStorageStatement> stmt = mTransaction->GetCachedStatement(query);
NS_ENSURE_TRUE(stmt, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
mozStorageStatementScoper scoper(stmt);
nsresult rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("index_id"),
mIndex->Id());
nsresult rv = stmt->BindInt64ByName(indexId, mIndex->Id());
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
NS_NAMED_LITERAL_CSTRING(value, "value");
rv = mKey.BindToStatement(stmt, value);
rv = mKeyRange->BindToStatement(stmt);
NS_ENSURE_SUCCESS(rv, rv);
mKey.Unset();
bool hasResult;
rv = stmt->ExecuteStep(&hasResult);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
@ -691,33 +743,66 @@ nsresult
GetKeyHelper::GetSuccessResult(JSContext* aCx,
jsval* aVal)
{
NS_ASSERTION(!mKey.IsUnset(), "Badness!");
return mKey.ToJSVal(aCx, aVal);
}
nsresult
GetHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
GetHelper::DoDatabaseWork(mozIStorageConnection* /* aConnection */)
{
NS_ASSERTION(aConnection, "Passed a null connection!");
NS_ASSERTION(mKeyRange, "Must have a key range here!");
nsCOMPtr<mozIStorageStatement> stmt =
mTransaction->IndexGetObjectStatement(mIndex->IsUnique(),
mIndex->IsAutoIncrement());
nsCString objectTable;
nsCString joinTable;
nsCString objectColumn;
if (mIndex->IsAutoIncrement()) {
objectTable.AssignLiteral("ai_object_data");
objectColumn.AssignLiteral("ai_object_data_id");
if (mIndex->IsUnique()) {
joinTable.AssignLiteral("ai_unique_index_data");
}
else {
joinTable.AssignLiteral("ai_index_data");
}
}
else {
objectTable.AssignLiteral("object_data");
objectColumn.AssignLiteral("object_data_id");
if (mIndex->IsUnique()) {
joinTable.AssignLiteral("unique_index_data");
}
else {
joinTable.AssignLiteral("index_data");
}
}
nsCString keyRangeClause;
mKeyRange->GetBindingClause(NS_LITERAL_CSTRING("value"), keyRangeClause);
NS_ASSERTION(!keyRangeClause.IsEmpty(), "Huh?!");
NS_NAMED_LITERAL_CSTRING(indexId, "index_id");
nsCString query = NS_LITERAL_CSTRING("SELECT data FROM ") + objectTable +
NS_LITERAL_CSTRING(" INNER JOIN ") + joinTable +
NS_LITERAL_CSTRING(" ON ") + objectTable +
NS_LITERAL_CSTRING(".id = ") + joinTable +
NS_LITERAL_CSTRING(".") + objectColumn +
NS_LITERAL_CSTRING(" WHERE ") + indexId +
NS_LITERAL_CSTRING(" = :") + indexId + keyRangeClause +
NS_LITERAL_CSTRING(" LIMIT 1");
nsCOMPtr<mozIStorageStatement> stmt = mTransaction->GetCachedStatement(query);
NS_ENSURE_TRUE(stmt, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
mozStorageStatementScoper scoper(stmt);
nsresult rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("index_id"),
mIndex->Id());
nsresult rv = stmt->BindInt64ByName(indexId, mIndex->Id());
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
NS_NAMED_LITERAL_CSTRING(value, "value");
rv = mKey.BindToStatement(stmt, value);
rv = mKeyRange->BindToStatement(stmt);
NS_ENSURE_SUCCESS(rv, rv);
mKey.Unset();
bool hasResult;
rv = stmt->ExecuteStep(&hasResult);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
@ -744,15 +829,8 @@ GetHelper::GetSuccessResult(JSContext* aCx,
}
nsresult
GetAllKeysHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
GetAllKeysHelper::DoDatabaseWork(mozIStorageConnection* /* aConnection */)
{
NS_ASSERTION(aConnection, "Passed a null connection!");
if (!mKeys.SetCapacity(50)) {
NS_ERROR("Out of memory!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
nsCString keyColumn;
nsCString tableName;
@ -775,13 +853,9 @@ GetAllKeysHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
}
}
NS_NAMED_LITERAL_CSTRING(indexId, "index_id");
NS_NAMED_LITERAL_CSTRING(value, "value");
nsCString keyClause;
if (!mKey.IsUnset()) {
keyClause = NS_LITERAL_CSTRING(" AND ") + value +
NS_LITERAL_CSTRING(" = :") + value;
nsCString keyRangeClause;
if (mKeyRange) {
mKeyRange->GetBindingClause(NS_LITERAL_CSTRING("value"), keyRangeClause);
}
nsCString limitClause;
@ -790,12 +864,14 @@ GetAllKeysHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
limitClause.AppendInt(mLimit);
}
NS_NAMED_LITERAL_CSTRING(indexId, "index_id");
nsCString query = NS_LITERAL_CSTRING("SELECT ") + keyColumn +
NS_LITERAL_CSTRING(" FROM ") + tableName +
NS_LITERAL_CSTRING(" WHERE ") + indexId +
NS_LITERAL_CSTRING(" = :") + indexId + keyClause +
NS_LITERAL_CSTRING(" = :") + indexId + keyRangeClause +
limitClause;
nsCOMPtr<mozIStorageStatement> stmt = mTransaction->GetCachedStatement(query);
NS_ENSURE_TRUE(stmt, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
@ -804,11 +880,13 @@ GetAllKeysHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
nsresult rv = stmt->BindInt64ByName(indexId, mIndex->Id());
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
if (!mKey.IsUnset()) {
rv = mKey.BindToStatement(stmt, value);
if (mKeyRange) {
rv = mKeyRange->BindToStatement(stmt);
NS_ENSURE_SUCCESS(rv, rv);
}
mKeys.SetCapacity(50);
bool hasResult;
while(NS_SUCCEEDED((rv = stmt->ExecuteStep(&hasResult))) && hasResult) {
if (mKeys.Capacity() == mKeys.Length()) {
@ -875,15 +953,8 @@ GetAllKeysHelper::GetSuccessResult(JSContext* aCx,
}
nsresult
GetAllHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
GetAllHelper::DoDatabaseWork(mozIStorageConnection* /* aConnection */)
{
NS_ASSERTION(aConnection, "Passed a null connection!");
if (!mCloneBuffers.SetCapacity(50)) {
NS_ERROR("Out of memory!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
nsCString dataTableName;
nsCString objectDataId;
nsCString indexTableName;
@ -910,12 +981,10 @@ GetAllHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
}
NS_NAMED_LITERAL_CSTRING(indexId, "index_id");
NS_NAMED_LITERAL_CSTRING(value, "value");
nsCString keyClause;
if (!mKey.IsUnset()) {
keyClause = NS_LITERAL_CSTRING(" AND ") + value +
NS_LITERAL_CSTRING(" = :") + value;
nsCString keyRangeClause;
if (mKeyRange) {
mKeyRange->GetBindingClause(NS_LITERAL_CSTRING("value"), keyRangeClause);
}
nsCString limitClause;
@ -930,7 +999,7 @@ GetAllHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
NS_LITERAL_CSTRING(".id = ") + indexTableName +
NS_LITERAL_CSTRING(".") + objectDataId +
NS_LITERAL_CSTRING(" WHERE ") + indexId +
NS_LITERAL_CSTRING(" = :") + indexId + keyClause +
NS_LITERAL_CSTRING(" = :") + indexId + keyRangeClause +
limitClause;
nsCOMPtr<mozIStorageStatement> stmt = mTransaction->GetCachedStatement(query);
@ -941,18 +1010,17 @@ GetAllHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
nsresult rv = stmt->BindInt64ByName(indexId, mIndex->Id());
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
if (!mKey.IsUnset()) {
rv = mKey.BindToStatement(stmt, value);
if (mKeyRange) {
rv = mKeyRange->BindToStatement(stmt);
NS_ENSURE_SUCCESS(rv, rv);
}
mCloneBuffers.SetCapacity(50);
bool hasResult;
while(NS_SUCCEEDED((rv = stmt->ExecuteStep(&hasResult))) && hasResult) {
if (mCloneBuffers.Capacity() == mCloneBuffers.Length()) {
if (!mCloneBuffers.SetCapacity(mCloneBuffers.Capacity() * 2)) {
NS_ERROR("Out of memory!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
mCloneBuffers.SetCapacity(mCloneBuffers.Capacity() * 2);
}
JSAutoStructuredCloneBuffer* buffer = mCloneBuffers.AppendElement();
@ -1015,16 +1083,9 @@ OpenKeyCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
NS_NAMED_LITERAL_CSTRING(value, "value");
nsCAutoString keyRangeClause;
nsCString keyRangeClause;
if (mKeyRange) {
if (!mKeyRange->Lower().IsUnset()) {
AppendConditionClause(value, lowerKeyName, false,
!mKeyRange->IsLowerOpen(), keyRangeClause);
}
if (!mKeyRange->Upper().IsUnset()) {
AppendConditionClause(value, upperKeyName, true,
!mKeyRange->IsUpperOpen(), keyRangeClause);
}
mKeyRange->GetBindingClause(value, keyRangeClause);
}
nsCAutoString directionClause = NS_LITERAL_CSTRING(" ORDER BY ") + value;
@ -1061,14 +1122,8 @@ OpenKeyCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
if (mKeyRange) {
if (!mKeyRange->Lower().IsUnset()) {
rv = mKeyRange->Lower().BindToStatement(stmt, lowerKeyName);
NS_ENSURE_SUCCESS(rv, rv);
}
if (!mKeyRange->Upper().IsUnset()) {
rv = mKeyRange->Upper().BindToStatement(stmt, upperKeyName);
NS_ENSURE_SUCCESS(rv, rv);
}
rv = mKeyRange->BindToStatement(stmt);
NS_ENSURE_SUCCESS(rv, rv);
}
bool hasResult;
@ -1214,23 +1269,14 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
}
NS_NAMED_LITERAL_CSTRING(id, "id");
NS_NAMED_LITERAL_CSTRING(lowerKeyName, "lower_key");
NS_NAMED_LITERAL_CSTRING(upperKeyName, "upper_key");
nsCString value = indexTable + NS_LITERAL_CSTRING(".value");
nsCString data = objectTable + NS_LITERAL_CSTRING(".data");
nsCString keyValue = objectTable + NS_LITERAL_CSTRING(".") + keyValueColumn;
nsCAutoString keyRangeClause;
nsCString keyRangeClause;
if (mKeyRange) {
if (!mKeyRange->Lower().IsUnset()) {
AppendConditionClause(value, lowerKeyName, false,
!mKeyRange->IsLowerOpen(), keyRangeClause);
}
if (!mKeyRange->Upper().IsUnset()) {
AppendConditionClause(value, upperKeyName, true,
!mKeyRange->IsUpperOpen(), keyRangeClause);
}
mKeyRange->GetBindingClause(value, keyRangeClause);
}
nsCAutoString directionClause = NS_LITERAL_CSTRING(" ORDER BY ") + value;
@ -1274,14 +1320,8 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
if (mKeyRange) {
if (!mKeyRange->Lower().IsUnset()) {
rv = mKeyRange->Lower().BindToStatement(stmt, lowerKeyName);
NS_ENSURE_SUCCESS(rv, rv);
}
if (!mKeyRange->Upper().IsUnset()) {
rv = mKeyRange->Upper().BindToStatement(stmt, upperKeyName);
NS_ENSURE_SUCCESS(rv, rv);
}
rv = mKeyRange->BindToStatement(stmt);
NS_ENSURE_SUCCESS(rv, rv);
}
bool hasResult;

Просмотреть файл

@ -47,6 +47,8 @@
#include "nsCycleCollectionParticipant.h"
class mozIStorageStatement;
BEGIN_INDEXEDDB_NAMESPACE
class IDBKeyRange : public nsIIDBKeyRange
@ -100,6 +102,73 @@ public:
return mUpperOpen;
}
bool IsOnly() const
{
return mIsOnly;
}
void 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;
}
else {
nsCAutoString clause;
if (!Lower().IsUnset()) {
// Lower key is set.
clause.Append(andStr + aKeyColumnName);
clause.AppendLiteral(" >");
if (!IsLowerOpen()) {
clause.AppendLiteral("=");
}
clause.Append(spacecolon + lowerKey);
}
if (!Upper().IsUnset()) {
// Upper key is set.
clause.Append(andStr + aKeyColumnName);
clause.AppendLiteral(" <");
if (!IsUpperOpen()) {
clause.AppendLiteral("=");
}
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;
}
protected:
~IDBKeyRange() { }

Просмотреть файл

@ -117,9 +117,9 @@ public:
GetHelper(IDBTransaction* aTransaction,
IDBRequest* aRequest,
IDBObjectStore* aObjectStore,
const Key& aKey)
IDBKeyRange* aKeyRange)
: AsyncConnectionHelper(aTransaction, aRequest), mObjectStore(aObjectStore),
mKey(aKey)
mKeyRange(aKeyRange)
{ }
~GetHelper()
@ -134,6 +134,7 @@ public:
void ReleaseMainThreadObjects()
{
mObjectStore = nsnull;
mKeyRange = nsnull;
IDBObjectStore::ClearStructuredCloneBuffer(mCloneBuffer);
AsyncConnectionHelper::ReleaseMainThreadObjects();
}
@ -141,7 +142,7 @@ public:
protected:
// In-params.
nsRefPtr<IDBObjectStore> mObjectStore;
Key mKey;
nsRefPtr<IDBKeyRange> mKeyRange;
private:
// Out-params.
@ -154,8 +155,8 @@ public:
DeleteHelper(IDBTransaction* aTransaction,
IDBRequest* aRequest,
IDBObjectStore* aObjectStore,
const Key& aKey)
: GetHelper(aTransaction, aRequest, aObjectStore, aKey)
IDBKeyRange* aKeyRange)
: GetHelper(aTransaction, aRequest, aObjectStore, aKeyRange)
{ }
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
@ -1063,21 +1064,20 @@ IDBObjectStore::Get(const jsval& aKey,
return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
}
Key key;
nsresult rv = key.SetFromJSVal(aCx, aKey);
if (NS_FAILED(rv)) {
// Maybe this is a key range.
return GetAll(aKey, 0, aCx, 1, _retval);
}
nsRefPtr<IDBKeyRange> keyRange;
nsresult rv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
NS_ENSURE_SUCCESS(rv, rv);
if (key.IsUnset()) {
if (!keyRange) {
// Must specify a key or keyRange for get().
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
}
nsRefPtr<IDBRequest> request = GenerateRequest(this);
NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
nsRefPtr<GetHelper> helper(new GetHelper(mTransaction, request, this, key));
nsRefPtr<GetHelper> helper =
new GetHelper(mTransaction, request, this, keyRange);
rv = helper->DispatchToTransactionPool();
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
@ -1163,13 +1163,12 @@ IDBObjectStore::Delete(const jsval& aKey,
return NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR;
}
Key key;
nsresult rv = key.SetFromJSVal(aCx, aKey);
if (NS_FAILED(rv)) {
return rv;
}
nsRefPtr<IDBKeyRange> keyRange;
nsresult rv = IDBKeyRange::FromJSVal(aCx, aKey, getter_AddRefs(keyRange));
NS_ENSURE_SUCCESS(rv, rv);
if (key.IsUnset()) {
if (!keyRange) {
// Must specify a key or keyRange for delete().
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
}
@ -1177,7 +1176,7 @@ IDBObjectStore::Delete(const jsval& aKey,
NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
nsRefPtr<DeleteHelper> helper =
new DeleteHelper(mTransaction, request, this, key);
new DeleteHelper(mTransaction, request, this, keyRange);
rv = helper->DispatchToTransactionPool();
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
@ -1547,12 +1546,32 @@ AddHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
nsCOMPtr<mozIStorageStatement> stmt;
if (!mOverwrite && !unsetKey) {
// Make sure the key doesn't exist already
stmt = mTransaction->GetStatement(autoIncrement);
NS_NAMED_LITERAL_CSTRING(id, "id");
NS_NAMED_LITERAL_CSTRING(osidStr, "osid");
nsCString table;
nsCString value;
if (autoIncrement) {
table.AssignLiteral("ai_object_data");
value = id;
}
else {
table.AssignLiteral("object_data");
value.AssignLiteral("key_value");
}
nsCString query = NS_LITERAL_CSTRING("SELECT data FROM ") + table +
NS_LITERAL_CSTRING(" WHERE ") + value +
NS_LITERAL_CSTRING(" = :") + id +
NS_LITERAL_CSTRING(" AND object_store_id = :") + osidStr;
stmt = mTransaction->GetCachedStatement(query);
NS_ENSURE_TRUE(stmt, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
mozStorageStatementScoper scoper(stmt);
rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("osid"), osid);
rv = stmt->BindInt64ByName(osidStr, osid);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
rv = mKey.BindToStatement(stmt, NS_LITERAL_CSTRING("id"));
@ -1706,26 +1725,43 @@ AddHelper::GetSuccessResult(JSContext* aCx,
}
nsresult
GetHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
GetHelper::DoDatabaseWork(mozIStorageConnection* /* aConnection */)
{
NS_PRECONDITION(aConnection, "Passed a null connection!");
NS_ASSERTION(mKeyRange, "Must have a key range here!");
nsCOMPtr<mozIStorageStatement> stmt =
mTransaction->GetStatement(mObjectStore->IsAutoIncrement());
nsCString table;
nsCString value;
if (mObjectStore->IsAutoIncrement()) {
table.AssignLiteral("ai_object_data");
value.AssignLiteral("id");
}
else {
table.AssignLiteral("object_data");
value.AssignLiteral("key_value");
}
nsCString keyRangeClause;
mKeyRange->GetBindingClause(value, keyRangeClause);
NS_ASSERTION(!keyRangeClause.IsEmpty(), "Huh?!");
NS_NAMED_LITERAL_CSTRING(osid, "osid");
nsCString query = NS_LITERAL_CSTRING("SELECT data FROM ") + table +
NS_LITERAL_CSTRING(" WHERE object_store_id = :") + osid +
keyRangeClause + NS_LITERAL_CSTRING(" LIMIT 1");
nsCOMPtr<mozIStorageStatement> stmt = mTransaction->GetCachedStatement(query);
NS_ENSURE_TRUE(stmt, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
mozStorageStatementScoper scoper(stmt);
nsresult rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("osid"),
mObjectStore->Id());
nsresult rv = stmt->BindInt64ByName(osid, mObjectStore->Id());
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
NS_ASSERTION(!mKey.IsUnset(), "Must have a key here!");
rv = mKey.BindToStatement(stmt, NS_LITERAL_CSTRING("id"));
rv = mKeyRange->BindToStatement(stmt);
NS_ENSURE_SUCCESS(rv, rv);
// Search for it!
bool hasResult;
rv = stmt->ExecuteStep(&hasResult);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
@ -1752,23 +1788,41 @@ GetHelper::GetSuccessResult(JSContext* aCx,
}
nsresult
DeleteHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
DeleteHelper::DoDatabaseWork(mozIStorageConnection* /*aConnection */)
{
NS_PRECONDITION(aConnection, "Passed a null connection!");
NS_ASSERTION(mKeyRange, "Must have a key range here!");
nsCOMPtr<mozIStorageStatement> stmt =
mTransaction->DeleteStatement(mObjectStore->IsAutoIncrement());
nsCString table;
nsCString value;
if (mObjectStore->IsAutoIncrement()) {
table.AssignLiteral("ai_object_data");
value.AssignLiteral("id");
}
else {
table.AssignLiteral("object_data");
value.AssignLiteral("key_value");
}
nsCString keyRangeClause;
mKeyRange->GetBindingClause(value, keyRangeClause);
NS_ASSERTION(!keyRangeClause.IsEmpty(), "Huh?!");
NS_NAMED_LITERAL_CSTRING(osid, "osid");
nsCString query = NS_LITERAL_CSTRING("DELETE FROM ") + table +
NS_LITERAL_CSTRING(" WHERE object_store_id = :") + osid +
keyRangeClause;
nsCOMPtr<mozIStorageStatement> stmt = mTransaction->GetCachedStatement(query);
NS_ENSURE_TRUE(stmt, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
mozStorageStatementScoper scoper(stmt);
nsresult rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("osid"),
mObjectStore->Id());
nsresult rv = stmt->BindInt64ByName(osid, mObjectStore->Id());
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
NS_ASSERTION(!mKey.IsUnset(), "Must have a key here!");
rv = mKey.BindToStatement(stmt, NS_LITERAL_CSTRING("key_value"));
rv = mKeyRange->BindToStatement(stmt);
NS_ENSURE_SUCCESS(rv, rv);
rv = stmt->Execute();
@ -1781,8 +1835,9 @@ nsresult
DeleteHelper::GetSuccessResult(JSContext* aCx,
jsval* aVal)
{
NS_ASSERTION(!mKey.IsUnset(), "Badness!");
return mKey.ToJSVal(aCx, aVal);
// XXX Will fix this for real in a bit.
*aVal = JSVAL_TRUE;
return NS_OK;
}
nsresult
@ -1832,19 +1887,10 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
}
NS_NAMED_LITERAL_CSTRING(id, "id");
NS_NAMED_LITERAL_CSTRING(lowerKeyName, "lower_key");
NS_NAMED_LITERAL_CSTRING(upperKeyName, "upper_key");
nsCAutoString keyRangeClause;
nsCString keyRangeClause;
if (mKeyRange) {
if (!mKeyRange->Lower().IsUnset()) {
AppendConditionClause(keyColumn, lowerKeyName, false,
!mKeyRange->IsLowerOpen(), keyRangeClause);
}
if (!mKeyRange->Upper().IsUnset()) {
AppendConditionClause(keyColumn, upperKeyName, true,
!mKeyRange->IsUpperOpen(), keyRangeClause);
}
mKeyRange->GetBindingClause(keyColumn, keyRangeClause);
}
nsCAutoString directionClause = NS_LITERAL_CSTRING(" ORDER BY ") + keyColumn;
@ -1878,14 +1924,8 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
if (mKeyRange) {
if (!mKeyRange->Lower().IsUnset()) {
rv = mKeyRange->Lower().BindToStatement(stmt, lowerKeyName);
NS_ENSURE_SUCCESS(rv, rv);
}
if (!mKeyRange->Upper().IsUnset()) {
rv = mKeyRange->Upper().BindToStatement(stmt, upperKeyName);
NS_ENSURE_SUCCESS(rv, rv);
}
rv = mKeyRange->BindToStatement(stmt);
NS_ENSURE_SUCCESS(rv, rv);
}
bool hasResult;

Просмотреть файл

@ -362,122 +362,6 @@ IDBTransaction::AddStatement(bool aCreate,
);
}
already_AddRefed<mozIStorageStatement>
IDBTransaction::DeleteStatement(bool aAutoIncrement)
{
if (aAutoIncrement) {
return GetCachedStatement(
"DELETE FROM ai_object_data "
"WHERE id = :key_value "
"AND object_store_id = :osid"
);
}
return GetCachedStatement(
"DELETE FROM object_data "
"WHERE key_value = :key_value "
"AND object_store_id = :osid"
);
}
already_AddRefed<mozIStorageStatement>
IDBTransaction::GetStatement(bool aAutoIncrement)
{
if (aAutoIncrement) {
return GetCachedStatement(
"SELECT data "
"FROM ai_object_data "
"WHERE id = :id "
"AND object_store_id = :osid"
);
}
return GetCachedStatement(
"SELECT data "
"FROM object_data "
"WHERE key_value = :id "
"AND object_store_id = :osid"
);
}
already_AddRefed<mozIStorageStatement>
IDBTransaction::IndexGetStatement(bool aUnique,
bool aAutoIncrement)
{
if (aAutoIncrement) {
if (aUnique) {
return GetCachedStatement(
"SELECT ai_object_data_id "
"FROM ai_unique_index_data "
"WHERE index_id = :index_id "
"AND value = :value"
);
}
return GetCachedStatement(
"SELECT ai_object_data_id "
"FROM ai_index_data "
"WHERE index_id = :index_id "
"AND value = :value"
);
}
if (aUnique) {
return GetCachedStatement(
"SELECT object_data_key "
"FROM unique_index_data "
"WHERE index_id = :index_id "
"AND value = :value"
);
}
return GetCachedStatement(
"SELECT object_data_key "
"FROM index_data "
"WHERE index_id = :index_id "
"AND value = :value"
);
}
already_AddRefed<mozIStorageStatement>
IDBTransaction::IndexGetObjectStatement(bool aUnique,
bool aAutoIncrement)
{
if (aAutoIncrement) {
if (aUnique) {
return GetCachedStatement(
"SELECT data "
"FROM ai_object_data "
"INNER JOIN ai_unique_index_data "
"ON ai_object_data.id = ai_unique_index_data.ai_object_data_id "
"WHERE index_id = :index_id "
"AND value = :value"
);
}
return GetCachedStatement(
"SELECT data "
"FROM ai_object_data "
"INNER JOIN ai_index_data "
"ON ai_object_data.id = ai_index_data.ai_object_data_id "
"WHERE index_id = :index_id "
"AND value = :value"
);
}
if (aUnique) {
return GetCachedStatement(
"SELECT data "
"FROM object_data "
"INNER JOIN unique_index_data "
"ON object_data.id = unique_index_data.object_data_id "
"WHERE index_id = :index_id "
"AND value = :value"
);
}
return GetCachedStatement(
"SELECT data "
"FROM object_data "
"INNER JOIN index_data "
"ON object_data.id = index_data.object_data_id "
"WHERE index_id = :index_id "
"AND value = :value"
);
}
already_AddRefed<mozIStorageStatement>
IDBTransaction::IndexUpdateStatement(bool aAutoIncrement,
bool aUnique,

Просмотреть файл

@ -118,20 +118,6 @@ public:
bool aOverwrite,
bool aAutoIncrement);
already_AddRefed<mozIStorageStatement>
DeleteStatement(bool aAutoIncrement);
already_AddRefed<mozIStorageStatement>
GetStatement(bool aAutoIncrement);
already_AddRefed<mozIStorageStatement>
IndexGetStatement(bool aUnique,
bool aAutoIncrement);
already_AddRefed<mozIStorageStatement>
IndexGetObjectStatement(bool aUnique,
bool aAutoIncrement);
already_AddRefed<mozIStorageStatement>
IndexUpdateStatement(bool aAutoIncrement,
bool aUnique,

Просмотреть файл

@ -84,6 +84,7 @@ TEST_FILES = \
test_odd_result_order.html \
test_open_empty_db.html \
test_open_objectStore.html \
test_optionalArguments.html \
test_overlapping_transactions.html \
test_put_get_values.html \
test_put_get_values_autoIncrement.html \

Просмотреть файл

@ -304,7 +304,7 @@
request = cursor.delete();
request.onerror = errorHandler;
request.onsuccess = function(event) {
is(event.target.result, sortedKeys[4], "Correct key");
is(event.target.result, true, "Actually deleted something");
is(keyIndex, 5, "Got result of remove before next continue");
gotRemoveEvent = true;
};

Просмотреть файл

@ -101,20 +101,14 @@
is(event.target.result[i], values[parseInt(i) + 3], "Same value");
}
// Get should take a key range also.
// Get should take a key range also but it doesn't return an array.
request = db.transaction("foo").objectStore("foo").get(keyRange);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.target.result instanceof Array, true, "Got an array object");
is(event.target.result.length, 4, "Correct length");
for (let i in event.target.result) {
is(event.target.result[i], values[parseInt(i) + 3], "Same value");
}
keyRange = IDBKeyRange.bound(4, 7);
is(event.target.result instanceof Array, false, "Not an array object");
is(event.target.result, values[3], "Correct value");
request = db.transaction("foo").objectStore("foo").getAll(keyRange, 2);
request.onerror = errorHandler;

Просмотреть файл

@ -74,7 +74,7 @@
}, 0);
yield;
is(key, data.key, "Got the right key");
is(key, true, "Got the right key");
finishTest();
yield;

Разница между файлами не показана из-за своего большого размера Загрузить разницу