aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6/doc/tutorials/portingguide/chapter1
diff options
context:
space:
mode:
Diffstat (limited to 'sources/pyside6/doc/tutorials/portingguide/chapter1')
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter1/chapter1.rst89
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter1/createdb.py94
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter1/images/chapter1_books.pngbin0 -> 25391 bytes
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter1/initdb.h113
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter1/main.py22
5 files changed, 318 insertions, 0 deletions
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter1/chapter1.rst b/sources/pyside6/doc/tutorials/portingguide/chapter1/chapter1.rst
new file mode 100644
index 000000000..87fb97660
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter1/chapter1.rst
@@ -0,0 +1,89 @@
+Chapter 1: ``initDb.h`` to ``createDb.py``
+*******************************************
+
+To begin with, port the C++ code that creates an SQLite
+database and tables, and adds data to them. In this case,
+all C++ code related to this lives in ``initdb.h``. The
+code in this header file is divided into following parts:
+
+* ``initDb`` - Creates a db and the necessary tables
+* ``addBooks`` - Adds data to the **books** table.
+* ``addAuthor`` - Adds data to the **authors** table.
+* ``addGenre`` - Adds data to the **genres** table.
+
+To start with, add these following ``import`` statements at
+the beginning of ``createdb.py``:
+
+.. literalinclude:: createdb.py
+ :language: python
+ :linenos:
+ :lines: 3-5
+
+The ``initDb`` function does most of the work needed to
+set up the database, but it depends on the ``addAuthor``,
+``addGenre``, and ``addBook`` helper functions to populate
+the tables. Port these helper functions first. Here is how
+the C++ and Python versions of these functions look like:
+
+C++ version
+-----------
+
+.. literalinclude:: initdb.h
+ :language: c++
+ :linenos:
+ :lines: 9-33
+
+Python version
+--------------
+
+.. literalinclude:: createdb.py
+ :language: python
+ :linenos:
+ :lines: 7-28
+
+Now that the helper functions are in place, port ``initDb``.
+Here is how the C++ and Python versions of this function
+looks like:
+
+C++ version (initDb)
+--------------------
+
+.. literalinclude:: initdb.h
+ :language: c++
+ :linenos:
+ :lines: 35-112
+
+Python version (init_db)
+------------------------
+
+.. literalinclude:: createdb.py
+ :language: python
+ :linenos:
+ :lines: 28-
+
+.. note:: The Python version uses the ``check`` function to
+ execute the SQL statements instead of the ``if...else``
+ block like in the C++ version. Although both are valid
+ approaches, the earlier one produces code that looks
+ cleaner and shorter.
+
+Your Python code to set up the database is ready now. To
+test it, add the following code to ``main.py`` and run it:
+
+.. literalinclude:: main.py
+ :language: python
+ :linenos:
+ :lines: 3-
+
+Use the following command from the prompt to run:
+
+.. code-block:: bash
+
+ python main.py
+
+Your table will look like this:
+
+.. image:: images/chapter1_books.png
+
+Try modifying the SQL statment in ``main.py`` to get data
+from the ``genres`` or ``authors`` table.
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter1/createdb.py b/sources/pyside6/doc/tutorials/portingguide/chapter1/createdb.py
new file mode 100644
index 000000000..da7d201a8
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter1/createdb.py
@@ -0,0 +1,94 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtSql import QSqlDatabase, QSqlError, QSqlQuery
+from datetime import date
+
+
+def add_book(q, title, year, authorId, genreId, rating):
+ q.addBindValue(title)
+ q.addBindValue(year)
+ q.addBindValue(authorId)
+ q.addBindValue(genreId)
+ q.addBindValue(rating)
+ q.exec_()
+
+
+def add_genre(q, name):
+ q.addBindValue(name)
+ q.exec_()
+ return q.lastInsertId()
+
+
+def add_author(q, name, birthdate):
+ q.addBindValue(name)
+ q.addBindValue(str(birthdate))
+ q.exec_()
+ return q.lastInsertId()
+
+BOOKS_SQL = """
+ create table books(id integer primary key, title varchar, author integer,
+ genre integer, year integer, rating integer)
+ """
+AUTHORS_SQL = """
+ create table authors(id integer primary key, name varchar, birthdate text)
+ """
+GENRES_SQL = """
+ create table genres(id integer primary key, name varchar)
+ """
+INSERT_AUTHOR_SQL = """
+ insert into authors(name, birthdate) values(?, ?)
+ """
+INSERT_GENRE_SQL = """
+ insert into genres(name) values(?)
+ """
+INSERT_BOOK_SQL = """
+ insert into books(title, year, author, genre, rating)
+ values(?, ?, ?, ?, ?)
+ """
+
+def init_db():
+ """
+ init_db()
+ Initializes the database.
+ If tables "books" and "authors" are already in the database, do nothing.
+ Return value: None or raises ValueError
+ The error value is the QtSql error instance.
+ """
+ def check(func, *args):
+ if not func(*args):
+ raise ValueError(func.__self__.lastError())
+ db = QSqlDatabase.addDatabase("QSQLITE")
+ db.setDatabaseName(":memory:")
+
+ check(db.open)
+
+ q = QSqlQuery()
+ check(q.exec_, BOOKS_SQL)
+ check(q.exec_, AUTHORS_SQL)
+ check(q.exec_, GENRES_SQL)
+ check(q.prepare, INSERT_AUTHOR_SQL)
+
+ asimovId = add_author(q, "Isaac Asimov", date(1920, 2, 1))
+ greeneId = add_author(q, "Graham Greene", date(1904, 10, 2))
+ pratchettId = add_author(q, "Terry Pratchett", date(1948, 4, 28))
+
+ check(q.prepare,INSERT_GENRE_SQL)
+ sfiction = add_genre(q, "Science Fiction")
+ fiction = add_genre(q, "Fiction")
+ fantasy = add_genre(q, "Fantasy")
+
+ check(q.prepare,INSERT_BOOK_SQL)
+ add_book(q, "Foundation", 1951, asimovId, sfiction, 3)
+ add_book(q, "Foundation and Empire", 1952, asimovId, sfiction, 4)
+ add_book(q, "Second Foundation", 1953, asimovId, sfiction, 3)
+ add_book(q, "Foundation's Edge", 1982, asimovId, sfiction, 3)
+ add_book(q, "Foundation and Earth", 1986, asimovId, sfiction, 4)
+ add_book(q, "Prelude to Foundation", 1988, asimovId, sfiction, 3)
+ add_book(q, "Forward the Foundation", 1993, asimovId, sfiction, 3)
+ add_book(q, "The Power and the Glory", 1940, greeneId, fiction, 4)
+ add_book(q, "The Third Man", 1950, greeneId, fiction, 5)
+ add_book(q, "Our Man in Havana", 1958, greeneId, fiction, 4)
+ add_book(q, "Guards! Guards!", 1989, pratchettId, fantasy, 3)
+ add_book(q, "Night Watch", 2002, pratchettId, fantasy, 3)
+ add_book(q, "Going Postal", 2004, pratchettId, fantasy, 3)
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter1/images/chapter1_books.png b/sources/pyside6/doc/tutorials/portingguide/chapter1/images/chapter1_books.png
new file mode 100644
index 000000000..164674220
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter1/images/chapter1_books.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter1/initdb.h b/sources/pyside6/doc/tutorials/portingguide/chapter1/initdb.h
new file mode 100644
index 000000000..5596defc0
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter1/initdb.h
@@ -0,0 +1,113 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef INITDB_H
+#define INITDB_H
+
+#include <QtSql>
+
+void addBook(QSqlQuery &q, const QString &title, int year, const QVariant &authorId,
+ const QVariant &genreId, int rating)
+{
+ q.addBindValue(title);
+ q.addBindValue(year);
+ q.addBindValue(authorId);
+ q.addBindValue(genreId);
+ q.addBindValue(rating);
+ q.exec();
+}
+
+QVariant addGenre(QSqlQuery &q, const QString &name)
+{
+ q.addBindValue(name);
+ q.exec();
+ return q.lastInsertId();
+}
+
+QVariant addAuthor(QSqlQuery &q, const QString &name, const QDate &birthdate)
+{
+ q.addBindValue(name);
+ q.addBindValue(birthdate);
+ q.exec();
+ return q.lastInsertId();
+}
+
+const auto BOOKS_SQL = QLatin1String(R"(
+ create table books(id integer primary key, title varchar, author integer,
+ genre integer, year integer, rating integer)
+ )");
+
+const auto AUTHORS_SQL = QLatin1String(R"(
+ create table authors(id integer primary key, name varchar, birthdate date)
+ )");
+
+const auto GENRES_SQL = QLatin1String(R"(
+ create table genres(id integer primary key, name varchar)
+ )");
+
+const auto INSERT_AUTHOR_SQL = QLatin1String(R"(
+ insert into authors(name, birthdate) values(?, ?)
+ )");
+
+const auto INSERT_BOOK_SQL = QLatin1String(R"(
+ insert into books(title, year, author, genre, rating)
+ values(?, ?, ?, ?, ?)
+ )");
+
+const auto INSERT_GENRE_SQL = QLatin1String(R"(
+ insert into genres(name) values(?)
+ )");
+
+QSqlError initDb()
+{
+ QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
+ db.setDatabaseName(":memory:");
+
+ if (!db.open())
+ return db.lastError();
+
+ QStringList tables = db.tables();
+ if (tables.contains("books", Qt::CaseInsensitive)
+ && tables.contains("authors", Qt::CaseInsensitive))
+ return QSqlError();
+
+ QSqlQuery q;
+ if (!q.exec(BOOKS_SQL))
+ return q.lastError();
+ if (!q.exec(AUTHORS_SQL))
+ return q.lastError();
+ if (!q.exec(GENRES_SQL))
+ return q.lastError();
+
+ if (!q.prepare(INSERT_AUTHOR_SQL))
+ return q.lastError();
+ QVariant asimovId = addAuthor(q, QLatin1String("Isaac Asimov"), QDate(1920, 2, 1));
+ QVariant greeneId = addAuthor(q, QLatin1String("Graham Greene"), QDate(1904, 10, 2));
+ QVariant pratchettId = addAuthor(q, QLatin1String("Terry Pratchett"), QDate(1948, 4, 28));
+
+ if (!q.prepare(INSERT_GENRE_SQL))
+ return q.lastError();
+ QVariant sfiction = addGenre(q, QLatin1String("Science Fiction"));
+ QVariant fiction = addGenre(q, QLatin1String("Fiction"));
+ QVariant fantasy = addGenre(q, QLatin1String("Fantasy"));
+
+ if (!q.prepare(INSERT_BOOK_SQL))
+ return q.lastError();
+ addBook(q, QLatin1String("Foundation"), 1951, asimovId, sfiction, 3);
+ addBook(q, QLatin1String("Foundation and Empire"), 1952, asimovId, sfiction, 4);
+ addBook(q, QLatin1String("Second Foundation"), 1953, asimovId, sfiction, 3);
+ addBook(q, QLatin1String("Foundation's Edge"), 1982, asimovId, sfiction, 3);
+ addBook(q, QLatin1String("Foundation and Earth"), 1986, asimovId, sfiction, 4);
+ addBook(q, QLatin1String("Prelude to Foundation"), 1988, asimovId, sfiction, 3);
+ addBook(q, QLatin1String("Forward the Foundation"), 1993, asimovId, sfiction, 3);
+ addBook(q, QLatin1String("The Power and the Glory"), 1940, greeneId, fiction, 4);
+ addBook(q, QLatin1String("The Third Man"), 1950, greeneId, fiction, 5);
+ addBook(q, QLatin1String("Our Man in Havana"), 1958, greeneId, fiction, 4);
+ addBook(q, QLatin1String("Guards! Guards!"), 1989, pratchettId, fantasy, 3);
+ addBook(q, QLatin1String("Night Watch"), 2002, pratchettId, fantasy, 3);
+ addBook(q, QLatin1String("Going Postal"), 2004, pratchettId, fantasy, 3);
+
+ return QSqlError();
+}
+
+#endif
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter1/main.py b/sources/pyside6/doc/tutorials/portingguide/chapter1/main.py
new file mode 100644
index 000000000..c1293bcbd
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter1/main.py
@@ -0,0 +1,22 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+
+from PySide6.QtSql import QSqlQueryModel
+from PySide6.QtWidgets import QTableView, QApplication
+
+import createdb
+
+if __name__ == "__main__":
+ app = QApplication()
+ createdb.init_db()
+
+ model = QSqlQueryModel()
+ model.setQuery("select * from books")
+
+ table_view = QTableView()
+ table_view.setModel(model)
+ table_view.resize(800, 600)
+ table_view.show()
+ sys.exit(app.exec())