Changeset 70522 in webkit


Ignore:
Timestamp:
Oct 26, 2010 8:21:32 AM (14 years ago)
Author:
jorlow@chromium.org
Message:

2010-10-26 Jeremy Orlow <jorlow@chromium.org>

Reviewed by Steve Block.

Quota for IndexedDB should be per origin not per database
https://bugs.webkit.org/show_bug.cgi?id=48064

Verify our backing database can handle multiple indexes, objectStores,
items in the index/object stores, etc within databases of different
names.

Also adjust the quota test so it doesn't fail with subtle differences
in the backing db (which can change the size a bit).

  • storage/indexeddb/database-quota-expected.txt:
  • storage/indexeddb/database-quota.html:
  • storage/indexeddb/duplicates-expected.txt: Added.
  • storage/indexeddb/duplicates.html: Added.

2010-10-26 Jeremy Orlow <jorlow@chromium.org>

Reviewed by Steve Block.

Quota for IndexedDB should be per origin not per database
https://bugs.webkit.org/show_bug.cgi?id=48064

Merge all databases for each origin into a single SQLiteDatabase.

Replace the awkward metaData table with a Database table.

Create a new IDBSQLiteDatabase class that wraps SQLiteDatabase
and implements weak pointer semantics for IDBFactory. It's ref
counted so multiple IDBDatabaseBackendImpls can share one.

Fix uniqueness constraints that were overly conservitive.

Get rid of the code that blows away existing data every time
the database is opened.

Get rid of the fairly useless indexedDB manual test and replace
it with one that verifies data persists.

Use name+origin (not just name) in our cache of IDBDatabaseBackend
objects (so one origin can't access anothers' data).

Test: storage/indexeddb/duplicates.html

  • WebCore.gypi:
  • manual-tests/indexed-database.html: Removed.
  • manual-tests/indexeddb-persists.html: Added.
  • storage/IDBDatabaseBackendImpl.cpp: (WebCore::extractMetaData): (WebCore::setMetaData): (WebCore::IDBDatabaseBackendImpl::IDBDatabaseBackendImpl): (WebCore::IDBDatabaseBackendImpl::setDescription): (WebCore::IDBDatabaseBackendImpl::sqliteDatabase): (WebCore::IDBDatabaseBackendImpl::createObjectStoreInternal): (WebCore::IDBDatabaseBackendImpl::setVersionInternal): (WebCore::IDBDatabaseBackendImpl::loadObjectStores):
  • storage/IDBDatabaseBackendImpl.h: (WebCore::IDBDatabaseBackendImpl::create): (WebCore::IDBDatabaseBackendImpl::id):
  • storage/IDBFactoryBackendImpl.cpp: (WebCore::IDBFactoryBackendImpl::removeSQLiteDatabase): (WebCore::openSQLiteDatabase): (WebCore::createTables): (WebCore::IDBFactoryBackendImpl::open): (WebCore::IDBFactoryBackendImpl::databaseFileName):
  • storage/IDBFactoryBackendImpl.h:
  • storage/IDBObjectStoreBackendImpl.cpp: (WebCore::putObjectStoreData): (WebCore::IDBObjectStoreBackendImpl::putInternal):
  • storage/IDBSQLiteDatabase.cpp: Added. (WebCore::IDBSQLiteDatabase::IDBSQLiteDatabase): (WebCore::IDBSQLiteDatabase::~IDBSQLiteDatabase):
  • storage/IDBSQLiteDatabase.h: Added. (WebCore::IDBSQLiteDatabase::create): (WebCore::IDBSQLiteDatabase::db):

2010-10-26 Jeremy Orlow <jorlow@chromium.org>

Reviewed by Steve Block.

Quota for IndexedDB should be per origin not per database
https://bugs.webkit.org/show_bug.cgi?id=48064

  • public/WebIDBFactory.h:
  • public/WebSecurityOrigin.h:
  • src/WebIDBFactory.cpp: (WebKit::WebIDBFactory::databaseFileName):
  • src/WebSecurityOrigin.cpp: (WebKit::WebSecurityOrigin::get):
Location:
trunk
Files:
4 added
1 deleted
17 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r70521 r70522  
     12010-10-26  Jeremy Orlow  <jorlow@chromium.org>
     2
     3        Reviewed by Steve Block.
     4
     5        Quota for IndexedDB should be per origin not per database
     6        https://bugs.webkit.org/show_bug.cgi?id=48064
     7
     8        Verify our backing database can handle multiple indexes, objectStores,
     9        items in the index/object stores, etc within databases of different
     10        names.
     11
     12        Also adjust the quota test so it doesn't fail with subtle differences
     13        in the backing db (which can change the size a bit).
     14
     15        * storage/indexeddb/database-quota-expected.txt:
     16        * storage/indexeddb/database-quota.html:
     17        * storage/indexeddb/duplicates-expected.txt: Added.
     18        * storage/indexeddb/duplicates.html: Added.
     19
    1202010-10-26  Jeremy Orlow  <jorlow@chromium.org>
    221
  • trunk/LayoutTests/storage/indexeddb/database-quota-expected.txt

    r69612 r70522  
    6969PASS data.length is 65536
    7070store = trans.objectStore('test123')
    71 store.add({x: data}, dataAdded)
    72 Success event fired:
    73 PASS 'result' in event is true
    74 PASS 'code' in event is false
    75 PASS 'message' in event is false
    76 PASS 'source' in event is true
    77 PASS event.source != null is true
    78 PASS 'onsuccess' in event.target is true
    79 PASS 'onerror' in event.target is true
    80 PASS 'readyState' in event.target is true
    81 PASS event.target.readyState is event.target.DONE
    82 
    83 store = event.source
    84 store.add({x: data}, dataAdded)
    85 Success event fired:
    86 PASS 'result' in event is true
    87 PASS 'code' in event is false
    88 PASS 'message' in event is false
    89 PASS 'source' in event is true
    90 PASS event.source != null is true
    91 PASS 'onsuccess' in event.target is true
    92 PASS 'onerror' in event.target is true
    93 PASS 'readyState' in event.target is true
    94 PASS event.target.readyState is event.target.DONE
    95 
    96 store = event.source
    97 store.add({x: data}, dataAdded)
    98 Success event fired:
    99 PASS 'result' in event is true
    100 PASS 'code' in event is false
    101 PASS 'message' in event is false
    102 PASS 'source' in event is true
    103 PASS event.source != null is true
    104 PASS 'onsuccess' in event.target is true
    105 PASS 'onerror' in event.target is true
    106 PASS 'readyState' in event.target is true
    107 PASS event.target.readyState is event.target.DONE
    108 
    109 store = event.source
    110 store.add({x: data}, dataAdded)
    111 Success event fired:
    112 PASS 'result' in event is true
    113 PASS 'code' in event is false
    114 PASS 'message' in event is false
    115 PASS 'source' in event is true
    116 PASS event.source != null is true
    117 PASS 'onsuccess' in event.target is true
    118 PASS 'onerror' in event.target is true
    119 PASS 'readyState' in event.target is true
    120 PASS event.target.readyState is event.target.DONE
    121 
    122 store = event.source
    123 store.add({x: data}, dataAdded)
    124 Success event fired:
    125 PASS 'result' in event is true
    126 PASS 'code' in event is false
    127 PASS 'message' in event is false
    128 PASS 'source' in event is true
    129 PASS event.source != null is true
    130 PASS 'onsuccess' in event.target is true
    131 PASS 'onerror' in event.target is true
    132 PASS 'readyState' in event.target is true
    133 PASS event.target.readyState is event.target.DONE
    134 
    135 store = event.source
    136 store.add({x: data}, dataAdded)
    137 Success event fired:
    138 PASS 'result' in event is true
    139 PASS 'code' in event is false
    140 PASS 'message' in event is false
    141 PASS 'source' in event is true
    142 PASS event.source != null is true
    143 PASS 'onsuccess' in event.target is true
    144 PASS 'onerror' in event.target is true
    145 PASS 'readyState' in event.target is true
    146 PASS event.target.readyState is event.target.DONE
    147 
    148 store = event.source
    149 store.add({x: data}, dataAdded)
    150 Success event fired:
    151 PASS 'result' in event is true
    152 PASS 'code' in event is false
    153 PASS 'message' in event is false
    154 PASS 'source' in event is true
    155 PASS event.source != null is true
    156 PASS 'onsuccess' in event.target is true
    157 PASS 'onerror' in event.target is true
    158 PASS 'readyState' in event.target is true
    159 PASS event.target.readyState is event.target.DONE
    160 
    161 store = event.source
    162 store.add({x: data}, dataAdded)
    163 Success event fired:
    164 PASS 'result' in event is true
    165 PASS 'code' in event is false
    166 PASS 'message' in event is false
    167 PASS 'source' in event is true
    168 PASS event.source != null is true
    169 PASS 'onsuccess' in event.target is true
    170 PASS 'onerror' in event.target is true
    171 PASS 'readyState' in event.target is true
    172 PASS event.target.readyState is event.target.DONE
    173 
    174 store = event.source
    175 store.add({x: data}, dataAdded)
    176 Success event fired:
    177 PASS 'result' in event is true
    178 PASS 'code' in event is false
    179 PASS 'message' in event is false
    180 PASS 'source' in event is true
    181 PASS event.source != null is true
    182 PASS 'onsuccess' in event.target is true
    183 PASS 'onerror' in event.target is true
    184 PASS 'readyState' in event.target is true
    185 PASS event.target.readyState is event.target.DONE
    186 
    187 store = event.source
    188 store.add({x: data}, dataAdded)
    189 Success event fired:
    190 PASS 'result' in event is true
    191 PASS 'code' in event is false
    192 PASS 'message' in event is false
    193 PASS 'source' in event is true
    194 PASS event.source != null is true
    195 PASS 'onsuccess' in event.target is true
    196 PASS 'onerror' in event.target is true
    197 PASS 'readyState' in event.target is true
    198 PASS event.target.readyState is event.target.DONE
    199 
    200 store = event.source
    201 store.add({x: data}, dataAdded)
    202 Success event fired:
    203 PASS 'result' in event is true
    204 PASS 'code' in event is false
    205 PASS 'message' in event is false
    206 PASS 'source' in event is true
    207 PASS event.source != null is true
    208 PASS 'onsuccess' in event.target is true
    209 PASS 'onerror' in event.target is true
    210 PASS 'readyState' in event.target is true
    211 PASS event.target.readyState is event.target.DONE
    212 
    213 store = event.source
    214 store.add({x: data}, dataAdded)
    215 Success event fired:
    216 PASS 'result' in event is true
    217 PASS 'code' in event is false
    218 PASS 'message' in event is false
    219 PASS 'source' in event is true
    220 PASS event.source != null is true
    221 PASS 'onsuccess' in event.target is true
    222 PASS 'onerror' in event.target is true
    223 PASS 'readyState' in event.target is true
    224 PASS event.target.readyState is event.target.DONE
    225 
    226 store = event.source
    227 store.add({x: data}, dataAdded)
    228 Success event fired:
    229 PASS 'result' in event is true
    230 PASS 'code' in event is false
    231 PASS 'message' in event is false
    232 PASS 'source' in event is true
    233 PASS event.source != null is true
    234 PASS 'onsuccess' in event.target is true
    235 PASS 'onerror' in event.target is true
    236 PASS 'readyState' in event.target is true
    237 PASS event.target.readyState is event.target.DONE
    238 
    239 store = event.source
    240 store.add({x: data}, dataAdded)
    241 Success event fired:
    242 PASS 'result' in event is true
    243 PASS 'code' in event is false
    244 PASS 'message' in event is false
    245 PASS 'source' in event is true
    246 PASS event.source != null is true
    247 PASS 'onsuccess' in event.target is true
    248 PASS 'onerror' in event.target is true
    249 PASS 'readyState' in event.target is true
    250 PASS event.target.readyState is event.target.DONE
    251 
    252 store = event.source
    253 store.add({x: data}, dataAdded)
    254 Success event fired:
    255 PASS 'result' in event is true
    256 PASS 'code' in event is false
    257 PASS 'message' in event is false
    258 PASS 'source' in event is true
    259 PASS event.source != null is true
    260 PASS 'onsuccess' in event.target is true
    261 PASS 'onerror' in event.target is true
    262 PASS 'readyState' in event.target is true
    263 PASS event.target.readyState is event.target.DONE
    264 
    265 store = event.source
    266 store.add({x: data}, dataAdded)
    267 Success event fired:
    268 PASS 'result' in event is true
    269 PASS 'code' in event is false
    270 PASS 'message' in event is false
    271 PASS 'source' in event is true
    272 PASS event.source != null is true
    273 PASS 'onsuccess' in event.target is true
    274 PASS 'onerror' in event.target is true
    275 PASS 'readyState' in event.target is true
    276 PASS event.target.readyState is event.target.DONE
    277 
    278 store = event.source
    279 store.add({x: data}, dataAdded)
    280 Success event fired:
    281 PASS 'result' in event is true
    282 PASS 'code' in event is false
    283 PASS 'message' in event is false
    284 PASS 'source' in event is true
    285 PASS event.source != null is true
    286 PASS 'onsuccess' in event.target is true
    287 PASS 'onerror' in event.target is true
    288 PASS 'readyState' in event.target is true
    289 PASS event.target.readyState is event.target.DONE
    290 
    291 store = event.source
    292 store.add({x: data}, dataAdded)
    293 Success event fired:
    294 PASS 'result' in event is true
    295 PASS 'code' in event is false
    296 PASS 'message' in event is false
    297 PASS 'source' in event is true
    298 PASS event.source != null is true
    299 PASS 'onsuccess' in event.target is true
    300 PASS 'onerror' in event.target is true
    301 PASS 'readyState' in event.target is true
    302 PASS event.target.readyState is event.target.DONE
    303 
    304 store = event.source
    305 store.add({x: data}, dataAdded)
    306 Success event fired:
    307 PASS 'result' in event is true
    308 PASS 'code' in event is false
    309 PASS 'message' in event is false
    310 PASS 'source' in event is true
    311 PASS event.source != null is true
    312 PASS 'onsuccess' in event.target is true
    313 PASS 'onerror' in event.target is true
    314 PASS 'readyState' in event.target is true
    315 PASS event.target.readyState is event.target.DONE
    316 
    317 store = event.source
    318 store.add({x: data}, dataAdded)
    319 Success event fired:
    320 PASS 'result' in event is true
    321 PASS 'code' in event is false
    322 PASS 'message' in event is false
    323 PASS 'source' in event is true
    324 PASS event.source != null is true
    325 PASS 'onsuccess' in event.target is true
    326 PASS 'onerror' in event.target is true
    327 PASS 'readyState' in event.target is true
    328 PASS event.target.readyState is event.target.DONE
    329 
    330 store = event.source
    331 store.add({x: data}, dataAdded)
    332 Success event fired:
    333 PASS 'result' in event is true
    334 PASS 'code' in event is false
    335 PASS 'message' in event is false
    336 PASS 'source' in event is true
    337 PASS event.source != null is true
    338 PASS 'onsuccess' in event.target is true
    339 PASS 'onerror' in event.target is true
    340 PASS 'readyState' in event.target is true
    341 PASS event.target.readyState is event.target.DONE
    342 
    343 store = event.source
    344 store.add({x: data}, dataAdded)
    345 Success event fired:
    346 PASS 'result' in event is true
    347 PASS 'code' in event is false
    348 PASS 'message' in event is false
    349 PASS 'source' in event is true
    350 PASS event.source != null is true
    351 PASS 'onsuccess' in event.target is true
    352 PASS 'onerror' in event.target is true
    353 PASS 'readyState' in event.target is true
    354 PASS event.target.readyState is event.target.DONE
    355 
    356 store = event.source
    357 store.add({x: data}, dataAdded)
    358 Success event fired:
    359 PASS 'result' in event is true
    360 PASS 'code' in event is false
    361 PASS 'message' in event is false
    362 PASS 'source' in event is true
    363 PASS event.source != null is true
    364 PASS 'onsuccess' in event.target is true
    365 PASS 'onerror' in event.target is true
    366 PASS 'readyState' in event.target is true
    367 PASS event.target.readyState is event.target.DONE
    368 
    369 store = event.source
    370 store.add({x: data}, dataAdded)
    371 Success event fired:
    372 PASS 'result' in event is true
    373 PASS 'code' in event is false
    374 PASS 'message' in event is false
    375 PASS 'source' in event is true
    376 PASS event.source != null is true
    377 PASS 'onsuccess' in event.target is true
    378 PASS 'onerror' in event.target is true
    379 PASS 'readyState' in event.target is true
    380 PASS event.target.readyState is event.target.DONE
    381 
    382 store = event.source
    383 store.add({x: data}, dataAdded)
    384 Success event fired:
    385 PASS 'result' in event is true
    386 PASS 'code' in event is false
    387 PASS 'message' in event is false
    388 PASS 'source' in event is true
    389 PASS event.source != null is true
    390 PASS 'onsuccess' in event.target is true
    391 PASS 'onerror' in event.target is true
    392 PASS 'readyState' in event.target is true
    393 PASS event.target.readyState is event.target.DONE
    394 
    395 store = event.source
    396 store.add({x: data}, dataAdded)
    397 Success event fired:
    398 PASS 'result' in event is true
    399 PASS 'code' in event is false
    400 PASS 'message' in event is false
    401 PASS 'source' in event is true
    402 PASS event.source != null is true
    403 PASS 'onsuccess' in event.target is true
    404 PASS 'onerror' in event.target is true
    405 PASS 'readyState' in event.target is true
    406 PASS event.target.readyState is event.target.DONE
    407 
    408 store = event.source
    409 store.add({x: data}, dataAdded)
    410 Success event fired:
    411 PASS 'result' in event is true
    412 PASS 'code' in event is false
    413 PASS 'message' in event is false
    414 PASS 'source' in event is true
    415 PASS event.source != null is true
    416 PASS 'onsuccess' in event.target is true
    417 PASS 'onerror' in event.target is true
    418 PASS 'readyState' in event.target is true
    419 PASS event.target.readyState is event.target.DONE
    420 
    421 store = event.source
    422 store.add({x: data}, dataAdded)
    423 Success event fired:
    424 PASS 'result' in event is true
    425 PASS 'code' in event is false
    426 PASS 'message' in event is false
    427 PASS 'source' in event is true
    428 PASS event.source != null is true
    429 PASS 'onsuccess' in event.target is true
    430 PASS 'onerror' in event.target is true
    431 PASS 'readyState' in event.target is true
    432 PASS event.target.readyState is event.target.DONE
    433 
    434 store = event.source
    435 store.add({x: data}, dataAdded)
    436 Success event fired:
    437 PASS 'result' in event is true
    438 PASS 'code' in event is false
    439 PASS 'message' in event is false
    440 PASS 'source' in event is true
    441 PASS event.source != null is true
    442 PASS 'onsuccess' in event.target is true
    443 PASS 'onerror' in event.target is true
    444 PASS 'readyState' in event.target is true
    445 PASS event.target.readyState is event.target.DONE
    446 
    447 store = event.source
    448 store.add({x: data}, dataAdded)
    449 Success event fired:
    450 PASS 'result' in event is true
    451 PASS 'code' in event is false
    452 PASS 'message' in event is false
    453 PASS 'source' in event is true
    454 PASS event.source != null is true
    455 PASS 'onsuccess' in event.target is true
    456 PASS 'onerror' in event.target is true
    457 PASS 'readyState' in event.target is true
    458 PASS event.target.readyState is event.target.DONE
    459 
    460 store = event.source
    461 store.add({x: data}, dataAdded)
    462 Success event fired:
    463 PASS 'result' in event is true
    464 PASS 'code' in event is false
    465 PASS 'message' in event is false
    466 PASS 'source' in event is true
    467 PASS event.source != null is true
    468 PASS 'onsuccess' in event.target is true
    469 PASS 'onerror' in event.target is true
    470 PASS 'readyState' in event.target is true
    471 PASS event.target.readyState is event.target.DONE
    472 
    473 store = event.source
    474 store.add({x: data}, dataAdded)
    475 Success event fired:
    476 PASS 'result' in event is true
    477 PASS 'code' in event is false
    478 PASS 'message' in event is false
    479 PASS 'source' in event is true
    480 PASS event.source != null is true
    481 PASS 'onsuccess' in event.target is true
    482 PASS 'onerror' in event.target is true
    483 PASS 'readyState' in event.target is true
    484 PASS event.target.readyState is event.target.DONE
    485 
    486 store = event.source
    487 store.add({x: data}, dataAdded)
    488 Success event fired:
    489 PASS 'result' in event is true
    490 PASS 'code' in event is false
    491 PASS 'message' in event is false
    492 PASS 'source' in event is true
    493 PASS event.source != null is true
    494 PASS 'onsuccess' in event.target is true
    495 PASS 'onerror' in event.target is true
    496 PASS 'readyState' in event.target is true
    497 PASS event.target.readyState is event.target.DONE
    498 
    499 store = event.source
    500 store.add({x: data}, dataAdded)
    501 Success event fired:
    502 PASS 'result' in event is true
    503 PASS 'code' in event is false
    504 PASS 'message' in event is false
    505 PASS 'source' in event is true
    506 PASS event.source != null is true
    507 PASS 'onsuccess' in event.target is true
    508 PASS 'onerror' in event.target is true
    509 PASS 'readyState' in event.target is true
    510 PASS event.target.readyState is event.target.DONE
    511 
    512 store = event.source
    513 store.add({x: data}, dataAdded)
    514 Success event fired:
    515 PASS 'result' in event is true
    516 PASS 'code' in event is false
    517 PASS 'message' in event is false
    518 PASS 'source' in event is true
    519 PASS event.source != null is true
    520 PASS 'onsuccess' in event.target is true
    521 PASS 'onerror' in event.target is true
    522 PASS 'readyState' in event.target is true
    523 PASS event.target.readyState is event.target.DONE
    524 
    525 store = event.source
    526 store.add({x: data}, dataAdded)
    527 Success event fired:
    528 PASS 'result' in event is true
    529 PASS 'code' in event is false
    530 PASS 'message' in event is false
    531 PASS 'source' in event is true
    532 PASS event.source != null is true
    533 PASS 'onsuccess' in event.target is true
    534 PASS 'onerror' in event.target is true
    535 PASS 'readyState' in event.target is true
    536 PASS event.target.readyState is event.target.DONE
    537 
    538 store = event.source
    539 store.add({x: data}, dataAdded)
    540 Success event fired:
    541 PASS 'result' in event is true
    542 PASS 'code' in event is false
    543 PASS 'message' in event is false
    544 PASS 'source' in event is true
    545 PASS event.source != null is true
    546 PASS 'onsuccess' in event.target is true
    547 PASS 'onerror' in event.target is true
    548 PASS 'readyState' in event.target is true
    549 PASS event.target.readyState is event.target.DONE
    550 
    551 store = event.source
    552 store.add({x: data}, dataAdded)
    553 Success event fired:
    554 PASS 'result' in event is true
    555 PASS 'code' in event is false
    556 PASS 'message' in event is false
    557 PASS 'source' in event is true
    558 PASS event.source != null is true
    559 PASS 'onsuccess' in event.target is true
    560 PASS 'onerror' in event.target is true
    561 PASS 'readyState' in event.target is true
    562 PASS event.target.readyState is event.target.DONE
    563 
    564 store = event.source
    565 store.add({x: data}, dataAdded)
    566 Success event fired:
    567 PASS 'result' in event is true
    568 PASS 'code' in event is false
    569 PASS 'message' in event is false
    570 PASS 'source' in event is true
    571 PASS event.source != null is true
    572 PASS 'onsuccess' in event.target is true
    573 PASS 'onerror' in event.target is true
    574 PASS 'readyState' in event.target is true
    575 PASS event.target.readyState is event.target.DONE
    576 
    577 store = event.source
    578 store.add({x: data}, dataAdded)
    579 Success event fired:
    580 PASS 'result' in event is true
    581 PASS 'code' in event is false
    582 PASS 'message' in event is false
    583 PASS 'source' in event is true
    584 PASS event.source != null is true
    585 PASS 'onsuccess' in event.target is true
    586 PASS 'onerror' in event.target is true
    587 PASS 'readyState' in event.target is true
    588 PASS event.target.readyState is event.target.DONE
    589 
    590 store = event.source
    591 store.add({x: data}, dataAdded)
    592 Success event fired:
    593 PASS 'result' in event is true
    594 PASS 'code' in event is false
    595 PASS 'message' in event is false
    596 PASS 'source' in event is true
    597 PASS event.source != null is true
    598 PASS 'onsuccess' in event.target is true
    599 PASS 'onerror' in event.target is true
    600 PASS 'readyState' in event.target is true
    601 PASS event.target.readyState is event.target.DONE
    602 
    603 store = event.source
    604 store.add({x: data}, dataAdded)
    605 Success event fired:
    606 PASS 'result' in event is true
    607 PASS 'code' in event is false
    608 PASS 'message' in event is false
    609 PASS 'source' in event is true
    610 PASS event.source != null is true
    611 PASS 'onsuccess' in event.target is true
    612 PASS 'onerror' in event.target is true
    613 PASS 'readyState' in event.target is true
    614 PASS event.target.readyState is event.target.DONE
    615 
    616 store = event.source
    617 store.add({x: data}, dataAdded)
    618 Success event fired:
    619 PASS 'result' in event is true
    620 PASS 'code' in event is false
    621 PASS 'message' in event is false
    622 PASS 'source' in event is true
    623 PASS event.source != null is true
    624 PASS 'onsuccess' in event.target is true
    625 PASS 'onerror' in event.target is true
    626 PASS 'readyState' in event.target is true
    627 PASS event.target.readyState is event.target.DONE
    628 
    629 store = event.source
    630 store.add({x: data}, dataAdded)
    631 Success event fired:
    632 PASS 'result' in event is true
    633 PASS 'code' in event is false
    634 PASS 'message' in event is false
    635 PASS 'source' in event is true
    636 PASS event.source != null is true
    637 PASS 'onsuccess' in event.target is true
    638 PASS 'onerror' in event.target is true
    639 PASS 'readyState' in event.target is true
    640 PASS event.target.readyState is event.target.DONE
    641 
    642 store = event.source
    643 store.add({x: data}, dataAdded)
    644 Success event fired:
    645 PASS 'result' in event is true
    646 PASS 'code' in event is false
    647 PASS 'message' in event is false
    648 PASS 'source' in event is true
    649 PASS event.source != null is true
    650 PASS 'onsuccess' in event.target is true
    651 PASS 'onerror' in event.target is true
    652 PASS 'readyState' in event.target is true
    653 PASS event.target.readyState is event.target.DONE
    654 
    655 store = event.source
    656 store.add({x: data}, dataAdded)
    657 Success event fired:
    658 PASS 'result' in event is true
    659 PASS 'code' in event is false
    660 PASS 'message' in event is false
    661 PASS 'source' in event is true
    662 PASS event.source != null is true
    663 PASS 'onsuccess' in event.target is true
    664 PASS 'onerror' in event.target is true
    665 PASS 'readyState' in event.target is true
    666 PASS event.target.readyState is event.target.DONE
    667 
    668 store = event.source
    669 store.add({x: data}, dataAdded)
    670 Success event fired:
    671 PASS 'result' in event is true
    672 PASS 'code' in event is false
    673 PASS 'message' in event is false
    674 PASS 'source' in event is true
    675 PASS event.source != null is true
    676 PASS 'onsuccess' in event.target is true
    677 PASS 'onerror' in event.target is true
    678 PASS 'readyState' in event.target is true
    679 PASS event.target.readyState is event.target.DONE
    680 
    681 store = event.source
    682 store.add({x: data}, dataAdded)
    683 Success event fired:
    684 PASS 'result' in event is true
    685 PASS 'code' in event is false
    686 PASS 'message' in event is false
    687 PASS 'source' in event is true
    688 PASS event.source != null is true
    689 PASS 'onsuccess' in event.target is true
    690 PASS 'onerror' in event.target is true
    691 PASS 'readyState' in event.target is true
    692 PASS event.target.readyState is event.target.DONE
    693 
    694 store = event.source
    695 store.add({x: data}, dataAdded)
    696 Success event fired:
    697 PASS 'result' in event is true
    698 PASS 'code' in event is false
    699 PASS 'message' in event is false
    700 PASS 'source' in event is true
    701 PASS event.source != null is true
    702 PASS 'onsuccess' in event.target is true
    703 PASS 'onerror' in event.target is true
    704 PASS 'readyState' in event.target is true
    705 PASS event.target.readyState is event.target.DONE
    706 
    707 store = event.source
    708 store.add({x: data}, dataAdded)
    709 Success event fired:
    710 PASS 'result' in event is true
    711 PASS 'code' in event is false
    712 PASS 'message' in event is false
    713 PASS 'source' in event is true
    714 PASS event.source != null is true
    715 PASS 'onsuccess' in event.target is true
    716 PASS 'onerror' in event.target is true
    717 PASS 'readyState' in event.target is true
    718 PASS event.target.readyState is event.target.DONE
    719 
    720 store = event.source
    721 store.add({x: data}, dataAdded)
    722 Success event fired:
    723 PASS 'result' in event is true
    724 PASS 'code' in event is false
    725 PASS 'message' in event is false
    726 PASS 'source' in event is true
    727 PASS event.source != null is true
    728 PASS 'onsuccess' in event.target is true
    729 PASS 'onerror' in event.target is true
    730 PASS 'readyState' in event.target is true
    731 PASS event.target.readyState is event.target.DONE
    732 
    733 store = event.source
    734 store.add({x: data}, dataAdded)
    735 Success event fired:
    736 PASS 'result' in event is true
    737 PASS 'code' in event is false
    738 PASS 'message' in event is false
    739 PASS 'source' in event is true
    740 PASS event.source != null is true
    741 PASS 'onsuccess' in event.target is true
    742 PASS 'onerror' in event.target is true
    743 PASS 'readyState' in event.target is true
    744 PASS event.target.readyState is event.target.DONE
    745 
    746 store = event.source
    747 store.add({x: data}, dataAdded)
    748 Success event fired:
    749 PASS 'result' in event is true
    750 PASS 'code' in event is false
    751 PASS 'message' in event is false
    752 PASS 'source' in event is true
    753 PASS event.source != null is true
    754 PASS 'onsuccess' in event.target is true
    755 PASS 'onerror' in event.target is true
    756 PASS 'readyState' in event.target is true
    757 PASS event.target.readyState is event.target.DONE
    758 
    759 store = event.source
    760 store.add({x: data}, dataAdded)
    761 Success event fired:
    762 PASS 'result' in event is true
    763 PASS 'code' in event is false
    764 PASS 'message' in event is false
    765 PASS 'source' in event is true
    766 PASS event.source != null is true
    767 PASS 'onsuccess' in event.target is true
    768 PASS 'onerror' in event.target is true
    769 PASS 'readyState' in event.target is true
    770 PASS event.target.readyState is event.target.DONE
    771 
    772 store = event.source
    773 store.add({x: data}, dataAdded)
    774 Success event fired:
    775 PASS 'result' in event is true
    776 PASS 'code' in event is false
    777 PASS 'message' in event is false
    778 PASS 'source' in event is true
    779 PASS event.source != null is true
    780 PASS 'onsuccess' in event.target is true
    781 PASS 'onerror' in event.target is true
    782 PASS 'readyState' in event.target is true
    783 PASS event.target.readyState is event.target.DONE
    784 
    785 store = event.source
    786 store.add({x: data}, dataAdded)
    787 Success event fired:
    788 PASS 'result' in event is true
    789 PASS 'code' in event is false
    790 PASS 'message' in event is false
    791 PASS 'source' in event is true
    792 PASS event.source != null is true
    793 PASS 'onsuccess' in event.target is true
    794 PASS 'onerror' in event.target is true
    795 PASS 'readyState' in event.target is true
    796 PASS event.target.readyState is event.target.DONE
    797 
    798 store = event.source
    799 store.add({x: data}, dataAdded)
    800 Success event fired:
    801 PASS 'result' in event is true
    802 PASS 'code' in event is false
    803 PASS 'message' in event is false
    804 PASS 'source' in event is true
    805 PASS event.source != null is true
    806 PASS 'onsuccess' in event.target is true
    807 PASS 'onerror' in event.target is true
    808 PASS 'readyState' in event.target is true
    809 PASS event.target.readyState is event.target.DONE
    810 
    811 store = event.source
    812 store.add({x: data}, dataAdded)
    813 Success event fired:
    814 PASS 'result' in event is true
    815 PASS 'code' in event is false
    816 PASS 'message' in event is false
    817 PASS 'source' in event is true
    818 PASS event.source != null is true
    819 PASS 'onsuccess' in event.target is true
    820 PASS 'onerror' in event.target is true
    821 PASS 'readyState' in event.target is true
    822 PASS event.target.readyState is event.target.DONE
    823 
    824 store = event.source
    825 store.add({x: data}, dataAdded)
    826 Success event fired:
    827 PASS 'result' in event is true
    828 PASS 'code' in event is false
    829 PASS 'message' in event is false
    830 PASS 'source' in event is true
    831 PASS event.source != null is true
    832 PASS 'onsuccess' in event.target is true
    833 PASS 'onerror' in event.target is true
    834 PASS 'readyState' in event.target is true
    835 PASS event.target.readyState is event.target.DONE
    836 
    837 store = event.source
    838 store.add({x: data}, dataAdded)
    839 Success event fired:
    840 PASS 'result' in event is true
    841 PASS 'code' in event is false
    842 PASS 'message' in event is false
    843 PASS 'source' in event is true
    844 PASS event.source != null is true
    845 PASS 'onsuccess' in event.target is true
    846 PASS 'onerror' in event.target is true
    847 PASS 'readyState' in event.target is true
    848 PASS event.target.readyState is event.target.DONE
    849 
    850 store = event.source
    851 store.add({x: data}, dataAdded)
    852 Success event fired:
    853 PASS 'result' in event is true
    854 PASS 'code' in event is false
    855 PASS 'message' in event is false
    856 PASS 'source' in event is true
    857 PASS event.source != null is true
    858 PASS 'onsuccess' in event.target is true
    859 PASS 'onerror' in event.target is true
    860 PASS 'readyState' in event.target is true
    861 PASS event.target.readyState is event.target.DONE
    862 
    863 store = event.source
    864 store.add({x: data}, dataAdded)
    865 Success event fired:
    866 PASS 'result' in event is true
    867 PASS 'code' in event is false
    868 PASS 'message' in event is false
    869 PASS 'source' in event is true
    870 PASS event.source != null is true
    871 PASS 'onsuccess' in event.target is true
    872 PASS 'onerror' in event.target is true
    873 PASS 'readyState' in event.target is true
    874 PASS event.target.readyState is event.target.DONE
    875 
    876 store = event.source
    877 store.add({x: data}, dataAdded)
    878 Success event fired:
    879 PASS 'result' in event is true
    880 PASS 'code' in event is false
    881 PASS 'message' in event is false
    882 PASS 'source' in event is true
    883 PASS event.source != null is true
    884 PASS 'onsuccess' in event.target is true
    885 PASS 'onerror' in event.target is true
    886 PASS 'readyState' in event.target is true
    887 PASS event.target.readyState is event.target.DONE
    888 
    889 store = event.source
    890 store.add({x: data}, dataAdded)
    891 Success event fired:
    892 PASS 'result' in event is true
    893 PASS 'code' in event is false
    894 PASS 'message' in event is false
    895 PASS 'source' in event is true
    896 PASS event.source != null is true
    897 PASS 'onsuccess' in event.target is true
    898 PASS 'onerror' in event.target is true
    899 PASS 'readyState' in event.target is true
    900 PASS event.target.readyState is event.target.DONE
    901 
    902 store = event.source
    903 store.add({x: data}, dataAdded)
    904 Success event fired:
    905 PASS 'result' in event is true
    906 PASS 'code' in event is false
    907 PASS 'message' in event is false
    908 PASS 'source' in event is true
    909 PASS event.source != null is true
    910 PASS 'onsuccess' in event.target is true
    911 PASS 'onerror' in event.target is true
    912 PASS 'readyState' in event.target is true
    913 PASS event.target.readyState is event.target.DONE
    914 
    915 store = event.source
    916 store.add({x: data}, dataAdded)
    917 Success event fired:
    918 PASS 'result' in event is true
    919 PASS 'code' in event is false
    920 PASS 'message' in event is false
    921 PASS 'source' in event is true
    922 PASS event.source != null is true
    923 PASS 'onsuccess' in event.target is true
    924 PASS 'onerror' in event.target is true
    925 PASS 'readyState' in event.target is true
    926 PASS event.target.readyState is event.target.DONE
    927 
    928 store = event.source
    929 store.add({x: data}, dataAdded)
    930 Success event fired:
    931 PASS 'result' in event is true
    932 PASS 'code' in event is false
    933 PASS 'message' in event is false
    934 PASS 'source' in event is true
    935 PASS event.source != null is true
    936 PASS 'onsuccess' in event.target is true
    937 PASS 'onerror' in event.target is true
    938 PASS 'readyState' in event.target is true
    939 PASS event.target.readyState is event.target.DONE
    940 
    941 store = event.source
    942 store.add({x: data}, dataAdded)
    943 Success event fired:
    944 PASS 'result' in event is true
    945 PASS 'code' in event is false
    946 PASS 'message' in event is false
    947 PASS 'source' in event is true
    948 PASS event.source != null is true
    949 PASS 'onsuccess' in event.target is true
    950 PASS 'onerror' in event.target is true
    951 PASS 'readyState' in event.target is true
    952 PASS event.target.readyState is event.target.DONE
    953 
    954 store = event.source
    955 store.add({x: data}, dataAdded)
    956 Success event fired:
    957 PASS 'result' in event is true
    958 PASS 'code' in event is false
    959 PASS 'message' in event is false
    960 PASS 'source' in event is true
    961 PASS event.source != null is true
    962 PASS 'onsuccess' in event.target is true
    963 PASS 'onerror' in event.target is true
    964 PASS 'readyState' in event.target is true
    965 PASS event.target.readyState is event.target.DONE
    966 
    967 store = event.source
    968 store.add({x: data}, dataAdded)
    969 Success event fired:
    970 PASS 'result' in event is true
    971 PASS 'code' in event is false
    972 PASS 'message' in event is false
    973 PASS 'source' in event is true
    974 PASS event.source != null is true
    975 PASS 'onsuccess' in event.target is true
    976 PASS 'onerror' in event.target is true
    977 PASS 'readyState' in event.target is true
    978 PASS event.target.readyState is event.target.DONE
    979 
    980 store = event.source
    981 store.add({x: data}, dataAdded)
    982 Success event fired:
    983 PASS 'result' in event is true
    984 PASS 'code' in event is false
    985 PASS 'message' in event is false
    986 PASS 'source' in event is true
    987 PASS event.source != null is true
    988 PASS 'onsuccess' in event.target is true
    989 PASS 'onerror' in event.target is true
    990 PASS 'readyState' in event.target is true
    991 PASS event.target.readyState is event.target.DONE
    992 
    993 store = event.source
    994 store.add({x: data}, dataAdded)
    995 Success event fired:
    996 PASS 'result' in event is true
    997 PASS 'code' in event is false
    998 PASS 'message' in event is false
    999 PASS 'source' in event is true
    1000 PASS event.source != null is true
    1001 PASS 'onsuccess' in event.target is true
    1002 PASS 'onerror' in event.target is true
    1003 PASS 'readyState' in event.target is true
    1004 PASS event.target.readyState is event.target.DONE
    1005 
    1006 store = event.source
    1007 store.add({x: data}, dataAdded)
    1008 Success event fired:
    1009 PASS 'result' in event is true
    1010 PASS 'code' in event is false
    1011 PASS 'message' in event is false
    1012 PASS 'source' in event is true
    1013 PASS event.source != null is true
    1014 PASS 'onsuccess' in event.target is true
    1015 PASS 'onerror' in event.target is true
    1016 PASS 'readyState' in event.target is true
    1017 PASS event.target.readyState is event.target.DONE
    1018 
    1019 store = event.source
    1020 store.add({x: data}, dataAdded)
    1021 Success event fired:
    1022 PASS 'result' in event is true
    1023 PASS 'code' in event is false
    1024 PASS 'message' in event is false
    1025 PASS 'source' in event is true
    1026 PASS event.source != null is true
    1027 PASS 'onsuccess' in event.target is true
    1028 PASS 'onerror' in event.target is true
    1029 PASS 'readyState' in event.target is true
    1030 PASS event.target.readyState is event.target.DONE
    1031 
    1032 store = event.source
    1033 store.add({x: data}, dataAdded)
    1034 Success event fired:
    1035 PASS 'result' in event is true
    1036 PASS 'code' in event is false
    1037 PASS 'message' in event is false
    1038 PASS 'source' in event is true
    1039 PASS event.source != null is true
    1040 PASS 'onsuccess' in event.target is true
    1041 PASS 'onerror' in event.target is true
    1042 PASS 'readyState' in event.target is true
    1043 PASS event.target.readyState is event.target.DONE
    1044 
    1045 store = event.source
    1046 store.add({x: data}, dataAdded)
    1047 Success event fired:
    1048 PASS 'result' in event is true
    1049 PASS 'code' in event is false
    1050 PASS 'message' in event is false
    1051 PASS 'source' in event is true
    1052 PASS event.source != null is true
    1053 PASS 'onsuccess' in event.target is true
    1054 PASS 'onerror' in event.target is true
    1055 PASS 'readyState' in event.target is true
    1056 PASS event.target.readyState is event.target.DONE
    1057 
    1058 store = event.source
    1059 store.add({x: data}, dataAdded)
    1060 Success event fired:
    1061 PASS 'result' in event is true
    1062 PASS 'code' in event is false
    1063 PASS 'message' in event is false
    1064 PASS 'source' in event is true
    1065 PASS event.source != null is true
    1066 PASS 'onsuccess' in event.target is true
    1067 PASS 'onerror' in event.target is true
    1068 PASS 'readyState' in event.target is true
    1069 PASS event.target.readyState is event.target.DONE
    1070 
    1071 store = event.source
    1072 store.add({x: data}, dataAdded)
    1073 Success event fired:
    1074 PASS 'result' in event is true
    1075 PASS 'code' in event is false
    1076 PASS 'message' in event is false
    1077 PASS 'source' in event is true
    1078 PASS event.source != null is true
    1079 PASS 'onsuccess' in event.target is true
    1080 PASS 'onerror' in event.target is true
    1081 PASS 'readyState' in event.target is true
    1082 PASS event.target.readyState is event.target.DONE
    1083 
    1084 store = event.source
    1085 store.add({x: data}, dataAdded)
    1086 Success event fired:
    1087 PASS 'result' in event is true
    1088 PASS 'code' in event is false
    1089 PASS 'message' in event is false
    1090 PASS 'source' in event is true
    1091 PASS event.source != null is true
    1092 PASS 'onsuccess' in event.target is true
    1093 PASS 'onerror' in event.target is true
    1094 PASS 'readyState' in event.target is true
    1095 PASS event.target.readyState is event.target.DONE
    1096 
    1097 store = event.source
    1098 store.add({x: data}, dataAdded)
    109971Error function called: (0) Error writing data to stable storage.
    110072Error event fired:
     
    110981PASS event.target.readyState is event.target.DONE
    111082
    1111 PASS Adding data failed due to quota error. Data added was: 5120 KB
     83PASS Adding data failed due to quota error. Data added was about 5 MB
    111284PASS successfullyParsed is true
    111385
  • trunk/LayoutTests/storage/indexeddb/database-quota.html

    r69612 r70522  
    9191{
    9292    if (dataAdded < 5 * 1024 * 1024) {
    93         if (dataAdded > 0) {
    94             verifySuccessEvent(event);
    95             store = evalAndLog("store = event.source");
    96         }
     93        if (dataAdded > 0)
     94            store = event.source;
    9795    } else {
    9896        testFailed("added more than quota");
     
    10199    }
    102100    dataAdded += 65536;
    103     result = evalAndLog("store.add({x: data}, dataAdded)");
     101    result = store.add({x: data}, dataAdded);
    104102    result.onsuccess = addData;
    105103    result.onerror = logError;
     
    114112function testComplete()
    115113{
    116     testPassed("Adding data failed due to quota error. Data added was: " + dataAdded / 1024 + " KB");
     114    testPassed("Adding data failed due to quota error. Data added was about " + Math.round(dataAdded / 1024 / 1024) + " MB");
    117115    done();
    118116}
  • trunk/WebCore/ChangeLog

    r70519 r70522  
     12010-10-26  Jeremy Orlow  <jorlow@chromium.org>
     2
     3        Reviewed by Steve Block.
     4
     5        Quota for IndexedDB should be per origin not per database
     6        https://bugs.webkit.org/show_bug.cgi?id=48064
     7
     8        Merge all databases for each origin into a single SQLiteDatabase.
     9
     10        Replace the awkward metaData table with a Database table.
     11
     12        Create a new IDBSQLiteDatabase class that wraps SQLiteDatabase
     13        and implements weak pointer semantics for IDBFactory. It's ref
     14        counted so multiple IDBDatabaseBackendImpls can share one.
     15
     16        Fix uniqueness constraints that were overly conservitive.
     17
     18        Get rid of the code that blows away existing data every time
     19        the database is opened.
     20
     21        Get rid of the fairly useless indexedDB manual test and replace
     22        it with one that verifies data persists.
     23
     24        Use name+origin (not just name) in our cache of IDBDatabaseBackend
     25        objects (so one origin can't access anothers' data).
     26
     27        Test: storage/indexeddb/duplicates.html
     28
     29        * WebCore.gypi:
     30        * manual-tests/indexed-database.html: Removed.
     31        * manual-tests/indexeddb-persists.html: Added.
     32        * storage/IDBDatabaseBackendImpl.cpp:
     33        (WebCore::extractMetaData):
     34        (WebCore::setMetaData):
     35        (WebCore::IDBDatabaseBackendImpl::IDBDatabaseBackendImpl):
     36        (WebCore::IDBDatabaseBackendImpl::setDescription):
     37        (WebCore::IDBDatabaseBackendImpl::sqliteDatabase):
     38        (WebCore::IDBDatabaseBackendImpl::createObjectStoreInternal):
     39        (WebCore::IDBDatabaseBackendImpl::setVersionInternal):
     40        (WebCore::IDBDatabaseBackendImpl::loadObjectStores):
     41        * storage/IDBDatabaseBackendImpl.h:
     42        (WebCore::IDBDatabaseBackendImpl::create):
     43        (WebCore::IDBDatabaseBackendImpl::id):
     44        * storage/IDBFactoryBackendImpl.cpp:
     45        (WebCore::IDBFactoryBackendImpl::removeSQLiteDatabase):
     46        (WebCore::openSQLiteDatabase):
     47        (WebCore::createTables):
     48        (WebCore::IDBFactoryBackendImpl::open):
     49        (WebCore::IDBFactoryBackendImpl::databaseFileName):
     50        * storage/IDBFactoryBackendImpl.h:
     51        * storage/IDBObjectStoreBackendImpl.cpp:
     52        (WebCore::putObjectStoreData):
     53        (WebCore::IDBObjectStoreBackendImpl::putInternal):
     54        * storage/IDBSQLiteDatabase.cpp: Added.
     55        (WebCore::IDBSQLiteDatabase::IDBSQLiteDatabase):
     56        (WebCore::IDBSQLiteDatabase::~IDBSQLiteDatabase):
     57        * storage/IDBSQLiteDatabase.h: Added.
     58        (WebCore::IDBSQLiteDatabase::create):
     59        (WebCore::IDBSQLiteDatabase::db):
     60
    1612010-10-20  Andrey Kosyakov  <caseq@chromium.org>
    262
  • trunk/WebCore/WebCore.gypi

    r70511 r70522  
    38533853            'storage/IDBRequest.cpp',
    38543854            'storage/IDBRequest.h',
     3855            'storage/IDBSQLiteDatabase.cpp',
     3856            'storage/IDBSQLiteDatabase.h',
    38553857            'storage/IDBSuccessEvent.cpp',
    38563858            'storage/IDBSuccessEvent.h',
  • trunk/WebCore/storage/IDBDatabaseBackendImpl.cpp

    r69974 r70522  
    3333#include "IDBDatabaseException.h"
    3434#include "IDBObjectStoreBackendImpl.h"
     35#include "IDBSQLiteDatabase.h"
    3536#include "IDBTransactionBackendInterface.h"
    3637#include "IDBTransactionCoordinator.h"
    37 #include "SQLiteDatabase.h"
    3838#include "SQLiteStatement.h"
    3939#include "SQLiteTransaction.h"
     
    4141namespace WebCore {
    4242
    43 static bool extractMetaData(SQLiteDatabase* sqliteDatabase, const String& expectedName, String& foundVersion)
    44 {
    45     SQLiteStatement metaDataQuery(*sqliteDatabase, "SELECT name, version FROM MetaData");
    46     if (metaDataQuery.prepare() != SQLResultOk || metaDataQuery.step() != SQLResultRow)
    47         return false;
    48 
    49     if (metaDataQuery.getColumnText(0) != expectedName) {
    50         LOG_ERROR("Name in MetaData (%s) doesn't match expected (%s) for IndexedDB", metaDataQuery.getColumnText(0).utf8().data(), expectedName.utf8().data());
     43static bool extractMetaData(SQLiteDatabase& sqliteDatabase, const String& name, String& foundVersion, int64& foundId)
     44{
     45    SQLiteStatement databaseQuery(sqliteDatabase, "SELECT id, version FROM Databases WHERE name = ?");
     46    if (databaseQuery.prepare() != SQLResultOk) {
    5147        ASSERT_NOT_REACHED();
    52     }
    53     foundVersion = metaDataQuery.getColumnText(1);
    54 
    55     if (metaDataQuery.step() == SQLResultRow) {
    56         LOG_ERROR("More than one row found in MetaData table");
     48        return false;
     49    }
     50    databaseQuery.bindText(1, name);
     51    if (databaseQuery.step() != SQLResultRow)
     52        return false;
     53
     54    foundId = databaseQuery.getColumnInt64(0);
     55    foundVersion = databaseQuery.getColumnText(1);
     56
     57    if (databaseQuery.step() == SQLResultRow)
    5758        ASSERT_NOT_REACHED();
    58     }
    59 
    6059    return true;
    6160}
    6261
    63 static bool setMetaData(SQLiteDatabase* sqliteDatabase, const String& name, const String& description, const String& version)
    64 {
    65     ASSERT(!name.isNull() && !description.isNull() && !version.isNull());
    66 
    67     sqliteDatabase->executeCommand("DELETE FROM MetaData");
    68 
    69     SQLiteStatement insert(*sqliteDatabase, "INSERT INTO MetaData (name, description, version) VALUES (?, ?, ?)");
    70     if (insert.prepare() != SQLResultOk) {
    71         LOG_ERROR("Failed to prepare MetaData insert statement for IndexedDB");
    72         return false;
    73     }
    74 
    75     insert.bindText(1, name);
    76     insert.bindText(2, description);
    77     insert.bindText(3, version);
    78 
    79     if (insert.step() != SQLResultDone) {
    80         LOG_ERROR("Failed to insert row into MetaData for IndexedDB");
    81         return false;
    82     }
     62static bool setMetaData(SQLiteDatabase& sqliteDatabase, const String& name, const String& description, const String& version, int64_t& rowId)
     63{
     64    ASSERT(!name.isNull());
     65    ASSERT(!description.isNull());
     66    ASSERT(!version.isNull());
     67
     68    String sql = rowId != IDBDatabaseBackendImpl::InvalidId ? "UPDATE Databases SET name = ?, description = ?, version = ? WHERE id = ?"
     69                                                            : "INSERT INTO Databases (name, description, version) VALUES (?, ?, ?)";
     70    SQLiteStatement query(sqliteDatabase, sql);
     71    if (query.prepare() != SQLResultOk) {
     72        ASSERT_NOT_REACHED();
     73        return false;
     74    }
     75
     76    query.bindText(1, name);
     77    query.bindText(2, description);
     78    query.bindText(3, version);
     79    if (rowId != IDBDatabaseBackendImpl::InvalidId)
     80        query.bindInt64(4, rowId);
     81
     82    if (query.step() != SQLResultDone)
     83        return false;
     84
     85    if (rowId == IDBDatabaseBackendImpl::InvalidId)
     86        rowId = sqliteDatabase.lastInsertRowID();
    8387
    8488    return true;
    8589}
    8690
    87 IDBDatabaseBackendImpl::IDBDatabaseBackendImpl(const String& name, const String& description, PassOwnPtr<SQLiteDatabase> sqliteDatabase, IDBTransactionCoordinator* coordinator)
     91IDBDatabaseBackendImpl::IDBDatabaseBackendImpl(const String& name, const String& description, IDBSQLiteDatabase* sqliteDatabase, IDBTransactionCoordinator* coordinator)
    8892    : m_sqliteDatabase(sqliteDatabase)
     93    , m_id(InvalidId)
    8994    , m_name(name)
    9095    , m_description(description)
     
    95100    ASSERT(!m_description.isNull());
    96101
    97     extractMetaData(m_sqliteDatabase.get(), m_name, m_version);
    98     setMetaData(m_sqliteDatabase.get(), m_name, m_description, m_version);
    99 
     102    bool success = extractMetaData(m_sqliteDatabase->db(), m_name, m_version, m_id);
     103    ASSERT_UNUSED(success, success == (m_id != InvalidId));
     104    if (!setMetaData(m_sqliteDatabase->db(), m_name, m_description, m_version, m_id))
     105        ASSERT_NOT_REACHED(); // FIXME: Need better error handling.
    100106    loadObjectStores();
    101107}
     
    111117
    112118    m_description = description;
    113     setMetaData(m_sqliteDatabase.get(), m_name, m_description, m_version);
     119    setMetaData(m_sqliteDatabase->db(), m_name, m_description, m_version, m_id);
     120}
     121
     122SQLiteDatabase& IDBDatabaseBackendImpl::sqliteDatabase() const
     123{
     124    return m_sqliteDatabase->db();
    114125}
    115126
     
    145156void IDBDatabaseBackendImpl::createObjectStoreInternal(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl> database, PassRefPtr<IDBObjectStoreBackendImpl> objectStore,  PassRefPtr<IDBTransactionBackendInterface> transaction)
    146157{
    147     SQLiteStatement insert(database->sqliteDatabase(), "INSERT INTO ObjectStores (name, keyPath, doAutoIncrement) VALUES (?, ?, ?)");
     158    SQLiteStatement insert(database->sqliteDatabase(), "INSERT INTO ObjectStores (name, keyPath, doAutoIncrement, databaseId) VALUES (?, ?, ?, ?)");
    148159    if (insert.prepare() != SQLResultOk) {
    149160        transaction->abort();
     
    153164    insert.bindText(2, objectStore->keyPath());
    154165    insert.bindInt(3, static_cast<int>(objectStore->autoIncrement()));
     166    insert.bindInt64(4, database->id());
    155167    if (insert.step() != SQLResultDone) {
    156168        transaction->abort();
     
    218230void IDBDatabaseBackendImpl::setVersionInternal(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl> database, const String& version, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendInterface> transaction)
    219231{
     232    int64_t databaseId = database->id();
    220233    database->m_version = version;
    221     if (!setMetaData(database->m_sqliteDatabase.get(), database->m_name, database->m_description, database->m_version)) {
     234    if (!setMetaData(database->m_sqliteDatabase->db(), database->m_name, database->m_description, database->m_version, databaseId)) {
    222235        // FIXME: The Indexed Database specification does not have an error code dedicated to I/O errors.
    223236        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Error writing data to stable storage."));
     
    241254void IDBDatabaseBackendImpl::loadObjectStores()
    242255{
    243     SQLiteStatement objectStoresQuery(sqliteDatabase(), "SELECT id, name, keyPath, doAutoIncrement FROM ObjectStores");
     256    SQLiteStatement objectStoresQuery(sqliteDatabase(), "SELECT id, name, keyPath, doAutoIncrement FROM ObjectStores WHERE databaseId = ?");
    244257    bool ok = objectStoresQuery.prepare() == SQLResultOk;
    245258    ASSERT_UNUSED(ok, ok); // FIXME: Better error handling?
     259
     260    objectStoresQuery.bindInt64(1, m_id);
    246261
    247262    while (objectStoresQuery.step() == SQLResultRow) {
  • trunk/WebCore/storage/IDBDatabaseBackendImpl.h

    r69721 r70522  
    3737
    3838class IDBObjectStoreBackendImpl;
     39class IDBSQLiteDatabase;
    3940class IDBTransactionCoordinator;
    4041class SQLiteDatabase;
     
    4243class IDBDatabaseBackendImpl : public IDBDatabaseBackendInterface {
    4344public:
    44     static PassRefPtr<IDBDatabaseBackendImpl> create(const String& name, const String& description, PassOwnPtr<SQLiteDatabase> database, IDBTransactionCoordinator* coordinator)
     45    static PassRefPtr<IDBDatabaseBackendImpl> create(const String& name, const String& description, IDBSQLiteDatabase* database, IDBTransactionCoordinator* coordinator)
    4546    {
    4647        return adoptRef(new IDBDatabaseBackendImpl(name, description, database, coordinator));
     
    4950
    5051    void setDescription(const String& description);
    51     SQLiteDatabase& sqliteDatabase() const { return *m_sqliteDatabase.get(); }
     52    SQLiteDatabase& sqliteDatabase() const;
     53
     54    static const int64_t InvalidId = 0;
     55    int64_t id() const { return m_id; }
    5256
    5357    virtual String name() const { return m_name; }
     
    6670
    6771private:
    68     IDBDatabaseBackendImpl(const String& name, const String& description, PassOwnPtr<SQLiteDatabase> database, IDBTransactionCoordinator*);
     72    IDBDatabaseBackendImpl(const String& name, const String& description, IDBSQLiteDatabase* database, IDBTransactionCoordinator*);
    6973
    7074    void loadObjectStores();
     
    7983    static void resetVersion(ScriptExecutionContext*, PassRefPtr<IDBDatabaseBackendImpl>, const String& version);
    8084
    81     OwnPtr<SQLiteDatabase> m_sqliteDatabase;
     85    RefPtr<IDBSQLiteDatabase> m_sqliteDatabase;
     86    int64 m_id;
    8287    String m_name;
    8388    String m_description;
  • trunk/WebCore/storage/IDBFactoryBackendImpl.cpp

    r70093 r70522  
    3434#include "IDBDatabaseBackendImpl.h"
    3535#include "IDBDatabaseException.h"
     36#include "IDBSQLiteDatabase.h"
    3637#include "IDBTransactionCoordinator.h"
    37 #include "SQLiteDatabase.h"
    3838#include "SecurityOrigin.h"
    3939#include <wtf/Threading.h>
     
    5353}
    5454
    55 static PassOwnPtr<SQLiteDatabase> openSQLiteDatabase(SecurityOrigin* securityOrigin, String name, const String& pathBase, int64_t maximumSize)
     55void IDBFactoryBackendImpl::removeSQLiteDatabase(const String& filePath)
     56{
     57    ASSERT(m_sqliteDatabaseMap.contains(filePath));
     58    m_sqliteDatabaseMap.remove(filePath);
     59}
     60
     61static PassRefPtr<IDBSQLiteDatabase> openSQLiteDatabase(SecurityOrigin* securityOrigin, const String& pathBase, int64_t maximumSize, const String& fileIdentifier, IDBFactoryBackendImpl* factory)
    5662{
    5763    String path = ":memory:";
     
    6369        }
    6470
    65         path = pathByAppendingComponent(pathBase, IDBFactoryBackendImpl::databaseFileName(name, securityOrigin));
     71        path = pathByAppendingComponent(pathBase, IDBFactoryBackendImpl::databaseFileName(securityOrigin));
    6672    }
    6773
    68     OwnPtr<SQLiteDatabase> sqliteDatabase = adoptPtr(new SQLiteDatabase());
    69     if (!sqliteDatabase->open(path)) {
     74    RefPtr<IDBSQLiteDatabase> sqliteDatabase = IDBSQLiteDatabase::create(fileIdentifier, factory);
     75    if (!sqliteDatabase->db().open(path)) {
    7076        // FIXME: Is there any other thing we could possibly do to recover at this point? If so, do it rather than just erroring out.
    7177        LOG_ERROR("Failed to open database file %s for IndexedDB", path.utf8().data());
     
    7379    }
    7480
    75     sqliteDatabase->setMaximumSize(maximumSize);
     81    // FIXME: Error checking?
     82    sqliteDatabase->db().setMaximumSize(maximumSize);
     83    sqliteDatabase->db().turnOnIncrementalAutoVacuum();
     84
    7685    return sqliteDatabase.release();
    7786}
    7887
    79 static bool createTables(SQLiteDatabase* sqliteDatabase)
     88static bool createTables(SQLiteDatabase& sqliteDatabase)
    8089{
    81     // FIXME: Remove all the drop table commands once the on disk structure stabilizes.
    8290    static const char* commands[] = {
    83         "DROP TABLE IF EXISTS MetaData",
    84         "CREATE TABLE IF NOT EXISTS MetaData (id INTEGER PRIMARY KEY, name TEXT NOT NULL, description TEXT NOT NULL, version TEXT NOT NULL)",
     91        "CREATE TABLE IF NOT EXISTS Databases (id INTEGER PRIMARY KEY, name TEXT NOT NULL, description TEXT NOT NULL, version TEXT NOT NULL)",
     92        "CREATE UNIQUE INDEX IF NOT EXISTS Databases_name ON Databases(name)",
    8593
    86         "DROP TABLE IF EXISTS ObjectStores",
    87         "CREATE TABLE IF NOT EXISTS ObjectStores (id INTEGER PRIMARY KEY, name TEXT NOT NULL UNIQUE, keyPath TEXT, doAutoIncrement INTEGER NOT NULL)",
    88         "DROP INDEX IF EXISTS ObjectStores_name",
    89         "CREATE UNIQUE INDEX IF NOT EXISTS ObjectStores_name ON ObjectStores(name)",
     94        "CREATE TABLE IF NOT EXISTS ObjectStores (id INTEGER PRIMARY KEY, name TEXT NOT NULL, keyPath TEXT, doAutoIncrement INTEGER NOT NULL, databaseId INTEGER NOT NULL REFERENCES Databases(id))",
     95        "CREATE UNIQUE INDEX IF NOT EXISTS ObjectStores_composit ON ObjectStores(databaseId, name)",
    9096
    91         "DROP TABLE IF EXISTS Indexes",
    92         "CREATE TABLE IF NOT EXISTS Indexes (id INTEGER PRIMARY KEY, objectStoreId INTEGER NOT NULL REFERENCES ObjectStore(id), name TEXT NOT NULL UNIQUE, keyPath TEXT, isUnique INTEGER NOT NULL)",
    93         "DROP INDEX IF EXISTS Indexes_composit",
     97        "CREATE TABLE IF NOT EXISTS Indexes (id INTEGER PRIMARY KEY, objectStoreId INTEGER NOT NULL REFERENCES ObjectStore(id), name TEXT NOT NULL, keyPath TEXT, isUnique INTEGER NOT NULL)",
    9498        "CREATE UNIQUE INDEX IF NOT EXISTS Indexes_composit ON Indexes(objectStoreId, name)",
    9599
    96         "DROP TABLE IF EXISTS ObjectStoreData",
    97         "CREATE TABLE IF NOT EXISTS ObjectStoreData (id INTEGER PRIMARY KEY, objectStoreId INTEGER NOT NULL REFERENCES ObjectStore(id), keyString TEXT UNIQUE, keyDate INTEGER UNIQUE, keyNumber INTEGER UNIQUE, value TEXT NOT NULL)",
    98         "DROP INDEX IF EXISTS ObjectStoreData_composit",
     100        "CREATE TABLE IF NOT EXISTS ObjectStoreData (id INTEGER PRIMARY KEY, objectStoreId INTEGER NOT NULL REFERENCES ObjectStore(id), keyString TEXT, keyDate INTEGER, keyNumber INTEGER, value TEXT NOT NULL)",
    99101        "CREATE UNIQUE INDEX IF NOT EXISTS ObjectStoreData_composit ON ObjectStoreData(keyString, keyDate, keyNumber, objectStoreId)",
    100102
    101         "DROP TABLE IF EXISTS IndexData",
    102103        "CREATE TABLE IF NOT EXISTS IndexData (id INTEGER PRIMARY KEY, indexId INTEGER NOT NULL REFERENCES Indexes(id), keyString TEXT, keyDate INTEGER, keyNumber INTEGER, objectStoreDataId INTEGER NOT NULL REFERENCES ObjectStoreData(id))",
    103         "DROP INDEX IF EXISTS IndexData_composit",
    104104        "CREATE INDEX IF NOT EXISTS IndexData_composit ON IndexData(keyString, keyDate, keyNumber, indexId)",
    105         "DROP INDEX IF EXISTS IndexData_objectStoreDataId",
    106105        "CREATE INDEX IF NOT EXISTS IndexData_objectStoreDataId ON IndexData(objectStoreDataId)",
    107         "DROP INDEX IF EXISTS IndexData_indexId",
    108106        "CREATE INDEX IF NOT EXISTS IndexData_indexId ON IndexData(indexId)"
    109107        };
    110108
    111109    for (size_t i = 0; i < arraysize(commands); ++i) {
    112         if (!sqliteDatabase->executeCommand(commands[i])) {
     110        if (!sqliteDatabase.executeCommand(commands[i])) {
    113111            // FIXME: We should try to recover from this situation. Maybe nuke the database and start over?
    114112            LOG_ERROR("Failed to run the following command for IndexedDB: %s", commands[i]);
     
    121119void IDBFactoryBackendImpl::open(const String& name, const String& description, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<SecurityOrigin> securityOrigin, Frame*, const String& dataDir, int64_t maximumSize)
    122120{
    123     IDBDatabaseBackendMap::iterator it = m_databaseBackendMap.find(name);
     121    String fileIdentifier = securityOrigin->databaseIdentifier();
     122    String uniqueIdentifier = fileIdentifier + "@" + name;
     123    IDBDatabaseBackendMap::iterator it = m_databaseBackendMap.find(uniqueIdentifier);
    124124    if (it != m_databaseBackendMap.end()) {
    125125        if (!description.isNull())
     
    131131    // FIXME: Everything from now on should be done on another thread.
    132132
    133     OwnPtr<SQLiteDatabase> sqliteDatabase = openSQLiteDatabase(securityOrigin.get(), name, dataDir, maximumSize);
    134     if (!sqliteDatabase || !createTables(sqliteDatabase.get())) {
    135         callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Internal error."));
    136         return;
     133    RefPtr<IDBSQLiteDatabase> sqliteDatabase;
     134    SQLiteDatabaseMap::iterator it2 = m_sqliteDatabaseMap.find(fileIdentifier);
     135    if (it2 != m_sqliteDatabaseMap.end())
     136        sqliteDatabase = it2->second;
     137    else {
     138        sqliteDatabase = openSQLiteDatabase(securityOrigin.get(), dataDir, maximumSize, fileIdentifier, this);
     139
     140        if (!sqliteDatabase || !createTables(sqliteDatabase->db())) {
     141            callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Internal error."));
     142            return;
     143        }
     144        m_sqliteDatabaseMap.set(fileIdentifier, sqliteDatabase.get());
    137145    }
    138146
    139     RefPtr<IDBDatabaseBackendImpl> databaseBackend = IDBDatabaseBackendImpl::create(name, description, sqliteDatabase.release(), m_transactionCoordinator.get());
     147    RefPtr<IDBDatabaseBackendImpl> databaseBackend = IDBDatabaseBackendImpl::create(name, description, sqliteDatabase.get(), m_transactionCoordinator.get());
    140148    callbacks->onSuccess(databaseBackend.get());
    141     m_databaseBackendMap.set(name, databaseBackend.release());
     149    m_databaseBackendMap.set(uniqueIdentifier, databaseBackend.release());
    142150}
    143151
    144 String IDBFactoryBackendImpl::databaseFileName(const String& name, SecurityOrigin* securityOrigin)
     152String IDBFactoryBackendImpl::databaseFileName(SecurityOrigin* securityOrigin)
    145153{
    146154    String databaseIdentifier = securityOrigin->databaseIdentifier();
    147     String santizedName = encodeForFileName(name);
    148     return databaseIdentifier + "@" + santizedName + ".indexeddb";
     155    return databaseIdentifier + ".indexeddb";
    149156}
    150157
  • trunk/WebCore/storage/IDBFactoryBackendImpl.h

    r69421 r70522  
    4040
    4141class IDBDatabaseBackendImpl;
     42class IDBSQLiteDatabase;
    4243class IDBTransactionCoordinator;
    4344
     
    5051    virtual ~IDBFactoryBackendImpl();
    5152
     53    // IDBSQLiteDatabase's lifetime may be shorter than ours, so we need notification when it dies.
     54    void removeSQLiteDatabase(const String& filePath);
     55
    5256    virtual void open(const String& name, const String& description, PassRefPtr<IDBCallbacks>, PassRefPtr<SecurityOrigin>, Frame*, const String& dataDir, int64_t maximumSize);
    5357
    54     static String databaseFileName(const String& name, SecurityOrigin*);
     58    static String databaseFileName(SecurityOrigin*);
    5559
    5660private:
    5761    IDBFactoryBackendImpl();
    5862
     63    // FIXME: Just hold a weak pointer.
    5964    typedef HashMap<String, RefPtr<IDBDatabaseBackendImpl> > IDBDatabaseBackendMap;
    6065    IDBDatabaseBackendMap m_databaseBackendMap;
     66
     67    typedef HashMap<String, IDBSQLiteDatabase*> SQLiteDatabaseMap;
     68    SQLiteDatabaseMap m_sqliteDatabaseMap;
     69
    6170    RefPtr<IDBTransactionCoordinator> m_transactionCoordinator;
    6271
    63     // We only create one instance of this class at a time.
     72    // Only one instance of the factory should exist at any given time.
    6473    static IDBFactoryBackendImpl* idbFactoryBackendImpl;
    6574};
  • trunk/WebCore/storage/IDBObjectStoreBackendImpl.cpp

    r70093 r70522  
    132132}
    133133
    134 static bool putObjectStoreData(SQLiteDatabase& db, IDBKey* key, SerializedScriptValue* value, int64_t objectStoreId, int64_t* dataRowId)
    135 {
    136     String sql = *dataRowId != -1 ? "UPDATE ObjectStoreData SET keyString = ?, keyDate = ?, keyNumber = ?, value = ? WHERE id = ?"
    137                                   : "INSERT INTO ObjectStoreData (keyString, keyDate, keyNumber, value, objectStoreId) VALUES (?, ?, ?, ?, ?)";
     134static bool putObjectStoreData(SQLiteDatabase& db, IDBKey* key, SerializedScriptValue* value, int64_t objectStoreId, int64_t& dataRowId)
     135{
     136    String sql = dataRowId != IDBObjectStoreBackendImpl::InvalidId ? "UPDATE ObjectStoreData SET keyString = ?, keyDate = ?, keyNumber = ?, value = ? WHERE id = ?"
     137                                                                   : "INSERT INTO ObjectStoreData (keyString, keyDate, keyNumber, value, objectStoreId) VALUES (?, ?, ?, ?, ?)";
    138138    SQLiteStatement query(db, sql);
    139139    if (query.prepare() != SQLResultOk)
     
    141141    key->bindWithNulls(query, 1);
    142142    query.bindText(4, value->toWireString());
    143     if (*dataRowId != -1)
    144         query.bindInt(5, *dataRowId);
     143    if (dataRowId != IDBDatabaseBackendImpl::InvalidId)
     144        query.bindInt64(5, dataRowId);
    145145    else
    146146        query.bindInt64(5, objectStoreId);
     
    149149        return false;
    150150
    151     if (*dataRowId == -1)
    152         *dataRowId = db.lastInsertRowID();
     151    if (dataRowId == IDBDatabaseBackendImpl::InvalidId)
     152        dataRowId = db.lastInsertRowID();
    153153
    154154    return true;
     
    239239    // Before this point, don't do any mutation.  After this point, rollback the transaction in case of error.
    240240
    241     int64_t dataRowId = isExistingValue ? getQuery.getColumnInt(0) : -1;
    242     if (!putObjectStoreData(objectStore->sqliteDatabase(), key.get(), value.get(), objectStore->id(), &dataRowId)) {
     241    int64_t dataRowId = isExistingValue ? getQuery.getColumnInt(0) : InvalidId;
     242    if (!putObjectStoreData(objectStore->sqliteDatabase(), key.get(), value.get(), objectStore->id(), dataRowId)) {
    243243        // FIXME: The Indexed Database specification does not have an error code dedicated to I/O errors.
    244244        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Error writing data to stable storage."));
  • trunk/WebCore/storage/IDBObjectStoreBackendImpl.h

    r69721 r70522  
    5353    virtual ~IDBObjectStoreBackendImpl();
    5454
     55    static const int64_t InvalidId = 0;
    5556    int64_t id() const
    5657    {
     
    9596    static void addIndexToMap(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBIndexBackendImpl>);
    9697
    97     static const int64_t InvalidId = 0;
    98 
    9998    RefPtr<IDBDatabaseBackendImpl> m_database;
    10099
  • trunk/WebCore/storage/IDBSQLiteDatabase.h

    r70521 r70522  
    1111 *     notice, this list of conditions and the following disclaimer in the
    1212 *     documentation and/or other materials provided with the distribution.
    13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
    14  *     its contributors may be used to endorse or promote products derived
    15  *     from this software without specific prior written permission.
    1613 *
    1714 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     
    2623 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2724 */
    28 #ifndef IDBFactoryBackendImpl_h
    29 #define IDBFactoryBackendImpl_h
    3025
    31 #include "IDBFactoryBackendInterface.h"
    32 #include <wtf/HashMap.h>
    33 #include <wtf/text/StringHash.h>
     26#ifndef IDBSQLiteDatabase_h
     27#define IDBSQLiteDatabase_h
    3428
    3529#if ENABLE(INDEXED_DATABASE)
    3630
     31#include "SQLiteDatabase.h"
     32#include <wtf/PassRefPtr.h>
     33#include <wtf/RefCounted.h>
     34#include <wtf/RefPtr.h>
     35
    3736namespace WebCore {
    3837
    39 class DOMStringList;
     38class IDBFactoryBackendImpl;
    4039
    41 class IDBDatabaseBackendImpl;
    42 class IDBTransactionCoordinator;
     40class IDBSQLiteDatabase : public RefCounted<IDBSQLiteDatabase> {
     41public:
     42    static PassRefPtr<IDBSQLiteDatabase> create(String identifier, IDBFactoryBackendImpl* factory)
     43    {
     44        return adoptRef(new IDBSQLiteDatabase(identifier, factory));
     45    }
     46    ~IDBSQLiteDatabase();
    4347
    44 class IDBFactoryBackendImpl : public IDBFactoryBackendInterface {
    45 public:
    46     static PassRefPtr<IDBFactoryBackendImpl> create()
    47     {
    48         return adoptRef(new IDBFactoryBackendImpl());
    49     }
    50     virtual ~IDBFactoryBackendImpl();
    51 
    52     virtual void open(const String& name, const String& description, PassRefPtr<IDBCallbacks>, PassRefPtr<SecurityOrigin>, Frame*, const String& dataDir, int64_t maximumSize);
    53 
    54     static String databaseFileName(const String& name, SecurityOrigin*);
     48    SQLiteDatabase& db() { return m_db; }
    5549
    5650private:
    57     IDBFactoryBackendImpl();
     51    IDBSQLiteDatabase(String identifier, IDBFactoryBackendImpl* factory);
    5852
    59     typedef HashMap<String, RefPtr<IDBDatabaseBackendImpl> > IDBDatabaseBackendMap;
    60     IDBDatabaseBackendMap m_databaseBackendMap;
    61     RefPtr<IDBTransactionCoordinator> m_transactionCoordinator;
    62 
    63     // We only create one instance of this class at a time.
    64     static IDBFactoryBackendImpl* idbFactoryBackendImpl;
     53    SQLiteDatabase m_db;
     54    String m_identifier;
     55    RefPtr<IDBFactoryBackendImpl> m_factory;
    6556};
    6657
     
    6960#endif
    7061
    71 #endif // IDBFactoryBackendImpl_h
    72 
     62#endif // IDBSQLiteDatabase_h
  • trunk/WebKit/chromium/ChangeLog

    r70513 r70522  
     12010-10-26  Jeremy Orlow  <jorlow@chromium.org>
     2
     3        Reviewed by Steve Block.
     4
     5        Quota for IndexedDB should be per origin not per database
     6        https://bugs.webkit.org/show_bug.cgi?id=48064
     7
     8        * public/WebIDBFactory.h:
     9        * public/WebSecurityOrigin.h:
     10        * src/WebIDBFactory.cpp:
     11        (WebKit::WebIDBFactory::databaseFileName):
     12        * src/WebSecurityOrigin.cpp:
     13        (WebKit::WebSecurityOrigin::get):
     14
    1152010-10-26  Sheriff Bot  <webkit.review.bot@gmail.com>
    216
  • trunk/WebKit/chromium/public/WebIDBFactory.h

    r69670 r70522  
    5959
    6060    // The file name that would be used for persisting a given indexed database on the file system.
     61    WEBKIT_API static WebString databaseFileName(const WebSecurityOrigin&);
     62    // FIXME: Remove after roll.
    6163    WEBKIT_API static WebString databaseFileName(const WebString& name, const WebSecurityOrigin&);
    6264};
  • trunk/WebKit/chromium/public/WebIDBKey.h

    r67600 r70522  
    8383
    8484private:
    85 
    8685    WebPrivatePtr<WebCore::IDBKey> m_private;
    8786};
  • trunk/WebKit/chromium/public/WebSecurityOrigin.h

    r59870 r70522  
    101101    WebSecurityOrigin& operator=(const WTF::PassRefPtr<WebCore::SecurityOrigin>&);
    102102    operator WTF::PassRefPtr<WebCore::SecurityOrigin>() const;
     103    WebCore::SecurityOrigin* get() const;
    103104#endif
    104105
  • trunk/WebKit/chromium/src/WebIDBFactory.cpp

    r67941 r70522  
    3232#include "WebIDBFactory.h"
    3333
    34 #if ENABLE(INDEXED_DATABASE)
    35 
    3634#include "IDBFactoryBackendImpl.h"
    37 #include "SecurityOrigin.h"
     35#include "WebSecurityOrigin.h"
     36#include <wtf/UnusedParam.h>
    3837
    3938using namespace WebCore;
     
    4140namespace WebKit {
    4241
     42WebString WebIDBFactory::databaseFileName(const WebSecurityOrigin& origin)
     43{
     44    return IDBFactoryBackendImpl::databaseFileName(origin.get());
     45}
     46
    4347WebString WebIDBFactory::databaseFileName(const WebString& name, const WebSecurityOrigin& origin)
    4448{
    45     RefPtr<SecurityOrigin> securityOrigin;
    46     securityOrigin = origin;
    47     return IDBFactoryBackendImpl::databaseFileName(name, securityOrigin.get());
     49    UNUSED_PARAM(name);
     50    return databaseFileName(origin);
    4851}
    4952
    5053}
    51 
    52 #endif // ENABLE(INDEXED_DATABASE)
  • trunk/WebKit/chromium/src/WebSecurityOrigin.cpp

    r59870 r70522  
    144144}
    145145
     146SecurityOrigin* WebSecurityOrigin::get() const
     147{
     148    return m_private;
     149}
     150
    146151void WebSecurityOrigin::assign(WebSecurityOriginPrivate* p)
    147152{
Note: See TracChangeset for help on using the changeset viewer.