- позволяет писать сценарии и создавать на их основе управляемые пользователем интерактивные приложения;
- обеспечивает возможность взаимодействовать с другими программами сервера;
- имеет средства динамического создания Web-страниц на основе информации пользователя;
- может вызвать внешнюю программу и передать в нее пользовательские данные.
В конечном итоге пользователь, не будучи ограничен в рамках заранее написанных документов, используя CGI сценарий может создать круг приложений, которые ему необходимы для получения информации.
Программе CGI необходимо извлечь информацию, обработать ее и сообщить ответ. Рассмотрим простой пример – создание виртуального документа:
Запускаем C++Builder. В главном меню выбираем File/New и в открывшейся таблице NewItems выбираем ConsoleApp.
Удаляем все, что находится в открывшемся окне и записываем код:
//Пример CGI
#include <vcl\vcl.h>
#pragma hdrstop
char S[] = "ПРИВЕТ<P>\n";
void main(void)
{
setvbuf(stdout, NULL, _IONBF, 0);
printf("\nContent-type: text/html\n\n");
printf("<html>\n");
printf("<body>\n");
printf(S);
printf("</body>\n");
printf("</html>\n");
}
Запоминаем программу и запускаем на трансляцию. После этого помещаем выполняемый файл (например Prim.exe) на Web-сервер в раздел CGI.
Запускаем броузер и вызывем программу из раздела CGI.
Во время выполнения программа посылает свою информацию на стандартный вывод, как поток данных, состоящий из двух частей:
- заголовок в котором описан формат возвращаемых данных
printf("\nContent-type: text/html\n\n"); - текстформата HTML;
- тело выходных данных – данные в формате HTML.
Сервер возвращает результаты выполнения CGI-программы броузеру.
Для Web-сервера неважен язык, на котором написана программа.
4.15 Программирование баз данных
Особенностью разработки доступа к базам данных при помощи C++Builder является полностью объектный визуальный подход. Вторая особенность заключается в том, что доступ к разным базам данных (dBase, Paradox, Oracle и другим) происходит совершенно унифицированно. Эта дает определенные преимущества по сравнению с таким мощным средством разработки баз данных как VisualFoxPro.
Интерфейсом между приложением и базами данных служит BDE - BorlandDatabaseEngine, т.е Механизм База данных Borland. Он позволяет не только осуществлять доступ к локальным базам данных, но и осуществлять доступ к данным по типу клиент-сервер. Одной из особенностей C++Builder является то,что доступ к базам данных осуществляется одинаково как на стадии разработки, так и на стадии исполнения.
Для разработки используется трех ступенчатая модель. Каждой ступени соответствует своя компонента (класс).
TDBGrid - отображает в окне область редактирования (по типу команды Browse (Grid) в FoxPro)
TdataSource - служит интерфейсом между TDBEdit и нижней компонентой.
TTable - содержит все записи таблици.
На более низком уровне работают драйвера BDE, осуществляющие непосредственный обмен с хранимыми данными.
Расмотрим более подробно описанные выше компоненты.
Источник данных (TDataSource).
Основные свойства.
AutoEdit - разрешает или запрещает редактирование записей (False или True).
DataSet - определяет имя конкретного набора данных, таблицы или запроса. Например Table1. Можно переключаться с одного набора данных на другой непосредственно во время выполнения программы.
Name - определяет название данной компоненты. Например DataSource.
С данной компонентой связаны три события OnDataChange, OnStateChange, OnUpdateData.
Таблица (TTable).
Основные свойства.
Active - разрешает или запрещает просмотр данных.
DatabaseName - псевдоним базы данных и путь к каталогу, где база данных содержится.
Name - псевдоним таблицы.
TableName - конкретное имя таблицы (в указанном каталоге).
Exclusive - разрешает или запрещает другому приложению обращаться к таблице.
IndexFiles - выбор индексного файла для таблицы.
IndexName - правило сортировки данных в индексе.
Filter - установка фильтра.
MasterFields и MasterSource - для образования связей между двумя таблицами.
Для данной компоненты определены стандартные методы используемые другими системами управления баз данных: Locate, Lookup, Append, Insert, Next, MoveBye и другие.
Отображение данных (TDBGrid).
Некоторые свойства.
DataSource - совпадает со свойством Name компоненты TDataSource. Врезультатеимеемследующуюсвязку:
TDBGrid TDataSource TTable
-----------------------------------------------------------------------------------------
DataSource <--> Name-DataSet <--> Name -DatabaseName-TableName
Такая связка обеспечит в окне редактирования появления записей таблицы имеющей имя TableName (см.ниже).
Другие свойства данной компоненты тривиальны - они определяют положение окна редактирования, цветовую гамму, размера окна, шрифты и т.п.
Еще одна компонента часто используется в связи с работой с базами данных.
Запросы (Tquery).
Данная компонента понадобится вам, если у вас возникнет необходимость пользоваться командами SQL-языка.
Основные свойства.
Active - разрешает или запрещает просмотр данных.
DatabaseName - содержит псевдоним базы данных или полный путь к каталогу, где эта база данных находится.
SQL - используется для ввода команды SQL. Синтаксис этих команд является стандартом и с ним можно познакомиться в любом руководстве по СУБД (например FoxPro).
RequestLive - разрешает или запрещает BDE возращать набор данных в любом случае.
Приступаем теперь к разбору конкретного примера. Пример очень прост. При запуске программы появляется форма. На форме имеется окно редактирования таблицы, кнопка "Выход", кнопка "Добавить", кнопка "Удалить". Таблица содержит данные о людях: ФИО, выданная сумма, дата выдачи. У вас будет имется возможность редактировать таблицу, добавлять и удалять записи. При запуске программа проверяет наличие таблицы в указанном каталоге и при необходимости создает и индексирует эту таблицу.
Поместим на форму три кнопки, TDBGrid (для просмотра таблицы), TTable, TDataSource.. Пусть наша таблица будет находится в каталоге c:\baza\ и будет иметь имя 'proba' Заполним свойства трех компонент основных компонент:
TTable :
DatabaseName=c:\baza\
Name=Table1
TableType=ttDBase
TableName=proba
IndexName=proba
TDataSource:
DataSet=Table1
Name=DataSource1
TDBGrid:
DataSource=DataSource1
Все остальные свойства можно оставить по умолчанию и менять по ходу работы над программой.
Приведем текст модуля Unit1.cpp содержащего основные исполняемые функции.
//---------------------------------------------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma link "Grids"
#pragma resource "*.dfm"
TForm1 *Form1;
char * baza="proba.dbf";
char * baza1="proba";
//---------------------------------------------------------------------------
//Конструктор
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
HANDLE handle;
//пытаемся открыть таблицу как обычный файл
handle=CreateFile(baza,
GENERIC_READ,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_ARCHIVE,
NULL);
if(handle!=INVALID_HANDLE_VALUE)
{
//файлестьизакроем
CloseHandle(handle);
} else
{
//файланет
//создаемтаблицу
Table1->FieldDefs->Clear();
Table1->FieldDefs->Add("Name", ftString, 20, true);
Table1->FieldDefs->Add("Zarpl", ftFloat, 0, true);
Table1->FieldDefs->Add("Data", ftDate, 0, true);
//теперь создаем индексный файл
Table1->IndexDefs->Clear();
TIndexOptions MyIndexOptions;
MyIndexOptions << ixPrimary << ixUnique;
Table1->IndexDefs->Add(baza1, "Data", MyIndexOptions);
Table1->CreateTable();
}
//здесьоткрытьтаблицу
Table1->Active = true;
//активизироватьиндекс
Table1->OpenIndexFile("proba.MDX");
}
//----------------------------------------------
//Деструктор
__fastcall TForm1::~TForm1()
{
//закрытьтаблицу
Table1->Active = false;
}
//---------------------------------------------------------------------------
//выход
void __fastcall TForm1::Button1Click(TObject *Sender)
{
//метод Close закрывает форму и вызывает деструктор
Close();
}
//---------------------------------------------------------------------------
//кнопка "добавитьзапись"
void __fastcall TForm1::Button3Click(TObject *Sender)
{
Table1->Append();
}
//---------------------------------------------------------------------------
//кнопка "удалить запись"
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Table1->Delete();
}
Прокоментируем вышеприведенный текст.
Отметим одну интересную возможность C++Builder. Он может одновременно работать как с библиотекой объектов с которой мы до сих пор работали так и непосредственно с функциями API. В нашей программе мы демонстрируем эту возможность: в конструкторе пытаемся открыть файл (функция CreateFile). Если открытие не удается, выполняется часть кода создающий таблицу и индексный файл. Ниже представлено окно работы нашей программы.
4.16 ПАКЕТЫ
Существенную роль в разработке приложений на языке C++Builder 3 и выше играют пакеты(packages), которые представляют собой библиотеки динамической компоновки, содержащие компоненты C++Builder из библиотеки визуальных компонент(VCL).
Применение пакетов позволяет умсеньшить размеры исполняемых (.EXE- файлов, однако в таком случае вместе с программой необходимо распространять эти библиотеки.
Существует несколько видов пакетов- выделим из них пакеты времени выполнения(ПВВ). Пакеты данного вида используются: когда приложение выполняется.
ПВВ могут связываться статически и динамически. При статическом связывании образуется выполняемый файл, для которого не нужны библиотеки с расширением (.BPL). Связывание в пакет динамически ведет к тому, что библиотеки .BPL должны распространяться с приложением.
В C++Builder 3 и выше в меню Project/Options/Packages естьопция Build with runtime packages. Если флажок возле этой опции установлен, то приложение необходимо распространять вместе с библиотеками .BPL, если флажок не установлен, то получается полностью скомпилированный выполняемы файл.
Динамическое связывание применяется при конструировании приложений, состоящих из большого количества выполняемых файлов.
Заключение
В представленном учебном пособии были рассмотрены некоторые вопросы программирования на языке С++ и C++Builder.