Создание, открытие и закрытие базы данных

Для создания и открытия баз данных предназначена пара функций: DatabaseOpen и DatabaseClose.

int DatabaseOpen(const string filename, uint flags)

Функция открывает или создаёт базу данных в файле с именем filename. Параметр может содержать не только имя, но и путь с вложенными папками относительно MQL5/Files (конкретного экземпляра терминала или в общей папке, см. флаги ниже). Расширение можно не указывать: при этом к имени по умолчанию добавляется ".sqlite".

Если в параметре filename указано значение NULL или пустая строка "", то база создается во временном файле, который будет автоматически удален после закрытия базы данных.

Если в параметре filename указана строка ":memory:", то база данных будет создана в памяти. Такая временная база будет автоматически удалена после закрытия.

Параметр flags содержит комбинацию флагов, описывающих дополнительные условия для создания или открытия базы, из перечисления ENUM_DATABASE_OPEN_FLAGS.

Идентификатор

Описание

DATABASE_OPEN_READONLY

Открыть только на чтение

DATABASE_OPEN_READWRITE

Открыть на чтение и запись

DATABASE_OPEN_CREATE

Создать файл на диске, если он не существует

DATABASE_OPEN_MEMORY

Создать базу данных в оперативной памяти

DATABASE_OPEN_COMMON

Файл находится в общей папке всех терминалов

Если в параметре flags не указан ни один из флагов DATABASE_OPEN_READONLY или DATABASE_OPEN_READWRITE, то будет использован флаг DATABASE_OPEN_READWRITE.

При успешном выполнении функция возвращает дескриптор базы данных, который затем используется в параметрах других функций для доступа к ней. В противном случае возвращается значение INVALID_HANDLE, а код ошибки можно узнать в _LastError.

void DatabaseClose(int database)

Функция DatabaseClose закрывает базу данных по её дескриптору, который был ранее получен из функции DatabaseOpen.

После вызова DatabaseClose все дескрипторы запросов, которые мы научимся создавать для открытой базы в следующих разделах, автоматически удаляются и становятся недействительными.

Функция ничего не возвращает, однако в случае передачи ей некорректного дескриптора установит _LastError в ERR_DATABASE_INVALID_HANDLE.

Начнем разрабатывать объектно-ориентированную обертку для баз данных в файле DBSQLite.mqh.

Класс DBSQLite обеспечит создание, открытие и закрытие баз данных. Позднее мы дополним его.

class DBSQLite
{
protected:
   const string path;
   const int handle;
   const uint flags;
   
public:
   DBSQLite(const string fileconst uint opts =
      DATABASE_OPEN_CREATE | DATABASE_OPEN_READWRITE):
      path(file), flags(opts), handle(DatabaseOpen(fileopts))
   {
   }
   
   ~DBSQLite(void)
   {
      if(handle != INVALID_HANDLE)
      {
         DatabaseClose(handle);
      }
   }
   
   int getHandle() const
   {
      return handle;
   }
   
   bool isOpen() const
   {
      return handle != INVALID_HANDLE;
   }
};

Обратите внимание, что база данных автоматически создается или открывается при создании объекта, и закрывается при его уничтожении.

С помощью данного класса напишем простой скрипт DBinit.mq5, который будет создавать или открывать указанную базу.

input string Database = "MQL5Book/DB/Example1";
   
void OnStart()
{
   DBSQLite db(Database);                   // создаем или открываем базу в конструкторе
   PRTF(db.getHandle());                    // 65537 / ok
   PRTF(FileIsExist(Database + ".sqlite")); // true / ok
}                                           // база закрывается в деструкторе

После первого запуска, при настройках по умолчанию, мы должны получить новый файл MQL5/Files/MQL5Book/DB/Example1.sqlite — это подтверждается в коде проверкой на существование файла. При последующих запусках с тем же именем скрипт просто открывает базу и выводит в журнал действующий дескриптор (некое целое число).