Создание программы - MySQL DatabaseBrowser. Часть 1
Сейчас использование баз данных, в то числе и удаленных стало обычной и повседневной практикой. Очень часто используется и СУБД MySQL – свободной распространяемая система управления базами данных. В основном она используется для малых и средних предприятий, где успешно решает многие задачи. Ее бесплатность, доступность, стабильность в работе и прочие характеристики позволяет говорить об это СУБД как о массовой альтернативе таких баз как InterBase или SyBase. Последние версии этой программы, существенно расширяющие ее возможности предлагают решение многих проблем, с которым сталкиваются как администратор баз данных, так и обычный пользователь.
Однако, существуют так же и проблемы при работе с Windows, как обязательное наличие драйверов ODBC для MySQL, если СУБД работает в этой среде. Стандартный клиент для MySQL не является удобным в настоящее время, так как является консольной программой. Опять же, требуется как минимум наличие установленной копии программы MySQL сервер на компьютере пользователя. Просмотр данных и простое редактирование также в стандартном клиенте не отвечает современным требованиям к интерфейсу. Решение целого ряда повседневных задач, предполагает стандартизацию пользовательского интерфейса и создание удобного юзабилити.
Поэтому мы пришли к необходимости создания собственного клиентского приложения Целью данного проекта является создание программы, которая бы позволяла выполнять наиболее общие операции с СУБД MySQL в операционной системе Windows, и при это не требовала наличия и настройки ODBC драйвера. Обычно это не умеет делать средний пользователь, и следовательно здесь требуется помощь администратора, что создает дополнительные трудности и самое главное, потерю рабочего времени. Кроме того, эта программа должна уметь соединяться и работать с удаленным MySQL сервером. Сам проект на данном этапе не является окончательной версией программы, поэтому реализуется с наиболее общими возможностями.
Далее будет описано шаг за шагом процесс создания проекта и с примерами исходного кода.
В начале мы создаем шаблон проекта. Для этого мы в Visual Studio выбираем «MFC APPWizard» и вводим название проекта «Myslqlone» . Далее, «Шаге1» выбираем «Single Document». В «Шаге2» и в «Шаге3» не меняем ничего, в «Шаге 4» отключаем «Printing and Print Preview» и переключаем радиобокс на «Internet Explorer Rebars”. В «Шаге 5» выбираем из 2 радиобоксов «Windows Explorer». На конец, в «Шаге 6» нажимаем кнопку «Finish». Выбранный нами тип проекта приложения наиболее полно отвечает решению поставленной задачи. В нем находятся изначально 2 удобных класса, «CleftView”, который является потомком класса «CtreeCtrl» в нашем случае, «CmysqloneView», который в свою очередь наследует от «ClistView», что очень удобно и ускоряет процесс разработки проекта. Оба эти класса могут использовать возможности контролов ClistCtrl и CtreeCTrl, от которых они порождены. Данные обстоятельства в последствии будут нами постоянно использоваться в этом проекте.. Все дальнейшие действия разбиты на этапы и описываются здесь ниже.
1. Копируем 2 файла в папку проекта: «libmysql.dll» и «libmysql.lib» из папки MySQL Server 4.1/lib/. Затем подключаем к проекту файл «libmysql.lib». Нам потребуется этий файлы для обеспечения работы программы и доступа к MySQL API функциям. Мы будем использовать MySQL C API функции, как наиболее стабильно работающие и обеспечивающие полный сервис.
2. Затем копируем все заголовочные файлы из директории MySQL Server 4.1/include/ все заголовочные файлы в директориюVC /include/ Visual Studio. Это также необходимо для создания и компиляции проекта.
3. Подключаем в файл “mysql.h” к файлу «stdafx.h» : #include "mysql.h"
4. Создаем переменную класса CImageList m_TreeImages в классе «CleftView.cpp» Она будет использована для создания списка изображени\й, которые будут в свою очередь использованы в создаваемом объекте типа CtreeCtrl.
5. Создаем в файле ресурсов новый ресурс.
6. Создаем в классе «CleftView.cpp» новый метод void FellTree(): void CLeftView::FillTree() { CTreeCtrl & m_tree = GetTreeCtrl(); m_tree.DeleteAllItems();
m_tree.SetImageList(&m_TreeImages, TVSIL_NORMAL);
HTREEITEM hRoot;
CMysqloneDoc* pDoc = GetDocument();
for (int i = 0; i < pDoc->m_available_bases.GetSize(); i++) { hRoot = m_tree.InsertItem(pDoc->m_available_bases[i], 0, 1); }
}
7. Создаем в методе класса «CleftView.cpp» :OnInitialUpdate() объект класса CimageList:
m_TreeImages.Create(IDB_BITMAP1, 16, 1, RGB(255, 255, 255)); Это создает список пиктограмм для CtreeCtrl
8. Добавляем в этот же класс метод OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult) для обработки события смены элементов списка.
10. Добавляем новый ресурс – диалоговое окно. Туда вставляем 3 поля редактирования,одному из них в стилях проставляем стиль: «password» . Далее мы заходи в Class Wizard и создаем новый класс для данного диалога. Назовем его «CLoginDlg». Он будет наследоваться от класса CDialog. Далее к каждому из полей редактирования создаем переменные типа Cstring. Это будут переменные этого класса для ввода данных по соединению с MySQL сервером.
11. Затем мы создаем переменную типа MYSQL mysql для класса «CmysqloneApp.cpp», это класс приложения. Эта переменная будет использоваться нами далее везде в программе для доступа к функциям MySQL. Затем создаем в этом же классе новый метод для соединения с сервером баз данных. типа BOOL ConnectToDb(). Вот его код:
BOOL CMysqloneApp::ConnectToDb() { CLoginDlg dlg;
while (dlg.DoModal()== IDOK) { if(!mysql_init(&mysql)){AfxMessageBox ("Can't make initialization to mysql server!");} if(mysql_real_connect(&mysql,dlg.m_host, dlg.m_login,dlg.m_password,NULL,0,NULL,0)){ return TRUE; } } return FALSE;
} В этом методе вызывается диалоговое окно CloginDlg, чтобы считать введенные пользователем данные и выполнить соединение с MySQL сервером. Данные пользователя хранятся в специальном файле, с расширением «.lgn», который предоставляет администратор. Ниже приводится код метода подключения к серверу баз данных: void CLoginDlg::OnBnClickedLogin() { UpdateData();
if( m_login =="") { AfxMessageBox("You must provide a username and password or click Cancel!"); return; } if( m_password =="") { AfxMessageBox("Invalid login entered"); return; }
fclose(file); } catch(...) { AfxMessageBox("Could not validate entered information to connect with MySQL database"); }
UpdateData(FALSE);
}
12. Подключаем заголовочный файл класса «CloginDlg.cpp» – «LoginDlg.h» к к файлу класса «CMysqloneApp»-«mysqlone.cpp»
#include "LoginDlg.h"
13. Создаем еще один метод для этого же класса типа void ExecuteSQL(CString sql). Он будет использоваться для выполнения запросов к MySQL серверу. Вот его код:
void CMysqloneApp::ExecuteSQL(CString sql) {
mysql_query (&mysql, sql);
}
Он также будет использоваться повсеместно в работе программы.
14. Затем мы создаем новые переменные для класса «CmysqloneDoc.cpp» CStringArray m_available_bases; //текстовой массив списка доступных .//баз. CString current_base; //переменная строкового типа для имени текущей //базы CString current_table; //строковая переменная для имени текущей таблицы bool connected;// переменная булевого типа для состояния соединения с //MySQL сервером.
15. На конец, вставляем следующий код вызова метода ConnectToDb() в «CMysqloneApp»-«mysqlone.cpp» в метод InitInstance():
SetRegistryKey(_T("MySQLOne- MySQL Database Browser"));
LoadStdProfileSettings(); // Load standard INI file options (including MRU)
//После этих строк.
if (!ConnectToDb()) { AfxMessageBox ("Could not connect to base\nQuitting"); return FALSE; }
Метод ConnectToDb() будет вызываться при запуске программы, а поскольку он булевого типа, то про возращении этим методом FALSE программа не будет работать. Теперь добавим еще один метод, который будет выбирать базу данных для дальнейшего использования.
16. Далее мы переходим в класс «CleftView.cpp» и через Class Wizard добавляем туда метод OnUpdate. Это один из поддерживаемых представлением методов, который нам нужно переопределить таким образом:
18. Теперь переходим в класс «CmysqloneView.cpp», где добавляем в метод этого класса OnInitialUpdate() следующий код для создания объекта типа ClistCTrl и задания его стилей отображения.
if (!pDoc->connected) { m_list.DeleteAllItems (); while(m_list.DeleteColumn(0)); return; } if (pDoc->current_table == "") return; m_list.DeleteAllItems(); while(m_list.DeleteColumn(0));
MYSQL* mysql = &(((CMysqloneApp*)AfxGetApp())->mysql); MYSQL_RES * my_res; MYSQL_ROW row; CString sql; sql="SHOW COLUMNS IN "; sql += pDoc->current_table; mysql_query (mysql, sql); my_res = mysql_store_result (mysql); int i = 0; int counter = 0; while (row = mysql_fetch_row (my_res)) { m_list.InsertColumn (i, row[0], LVCFMT_LEFT, 100); i++; } counter = i; mysql_free_result (my_res);
sql = "SELECT * FROM "; sql += pDoc->current_table; mysql_query (mysql, sql); my_res = mysql_store_result (mysql); i = 0; LVITEM item; item.mask = LVIF_TEXT; while (row = mysql_fetch_row (my_res)) { item.iItem = i; item.iSubItem = 0; item.pszText = row[0]; m_list.InsertItem (&item); for (int z = 1; z < counter; z++) { item.iSubItem = z; item.pszText = row[z]; m_list.SetItem (&item); }
i++; }
}
Этот метод будет использоваться для отображения в правой части окна структуры данных, полученных в результате запросе к базе данных. Фактически, это и будет главное просмотровое окно программы, отображающие данные и структуру таблиц баз данных.
20. Теперь мы снова идем во вкладку «Resources» и добавляем новый ресурс – диалоговое окно. Это окно будет использоваться для создания новой базы данных. Мы вводим туда новое текстовое поле типа CEdit и СStatic, для создания текстового заголовка: «New Database Name». Создаем в Class Wizarde новый класс «CNewDatabaseDlg». К текстовому полю CEdit подключаем переменную типа CString - «m_newdatabase». Эта переменная для задания нового имени вновь создаваемой базы данных.
21. Переопределяем метод этого класса OnOK() для исполнения запроса к MySQL серверу по созданию новой базы.
22. Подключаем заголовочный файл нового диалогового «CreateNewTableDlg.h» к классу «CleftView.срр» для последующей обработки командой меню.
23. Теперь переходим опять во вкладку «Resources» и добавляем новое диалоговое окно. На этот раз в нем будет окно для исполнения запросов к базе данных. Мы добавляем туда следующие контролы: ССombox – сюда мы будем вводить SQL запрос, CListBox - это будет форма для отображения списка доступных нам баз данных и CListCtrl - в нем будут отображаться результаты SQL запросов. Итак, мы создаем 2 переменных класса: CListBox m_listbox и CListCtrl m_list.
24. Затем мы добавляем новый метод к этому классу диалога- void AddStr(). Этот метод будет получать строковую переменную, введенную в CComboBox . Далее код этого метода:
25. Теперь нам необходимо заполнить список базами данных, которыей находятся в данный момент на сервере MySQL. Для этого мы подключаем и переопределяем метод OnInitDialog(). В нем мы заполняем список CListBox, который буджет показываться при запуске этого окна.
Listen to the stage manager and get on stage when they tell you to. No one has time for the rock star bullshit. None of the techs backstage care if you're David Bowie or the milkman. When you act like a jerk, they are completely unimpressed with the infantile display that you might think comes with your dubious status. They were there hours before you building the stage, and they will be there hours after you leave tearing it down. They should get your salary, and you should get theirs. -- Lollapalooza Alumni Henry Rollins