Оглавление Проект: База данных MySQL5



Главная форма программы.

Проект создан переработкой консольного приложения, описанного ранее. В связи с использованием модуля MySQL50 вместо MySQL4 внесены коррективы. База данных состоит из трёх простейших таблиц и предназначена для анализа семейного бюджета (расходы):

Таблицы созданы запросами:
CREATE TABLE User (
ID INT UNSIGNED NOT NULL AUTO_INCREMENT,
Name VARCHAR( 30 )  NOT NULL,
Pass  VARCHAR( 10 )  NOT NULL,
PRIMARY KEY ( ID ) ,
UNIQUE (Name))

Позже было добавлено поле Foto - для хранения фотографий
(при помощи запроса ALTER TABLE): 
ALTER TABLE User 
ADD COLUMN Foto MEDIUMBLOB  NULL AFTER Pass

CREATE TABLE RASXOD (
ID INT UNSIGNED NOT NULL AUTO_INCREMENT,
KTO INT UNSIGNED NOT NULL,
STAT INT UNSIGNED NOT NULL, 
Rasxod double(8,2)  UNSIGNED NOT NULL,
PRIMARY KEY ( id ) )

CREATE TABLE STAT (
ID INT UNSIGNED NOT NULL AUTO_INCREMENT,
STAT VARCHAR( 40 )  NOT NULL ,
PRIMARY KEY ( id ) ,
UNIQUE (STAT))
 1. Комментарии к главному модулю. 

{ --- Как и все примеры - эта программа - результат поисков и опытов ---

Приложение демонстрирует работу с простейшей базой данных. Используются
данные типа MediumBlob для хранения картинок - фото. Бинарные данные картинок
кодируются MIME-base64 и хранятся в виде текста, а при просмотре - декодируются.
На это тратится время и дополнительно 30% памяти, но похоже, по другому нельзя.
Возможно, что лучше в таблице хранить имена файлов (*.jpg, *.png ), но полезно
уметь хранить бинарные данные в таблице. 

1. Главная форма: frmMySQL5, модуль - unmain1.
Должен быть доступен MySQL. Например, у меня установлен Denwer3, при запуске
которого доступнен MySQL5 (и PHP5). Для создания БД достаточно создать папку
..\mysql5\data\lab3_2\
Подключаюсь к БД MySQL и выполняю запрос, вписанный в окошко memSQL.
(Для этого - жмём кнопку Connect + SQL).
Процесс выполнения отображается в окне memLog, а результаты запроса -
в окне SG1: TStringGrid; Т е на этой форме задаем параметры подключения и
выполняем произвольные запросы.

2. Форма: frmZapros, модуль unzapros - для отображения примеров запросов
и копирования их в окошко memSQL (где их можно подредактировать).
Примеры запросов отображаются при щелчке по кнопке Запросы.
Свои примеры Вы можете добавить в файл zaprosi.txt

3. Форма: frmUserShow, модуль unusershow - отображает записи таблицы
User, показывая картинки (фото юзера) и позволяет редактировать каждую
запись (при этом можно заменить картинку - из файла на диске). Можно также
добавлять записи в эту таблицу и удалять (текущую запись).
Дополнительные возможности: сохранить картинку их формы на диск, очистить
картинку на форме, загрузить картинку (форматы: jpeg, png, bmp и др,
но не gif) с диска, менять масштаб. Окошко Memo показывает MIME-base64
кодировку картинки - при обновлении и добавлении записи (вероятно, лучше
это убрать).

4. Тексты исходников (*.pas, *.lfm) хранятся в кодировке UTF8. Лазарус
может перекодировать в другие кодировки (прав щелчок в окне редактора
| Параметры файла | Кодировка: установить кодировку. Затем выбрать
в диалоге: изменить файл). Однако, если перекодировать, например, в ANSI
(cp1251), то в *.pas придется применять функцию AnsiToUTF8 при выводе
в Memo, диалоговые окна и другие контролы. Похоже, Лазарус предпочитает
UTF8. Но кодировку UTF8 читает блокнот(WinXP), так что проблем с просмотром
исходников быть не должно.

5. (Для запуска проекта (файла .exe) требуется библиотека
libmysql.dll  которая входит в MySQL_Foto_Full.rar (можно скачать).
Для уменьшения размера полученного при компиляции .exe-файла в 15 раз 
создайте файл str.cmd:
E:\lazarus\fpc\2.2.4\bin\i386-win32\strip.exe %1
E:\lazarus\fpc\2.2.4\bin\i386-win32\upx.exe %1
(отредактируйте путь к Лазарусу и выполните команду:
str.cmd projmysql0.exe - при закрытом проекте.)
}

Текст процедуры  ConnectPlusSQL (главного модуля)
procedure TfrmMySQL5.ConnectPlusSQL;
 var ii,jj: integer; erik: longint;
 {Выполняет подключение к MySQL, запросы (2 или 3) и закрывает MySQL}
procedure byby;
begin   // действия при выходе из MySQL
  mysql_free_result (recbuf);
  mysql_close(sock);
end;
begin
  SG1.DefaultColWidth:= StrToInt(edWidth.Text);
  memLOg.Clear;
  mysql_init(PMySQL(@qmysql));
  Host:= PChar(edHost.Text);
  Login:= PChar(edLog.Text);
  DataBase:= PChar(edDB.Text);
  Pass:= PChar(edPass.Text);
  Query:= PChar(memSQL.Text);

  sock :=  mysql_real_connect(PMySQL(@qmysql),Host,Login,Pass,
  DataBase,0,nil,0);

  if sock=Nil then
    begin
      memLog.Lines.Append('Не могу подключиться к MySQL.');
      memLog.Lines.Append('Ошибка: '+mysql_error(@qmysql));
      byby; exit;
    end;

   memLog.Lines.Append('Подключние:');
   memLog.Lines.Append('Host info  : ' + mysql_get_host_info(sock));
   memLog.Lines.Append('Server info: ' + mysql_stat(sock));
   memLog.Lines.Append('Client info: ' + mysql_get_client_info);

  if mysql_select_db(sock,DataBase) < 0 then
    begin
      memLog.Lines.Append('Не могу выбрать базу данных'+Database);
      memLog.Lines.Append(mysql_error(sock));
      byby; exit;
    end else
     memLog.Lines.Append('Выбрана база данных: ' + DataBase);

  memLog.Lines.Append('Выполняю запрос: '+ Query);

  erik:= mysql_query(sock,Query);

    if ( erik <> 0) then
      begin
        memLog.Lines.Append('<<-- Не могу выполнить этот запрос -->>');
        memLog.Lines.Append('<<-- Ошибка: '+mysql_error(sock)+' -->>');
        byby; exit;
      end else
        memLog.Lines.Append(' Запрос выполнен ');

  recbuf := mysql_store_result(sock); // результат выполнения запроса
  if RecBuf=Nil then
    begin
      memLog.Lines.Append('Query returned nil result.');
      mysql_close(sock);
      byby; exit;
    end;

  NumRows1:= mysql_num_rows (recbuf);
  NumCols1:= mysql_num_fields(recbuf);

  memLog.Lines.Append('Результат: число строк = '
    + IntToStr(NumRows1));
  memLog.Lines.Append('Результат: число столбцов = '
   + IntToStr(NumCols1));

  SG1.RowCount:= NumRows1 + 1;
  SG1.ColCount:= NumCols1;

  for jj:= 0 to NumCols1 - 1 do  // имена колонок запроса добываю
    SG1.Cells[jj,0]:= mysql_fetch_field_direct(recbuf,jj)^.name;

  rowbuf := mysql_fetch_row(recbuf); // 1-я строка результата

  ii:=1;
  while (rowbuf <>nil) do
    begin
      for jj:= 0 to NumCols1 - 1 do
       SG1.Cells[jj,ii] := rowbuf[jj];
       rowbuf := mysql_fetch_row(recbuf); // следующая строка результата
       inc(ii);
    end;
 byby;
end;

- Показываю форму frmUserShow 
procedure TfrmMySQL5.btnUserClick(Sender: TObject);
begin
  frmUserShow.ConnectUser(PChar(''),PChar('select * from user limit ' +
     intToStr(nacalo) + ',1'));;
  frmUserShow.ShowModal; // показываю форму frmUserShow модально
end;

procedure TfrmMySQL5.btnZaprosClick(Sender: TObject);
begin
  frmZapros.Show; // показываю форму frmZapros немодально
end;

Заголовки функций (mysql_real_connect, mysql_get_host_info и т п) несложно найти: подвести текстовый курсор (в редакторе Lazarus) к термину и щелкнуть мышкой, удерживая нажатой Ctrl. (но при этом модуль, содержащий описание термина, должен присутствовать в uses). Описания специфических типов данных ( MYSQL_ROW, PMYSQL_RES, PMYSQL, MYSQL ) находятся так же, но приходится проследить цепочку ссылок и учитывать директивы {$IFDEF **}


На форме frmUserShow для просмотра данных выполняется только 1 запрос: Query:= PChar('select * from user limit ' + IntToStr(nacalo) + ',1'); - для просмотра 1 записи - со смещением nacalo от начала таблицы. Поля этой записи хранятся в структуре rowbuf2 и выводятся в окошки Edit и (картинка - поле Foto) - в Image1. Почему-то rowbuf2[0] доступо только в методе Pokazz. Там копирую IDStr:= rowbuf2[0]; и в дальнейшем использую IDStr. Вероятно, со временем причина найдется.


Форма просмотра таблицы user

Скачать RAR-архив исходников + .exe + база данных lab3_2 (в папке lab3_2) + libmysql.dll (MySQL_Foto_Full.rar - 1.2 Мб)

Распакуйте архив в папку и откройте projmysql0.lpi - для работы с проектом
Проект должен открыться (если установлен Лазарус). Или запустите projmysql0.exe
( Предварительно поместите БД lab3_2 (папка lab3_2) в папку mysql5\data\ и запустите сервер MySQL. Я пользуюсь пакетом Denwer3, в который входит MySQL5 (скачать Denwer3 можно здесь)) ).
Rambler's Top100
Hosted by uCoz