Crear, abrir y cerrar bases de datos

Las funciones DatabaseOpen y DatabaseClose permiten crear y abrir bases de datos.

int DatabaseOpen(const string filename, uint flags)

La función abre o crea una base de datos en un archivo denominado filename. El parámetro puede contener no sólo el nombre, sino también la ruta con subcarpetas relativa a MQL5/Files (de una instancia de terminal específica o en una carpeta compartida, véanse las banderas más abajo). La extensión puede omitirse, lo que añade «.sqlite» al nombre por defecto.

Si se especifica NULL o una cadena vacía «» en el parámetro filename, la base de datos se crea en un archivo temporal, que se borrará automáticamente después de cerrar la base de datos.

Si se especifica la cadena «:memory:» en el parámetro filename, la base de datos se creará en memoria. Dicha base temporal se borrará automáticamente tras el cierre.

El parámetro flags contiene una combinación de banderas que describen condiciones adicionales para crear o abrir una base de datos de la enumeración ENUM_DATABASE_OPEN_FLAGS.

Identificador

Descripción

DATABASE_OPEN_READONLY

Abrir sólo para lectura

DATABASE_OPEN_READWRITE

Abrir para lectura y escritura

DATABASE_OPEN_CREATE

Crear un archivo en disco si no existe

DATABASE_OPEN_MEMORY

Crear una base de datos en memoria

DATABASE_OPEN_COMMON

El archivo se encuentra en la carpeta compartida de todos los terminales

Si no se especifica ninguno de los indicadores DATABASE_OPEN_READONLY o DATABASE_OPEN_READWRITE en el parámetro flags, se utilizará el indicador DATABASE_OPEN_READWRITE.

En caso de éxito, la función devuelve un manejador a la base de datos, que luego se utiliza como parámetro para que otras funciones accedan a ella. En caso contrario, se devuelve INVALID_HANDLE, y el código de error se puede encontrar en _LastError.

void DatabaseClose(int database)

La función DatabaseClose cierra la base de datos por su manejador, recibido previamente de la función DatabaseOpen.

Después de llamar a DatabaseClose, todos los manejadores de consulta que aprenderemos a crear para una base abierta en las siguientes secciones se eliminan e invalidan automáticamente.

La función no devuelve nada. Sin embargo, si se le pasa un manejador incorrecto, establecerá _LastError en ERR_DATABASE_INVALID_HANDLE.

Empecemos a desarrollar un envoltorio orientado a objetos para bases de datos en un archivo DBSQLite.mqh.

La clase DBSQlite garantizará la creación, apertura y cierre de bases de datos. Lo ampliaremos más adelante.

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;
   }
};

Tenga en cuenta que la base de datos se crea o se abre automáticamente cuando se crea el objeto, y se cierra cuando se destruye el objeto.

Usando esta clase, vamos a escribir un script DBinit.mq5 sencillo, que creará o abrirá la base de datos especificada.

input string Database = "MQL5Book/DB/Example1";
   
void OnStart()
{
   DBSQLite db(Database);                   // create or open the base in the constructor
   PRTF(db.getHandle());                    // 65537 / ok
   PRTF(FileIsExist(Database + ".sqlite")); // true / ok
// the base is closed in the destructor

Tras la primera ejecución, con la configuración por defecto, deberíamos obtener un nuevo archivo MQL5/Files/MQL5Book/DB/Example1.sqlite. Esto se confirma en el código comprobando la existencia del archivo. En ejecuciones posteriores con el mismo nombre, el script simplemente abre la base de datos y registra el descriptor actual (un número entero).