Discussion de l'article "SQLite Gestion native des bases de données SQL dans MQL5" - page 7

 
Renat Fatkhullin:

Il sera de 2840 dans la version bêta demain :

  • Version SQLite 2.35.2

  • mode WAL permanent, permettant de travailler avec une base de données ouverte depuis différentes applications (auparavant MetaEditor ne pouvait pas travailler en parallèle avec le terminal).

Très heureux, merci
 
Edgar Akhmadeev:
Très heureux, merci

La Beta 2840 est disponible, n'hésitez pas à l'essayer.

 
Renat Fatkhullin:

Il sera de 2840 dans la version bêta demain :

  • Version SQLite 2.35.2

  • mode WAL permanent, permettant de travailler avec une base de données ouverte à partir de différentes applications (auparavant MetaEditor ne pouvait pas travailler en parallèle avec le terminal)

  • extension des fonctions statistiques
    exemple :
  • nouvelles fonctions mathématiques
  • Lesupport JSON est également inclus

    Nous inclurons le nouveau type json dans l'assistant de création de base de données plus tard.



Renat, merci beaucoup !!!
Je ne m'attendais pas à ce que ce soit aussi rapide, j'en suis très heureux))))))
 
fxsaber:

Si quelqu'un a trouvé la solution, qu'il nous montre la mise en œuvre d'une telle tâche.

  1. Il y a deux terminaux.
  2. Il est nécessaire de transférer les cotations en temps réel d'un symbole du terminal 1 vers le symbole personnalisé correspondant du terminal 2.
fxsaber:

Dans le cadre de cette tâche, ai-je bien compris que dans les deux cas (lors de la lecture de la base sur Terminal2 et de l'écriture dans la base sur Terminal1), cela doit être bloqué par le mécanisme de transaction?

Quel est le moyen le plus économique de déterminer que la base de données a été mise à jour ?

C'est fondamentalement faux. Vous décrivez une application client-serveur distribuée, avec un schéma de 1 écrivain, n lecteurs. Lors de la conception de tels systèmes (et de tout système distribué en général), il convient d'essayer d'éviter les verrous en utilisant des méthodes d'organisation des données et d'accès à celles-ci qui ne soient pas soumises à des verrous. Si la technologie utilisée ne permet pas d'éviter les verrous, il ne s'agit peut-être pas de la meilleure solution pour votre tâche. Cependant, pour d'autres tâches, la technologie peut être excellente.
Dans votre cas, il est préférable de déployer un serveur complet (vous pouvez le faire sur la même machine que le client) et d'écrire des citations dans la file d'attente des messages, comme Kafka, par exemple. Le client lira ces citations à partir de l'index requis. Il s'agit d'un schéma d'accès aux données sans verrou.

fxsaber:

Il s'avère donc que l'échange de données offre moins de possibilités que l'échange de fichiers ?

Catégoriquement non. Le partage via des fichiers n'est pas du tout atomique, il nécessite donc des verrous à la fois du côté du lecteur et du côté de l'auteur. C'est le moyen le plus sûr d'obtenir un blocage et de se perdre dans des erreurs difficiles à trouver et incompréhensibles.

 
Vasiliy Sokolov:

C'est fondamentalement faux. Vous décrivez une application client-serveur distribuée avec un schéma de 1 auteur, n lecteurs. Lors de la conception de tels systèmes (et de tout système distribué en général), il convient d'essayer d'éviter les verrous, en utilisant des méthodes d'organisation des données et d'accès à celles-ci qui ne soient pas soumises à des verrous. Si la technologie utilisée ne permet pas d'éviter les verrous, il ne s'agit peut-être pas de la meilleure solution pour votre tâche. Cependant, pour d'autres tâches, la technologie peut être excellente.
Dans votre cas, il est préférable de déployer un serveur complet (vous pouvez le faire sur la même machine que le client) et d'écrire des citations dans la file d'attente des messages, comme Kafka, par exemple. Le client lira ces citations à partir de l'index requis. Il s'agit d'un schéma d'accès aux données sans verrou.

Catégoriquement non. Le partage via des fichiers n'est en aucun cas atomique, il nécessite donc des verrous à la fois du côté du lecteur et du côté de l'auteur. C'est le moyen le plus sûr d'obtenir un blocage et de se perdre dans des erreurs difficiles à voir et incompréhensibles.

Merci pour cette réponse si détaillée ! Malheureusement, j'ai complètement oublié le problème que je résolvais à l'époque. C'est pourquoi je ne peux pas partager mes réflexions sur le sujet.

 
Renat Fatkhullin:

La version bêta 2840 est disponible, veuillez l'essayer.

Renat, bonjour !

J'ai également remarqué un problème dans StringFormat, lorsqu'une chaîne de données d'entrée assez importante y est placée, par exemple à partir d'un fichier de ressources avec 3-4 déclarations, par exemple %d, %s, %lld, %s, j'ai vérifié plusieurs variantes de substitution, il s'agit simplement d'un grand volume visité dans la fonction, ce qui entraîne l'erreur 4003.

J'ai temporairement adopté la fonction StringReplace dans les projets, qui fonctionne correctement avec des données volumineuses dans la chaîne d'entrée.
 
Apprentissage, merci pour le partage.
 
Il y a une erreur dans le fichier DataBasePrepare. Je remplacerais la "paire" par une chaîne de caractères, est-ce correct ?
 

Questions sur cette solution

- Y a-t-il des problèmes lorsque plusieurs EAs utilisent la même base de données sqlite simultanément ?

- Si MT5 tombe en panne, certaines données peuvent-elles être perdues ? Quelle est la fréquence d'écriture des données sur le disque ?

 

Bonjour, chers développeurs !

La fonction "DatabaseExport" ne veut en aucun cas fonctionner...elle donne l'erreur 5601 (query execution error, but I do not execute the query) quand je spécifie le nom de la table dans les paramètres,

et lorsque je spécifie la requête SQL, elle donne l'erreur 4022 (annulation de l'exécution du programme), probablement une erreur à l'intérieur de la fonction MQL, une partie du code de ma bibliothèque :


//+------------------------------------------------------------------+
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();
  }
//+------------------------------------------------------------------+