Журнал LinuxFormat - перейти на главную

LXF71:Gambas

Материал из Linuxformat
Версия от 13:59, 22 мая 2008; Yaleks (обсуждение | вклад)

(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Содержание

Легкий доступ к базам данных

PART 1 Хотите написать красивое приложение для работы с вашей базой данных? У вас есть на это всего десять минут? Доктор Марк Александр Бэйн (Dr Mark Alexander Bain) прописал Gambas!

я буду удивлён, если мой вопрос “как вам понравится Visual Basic для Linux?” не вызовет у вас злости. Пожалуйста, успокойтесь, дышите ровно и перестаньте рвать журнал. Давайте я лучше спрошу так: «как быть опытным программистам на Visual Basic, которые хотели бы полностью перебраться под Linux, но не сделают этого до тех пор, пока не смогут взять с собой свои навыки?» Для этого нужен язык программирования, который не является VB, но позволит программистам на VB работать в Linux. Звучит гораздо лучше, правда?

Этот язык – Gambas. он спроектирован так, что каждый, кто раньше пользовался Visual Basic, почувствует себя здесь, как дома, а новичок в программировании с его помощью сможет разрабатывать приложения, которые выглядят профессионально. В конце этого урока вы научитесь создавать графический пользовательский интерфейс, настраивать (простую) базу данных, а также читать и писать в неё информацию при помощи графического интерфейса.

Итак, приступим!

самое начало

Время инсталлировать базу данных. Да, я знаю что вы хотите сразу получить GUI и углубиться в код. Но убедиться в том, что база данных на месте действительно важно. Почему? Потому, что процесс установки Gambas требует драйверов, которые входят в состав базы данных. Его можно скомпилировать и без них, и им потом даже можно будет пользоваться, но вот поддержки баз данных вы при этом не получите.

Итак, нам нужна база данных. Если вы сразу подумали MS Access, умойте с мылом своё сознание. я имел ввиду MySQL или PostgreSQL. Почему? Потому что они оба бесплатны, просты в использовании и очень надёжны.

Главный недостаток PostgreSQL состоит в том, что Gambas ожидает что у вас установлены пакеты разработки PostgreSQL. Это значит, что вам придётся где-то достать эти файлы для вашего дистрибутива Linux. Если вы не уверены, или спешите (или просто такой же лентяй, как и я), возьмите MySQL. Gambas может работать с ним прямо из коробочки.

В процессе установки Gambas нет ничего особенного, и вы очень скоро сможете его запустить. Дистрибутив Gambas можно скачать с http://gambas.sourceforge.net. При первом запуске вы увидите окно с приглашением создать новый проект или открыть существующий. Выбор первой опции запустит мастер, который проведёт вас по всем этапам подготовки проекта. как только он закончится, первое что надо будет сделать – это создать новую форму (в конце концов, мы работаем с GUI!). Для этого в окне Project активируйте папку Forms, щелкните правой кнопкой мыши и выберите пункт меню New.

построение GUI

Итак, наконец-то мы можем перейти к созданию графического интерфейса, выбирая нужные элементы в панели инструментов, а затем рисуя их на форме мышкой. Для первого примера мы добавим только выпадающий список (combo box) и поле ввода (text box). щелчок на зелёном треугольнике позволит вам запустить приложение. Да, пока оно не делает ничего особенного, но мы можем добавить код, чтобы исправить это упущение. Для того, чтобы вернуться в режим дизайнера кликните на красном квадрате в меню окна Project.

Gambas управляется событиями (как и Visual Basic). Это значит, что весь выполняемый код мы должны связать с кнопками, выпадающими списками и так далее. Двойной щелчок на форме открывает окно редактирования кода. Сейчас оно выглядит примерно так:

‘ Gambas class file
PUBLIC SUB Form_Open()
END

В этом месте мы можем размещать переменные, функции, процедуры и комментарии (они начинаются с символа ‘). По умолчанию система создаёт процедуру (подпрограмму) Form_Open, которая выполняется в момент открытия формы. Вот, каким образом Gambas управляется событиями.

Немного доработаем код:

‘ Gambas class file
PUBLIC SUB Form_Open()
combobox1.Add(“Fred Jones”)
combobox1.Add(“Mary Smith”)
combobox1.Add(“Jim Thompson”)
END

Нажатием зелёной кнопки Run запустим наш проект. теперь у вас есть форма с работающим выпадающим списком. Здорово, правда?

Вернёмся в режим дизайнера с помощью красной кнопки Stop и щелкнем дважды на выпадающем списке. В приложении появится новая процедура (ComboBox1_Click), после создания кода для которой мы должны получить примерно следующее:

‘ Gambas class file
PUBLIC SUB Form_Open()
combobox1.Add(“Fred Jones”)
combobox1.Add(“Mary Smith”)
combobox1.Add(“Jim Thompson”)
ComboBox1_Click
END
PUBLIC SUB ComboBox1_Click()
IF combobox1.text = “Fred Jones” THEN
textbox1.Text=”London”
ELSE IF combobox1.text = “Mary Smith” THEN
textbox1.Text=”Paris”
ELSE IF combobox1.text = “Jim Thompson” THEN
textbox1.Text=”New York”
END IF
END

Заметьте, что процедура ComboBox1_Click вызывается в конце процедуры Form_Open. Попробуйте запустить приложение в таком виде и спрятав это строчку за символ комментария, чтобы понять зачем она нужна.

Итак, у нас уже есть работоспособный графический интерфейс, но все данные прописаны прямо в коде приложения – не самая лучшая ситуация. Представьте себе, что в этом приложении лежат данные о целой компании, а затем Фред переезжает в берлин, Мэри внезапно выходит замуж (или разводится), а Джим превратился в Джэйн. Используя базу данных для хранения информации, мы можем писать приложения, которые гораздо проще поддерживать.

настройка данных

Перед тем, как начинать программировать работу с базой данных, её нужно настроить определённым образом. Для начала приведём код настройки окружения базы (для MySQL и PostrgeSQL соответственно).

MySQL (от имени root) PostgreSQL (от имени root)
su mysql
mysql_install_db
useradd -d /home/postgres postgres
mkdir /home/postgres
chown postgres /home/postgres
mkdir /usr/local/pgsql/data
chown postgres /usr/local/pgsql/data
su postgres
/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data

Это нужно выполнить только один раз, лучше всего сразу после установки пакета.

Для запуска базы данных наберите:

MySQL (от имени mysqll) PostgreSQL (от имени postgres)
/usr/bin/mysqld_safe &
/usr/local/pgsql/bin/postmaster -D /usr/local/
pgsql/data >~/logfile 2>&1 &

как правило, подобный запуск нужно выполнять при каждой загрузке вашего компьютера.

MySQL (от имени любого пользователя) PostgreSQL (от имени любого пользователя)
echo “create database customers”| mysql -uroot
mysql -uroot < data.sql
/usr/local/pgsql/bin/createdb customers
/usr/local/pgsql/bin/psql customers < data.sql
CREATE TABLE manager (
id int AUTO_INCREMENT,
surname varchar(50),
firstname varchar(50),
PRIMARY KEY (id));
CREATE TABLE office (
id int AUTO_INCREMENT,
city varchar(50),
manager_id int,
PRIMARY KEY (id));
GRANT SELECT,INSERT,DELETE,UPDATE ON *
TO bainm@localhost IDENTIFIED BY 
‘mypassword’;
CREATE TABLE manager (
id bigserial,
surname varchar(50),
firstname varchar(50),
PRIMARY KEY (id));
CREATE TABLE office (
id bigserial,
city varchar(50),
manager_id int,
PRIMARY KEY (id));
CREATE user bainm password ‘mypassword’;
GRANT SELECT,INSERT,DELETE,UPDATE ON manager TO bainm;
GRANT SELECT,INSERT,DELETE,UPDATE ON office TO bainm;

таким образом, вы создадите таблицу. Для того, чтобы загрузить в неё данные, нужен следующий код:

/*Загрузка данных по умолчанию*/
INSERT INTO manager (firstname,surname) VALUES (‘Fred’,’Jones’);
INSERT INTO manager (firstname,surname) VALUES(‘Mary’,’Smith’);
INSERT INTO manager (firstname,surname) VALUES (‘Jim’,‘Johnson’);
INSERT INTO office(city,manager_id) VALUES (‘London’,1);
INSERT INTO office(city,manager_id) VALUES (‘Paris’,2);
INSERT INTO office(city,manager_id) VALUES (‘New York’,3);

Хотя для каждой базы данных существует свой набор инструментов, основы языка запросов одинаковы. оба приложения понимают SQL (Structured Query Language, язык структурированных запросов), однако в его реализации есть небольшие отличия. Например, в MySQL вы можете указать звёздочку (*) в выражении GRANT, тогда как PostgreSQL требует отдельного GRANT для каждой таблицы. однако, в подавляющем большинстве случаев запрос, написанный для одной базы данных будет работать и для другой.

Перед тем, как выполнять запросы, мы должны присоединиться к базе данных. Gambas содержит множество компонентов, которые можно добавлять в процессе создания формы. В данном случае нам потребуются компоненты доступа к базам данных. Выберите в окне Project пункт меню Project, а затем Properties. Перейдите к вкладке Components и включите галочку около gb.db. теперь наше приложение готово подключиться к базе данных.

Чтобы создать подключение, нам придётся писать код, правда, он будет очень простым. Для начала надо сказать программе, какое подключение использовать.

‘ Gambas class file
PRIVATE conn AS NEW Connection

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

В первую очередь нам надо указать, как и куда подключаться – каким драйвером воспользоваться, имя пользователя и пароль, а также название базы данных.

WITH conn
.Type = “mysql”
.Host = “localhost”
.Login = “bainm”
.Password = “mypassword”
.Name = “customers”
END WITH

После настройки нам осталось только открыть соединение, и мы будем готовы отправлять и получать информацию.

TRY conn.OPEN

Использование TRY необходимо потому, что мы не хотим чтобы наше приложение обрушилось, если вдруг оно не сможет присоединиться.

Вместо этого мы поймаем и обработаем любую ошибку, которая может возникнуть.

TRY conn.Open
IF ERROR THEN
Message (“Cannot Open Database. Error = “ & Error.Text)
END IF

Вся функция для настройки и открытия соединения выглядит так:

‘ Gambas class file
PRIVATE conn AS NEW Connection
PRIVATE FUNCTION make_connection() AS Boolean
WITH conn
.Type = “mysql”
.Host = “localhost”
.Login = “bainm”
.Password = “mypassword”
.Name = “customers”
END WITH
TRY conn.Open
IF ERROR THEN
Message (“Cannot Open Database. Error= “ &
Error.Text)
RETURN FALSE
END IF
RETURN TRUE
END

Функция возвращает TRUE, если подключение удалось и FALSE в противном случае.

время воспользоваться данными

Получив соединение с базой данных, можно воспользоваться содержащейся в ней информацией. Для начала заполним выпадающий список.

Любой программист на Visual Basic использовал бы в этих целях объект Recordset. В Gambas эту роль выполняет Result. он содержит в себе результаты запроса к базе данных. Например, чтобы получить список всех менеджеров, мы должны выполнить следующий запрос:

SELECT surname,firstname FROM manager

отправить этот запрос базе данных и получить результат в виде Result можно вот так:

resManager= conn.Exec(“select surname,firstname from manager”)

теперь этой информацией можно воспользоваться, чтобы заполнить выпадающий список. Напишем простой цикл

FOR EACH resManager
ComboBox1.Add (resManager!firstname & “ “ & resManager!surname)
NEXT

обратите внимание на то, что к каждому полю результата мы обращаемся при помощи имени объекта Result, восклицательного знака и имени поля, например res!firstname.

Если сделать resManager глобальной переменной, она будет доступна в других процедурах и функциях, а включив поле id в запрос мы получим возможность легко ссылаться на эти данные из любого места программы. обратите внимание на то, как строки соединяются друг с другом при помощи &.

PRIVATE resManager AS Result
PRIVATE SUB load_combo()
DIM sql AS String
sql=”select id, surname,firstname from manager”
resManager= conn.Exec(sql)
FOR EACH resManager
ComboBox1.Add (resManager!firstname & “ “ & resManager!surname)
NEXT
END

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

Вернёмся к процедуре load_combo, в которой мы заносим список менеджеров в resManager. каждая запись включает в себя идентификатор ID, имя и фамилию каждого менеджера. Всё, что нам нужно сделать – это перейти к нужной строчке, достать из нее ID и запросить у базы данных офис менеджера с таким идентификатором. Мы можем использовать поле index выпадающего списка для определения строки, к которой нужно перейти (для первого менеджера index = 0, для второго – 1, для третьего – 2 и так далее). технология проста: сначала нужно переместить указатель resManager на первую запись, а потом переместиться к следующей n раз, где n – это index выпадающего списка.

resManager.MoveFirst
resManager.MoveTo( ComboBox1.INDEX)

текст запроса генерируется на основе resManager!id.

sql=SELECT city FROM office” &
“ WHERE manager_id=” & resManager!id

Целиком процедура будет выглядеть так:

PUBLIC SUB ComboBox1_Click()
DIM res AS Result
DIM sql AS String
resManager.MoveFirst
resManager.MoveTo( ComboBox1.Index)
sql = “select city from office” & “ where manager_id=” &
resManager!id
res = conn.Exec(sql)
textbox1.Text=res!city
END

окончательный вариант Form_Open

PUBLIC SUB Form_Open()
IF make_connection()=TRUE THEN
load_combo
ComboBox1_Click
END IF
END

Мы уже выполняли запись в базу данных, когда настраивали её. Делалось это при помощи оператора INSERT. Второй способ изменения данных – это оператор UPDATE. Давайте для начала рассмотрим INSERT.

Для этих целей добавим на форму поле ввода и кнопку и используем их для указания нового города. Выполните двойной щелчок на кнопке и вы обнаружите процедуру Button1_Click.

PUBLIC SUB Button1_Click()
END

основной целью процедуры является создание SQL-запроса для вставки в базу нового города на основе содержимого поля ввода

sql=”insert into office (city) values (‘” & textbox2.text &”’)”

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

PUBLIC SUB Button1_Click()
DIM res AS Result
DIM sql AS String
IF textbox2.text <> “” THEN
sql=”insert into office (city) values (‘” & textbox2.text &”’)”
res=conn.Exec(sql)
ELSE
message (“Input required”)
END IF
END

обратите внимание: на экране кнопка имеет надпись Button1, а второе поле ввода - TextBox2. Для изменения этих названий убедитесь, что вы находитесь в режиме дизайнера, щелкните (только один раз, вы ведь не собираетесь писать код) на нужном элементе управления и нажмите F4. Появится страница Properties. отыщите там элемент с названием Text и замените его значение на «Add» для кнопки и пустую строку для поля ввода.

Если вы запустите приложение и нажмёте кнопку Add, внешне ничего не произойдёт. однако, при помощи следующей команды оболочки

echoselect * from office”| mysql -uroot customers

вы можете убедиться, что город был добавлен в базу данных.

Для того, чтобы увидеть новый город в приложении, нужно создать новый выпадающий список и заполнить его данными из таблицы городов, в которых еще нет ни одного менеджера. Значит, нам нужно добавить такой список в форму и написать процедуру для его заполнения (она будет вызываться из Form_Open и при нажатии кнопки Add).

PRIVATE resNewOffice AS Result ‘Global variable
PRIVATE SUB load_new_office ()
DIM sql AS String
sql=”select id,city from office where manager_id is NULL”
resNewOffice=conn.Exec(sql)
combobox2.Clear
FOR EACH resNewOffice
combobox2.Add(resNewOffice!city)
NEXT
END

Эта функция очень похожа на процедуру для заполнения выпадающего списка менеджеров с одним отличием

combobox2.Clear

Поскольку она может быть вызвана не только из Form_Open (когда выпадающий список еще пуст), но и при добавлении города. Эта строчка очищает список, чтобы в него можно было загрузить новые данные.

Наконец, мы рассмотрим, как изменять данные в базе при помощи выражения UPDATE. Допустим, мы хотим переместить одного из менеджеров в новый офис. Эта процедура перенесёт id менеджера из записи о старом офисе в запись о новом:

PUBLIC SUB Button2_Click()
DIM res AS Result
DIM sql AS String
resNewOffice.MoveFirst
resNewOffice.MoveTo (combobox2.Index)
resManager.MoveFirst
resManager.MoveTo (combobox1.Index)
sql=”update office set manager_id=NULL” & “ where
manager_id=” & resManager!id
res=conn.Exec(sql)
sql=”update office set manager_id=” & resManager!id &
“ where id=” & resNewOffice!id
res=conn.Exec(sql)
ComboBox1_Click
load_new_office
END

Ну вот, всё что нам осталось – это привести экран в порядок, добавив метки (используйте F4, чтобы получить доступ к окну Properties и изменить текст меток).

использование хранимых процедур

Хранимые процедуры очень похожи на обычные процедуры и функции с тем отличием, что они хранятся на стороне базы данных, а не на стороне клиентского приложения. Их достоинством является то, что если вы изменили код процедуры, то результат его работы (или ошибку) увидят все пользователи системы без необходимости в установке новой версии вашей программы. Хранимые процедуры очень полезны для выполнения операторов UPDATE/INSERT.

Если вы измените структуру или положение таблицы, вам нужно будет только изменить код хранимой процедуры в базе данных вместо того, чтобы перекомпилировать и обновлять приложение на всех рабочих местах. Хранимые процедуры создаются следующим образом (в PostgreSQL и MySQL 5.0)

mysql> CREATE PROCEDURE updateLocation (IN manid INT,IN offid INT)
-> BEGIN
-> UPDATE office SET manager_id=NULL WHERE manager_id=manid;
UPDATE office SET manager_id=manid WHERE id=offid;
-> END
-> //

А вот так выглядит использование хранимой процедуры (из Gambas).

PUBLIC SUB Button2_Click()
DIM res AS Result
DIM sql AS String
resNewOffice.MoveFirst
resNewOffice.MoveTo (combobox2.Index)
resManager.MoveFirst
resManager.MoveTo (combobox1.Index)
sql=”call updateLocation(resManager!id,resNewOffice!id)”
res=conn.Exec(sql)
ComboBox1_Click
load_new_office
END

Программировать в Gambas легко. Если вы опытный программист под Windows, я надеюсь что вы увидели путь в Linux, проложенный маленькой синей креветкой Gambas.

Персональные инструменты
купить
подписаться
Яндекс.Метрика