Skip to content

Commit 9056c16

Browse files
sapiersapier
sapier
authored and
sapier
committed
Fix sqlite3 map shutdown fails due to missing to finalize list statement
Add error output on fail to shutdown sqlite3 map db Implement shutdown of sqlite3 rollback db
1 parent d4245e6 commit 9056c16

File tree

2 files changed

+69
-28
lines changed

2 files changed

+69
-28
lines changed

src/database-sqlite3.cpp

+43-28
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2020
/*
2121
SQLite format specification:
2222
- Initially only replaces sectors/ and sectors2/
23-
23+
2424
If map.sqlite does not exist in the save dir
2525
or the block was not found in the database
2626
the map will try to load from sectors folder.
2727
In either case, map.sqlite will be created
2828
and all future saves will save there.
29-
29+
3030
Structure of map.sqlite:
3131
Tables:
3232
blocks
@@ -85,27 +85,27 @@ void Database_SQLite3::createDirs(std::string path)
8585
void Database_SQLite3::verifyDatabase() {
8686
if(m_database)
8787
return;
88-
88+
8989
{
9090
std::string dbp = m_savedir + DIR_DELIM + "map.sqlite";
9191
bool needs_create = false;
9292
int d;
93-
93+
9494
/*
9595
Open the database connection
9696
*/
97-
97+
9898
createDirs(m_savedir); // ?
99-
99+
100100
if(!fs::PathExists(dbp))
101101
needs_create = true;
102-
102+
103103
d = sqlite3_open_v2(dbp.c_str(), &m_database, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
104104
if(d != SQLITE_OK) {
105105
infostream<<"WARNING: SQLite3 database failed to open: "<<sqlite3_errmsg(m_database)<<std::endl;
106106
throw FileNotGoodException("Cannot open database file");
107107
}
108-
108+
109109
if(needs_create)
110110
createDatabase();
111111

@@ -123,19 +123,19 @@ void Database_SQLite3::verifyDatabase() {
123123
infostream<<"WARNING: SQLite3 database read statment failed to prepare: "<<sqlite3_errmsg(m_database)<<std::endl;
124124
throw FileNotGoodException("Cannot prepare read statement");
125125
}
126-
126+
127127
d = sqlite3_prepare(m_database, "REPLACE INTO `blocks` VALUES(?, ?)", -1, &m_database_write, NULL);
128128
if(d != SQLITE_OK) {
129129
infostream<<"WARNING: SQLite3 database write statment failed to prepare: "<<sqlite3_errmsg(m_database)<<std::endl;
130130
throw FileNotGoodException("Cannot prepare write statement");
131131
}
132-
132+
133133
d = sqlite3_prepare(m_database, "SELECT `pos` FROM `blocks`", -1, &m_database_list, NULL);
134134
if(d != SQLITE_OK) {
135135
infostream<<"WARNING: SQLite3 database list statment failed to prepare: "<<sqlite3_errmsg(m_database)<<std::endl;
136136
throw FileNotGoodException("Cannot prepare read statement");
137137
}
138-
138+
139139
infostream<<"ServerMap: SQLite3 database opened"<<std::endl;
140140
}
141141
}
@@ -158,8 +158,8 @@ void Database_SQLite3::saveBlock(MapBlock *block)
158158
u8 version = SER_FMT_VER_HIGHEST_WRITE;
159159
// Get destination
160160
v3s16 p3d = block->getPos();
161-
162-
161+
162+
163163
#if 0
164164
v2s16 p2d(p3d.X, p3d.Z);
165165
std::string sectordir = getSectorDir(p2d);
@@ -175,21 +175,21 @@ void Database_SQLite3::saveBlock(MapBlock *block)
175175
[0] u8 serialization version
176176
[1] data
177177
*/
178-
178+
179179
verifyDatabase();
180-
180+
181181
std::ostringstream o(std::ios_base::binary);
182-
182+
183183
o.write((char*)&version, 1);
184-
184+
185185
// Write basic data
186186
block->serialize(o, version, true);
187-
187+
188188
// Write block to database
189-
189+
190190
std::string tmp = o.str();
191191
const char *bytes = tmp.c_str();
192-
192+
193193
if(sqlite3_bind_int64(m_database_write, 1, getBlockAsInteger(p3d)) != SQLITE_OK)
194194
infostream<<"WARNING: Block position failed to bind: "<<sqlite3_errmsg(m_database)<<std::endl;
195195
if(sqlite3_bind_blob(m_database_write, 2, (void *)bytes, o.tellp(), NULL) != SQLITE_OK) // TODO this mught not be the right length
@@ -200,7 +200,7 @@ void Database_SQLite3::saveBlock(MapBlock *block)
200200
<<sqlite3_errmsg(m_database)<<std::endl;
201201
// Make ready for later reuse
202202
sqlite3_reset(m_database_write);
203-
203+
204204
// We just wrote it to the disk so clear modified flag
205205
block->resetModified();
206206
}
@@ -323,13 +323,13 @@ void Database_SQLite3::createDatabase()
323323
throw FileNotGoodException("Could not create sqlite3 database structure");
324324
else
325325
infostream<<"ServerMap: SQLite3 database structure was created";
326-
326+
327327
}
328328

329329
void Database_SQLite3::listAllLoadableBlocks(std::list<v3s16> &dst)
330330
{
331331
verifyDatabase();
332-
332+
333333
while(sqlite3_step(m_database_list) == SQLITE_ROW)
334334
{
335335
sqlite3_int64 block_i = sqlite3_column_int64(m_database_list, 0);
@@ -339,13 +339,28 @@ void Database_SQLite3::listAllLoadableBlocks(std::list<v3s16> &dst)
339339
}
340340
}
341341

342+
343+
#define FINALIZE_STATEMENT(statement) \
344+
if ( statement ) \
345+
rc = sqlite3_finalize(statement); \
346+
if ( rc != SQLITE_OK ) \
347+
errorstream << "Database_SQLite3::~Database_SQLite3():" \
348+
<< "Failed to finalize: " << #statement << ": rc=" << rc << std::endl;
349+
342350
Database_SQLite3::~Database_SQLite3()
343351
{
344-
if(m_database_read)
345-
sqlite3_finalize(m_database_read);
346-
if(m_database_write)
347-
sqlite3_finalize(m_database_write);
352+
int rc = SQLITE_OK;
353+
354+
FINALIZE_STATEMENT(m_database_read)
355+
FINALIZE_STATEMENT(m_database_write)
356+
FINALIZE_STATEMENT(m_database_list)
357+
348358
if(m_database)
349-
sqlite3_close(m_database);
359+
rc = sqlite3_close(m_database);
360+
361+
if (rc != SQLITE_OK) {
362+
errorstream << "Database_SQLite3::~Database_SQLite3(): "
363+
<< "Failed to close database: rc=" << rc << std::endl;
364+
}
350365
}
351366

src/rollback.cpp

+26
Original file line numberDiff line numberDiff line change
@@ -1091,10 +1091,36 @@ class RollbackManager: public IRollbackManager
10911091

10921092
SQL_databaseCheck();
10931093
}
1094+
#define FINALIZE_STATEMENT(statement) \
1095+
if ( statement ) \
1096+
rc = sqlite3_finalize(statement); \
1097+
if ( rc != SQLITE_OK ) \
1098+
errorstream << "RollbackManager::~RollbackManager():" \
1099+
<< "Failed to finalize: " << #statement << ": rc=" << rc << std::endl;
10941100

10951101
~RollbackManager() {
10961102
infostream << "RollbackManager::~RollbackManager()" << std::endl;
10971103
flush();
1104+
1105+
int rc = SQLITE_OK;
1106+
1107+
FINALIZE_STATEMENT(dbs_insert)
1108+
FINALIZE_STATEMENT(dbs_replace)
1109+
FINALIZE_STATEMENT(dbs_select)
1110+
FINALIZE_STATEMENT(dbs_select_range)
1111+
FINALIZE_STATEMENT(dbs_select_withActor)
1112+
FINALIZE_STATEMENT(dbs_knownActor_select)
1113+
FINALIZE_STATEMENT(dbs_knownActor_insert)
1114+
FINALIZE_STATEMENT(dbs_knownNode_select)
1115+
FINALIZE_STATEMENT(dbs_knownNode_insert)
1116+
1117+
if(dbh)
1118+
rc = sqlite3_close(dbh);
1119+
1120+
if (rc != SQLITE_OK) {
1121+
errorstream << "RollbackManager::~RollbackManager(): "
1122+
<< "Failed to close database: rc=" << rc << std::endl;
1123+
}
10981124
}
10991125

11001126
void addAction(const RollbackAction &action) {

0 commit comments

Comments
 (0)