Changeset 129037 in webkit


Ignore:
Timestamp:
Sep 19, 2012 1:28:35 PM (12 years ago)
Author:
dgrogan@chromium.org
Message:

IndexedDB: fire upgradeneeded even without an explicit integer version
https://bugs.webkit.org/show_bug.cgi?id=96444

Reviewed by Tony Chang.

Source/WebCore:

Also of note:

  • New databases now get a default version of 1 instead of

the empty string when they are opened.

  • We now allow databases with an integer version to revert to a string

version by calling setVersion.

Implementation detail: we store both an integer version and string
version for a particular database. If both are set we give preference
to the integer version and assume the db is on the integer track.

Test: storage/indexeddb/intversion-two-opens-no-versions.html

  • Modules/indexeddb/IDBDatabaseBackendImpl.cpp:

(WebCore):
(WebCore::IDBDatabaseBackendImpl::IDBDatabaseBackendImpl):
(WebCore::IDBDatabaseBackendImpl::setVersion):
(WebCore::IDBDatabaseBackendImpl::setVersionInternal):
Now that this can be called even after an int version is set we have
to make it revoke the int version.

(WebCore::IDBDatabaseBackendImpl::openConnection):
Nested ifs were getting deep, so refactor to return early instead.

(WebCore::IDBDatabaseBackendImpl::deleteDatabase):
(WebCore::IDBDatabaseBackendImpl::resetVersion):
Now that an int version could have been set before setVersion was
called we have to reset the int version on abort.

  • Modules/indexeddb/IDBDatabaseBackendImpl.h:

(IDBDatabaseBackendImpl):

  • Modules/indexeddb/IDBLevelDBBackingStore.cpp:

(WebCore::IDBLevelDBBackingStore::updateIDBDatabaseIntVersion):

  • Modules/indexeddb/IDBOpenDBRequest.cpp:

0 is now a valid integer version to store to leveldb if an idb
database is reverting to a string version.

(WebCore::IDBOpenDBRequest::onUpgradeNeeded):
If the open request did not specify an integer version but
upgradeneeded is called, it means the database was given the default
version of 1.

LayoutTests:

Mostly updating expectations about getting an upgradeneeded on a new
database and the default version being 1 instead of "".

  • http/tests/inspector/indexeddb/database-structure-expected.txt:
  • storage/indexeddb/cursor-overloads-expected.txt:
  • storage/indexeddb/cursor-overloads.html:
  • storage/indexeddb/dont-commit-on-blocked-expected.txt:
  • storage/indexeddb/dont-commit-on-blocked.html:
  • storage/indexeddb/factory-deletedatabase-interactions-expected.txt:
  • storage/indexeddb/intversion-and-setversion-expected.txt:

Remove test that setVersion fires an error if an int version is set.
Change it to testing that an int version can replace a string version
that replaced an int version.

  • storage/indexeddb/intversion-bad-parameters-expected.txt:
  • storage/indexeddb/intversion-invalid-setversion-has-no-side-effects-expected.txt: Removed.

setVersion is no longer invalid so this test can be deleted.

  • storage/indexeddb/intversion-omit-parameter-expected.txt:

We now fully pass this test.

  • storage/indexeddb/intversion-two-opens-no-versions-expected.txt: Added.
  • storage/indexeddb/intversion-two-opens-no-versions.html: Renamed from LayoutTests/storage/indexeddb/intversion-invalid-setversion-has-no-side-effects.html.
  • storage/indexeddb/list-ordering-expected.txt:
  • storage/indexeddb/noblobs-expected.txt:
  • storage/indexeddb/noblobs.html:
  • storage/indexeddb/open-during-transaction-expected.txt:

This test had a bug in it AND its behavior is changed. It was trying
to open one database twice and another once but was actually opening
three different databases. The behavior change is that now the
transaction finishes while the last call to open is firing
upgradeneeded.

  • storage/indexeddb/pending-activity-expected.txt:
  • storage/indexeddb/pending-activity-workers-expected.txt:
  • storage/indexeddb/resources/intversion-and-setversion.js:

(deleteSuccess):
(initialUpgradeNeeded):
(openSuccess):
(firstUpgradeNeeded):
(transactionCompleted):
(firstOpenWithVersion):
(secondSetVersionCallback):
(setIntVersion2):
(versionChangeGoingFromStringToInt):
(version2ConnectionBlocked):
(version2ConnectionSuccess):
(errorWhenTryingLowVersion):

  • storage/indexeddb/resources/intversion-invalid-setversion-has-no-side-effects.js: Removed.
  • storage/indexeddb/resources/intversion-two-opens-no-versions.js: Added.

(test):
(deleteSuccess):
(connection1UpgradeNeeded):
(connection1OpenSuccess):
(connection2UpgradeNeeded):
(connection2OpenSuccess):

  • storage/indexeddb/resources/list-ordering.js:
  • storage/indexeddb/resources/open-during-transaction.js:

(startTransaction.trans.oncomplete):
(startTransaction):
(tryOpens.openreq3.onsuccess):
(tryOpens):

  • storage/indexeddb/resources/pending-activity.js:
  • storage/indexeddb/structured-clone-expected.txt:
  • storage/indexeddb/structured-clone.html:
Location:
trunk
Files:
2 added
2 deleted
27 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r129036 r129037  
     12012-09-19  David Grogan  <dgrogan@chromium.org>
     2
     3        IndexedDB: fire upgradeneeded even without an explicit integer version
     4        https://bugs.webkit.org/show_bug.cgi?id=96444
     5
     6        Reviewed by Tony Chang.
     7
     8        Mostly updating expectations about getting an upgradeneeded on a new
     9        database and the default version being 1 instead of "".
     10
     11        * http/tests/inspector/indexeddb/database-structure-expected.txt:
     12        * storage/indexeddb/cursor-overloads-expected.txt:
     13        * storage/indexeddb/cursor-overloads.html:
     14        * storage/indexeddb/dont-commit-on-blocked-expected.txt:
     15        * storage/indexeddb/dont-commit-on-blocked.html:
     16        * storage/indexeddb/factory-deletedatabase-interactions-expected.txt:
     17        * storage/indexeddb/intversion-and-setversion-expected.txt:
     18        Remove test that setVersion fires an error if an int version is set.
     19        Change it to testing that an int version can replace a string version
     20        that replaced an int version.
     21
     22        * storage/indexeddb/intversion-bad-parameters-expected.txt:
     23        * storage/indexeddb/intversion-invalid-setversion-has-no-side-effects-expected.txt: Removed.
     24        setVersion is no longer invalid so this test can be deleted.
     25
     26        * storage/indexeddb/intversion-omit-parameter-expected.txt:
     27        We now fully pass this test.
     28
     29        * storage/indexeddb/intversion-two-opens-no-versions-expected.txt: Added.
     30        * storage/indexeddb/intversion-two-opens-no-versions.html: Renamed from LayoutTests/storage/indexeddb/intversion-invalid-setversion-has-no-side-effects.html.
     31        * storage/indexeddb/list-ordering-expected.txt:
     32        * storage/indexeddb/noblobs-expected.txt:
     33        * storage/indexeddb/noblobs.html:
     34        * storage/indexeddb/open-during-transaction-expected.txt:
     35        This test had a bug in it AND its behavior is changed. It was trying
     36        to open one database twice and another once but was actually opening
     37        three different databases. The behavior change is that now the
     38        transaction finishes while the last call to open is firing
     39        upgradeneeded.
     40
     41        * storage/indexeddb/pending-activity-expected.txt:
     42        * storage/indexeddb/pending-activity-workers-expected.txt:
     43        * storage/indexeddb/resources/intversion-and-setversion.js:
     44        (deleteSuccess):
     45        (initialUpgradeNeeded):
     46        (openSuccess):
     47        (firstUpgradeNeeded):
     48        (transactionCompleted):
     49        (firstOpenWithVersion):
     50        (secondSetVersionCallback):
     51        (setIntVersion2):
     52        (versionChangeGoingFromStringToInt):
     53        (version2ConnectionBlocked):
     54        (version2ConnectionSuccess):
     55        (errorWhenTryingLowVersion):
     56        * storage/indexeddb/resources/intversion-invalid-setversion-has-no-side-effects.js: Removed.
     57        * storage/indexeddb/resources/intversion-two-opens-no-versions.js: Added.
     58        (test):
     59        (deleteSuccess):
     60        (connection1UpgradeNeeded):
     61        (connection1OpenSuccess):
     62        (connection2UpgradeNeeded):
     63        (connection2OpenSuccess):
     64        * storage/indexeddb/resources/list-ordering.js:
     65        * storage/indexeddb/resources/open-during-transaction.js:
     66        (startTransaction.trans.oncomplete):
     67        (startTransaction):
     68        (tryOpens.openreq3.onsuccess):
     69        (tryOpens):
     70        * storage/indexeddb/resources/pending-activity.js:
     71        * storage/indexeddb/structured-clone-expected.txt:
     72        * storage/indexeddb/structured-clone.html:
     73
    1742012-09-19  Dominic Mazzoni  <dmazzoni@google.com>
    275
  • trunk/LayoutTests/http/tests/inspector/indexeddb/database-structure-expected.txt

    r128642 r129037  
    1919Dumping database:
    2020testDatabase1
    21     version: 1
     21    version: 2
    2222    objectStores:
    2323    testObjectStore1
     
    2828Dumping database:
    2929testDatabase1
    30     version: 2
     30    version: 3
    3131    objectStores:
    3232    testObjectStore1
     
    4141Dumping database:
    4242testDatabase1
    43     version: 3
     43    version: 4
    4444    objectStores:
    4545    testObjectStore1
     
    5858Dumping database:
    5959testDatabase1
    60     version: 4
     60    version: 5
    6161    objectStores:
    6262    testObjectStore1
     
    7979Dumping database:
    8080testDatabase1
    81     version: 5
     81    version: 6
    8282    objectStores:
    8383    testObjectStore1
     
    9696Dumping database:
    9797testDatabase1
    98     version: 6
     98    version: 7
    9999    objectStores:
    100100    testObjectStore1
     
    109109Dumping database:
    110110testDatabase1
    111     version: 7
     111    version: 8
    112112    objectStores:
    113113    testObjectStore1
     
    118118Dumping database:
    119119testDatabase1
    120     version: 8
     120    version: 9
    121121    objectStores:
    122122
  • trunk/LayoutTests/storage/indexeddb/cursor-overloads-expected.txt

    r128642 r129037  
    3434indexedDB.open(dbname)
    3535db = request.result
    36 PASS db.version is ""
     36PASS db.version is 1
    3737db.setVersion('1')
    3838store = db.createObjectStore('store')
  • trunk/LayoutTests/storage/indexeddb/cursor-overloads.html

    r123048 r129037  
    2121        request.onsuccess = function(e) {
    2222            evalAndLog("db = request.result");
    23             shouldBeEqualToString("db.version", "");
     23            shouldBe("db.version", '1');
    2424            request = evalAndLog("db.setVersion('1')");
    2525            request.onerror = unexpectedErrorCallback;
  • trunk/LayoutTests/storage/indexeddb/dont-commit-on-blocked-expected.txt

    r113485 r129037  
    1111db = request.result
    1212db.onversionchange = onVersionChange
    13 PASS db.version is ""
     13PASS db.version is 1
    1414db.setVersion('1')
    1515store = db.createObjectStore('store1')
  • trunk/LayoutTests/storage/indexeddb/dont-commit-on-blocked.html

    r113485 r129037  
    2727            db.onerror = unexpectedErrorCallback;
    2828            evalAndLog("db.onversionchange = onVersionChange");
    29             shouldBeEqualToString("db.version", "");
     29            shouldBe("db.version", "1");
    3030            request = evalAndLog("db.setVersion('1')");
    3131            request.onerror = unexpectedErrorCallback;
  • trunk/LayoutTests/storage/indexeddb/factory-deletedatabase-interactions-expected.txt

    r128642 r129037  
    1313'deleteDatabase()'
    1414'h.onversionchange'
    15     in versionchange, old = "" new = ""
     15    in versionchange, old = 1 new = ""
    1616    h closing, but not immediately
    1717'deleteDatabase().onblocked'
     
    2626'deleteDatabase()'
    2727'h.onversionchange'
    28     in versionchange, old = "" new = ""
     28    in versionchange, old = 1 new = ""
    2929    h closing immediately
    3030'h.close'
     
    5959'deleteDatabase()'
    6060'h2.onversionchange'
    61     in versionchange, old = "" new = "1"
     61    in versionchange, old = 1 new = "1"
    6262'h.setVersion.onblocked'
    6363'h3.open'
  • trunk/LayoutTests/storage/indexeddb/intversion-and-setversion-expected.txt

    r128642 r129037  
    1313indexedDB.open(dbname)
    1414
     15initialUpgradeNeeded():
     16
    1517openSuccess():
    1618db = event.target.result
    17 PASS db.version is ""
     19PASS db.version is 1
    1820request = db.setVersion("some version")
    1921
     
    4850PASS didTransactionComplete is true
    4951db = event.target.result
     52db.onversionchange = versionChangeGoingFromStringToInt
    5053PASS String(db) is "[object IDBDatabase]"
    5154PASS request.transaction is null
     
    5457request = db.setVersion("string version 2")
    5558PASS String(request) is "[object IDBVersionChangeRequest]"
    56 request.onerror = setVersionNotAllowed
     59request.onsuccess = secondSetVersionCallback
    5760
    58 setVersionNotAllowed():
    59 PASS event.type is "error"
    60 request.webkitErrorMessage = You can't use the setVersion function if you've already set the version through an open call.  The current integer version is 2
     61secondSetVersionCallback():
     62transaction = event.target.result
     63transaction.oncomplete = setIntVersion2
     64
     65setIntVersion2():
     66request = indexedDB.open(dbname, 2)
     67request.onsuccess = version2ConnectionSuccess
     68request.onblocked = version2ConnectionBlocked
     69
     70versionChangeGoingFromStringToInt():
    6171db.close()
     72
     73version2ConnectionBlocked():
     74
     75version2ConnectionSuccess():
     76event.target.result.close()
    6277request = indexedDB.open(dbname, 1)
    6378request.onerror = errorWhenTryingLowVersion
  • trunk/LayoutTests/storage/indexeddb/intversion-bad-parameters-expected.txt

    r127049 r129037  
    2323Expecting TypeError exception from request = indexedDB.open(dbname, -1)
    2424FAIL No exception thrown!
    25 FAIL Success function called unexpectedly.
     25FAIL onupgradeneeded called unexpectedly
    2626PASS successfullyParsed is true
    2727
  • trunk/LayoutTests/storage/indexeddb/intversion-omit-parameter-expected.txt

    r124383 r129037  
    99indexedDB.deleteDatabase(dbname)
    1010indexedDB.open(dbname)
     11PASS Got upgradeneeded event
    1112
    1213openSuccess():
    1314db = event.target.result
    1415Test line from IDBFactory.open: If no version is specified and no database exists, set database version to 1.
    15 FAIL db.version should be 1 (of type number). Was  (of type string).
     16PASS db.version is 1
    1617PASS successfullyParsed is true
    1718
  • trunk/LayoutTests/storage/indexeddb/intversion-two-opens-no-versions.html

    r129036 r129037  
    55</head>
    66<body>
    7 <script src="resources/intversion-invalid-setversion-has-no-side-effects.js"></script>
     7<script src="resources/intversion-two-opens-no-versions.js"></script>
    88<script src="../../fast/js/resources/js-test-post.js"></script>
    99</body>
  • trunk/LayoutTests/storage/indexeddb/list-ordering-expected.txt

    r128642 r129037  
    1414indexedDB.open('list-ordering')
    1515db = request.result
    16 PASS db.version is ""
     16PASS db.version is 1
    1717db.setVersion('1')
    1818
  • trunk/LayoutTests/storage/indexeddb/noblobs-expected.txt

    r128642 r129037  
    1111indexedDB.open('noblobs')
    1212db = request.result
    13 PASS db.version is ""
     13PASS db.version is 1
    1414db.setVersion('1')
    1515store = db.createObjectStore('storeName')
  • trunk/LayoutTests/storage/indexeddb/noblobs.html

    r116337 r129037  
    3939        request.onsuccess = function(e) {
    4040            evalAndLog("db = request.result");
    41             shouldBeEqualToString("db.version", "");
     41            shouldBe("db.version", "1");
    4242            request = evalAndLog("db.setVersion('1')");
    4343            request.onerror = unexpectedErrorCallback;
  • trunk/LayoutTests/storage/indexeddb/open-during-transaction-expected.txt

    r128642 r129037  
    2020
    2121trying to open the same database
    22 openreq2 = indexedDB.open('db1')
     22openreq2 = indexedDB.open('open-during-transaction1')
    2323
    2424trying to open a different database
     
    2929state = 'open2complete'
    3030
     31transaction complete
     32PASS state is "open2complete"
     33
    3134openreq3.onsuccess
    3235PASS state is "open2complete"
    3336state = 'open3complete'
    34 
    35 transaction complete
    36 PASS state is "open3complete"
    3737PASS successfullyParsed is true
    3838
  • trunk/LayoutTests/storage/indexeddb/pending-activity-expected.txt

    r128642 r129037  
    1212indexedDB.open(dbname)
    1313db = request.result
    14 PASS db.version is ""
     14PASS db.version is 1
    1515db.setVersion('1')
    1616store = db.createObjectStore('store')
  • trunk/LayoutTests/storage/indexeddb/pending-activity-workers-expected.txt

    r128642 r129037  
    1313[Worker] indexedDB.open(dbname)
    1414[Worker] db = request.result
    15 PASS [Worker] db.version is ""
     15PASS [Worker] db.version is 1
    1616[Worker] db.setVersion('1')
    1717[Worker] store = db.createObjectStore('store')
  • trunk/LayoutTests/storage/indexeddb/resources/intversion-and-setversion.js

    r124383 r129037  
    2323    request.onsuccess = openSuccess;
    2424    request.onerror = unexpectedErrorCallback;
    25     request.onupgradeneeded = unexpectedUpgradeNeededCallback;
    26     request.onblocked = unexpectedBlockedCallback;
     25    request.onupgradeneeded = initialUpgradeNeeded;
     26    request.onblocked = unexpectedBlockedCallback;
     27}
     28
     29
     30function initialUpgradeNeeded(evt)
     31{
     32    preamble(evt);
    2733}
    2834
     
    3339    debug("openSuccess():");
    3440    db = evalAndLog("db = event.target.result");
    35     shouldBeEqualToString("db.version", "");
     41    shouldBe("db.version", "1");
    3642    evalAndLog('request = db.setVersion("some version")');
    3743    request.onsuccess = inSetVersion;
     
    8692function firstUpgradeNeeded(evt)
    8793{
    88     event = evt;
    89     debug("");
    90     debug("firstUpgradeNeeded():");
     94    preamble(evt);
    9195    evalAndLog("db = event.target.result");
    9296    shouldBeEqualToString("String(db)", "[object IDBDatabase]");
     
    101105function transactionCompleted(evt)
    102106{
    103     event = evt;
    104     debug("");
    105     debug("transactionCompleted():");
     107    preamble(evt);
    106108    evalAndLog("didTransactionComplete = true");
    107109}
     
    109111function firstOpenWithVersion(evt)
    110112{
    111     event = evt;
    112     debug("");
    113     debug("firstOpenWithVersion():");
     113    preamble(evt);
    114114    shouldBeTrue("didTransactionComplete");
    115115    evalAndLog("db = event.target.result");
     116    evalAndLog("db.onversionchange = versionChangeGoingFromStringToInt");
    116117    shouldBeEqualToString("String(db)", "[object IDBDatabase]");
    117118    shouldBeNull("request.transaction");
     
    120121    evalAndLog('request = db.setVersion("string version 2")');
    121122    shouldBeEqualToString("String(request)", "[object IDBVersionChangeRequest]");
    122     request.onblocked = unexpectedBlockedCallback;
    123     request.onsuccess = unexpectedSuccessCallback;
    124     evalAndLog("request.onerror = setVersionNotAllowed");
    125 }
    126 
    127 function setVersionNotAllowed(evt)
    128 {
    129     event = evt;
    130     debug("");
    131     debug("setVersionNotAllowed():");
    132     shouldBeEqualToString("event.type", "error");
    133     debug("request.webkitErrorMessage = " + request.webkitErrorMessage);
    134     evalAndLog("db.close()");
     123    evalAndLog("request.onsuccess = secondSetVersionCallback");
     124    request.onblocked = unexpectedBlockedCallback;
     125    request.onerror = unexpectedErrorCallback;
     126}
     127
     128function secondSetVersionCallback(evt)
     129{
     130    preamble(evt);
     131    evalAndLog("transaction = event.target.result");
     132    evalAndLog("transaction.oncomplete = setIntVersion2");
     133}
     134
     135function setIntVersion2(evt)
     136{
     137    preamble(evt);
     138    evalAndLog("request = indexedDB.open(dbname, 2)");
     139    evalAndLog("request.onsuccess = version2ConnectionSuccess");
     140    evalAndLog("request.onblocked = version2ConnectionBlocked");
     141    request.onerror = unexpectedErrorCallback;
     142}
     143
     144function versionChangeGoingFromStringToInt(evt)
     145{
     146    preamble(evt);
     147    evalAndLog("db.close()");
     148}
     149
     150function version2ConnectionBlocked(evt)
     151{
     152    preamble(evt);
     153}
     154
     155function version2ConnectionSuccess(evt)
     156{
     157    preamble(evt);
     158    evalAndLog("event.target.result.close()");
    135159    evalAndLog("request = indexedDB.open(dbname, 1)");
    136160    evalAndLog("request.onerror = errorWhenTryingLowVersion");
    137161    request.onblocked = unexpectedBlockedCallback;
    138162    request.onsuccess = unexpectedSuccessCallback;
     163    request.onupgradeneeded = unexpectedUpgradeNeededCallback;
    139164}
    140165
    141166function errorWhenTryingLowVersion(evt)
    142167{
    143     event = evt;
    144     debug("");
    145     debug("errorWhenTryingLowVersion():");
     168    preamble(evt);
    146169    debug("request.webkitErrorMessage = " + request.webkitErrorMessage);
    147170    evalAndLog("request = indexedDB.open(dbname, 4)");
  • trunk/LayoutTests/storage/indexeddb/resources/list-ordering.js

    r112202 r129037  
    5353        request.onsuccess = function(e) {
    5454            evalAndLog("db = request.result");
    55             shouldBeEqualToString("db.version", "");
     55            shouldBe("db.version", "1");
    5656            request = evalAndLog("db.setVersion('1')");
    5757            request.onerror = unexpectedErrorCallback;
  • trunk/LayoutTests/storage/indexeddb/resources/open-during-transaction.js

    r120976 r129037  
    4646    trans.oncomplete = function (e) {
    4747        debug("transaction complete");
    48         shouldBeEqualToString("state", "open3complete");
    49         finishJSTest();
     48        shouldBeEqualToString("state", "open2complete");
     49        debug("");
    5050    };
    5151
     
    5757{
    5858    debug("trying to open the same database");
    59     evalAndLog("openreq2 = indexedDB.open('db1')");
     59    evalAndLog("openreq2 = indexedDB.open('open-during-transaction1')");
    6060    openreq2.onerror = unexpectedErrorCallback;
    6161    openreq2.onsuccess = function (e) {
     
    7474        shouldBeEqualToString("state", "open2complete");
    7575        evalAndLog("state = 'open3complete'");
    76         debug("");
     76        finishJSTest();
    7777    }
    7878    debug("");
  • trunk/LayoutTests/storage/indexeddb/resources/pending-activity.js

    r126254 r129037  
    2323        request.onsuccess = function(e) {
    2424            evalAndLog("db = request.result");
    25             shouldBeEqualToString("db.version", "");
     25            shouldBe("db.version", "1");
    2626            request = evalAndLog("db.setVersion('1')");
    2727            request.onerror = unexpectedErrorCallback;
  • trunk/LayoutTests/storage/indexeddb/structured-clone-expected.txt

    r128642 r129037  
    1111indexedDB.open('structured-clone')
    1212db = request.result
    13 PASS db.version is ""
     13PASS db.version is 1
    1414db.setVersion('1')
    1515store = db.createObjectStore('storeName')
  • trunk/LayoutTests/storage/indexeddb/structured-clone.html

    r122262 r129037  
    3737        request.onsuccess = function(e) {
    3838            evalAndLog("db = request.result");
    39             shouldBeEqualToString("db.version", "");
     39            shouldBe("db.version", "1");
    4040            request = evalAndLog("db.setVersion('1')");
    4141            request.onerror = unexpectedErrorCallback;
  • trunk/Source/WebCore/ChangeLog

    r129036 r129037  
     12012-09-19  David Grogan  <dgrogan@chromium.org>
     2
     3        IndexedDB: fire upgradeneeded even without an explicit integer version
     4        https://bugs.webkit.org/show_bug.cgi?id=96444
     5
     6        Reviewed by Tony Chang.
     7
     8        Also of note:
     9        - New databases now get a default version of 1 instead of
     10        the empty string when they are opened.
     11        - We now allow databases with an integer version to revert to a string
     12        version by calling setVersion.
     13
     14        Implementation detail: we store both an integer version and string
     15        version for a particular database. If both are set we give preference
     16        to the integer version and assume the db is on the integer track.
     17
     18        Test: storage/indexeddb/intversion-two-opens-no-versions.html
     19
     20        * Modules/indexeddb/IDBDatabaseBackendImpl.cpp:
     21        (WebCore):
     22        (WebCore::IDBDatabaseBackendImpl::IDBDatabaseBackendImpl):
     23        (WebCore::IDBDatabaseBackendImpl::setVersion):
     24        (WebCore::IDBDatabaseBackendImpl::setVersionInternal):
     25        Now that this can be called even after an int version is set we have
     26        to make it revoke the int version.
     27
     28        (WebCore::IDBDatabaseBackendImpl::openConnection):
     29        Nested ifs were getting deep, so refactor to return early instead.
     30
     31        (WebCore::IDBDatabaseBackendImpl::deleteDatabase):
     32        (WebCore::IDBDatabaseBackendImpl::resetVersion):
     33        Now that an int version could have been set before setVersion was
     34        called we have to reset the int version on abort.
     35
     36        * Modules/indexeddb/IDBDatabaseBackendImpl.h:
     37        (IDBDatabaseBackendImpl):
     38        * Modules/indexeddb/IDBLevelDBBackingStore.cpp:
     39        (WebCore::IDBLevelDBBackingStore::updateIDBDatabaseIntVersion):
     40        * Modules/indexeddb/IDBOpenDBRequest.cpp:
     41        0 is now a valid integer version to store to leveldb if an idb
     42        database is reverting to a string version.
     43
     44        (WebCore::IDBOpenDBRequest::onUpgradeNeeded):
     45        If the open request did not specify an integer version but
     46        upgradeneeded is called, it means the database was given the default
     47        version of 1.
     48
    1492012-09-19  Dominic Mazzoni  <dmazzoni@google.com>
    250
  • trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.cpp

    r128795 r129037  
    128128}
    129129
     130namespace {
     131const char* NoStringVersion = "";
     132}
     133
    130134IDBDatabaseBackendImpl::IDBDatabaseBackendImpl(const String& name, IDBBackingStore* backingStore, IDBTransactionCoordinator* coordinator, IDBFactoryBackendImpl* factory, const String& uniqueIdentifier)
    131135    : m_backingStore(backingStore)
    132136    , m_id(InvalidId)
    133137    , m_name(name)
    134     , m_version("")
     138    , m_version(NoStringVersion)
    135139    , m_intVersion(IDBDatabaseMetadata::NoIntVersion)
    136140    , m_identifier(uniqueIdentifier)
     
    239243    if (!m_databaseCallbacksSet.contains(databaseCallbacks)) {
    240244        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::IDB_ABORT_ERR, "Connection was closed before set version transaction was created"));
    241         return;
    242     }
    243     if (m_intVersion != IDBDatabaseMetadata::NoIntVersion) {
    244         callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, String::format("You can't use the setVersion function if you've already set the version through an open call.  The current integer version is %lld", static_cast<long long>(m_intVersion))));
    245245        return;
    246246    }
     
    273273    if (!transaction->scheduleTask(
    274274            createCallbackTask(&IDBDatabaseBackendImpl::setVersionInternal, database, version, callbacks, transaction),
    275             createCallbackTask(&IDBDatabaseBackendImpl::resetVersion, database, m_version))) {
     275            createCallbackTask(&IDBDatabaseBackendImpl::resetVersion, database, m_version, m_intVersion))) {
    276276        // FIXME: Remove one of the following lines.
    277277        ASSERT_NOT_REACHED();
     
    285285    int64_t databaseId = database->id();
    286286    database->m_version = version;
    287     if (!database->m_backingStore->updateIDBDatabaseMetaData(databaseId, database->m_version)) {
     287    database->m_intVersion = IDBDatabaseMetadata::NoIntVersion;
     288    if (!database->m_backingStore->updateIDBDatabaseMetaData(databaseId, database->m_version) || !database->m_backingStore->updateIDBDatabaseIntVersion(databaseId, database->m_intVersion)) {
    288289        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Error writing data to stable storage."));
    289290        transaction->abort();
     
    438439{
    439440    ASSERT(m_backingStore.get());
    440     if (!m_pendingDeleteCalls.isEmpty() || m_runningVersionChangeTransaction || !m_pendingSetVersionCalls.isEmpty())
     441    if (!m_pendingDeleteCalls.isEmpty() || m_runningVersionChangeTransaction || !m_pendingSetVersionCalls.isEmpty()) {
    441442        m_pendingOpenCalls.append(PendingOpenCall::create(callbacks, databaseCallbacks));
    442     else {
    443         if (m_id == InvalidId && !openInternal())
    444             callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Internal error."));
    445         else {
    446             m_databaseCallbacksSet.add(RefPtr<IDBDatabaseCallbacks>(databaseCallbacks));
    447             callbacks->onSuccess(this);
    448         }
    449     }
     443        return;
     444    }
     445    if (m_id == InvalidId && !openInternal()) {
     446        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Internal error."));
     447        return;
     448    }
     449    if (m_version == NoStringVersion && m_intVersion == IDBDatabaseMetadata::NoIntVersion) {
     450        // Spec says: If no version is specified and no database exists, set
     451        // database version to 1. We infer that the database didn't exist from
     452        // its lack of either type of version.
     453        openConnectionWithVersion(callbacks, databaseCallbacks, 1);
     454        return;
     455    }
     456    m_databaseCallbacksSet.add(RefPtr<IDBDatabaseCallbacks>(databaseCallbacks));
     457    callbacks->onSuccess(this);
    450458}
    451459
     
    483491    RefPtr<IDBDatabaseBackendImpl> database = this;
    484492    OwnPtr<ScriptExecutionContext::Task> intVersionTask = createCallbackTask(&IDBDatabaseBackendImpl::setIntVersionInternal, database, requestedVersion, callbacks, transaction);
    485     OwnPtr<ScriptExecutionContext::Task> resetVersionOnAbortTask = createCallbackTask(&IDBDatabaseBackendImpl::resetIntVersion, database, m_intVersion);
     493    OwnPtr<ScriptExecutionContext::Task> resetVersionOnAbortTask = createCallbackTask(&IDBDatabaseBackendImpl::resetVersion, database, m_version, m_intVersion);
    486494    if (!transaction->scheduleTask(intVersionTask.release(), resetVersionOnAbortTask.release())) {
    487495        // FIXME: Remove one of the following lines.
     
    532540    for (DatabaseCallbacksSet::const_iterator it = m_databaseCallbacksSet.begin(); it != m_databaseCallbacksSet.end(); ++it) {
    533541        // Front end ensures the event is not fired at connections that have closePending set.
    534         (*it)->onVersionChange("");
     542        (*it)->onVersionChange(NoStringVersion);
    535543    }
    536544    // FIXME: Only fire onBlocked if there are open connections after the
     
    547555        return;
    548556    }
    549     m_version = "";
     557    m_version = NoStringVersion;
    550558    m_id = InvalidId;
    551559    m_intVersion = IDBDatabaseMetadata::NoIntVersion;
     
    618626}
    619627
    620 void IDBDatabaseBackendImpl::resetVersion(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl> database, const String& version)
    621 {
    622     database->m_version = version;
    623 }
    624 
    625 void IDBDatabaseBackendImpl::resetIntVersion(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl> database, int64_t oldVersion)
    626 {
    627     database->m_intVersion = oldVersion;
    628 }
    629 
     628void IDBDatabaseBackendImpl::resetVersion(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl> database, const String& previousVersion, int64_t previousIntVersion)
     629{
     630    database->m_version = previousVersion;
     631    database->m_intVersion = previousIntVersion;
     632}
    630633
    631634} // namespace WebCore
  • trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.h

    r128533 r129037  
    9292    static void removeObjectStoreFromMap(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl>, PassRefPtr<IDBObjectStoreBackendImpl>);
    9393    static void addObjectStoreToMap(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl>, PassRefPtr<IDBObjectStoreBackendImpl>);
    94     static void resetVersion(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl>, const String& version);
    95     static void resetIntVersion(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl>, int64_t intVersion);
     94    static void resetVersion(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl>, const String& version, int64_t intVersion);
    9695
    9796    RefPtr<IDBBackingStore> m_backingStore;
  • trunk/Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.cpp

    r128217 r129037  
    340340{
    341341    ASSERT(m_currentTransaction);
    342     // FIXME: Change this to strictly greater than 0 once we throw TypeError for
    343     // bad versions.
     342    if (intVersion == IDBDatabaseMetadata::NoIntVersion)
     343        intVersion = IDBDatabaseMetadata::DefaultIntVersion;
    344344    ASSERT_WITH_MESSAGE(intVersion >= 0, "intVersion was %lld", static_cast<long long>(intVersion));
    345345    if (!putVarInt(m_currentTransaction.get(), DatabaseMetaDataKey::encode(rowId, DatabaseMetaDataKey::UserIntVersion), intVersion))
  • trunk/Source/WebCore/Modules/indexeddb/IDBOpenDBRequest.cpp

    r128674 r129037  
    8989
    9090    if (oldVersion == IDBDatabaseMetadata::NoIntVersion) {
    91       // This database hasn't had an integer version before.
    92       oldVersion = IDBDatabaseMetadata::DefaultIntVersion;
     91        // This database hasn't had an integer version before.
     92        oldVersion = IDBDatabaseMetadata::DefaultIntVersion;
    9393    }
     94    if (m_version == IDBDatabaseMetadata::NoIntVersion)
     95        m_version = 1;
    9496    enqueueEvent(IDBUpgradeNeededEvent::create(oldVersion, m_version, eventNames().upgradeneededEvent));
    9597}
Note: See TracChangeset for help on using the changeset viewer.