niedziela, 5 listopada 2017

C# - Komunikacja z baza danych SQLite

Ten post chciałbym poświęcić na opisanie sposobu komunikacji z bazą danych SQLite.

[Źródło: https://docs.microsoft.com/en-us/dotnet/]

Program:


Do tworzenia bazy danych wykorzystuje się bibliotekę System.Data.SQLite.


Jeśli ta opcja nie jest dostępna to należy doinstalować pakiet w Visual Studio.

W celu wykonania operacji przygotowałem program okienkowy. Okno główne programu wygląda następująco:


Po kliknięciu w przycisk Odczytaj dane z bazy danych następuje wyciągnięcie informacji z bazy oraz odblokowanie pozostałych funkcji:


Wyszukiwanie w bazie możliwe jest do zrealizowania na kilka sposobów. Jednym z nich jest podanie pełnej nazwy firmy w polu Nazwa firmy. Jeśli firma zostanie znaleziona to pozostałe pola tekstowe zostaną uzupełnione.


Pole zaznaczone na czerwono wyszukuje w polu gridView dane w czasie rzeczywistym. Domyślnie ustawione jest wyszukiwanie po literach od początku. Natomiast można to łatwo zmienić tak aby można było wyszukiwać fragment tekstu ze środka. Funkcje wyglądają następująco:

  1. private void serGridVTxtBox_TextChanged(object sender, EventArgs e)
  2. {
  3.     serTxtStWith();
  4. }
  5. private void serTxtStWith()
  6. {
  7.     (dbGridView.DataSource as DataTable).DefaultView.RowFilter = string.Format("Nazwa LIKE '{0}%'", serGridVTxtBox.Text);
  8. }
  9. private void serTxtContain()
  10. {
  11.     (dbGridView.DataSource as DataTable).DefaultView.RowFilter = string.Format("Nazwa LIKE '%{0}%'", serGridVTxtBox.Text);
  12. }

Wywołanie funkcji ustawiłem w zdarzeniu textChanged. Czyli za każdym razem jak zawartość pola tekstowego ulegnie zmianie to nastąpi wywołanie i przeszukanie pola DataGridView.

Po uruchomieniu dostępne są jedynie dwie opcje czyli otwarcie bazy danych bądź jej zamknięcie.
Stworzenie bazy danych wykonałem wcześniej. Do tego potrzebne są następujące komendy:

  1. private static SQLiteConnection m_dbConnection;
  2. private static SQLiteCommand command;
  3. private static SQLiteDataAdapter adapter;
  4. public static void createDataBase()
  5. {
  6.     dataBaseConn.createNewDatabase();
  7.     dataBaseConn.connectToDatabase(sqliteName);
  8.     dataBaseConn.createData();
  9. }
  10. private static void createNewDatabase(string nazwa)
  11. {
  12.     string name = nazwa + ".db";
  13.     SQLiteConnection.CreateFile(name);
  14. }
  15. private static void connectToDatabase(string nazwa)
  16. {
  17.     dataBaseConn.m_dbConnection = new SQLiteConnection("Data source=" + nazwa + "; Version=3");
  18.     dataBaseConn.m_dbConnection.Open();
  19. }
  20. private static void createTable()
  21. {
  22.     sql = "create table " + sqliteTabNam + " (Nazwa varchar(40), Telefon varchar(40), Adres varchar(70),
  23.                                                 KodPocztowy varchar(20), Produkt varchar(40), Koszty int)";
  24.     dataBaseConn.executeCommand(sql, m_dbConnection);
  25. }

Najpierw bazę należy stworzyć następnie się z nią połączyć po czym stworzyć tabelę z danymi. Opcja tworzenia bazy potrzebna będzie tylko przy pierwszym uruchomieniu. Dalej praca będzie przebiegała tylko na bazie istniejącej. 

Połączenie z bazą wykonuje się poprzez obiekt SQLiteConnection. Przechowuje on informacje o przygotowanym połączeniu czyli nazwę pliku z bazą danych wersje SQLite czy nazwę użytkownika i hasło do logowania. 

Po operacjach na bazie danych trzeba ją zamknąć. Wykonuje się to poprzez zamknięcie okna przez przycisk Zamknij Okno lub znaczek x. Bazę danych można też zamknąć przez przycisk Zamknij bazę danych. Każdy z nich wywołuje tą samą metodę zamykającą:

  1. private static void closeConnectionDB()
  2. {
  3.     dataBaseConn.m_dbConnection.Close();
  4. }

Wszystkie funkcje obsługujące komunikację z bazą danych zostały przygotowane w klasie dataBaseConn. Udostępnione funkcje publiczne służą jedynie do wywołania funkcji prywatnej w której zdefiniowane są parametry wykonujące bezpośrednio operacje na bazie.

Cała lista funkcji prywatnych jak i publicznych wygląda następująco:

  1. namespace sqliteDBCommu
  2. {
  3.     public class dataBaseConn
  4.     {
  5.         public enum products
  6.         {
  7.             prodNone = 0,
  8.             prodRelEn = 1,
  9.             prodPowersupEn = 2,
  10.             prodMicrocon = 3,
  11.             prodDiffe = 4
  12.         };
  13.         private static SQLiteConnection m_dbConnection;
  14.         private static SQLiteCommand command;
  15.         private static SQLiteDataAdapter adapter;
  16.         private static string sql = "";
  17.         private static string sqliteName = "MyDatabase";
  18.         private static string sqliteTabNam = "test";
  19.         private products prodData;
  20.         private static List<string> searchDBReadData = new List<string>{ };
  21.         //---------------------------------------------------------
  22.         public products currentProd
  23.         {
  24.             get { return prodData; }
  25.             set { prodData = value; }
  26.         }
  27.         public static string sqLiteName
  28.         {
  29.             get { return sqliteName; }
  30.             set { sqliteName = value; }
  31.         }
  32.         public static string sqLiteTabName
  33.         {
  34.             get { return sqliteTabNam; }
  35.             set { sqliteTabNam = value; }
  36.         }
  37.         public static List<string> searchDBReadData_Lis
  38.         {
  39.             get { return searchDBReadData;  }
  40.             private set { searchDBReadData = value; }
  41.         }
  42.         //---------------------------------------------------------
  43.         public static void openDataBase();
  44.         //---------------------------------------------------------
  45.         public static void createDataBase();
  46.         //---------------------------------------------------------
  47.         public static void closeDataBase();
  48.         //---------------------------------------------------------
  49.         public static void makeNewDataBase(string nazwa);
  50.         //---------------------------------------------------------
  51.         public static void makeNewDataBase();
  52.         //---------------------------------------------------------
  53.         public static void createData();
  54.         //---------------------------------------------------------
  55.         public static void writeDataToDatabase(string comName, string telepNum, string adres, string postalCode,
  56.                                                 products products, Int32 expense);
  57.         //---------------------------------------------------------
  58.         public static void updateDataInDataBase(string comName, string telepNum, string adres, string postalCode,
  59.                                                 products products, Int32 expense);
  60.         //---------------------------------------------------------
  61.         public static byte searchInDataBase(string comName);
  62.         //---------------------------------------------------------
  63.         public static string[] searchInDataBase2(string comName);
  64.         //---------------------------------------------------------
  65.         public static System.Data.DataTable searchInDB();
  66.         //---------------------------------------------------------
  67.         public static void delateRecord(string name);
  68.         //---------------------------------------------------------
  69.         public static dataBaseConn.products convertStrinIntoProd(string prodName);
  70.         //---------------------------------------------------------
  71.         //------------------ Private Functions ==================//
  72.         //---------------------------------------------------------
  73.         private static void createNewDatabase(string nazwa);
  74.         //---------------------------------------------------------
  75.         private static void createTable();
  76.         //---------------------------------------------------------
  77.         private static void connectToDatabase(string nazwa);
  78.         //---------------------------------------------------------
  79.         private static void passDataToTable(string comName, string telepNum, string adres, string postalCode, products products,
  80.                                                 Int32 expense);
  81.         //---------------------------------------------------------
  82.         private static void updateDataInTable(string comName, string telepNum, string adres, string postalCode, products products,
  83.                                                 Int32 expense);
  84.         //---------------------------------------------------------
  85.         private static string asignStrToProd(products products);
  86.         //---------------------------------------------------------
  87.         private static dataBaseConn.products asignProdToStr(string prodName);
  88.         //---------------------------------------------------------
  89.         private static void checkConnectionDB();
  90.         //---------------------------------------------------------
  91.         private static void closeConnectionDB();
  92.         //---------------------------------------------------------
  93.         private static void executeCommand(string sql, SQLiteConnection m_dbConnection);
  94.         //---------------------------------------------------------
  95.         private static byte searchInDB(string comName);
  96.         //---------------------------------------------------------
  97.         private static System.Data.DataTable searchInDataBase();
  98.     }
  99. }

Przesłanie komendy do bazy wykonuje się poprzez funkcji executeCommand. Jako argumenty przekazuje się samą komendą oraz informacje o połączeniu:

  1. private static void executeCommand(string sql, SQLiteConnection m_dbConnection)
  2. {
  3.     checkConnectionDB();
  4.     command = new SQLiteCommand(sql, m_dbConnection);
  5.     command.ExecuteNonQuery();
  6. }

Dodatkowo w programie zostały przygotowane dwa dodatkowe okna. Jedno z nich umożliwia dodawanie rekordu do bazy danych.


Na samym początku sprawdzane są pola tekstowe oraz combo Box z rodzajem produktu. Jeśli wszystkie zostały wypełnione wtedy sprawdzany jest format danych dla pola koszty. Został on ustawiony tak aby była możliwość wprowadzenia jedynie liczby. Jeśli wszystkie warunki są spełnione do wyświetli się pytanie czy dodawanie ma się odbyć jeśli tak to wywołana zostanie funkcja writeDataToDataBase.

  1. private static void passDataToTable(string comName, string telepNum, string adres,
  2.                                string postalCode, products products, Int32 expense)
  3. {
  4.     string expenseConvert = Convert.ToString(expense);
  5.     string productStr = asignStrToProd(products);
  6.    
  7.     string sql = "insert into " + sqliteTabNam + " (Nazwa, Telefon, Adres, KodPocztowy,
  8. Produkt, Koszty) values ('" + comName + "', '" + telepNum + "', '" + adres + "', '" postalCode + "', '" + productStr + "', " + expenseConvert + ")";
  9.     dataBaseConn.executeCommand(sql, m_dbConnection);
  10. }

Komenda w bardziej przejrzystej formie wygląda następująco:

insert into test (Nazwa, Telefon, Adres, KodPocztowy, Produkt, Koszty)  values ('WarNazwa', 'WarTelefon', 'WarAdres', 'WarProd', WarExpense)

Drugie natomiast służy do usuwania rekordu:


W celu usunięcia rekordu podaje się pełną nazwę firmy. Najpierw sprawdzane jest czy firma istnieje w bazie danych. Jeśli tak to zostaje ona usunięta z bazy.

  1. private void delateRecBtn_Click(object sender, EventArgs e)
  2. {
  3.     byte status = dataBaseConn.searchInDataBase(delateRecTxtBox.Text);
  4.    
  5.     if (status == 0)
  6.     {
  7.         MessageBox.Show("Nie znaleziono podanej firmy w bazie danych!""ERROR", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  8.     }
  9.     else if (status == 1)
  10.     {
  11.         /* Display msg to user with question */
  12.         if (MessageBox.Show("Znaleziono dane dla podanej firmy. Czy napewno chcesz ją usunąć z bazy danych?",
  13.              "Usuwanie danych", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
  14.         {
  15.             dataBaseConn.delateRecord(delateRecTxtBox.Text);
  16.         }
  17.         else
  18.         {
  19.             return;
  20.         }
  21.         MessageBox.Show("Firma usunięta z bazy danych!""Usuwanie danych", MessageBoxButtons.OK, MessageBoxIcon.Information);
  22.     }
  23.     else if (status > 1)
  24.     {
  25.         MessageBox.Show("Znaleziono wiecej pasujących rekordów, należy zweryfikować poprawność danych w bazie SQL!""ERROR",
  26.                                            MessageBoxButtons.OK, MessageBoxIcon.Warning);
  27.     }
  28. }

Usuwanie z bazy danych wykonuje funkcja:

  1. private static void delRecFromDB(string name)
  2. {
  3.     dataBaseConn.sql = "DELETE FROM " + sqliteTabNam + " WHERE Nazwa='" + name + "'";
  4.     dataBaseConn.executeCommand(dataBaseConn.sql, dataBaseConn.m_dbConnection);
  5. }

Komenda wysyłana wygląda następująco:

DELETE FROM test WHERE Nazwa='WarPolaName'

Pliki z projektem można znaleźć na dysku Google pod tym linkiem w zakładce C#.