Найти тему

SQLite — быстрый старт

Оглавление

В этой статье мы напишем простую программу с использованием библиотеки SQLite. Программа создаст базу данных, запишет туда информацию, а потом выведет эту информацию на экран.

1. Создание нового проекта

Для работы с таблицей мы будем виджеты GTK+, поэтому запустите CodeBlocks и выполните «Файл — Создать — Проект — GTK+ project». Готовый проект вы можете скачать в конце этой статьи.

Установите параметры проекта. Меню «Проект — Свойства — Цели сборки». Поставьте выделенные параметры.

-2

Запустите приложение для проверки.

-3

Библиотека GTK+ работает. Теперь убедитесь, что библиотека SQLite подключена к CodeBlocks.

2. Подключение GtkListStore для вывода таблицы

В GTK+ для работы со сложными данными используется GtkTreeModel — набор функций для хранения и отображения данных.
Существует две модели хранения GtkListStore и GtkTreeStore и один виджет отображения GtkTreeView, который поддерживает обе модели хранения.

-4

Для работы с таблицами нужно сделать запрос к БД и поместить результат в структуру GtkListStore. Виджет GtkTreeView отобразит данные в виде таблицы.

-5

Для работы с таблицей в GTK+ нужно:

  • Создать буфер GtkListStore.
  • Добавить строки в буфер.
  • Создать таблицу GtkTreeView.
  • Добавить столбцы в таблицу.

Для обращения к таблице используется:

  • Итератор GtkTreeIter — текущая строка.
  • Колонка GtkTreeViewColumn — текущий столбец.
  • Рендер GtkCellRenderer — текущая ячейка.

Запускаем Glade и готовим виджет, для этого.

  • Создаем буфер liststore1 для модели таблицы,
  • Создаем виджет дерева treeview1.
  • Указываем для этого виджета буфер liststore1.
-6

Сохраняем интерфейс в файл main.glade. Виджет готов, теперь его надо настроить: указать столбцы и формат ячеек.

3. Настройка виджета GtkTreeView в Glade

У нас сейчас пустое окно, в котором есть дерево treeview1 и буфер liststore1. Нажимаем на иконку Edit.

-7

В редакторе виджета «Дерево» столбцы настраиваются на вкладке “Основные”, а ячейки — на вкладке “Иерархия”. Сначала добавим три столбца:

  • guint1
  • gcharray1
  • guin2
-8

Теперь настроим ячейки:

  • Номер
  • Фамилия
  • Оклад
-9

Всё, интерфейс готов. Теперь можно писать обращение к базе данных.

4. Создание базы данных SQLite

Для подключения к БД SQLite используется команда sqlite3_open(«b1.db», &db). В этой строчке открывается база данных b1.db, если ее нет, то она создается.

В качестве примера возьмем таблицу «Сотрудники», в которой зададим поля:

  • N
  • Фамилия
  • Оклад

Теперь составляем SQL-запрос, в котором создаем таблицу «Сотрудники» и задаем значения полей. Начинается запрос с удаления таблицы «Сотрудники», если она есть. Это для того, чтобы мы могли запускать программу несколько раз.

В этой статье мы напишем простую программу с использованием библиотеки SQLite. Программа создаст базу данных, запишет туда информацию, а потом выведет эту информацию на экран.

Содержание

1. Создание нового проекта

Для работы с таблицей мы будем виджеты GTK+, поэтому запустите CodeBlocks и выполните «Файл — Создать — Проект — GTK+ project». Готовый проект вы можете скачать в конце этой статьи.

-10

Установите параметры проекта. Меню «Проект — Свойства — Цели сборки». Поставьте выделенные параметры.

-11

Запустите приложение для проверки.

-12

Библиотека GTK+ работает. Теперь убедитесь, что библиотека SQLite подключена к CodeBlocks. Об этом подробно написано здесь.

2. Подключение GtkListStore для вывода таблицы

В GTK+ для работы со сложными данными используется GtkTreeModel — набор функций для хранения и отображения данных.
Существует две модели хранения GtkListStore и GtkTreeStore и один виджет отображения GtkTreeView, который поддерживает обе модели хранения.

-13

Для работы с таблицами нужно сделать запрос к БД и поместить результат в структуру GtkListStore. Виджет GtkTreeView отобразит данные в виде таблицы.

-14

Для работы с таблицей в GTK+ нужно:

  • Создать буфер GtkListStore.
  • Добавить строки в буфер.
  • Создать таблицу GtkTreeView.
  • Добавить столбцы в таблицу.

Для обращения к таблице используется:

  • Итератор GtkTreeIter — текущая строка.
  • Колонка GtkTreeViewColumn — текущий столбец.
  • Рендер GtkCellRenderer — текущая ячейка.

Запускаем Glade и готовим виджет, для этого.

  • Создаем буфер liststore1 для модели таблицы,
  • Создаем виджет дерева treeview1.
  • Указываем для этого виджета буфер liststore1.
-15

Сохраняем интерфейс в файл main.glade. Виджет готов, теперь его надо настроить: указать столбцы и формат ячеек.

3. Настройка виджета GtkTreeView в Glade

У нас сейчас пустое окно, в котором есть дерево treeview1 и буфер liststore1. Нажимаем на иконку Edit.

-16

В редакторе виджета «Дерево» столбцы настраиваются на вкладке “Основные”, а ячейки — на вкладке “Иерархия”. Сначала добавим три столбца:

  • guint1
  • gcharray1
  • guin2
-17

Теперь настроим ячейки:

  • Номер
  • Фамилия
  • Оклад
-18

Всё, интерфейс готов. Теперь можно писать обращение к базе данных.

4. Создание базы данных SQLite

Для подключения к БД SQLite используется команда sqlite3_open(«b1.db», &db). В этой строчке открывается база данных b1.db, если ее нет, то она создается.

В качестве примера возьмем таблицу «Сотрудники», в которой зададим поля:

  • N
  • Фамилия
  • Оклад

Теперь составляем SQL-запрос, в котором создаем таблицу «Сотрудники» и задаем значения полей. Начинается запрос с удаления таблицы «Сотрудники», если она есть. Это для того, чтобы мы могли запускать программу несколько раз.

// Запись в БД

int SaveDB()

{

char* SQL1 = "DROP TABLE IF EXISTS Сотрудники; \

CREATE TABLE Сотрудники(N,Фамилия,Оклад); \

INSERT INTO Сотрудники VALUES(1,'Иванов',20000); \

INSERT INTO Сотрудники VALUES(2,'Петров',25000); \

INSERT INTO Сотрудники VALUES(3,'Сидоров',30000); \

";

if (sqlite3_exec(db, SQL1, 0, 0, &err))

{

sprintf(str, "Ошибка выполнения SQL-запроса: %sn", err);

sqlite3_free(err);

return 2;

}

return 0;

}

5. Загрузка данных в буфер виджета GtkTreeView

Когда мы подключились к баз данных, мы можем загрузить строки БД в буфер виджета GtkTreeView. Сам буфер мы задаем строчкой:

GtkListStore *buffer; // Буфер таблицы

Загрузку данных выполняет следующий код:

// Цикл по SQL-запросу и запись в буфер таблицы

while((rc = sqlite3_step(stmt)) == SQLITE_ROW)

{

gtk_list_store_append (buffer, &iter);

gtk_list_store_set (buffer, &iter,

C_NUM, sqlite3_column_int(stmt, C_NUM),

C_NAME, sqlite3_column_text(stmt, C_NAME),

C_OKLAD, (guint) sqlite3_column_int(stmt, C_OKLAD),

-1);

}

Здесь мы в цикле перебираем строки запроса и заполняем ячейки таблицы значениями полей из базы данных.

6. Итоговая программа

Остальные шаги по выводу таблицы на экран достаточно стандартны. Подключаем интерфейс main.glade и выводим на экран основное окно. Вот код целиком.

В результате мы получаем вывод таблицы из базы данных на экран.

-19

С помощью SQLite Studio можно подключиться к этой БД и увидеть, что все данные отражаются правильно.

-20

Полностью проект можно скачать здесь

5. Загрузка данных в буфер виджета GtkTreeView

Когда мы подключились к баз данных, мы можем загрузить строки БД в буфер виджета GtkTreeView. Сам буфер мы задаем строчкой:

1GtkListStore *buffer; // Буфер таблицы

Загрузку данных выполняет следующий код:

12345678910 // Цикл по SQL-запросу и запись в буфер таблицы while((rc = sqlite3_step(stmt)) == SQLITE_ROW) { gtk_list_store_append (buffer, &iter); gtk_list_store_set (buffer, &iter, C_NUM, sqlite3_column_int(stmt, C_NUM), C_NAME, sqlite3_column_text(stmt, C_NAME), C_OKLAD, (guint) sqlite3_column_int(stmt, C_OKLAD), -1); }

Здесь мы в цикле перебираем строки запроса и заполняем ячейки таблицы значениями полей из базы данных.

6. Итоговая программа

Остальные шаги по выводу таблицы на экран достаточно стандартны. Подключаем интерфейс main.glade и выводим на экран основное окно. Вот код целиком.

/****************************************

Пример использования SQLite и GtkTreeView

*****************************************/

# include <stdlib.h>

# include <gtk/gtk.h>

# include <sqlite3.h>

GtkWidget *window1;

GtkBuilder *builder1;

sqlite3 *db; // хэндл БД

// Структуры данных для виджета

GtkListStore *buffer; // Буфер таблицы

GtkTreeView *table; // Таблица

GtkTreeViewColumn *column; // Отображаемая колонка

GtkTreeIter iter; // Итератор таблицы (текущая строка)

GtkCellRenderer *renderer; // Рендер таблицы (текущая ячейка)

// Обозначения полей

enum

{

C_NUM, C_NAME, C_OKLAD

};

// Структуры данных для базы данных

sqlite3_stmt* stmt; // строка запроса к БД

char *err = 0;

int rc = 0;

int ShowGladeError()

{

GtkWidget *dialog;

dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,

GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,

"Не найден файл\n main.glade");

gtk_dialog_run(GTK_DIALOG(dialog));

gtk_widget_destroy(dialog);

return 0;

}

char str[1000];

int lenstr=0;

// Открываем БД

void StartDB()

{

if( sqlite3_open("b1.db", &db))

{

sprintf(str, "Ошибка открытия БД: %s\n", sqlite3_errmsg(db));

}

}

void EndDB()

{

sqlite3_close(db);

}

// Запись в БД

int SaveDB()

{

char* SQL1 = "DROP TABLE IF EXISTS Сотрудники; \

CREATE TABLE Сотрудники(N,Фамилия,Оклад); \

INSERT INTO Сотрудники VALUES(1,'Иванов',20000); \

INSERT INTO Сотрудники VALUES(2,'Петров',25000); \

INSERT INTO Сотрудники VALUES(3,'Сидоров',30000); \

";

if (sqlite3_exec(db, SQL1, 0, 0, &err))

{

sprintf(str, "Ошибка выполнения SQL-запроса: %sn", err);

sqlite3_free(err);

return 2;

}

return 0;

}

// Загрузка таблицы из БД в буфер виджета

int LoadDB()

{

char* SQL2 = "SELECT N, Фамилия, Оклад FROM Сотрудники;";

// Готовим SQL-запрос к БД

if(sqlite3_prepare_v2(db, SQL2, -1, &stmt, NULL) != SQLITE_OK)

{

sprintf(str, "Ошибка подготовки SQL-запроса: %s\n", sqlite3_errmsg(db));

sqlite3_finalize(stmt);

return 3;

}

// Цикл по SQL-запросу и запись в буфер таблицы

while((rc = sqlite3_step(stmt)) == SQLITE_ROW)

{

gtk_list_store_append (buffer, &iter);

gtk_list_store_set (buffer, &iter,

C_NUM, sqlite3_column_int(stmt, C_NUM),

C_NAME, sqlite3_column_text(stmt, C_NAME),

C_OKLAD, (guint) sqlite3_column_int(stmt, C_OKLAD),

-1);

}

if(rc != SQLITE_DONE)

{

sprintf(str, "Ошибка выполнения SQL-запроса: %s\n", sqlite3_errmsg(db));

sqlite3_finalize(stmt);

return 4;

}

// 5. Освобождаем строку запроса

sqlite3_finalize(stmt);

return 0;

}

void ShowError ()

{

GtkWidget *dialog = NULL;

dialog = gtk_message_dialog_new (GTK_WINDOW (window1), GTK_DIALOG_MODAL,

GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, str);

gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);

gtk_dialog_run (GTK_DIALOG (dialog));

gtk_widget_destroy (dialog);

}

int ShowMainWindow()

{

builder1 = gtk_builder_new ();

if (gtk_builder_add_from_file (builder1, "main.glade", NULL))

{

window1 = GTK_WIDGET(gtk_builder_get_object(builder1, "window1"));

buffer = GTK_LIST_STORE(gtk_builder_get_object(builder1, "liststore1"));

table = GTK_TREE_VIEW(gtk_builder_get_object(builder1, "treeview1"));

gtk_window_set_default_size (GTK_WINDOW (window1), 500, 300);

gtk_window_set_position(GTK_WINDOW(window1), GTK_WIN_POS_CENTER);

gtk_builder_connect_signals (builder1, NULL);

g_signal_connect(G_OBJECT(window1), "destroy", G_CALLBACK(gtk_main_quit), NULL);

SaveDB();

if(LoadDB())

{

ShowError();

}

gtk_widget_show (window1);

return TRUE;

}

else

{

return FALSE;

}

}

int main (int argc, char *argv[])

{

gtk_init (&argc, &argv);

StartDB();

if (ShowMainWindow ())

{

gtk_main ();

EndDB();

return 0;

}

else

{

ShowGladeError();

EndDB();

return 1;

}

}

В результате мы получаем вывод таблицы из базы данных на экран.

-21

С помощью SQLite Studio можно подключиться к этой БД и увидеть, что все данные отражаются правильно.

-22

Полностью проект можно скачать здесь

Можно ли стать программистом за год с нуля?
Читайте в моей бесплатной мини-книге «Путь в программисты». Скачать её можно здесь.