| 1540 | } |
| 1541 | |
| 1542 | void SQLiteDB::createFromScratch() { |
| 1543 | int sqliteFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; |
| 1544 | checkError("open", sqlite3_open_v2(filename.c_str(), &db, sqliteFlags, nullptr)); |
| 1545 | |
| 1546 | Statement(*this, "PRAGMA page_size = 4096").nextRow(); // fast |
| 1547 | btree = db->aDb[0].pBt; |
| 1548 | initPagerCodec(); |
| 1549 | |
| 1550 | Statement(*this, "PRAGMA auto_vacuum = 2").nextRow(); // slow all the time |
| 1551 | Statement(*this, "PRAGMA journal_mode = WAL").nextRow(); // sometimes slow |
| 1552 | sqlite3_extended_result_codes(db, 1); |
| 1553 | |
| 1554 | sqlite3_mutex_enter(db->mutex); |
| 1555 | haveMutex = true; |
| 1556 | |
| 1557 | beginTransaction(true); |
| 1558 | u32 pgnoRoot = -1; |
| 1559 | sqlite3BtreeGetMeta(btree, BTREE_LARGEST_ROOT_PAGE, &pgnoRoot); |
| 1560 | |
| 1561 | // We expect our tables are #3, #4 (since autovacuum is enabled, there is a pointer map page at #2) |
| 1562 | if (pgnoRoot == 4) { |
| 1563 | table = pgnoRoot - 1; |
| 1564 | freetable = pgnoRoot; |
| 1565 | rollback(); |
| 1566 | } else if (pgnoRoot == 1) { |
| 1567 | // The database is empty; create tables |
| 1568 | checkError("BtreeCreateTable", sqlite3BtreeCreateTable(btree, &table, BTREE_BLOBKEY)); |
| 1569 | ASSERT(table == 3); |
| 1570 | checkError("BtreeCreateTable2", sqlite3BtreeCreateTable(btree, &freetable, BTREE_INTKEY)); |
| 1571 | ASSERT(freetable == table + 1); |
| 1572 | endTransaction(); |
| 1573 | } else { |
| 1574 | TraceEvent("PgnoRoot").detail("Value", pgnoRoot); |
| 1575 | checkError("CheckTables", SQLITE_CORRUPT); |
| 1576 | } |
| 1577 | } |
| 1578 | |
| 1579 | struct ThreadSafeCounter { |
| 1580 | volatile int64_t counter; |
no test coverage detected