Alexander Grigoryev
Alexander Grigoryev

Reputation: 109

Mono + SQLite. Unable to open database

I have a DBHandler class with constructor and method, that updates SQLite database or inserts a new record into it:

public class DBHandler
    {
        private string dbName;
        private string tableName = "table1";
        private string dbPath;

        public DBHandler (string _dbName)
        {
            dbName = _dbName;
            dbPath = Path.Combine(Directory.GetCurrentDirectory (), dbName);

            bool exists = File.Exists (dbPath);
            if (!exists) {
                Mono.Data.Sqlite.SqliteConnection.CreateFile (dbPath);
                string createQuery = "CREATE TABLE " + tableName +
                                     "(" +
                                     "word1," +
                                     "word2," +
                                     "n INT INTEGER DEFAULT 1," +
                                     "PRIMARY KEY (word1, word2)" +
                                     ");";

                using (SqliteConnection connection = new SqliteConnection (String.Format ("Data Source={0};", dbPath))) {   
                    connection.Open ();
                    using (var c = connection.CreateCommand ()) {
                        c.CommandText = createQuery;
                        c.ExecuteNonQuery ();
                    }
                }
            }
        }

        public void InputToDb (WordPair pair)
        {
            string word1 = pair.word1;
            string word2 = pair.word2;
            int n = pair.n;
            int newN = 1;

            using (SqliteConnection connection = new SqliteConnection (String.Format ("Data Source={0};", dbPath))) {
                connection.Open ();

                using (var c1 = connection.CreateCommand ()) { 
                    c1.CommandText = "SELECT n from " + tableName + " WHERE word1 = '" + word1 + "' AND word2 = '" + word2 + "';";
                    var r = c1.ExecuteReader ();
                    r.Read ();
                    if (!r.HasRows)
                        newN = 1;
                    else
                        newN = int.Parse (r ["n"].ToString ()) + 1;
                } 
            }

            using (SqliteConnection connection = new SqliteConnection (String.Format ("Data Source={0};", dbPath))) {
                connection.Open ();
                using (var c2 = connection.CreateCommand ()) { 
                    string inputQuery = "INSERT OR REPLACE INTO " + tableName + " (word1, word2, n) " +
                                        "VALUES ('" + word1 + "', " +
                                        "'" + word2 + "', " +
                                        newN.ToString () +
                                        ");";
                    c2.CommandText = inputQuery;
                    c2.ExecuteNonQuery ();
                }
            }
        }
}  

This is class is used as follows:

DBHandler dbh = new DBHandler ("database6.db3");
 for (int i = 0; i < buffer.Count-1; i++) {
    WordPair tempPair = new WordPair (buffer.Dequeue(), buffer.Peek(), 1);
    dbh.InputToDb (tempPair);
 }

(buffer is just a queue of strings)

This always works fine for few iterations (usually 8-10) and then crushes with "Unable to open database" exception in string c2.ExecuteNonQuery (); in InputToDb(...) method. It looks like something (connection or command) wasn't disposed correctly after previous using, but I have no idea where's a problem.

Upvotes: 0

Views: 514

Answers (1)

Alexander Grigoryev
Alexander Grigoryev

Reputation: 109

The problem was the following:

should use this

using (var r = c1.ExecuteReader ()) {
    r.Read ();
    ...
}

instead of just this

var r = c1.ExecuteReader ());
r.Read ();
...

Wish you not to become a victim of simplified tutorials.

Upvotes: 1

Related Questions