@@ -73,6 +73,9 @@ class SQLiteBuildDB : public BuildDB {
7373 // / * 4: Pre-history
7474 static const int currentSchemaVersion = 8 ;
7575
76+ std::string path;
77+ uint32_t clientSchemaVersion;
78+
7679 sqlite3 *db = nullptr ;
7780
7881 // / The mutex to protect all access to the database and statements.
@@ -98,16 +101,10 @@ class SQLiteBuildDB : public BuildDB {
98101 return out;
99102 }
100103
101- public:
102- virtual ~SQLiteBuildDB () {
103- if (db)
104- close ();
105- }
106-
107- bool open (StringRef path, uint32_t clientSchemaVersion,
108- std::string *error_out) {
109- std::lock_guard<std::mutex> guard (dbMutex);
110- assert (!db);
104+ bool open (std::string *error_out) {
105+ // The db is opened lazily whenever an operation on it occurs. Thus if it is
106+ // already open, we don't need to do any further work.
107+ if (db) return true ;
111108
112109 // Configure SQLite3 on first use.
113110 //
@@ -124,7 +121,7 @@ class SQLiteBuildDB : public BuildDB {
124121 }
125122 }
126123
127- int result = sqlite3_open (path.str (). c_str (), &db);
124+ int result = sqlite3_open (path.c_str (), &db);
128125 if (result != SQLITE_OK) {
129126 *error_out = " unable to open database: " + std::string (
130127 sqlite3_errstr (result));
@@ -166,7 +163,7 @@ class SQLiteBuildDB : public BuildDB {
166163 sqlite3_close (db);
167164
168165 // Always recreate the database from scratch when the schema changes.
169- result = basic::sys::unlink (path.str (). c_str ());
166+ result = basic::sys::unlink (path.c_str ());
170167 if (result == -1 ) {
171168 if (errno != ENOENT) {
172169 *error_out = std::string (" unable to unlink existing database: " ) +
@@ -176,7 +173,7 @@ class SQLiteBuildDB : public BuildDB {
176173 }
177174 } else {
178175 // If the remove was successful, reopen the database.
179- int result = sqlite3_open (path.str (). c_str (), &db);
176+ int result = sqlite3_open (path.c_str (), &db);
180177 if (result != SQLITE_OK) {
181178 *error_out = getCurrentErrorMessage ();
182179 return false ;
@@ -285,22 +282,38 @@ class SQLiteBuildDB : public BuildDB {
285282 }
286283
287284 void close () {
288- std::lock_guard<std::mutex> guard (dbMutex);
289- assert (db);
285+ if (!db) return ;
290286
291287 // Destroy prepared statements.
292288 sqlite3_finalize (findKeyIDForKeyStmt);
289+ findKeyIDForKeyStmt = nullptr ;
293290 sqlite3_finalize (findKeyNameForKeyIDStmt);
291+ findKeyNameForKeyIDStmt = nullptr ;
294292 sqlite3_finalize (findRuleResultStmt);
293+ findRuleResultStmt = nullptr ;
295294 sqlite3_finalize (fastFindRuleResultStmt);
295+ fastFindRuleResultStmt = nullptr ;
296296 sqlite3_finalize (deleteFromKeysStmt);
297+ deleteFromKeysStmt = nullptr ;
297298 sqlite3_finalize (insertIntoKeysStmt);
299+ insertIntoKeysStmt = nullptr ;
298300 sqlite3_finalize (insertIntoRuleResultsStmt);
301+ insertIntoRuleResultsStmt = nullptr ;
299302
300303 sqlite3_close (db);
301304 db = nullptr ;
302305 }
303306
307+ public:
308+ SQLiteBuildDB (StringRef path, uint32_t clientSchemaVersion)
309+ : path(path), clientSchemaVersion(clientSchemaVersion) { }
310+
311+ virtual ~SQLiteBuildDB () {
312+ std::lock_guard<std::mutex> guard (dbMutex);
313+ if (db)
314+ close ();
315+ }
316+
304317 // / @name BuildDB API
305318 // / @{
306319
@@ -310,7 +323,11 @@ class SQLiteBuildDB : public BuildDB {
310323
311324 virtual uint64_t getCurrentIteration (bool * success_out, std::string *error_out) override {
312325 std::lock_guard<std::mutex> guard (dbMutex);
313- assert (db);
326+
327+ if (!open (error_out)) {
328+ *success_out = false ;
329+ return 0 ;
330+ }
314331
315332 // Fetch the iteration from the info table.
316333 sqlite3_stmt* stmt;
@@ -342,6 +359,11 @@ class SQLiteBuildDB : public BuildDB {
342359
343360 virtual bool setCurrentIteration (uint64_t value, std::string *error_out) override {
344361 std::lock_guard<std::mutex> guard (dbMutex);
362+
363+ if (!open (error_out)) {
364+ return false ;
365+ }
366+
345367 sqlite3_stmt* stmt;
346368 int result;
347369 result = sqlite3_prepare_v2 (
@@ -388,6 +410,10 @@ class SQLiteBuildDB : public BuildDB {
388410 std::lock_guard<std::mutex> guard (dbMutex);
389411 assert (result_out->builtAt == 0 );
390412
413+ if (!open (error_out)) {
414+ return false ;
415+ }
416+
391417 // Fetch the basic rule information.
392418 int result;
393419 int numDependencyBytes = 0 ;
@@ -523,6 +549,10 @@ class SQLiteBuildDB : public BuildDB {
523549 std::lock_guard<std::mutex> guard (dbMutex);
524550 int result;
525551
552+ if (!open (error_out)) {
553+ return false ;
554+ }
555+
526556 auto dbKeyID = getKeyID (keyID, error_out);
527557 if (!error_out->empty ()) {
528558 return false ;
@@ -582,6 +612,9 @@ class SQLiteBuildDB : public BuildDB {
582612 virtual bool buildStarted (std::string *error_out) override {
583613 std::lock_guard<std::mutex> guard (dbMutex);
584614
615+ if (!open (error_out))
616+ return false ;
617+
585618 // Execute the entire build inside a single transaction.
586619 //
587620 // FIXME: We should revist this, as we probably wouldn't want a crash in the
@@ -603,6 +636,10 @@ class SQLiteBuildDB : public BuildDB {
603636 int result = sqlite3_exec (db, " END;" , nullptr , nullptr , nullptr );
604637 assert (result == SQLITE_OK);
605638 (void )result;
639+
640+ // We close the connection whenever a build completes so that we release
641+ // any locks that we may have on the file.
642+ close ();
606643 }
607644
608645 // / @}
@@ -740,10 +777,7 @@ if (result != SQLITE_OK) { \
740777std::unique_ptr<BuildDB> core::createSQLiteBuildDB (StringRef path,
741778 uint32_t clientSchemaVersion,
742779 std::string* error_out) {
743- auto db = llvm::make_unique<SQLiteBuildDB>();
744- if (!db->open (path, clientSchemaVersion, error_out))
745- return nullptr ;
746-
780+ auto db = llvm::make_unique<SQLiteBuildDB>(path, clientSchemaVersion);
747781 return std::move (db);
748782}
749783
0 commit comments