Adam Ierymenko преди 10 години
родител
ревизия
cea3f28155
променени са 2 файла, в които са добавени 46 реда и са изтрити 11 реда
  1. 20 11
      netconf/SqliteNetworkConfigMaster.cpp
  2. 26 0
      selftest.cpp

+ 20 - 11
netconf/SqliteNetworkConfigMaster.cpp

@@ -66,27 +66,36 @@ SqliteNetworkConfigMaster::SqliteNetworkConfigMaster(const Identity &signingId,c
 		throw std::runtime_error("SqliteNetworkConfigMaster cannot open database file");
 	sqlite3_busy_timeout(_db,10000);
 
-	sqlite3_stmt *s = (sqlite3_stmt *)0;
-	if (sqlite3_prepare_v2(_db,"SELECT v FROM Config WHERE k = 'schemaVersion';",-1,&s,(const char **)0) != SQLITE_OK) {
-		sqlite3_close(_db);
-		throw std::runtime_error("SqliteNetworkConfigMaster cannot create prepared statement (library problem?)");
+	sqlite3_stmt *s;
+	for(int k=0;k<2;++k) {
+		s = (sqlite3_stmt *)0;
+		if ((sqlite3_prepare_v2(_db,"SELECT 'v' FROM Config WHERE 'k' = 'schemaVersion';",-1,&s,(const char **)0) != SQLITE_OK)||(!s)) {
+			if (sqlite3_exec(_db,ZT_NETCONF_SCHEMA_SQL"INSERT INTO Config (k,v) VALUES ('schemaVersion',"ZT_NETCONF_SQLITE_SCHEMA_VERSION_STR");",0,0,0) != SQLITE_OK) {
+				sqlite3_close(_db);
+				throw std::runtime_error("SqliteNetworkConfigMaster cannot initialize database and/or insert schemaVersion into Config table");
+			} else {
+				// Initialized database and set schema version, so we are done.
+				return;
+			}
+		} else break;
 	}
 	if (!s) {
 		sqlite3_close(_db);
-		throw std::runtime_error("SqliteNetworkConfigMaster cannot create prepared statement (library problem?)");
+		throw std::runtime_error("SqliteNetworkConfigMaster unable to create prepared statement or initialize database");
 	}
 
-	int schemaVersion = -1;
+	// If we made it here, database was opened and prepared statement was created
+	// to check schema version. Check and upgrade if needed.
+
+	int schemaVersion = -1234;
 	if (sqlite3_step(s) == SQLITE_ROW)
 		schemaVersion = sqlite3_column_int(s,0);
 
 	sqlite3_finalize(s);
 
-	if (schemaVersion == -1) {
-		if (sqlite3_exec(_db,ZT_NETCONF_SCHEMA_SQL"INSERT INTO Config (k,v) VALUES ('schemaVersion',"ZT_NETCONF_SQLITE_SCHEMA_VERSION_STR");",0,0,0) != SQLITE_OK) {
-			sqlite3_close(_db);
-			throw std::runtime_error("SqliteNetworkConfigMaster cannot initialize database and/or insert schemaVersion into Config table");
-		}
+	if (schemaVersion == -1234) {
+		sqlite3_close(_db);
+		throw std::runtime_error("SqliteNetworkConfigMaster schemaVersion not found in Config table (init failure?)");
 	} else if (schemaVersion != ZT_NETCONF_SQLITE_SCHEMA_VERSION) {
 		// Note -- this will eventually run auto-upgrades so this isn't how it'll work going forward
 		sqlite3_close(_db);

+ 26 - 0
selftest.cpp

@@ -55,6 +55,10 @@
 #include "node/Defaults.hpp"
 #include "node/Node.hpp"
 
+#ifdef ZT_ENABLE_NETCONF_MASTER
+#include "netconf/SqliteNetworkConfigMaster.hpp"
+#endif // ZT_ENABLE_NETCONF_MASTER
+
 #ifdef __WINDOWS__
 #include <tchar.h>
 #endif
@@ -636,6 +640,27 @@ static int testOther()
 	return 0;
 }
 
+static int testSqliteNetconfMaster()
+{
+#ifdef ZT_ENABLE_NETCONF_MASTER
+	try {
+		std::cout << "[netconf] Generating signing identity..." << std::endl;
+		Identity signingId;
+		signingId.generate();
+
+		std::cout << "[netconf] Creating database..." << std::endl;
+		SqliteNetworkConfigMaster netconf(signingId,"netconf-test.db");
+	} catch (std::runtime_error &exc) {
+		std::cout << "FAIL! (unexpected exception: " << exc.what() << ")" << std::endl;
+		return -1;
+	} catch ( ... ) {
+		std::cout << "FAIL! (unexpected exception: ...)" << std::endl;
+		return -1;
+	}
+#endif // ZT_ENABLE_NETCONF_MASTER
+	return 0;
+}
+
 #ifdef __WINDOWS__
 int _tmain(int argc, _TCHAR* argv[])
 #else
@@ -686,6 +711,7 @@ int main(int argc,char **argv)
 
 	srand((unsigned int)time(0));
 
+	r |= testSqliteNetconfMaster();
 	r |= testCrypto();
 	r |= testHttp();
 	r |= testPacket();