diff --git a/.github/workflows/msvc.yml b/.github/workflows/msvc.yml index e10db9290..a5673aa98 100644 --- a/.github/workflows/msvc.yml +++ b/.github/workflows/msvc.yml @@ -196,20 +196,8 @@ jobs: working-directory: ../TinyORM-builds-cmake/build-msvc-cmake-debug/tests/testdata_tom run: | $env:Path = '..\..;' + $env:Path - .\tom_testdata.exe migrate --seed --no-ansi - env: - DB_MYSQL_CHARSET: utf8mb4 - DB_MYSQL_COLLATION: utf8mb4_0900_ai_ci - DB_MYSQL_DATABASE: ${{ secrets.DB_MYSQL_DATABASE }} - DB_MYSQL_HOST: ${{ secrets.DB_MYSQL_HOST }} - DB_MYSQL_PASSWORD: ${{ secrets.DB_MYSQL_PASSWORD }} - DB_MYSQL_USERNAME: ${{ secrets.DB_MYSQL_USERNAME }} - TOM_TESTDATA_ENV: testing - - - name: Create and Seed tables for unit tests (PostgreSQL, SQLite) - working-directory: tests/testdata - run: | - php.exe ./create_and_seed_database.php --skip-mysql-migrate + .\tom_testdata.exe migrate --database=tinyorm_testdata_tom_mysql --seed --no-ansi + .\tom_testdata.exe migrate --database=tinyorm_testdata_tom_postgres --seed --no-ansi env: DB_MYSQL_CHARSET: utf8mb4 DB_MYSQL_COLLATION: utf8mb4_0900_ai_ci @@ -222,6 +210,13 @@ jobs: DB_PGSQL_HOST: ${{ secrets.DB_PGSQL_HOST }} DB_PGSQL_PASSWORD: ${{ secrets.DB_PGSQL_PASSWORD }} DB_PGSQL_USERNAME: ${{ secrets.DB_PGSQL_USERNAME }} + TOM_TESTDATA_ENV: testing + + - name: Create and Seed tables for unit tests (PostgreSQL, SQLite) + working-directory: tests/testdata + run: | + php.exe ./create_and_seed_database.php --skip-mysql-migrate --skip-postgres-migrate + env: DB_SQLITE_DATABASE: ${{ runner.temp }}/${{ secrets.DB_SQLITE_DATABASE }} - name: TinyORM execute ctest 🔥 diff --git a/tests/testdata/create_and_seed_database.php b/tests/testdata/create_and_seed_database.php index b9a44328d..59a42f9d0 100644 --- a/tests/testdata/create_and_seed_database.php +++ b/tests/testdata/create_and_seed_database.php @@ -394,14 +394,14 @@ function seedTables(string $connection): void } /** - * Fix sequence number for Postgres. + * Fix sequence numbers for the PostgreSQL. * * I have to fix sequences in Postgres because I'm inserting IDs manually, and * it doesn't increment sequences. * * @return void */ -function fixSequences(): void +function fixPostgresSequences(): void { $sequences = [ 'torrents_id_seq' => 7, @@ -433,11 +433,12 @@ function fixSequences(): void function createAndSeedTables(array $connections, array $options): void { foreach ($connections as $connection) { - /* Allow to skip dropping and creating tables for the mysql connection. - Currently, TinyORM's migrations supports the MySQL database only, and I want to use our - tom migrations in CI/CD pipelines, this is the reason for the condition below. */ - if (array_key_exists('skip-mysql-migrate', $options) && - $connection === 'mysql' + /* Allow to skip dropping and creating tables for the mysql and pgsql connection. + Currently, TinyORM's migrations supports the MySQL and PostgreSQL database, and + I want to use our tom migrations in CI/CD pipelines, this is the reason + for the condition below. */ + if ((array_key_exists('skip-mysql-migrate', $options) && $connection === 'mysql') || + (array_key_exists('skip-postgres-migrate', $options) && $connection === 'pgsql') ) continue; @@ -446,7 +447,7 @@ function createAndSeedTables(array $connections, array $options): void seedTables($connection); if ($connection === 'pgsql') - fixSequences(); + fixPostgresSequences(); } } @@ -499,7 +500,8 @@ addConnections($capsule, $configs); // Parse command line options $options = getopt('', [ - 'skip-mysql-migrate' + 'skip-mysql-migrate', + 'skip-postgres-migrate', ]); createAndSeedTables(array_keys($configs), $options); diff --git a/tests/testdata_tom/database/seeders/databaseseeder.hpp b/tests/testdata_tom/database/seeders/databaseseeder.hpp index f7d49dd11..e3bf13d48 100644 --- a/tests/testdata_tom/database/seeders/databaseseeder.hpp +++ b/tests/testdata_tom/database/seeders/databaseseeder.hpp @@ -37,10 +37,10 @@ namespace Seeders DB::table("role_user")->insert({"role_id", "user_id", "active"}, { - {1, 1, 1}, - {2, 1, 0}, - {3, 1, 1}, - {2, 2, 1}, + {1, 1, true}, + {2, 1, false}, + {3, 1, true}, + {2, 2, true}, }); DB::table("user_phones")->insert({ID, "user_id", "number"}, @@ -113,12 +113,12 @@ namespace Seeders DB::table("tag_torrent")->insert({"torrent_id", "tag_id", "active", CREATED_AT, UPDATED_AT}, { - {2, 1, 1, "2021-02-21 17:31:58", "2021-02-21 18:49:22"}, - {2, 2, 1, "2021-02-22 17:31:58", "2021-02-22 18:49:22"}, - {2, 3, 0, "2021-02-23 17:31:58", "2021-02-23 18:49:22"}, - {2, 4, 1, "2021-02-24 17:31:58", "2021-02-24 18:49:22"}, - {3, 2, 1, "2021-02-25 17:31:58", "2021-02-25 18:49:22"}, - {3, 4, 1, "2021-02-26 17:31:58", "2021-02-26 18:49:22"}, + {2, 1, true, "2021-02-21 17:31:58", "2021-02-21 18:49:22"}, + {2, 2, true, "2021-02-22 17:31:58", "2021-02-22 18:49:22"}, + {2, 3, false, "2021-02-23 17:31:58", "2021-02-23 18:49:22"}, + {2, 4, true, "2021-02-24 17:31:58", "2021-02-24 18:49:22"}, + {3, 2, true, "2021-02-25 17:31:58", "2021-02-25 18:49:22"}, + {3, 4, true, "2021-02-26 17:31:58", "2021-02-26 18:49:22"}, }); DB::table("tag_properties")->insert({ID, "tag_id", "color", "position", CREATED_AT, UPDATED_AT}, @@ -128,7 +128,43 @@ namespace Seeders {3, 3, "red", 2, "2021-02-13 12:41:28", "2021-02-13 22:17:11"}, {4, 4, "orange", 3, "2021-02-14 12:41:28", "2021-02-14 22:17:11"}, }); + + // Fix sequence numbers for the PostgreSQL + if (DB::getDefaultConnection() == + QLatin1String("tinyorm_testdata_tom_postgres") + ) + fixPostgresSequences(); } + + private: + /*! Fix sequence numbers for the PostgreSQL. */ + inline void fixPostgresSequences() const; }; + /* private */ + + void DatabaseSeeder::fixPostgresSequences() const + { + /* I have to fix sequences in Postgres because I'm inserting IDs manually, and + it doesn't increment sequences. */ + + std::unordered_map sequences { + {QStringLiteral("torrents_id_seq"), 7}, + {QStringLiteral("torrent_peers_id_seq"), 5}, + {QStringLiteral("torrent_previewable_files_id_seq"), 10}, + {QStringLiteral("torrent_previewable_file_properties_id_seq"), 6}, + {QStringLiteral("file_property_properties_id_seq"), 7}, + {QStringLiteral("torrent_tags_id_seq"), 6}, + {QStringLiteral("tag_properties_id_seq"), 5}, + {QStringLiteral("users_id_seq"), 4}, + {QStringLiteral("roles_id_seq"), 4}, + {QStringLiteral("user_phones_id_seq"), 4}, + }; + + for (auto &&[sequence, id] : sequences) + DB::connection().unprepared( + QStringLiteral("ALTER SEQUENCE %1 RESTART WITH %2") + .arg(std::move(sequence)).arg(id)); + } + } // namespace Seeders diff --git a/tests/testdata_tom/main.cpp b/tests/testdata_tom/main.cpp index 69328de38..e863c2fa7 100644 --- a/tests/testdata_tom/main.cpp +++ b/tests/testdata_tom/main.cpp @@ -69,21 +69,46 @@ std::shared_ptr setupManager() // Ownership of the shared_ptr() return DB::create({ - {driver_, QMYSQL}, - {host_, qEnvironmentVariable("DB_MYSQL_HOST", H127001)}, - {port_, qEnvironmentVariable("DB_MYSQL_PORT", P3306)}, - {database_, qEnvironmentVariable("DB_MYSQL_DATABASE", EMPTY)}, - {username_, qEnvironmentVariable("DB_MYSQL_USERNAME", EMPTY)}, - {password_, qEnvironmentVariable("DB_MYSQL_PASSWORD", EMPTY)}, - {charset_, qEnvironmentVariable("DB_MYSQL_CHARSET", UTF8MB4)}, - {collation_, qEnvironmentVariable("DB_MYSQL_COLLATION", UTF8MB40900aici)}, - {timezone_, TZ00}, - {prefix_, EMPTY}, - {prefix_indexes, true}, - {strict_, true}, - {isolation_level, QStringLiteral("REPEATABLE READ")}, - {engine_, InnoDB}, - {options_, QVariantHash()}, + // MySQL connection + {QStringLiteral("tinyorm_testdata_tom_mysql"), { + {driver_, QMYSQL}, + {host_, qEnvironmentVariable("DB_MYSQL_HOST", H127001)}, + {port_, qEnvironmentVariable("DB_MYSQL_PORT", P3306)}, + {database_, qEnvironmentVariable("DB_MYSQL_DATABASE", EMPTY)}, + {username_, qEnvironmentVariable("DB_MYSQL_USERNAME", EMPTY)}, + {password_, qEnvironmentVariable("DB_MYSQL_PASSWORD", EMPTY)}, + {charset_, qEnvironmentVariable("DB_MYSQL_CHARSET", UTF8MB4)}, + {collation_, qEnvironmentVariable("DB_MYSQL_COLLATION", + UTF8MB40900aici)}, + {timezone_, TZ00}, + {prefix_, EMPTY}, + {prefix_indexes, true}, + {strict_, true}, + {isolation_level, QStringLiteral("REPEATABLE READ")}, + {engine_, InnoDB}, + {options_, QVariantHash()}, + }}, + + // PostgreSQL connection + {QStringLiteral("tinyorm_testdata_tom_postgres"), { + {driver_, QPSQL}, + {host_, qEnvironmentVariable("DB_PGSQL_HOST", H127001)}, + {port_, qEnvironmentVariable("DB_PGSQL_PORT", P5432)}, + {database_, qEnvironmentVariable("DB_PGSQL_DATABASE", EMPTY)}, + {schema_, qEnvironmentVariable("DB_PGSQL_SCHEMA", PUBLIC)}, + {username_, qEnvironmentVariable("DB_PGSQL_USERNAME", postgres_)}, + {password_, qEnvironmentVariable("DB_PGSQL_PASSWORD", EMPTY)}, + {charset_, qEnvironmentVariable("DB_PGSQL_CHARSET", UTF8)}, + // I don't use timezone types in postgres anyway + {timezone_, UTC}, + {prefix_, EMPTY}, + {prefix_indexes, true}, + // ConnectionFactory provides a default value for this (for reference only) +// {dont_drop, QStringList {QStringLiteral("spatial_ref_sys")}}, + {options_, QVariantHash()}, + }} }, - QStringLiteral("tinyorm_testdata_tom")); + /* Because the default connection name is not defined, then will be needed + to provide the connection name using the --database=xyz argument. */ + {}); } diff --git a/tom/src/tom/application.cpp b/tom/src/tom/application.cpp index b1f5f9cd6..3991f9cce 100644 --- a/tom/src/tom/application.cpp +++ b/tom/src/tom/application.cpp @@ -616,7 +616,10 @@ std::shared_ptr Application::resolver() const noexc void Application::throwIfEmptyDefaultConnection() const { - if (!m_db->getDefaultConnection().isEmpty()) + // Throw if exactly one connection is registered + if (!m_db->getDefaultConnection().isEmpty() || m_db->connectionsSize() > 1 || + m_db->connectionsSize() < 1 + ) return; throw Exceptions::RuntimeError("Default database connection not configured.");