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 |