Генератор
Проектов

Проект utldbs

Проект демонстрирует использование SQL-базы данных.

В качестве основы этого проекта взят проект utlgbd или utldoc. Структура данных здесь та же самая - иерархия организация, сотрудник. Но в нашем случае данные создаются и хранятся не в документе в памяти программы, не в сетевой базе, а в реляционной базе данных.

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

Структура базы данных в отличие от типа-документа определяется в пакете типа database отдельным разделом после декларации типов. Таблицы задаются ключевым словом table, индексы - ключевым словом index.

После описания структуры базы можно описать произвольное количество именованных SQL-запросов. Каждый такой запрос начинается ключевым словом sql, после которого идет имя запроса, пара скобок с описанием входных и выходных параметров запроса. Далее располагается сам sql-запрос. Реализовано некоторое подмножество стандартного языка SQL. Входные и выходные параметры предваряются двоеточием.

В отличие от типового sql-запроса здесь принципиально разделены запросы select и cursor. Запрос select должен выдавать не более одного результата, иначе диагностируется ошибка. Запрос cursor может выдавать произвольное количество результатов, по мере обработки каждого результата можно выполнять другие запросы.

В проекте описаны две утилиты: utlfill - заполнение базы тестовыми данными и utlview - печать в консоли содержимого базы данных.

В данном проекте задействованы системные пакеты rand и rand_test для генерации случайных тестовых данных.

Файл utldbs.gen:

project utldbs
  /version="01.001"
  /firm="УСТ"
  /http="http://www.ustech.ru"
  /email="managers@ustech.ru"

database orgdbs

utility utlfill

utility utlview

dbsutility orgdbs_utl

Файл orgdbs.database:

database orgdbs;
  /driver=(dbd_sqlite)

type t_orgname : char8[100];
type t_addr : char8[100];
type t_phone : char8[30];
type t_empname : char8[100];
type t_org : struct
( t_orgname orgname,
  t_addr addr,
  t_phone phone
);
type t_emp : struct
( t_orgname orgname,
  t_empname empname1,
  t_empname empname2,
  t_empname empname3,
  t_addr addr,
  t_phone phone
);

table org : t_org;
table emp : t_emp;
index i_org on org(orgname);
index i_emp on emp(orgname,empname1,empname2,empname3);

sql org_cre
( t_orgname orgname,
  t_addr addr,
  t_phone phone
):
(
)
  insert into org values
  ( :orgname,
    :addr,
    :phone
  );

sql org_cur
(
):
( t_orgname orgname,
  t_addr addr,
  t_phone phone
)
  cursor for
  select
    *
  from
    org;

sql emp_cre
( t_orgname orgname,
  t_empname empname1,
  t_empname empname2,
  t_empname empname3,
  t_addr addr,
  t_phone phone
):
(
)
  insert into emp values
  ( :orgname,
    :empname1,
    :empname2,
    :empname3,
    :addr,
    :phone
  );

sql emp_cur
( t_orgname orgname0
):
( t_orgname orgname,
  t_empname empname1,
  t_empname empname2,
  t_empname empname3,
  t_addr addr,
  t_phone phone
)
  cursor for
  select
    *
  from
    emp
  where
    orgname = :orgname0;

Файл utlfill.utility:

utility utlfill:"UTLFILL"

proc fill(orgdbs.orgdbs porgs)
{ var
    int iorg;

  rand.init();

  for ( iorg := 0; iorg < 6; iorg += 1 )
  { var
      orgdbs.org_cre sql_org,
      int iemp;

    rand_test.firm8(sql_org.orgname);
    rand_test.addr8(false,sql_org.addr);
    rand_test.phone(sql_org.phone);
    orgdbs.org_cre_insert_err(porgs,sql_org);

    for ( iemp := 0; iemp < 8; iemp += 1 )
    { var
        orgdbs.emp_cre sql_emp;

      sql_emp.orgname := sql_org.orgname;
      rand_test.name8(sql_emp.empname1,sql_emp.empname2,sql_emp.empname3);
      rand_test.addr8(true,sql_emp.addr);
      rand_test.phone(sql_emp.phone);
      orgdbs.emp_cre_insert_err(porgs,sql_emp);
    }
  }

  orgdbs.commit(porgs);
}

main
{ varobj
    orgdbs.orgdbs porgs;

  porgs.d_exe8 := xutl.d_exe8;
  porgs.drvname := "dbd_sqlite";
  porgs.srvname := "";
  porgs.dbsname += "orgdbs_bas";
  porgs.usrname := "orgdbs_log";
  porgs.passwrd := "orgdbs_pas";
  porgs.datname := "orgdbs_bas";
  porgs.logname := "orgdbs_log";
  orgdbs.init(porgs);
  orgdbs.open(porgs);
  call fill(porgs);
  orgdbs.close(porgs);
  orgdbs.finish(porgs);
}

Файл utlview.utility:

utility utlview:"UTLVIEW"

proc view(orgdbs.orgdbs porgs)
{ var
    orgdbs.org_cur sql_org;

  orgdbs.org_cur_open_err(porgs,sql_org);

  for ( ; ; )
  { orgdbs.org_cur_fetch_err(porgs,sql_org);
    if ( porgs.sqlcode <> 0 )
      break;

    dprint(U"Наименование: ",sql_org.orgname,"\n");
    dprint(U"Адрес: ",sql_org.addr,"\n");
    dprint(U"Телефон: ",sql_org.phone,"\n");

    { var
        orgdbs.emp_cur sql_emp;

      sql_emp.orgname0 := sql_org.orgname;
      orgdbs.emp_cur_open_err(porgs,sql_emp);

      for ( ; ; )
      { orgdbs.emp_cur_fetch_err(porgs,sql_emp);
        if ( porgs.sqlcode <> 0 )
          break;

        dprint(U"  Наименование: ",sql_emp.orgname,"\n");
        dprint(U"  Фамилия: ",sql_emp.empname1,"\n");
        dprint(U"  Имя: ",sql_emp.empname2,"\n");
        dprint(U"  Отчество: ",sql_emp.empname3,"\n");
        dprint(U"  Адрес: ",sql_emp.addr,"\n");
        dprint(U"  Телефон: ",sql_emp.phone,"\n");
      }

      orgdbs.emp_cur_close_err(porgs,sql_emp);
    }
  }

  orgdbs.org_cur_close_err(porgs,sql_org);
  orgdbs.commit(porgs);
}

main
{ varobj
    orgdbs.orgdbs porgs;

  porgs.d_exe8 := xutl.d_exe8;
  porgs.drvname := "dbd_sqlite";
  porgs.srvname := "";
  porgs.dbsname += "orgdbs_bas";
  porgs.usrname := "orgdbs_log";
  porgs.passwrd := "orgdbs_pas";
  porgs.datname := "orgdbs_bas";
  porgs.logname := "orgdbs_log";
  orgdbs.init(porgs);
  orgdbs.open(porgs);
  call view(porgs);
  orgdbs.close(porgs);
  orgdbs.finish(porgs);
}
Скачать проект utldbs