Sources
Delphi Russian Knowledge Base
DRKB - база знаний по Дельфи в рунете, составленная Виталием Невзоровым

Advantage Database Server

01.01.2007
Vyacheslav

Краткое описание

Advantage Database Server (ADS) - разработка фирмы Extended System, Inc (http://www.AdvantageDatabase.com). Развивается с начала 90-x годов. Первоначально была известен как Advantage X-Base Server и предназначался для работы в клиент-серверном режиме с таблицами формата dbf(Clipper, Foxpro) и базировался до 4 версии только на Novell платформе. К отличительной особенностью является использование ISAМ(indexed sequentil access method) - индексный последовательный метод доступа. С версии 5.0 появилась версия для NT и добавлен собственный форма таблиц, а с версии 5.5 поддерживается SQL. В настоящее время выпущена версия с номером 7.0

Возможности

Небольшое отступление: ADS с таблицами работает в двух режимах Free Tables и Database. Режим Free Tables предполагает работу с таблицами как с отдельными несвязанными с друг другом структурными единицами. При режиме Database группа таблиц рассматривается как единая база данных со всеми вытекающими последствиями. Открыть таблицу, входящую в Database как самостоятельную таблицу в режиме Free Tables невозможно.

Формат DBF

Формат ADT

Для обоих форматов

Пример AEP

////////////////////////////////////////////////////////////////////////////
// ## Назначение: Точка входа хранимой процедуры "Обновление справочника серий"
// ## Описание:
// ## Аргументы:  Параметры  хранимой процедуры:
// ##             Входные: Нет
// ##             Выходные: Таблица со списком новых серий
// ##             ID integer      - идентификатор записи,
// ##             Grup char(5)    - группа,
// ##             NNum char(13)   - номенклатурный номер,
// ##             Name char(34)   - наименование сертификата,
// ##             Series char(25) - серия
// ## Возврат:    Код ошибки
// ## Исключения: нет
extern "C" UNSIGNED32 __declspec(dllexport) WINAPI RefreshSeries
(
  UNSIGNED32   a_ConnectionID, // Идентификатор сессии
  UNSIGNED8   *a_UserName,     // Имя пользователя (логин)
  UNSIGNED8   *a_Password,     // Пароль пользователя
  UNSIGNED8   *a_ProcName,     // Имя хранимой процедуры(не пользоваться:
                               // будет исключено в следующей версии
  UNSIGNED32   a_RecNum,       // Аргумент зарезервирован для тригера
  UNSIGNED8   *a_InpName,      // Имя таблицы входных аргументов хранимой процедуры
  UNSIGNED8   *a_OutName       // Имя таблицы  выходных аргументов хранимой процедуры
                               // или возращаемого курсора данных
)
{
  try
  {
      TModuleAEP* ModuleAEP = (TModuleAEP*)gAEPSessionMgr->GetDM(a_ConnectionID);
      ModuleAEP->ParamsReconnect((char*)a_InpName, (char*)a_OutName);
      ModuleAEP->RefreshSeries();
  }
  catch( EADSDatabaseError *E )
  {
      return E->ACEErrorCode;
  }
  return AE_SUCCESS;
}

void __fastcall TCertModuleAEP::RefreshSeries(void)
{
  try
  {
    FreeSeries_->Active = true;
    Series_->Active = true;
    NewSeries_->Active = true;
    try
    {
        Series_->Last();
        int LastID = Series_ID->AsInteger;
        NewSeries_->AdsCopyTableContents(Series_);
        Series_->Filter = Format("ID > %d",ARRAYOFCONST((LastID)));
        Series_->Filtered = true;
        Series_->AdsCopyTableContents(FreeSeries_);
        Series_->AdsCopyTableContents(Output_);
    }
    __finally
    {
        Series_->Filtered = false;
        Series_->Active = false;
        FreeSeries_->Active = false;
        NewSeries_->Active = false;
    }
  }
  catch(Exception& Exc)
  {
    Output_->Append();
    Output_->FieldByName("Name")->AsString = Exc.Message;
    Output_->Post();
  }
}

Наличие триггеров

Триггеры имеются с в режиме Database, начиная с версии 7.

Поддерживаются три вида триггеров: BEFORE, AFTER и INSTEAD OF.

Триггера могут быть написаны либо также как AEP, в виде dll, COM, либо они могут предствалять из себя SQL-выражение.

CREATE TRIGGER mytrigger ON orders AFTER DELETE
BEGIN
 INSERT INTO backup_orders SELECT * FROM __old;
END

CREATE TRIGGER mytrigger ON orders INSTEAD OF UPDATE
FUNCTION MyFunction IN ASSEMBLY MyAssembly.MyClass PRIORITY 2

Пример кода тригера INSTEAD OF INSERT, который заполняет поле при вставке новой записи значением GUID

library AutoGUID;
{$INCLUDE versions.inc}
{$IFDEF ADSDELPHI7_OR_NEWER}
{$WARN UNSAFE_TYPE OFF}
{$WARN UNSAFE_CODE OFF}
{$WARN UNSAFE_CAST OFF}
{$ENDIF}
uses
  SysUtils,
  Classes,
  ace,
  adscnnct,
  adsset,
  adsdata,
  adstable,
  COMobj;
// Utility Function Prototype
procedure SetError ( conn : TAdsConnection; code : UNSIGNED32; err : string ); forward;
// Sample Advantage Trigger function. If you change the name of this
// function, remember to also change the name in the exports list at the bottom
// of this file.
function InsertGUID
(
  ulConnectionID : UNSIGNED32; // (I) Unique ID identifying the user causing this trig
  hConnection    : ADSHANDLE;  // (I) Active ACE connection handle user can perform
                               //     operations on
  pcTriggerName  : PChar;      // (I) Name of the trigger object in the dictionary
  pcTableName    : PChar;      // (I) Name of the base table that caused the trigger
  ulEventType    : UNSIGNED32; // (I) Flag with event type (insert, update, etc.)
  ulTriggerType  : UNSIGNED32; // (I) Flag with trigger type (before, after, etc.)
  ulRecNo        : UNSIGNED32  // (I) Record number of the record being modified
) : UNSIGNED32;
{$IFDEF WIN32}stdcall;{$ENDIF}{$IFDEF LINUX}cdecl;{$ENDIF} // Do not change the prototype.
const
// In this case, the first field is the Primary Key field
//   in the base table that needs the AutoGUID value.
// This constant definition is necessary because
//   triggers don't take parameters.
  iGUIDfieldNum           : Integer = 0;
var
  oConn                   : TAdsConnection;
  oNewTable, oSourceTable : TAdsTable;
  iFieldNum               : Integer;
begin
  // Result is currently reserved and not used. Always return zero.
  Result := 0;
  // Allocate a connection object using an active connection, no need to open it after this.
  oConn := TAdsConnection.CreateWithHandle( nil, hConnection );
  try
    try
      oConn.Name := 'conn';
      oNewTable := TAdsTable.Create( nil );
      oNewTable.DatabaseName := oConn.Name;
      oNewTable.TableName := '__new';
      oNewTable.Open;
      oSourceTable := TAdsTable.Create( nil );
      oSourceTable.DatabaseName := oConn.Name;
      oSourceTable.TableName := pcTableName;
      oSourceTable.Open;
      oSourceTable.Insert;
      //  Copy all new field values over without posting.
      for iFieldNum := 0 to Pred(oSourceTable.FieldCount) do
        if not oNewTable.Fields[iFieldNum].IsNull then
            oSourceTable.Fields[iFieldNum].Value :=
            oNewTable.Fields[iFieldNum].Value
           else
            oSourceTable.Fields[iFieldNum].Clear;
      //  Now set the GUID field value to a GUID value.
      oSourceTable.Fields[iGUIDfieldNum].AsString := CreateClassID;
      oSourceTable.Post;
    except
      on E : EADSDatabaseError do
        SetError( oConn, E.ACEErrorCode, E.message );
      on E : Exception do
        SetError( oConn, 0, E.message );
    end;
  finally
    FreeAndNil(oSourceTable);
    FreeAndNil(oNewTable);
    FreeAndNil(oConn);
  end;
end;

// Utility function to return an error from a trigger.
procedure SetError
(
  conn : TAdsConnection;
  code : UNSIGNED32;
  err  : string
);
begin
  // Errors can be returned by placing a row into the __error table.
  conn.Execute( 'INSERT INTO __error VALUES( ' +
                 IntToStr( code ) +  ', ' + QuotedStr( err ) + ' )' );
end;
exports
InsertGUID;
begin
  // Because this DLL is used by a multi-threaded application (the Advantage
  // server), we must set the Delphi IsMultiThread global variable to TRUE.
  IsMultiThread := TRUE;
end.

Репликация и синхронизация, перенос данных, средства backup.

Встроенных механизмов в настоящее время нет, их появление запланировано в версии 8, но возможно использовании внешнего Advantage Replication, выполненного на основе сервера приложений этой же фирмы - OneBridge Mobile Groupware (ранее известного как XTNDConnect Server). Кстати этот репликатор может применяться как между серверам различных(других) фирм, так и для синхронизации баз данных между клиентом и сервером в режиме работы briefcase. Синхронизация может проходить по определенному алгоритму с заданием полей, приоритетов и правил разрешений конфликтов. Кроме того, по-скольку базы данных представляют собой набор файлов возможно использование стандартных файловых backup-систем.

Поддержка кластеров

В настоящее время поддержки кластеров нет. Запланировано в версии 7.1

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

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

Такую операцию можно сделать если

  1. базы данных расположены на одном сервере
  2. запрос направлен к локальному серверу и нужно к еще подключить таблицу(ы) от удаленного сервера.

В этом случае используется понятие Link, при создании которого указываеися алиас, путь к справочнику БД, имя пользователя и пароль, под которым происходит подключение. Если имя пользователя и пароль не задан, то подключение будет производится под тем же именем, под которым пользователь подключен к текущей.

В примерах backup и Link1 - линки к другим базам данных.

UPDATE Customers SET address = (
  SELECT address FROM backup.Customers b
  WHERE b.cust_id = Customers.cust_id
)

CREATE VIEW Link1_T1 AS
  SELECT cust_name FROM Link1.customers
  WHERE credit_limit > 50000

Кроме того, так как хранимые процедуры - это dll, COM или shared object, то посредством них можно обеспечить доступ к любым СУБД, например: подключиться к MS SQL, получить данные, вставить эти данные в набор, заполнить поля дополнительными данными из таблицы ADS, и этот набор вернуть в качестве результата работы AEP.

Можно, например, организовать цепочку вызовов процедур на удаленных серверах, например :

и т.д

Поддерживаемые типы данных

Формат DBF

Формат ADT

Поддерживаемые конструкции SQL

Кроме того имеется возможность получить с помощью SQL-выражения всю информацию по метаданным, используя системные псевдо таблицы.

Например, получение всех объектов из справочника БД:

SELECT * FROM system.objects

Справочник БД:

Поддержка транзакций

Есть.

Системы репортинга, в том числе для Web

Возможно использование других репортинговых систем: Crystal Report, Fast Report, Quick Report, Rave и д.р. Собственного репортинга, ориентированного на Web, нет.

Наличие собственного агента для выполнения заданий по расписанию

Нет.

Защита данных, шифрование

Возможно шифрование как отдельно взятых таблиц, так и шифрование базы данных в целом (вместе с метаданными).

Используется профессиональный 160-битный алгоритм шифрования.

Простота использования

Сам сервер после установки в администрировании не нужается. Адинистрирование необходимо только для текущего ведения (создание, реорганизация, модификация) баз данных и таблиц

Платформы

Версии продуктов, краткая характеристика отличий

Способы доступа

Previous page:
Прямой доступ к базе данных 1С
Top:
DRKB
Next page:
Berkeley DB