@@ -20,13 +20,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
20
20
/*
21
21
SQLite format specification:
22
22
- Initially only replaces sectors/ and sectors2/
23
-
23
+
24
24
If map.sqlite does not exist in the save dir
25
25
or the block was not found in the database
26
26
the map will try to load from sectors folder.
27
27
In either case, map.sqlite will be created
28
28
and all future saves will save there.
29
-
29
+
30
30
Structure of map.sqlite:
31
31
Tables:
32
32
blocks
@@ -85,27 +85,27 @@ void Database_SQLite3::createDirs(std::string path)
85
85
void Database_SQLite3::verifyDatabase () {
86
86
if (m_database)
87
87
return ;
88
-
88
+
89
89
{
90
90
std::string dbp = m_savedir + DIR_DELIM + " map.sqlite" ;
91
91
bool needs_create = false ;
92
92
int d;
93
-
93
+
94
94
/*
95
95
Open the database connection
96
96
*/
97
-
97
+
98
98
createDirs (m_savedir); // ?
99
-
99
+
100
100
if (!fs::PathExists (dbp))
101
101
needs_create = true ;
102
-
102
+
103
103
d = sqlite3_open_v2 (dbp.c_str (), &m_database, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL );
104
104
if (d != SQLITE_OK) {
105
105
infostream<<" WARNING: SQLite3 database failed to open: " <<sqlite3_errmsg (m_database)<<std::endl;
106
106
throw FileNotGoodException (" Cannot open database file" );
107
107
}
108
-
108
+
109
109
if (needs_create)
110
110
createDatabase ();
111
111
@@ -123,19 +123,19 @@ void Database_SQLite3::verifyDatabase() {
123
123
infostream<<" WARNING: SQLite3 database read statment failed to prepare: " <<sqlite3_errmsg (m_database)<<std::endl;
124
124
throw FileNotGoodException (" Cannot prepare read statement" );
125
125
}
126
-
126
+
127
127
d = sqlite3_prepare (m_database, " REPLACE INTO `blocks` VALUES(?, ?)" , -1 , &m_database_write, NULL );
128
128
if (d != SQLITE_OK) {
129
129
infostream<<" WARNING: SQLite3 database write statment failed to prepare: " <<sqlite3_errmsg (m_database)<<std::endl;
130
130
throw FileNotGoodException (" Cannot prepare write statement" );
131
131
}
132
-
132
+
133
133
d = sqlite3_prepare (m_database, " SELECT `pos` FROM `blocks`" , -1 , &m_database_list, NULL );
134
134
if (d != SQLITE_OK) {
135
135
infostream<<" WARNING: SQLite3 database list statment failed to prepare: " <<sqlite3_errmsg (m_database)<<std::endl;
136
136
throw FileNotGoodException (" Cannot prepare read statement" );
137
137
}
138
-
138
+
139
139
infostream<<" ServerMap: SQLite3 database opened" <<std::endl;
140
140
}
141
141
}
@@ -158,8 +158,8 @@ void Database_SQLite3::saveBlock(MapBlock *block)
158
158
u8 version = SER_FMT_VER_HIGHEST_WRITE;
159
159
// Get destination
160
160
v3s16 p3d = block->getPos ();
161
-
162
-
161
+
162
+
163
163
#if 0
164
164
v2s16 p2d(p3d.X, p3d.Z);
165
165
std::string sectordir = getSectorDir(p2d);
@@ -175,21 +175,21 @@ void Database_SQLite3::saveBlock(MapBlock *block)
175
175
[0] u8 serialization version
176
176
[1] data
177
177
*/
178
-
178
+
179
179
verifyDatabase ();
180
-
180
+
181
181
std::ostringstream o (std::ios_base::binary);
182
-
182
+
183
183
o.write ((char *)&version, 1 );
184
-
184
+
185
185
// Write basic data
186
186
block->serialize (o, version, true );
187
-
187
+
188
188
// Write block to database
189
-
189
+
190
190
std::string tmp = o.str ();
191
191
const char *bytes = tmp.c_str ();
192
-
192
+
193
193
if (sqlite3_bind_int64 (m_database_write, 1 , getBlockAsInteger (p3d)) != SQLITE_OK)
194
194
infostream<<" WARNING: Block position failed to bind: " <<sqlite3_errmsg (m_database)<<std::endl;
195
195
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)
200
200
<<sqlite3_errmsg (m_database)<<std::endl;
201
201
// Make ready for later reuse
202
202
sqlite3_reset (m_database_write);
203
-
203
+
204
204
// We just wrote it to the disk so clear modified flag
205
205
block->resetModified ();
206
206
}
@@ -323,13 +323,13 @@ void Database_SQLite3::createDatabase()
323
323
throw FileNotGoodException (" Could not create sqlite3 database structure" );
324
324
else
325
325
infostream<<" ServerMap: SQLite3 database structure was created" ;
326
-
326
+
327
327
}
328
328
329
329
void Database_SQLite3::listAllLoadableBlocks (std::list<v3s16> &dst)
330
330
{
331
331
verifyDatabase ();
332
-
332
+
333
333
while (sqlite3_step (m_database_list) == SQLITE_ROW)
334
334
{
335
335
sqlite3_int64 block_i = sqlite3_column_int64 (m_database_list, 0 );
@@ -339,13 +339,28 @@ void Database_SQLite3::listAllLoadableBlocks(std::list<v3s16> &dst)
339
339
}
340
340
}
341
341
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
+
342
350
Database_SQLite3::~Database_SQLite3 ()
343
351
{
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
+
348
358
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
+ }
350
365
}
351
366
0 commit comments