MQL5Book/Scripts/p7/DBmetaProgramming.mq5
super.admin 1c8e83ce31 convert
2025-05-30 16:09:41 +02:00

101 lines
3.4 KiB
MQL5

//+------------------------------------------------------------------+
//| DBmetaProgramming.mq5 |
//| Copyright 2022, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property description "Example of extraction of data type meta-information. Unfortunately it's not compatible with SQL binding facilities in MQL5."
#include "..\..\Include\Defines.mqh"
#include "..\..\Include\PRTF.mqh"
#include "..\..\Include\TypeName.mqh"
//+------------------------------------------------------------------+
//| Meta-information about DB table record based on object prototype |
//+------------------------------------------------------------------+
template<typename S>
struct DBEntity
{
template<typename T>
struct DBField
{
T f;
DBField(const string name, const string constraints = "")
{
Print(__FUNCSIG__);
Print(TYPENAME(T), " ", name);
const int n = EXPAND(prototype);
prototype[n][0] = TYPENAME(T);
prototype[n][1] = name;
prototype[n][2] = constraints;
}
};
static string prototype[][3]; // 0 - type, 1 - name, 2 - constraint
};
template<typename S>
static string DBEntity::prototype[][3];
#define DB_FIELD(T,N) struct T##_##N: DBField<T> { T##_##N() : DBField<T>(#N) { } } _##T##_##N;
/*
DB_FIELD expands to:
struct Type: DBField<Type>
{
Type_Name() : DBField<Type>(Name) { }
} _Type_Name;
*/
//+------------------------------------------------------------------+
//| Original test struct |
//+------------------------------------------------------------------+
struct Data
{
long id;
string name;
datetime timestamp;
double income;
};
//+------------------------------------------------------------------+
//| Original test struct |
//+------------------------------------------------------------------+
struct DataDB: public DBEntity<DataDB>
{
DB_FIELD(long, id);
DB_FIELD(string, name);
DB_FIELD(datetime, timestamp);
DB_FIELD(double, income);
} proto;
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
PRTF(sizeof(Data));
PRTF(sizeof(DataDB));
ArrayPrint(DataDB::prototype);
}
//+------------------------------------------------------------------+
/*
DBEntity<DataDB>::DBField<long>::DBField<long>(const string,const string)
long id
DBEntity<DataDB>::DBField<string>::DBField<string>(const string,const string)
string name
DBEntity<DataDB>::DBField<datetime>::DBField<datetime>(const string,const string)
datetime timestamp
DBEntity<DataDB>::DBField<double>::DBField<double>(const string,const string)
double income
sizeof(Data)=36 / ok
sizeof(DataDB)=36 / ok
[,0] [,1] [,2]
[0,] "long" "id" ""
[1,] "string" "name" ""
[2,] "datetime" "timestamp" ""
[3,] "double" "income" ""
*/
//+------------------------------------------------------------------+