Обсуждение статьи "SQLite: нативная работа с базами данных на SQL в MQL5" - страница 7

 
Renat Fatkhullin:

Завтра в бете 2840 будет:

  • версия SQLite 2.35.2

  • постоянный WAL режим, позволяющий работать с открытой базой из разных приложений (раньше MetaEditor не мог работать параллельно терминалу).

Очень радует, спасибо
 
Edgar Akhmadeev:
Очень радует, спасибо

Бета 2840 доступна, попробуйте пожалуйста.

 
Renat Fatkhullin:

Завтра в бете 2840 будет:

  • версия SQLite 2.35.2

  • постоянный WAL режим, позволяющий работать с открытой базой из разных приложений (раньше MetaEditor не мог работать параллельно терминалу)

  • расширение статистический функций
    пример:
  • новые математические функции
  • JSON поддержку тоже включили

    В визард создания баз данных новый json тип включим позже.



Ренат, огромное спасибо!!! 
Не ожидал, что так быстро, очень обрадовали)))
 
fxsaber:

Кто разобрался, прошу показать реализацию такой задачи.

  1. Есть два Терминала.
  2. Нужно котиры одного символа с Терминала1 перекидывать реал-тайм в соответствующий кастомный символ Терминала2.
fxsaber:

В рамках этой задачи правильно ли понимаю, что в обоих случаях (при чтении базы на Терминале2 и записи в базу в Терминале1) нужно ее блокировать через механизм транзакций?

Как наиболее дешево определить, что база данных была обновлена?

Фундаментально неправильно. Вы описываете распределенное клиент-серверное приложение, со схемой 1 писатель, n читателей. При проектировании подобных систем (да и вообще любых распределенных систем) необходимо стараться избегать каких-либо блокировок, используя lock-free способы организации данных и доступ к ним. Если используемая технология не позволяет обойтись без блокировки, то возможно это вообще не лучшее решение для Вашей задачи. При этом для других задач технология может быть замечательной.
В Вашем случае лучше развернуть полноценный сервер (можно на той же машине что и клиент) и писать котировки в очередь сообщений, посмотрите в сторону Kafka, например. Клиент будет читать эти котировки с нужного индекса. Это lock-free схема доступа к данным.

fxsaber:

Получается, что обмен данными имеет меньше возможностей, чем через файлы?

Категорически нет. Обмен через файлы ни разу не атомарен, потому требует блокировок как на стороне читателя так и на стороне писателя. Это самый надежный способ получить deadlock и потеряться в отлавливании трудноуловимых и непонятных ошибках.

 
Vasiliy Sokolov:

Фундаментально неправильно. Вы описываете распределенное клиент-серверное приложение, со схемой 1 писатель, n читателей. При проектировании подобных систем (да и вообще любых распределенных систем) необходимо стараться избегать каких-либо блокировок, используя lock-free способы организации данных и доступ к ним. Если используемая технология не позволяет обойтись без блокировки, то возможно это вообще не лучшее решение для Вашей задачи. При этом для других задач технология может быть замечательной.
В Вашем случае лучше развернуть полноценный сервер (можно на той же машине что и клиент) и писать котировки в очередь сообщений, посмотрите в сторону Kafka, например. Клиент будет читать эти котировки с нужного индекса. Это lock-free схема доступа к данным.

Категорически нет. Обмен через файлы ни разу не атомарен, потому требует блокировок как на стороне читателя так и на стороне писателя. Это самый надежный способ получить deadlock и потеряться в отлавливании трудноуловимых и непонятных ошибках.

Спасибо за столь подробный ответ! К сожалению, я совсем забыл, какую тогда задачу решал. Поэтому не могу поделиться своими соображениями по теме.

 
Renat Fatkhullin:

Бета 2840 доступна, попробуйте пожалуйста.

Ренат, доброе утро!

Ещё заметил проблему в StringFormat, когда в нее помещается достаточно большая входная строка данных, например из файла ресурсов в котором имеется 3-4 постановки, например %d, %s, %lld, %s, я проверил несколько вариантов подстановок дело именно в большом объеме посещаемом в функцию, в результате возникает ошибка 4003

Временно перешёл в проектах на функцию StringReplace она корректно работает с большими данными во входной строке
 

Добрый день, уважаемые разработчики!

Функция "DatabaseExport" никак не хочет работать...выдает ошибку 5601 (ошибка выполнения запроса, но запрос я не выполняю) когда указываю имя таблицы в параметрах,

а когда указываю SQL запрос, то ошибка 4022 (отмена выполнения программы), возможно ошибка внутри MQL функции, часть кода из моей библиотеки:


//+------------------------------------------------------------------+
void CSQLite::DataBaseToFile(void)
  {
   uint flags=DATABASE_EXPORT_COMMON_FOLDER | DATABASE_EXPORT_QUOTED_STRINGS;

   long count_rows=0;

   string tables[],
          file_name,
          separator=";",
          query="SELECT name FROM sqlite_master WHERE tbl_name <> 'sqlite_sequence' AND type='table'";

   int total=GetValuesFromDataBase(query,tables); // ТУТ ВСЕ ОК, СПИСОК ТАБЛИЦ ИЗ БАЗЫ ПОЛУЧЕН.

   if(m_handle==NULL)
      Open();

   for(int i=0; i<total; i++)
     {
      file_name=StringFormat("%s.%s",m_name,tables[i]);
      count_rows=DatabaseExport(m_handle,tables[i],file_name,flags,separator); // ОШИБКА ПОСЛЕ ВЫПОЛНЕНИЯ ДАННОЙ ФУНКЦИИ
      Print(StringFormat("Export file: %s, rows: %lld",file_name,count_rows));

      if(count_rows<0)
         Print("DB: ", m_name,", Table: ",tables[i], ", Import failed with code ", GetLastError());
      else
         if(count_rows>0)
            Print(StringFormat("Import file: %s, rows: %lld",file_name,count_rows));
     }

   Finalize();
  }
//+------------------------------------------------------------------+
 

И вопрос №2:

Пытаюсь использовать функции ATTACH/DETACH, чтобы передать данные между БД встроенным механизмом SQLite, в результате ошибка транзакции 5601...

При выполнении этой же транзакции в SQLiteStudio, все отлично.

Это сделано специально или что-то не работает? 

   m_db.Create("IndiTemp","indi",m_db_main.GetStruct(),true);
   string db_path=StringFormat("%s\\Files\\%s.sqlite",
                               TerminalInfoString(TERMINAL_COMMONDATA_PATH),
                               "Indi");
                               
   string query=StringFormat("ATTACH DATABASE '%s' AS X; ",db_path),
          tables[];
          
   int total=m_db.GetTables(tables);
   if(total>0)
     {
      for(int i=0; i<total; i++)
         StringAdd(query,StringFormat("INSERT OR IGNORE INTO %s SELECT * FROM X.%s; ",tables[i],tables[i]));
     }
     
   StringAdd(query,"DETACH X; ");
   m_db.TransactionExecute(query);
 
Daniil Kurmyshev #:

Добрый день, уважаемые разработчики!

Функция "DatabaseExport" никак не хочет работать...выдает ошибку 5601 (ошибка выполнения запроса, но запрос я не выполняю) когда указываю имя таблицы в параметрах,

а когда указываю SQL запрос, то ошибка 4022 (отмена выполнения программы), возможно ошибка внутри MQL функции, часть кода из моей библиотеки:


К сожалению, функция DatabaseExport так и не получила функционал по экспорту таблицы (хотя изначально этот функционал предполагался) и на текущий момент поддерживает только запросы.

По ошибке 4022, Вы получаете её при тестировании, если да, то в тестере имеется ограничение на размер файла экспорта -  1GB общий размер записанных на диск данных ?

 
Daniil Kurmyshev #:

И вопрос №2:

Пытаюсь использовать функции ATTACH/DETACH, чтобы передать данные между БД встроенным механизмом SQLite, в результате ошибка транзакции 5601...

При выполнении этой же транзакции в SQLiteStudio, все отлично.

Это сделано специально или что-то не работает? 

Запрос должен работать, проверьте правильность путей
Причина обращения: