-1

I am using An XAMPP locally hosted MySQL server with my login database on. I am trying to compare the entries in the database to the inputs of the TextBoxes in the vb program. However, upon clicking the button the program freezes.

Imports MySql.Data.MySqlClient
Public Class Login
    Private Sub Login_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        'TODO: This line of code loads data into the 'Parts.User' table. You can move, or remove it, as needed.
        'Me.UserTableAdapter.Fill(Me.Parts.User)

    End Sub
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        If TextBox1.Text = "" Or TextBox2.Text = "" Then
            MsgBox("Oops ¯\_(ツ)_/¯ " + Err.Description(), MsgBoxStyle.OkOnly, "Enter Value")
        Else
            Try
                Dim connectionString = "server=localhost; userid=root; password=; database=partstest1; CharSet=utf8;"
                Dim connDB = New MySqlConnection(connectionString)
                Try
                    connDB.Open()
                    Dim objCmd = New MySqlCommand
                    objCmd.Connection = connDB
                    objCmd.CommandText = "SELECT ID, Username, Password FROM `user` WHERE `Username` = '" + TextBox1.Text + "' and `Password` = '" + TextBox2.Text + "';"
                    objCmd.CommandType = CommandType.Text
                    Dim objAdpt = New MySqlDataAdapter
                    Dim objDS = New DataSet
                    objAdpt.SelectCommand = objCmd
                    objAdpt.Fill(objDS)
                    Console.WriteLine(objDS)
                    If TextBox1.Text = "admin" Then
                        'If Access_Level = 0 Then
                        Me.Hide()
                        AdminMainMenu.Show()
                    Else
                        Me.Hide()
                        MainMenu.Show()
                    End If
                Catch
                    MsgBox("Oops " + Err.Description(), MsgBoxStyle.OkOnly, "Failed to Open")
                    MsgBox("Incorrect login details", MsgBoxStyle.OkOnly)

                End Try
            Catch ex As System.Exception
                System.Windows.Forms.MessageBox.Show(ex.Message)
            End Try
        End If
        TextBox1.Clear()
        TextBox2.Clear()
    End Sub
End Class

I tried putting the TextBox.Text equal to a different variable but it had not made a difference. Is my command too complex or have I formatted it wrong maybe? I am pretty new to SQL so any help would be appreciated.

djv
  • 15,168
  • 7
  • 48
  • 72
Arc_G
  • 5
  • 4
  • **never** store passwords as text in your database only hashed ones – nbk Mar 06 '20 at 18:23
  • Oh they are hashed, i am trying an unhashed one to begin with as there are less things for me to mess up. I am using SHA256 for the hash – Arc_G Mar 06 '20 at 18:27
  • I also reduced it to simple words to see if it would make a difference to the compute time – Arc_G Mar 06 '20 at 18:40
  • Also, don't do this database stuff on your UI thread. Use `Async / Await` to offload it. This will make your program not freeze, but it won't necessarily help with the timeout. – djv Mar 06 '20 at 18:55
  • I'm sorry i don't quite understand also thanks for editing my question :) – Arc_G Mar 06 '20 at 18:58

1 Answers1

0

This will perform the database operations off the UI, and moves the UI elements out of the database operations. It uses Async / Await

Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    If TextBox1.Text = "" Or TextBox2.Text = "" Then
        MsgBox("Oops ¯\_(ツ)_/¯ " + Err.Description(), MsgBoxStyle.OkOnly, "Enter Value")
    Else
        Try
            Await getDataSet(TextBox1.Text, TextBox2.Text)
        Catch ex As Exception
            'MsgBox("Oops " + Err.Description(), MsgBoxStyle.OkOnly, "Failed to Open")
            'MsgBox("Incorrect login details", MsgBoxStyle.OkOnly)
            System.Windows.Forms.MessageBox.Show(ex.Message)
        End Try
        If TextBox1.Text = "admin" Then
            'If Access_Level = 0 Then
            Me.Hide()
            AdminMainMenu.Show()
        Else
            Me.Hide()
            MainMenu.Show()
        End If
    End If
    TextBox1.Clear()
    TextBox2.Clear()
End Sub

Async Function getDataSet(username As String, password As String) As Task(Of DataSet)
    Return Await Task.Factory.StartNew(
        Function()
            Dim connectionString = "server=localhost; userid=root; password=; database=partstest1; CharSet=utf8;"
            Dim commandText = "SELECT ID, Username, Password FROM `user` WHERE `Username` = '" & username & "' and `Password` = '" & password & "';"
            Using connDB = New MySqlConnection(connectionString), objCmd = New MySqlCommand(), objAdpt = New MySqlDataAdapter()
                connDB.Open()
                objCmd.Connection = connDB
                objCmd.CommandText = commandText 
                objCmd.CommandType = CommandType.Text
                objAdpt.SelectCommand = objCmd
                Dim objDs = New DataSet()
                objAdpt.Fill(objDs)
                Console.WriteLine(objDs)
                Return objDs
            End Using
        End Function)
End Function

I'm not going to address your potential SQL Injection issue. But you can educate yourself if you want to.

If your database connection is timing out then you need to fix your connection string, I guess. I don't think anyone can help you with that without being on site.

This answer will help your application not freeze.

Your application is suffering from not following Separation of Concerns. By not doing so, your long-running tasks are being performed on the UI. The Async / Await here is a way to offload some of the database processing. But you should also understand that zero non-UI processing should be performed on the UI. Keep that in mind and find ways to comply (Async / Await, BackgroundWorker, System.Threading.Thread)

djv
  • 15,168
  • 7
  • 48
  • 72
  • It has definitely stopped the long wait times. It now highlights `objAdpt.Fill(objDs)` says i have a problem with my sql syntax, I just went onto phpmyadmin and checked the query it works on there. Thanks for explaining what async and await do it makes a lot of sense now. – Arc_G Mar 06 '20 at 21:10
  • @Arc_G I also put your disposable objects into `Using` blocks so they are automatically disposed when you are done with them. This is good practice. As for the query, break the code on the line `Using connDB = New ...` and check the value of `commandText`. Does it make sense? – djv Mar 06 '20 at 21:20
  • Yeah i have used using before so like `Using connection as New MySql connection("connectionstring") ... End Using` like that and ill check the command text value now – Arc_G Mar 06 '20 at 21:23
  • I removed the other places in which it had worked before i may have had a global variable getting in the way. – Arc_G Mar 06 '20 at 21:30
  • So maybe it was some other issue? At least this code should help your app be more responsive – djv Mar 06 '20 at 21:35