// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

/*!
\page topics-data-io.html
\title Data Input Output
\brief Qt's data input output
\ingroup explanations-dataprocessingandio

This page provides an overview of various ways of retrieving and saving data using Qt.

\section1 Saving and Loading Data

The QIODevice class is the base class for all file and data storage devices
in \l {Qt Core}. All classes that are used for reading and writing data
inherit from it.

Examples of devices are QFile, QBuffer, QTcpSocket, and QProcess.
QFile is used for reading and writing text, binary files, and \l resources,
using the QIODevice interface. A QFile may be used by itself or, more
conveniently, with a QTextStream or QDataStream.

The QBuffer class provides a QIODevice interface for a QByteArray.
QTcpSocket enables the developer to establish a TCP connection and transfer
streams of data. QProcess is used to start external programs, and to read
from and write to that process.

\list
\li \l {Input/Output and Networking} (list of I/O related classes)
\li \l {File and Datastream Functions}
\endlist

\section1 Serialized data
The Qt API provides support for \l [QtCore] {Qt Serialization}
{data serialization} for several use cases.

\list
\li \l JSON support in Qt provides an easy to use C++ API to parse, modify
    and save JSON data
\li \l QDataStream class provides serialization of binary data to a QIODevice
\li \l {Qt XML C++ Classes} provide C++ implementations of the
    \l [QtXML] {XML Streaming} and DOM standards for XML
\endlist

\section1 Database

The \l {Qt SQL} module uses driver plugins to communicate with several database
APIs. Qt has drivers for SQLite, MySQL, DB2, Borland InterBase, Oracle, ODBC,
and PostgreSQL. It is also possible to develop your own driver if Qt does not
provide the driver needed.

Qt's SQL classes can be divided in 3 layers:
\table
    \header
        \li Layer
        \li Purpose
        \li Example class
    \row
        \li
            \list
               \li Driver layer
               \li SQL API layer
               \li User Interface layer
            \endlist
        \li
            \list
               \li Low-level communication between database and the SQL API layer
               \li Provide access to databases
               \li Link data from a database to data-aware widgets
            \endlist
        \li
            \list
               \li QSqlDriver, QSqlDriverCreator
               \li QSqlDatabase, QSqlQuery
               \li QSqlQueryModel (readonly), QSqlTableModel (read/write), QSqlRelationalTableModel (read/write with foreign-key support)
            \endlist
\endtable

With all the SQL drivers, with the exception of SQLite, you can connect to a
server that is hosting your database system. If you use the embedded MySQL Server,
you do not need a MySQL server in order to use that database system.

For instructions on how to build the SQL database drivers, see \l{SQL Database Drivers}.

The Qt SQLite plugin is very suitable for local storage. SQLite is a relational
database management system contained in a small (~350 KiB) C library.
In contrast to other database management systems, SQLite is not a separate process
that is accessed from the client application, but an integral part of it. SQLite
operates on a single file, which must be set as the database name when opening
a connection. If the file does not exist, SQLite will try to create it.

SQLite has some restrictions regarding multiple users and multiple transactions.
If you are reading or writing on a file from different transactions, your
application might freeze until one transaction commits or rolls back.

Once the driver part is set up, the data is accessible using the classes,
QSqlQueryModel, QSqlTableModel, and QSqlRelationalTableModel. QSqlTableModel
and QSqlRelationalTableModel provide editable models that can used with Qt's
item views. QSqlTableModel has read/write access to a single table, whereas
QSqlRelationalTableModel has read/write access to the main table (not to the
table with the foreign key).

The following pages contain information about incorporating SQL into
applications:
\list
\li \l {SQL Programming}
    \list
    \li \l{Database Classes}
    \li \l{Executing SQL Statements}
    \li \l{Using the SQL Model Classes}
    \li \l{Presenting Data in a Table View}
    \li \l{Creating Data-Aware Forms}
    \endlist
\endlist

\section1 XML Support in Qt

Qt provides APIs to read and parse XML streams, and also to write to these
streams. The following key classes facilitate these actions by providing the
necessary infrastructure:
\list
 \li QDomDocument class represents the entire XML document as a document tree and
     provides primary access to the document's data.
  \list
    \li It has several functions for creating document data, for example,
        \l {QDomDocument::createElement()} {createElement()}, \l {QDomDocument::createTextNode()}
        {createTextNode()}, \l {QDomDocument::createComment()} {createComment()},
        \l {QDomDocument::createCDATASection()} {createCDATASection()},
        \l {QDomDocument::createProcessingInstruction()} {createProcessingInstruction()},
        \l {QDomDocument::createAttribute()} {createAttribute()},
        and \l {QDomDocument::createEntityReference()} {createEntityReference()}.
  \endlist
 \li QXmlStreamReader class provides a parser to read XML. It is a well-formed
     XML 1.0 parser that does not include external parsed entities.
  \list
   \li It understands and resolves XML namespaces. For example, in
       case of a StartElement, namespaceUri() returns the namespace the element
       is in, and name() returns the element's local name. The combination of
       namespaceUri() and name() uniquely identifies an element.
   \li It is not CPU-intensive, as it doesn't store the entire XML
       document tree in memory. It only stores the current token at the time
       it is reported.
  \endlist
 \li The QXmlStreamWriter class provides an XML writer with a simple streaming
     API. It is the counterpart to QXmlStreamReader for writing XML, and it
     operates on a QIODevice specified with setDevice().
  \list
   \li It is a simple API that provides a dedicated function for every XML
       token or event you want to write.
   \li It takes care of prefixing namespaces based on the namespaceUri
       specified while writing elements or attributes. If you have to use
       certain standardized prefixes, you can force the writer to use them
       by declaring the namespaces manually with either writeNamespace()
       or writeDefaultNamespace().
   \li It can automatically format the generated XML data by adding
       line-breaks and indentation, making it readable. This feature can be
       turned on with the auto-formatting property.
  \endlist
\endlist

The following topics provide more insight into Qt XML support:
\list
\li \l {An Introduction to Namespaces}
\li \l {XML Streaming}
\endlist

\section1 JSON in Qt

JSON is a text-based open standard for data interchange that is easy to read
and parse. It is used for representing simple data structures and associative
arrays, called objects. It is related to JavaScript, but is a language-independent
notation form.

An object can take 2 forms:

\table
    \header
        \li Collection of name/value pairs
        \li Ordered list of values
    \row
        \li
        \code
           {
                     "last_name": "Routledge",
                     "first_name": "Ronald",
                     "birth_date": 1960
           }
        \endcode
        \li
        \code
            "colors": ["green", "blue", "yellow"]
        \endcode
\endtable

\list
\li \l {JSON Support in Qt}
\li \l {Saving and Loading a Game}
\li \l {Serialization Converter}
\endlist

\section1 Local Storage

The Local Storage API provides the ability to access local offline storage in an
 SQL database from QML and JavaScript.

These databases are user-specific and QML-specific, but accessible to all QML
applications. They are stored in the Databases subdirectory of
QDeclarativeEngine::offlineStoragePath() as SQLite databases
(\l {SQL Database Drivers}).

The API conforms to the Synchronous API of the HTML5 Web Database API,
W3C Working Draft 29 October 2009 (\l {HTML5 Web Database API}).

See \l {Qt Quick Examples - Local Storage} for a basic demonstration of using the Local
Storage API.

\list
\li \l {Qt Quick Local Storage QML Types}
\endlist

\section1 QSettings Class

The QSettings class provides persistent storage of application settings.
An application usually remembers its settings from the previous session.

Settings are stored differently on different platforms. For example,
on Windows they are stored in the registry, whereas on \macos they are
stored in XML files.

QSettings enable you to save and restore application settings in a portable
manner. Constructing and destroying a QSettings object is lightweight and
fast. While creating an object of QSettings, it is a good practice to specify
not only the name of the application, but also the name of your organization.
For example:

\code
   QSettings settings("MyCompany", "Accountancy");
\endcode

\section1 Resources

\l {The Qt Resource System} is a platform-independent mechanism for storing binary
files in the application's executable. This is handy if your application
frequently needs a certain file, or set of files. It also protects against
loss of that particular file .

Resource data can either be compiled into the binary and accessed
immediately in the application code, or a binary resource can be created
dynamically and registered with the resource system by the application.

By default, resources are accessible from the application code by the same file
name as they are stored in the source tree, with a \c{:/} prefix, or by a URL
with a qrc scheme.

\section1 Connectivity
\list
    \li \l {Qt Serial Port}
    \li \l {Qt Modbus}
    \li \l {Qt CAN Bus}
    \li \l {Qt Bluetooth}
    \li \l {Qt NFC}
\endlist

\section1 File Archiving

An archive file is a collection of files or directories which are generally
compressed in order to reduce the space they would otherwise consume on a
drive. Examples of archive files are ZIP, TAR, RAR and 7z.

Qt has support for archives produced by zlib (see
\l{How to compress data with Qt?}{qCompress() and qUncompress()}).

*/
