| 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 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 if (!putInt(m_db.get(), key, rowId)) | 205 if (!putInt(m_db.get(), key, rowId)) |
| 206 return false; | 206 return false; |
| 207 } | 207 } |
| 208 | 208 |
| 209 if (!putString(m_db.get(), DatabaseMetaDataKey::encode(rowId, DatabaseMetaDa
taKey::kUserVersion), version)) | 209 if (!putString(m_db.get(), DatabaseMetaDataKey::encode(rowId, DatabaseMetaDa
taKey::kUserVersion), version)) |
| 210 return false; | 210 return false; |
| 211 | 211 |
| 212 return true; | 212 return true; |
| 213 } | 213 } |
| 214 | 214 |
| 215 static bool checkObjectStoreAndMetaDataType(const LevelDBIterator* it, const Vec
tor<char>& stopKey, int64_t objectStoreId, int64_t metaDataType) |
| 216 { |
| 217 if (!it->isValid() || compareKeys(it->key(), stopKey) >= 0) |
| 218 return false; |
| 219 |
| 220 ObjectStoreMetaDataKey metaDataKey; |
| 221 const char* p = ObjectStoreMetaDataKey::decode(it->key().begin(), it->key().
end(), &metaDataKey); |
| 222 ASSERT_UNUSED(p, p); |
| 223 if (metaDataKey.objectStoreId() != objectStoreId) |
| 224 return false; |
| 225 if (metaDataKey.metaDataType() != metaDataType) |
| 226 return false; |
| 227 return true; |
| 228 } |
| 229 |
| 215 void IDBLevelDBBackingStore::getObjectStores(int64_t databaseId, Vector<int64_t>
& foundIds, Vector<String>& foundNames, Vector<String>& foundKeyPaths, Vector<bo
ol>& foundAutoIncrementFlags) | 230 void IDBLevelDBBackingStore::getObjectStores(int64_t databaseId, Vector<int64_t>
& foundIds, Vector<String>& foundNames, Vector<String>& foundKeyPaths, Vector<bo
ol>& foundAutoIncrementFlags) |
| 216 { | 231 { |
| 217 const Vector<char> startKey = ObjectStoreMetaDataKey::encode(databaseId, 1,
0); | 232 const Vector<char> startKey = ObjectStoreMetaDataKey::encode(databaseId, 1,
0); |
| 218 const Vector<char> stopKey = ObjectStoreMetaDataKey::encodeMaxKey(databaseId
); | 233 const Vector<char> stopKey = ObjectStoreMetaDataKey::encodeMaxKey(databaseId
); |
| 219 | 234 |
| 220 OwnPtr<LevelDBIterator> it = m_db->createIterator(); | 235 OwnPtr<LevelDBIterator> it = m_db->createIterator(); |
| 221 for (it->seek(startKey); it->isValid() && compareKeys(it->key(), stopKey) <
0; it->next()) { | 236 it->seek(startKey); |
| 237 while (it->isValid() && compareKeys(it->key(), stopKey) < 0) { |
| 222 const char *p = it->key().begin(); | 238 const char *p = it->key().begin(); |
| 223 const char *limit = it->key().end(); | 239 const char *limit = it->key().end(); |
| 224 | 240 |
| 225 ObjectStoreMetaDataKey metaDataKey; | 241 ObjectStoreMetaDataKey metaDataKey; |
| 226 p = ObjectStoreMetaDataKey::decode(p, limit, &metaDataKey); | 242 p = ObjectStoreMetaDataKey::decode(p, limit, &metaDataKey); |
| 227 ASSERT(p); | 243 ASSERT(p); |
| 244 if (metaDataKey.metaDataType()) { |
| 245 LOG_ERROR("Internal Indexed DB error."); |
| 246 return; |
| 247 } |
| 228 | 248 |
| 229 int64_t objectStoreId = metaDataKey.objectStoreId(); | 249 int64_t objectStoreId = metaDataKey.objectStoreId(); |
| 230 | |
| 231 String objectStoreName = decodeString(it->value().begin(), it->value().e
nd()); | 250 String objectStoreName = decodeString(it->value().begin(), it->value().e
nd()); |
| 232 | 251 |
| 233 it->next(); | 252 it->next(); |
| 234 if (!it->isValid()) { | 253 if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, 1
)) { |
| 235 LOG_ERROR("Internal Indexed DB error."); | 254 LOG_ERROR("Internal Indexed DB error."); |
| 236 return; | 255 return; |
| 237 } | 256 } |
| 238 String keyPath = decodeString(it->value().begin(), it->value().end()); | 257 String keyPath = decodeString(it->value().begin(), it->value().end()); |
| 258 bool hasKeyPath = true; |
| 239 | 259 |
| 240 it->next(); | 260 it->next(); |
| 241 if (!it->isValid()) { | 261 if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, 2
)) { |
| 242 LOG_ERROR("Internal Indexed DB error."); | 262 LOG_ERROR("Internal Indexed DB error."); |
| 243 return; | 263 return; |
| 244 } | 264 } |
| 265 // FIXME: Add encode/decode functions for bools |
| 245 bool autoIncrement = *it->value().begin(); | 266 bool autoIncrement = *it->value().begin(); |
| 246 | 267 |
| 247 it->next(); // Is evicatble. | 268 it->next(); // Is evicatble. |
| 248 if (!it->isValid()) { | 269 if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, 3
)) { |
| 249 LOG_ERROR("Internal Indexed DB error."); | 270 LOG_ERROR("Internal Indexed DB error."); |
| 250 return; | 271 return; |
| 251 } | 272 } |
| 252 | 273 |
| 253 it->next(); // Last version. | 274 it->next(); // Last version. |
| 254 if (!it->isValid()) { | 275 if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, 4
)) { |
| 255 LOG_ERROR("Internal Indexed DB error."); | 276 LOG_ERROR("Internal Indexed DB error."); |
| 256 return; | 277 return; |
| 257 } | 278 } |
| 258 | 279 |
| 259 it->next(); // Maxium index id allocated. | 280 it->next(); // Maxium index id allocated. |
| 260 if (!it->isValid()) { | 281 if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, 5
)) { |
| 261 LOG_ERROR("Internal Indexed DB error."); | 282 LOG_ERROR("Internal Indexed DB error."); |
| 262 return; | 283 return; |
| 263 } | 284 } |
| 264 | 285 |
| 286 it->next(); // [optional] has key path (is not null) |
| 287 if (checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, 6)
) { |
| 288 // FIXME: Add encode/decode functions for bools |
| 289 hasKeyPath = *it->value().begin(); |
| 290 if (!hasKeyPath && !keyPath.isEmpty()) { |
| 291 LOG_ERROR("Internal Indexed DB error."); |
| 292 return; |
| 293 } |
| 294 it->next(); |
| 295 } |
| 296 |
| 265 foundIds.append(objectStoreId); | 297 foundIds.append(objectStoreId); |
| 266 foundNames.append(objectStoreName); | 298 foundNames.append(objectStoreName); |
| 267 foundKeyPaths.append(keyPath); | 299 foundKeyPaths.append(hasKeyPath ? keyPath : String()); |
| 268 foundAutoIncrementFlags.append(autoIncrement); | 300 foundAutoIncrementFlags.append(autoIncrement); |
| 269 } | 301 } |
| 270 } | 302 } |
| 271 | 303 |
| 272 static int64_t getNewObjectStoreId(LevelDBTransaction* transaction, int64_t data
baseId) | 304 static int64_t getNewObjectStoreId(LevelDBTransaction* transaction, int64_t data
baseId) |
| 273 { | 305 { |
| 274 int64_t maxObjectStoreId = -1; | 306 int64_t maxObjectStoreId = -1; |
| 275 const Vector<char> maxObjectStoreIdKey = DatabaseMetaDataKey::encode(databas
eId, DatabaseMetaDataKey::kMaxObjectStoreId); | 307 const Vector<char> maxObjectStoreIdKey = DatabaseMetaDataKey::encode(databas
eId, DatabaseMetaDataKey::kMaxObjectStoreId); |
| 276 if (!getInt(transaction, maxObjectStoreIdKey, maxObjectStoreId)) | 308 if (!getInt(transaction, maxObjectStoreIdKey, maxObjectStoreId)) |
| 277 maxObjectStoreId = 0; | 309 maxObjectStoreId = 0; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 291 int64_t objectStoreId = getNewObjectStoreId(m_currentTransaction.get(), data
baseId); | 323 int64_t objectStoreId = getNewObjectStoreId(m_currentTransaction.get(), data
baseId); |
| 292 if (objectStoreId < 0) | 324 if (objectStoreId < 0) |
| 293 return false; | 325 return false; |
| 294 | 326 |
| 295 const Vector<char> nameKey = ObjectStoreMetaDataKey::encode(databaseId, obje
ctStoreId, 0); | 327 const Vector<char> nameKey = ObjectStoreMetaDataKey::encode(databaseId, obje
ctStoreId, 0); |
| 296 const Vector<char> keyPathKey = ObjectStoreMetaDataKey::encode(databaseId, o
bjectStoreId, 1); | 328 const Vector<char> keyPathKey = ObjectStoreMetaDataKey::encode(databaseId, o
bjectStoreId, 1); |
| 297 const Vector<char> autoIncrementKey = ObjectStoreMetaDataKey::encode(databas
eId, objectStoreId, 2); | 329 const Vector<char> autoIncrementKey = ObjectStoreMetaDataKey::encode(databas
eId, objectStoreId, 2); |
| 298 const Vector<char> evictableKey = ObjectStoreMetaDataKey::encode(databaseId,
objectStoreId, 3); | 330 const Vector<char> evictableKey = ObjectStoreMetaDataKey::encode(databaseId,
objectStoreId, 3); |
| 299 const Vector<char> lastVersionKey = ObjectStoreMetaDataKey::encode(databaseI
d, objectStoreId, 4); | 331 const Vector<char> lastVersionKey = ObjectStoreMetaDataKey::encode(databaseI
d, objectStoreId, 4); |
| 300 const Vector<char> maxIndexIdKey = ObjectStoreMetaDataKey::encode(databaseId
, objectStoreId, 5); | 332 const Vector<char> maxIndexIdKey = ObjectStoreMetaDataKey::encode(databaseId
, objectStoreId, 5); |
| 333 const Vector<char> hasKeyPathKey = ObjectStoreMetaDataKey::encode(databaseI
d, objectStoreId, 6); |
| 301 const Vector<char> namesKey = ObjectStoreNamesKey::encode(databaseId, name); | 334 const Vector<char> namesKey = ObjectStoreNamesKey::encode(databaseId, name); |
| 302 | 335 |
| 303 bool ok = putString(m_currentTransaction.get(), nameKey, name); | 336 bool ok = putString(m_currentTransaction.get(), nameKey, name); |
| 304 if (!ok) { | 337 if (!ok) { |
| 305 LOG_ERROR("Internal Indexed DB error."); | 338 LOG_ERROR("Internal Indexed DB error."); |
| 306 return false; | 339 return false; |
| 307 } | 340 } |
| 308 | 341 |
| 309 ok = putString(m_currentTransaction.get(), keyPathKey, keyPath); | 342 ok = putString(m_currentTransaction.get(), keyPathKey, keyPath); |
| 310 if (!ok) { | 343 if (!ok) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 329 LOG_ERROR("Internal Indexed DB error."); | 362 LOG_ERROR("Internal Indexed DB error."); |
| 330 return false; | 363 return false; |
| 331 } | 364 } |
| 332 | 365 |
| 333 ok = putInt(m_currentTransaction.get(), maxIndexIdKey, kMinimumIndexId); | 366 ok = putInt(m_currentTransaction.get(), maxIndexIdKey, kMinimumIndexId); |
| 334 if (!ok) { | 367 if (!ok) { |
| 335 LOG_ERROR("Internal Indexed DB error."); | 368 LOG_ERROR("Internal Indexed DB error."); |
| 336 return false; | 369 return false; |
| 337 } | 370 } |
| 338 | 371 |
| 372 ok = putInt(m_currentTransaction.get(), hasKeyPathKey, !keyPath.isNull()); |
| 373 if (!ok) { |
| 374 LOG_ERROR("Internal Indexed DB error."); |
| 375 return false; |
| 376 } |
| 377 |
| 339 ok = putInt(m_currentTransaction.get(), namesKey, objectStoreId); | 378 ok = putInt(m_currentTransaction.get(), namesKey, objectStoreId); |
| 340 if (!ok) { | 379 if (!ok) { |
| 341 LOG_ERROR("Internal Indexed DB error."); | 380 LOG_ERROR("Internal Indexed DB error."); |
| 342 return false; | 381 return false; |
| 343 } | 382 } |
| 344 | 383 |
| 345 assignedObjectStoreId = objectStoreId; | 384 assignedObjectStoreId = objectStoreId; |
| 346 | 385 |
| 347 return true; | 386 return true; |
| 348 } | 387 } |
| 349 | 388 |
| 350 static bool deleteRange(LevelDBTransaction* transaction, const Vector<char>& beg
in, const Vector<char>& end) | 389 static bool deleteRange(LevelDBTransaction* transaction, const Vector<char>& beg
in, const Vector<char>& end) |
| 351 { | 390 { |
| 352 OwnPtr<LevelDBIterator> it = transaction->createIterator(); | 391 OwnPtr<LevelDBIterator> it = transaction->createIterator(); |
| 353 for (it->seek(begin); it->isValid() && compareKeys(it->key(), end) < 0; it->
next()) { | 392 for (it->seek(begin); it->isValid() && compareKeys(it->key(), end) < 0; it->
next()) { |
| 354 if (!transaction->remove(it->key())) | 393 if (!transaction->remove(it->key())) |
| 355 return false; | 394 return false; |
| 356 } | 395 } |
| 357 | 396 |
| 358 return true; | 397 return true; |
| 359 } | 398 } |
| 360 | 399 |
| 361 void IDBLevelDBBackingStore::deleteObjectStore(int64_t databaseId, int64_t objec
tStoreId) | 400 void IDBLevelDBBackingStore::deleteObjectStore(int64_t databaseId, int64_t objec
tStoreId) |
| 362 { | 401 { |
| 363 ASSERT(m_currentTransaction); | 402 ASSERT(m_currentTransaction); |
| 364 | 403 |
| 365 String objectStoreName; | 404 String objectStoreName; |
| 366 getString(m_currentTransaction.get(), ObjectStoreMetaDataKey::encode(databas
eId, objectStoreId, 0), objectStoreName); | 405 getString(m_currentTransaction.get(), ObjectStoreMetaDataKey::encode(databas
eId, objectStoreId, 0), objectStoreName); |
| 367 | 406 |
| 368 if (!deleteRange(m_currentTransaction.get(), ObjectStoreMetaDataKey::encode(
databaseId, objectStoreId, 0), ObjectStoreMetaDataKey::encode(databaseId, object
StoreId, 6))) | 407 if (!deleteRange(m_currentTransaction.get(), ObjectStoreMetaDataKey::encode(
databaseId, objectStoreId, 0), ObjectStoreMetaDataKey::encodeMaxKey(databaseId,
objectStoreId))) |
| 369 return; // FIXME: Report error. | 408 return; // FIXME: Report error. |
| 370 | 409 |
| 371 m_currentTransaction->remove(ObjectStoreNamesKey::encode(databaseId, objectS
toreName)); | 410 m_currentTransaction->remove(ObjectStoreNamesKey::encode(databaseId, objectS
toreName)); |
| 372 | 411 |
| 373 if (!deleteRange(m_currentTransaction.get(), IndexFreeListKey::encode(databa
seId, objectStoreId, 0), IndexFreeListKey::encodeMaxKey(databaseId, objectStoreI
d))) | 412 if (!deleteRange(m_currentTransaction.get(), IndexFreeListKey::encode(databa
seId, objectStoreId, 0), IndexFreeListKey::encodeMaxKey(databaseId, objectStoreI
d))) |
| 374 return; // FIXME: Report error. | 413 return; // FIXME: Report error. |
| 375 if (!deleteRange(m_currentTransaction.get(), IndexMetaDataKey::encode(databa
seId, objectStoreId, 0, 0), IndexMetaDataKey::encodeMaxKey(databaseId, objectSto
reId))) | 414 if (!deleteRange(m_currentTransaction.get(), IndexMetaDataKey::encode(databa
seId, objectStoreId, 0, 0), IndexMetaDataKey::encodeMaxKey(databaseId, objectSto
reId))) |
| 376 return; // FIXME: Report error. | 415 return; // FIXME: Report error. |
| 377 | 416 |
| 378 clearObjectStore(databaseId, objectStoreId); | 417 clearObjectStore(databaseId, objectStoreId); |
| (...skipping 926 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1305 // FIXME: this is checking for presence of the domain, not the database itse
lf | 1344 // FIXME: this is checking for presence of the domain, not the database itse
lf |
| 1306 return fileExists(path+"/CURRENT"); | 1345 return fileExists(path+"/CURRENT"); |
| 1307 } | 1346 } |
| 1308 | 1347 |
| 1309 // FIXME: deleteDatabase should be part of IDBBackingStore. | 1348 // FIXME: deleteDatabase should be part of IDBBackingStore. |
| 1310 | 1349 |
| 1311 } // namespace WebCore | 1350 } // namespace WebCore |
| 1312 | 1351 |
| 1313 #endif // ENABLE(LEVELDB) | 1352 #endif // ENABLE(LEVELDB) |
| 1314 #endif // ENABLE(INDEXED_DATABASE) | 1353 #endif // ENABLE(INDEXED_DATABASE) |
| OLD | NEW |