OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 } | 102 } |
103 | 103 |
104 IDBDatabaseBackendImpl::IDBDatabaseBackendImpl(const String& name, IDBBackingSto
re* backingStore, IDBTransactionCoordinator* coordinator, IDBFactoryBackendImpl*
factory, const String& uniqueIdentifier) | 104 IDBDatabaseBackendImpl::IDBDatabaseBackendImpl(const String& name, IDBBackingSto
re* backingStore, IDBTransactionCoordinator* coordinator, IDBFactoryBackendImpl*
factory, const String& uniqueIdentifier) |
105 : m_backingStore(backingStore) | 105 : m_backingStore(backingStore) |
106 , m_id(InvalidId) | 106 , m_id(InvalidId) |
107 , m_name(name) | 107 , m_name(name) |
108 , m_version("") | 108 , m_version("") |
109 , m_identifier(uniqueIdentifier) | 109 , m_identifier(uniqueIdentifier) |
110 , m_factory(factory) | 110 , m_factory(factory) |
111 , m_transactionCoordinator(coordinator) | 111 , m_transactionCoordinator(coordinator) |
| 112 , m_pendingConnectionCount(0) |
112 { | 113 { |
113 ASSERT(!m_name.isNull()); | 114 ASSERT(!m_name.isNull()); |
114 } | 115 } |
115 | 116 |
116 bool IDBDatabaseBackendImpl::openInternal() | 117 bool IDBDatabaseBackendImpl::openInternal() |
117 { | 118 { |
118 bool success = m_backingStore->getIDBDatabaseMetaData(m_name, m_version, m_i
d); | 119 bool success = m_backingStore->getIDBDatabaseMetaData(m_name, m_version, m_i
d); |
119 ASSERT(success == (m_id != InvalidId)); | 120 ASSERT(success == (m_id != InvalidId)); |
120 if (success) { | 121 if (success) { |
121 loadObjectStores(); | 122 loadObjectStores(); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::IDB_AB
ORT_ERR, "Connection was closed before set version transaction was created")); | 216 callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::IDB_AB
ORT_ERR, "Connection was closed before set version transaction was created")); |
216 return; | 217 return; |
217 } | 218 } |
218 for (DatabaseCallbacksSet::const_iterator it = m_databaseCallbacksSet.begin(
); it != m_databaseCallbacksSet.end(); ++it) { | 219 for (DatabaseCallbacksSet::const_iterator it = m_databaseCallbacksSet.begin(
); it != m_databaseCallbacksSet.end(); ++it) { |
219 if (*it != databaseCallbacks) | 220 if (*it != databaseCallbacks) |
220 (*it)->onVersionChange(version); | 221 (*it)->onVersionChange(version); |
221 } | 222 } |
222 // FIXME: Only fire onBlocked if there are open connections after the | 223 // FIXME: Only fire onBlocked if there are open connections after the |
223 // VersionChangeEvents are received, not just set up to fire. | 224 // VersionChangeEvents are received, not just set up to fire. |
224 // https://bugs.webkit.org/show_bug.cgi?id=71130 | 225 // https://bugs.webkit.org/show_bug.cgi?id=71130 |
225 if (m_databaseCallbacksSet.size() > 1) { | 226 if (connectionCount() > 1) { |
226 callbacks->onBlocked(); | 227 callbacks->onBlocked(); |
227 RefPtr<PendingSetVersionCall> pendingSetVersionCall = PendingSetVersionC
all::create(version, callbacks, databaseCallbacks); | 228 RefPtr<PendingSetVersionCall> pendingSetVersionCall = PendingSetVersionC
all::create(version, callbacks, databaseCallbacks); |
228 m_pendingSetVersionCalls.append(pendingSetVersionCall); | 229 m_pendingSetVersionCalls.append(pendingSetVersionCall); |
229 return; | 230 return; |
230 } | 231 } |
231 if (m_runningVersionChangeTransaction) { | 232 if (m_runningVersionChangeTransaction) { |
232 RefPtr<PendingSetVersionCall> pendingSetVersionCall = PendingSetVersionC
all::create(version, callbacks, databaseCallbacks); | 233 RefPtr<PendingSetVersionCall> pendingSetVersionCall = PendingSetVersionC
all::create(version, callbacks, databaseCallbacks); |
233 m_pendingSetVersionCalls.append(pendingSetVersionCall); | 234 m_pendingSetVersionCalls.append(pendingSetVersionCall); |
234 return; | 235 return; |
235 } | 236 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 RefPtr<IDBTransactionBackendInterface> transaction = prpTransaction; | 272 RefPtr<IDBTransactionBackendInterface> transaction = prpTransaction; |
272 ASSERT(m_transactions.contains(transaction.get())); | 273 ASSERT(m_transactions.contains(transaction.get())); |
273 m_transactions.remove(transaction.get()); | 274 m_transactions.remove(transaction.get()); |
274 if (transaction->mode() == IDBTransaction::VERSION_CHANGE) { | 275 if (transaction->mode() == IDBTransaction::VERSION_CHANGE) { |
275 ASSERT(transaction.get() == m_runningVersionChangeTransaction.get()); | 276 ASSERT(transaction.get() == m_runningVersionChangeTransaction.get()); |
276 m_runningVersionChangeTransaction.clear(); | 277 m_runningVersionChangeTransaction.clear(); |
277 processPendingCalls(); | 278 processPendingCalls(); |
278 } | 279 } |
279 } | 280 } |
280 | 281 |
| 282 int32_t IDBDatabaseBackendImpl::connectionCount() |
| 283 { |
| 284 return m_databaseCallbacksSet.size() + m_pendingConnectionCount; |
| 285 } |
| 286 |
281 void IDBDatabaseBackendImpl::processPendingCalls() | 287 void IDBDatabaseBackendImpl::processPendingCalls() |
282 { | 288 { |
283 ASSERT(m_databaseCallbacksSet.size() <= 1); | 289 ASSERT(connectionCount() <= 1); |
284 | 290 |
285 // Pending calls may be requeued or aborted | 291 // Pending calls may be requeued or aborted |
286 Deque<RefPtr<PendingSetVersionCall> > pendingSetVersionCalls; | 292 Deque<RefPtr<PendingSetVersionCall> > pendingSetVersionCalls; |
287 m_pendingSetVersionCalls.swap(pendingSetVersionCalls); | 293 m_pendingSetVersionCalls.swap(pendingSetVersionCalls); |
288 while (!pendingSetVersionCalls.isEmpty()) { | 294 while (!pendingSetVersionCalls.isEmpty()) { |
289 ExceptionCode ec = 0; | 295 ExceptionCode ec = 0; |
290 RefPtr<PendingSetVersionCall> pendingSetVersionCall = pendingSetVersionC
alls.takeFirst(); | 296 RefPtr<PendingSetVersionCall> pendingSetVersionCall = pendingSetVersionC
alls.takeFirst(); |
291 setVersion(pendingSetVersionCall->version(), pendingSetVersionCall->call
backs(), pendingSetVersionCall->databaseCallbacks(), ec); | 297 setVersion(pendingSetVersionCall->version(), pendingSetVersionCall->call
backs(), pendingSetVersionCall->databaseCallbacks(), ec); |
292 ASSERT(!ec); | 298 ASSERT(!ec); |
293 } | 299 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 } | 344 } |
339 } | 345 } |
340 | 346 |
341 RefPtr<IDBTransactionBackendInterface> transaction = IDBTransactionBackendIm
pl::create(objectStoreNames, mode, this); | 347 RefPtr<IDBTransactionBackendInterface> transaction = IDBTransactionBackendIm
pl::create(objectStoreNames, mode, this); |
342 m_transactions.add(transaction.get()); | 348 m_transactions.add(transaction.get()); |
343 return transaction.release(); | 349 return transaction.release(); |
344 } | 350 } |
345 | 351 |
346 void IDBDatabaseBackendImpl::registerFrontendCallbacks(PassRefPtr<IDBDatabaseCal
lbacks> callbacks) | 352 void IDBDatabaseBackendImpl::registerFrontendCallbacks(PassRefPtr<IDBDatabaseCal
lbacks> callbacks) |
347 { | 353 { |
| 354 ASSERT(m_backingStore.get()); |
| 355 ASSERT(m_pendingConnectionCount); |
| 356 --m_pendingConnectionCount; |
348 m_databaseCallbacksSet.add(RefPtr<IDBDatabaseCallbacks>(callbacks)); | 357 m_databaseCallbacksSet.add(RefPtr<IDBDatabaseCallbacks>(callbacks)); |
349 } | 358 } |
350 | 359 |
351 void IDBDatabaseBackendImpl::openConnection(PassRefPtr<IDBCallbacks> callbacks) | 360 void IDBDatabaseBackendImpl::openConnection(PassRefPtr<IDBCallbacks> callbacks) |
352 { | 361 { |
| 362 ASSERT(m_backingStore.get()); |
353 if (!m_pendingDeleteCalls.isEmpty() || m_runningVersionChangeTransaction ||
!m_pendingSetVersionCalls.isEmpty()) | 363 if (!m_pendingDeleteCalls.isEmpty() || m_runningVersionChangeTransaction ||
!m_pendingSetVersionCalls.isEmpty()) |
354 m_pendingOpenCalls.append(PendingOpenCall::create(callbacks)); | 364 m_pendingOpenCalls.append(PendingOpenCall::create(callbacks)); |
355 else { | 365 else { |
356 if (m_id == InvalidId && !openInternal()) | 366 if (m_id == InvalidId && !openInternal()) |
357 callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UN
KNOWN_ERR, "Internal error.")); | 367 callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UN
KNOWN_ERR, "Internal error.")); |
358 else | 368 else { |
| 369 ++m_pendingConnectionCount; |
359 callbacks->onSuccess(this); | 370 callbacks->onSuccess(this); |
| 371 } |
360 } | 372 } |
361 } | 373 } |
362 | 374 |
363 void IDBDatabaseBackendImpl::deleteDatabase(PassRefPtr<IDBCallbacks> prpCallback
s) | 375 void IDBDatabaseBackendImpl::deleteDatabase(PassRefPtr<IDBCallbacks> prpCallback
s) |
364 { | 376 { |
365 if (m_runningVersionChangeTransaction || !m_pendingSetVersionCalls.isEmpty()
) { | 377 if (m_runningVersionChangeTransaction || !m_pendingSetVersionCalls.isEmpty()
) { |
366 m_pendingDeleteCalls.append(PendingDeleteCall::create(prpCallbacks)); | 378 m_pendingDeleteCalls.append(PendingDeleteCall::create(prpCallbacks)); |
367 return; | 379 return; |
368 } | 380 } |
369 RefPtr<IDBCallbacks> callbacks = prpCallbacks; | 381 RefPtr<IDBCallbacks> callbacks = prpCallbacks; |
(...skipping 18 matching lines...) Expand all Loading... |
388 m_id = InvalidId; | 400 m_id = InvalidId; |
389 m_objectStores.clear(); | 401 m_objectStores.clear(); |
390 callbacks->onSuccess(SerializedScriptValue::nullValue()); | 402 callbacks->onSuccess(SerializedScriptValue::nullValue()); |
391 } | 403 } |
392 | 404 |
393 void IDBDatabaseBackendImpl::close(PassRefPtr<IDBDatabaseCallbacks> prpCallbacks
) | 405 void IDBDatabaseBackendImpl::close(PassRefPtr<IDBDatabaseCallbacks> prpCallbacks
) |
394 { | 406 { |
395 RefPtr<IDBDatabaseCallbacks> callbacks = prpCallbacks; | 407 RefPtr<IDBDatabaseCallbacks> callbacks = prpCallbacks; |
396 ASSERT(m_databaseCallbacksSet.contains(callbacks)); | 408 ASSERT(m_databaseCallbacksSet.contains(callbacks)); |
397 m_databaseCallbacksSet.remove(callbacks); | 409 m_databaseCallbacksSet.remove(callbacks); |
398 if (m_databaseCallbacksSet.size() > 1) | 410 if (connectionCount() > 1) |
399 return; | 411 return; |
400 | 412 |
401 processPendingCalls(); | 413 processPendingCalls(); |
402 | 414 |
403 if (!m_databaseCallbacksSet.size()) { | 415 if (!connectionCount()) { |
404 TransactionSet transactions(m_transactions); | 416 TransactionSet transactions(m_transactions); |
405 for (TransactionSet::const_iterator it = transactions.begin(); it != tra
nsactions.end(); ++it) | 417 for (TransactionSet::const_iterator it = transactions.begin(); it != tra
nsactions.end(); ++it) |
406 (*it)->abort(); | 418 (*it)->abort(); |
407 ASSERT(m_transactions.isEmpty()); | 419 ASSERT(m_transactions.isEmpty()); |
408 | 420 |
409 m_backingStore.clear(); | 421 m_backingStore.clear(); |
410 // This check should only be false in tests. | 422 // This check should only be false in tests. |
411 if (m_factory) | 423 if (m_factory) |
412 m_factory->removeIDBDatabaseBackend(m_identifier); | 424 m_factory->removeIDBDatabaseBackend(m_identifier); |
413 } | 425 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 | 457 |
446 void IDBDatabaseBackendImpl::resetVersion(ScriptExecutionContext*, PassRefPtr<ID
BDatabaseBackendImpl> database, const String& version) | 458 void IDBDatabaseBackendImpl::resetVersion(ScriptExecutionContext*, PassRefPtr<ID
BDatabaseBackendImpl> database, const String& version) |
447 { | 459 { |
448 database->m_version = version; | 460 database->m_version = version; |
449 } | 461 } |
450 | 462 |
451 | 463 |
452 } // namespace WebCore | 464 } // namespace WebCore |
453 | 465 |
454 #endif // ENABLE(INDEXED_DATABASE) | 466 #endif // ENABLE(INDEXED_DATABASE) |
OLD | NEW |