File indexing completed on 2024-04-28 16:30:34

0001 /***************************************************************************
0002  * SPDX-FileCopyrightText: 2022 S. MANKOWSKI stephane@mankowski.fr
0003  * SPDX-FileCopyrightText: 2022 G. DE BURE support@mankowski.fr
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  ***************************************************************************/
0006 #ifndef SKGSERVICES_H
0007 #define SKGSERVICES_H
0008 /** @file
0009  * This file defines classes SKGServices.
0010  *
0011  * @author Stephane MANKOWSKI / Guillaume DE BURE
0012  */
0013 #include <qurl.h>
0014 
0015 #include <qdatetime.h>
0016 #include <qhash.h>
0017 #include <qicon.h>
0018 #include <qstringlist.h>
0019 
0020 #include "skgbasemodeler_export.h"
0021 #include "skgdefine.h"
0022 #include "skgerror.h"
0023 
0024 /**
0025  * @var SQLLITEERROR
0026  * Must be used to generate a SKGError on an error coming from sqlite's API
0027  * Example of usage:
0028  * @code
0029  * int rc=QSqlDatabase_close ( currentDatabase );
0030  * if(rc!=SQLITE_OK) err=SKGError(SQLLITEERROR+rc, QSqlDatabase_errmsg(currentDatabase));
0031  * @see SKGError
0032  * @endcode
0033 
0034  */
0035 static const int SQLLITEERROR = 10000;
0036 
0037 class QSqlDatabase;
0038 class QTextStream;
0039 class QDomDocument;
0040 class SKGDocument;
0041 
0042 /**
0043  * A map of strings ==> SKGQStringQStringMap
0044  */
0045 using SKGQStringQStringMap = QHash<QString, QString>;
0046 
0047 /**
0048  * A list of QStringList ==> SKGStringListList
0049  */
0050 using SKGStringListList = QList<QStringList>;
0051 
0052 /**
0053  * A list of int ==> SKGIntList
0054  */
0055 using SKGIntList = QList<int>;
0056 
0057 /**
0058 * This class containing various static services
0059 */
0060 class SKGBASEMODELER_EXPORT SKGServices : public QObject
0061 {
0062     Q_OBJECT
0063 public:
0064     /**
0065      * Unit value
0066      */
0067     struct SKGUnitInfo {
0068         /** The name of the unit */
0069         QString Name;
0070         /** The amount of the unit */
0071         double Value = 0.0;
0072         /** The number of decimal of the unit*/
0073         int NbDecimal = 2;
0074 
0075         /** The symbol of the unit */
0076         QString Symbol;
0077         /** The country of the unit */
0078         QString Country;
0079         /** The Internet code of the unit */
0080         QString Internet;
0081         /** The download source */
0082         QString Source;
0083         /** The parent unit of the unit */
0084         QString Parent;
0085         /** The date of the unit */
0086         QDate Date;
0087         /** To know if the unit is obsolete or not */
0088         bool Obsolete = false;
0089     };
0090 
0091     /**
0092      * This structure defines attributes types
0093      */
0094     enum AttributeType {
0095         TEXT,       /**< Text */
0096         INTEGER,    /**< Integer */
0097         FLOAT,      /**< Float */
0098         DATE,       /**< Date */
0099         ID,         /**< Unique identifier */
0100         LINK,       /**< Link */
0101         BLOB,       /**< Blob */
0102         BOOL,       /**< Boolean (Y, N) */
0103         TRISTATE,   /**< Tri-state (N, P, C) */
0104         OTHER           /**< Other or undefined */
0105     };
0106 
0107     /**
0108      * This enumerate defines attributes types
0109      */
0110     Q_ENUM(AttributeType)
0111 
0112     /**
0113      * Describe an attribute
0114      */
0115     struct SKGAttributeInfo {
0116         QString name;           /**< The internal name of the attribute */
0117         QString display;        /**< The name for display of the attribute */
0118         QIcon icon;                 /**< The icon for display of the attribute */
0119         AttributeType type;         /**< The type of the attribute */
0120         bool notnull{};           /**< To know if the attribute can be null or not */
0121         QString defaultvalue;       /**< The default value of the attribute */
0122     };
0123 
0124     /**
0125      * Search criteria
0126      */
0127     struct SKGSearchCriteria {
0128         QChar mode;              /**< The mode '+' or '-' */
0129         QStringList words;       /**< The list of words */
0130     };
0131 
0132     /**
0133      * A list of SKGSearchCriteria ==> SKGAttributesList
0134      */
0135     using SKGSearchCriteriaList = QVector<SKGSearchCriteria>;
0136 
0137     /**
0138      * A list of SKGAttributeInfo ==> SKGAttributesList
0139      */
0140     using SKGAttributesList = QVector<SKGAttributeInfo>;
0141 
0142     /**
0143      * This enumerate defines dump modes
0144      */
0145     enum DumpMode {
0146         DUMP_CSV, /**< To dump in CSV mode */
0147         DUMP_TEXT  /**< To dump in DUMP_TEXT mode */
0148     };
0149 
0150     /**
0151      * This enumerate defines dump modes
0152      */
0153     Q_ENUM(DumpMode)
0154 
0155     /**
0156      * Get list of search criteria of a string (example: +cat1 -abc +auto)
0157      * @param iString a string to analyze
0158      * @return the search criteria list
0159      */
0160     static SKGServices::SKGSearchCriteriaList stringToSearchCriterias(const QString& iString);
0161 
0162     /**
0163      * Compute a SQL where clause with criteria and list of attributes
0164      * @param iSearchCriterias the list of criteria
0165      * @param iAttributes the list of attributes
0166      * @param iDocument if a document is given, this document will be used to find the synonym of attributes
0167      * @param iForDisplay to build the human readable string explaining the query
0168      * @return the where clause
0169      */
0170     static QString searchCriteriasToWhereClause(const SKGServices::SKGSearchCriteriaList& iSearchCriterias,
0171             const QStringList& iAttributes,
0172             const SKGDocument* iDocument,
0173             bool iForDisplay = false);
0174 
0175     /**
0176      * Get environment variable
0177      * @param iAttribute name of the variable
0178      * @return value of the variable
0179      */
0180     static QString getEnvVariable(const QString& iAttribute);
0181 
0182     /**
0183      * Convert a integer into a QString
0184      * @param iNumber the integer to convert
0185      * @return the converted QString
0186      */
0187     static QString intToString(qlonglong iNumber);
0188 
0189     /**
0190      * Convert a QString into an integer
0191      * @param iNumber the QString to convert
0192      * @return the converted integer
0193      */
0194     static qlonglong stringToInt(const QString& iNumber);
0195 
0196     /**
0197      * Convert a QString into a csv QString
0198      * @param iNumber the QString to convert
0199      * @return the converted csv string
0200      */
0201     static QString stringToCsv(const QString& iNumber);
0202 
0203     /**
0204      * Convert a QStringList into a csv QString
0205      * @param iList the QStringList to convert
0206      * @param iSeparator the separator
0207      * @return the converted csv string
0208      */
0209     static QString stringsToCsv(const QStringList& iList, QChar iSeparator = QLatin1Char(';'));
0210 
0211     /**
0212      * Convert a QString to a html QString
0213      * @param iString the QString to convert
0214      * @return the converted html string
0215      */
0216     static QString stringToHtml(const QString& iString);
0217 
0218     /**
0219      * Convert a html QString to a QString
0220      * @param iString the QString to convert
0221      * @return the converted string
0222      */
0223     static QString htmlToString(const QString& iString);
0224 
0225     /**
0226      * Convert a double into a QString
0227      * @param iNumber the double to convert
0228      * @return the converted QString
0229      */
0230     static QString doubleToString(double iNumber);
0231 
0232     /**
0233      * Convert a QString into an double
0234      * @param iNumber the QString to convert
0235      * @return the converted double
0236      */
0237     static double stringToDouble(const QString& iNumber);
0238 
0239     /**
0240      * Convert a QDateTime into a QString ready for sql order.
0241      * The output format is "%Y-%m-%d %H-%M-%S"
0242      * @param iDateTime the time
0243      * @return the converted QString
0244      */
0245     static QString timeToString(const QDateTime& iDateTime);
0246 
0247     /**
0248      * Convert a date in a period
0249      * @param iDate the time
0250      * @param iPeriod the period.
0251      * D for day, example: 2013-05-21
0252      * W for week, example: 2013-W10
0253      * M for month, example: 2013-05
0254      * Q for quarter, example: 2013-Q2
0255      * S for semester, example: 2013-S1
0256      * Y for year, example: 2013
0257      * @return the period string
0258      */
0259     // cppcheck-suppress passedByValue
0260     static QString dateToPeriod(QDate iDate, const QString& iPeriod);
0261 
0262     /**
0263      * Compute the number of working days between two dates.
0264      * @param iFrom first date
0265      * @param iTo seconde date
0266      * @return the number of working days.
0267      */
0268     // cppcheck-suppress passedByValue
0269     static int nbWorkingDays(QDate iFrom, QDate iTo);
0270 
0271     /**
0272      * Convert a QString to QDateTime.
0273      * @param iDateString the time. The format must be "%Y-%m-%d %H-%M-%S" or "%Y-%m-%d"
0274      * @return the converted QDateTime
0275      */
0276     static QDateTime stringToTime(const QString& iDateString);
0277 
0278     /**
0279      * Convert a QString to QDate.
0280      * @param iDateString the date string. Could be a partial date like 1/12.
0281      * @param iFixupBackward the date string is fixed in backward mode.
0282      * @return the converted QDate
0283      */
0284     static QDate partialStringToDate(const QString& iDateString, bool iFixupBackward = true);
0285 
0286     /**
0287      * Convert a QDateTime into a QString ready for sql order.
0288      * The output format is "%Y-%m-%d"
0289      * @param iDateTime the time
0290      * @return the converted QString
0291      */
0292     static QString dateToSqlString(const QDateTime& iDateTime);
0293 
0294     /**
0295      * Convert a QDate into a QString ready for sql order.
0296      * The output format is "%Y-%m-%d"
0297      * @param iDate the date
0298      * @return the converted QString
0299      */
0300     // cppcheck-suppress passedByValue
0301     static QString dateToSqlString(QDate iDate);
0302 
0303     /**
0304      * Format a date.
0305      * The output format is "YYYY-MM-DD"
0306      * @param iDate the QString representing the input date
0307      * @param iFormat the format of the input date. Must be in the following list:
0308      * "YYYYMMDD","DDMMYYYY", "MMDDYYYY" "YYYY-MM-DD"
0309      * "MM/DD/YY", "MM-DD-YY", "DD/MM/YY", "DD-MM-YY"
0310      * "MM/DD/YYYY", "MM-DD-YYYY", "DD/MM/YYYY", "DD-MM-YYYY"
0311      * "DD/MMM/YY" "DD-MMM-YY" DDMMMYY
0312      * "DD/MMM/YYYY" "DD-MMM-YYYY" DDMMMYYYY
0313      * @return the converted QString
0314      */
0315     static QString dateToSqlString(const QString& iDate, const QString& iFormat);
0316 
0317     /**
0318      * Get the sql where clause corresponding to a period date.
0319      * @param iPeriod the period date (some thing like "ALL" "2014" or "2014-04" or "2014-Q2" or "2014-S2"
0320      * @param iDateAttribute the date attribute
0321      * @param iComparator the sql comparator (= by default. But you can use < or >)
0322      * @return the where clause
0323      */
0324     static QString getPeriodWhereClause(const QString& iPeriod, const QString& iDateAttribute = QStringLiteral("d_date"), const QString& iComparator = QStringLiteral("="));
0325 
0326     /**
0327      * Get the last date of a period.
0328      * @param iPeriod the period date
0329      * @return the last date
0330      */
0331     static QDate periodToDate(const QString& iPeriod);
0332 
0333     /**
0334      * Get the neighboring period.
0335      * @param iPeriod the period date (some thing like "ALL" "2014" or "2014-04" or "2014-Q2" or "2014-S2"
0336      * @param iDelta the delta to apply (-1 = previous, +1 = next)
0337      * @return the neighboring period
0338      */
0339     static QString getNeighboringPeriod(const QString& iPeriod, int iDelta = -1);
0340 
0341     /**
0342      * Get the format of a list of string dates
0343      * @param iDates a list of string dates
0344      * @return the supported format of all of these dates.
0345      */
0346     static QString getDateFormat(const QStringList& iDates);
0347 
0348     /**
0349      * Get the string representing the percentage
0350      * @param iAmount the amount
0351      * @param iNbDecimal the number of decimals
0352      * @return the string.
0353      */
0354     static QString toPercentageString(double iAmount, int iNbDecimal = 2);
0355 
0356     /**
0357      * Get the string representing the amount
0358      * @param iAmount the amount
0359      * @param iSymbol the symbol
0360      * @param iNbDecimal the number of decimals
0361      * @return the string.
0362      */
0363     static QString toCurrencyString(double iAmount, const QString& iSymbol = QString(), int iNbDecimal = 2);
0364 
0365     /**
0366      * Return string ready for sql order
0367      * @param iString the string
0368      * @return the escaped string
0369      */
0370     static QString stringToSqlString(const QString& iString);
0371 
0372     /**
0373      * Split a csv line
0374      * @param iString the csv line
0375      * @param iSeparator the csv separator
0376      * @param iCoteDefineBlock to indicate if the character double cote define a block
0377      * @param oRealSeparator the real csv separator. If the csv string is strictly all enclosed then oRealSeparator will contain the real separator. Can be nullptr
0378      * @return the list of all values in this csv line. Return an empty list if some cote are opened and not closed
0379      */
0380     static QStringList splitCSVLine(const QString& iString, QChar iSeparator, bool iCoteDefineBlock, QChar* oRealSeparator);
0381 
0382     /**
0383      * Split a csv line
0384      * @param iString the csv line
0385      * @param iSeparator the csv separator
0386      * @param iCoteDefineBlock to indicate if the character double cote define a block
0387      * @return the list of all values in this csv line. Return an empty list if some cote are opened and not closed
0388      */
0389     static QStringList splitCSVLine(const QString& iString, QChar iSeparator = QLatin1Char(';'), bool iCoteDefineBlock = true);
0390 
0391     /**
0392      * To dump a table
0393      * @param iTable A table
0394      * @param iMode dump mode
0395      * @return the dump of the table
0396      */
0397     static QStringList tableToDump(const SKGStringListList& iTable, SKGServices::DumpMode iMode);
0398 
0399     /**
0400      * Get the table name corresponding to a table or a view
0401      * @param iTable table or view
0402      * @return table name corresponding
0403      */
0404     static QString getRealTable(const QString& iTable);
0405 
0406     /**
0407      * Copy a sqlite database from memory to file or from file to memory.
0408      * It is used to do a load or a save
0409      * @param iFileDb the sqlite pointer corresponding to a file database
0410      * @param iMemoryDb the sqlite pointer corresponding to  memory database
0411      * @param iFromFileToMemory
0412      *        true: the copy is done from iFileDb to iMemoryDb (needed of a load)
0413      *        false: the copy is done from iMemoryDb to iFileDb (needed of a save)
0414      * @param iPassword the password
0415      * @return An object managing the error
0416      *   @see SKGError
0417      */
0418     static SKGError copySqliteDatabase(const QSqlDatabase& iFileDb, const QSqlDatabase& iMemoryDb, bool iFromFileToMemory, const QString& iPassword = QString());
0419 
0420     /**
0421      * Copy a sqlite database into an XML document.
0422      * @param iDb the sqlite pointer corresponding to database
0423      * @param oDocument the xml document
0424      * @param oDocument the xml document
0425      * @return An object managing the error
0426      *   @see SKGError
0427      */
0428     static SKGError copySqliteDatabaseToXml(const QSqlDatabase& iDb, QDomDocument& oDocument, QVector<QString>* iIgnore = nullptr);
0429 
0430     /**
0431      * Execute a sqlite orders
0432      * @param iDb a database pointer
0433      * @param iSqlOrders the sql orders
0434      * @return An object managing the error
0435      *   @see SKGError
0436      */
0437     static SKGError executeSqliteOrders(const QSqlDatabase& iDb, const QStringList& iSqlOrders);
0438 
0439     /**
0440      * Execute a sqlite order
0441      * @param iDb a database pointer
0442      * @param iSqlOrder the sql order
0443      * @param iBind the binded variables and values
0444      * @param iLastId to retrieve the id of the last created object. Can be nullptr
0445      * @return An object managing the error
0446      *   @see SKGError
0447      */
0448     static SKGError executeSqliteOrder(const QSqlDatabase& iDb, const QString& iSqlOrder, const QMap<QString, QVariant>& iBind, int* iLastId);
0449 
0450     /**
0451      * Execute a sqlite order
0452      * @param iDb a database pointer
0453      * @param iSqlOrder the sql order
0454      * @param iLastId to retrieve the id of the last created object. Can be nullptr
0455      * @return An object managing the error
0456      *   @see SKGError
0457      */
0458     static SKGError executeSqliteOrder(const QSqlDatabase& iDb, const QString& iSqlOrder, int* iLastId = nullptr);
0459 
0460     /**
0461     * Execute a select sqlite order and return the result in @p oResult
0462     * @param iDb A database pointer
0463     * @param iSqlOrder the sql order
0464     * @param oResult the result of the select. It is a vector of vector of QString
0465     * @return An object managing the error
0466     *   @see SKGError
0467     */
0468     static SKGError executeSelectSqliteOrder(const QSqlDatabase& iDb, const QString& iSqlOrder, SKGStringListList& oResult);
0469 
0470     /**
0471      * Execute a select sqlite order returning one value and return the result in @p oResult
0472      * @param iDb A database pointer
0473      * @param iSqlOrder the sql order
0474      * @param oResult the result of the select
0475      * @return An object managing the error
0476      *   @see SKGError
0477      */
0478     static SKGError executeSingleSelectSqliteOrder(const QSqlDatabase& iDb, const QString& iSqlOrder, QString& oResult);
0479 
0480     /**
0481     * dump a select sqlite order
0482     * @param iDb A database pointer
0483     * @param iSqlOrder the sql order
0484     * @param iMode dump mode
0485     * @return An object managing the error
0486     *   @see SKGError
0487     */
0488     static SKGError dumpSelectSqliteOrder(const QSqlDatabase& iDb, const QString& iSqlOrder, SKGServices::DumpMode iMode = DUMP_TEXT);
0489 
0490     /**
0491     * dump a select sqlite order
0492     * @param iDb A database pointer
0493     * @param iSqlOrder the sql order
0494     * @param oStream the output stream, nullptr for std output (cout)
0495     * @param iMode dump mode
0496     * @return An object managing the error
0497     *   @see SKGError
0498     */
0499     static SKGError dumpSelectSqliteOrder(const QSqlDatabase& iDb, const QString& iSqlOrder, QTextStream* oStream, SKGServices::DumpMode iMode = DUMP_TEXT);
0500 
0501     /**
0502      * dump a select sqlite order
0503      * @param iDb A database pointer
0504      * @param iSqlOrder the sql order
0505      * @param oResult the output
0506      * @param iMode dump mode
0507      * @return An object managing the error
0508      *   @see SKGError
0509      */
0510     static SKGError dumpSelectSqliteOrder(const QSqlDatabase& iDb, const QString& iSqlOrder, QString& oResult, SKGServices::DumpMode iMode = DUMP_TEXT);
0511 
0512     /**
0513      * dump a select sqlite order
0514      * @param iDb A database pointer
0515      * @param iSqlOrder the sql order
0516      * @param oResult the output
0517      * @param iMode dump mode
0518      * @return An object managing the error
0519      *   @see SKGError
0520      */
0521     static SKGError dumpSelectSqliteOrder(const QSqlDatabase& iDb, const QString& iSqlOrder, QStringList& oResult, SKGServices::DumpMode iMode = DUMP_TEXT);
0522 
0523     /**
0524      * Read a property file
0525      * @param iFileName A file name
0526      * @param oProperties the properties
0527      * @return An object managing the error
0528      *   @see SKGError
0529      */
0530     static SKGError readPropertyFile(const QString& iFileName, QHash<QString, QString>& oProperties);
0531 
0532     /**
0533      * Return the current time in millisecond
0534      * @return current
0535      */
0536     static double getMicroTime();
0537 
0538     /**
0539      * Encrypt or decrypt a file
0540      * @param iFileSource source file
0541      * @param iFileTarget target file
0542      * @param iPassword password
0543      * @param iEncrypt true to encrypt, false to decrypt
0544      * @param iHeaderFile the header file (useful for a magic mime type)
0545      * @param oModeSQLCipher to know if the file is in SQLite or SQLCipher mode
0546      * @return An object managing the error
0547      *   @see SKGError
0548      */
0549     static SKGError cryptFile(const QString& iFileSource,
0550                               const QString& iFileTarget,
0551                               const QString& iPassword,
0552                               bool iEncrypt,
0553                               const QString& iHeaderFile,
0554                               bool& oModeSQLCipher);
0555 
0556     /**
0557      * Download a non local URL to a string
0558      * @param iSourceUrl the non local URL
0559      * @param oStream the downloaded string
0560      * @return An object managing the error
0561      *   @see SKGError
0562      */
0563     static SKGError downloadToStream(const QUrl& iSourceUrl, QByteArray& oStream);
0564 
0565     /**
0566      * Download a non local URL to a temporary file
0567      * @param iSourceUrl the non local URL
0568      * @param oTemporaryFile a temporary file. You have to delete it
0569      * @return An object managing the error
0570      *   @see SKGError
0571      */
0572     static SKGError download(const QUrl& iSourceUrl, QString& oTemporaryFile);
0573 
0574     /**
0575      * Upload from a source to a destination
0576      * @param iSourceUrl the source
0577      * @param iDescUrl the destination
0578      * @return An object managing the error
0579      *   @see SKGError
0580      */
0581     static SKGError upload(const QUrl& iSourceUrl, const QUrl& iDescUrl);
0582 
0583     /**
0584      * To enable, disable sql traces
0585      */
0586     static int SKGSqlTraces;
0587 
0588     /**
0589      * Create a table with all values expressed in % of the column
0590      * @param iTable table
0591      * @param iOfColumns false to compute percentage of lines, true to compute perceentage of columns
0592      * @param iAbsolute transform all values in absolute
0593      * @return the table
0594      */
0595     static SKGStringListList getPercentTable(const SKGStringListList& iTable, bool iOfColumns = true, bool iAbsolute = false);
0596 
0597     /**
0598      * Create a table in base 100
0599      * @param iTable table
0600      * @return the table
0601      */
0602     static SKGStringListList getBase100Table(const SKGStringListList& iTable);
0603 
0604     /**
0605      * Create an historized table.
0606      * Each column is the sum of previous ones
0607      * @param iTable table
0608      * @return the table
0609      */
0610     static SKGStringListList getHistorizedTable(const SKGStringListList& iTable);
0611 
0612     /**
0613      * Encode a string for an url
0614      * @param iString the decoded string
0615      * @return the encoded string
0616      */
0617     static QString encodeForUrl(const QString& iString);
0618 
0619     /**
0620      * Return the icon form theme with expected overlays
0621      *
0622      * @param iName The name of the icon
0623      * @param iOverlays List of overlays
0624      * @return The icon
0625      */
0626     static QIcon fromTheme(const QString& iName, const QStringList& iOverlays = QStringList());
0627 
0628     /**
0629      * Get a major version (ex: 4.3) of a version (ex: 4.3.1)
0630      * @param iVersion the version
0631      * @return the major version
0632      */
0633     static QString getMajorVersion(const QString& iVersion);
0634 
0635     /**
0636      * Get a full path command line
0637      * @param iCommandLine command line
0638      * @return the full path command line
0639      */
0640     static QString getFullPathCommandLine(const QString& iCommandLine);
0641 
0642     /**
0643      * Get the next string
0644      * @param iString the string
0645      * @return the next string
0646      */
0647     static QString getNextString(const QString& iString);
0648 
0649 private:
0650     Q_DISABLE_COPY(SKGServices)
0651     static SKGError m_lastCallbackError;
0652 };
0653 #endif