Система управления банком данных: различия между версиями
Строка 166: | Строка 166: | ||
=== Интерфейс базы данных IDatabase === | === Интерфейс базы данных IDatabase === | ||
<source lang=cpp> | |||
uint32_t AddRef(); | |||
</source> | |||
Функция, выполняющая инкремент счетчика ссылок, связанного с базой данных. | |||
Возвращаемое значение: | |||
Результирующее значение счетчика. | |||
<source lang=cpp> | |||
uint32_t Release(); | |||
</source> | |||
Функция, выполняющая декремент счетчика ссылок, связанного с сервером, а также удаление объекта из памяти, если счетчик в результате декремента достигает нуля. | |||
Возвращаемое значение: | |||
Результирующее значение счетчика. | |||
<source lang=cpp> | |||
return_code_t GetGroup(/*in, zero_terminated*/ const char* group_name, /*out*/ IGroup** group); | |||
</source> | |||
Функция, создающая и возвращающая экземпляр объекта, ассоциированного с существующей группой элементов данных в БД. Если группа не существует в БД, функция завершается с ошибкой <code>-ENOENT</code>. | |||
Параметры: | |||
* <code>group_name</code> C-строка, задающая уникальное в пределах базы данных имя группы. | |||
* <code>group</code> Указатель, на выходе получающий экземпляр компонента, ассоциированного с указанной группой. Если функция завершается с ошибкой, указатель должен быть установлен в нулевое значение. | |||
<source lang=cpp> | |||
return_code_t CreateGroup(/*in, zero_terminated*/ const char* group_name); | |||
</source> | |||
Функция, создающая пустую группу с заданным именем, которое должно быть уникальным среди существующих групп базы данных. Если имя не уникально, функция завершается с ошибкой <code>-EEXIST</code>. | |||
Параметры: | |||
* <code>group_name</code> C-строка, задающая уникальное в пределах базы данных имя группы | |||
<source lang=cpp> | |||
return_code_t EnumerateGroups(/*out*/IEnumGroups** enumeration); | |||
</source> | |||
Функция, создающая объект-перечисление групп базы данных. | |||
Параметры: | |||
* <code>enumeration</code> Возвращаемый пользователю экземпляр перечисления групп. | |||
<source lang=cpp> | |||
return_code_t GetGroupCount(/*out*/uint32_t* group_count); | |||
</source> | |||
Функция, возвращающая через выходной параметр количество групп, существующих в базе данных. | |||
Параметры: | |||
* <code>group_count</code> Указатель на 32-битовое целое, в который записывается число групп в базе данных. | |||
<source lang=cpp> | |||
return_code_t AccessCheck(uint32_t access_mask); | |||
</source> | |||
Функция, реализующая проверку наличия доступа вызывающего клиента к базе данных в соответствии с заданной маской. | |||
Параметры: | |||
* <code>access_mask</code> 32-битовая маска флагов, задающих проверяемый доступ. | |||
Возвращаемые значения: | |||
Нулевое, если доступ разрешен, <code>EACCES</code> - если разрешен. В случае ошибки возвращается отрицательное значение. | |||
=== Клиенский интерфейс обработчика событий IDatabaseEventSrc === | === Клиенский интерфейс обработчика событий IDatabaseEventSrc === |
Версия 21:21, 13 июля 2015
Требования
СУБД должна предоставлять программный и пользовательский интерфейс, имеющий семантику иерархической структуры "сервер-база данных-группа-элемент". Реализация СУБД должна быть ориентирована на массовые параллельные запросы от большого числа клиентов на чтение.
Существующая реализация подсистем системы моделирования основывается на интерфейсе, представленном в монографии, а также реализации СУБД в проекте amdb_outer, залитом в репозиторий. Поэтому требования к интерфейсу, представленные ниже, основаны на существующей реализации, но немного адаптированы под новые условия: убран COM, и зависимость от Windows на уровне интерфейса.
Общие требования
- Интерфейс должен предоставляться so/dll-библиотекой, выполняющей роль внутрипроцессного прокси сервера, работающего на стороне клиента, и выполняющего функции по формированию SQL-запросов.
- Интерфейсы реализуются в виде абстрактных классов (что соответствует понятию интерфейса в большинстве ООП языков), имеющих чисто виртуальные методы, реализованные прокси-сервером.
- Все параметры - как входные, так и выходные - должны быть параметрами, но не возвращаемым значением. Все методы, кроме методов
AddRef
иRelease
, реализующих подсчет ссылок, должны возвращать целочисленный 32-битовый код ошибки/успеха. - Отрицательные значения кодов ошибок должны соответствовать об ошибке выполнения запроса (возникающей на участке от прокси-сервера до СУБД и обратно), положительные значения должны переносить код завершения, считающегося успешным. При этом абсолютное значение модуля кода ошибки должно быть задано в терминах POSIX, а численные значения должны быть определены в интерфейсе СУБД и быть одинаковыми на клиенте и сервере.
- Строковые параметры должны завершаться нулем.
- Интерфейсные методы не должны генерировать исключения и использовать другие языковые конструкции кроме указанных выше. Разрешается использование наследования.
- При передаче входного параметра метода прокси-серверу ответственность за управление соответствующей памятью лежит на клиенте.
- Память, выделенная на этапе "прокси сервер-СУБД" должна освобождаться на этом же этапе, если она не передается клиенту прокси-сервера.
- Выходные параметры, память для хранения которых выделяется прокси-сервером, должны освобождаться клиентом посредством статического вызова
FreeData
интерфейсаIServerControl
либо вызовомRelease
полученного от сервера компонента.
Ниже представлено описание требуемых интерфейсов СУБД и их методов в контексте клиента прокси-сервера и с использованием синтаксиса C++, соответствующего более общему (независимому от языка) синтаксису, используемому на диаграмме.
Вспомогательные типы данных
#include <cstdint>
typedef std::uint64_t IDENTIFIER_TYPE;
Беззнаковый целочисленный 64-битовый тип данных, являющийся идентификатором элементов данных БД. Является детерминированной функцией от имени элемента. Возможно, в будущем мы обойдемся без него.
#include <cstdint>
typedef std::int32_t return_code_t;
Целочисленный знаковый 4-байтовый тип кода ошибки, возвращаемого интерфейсными функциями.
#define UUID_SIZE 16
typedef struct {char data[UUID_SIZE];} UUID;
UUID.
Интерфейс сервера IServerControl
Интерфейс служит для получения доступа к конкретной базе данных из возможного доступа. При этом определен статический метод для получения доступа к самому серверу.
Статические методы
return_code_t GetDBMSInstance(/*in, zero_terminated*/ const char* address, /*in*/ const UUID& impl_id, /*out*/ IServerControl** pServer);
Функция, создающая на стороне клиента экземпляр основного компонента, ассоциированного с удаленной СУБД.
Параметры:
address
IP-адрес и порт сервера баз данных, выраженные C-строкой в формате "адрес:порт".impl_id
Идентификатор реализации СУБД. Пока можно игнорировать.pServer
Выходной параметр, в который записывается экземпляр, ассоциированный с СУБД.
return_code_t FreeData(/*in*/ const void* data);
Функция, выполняющая освобождение памяти, выделенной прокси-сервером
Параметры:
data
Данные, выделенные прокси-сервером и возвращенные клиенту.
Методы
uint32_t AddRef();
Функция, выполняющая инкремент счетчика ссылок, связанного с сервером.
Возвращаемое значение:
Результирующее значение счетчика.
uint32_t Release();
Функция, выполняющая декремент счетчика ссылок, связанного с сервером, а также удаление объекта из памяти, если счетчик в результате декремента достигает нуля.
Возвращаемое значение:
Результирующее значение счетчика.
return_code_t OpenDatabase(/*in, zero_terminated*/ const char* database_name, /*in, zero_terminated*/ const char* principal_name, /*in, zero_terminated*/ const char* password, /*out*/ IDatabase** pDB);
Функция, выполняющая открытие базы данных с доступом, соответствующим роли клиента, а также создающая на стороне клиента экземпляр компонента, ассоциированного с базой данных.
Параметры:
database_name
Строка, задающая уникальное (в пределах сервера) имя открываемой базы данных.principal_name
Логин пользователя, от имени которого делается вызов.password
Пароль пользователя, от имени которого делается вызов.pDB
Выходной параметр, в который записывается экземпляр, ассоциированный с базой данных.
return_code_t CreateDatabase(/*in, zero_terminated*/ const char* database_name, /*in, zero_terminated*/ const char* principal_name, /*in, zero_terminated*/ const char* password, std::uint64_t db_type_id, std::uint32_t type_version, /*out*/ IDatabase** pDB);
Функция, выполняющая создание базы данных с полным доступом к ней клиента, а также создающая на стороне клиента экземпляр компонента, ассоциированного с созданной базой данных.
Параметры:
database_name
Строка, задающая уникальное (в пределах сервера) имя создаваемой базы данных.principal_name
Логин пользователя, от имени которого делается вызов.password
Пароль пользователя, от имени которого делается вызов.db_type_id
Целочисленный идентификатор типа базы данных. Пока можно игнорировать, но лучше записывать это значение как метаинформацию о созданной базе данных, например в заголовок файла.type_version
Целочисленный идентификатор версии типа базы данных. Пока можно игнорировать, но лучше записывать это значение как метаинформацию о созданной базе данных, например в заголовок файла.pDB
Выходной параметр, в который записывается экземпляр, ассоциированный с базой данных.
return_code_t DeleteDatabase(/*in, zero_terminated*/ const char* database_name, /*in, zero_terminated*/ const char* principal_name, /*in, zero_terminated*/ const char* password);
Функция, выполняющая удаление базы данных, если на это имеется доступ у пользователя, от имени которого делается вызов. Если на удаляемую базу данных на момент вызова функции ссылаются клиенты (т.е. у клиентов существуют открытые экземпляры IDatabase
), функция должна завершаться с возвращаемой ошибкой -EPERM
.
Параметры:
database_name
Строка, задающая уникальное (в пределах сервера) имя удаляемой базы данных.principal_name
Логин пользователя, от имени которого делается вызов.password
Пароль пользователя, от имени которого делается вызов.
return_code_t SetDatabaseSecurity(/*in, zero_terminated*/ const char* database_name, /*in, zero_terminated*/ const char* principal_name, /*in, zero_terminated*/ const char* password, /*in, byte_size(dacl_size)*/ const void* dacl, std::uint32_t dacl_size);
Функция, устанавливающая разграничительный список контроля доступа (DACL) к базе данных для ролей пользователей. Реализацию функции можно пока отложить.
Параметры:
database_name
Строка, задающая уникальное (в пределах сервера) имя базы данных.principal_name
Логин пользователя, от имени которого делается вызов.password
Пароль пользователя, от имени которого делается вызов.dacl
Указатель на бинарное представление DACL размером dacl_size.dacl_size
Байтовый размер DACL.
return_code_t GetDatabaseSecurity(/*in, zero_terminated*/ const char* database_name, /*in, zero_terminated*/ const char* principal_name, /*in, zero_terminated*/ const char* password, /*out, byte_size(dacl_size)*/ void** dacl, /*out*/ std::uint32_t* dacl_size);
Функция, возвращающая разграничительный список контроля доступа (DACL) к базе данных вызывающему пользователю. Реализацию функции можно пока отложить.
Параметры:
database_name
Строка, задающая уникальное (в пределах сервера) имя базы данных.principal_name
Логин пользователя, от имени которого делается вызов.password
Пароль пользователя, от имени которого делается вызов.dacl
Указатель на память, на выходе принимающий адрес буфера, в который записывается бинарное представление DACL базы данных.dacl_size
Байтовый размер DACL.
Интерфейс базы данных IDatabase
uint32_t AddRef();
Функция, выполняющая инкремент счетчика ссылок, связанного с базой данных.
Возвращаемое значение:
Результирующее значение счетчика.
uint32_t Release();
Функция, выполняющая декремент счетчика ссылок, связанного с сервером, а также удаление объекта из памяти, если счетчик в результате декремента достигает нуля.
Возвращаемое значение:
Результирующее значение счетчика.
return_code_t GetGroup(/*in, zero_terminated*/ const char* group_name, /*out*/ IGroup** group);
Функция, создающая и возвращающая экземпляр объекта, ассоциированного с существующей группой элементов данных в БД. Если группа не существует в БД, функция завершается с ошибкой -ENOENT
.
Параметры:
group_name
C-строка, задающая уникальное в пределах базы данных имя группы.group
Указатель, на выходе получающий экземпляр компонента, ассоциированного с указанной группой. Если функция завершается с ошибкой, указатель должен быть установлен в нулевое значение.
return_code_t CreateGroup(/*in, zero_terminated*/ const char* group_name);
Функция, создающая пустую группу с заданным именем, которое должно быть уникальным среди существующих групп базы данных. Если имя не уникально, функция завершается с ошибкой -EEXIST
.
Параметры:
group_name
C-строка, задающая уникальное в пределах базы данных имя группы
return_code_t EnumerateGroups(/*out*/IEnumGroups** enumeration);
Функция, создающая объект-перечисление групп базы данных.
Параметры:
enumeration
Возвращаемый пользователю экземпляр перечисления групп.
return_code_t GetGroupCount(/*out*/uint32_t* group_count);
Функция, возвращающая через выходной параметр количество групп, существующих в базе данных.
Параметры:
group_count
Указатель на 32-битовое целое, в который записывается число групп в базе данных.
return_code_t AccessCheck(uint32_t access_mask);
Функция, реализующая проверку наличия доступа вызывающего клиента к базе данных в соответствии с заданной маской.
Параметры:
access_mask
32-битовая маска флагов, задающих проверяемый доступ.
Возвращаемые значения:
Нулевое, если доступ разрешен, EACCES
- если разрешен. В случае ошибки возвращается отрицательное значение.