/// <summary> /// Performs actual dump. /// </summary> private void doDumpToFile(string tsvFileName) { SqliteConnection dumpConn = null; SqliteCommand cmdSelAll = null; try { // For the dump, we use a separate connection // This allows main connection to be safely accessed from other threads while dump is in progress bool dbExists; getOpenConn(out dumpConn, out dbExists); using (SqliteCommand cmdPragma = dumpConn.CreateCommand()) { // This pragma is a MUST to avoid locking the DB for the duration of the dump // Without it, concurrent store requests will time out. cmdPragma.CommandText = "PRAGMA read_uncommitted = 1;"; cmdPragma.ExecuteNonQuery(); } // Dumping is rare. No need to prepare and reuse this command. cmdSelAll = dumpConn.CreateCommand(); cmdSelAll.CommandText = sqlSelAll; cmdSelAll.Prepare(); // Write from reader, straight to output file. using (FileStream fs = new FileStream(tsvFileName, FileMode.Create, FileAccess.ReadWrite)) using (StreamWriter sw = new StreamWriter(fs)) using (var rdr = cmdSelAll.ExecuteReader()) { sw.WriteLine(StoredResult.GetTSVHeader()); while (rdr.Read()) { // uid, country, quiz_ix, survey_ix, score, res_enc, survey_enc int dateNum = (int)(rdr.GetInt64(0) / 1000000); int xDay = dateNum % 100; dateNum /= 100; int xMonth = dateNum % 100; dateNum /= 100; int xYear = dateNum; DateTime date = new DateTime(xYear, xMonth, xDay); StoredResult sr = new StoredResult(rdr.GetString(1), date, rdr.GetInt32(2), rdr.GetInt32(3), rdr.GetInt32(4), rdr.GetString(5), rdr.GetString(6)); sw.WriteLine(sr.GetTSV()); } } dumpConn.Close(); } finally { if (cmdSelAll != null) { cmdSelAll.Dispose(); } if (dumpConn != null) { dumpConn.Dispose(); } } }