Files
qt5-legatus-legacy/Lts/Common/CodeGen/StructBuilder.h
T
2026-08-13 18:33:10 +02:00

347 lines
11 KiB
C++
Executable File

/**
* @RDE_HEADER@
* Build up struct informations for the generators
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include <QtCore/QString>
#include "XmlReader.h"
#include "codegen_export.h"
namespace NGL
{
class INGLLogger;
}
namespace CodeGen
{
class StructBuilder;
struct EaData
{
QString table;
QString column;
QString type;
QString toString() const
{
return table +
QLatin1Char(';') + column +
QLatin1Char(';') + type;
}
};
struct FullQualifiedColumnInformation : public ColumnInformation
{
QString table;
bool usedForInsert = false;
bool usedForView = false;
QString columnNameView;
QString getColumnNameView() const { return columnNameView.isEmpty() ? columnName : columnNameView; }
FullQualifiedColumnInformation() = default;
FullQualifiedColumnInformation(const ColumnInformation &ci, const QString &tableName)
: ColumnInformation(ci)
, table(tableName)
{}
QString toString() const
{
return table +
QLatin1Char(';') + columnName +
QLatin1Char(';') + datatype +
// QLatin1Char(';') + comment +
QLatin1Char(';') + (isPrimaryKey ? QLatin1String("true") : QLatin1String("false")) +
QLatin1Char(';') + (isForeignKey ? QLatin1String("true") : QLatin1String("false")) +
QLatin1Char(';') + (usedForInsert ? QLatin1String("true") : QLatin1String("false")) +
QLatin1Char(';') + (usedForView ? QLatin1String("true") : QLatin1String("false"));
}
};
class DataTypeInfo
{
public:
DataTypeInfo(const QString &name, bool isPod)
: m_name(name)
, m_isPod(isPod)
{}
virtual ~DataTypeInfo() = default;
virtual QString name() const { return m_name; }
virtual QString idlType() const = 0; // used in .idl file
virtual QString ddsType() const = 0; // used in generated code from rtiddsgen
virtual QString sqlType() const = 0; // used in sql statements
virtual QString cppType() const = 0; // used in our code
virtual QString cppTypeConstRef() const { return isPod() ? cppType() : QLatin1String("const ") + cppType() + QLatin1String(" &"); }
virtual bool isPod() const { return m_isPod; }
virtual bool isSequence() const { return false; }
virtual bool isStructure() const { return false; }
virtual QVector<QSharedPointer<DataTypeInfo>> member() const { return QVector<QSharedPointer<DataTypeInfo>>(); }
virtual QSharedPointer<DataTypeInfo> innerDataType() const { return QSharedPointer<DataTypeInfo>(); }
static QSharedPointer<DataTypeInfo> fromIdlDataType(const QString &name,
const QString &idlType,
StructBuilder *structBuilder,
const QString &svcName = QString());
protected:
const QString m_name;
const bool m_isPod;
};
struct IdlData : public IdlColumnInformation
{
QSharedPointer<DataTypeInfo> dataTypeInfo;
IdlData() = default;
explicit IdlData(const IdlColumnInformation &ci)
: IdlColumnInformation(ci)
{}
QString toString() const
{
return name +
QLatin1Char(';') + type +
// QLatin1Char(';') + comment +
QLatin1Char(';') + (isKey ? QLatin1String("true") : QLatin1String("false")) +
QLatin1Char(';') + (isOptional ? QLatin1String("true") : QLatin1String("false"));
}
};
struct CppData
{
QString structName;
QString memberName;
QString defaultValue;
bool usedForCppStruct = false;
bool usedForJson = false;
bool isReadOnly = false;
bool isOptional = false;
QString type;
QString ddsType; // = type, except for e.g. QByteArray
QString toVariantPre; // e.g. static_cast<int>(
QString toVariantPost; // e.g. .x())
QString fromVariantPre1; // before ' = '
QString fromVariantPre2; // after ' = '
QString fromVariantPost;
QString toJsonPre;
QString toJsonPost;
QString fromJsonPre2;
QString fromJsonPost;
QString toString() const
{
return structName +
QLatin1Char(';') + memberName +
QLatin1Char(';') + (usedForCppStruct ? QLatin1String("true") : QLatin1String("false")) +
QLatin1Char(';') + (isReadOnly ? QLatin1String("true") : QLatin1String("false")) +
QLatin1Char(';') + type +
QLatin1Char(';') + toVariantPre +
QLatin1Char(';') + toVariantPost +
QLatin1Char(';') + fromVariantPre1 +
QLatin1Char(';') + fromVariantPre2 +
QLatin1Char(';') + fromVariantPost;
}
};
struct MemberInformation
{
EaData ea;
FullQualifiedColumnInformation db;
CppData cpp;
bool isDdsKey = false;
QSharedPointer<ForeignKeyInformation> fk;
QSharedPointer<EnumInformation> enumeration;
QString toString() const
{
return ea.toString() + QLatin1Char(';') +
db.toString() + QLatin1Char(';') +
cpp.toString();
}
bool isEmpty() const
{
return ea.column.isEmpty();
}
};
struct CompleteStructInformation
{
QString structName;
QString viewName;
QSet<QSharedPointer<TableInformation> > tables;
QSharedPointer<TableInformation> primaryTable;
QVector<MemberInformation> member;
QVector<DbNotifcationInformation> dbNotifications;
bool hasStaticContent = false;
bool isEmpty() const
{
return primaryTable.isNull();
}
};
struct CompleteTopicTypeInformation final : public TopicTypeInformationBase
{
QString serviceName;
QVector<IdlData> members;
CompleteTopicTypeInformation() = default;
explicit CompleteTopicTypeInformation(const TopicTypeInformationBase &s)
: TopicTypeInformationBase(s)
{}
bool hasBaseValue() const { return !baseValueType.isEmpty(); }
bool isValid() const { return TopicTypeInformationBase::isValid() && !members.isEmpty(); }
};
struct CompleteTableInformation : public TableInformation
{
QVector<MemberInformation> columns;
explicit CompleteTableInformation(const TableInformation &o)
: TableInformation(o)
{}
CompleteTableInformation() = default;
bool isEmpty() const { return columns.isEmpty(); }
};
class CODEGEN_BASE_EXPORT StructBuilder
{
struct ColumnInformationEx : public ColumnInformation
{
QSharedPointer<TableInformation> table;
ColumnInformationEx() = default;
ColumnInformationEx(const ColumnInformation &o,
const QSharedPointer<TableInformation> &ti)
: ColumnInformation(o)
, table(ti)
{}
};
public:
struct ServiceTypeStruct
{
QString service;
QString type;
bool bIsSequence = false;
bool isExternalType() const { return !service.isEmpty(); }
bool isSequence() const { return bIsSequence; }
QString fqType() const { return service + QStringLiteral("::") + type; }
};
explicit StructBuilder(XmlReader *xmlReader);
~StructBuilder() = default;
bool buildStructures();
QVector<CompleteStructInformation> structInformations() const
{
return m_structInfos;
}
QVector<CompleteTopicTypeInformation> topicTypeInformations() const
{
return m_topicTypeInfos;
}
CompleteStructInformation structInformationByTableName(const QString &tableName) const;
EnumInformation enumInformationByType(const QString &type, bool checkExternals = true, bool verbose = true);
CompleteTopicTypeInformation topicTypeInformationByStructType(const QString &type, bool checkExternals = true);
CompleteTopicTypeInformation externalTopicTypeByStructType(const ServiceTypeStruct &sts);
QVector<EnumInformation> enumInformations() const
{
return m_enumInfos;
}
QMap<QString, CompleteTableInformation> getDbTables() const
{
return m_sqlTableInformations;
}
QMap<QString, ViewInformation> getDbViews() const
{
return m_sqlViewInformations;
}
bool needPoint3d() const
{
return m_needPoint3d;
}
bool needPgArrayInclude() const
{
return m_needPgArrayInclude;
}
CompleteTableInformation completeTableInformation(const CompleteTopicTypeInformation &ctti);
CompleteTableInformation getRecordingTopicTable(const QString &structName);
QMap<QString, CompleteTableInformation> getRecordingTopicTables();
QVector<QSharedPointer<DataTypeInfo> > getSerializeFromToJsonTopics() const;
bool fixupQVariantConversions(MemberInformation &mi) const;
Q_REQUIRED_RESULT static QString firstCharLowercase(const QString &txt);
Q_REQUIRED_RESULT static QString camelCaseString(const QString &in, bool bFirstUppercase = false);
Q_REQUIRED_RESULT static QString camelCaseToUnderline(const QString &in);
bool buildJSonStructureInformationFromIdlData(const CompleteTopicTypeInformation &ctti);
QMap<QString, QVector<MemberInformation>> jsonStructureInformation() const { return m_jsonStructureInformation; }
private:
bool handleEnum(const EnumInformation &ei);
bool handleTable(const ServiceStructInformation &ssi);
bool handleIdlStructInfo(const TopicTypeInformation &tti,
QVector<CompleteTopicTypeInformation> &destination,
const QString &svcName = QString());
bool loadExternalTopicType(const ServiceTypeStruct &sts);
bool getColumnsFromTable(const QString &tableName,
QVector<ColumnInformationEx> &columns,
QVector<QString> &tableNames) const;
bool fixupCustomDbDatatypes(MemberInformation &memberInfo, QVector<MemberInformation> &members);
bool fixupDatatypePoint2d(MemberInformation &memberInfo, QVector<MemberInformation> &members);
bool fixupDatatypePoint3d(MemberInformation &memberInfo, QVector<MemberInformation> &members);
bool fixupDatatypeIntegerArray(MemberInformation &memberInfo);
QVector<MemberInformation> buildDbTableInformationFromIdlData(const CompleteTopicTypeInformation &ctti,
const QString &tableName,
const QString &columnNamePrefix,
const QString &cppStructure);
void addToSerializeFromToJsonTopics(const QSharedPointer<DataTypeInfo> &toAdd);
CompleteTableInformation getRecordingTopicTable(const CompleteTopicTypeInformation &ctti,
const MemberInformation &miPrimaryKey);
MemberInformation getRecordPrimaryKey() const;
ServiceTypeStruct extractServiceAndTypeFromTypename(const QString &type);
void addToSqlTableInformation(const MemberInformation &mi);
private:
QVector<CompleteStructInformation> m_structInfos;
QVector<CompleteTopicTypeInformation> m_topicTypeInfos;
mutable QVector<CompleteTopicTypeInformation> m_externalTopicTypes;
QVector<EnumInformation> m_enumInfos;
QMap<QString, CompleteTableInformation> m_sqlTableInformations;
QMap<QString, ViewInformation> m_sqlViewInformations;
QSet<QString> m_sqlTableInformationsAlreadyAvailable;
QVector<QSharedPointer<DataTypeInfo>> m_serializeFromToJsonTopics;
QMap<QString, QVector<MemberInformation>> m_jsonStructureInformation;
bool m_needPoint3d; // need include of 'qpoint3d.h'
bool m_needPgArrayInclude; // need include of 'LtsUtilsCore/pgarray.h'
XmlReader *m_xmlReader;
NGL::INGLLogger &m_logger;
NGL::INGLLogger &m_loggerCSV;
};
} // namespace CodeGen