Question

Sorry, If u filling bored. I have searched on several search engines but could not got any result. Anyway I am working in an App which database is mysql. Now I have created a database wrapper class and want to check if the connection is already opened. Could u help me?

             String^ constring = L"datasource=localhost;port=3306;username=root;password=pass;database=eps;";
             String^ my_query = L"select id from eps_users where usr = '" + this->user_name->Text + "' and psw = md5('" + this->pass_word->Text + "');";
             MySqlConnection^ conDatabase = gcnew MySqlConnection(constring);
             MySqlCommand^ cmd = gcnew MySqlCommand(my_query, conDatabase);
             MySqlDataReader^ myreader;
             try
             {
                 conDatabase->Open();
                 myreader = cmd->ExecuteReader();
                 int count = 0;
                 while (myreader->Read())
                 {
                     count = count + 1;

             }
             if (count == 1){
                 MessageBox::Show("Username And Password is correct.", "Success", MessageBoxButtons::OK,
                     MessageBoxIcon::Information);
                 this->Hide();
                 Form2^ f2 = gcnew Form2(constring);
                 f2->ShowDialog();
             }
             else{
                 MessageBox::Show("Username And Password is not correct.", "Error", MessageBoxButtons::OK,
                     MessageBoxIcon::Error);
                 // <del>
                 this->Hide();
                 Form2^ f2 = gcnew Form2(constring);
                 f2->ShowDialog();
                 // </del>
             }
         }
         catch (Exception^ ex)
         {
             MessageBox::Show(ex->Message);
         }
         conDatabase->Close();

I need to check if( conDatabase->HasBeenOpened()) { conDatabase->Open();}

Was it helpful?

Solution

The MySqlConnection type implements a feature called connection pooling that relies on the garbage collector to help recycle connections to your database, such that the best practice with regards to connection objects is to create a brand new object for most calls to the database, so that the garbage collector can correctly recycle the old ones. The process goes like this:

  1. Create a new connection
  2. Open the connection
  3. Use the connection for one query/transaction
  4. Dispose the connection

Where all four steps live within a single try/catch/finally block. (Also, the dispose step needs to happen inside the finally block!) Because you generally start with a brand new connection object, there's not typically a need to check if it's open first: you know it's closed. You also don't need to check the state after calling Open(): the method will block until it's finished, and throw an exception if it fails.

However, if you really are in one of the (rare!) situations where it's a good idea to preserve the connection for an extended period, you can check the state like this:

if( conDatabase->State == ConnectionState::Open)

Now, there is one other issue in that code I'd like to talk about. The issue comes down to this: what do you think will happen if I put the following into your username text box:

';DROP Table eps_users;--

If you think that it will try to execute that DROP statement in your database, you're right: it will! More subtle and damaging queries are possible, as well. This is a huge issue: there are bots that run full time crawling web sites looking for ways to abuse this, and even an corporate internal desktop apps will get caught from time to time. To fix this, you need to use Parameterized Queries for every instance where include user-provided data as part of your sql statement.

A quick example might look like this:

String^ my_query = L"select id from eps_users where usr = @userID;";
MySqlCommand^ cmd = gcnew MySqlCommand(my_query, conDatabase);
cmd->Parameters->AddWithValue(L"@userID", this->user_name->Text);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top