Files
TinyORM/docs/building/migrations.mdx
silverqx 5ff160dec5 use upsert alias on MySQL
The MySQL >=8.0.19 supports aliases in the VALUES and SET clauses
of INSERT INTO ... ON DUPLICATE KEY UPDATE statement for the row to be
inserted and its columns. It also generates warning from >=8.0.20 if
an old style used.

This enhancement detects the MySQL version and on the base of it uses
alias during the upsert call.

Also a user can override the version through the MySQL database
configuration. It helps to save/avoid one database query
(select version()) during the upsert method call or during connecting
to the MySQL database (version is needed if strict mode is enabled).

 - added unit and functional tests
 - updated number of unit tests to 1402
 - updated upsert docs
 - added ConfigUtils to avoid duplicates

Others:

 - added the version database configuration everywhere
 - docs added few lines about MySQL version configuration option
 - docs updated database configurations, added a new missing options
2022-08-12 15:37:56 +02:00

787 lines
25 KiB
Plaintext

---
sidebar_position: 3
sidebar_label: Migrations
description: How to compile the TinyORM migrations (tom) c++ console application on Windows and Linux.
keywords: [c++ orm, building, migrations, tinyorm]
---
import CodeBlock from '@theme/CodeBlock'
import TabItem from '@theme/TabItem'
import Tabs from '@theme/Tabs'
import {
shell,
application, bash, pwsh,
bash_label, pwsh_label
} from '@theme/constants'
import {
applicationFolder,
applicationFolderPath,
convertToCmakeEnvVariable,
rootFolderPath
} from '@theme/utils/rootFolderUtils'
# Building: Migrations
- [Introduction](#introduction)
- [Prerequisites](#prerequisites)
- [vcpkg.json manifest](#vcpkg-json-manifest)
- [Source code](#source-code)
- [Main file](#main-file)
- [Migrations](#migrations)
- [Seeders](#seeders)
- [Migrations with CMake](#migrations-with-cmake)
- [CMake project](#cmake-project)
- [Build migrations](#build-migrations-cmake)
- [Execute migrations](#execute-migrations-cmake)
- [Migrations with qmake](#migrations-with-qmake)
- [qmake project](#qmake-project)
- [Build migrations](#build-migrations-qmake)
- [Execute migrations](#execute-migrations-qmake)
- [Finish](#finish)
## Introduction
We will try to create a working migrations console application called as <abbr title='TinyORM migrations'>`tom`</abbr> in the terminal with the `CMake` and in the `QtCreator` IDE with the `qmake`.
The `tom` console application also expects the following [folders structure](building/tinyorm.mdx#folders-structure), let's create them.
<Tabs groupId={shell}>
<TabItem value={pwsh} label={pwsh_label}>
<CodeBlock className='language-powershell'>
{`cd ${applicationFolderPath(pwsh)}
mkdir tom/tom
cd tom`}
</CodeBlock>
</TabItem>
<TabItem value={bash} label={bash_label}>
<CodeBlock className='language-bash'>
{`cd ${applicationFolderPath(bash)}
mkdir -p tom/tom
cd tom`}
</CodeBlock>
</TabItem>
</Tabs>
`TinyORM` source tree contains the `tom` example application, you can inspire or look at the [source code](https://github.com/silverqx/TinyORM/tree/main/examples/tom). Also `TinyORM` unit tests use a `tom` migrations internally to create the database structure, internally called as the [`tom` migrations for unit tests](https://github.com/silverqx/TinyORM/tree/main/tests/testdata_tom).
All these three console applications the `tom` example, `tom` migrations for unit tests, and the application described in this tutorial have practically identical source code (the main.cpp file).
## Prerequisites
Working MySQL database server as the `tom` migrations currently provides support only for the MySQL database.
Install required dependencies and build the `TinyORM` library with the `tom` (it's enabled by default) as is described [here](building/hello-world.mdx#install-dependencies) and [here](building/tinyorm.mdx).
### vcpkg.json manifest {#vcpkg-json-manifest}
Whole section about the `vcpkg` dependencies is described in the [Install dependencies](building/hello-world.mdx#install-dependencies).
Create a `vcpkg.json` file with the following content. `CMake` example below uses this method.
```bash
cd tom
vim vcpkg.json
```
```json
{
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg/master/scripts/vcpkg.schema.json",
"name": "tom",
"version-semver": "0.1.0",
"description": "Tom console for TinyORM.",
"maintainers": "Silver Zachara <silver.zachara@gmail.com>",
"supports": "!(uwp | arm | android | emscripten)",
"dependencies": [
"range-v3",
"tabulate"
]
}
```
:::note
Only `CMake` via the `toolchain file` supports this method.
:::
## Source code
Let's start in the `tom` project folder.
<Tabs groupId={shell}>
<TabItem value={pwsh} label={pwsh_label}>
<CodeBlock className='language-powershell'>
{`cd ${applicationFolderPath(pwsh)}/tom/tom`}
</CodeBlock>
</TabItem>
<TabItem value={bash} label={bash_label}>
<CodeBlock className='language-bash'>
{`cd ${applicationFolderPath(bash)}/tom/tom`}
</CodeBlock>
</TabItem>
</Tabs>
### Main file
Create `main.cpp` source file.
```bash
vim main.cpp
```
:::tip
To paste a source code correctly in `vim`, press <kbd>Shift</kbd> + <kbd>p</kbd>.
:::
And paste the following code.
<a id='string-constants-example' />
#include <orm/db.hpp>
#include <tom/application.hpp>
#include "migrations/2014_10_12_000000_create_posts_table.hpp"
#include "seeders/databaseseeder.hpp"
using Orm::DatabaseManager;
using Orm::DB;
using TomApplication = Tom::Application;
using namespace Migrations; // NOLINT(google-build-using-namespace)
using namespace Seeders; // NOLINT(google-build-using-namespace)
/*! Build the database manager instance and add a database connection. */
std::shared_ptr<DatabaseManager> setupManager();
/*! c++ main function. */
int main(int argc, char *argv[])
{
try {
// Ownership of the shared_ptr()
auto db = setupManager();
return TomApplication(argc, argv, db, "TOM_MIGRATIONS_ENV")
.migrations<CreatePostsTable>()
.seeders<DatabaseSeeder>()
// Fire it up 🔥🚀✨
.run();
} catch (const std::exception &e) {
TomApplication::logException(e);
}
return EXIT_FAILURE;
}
std::shared_ptr<DatabaseManager> setupManager()
{
using namespace Orm::Constants; // NOLINT(google-build-using-namespace)
// 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},
{Version, {}}, // Autodetect
{options_, QVariantHash()},
},
QStringLiteral("tinyorm_tom"));
}
:::tip
If you have defined more database connections then you can tag the lines with the database connection names with the `// shell:connection` comment and this connection names will be provided to the bash/zsh/pwsh completion for the `--database=` option, [example](https://github.com/silverqx/TinyORM/blob/main/examples/tom/main.cpp#L71).
:::
### Migrations
If you have already built the `tom` application then you can generate a migrations using the [`make:migration`](database/migrations.mdx#generating-migrations) command 😎.
```bash
tom make:migration create_posts_table
```
Below is the expected folders structure for the migrations. The [`migrations.pri`](#migrations-source-files) file is used only by the `qmake` build system and is not needed with `CMake` builds.
<a id='folders-structure' />
```text
tom/
└── database/
├── migrations/
├── seeders/
├── migrations.pri
└── seeders.pri
```
Let's create the first migration manually.
<Tabs groupId={shell}>
<TabItem value={pwsh} label={pwsh_label}>
<CodeBlock className='language-powershell'>
{`mkdir database/migrations\n
vim database/migrations/2014_10_12_000000_create_posts_table.hpp`}
</CodeBlock>
</TabItem>
<TabItem value={bash} label={bash_label}>
<CodeBlock className='language-bash'>
{`mkdir -p database/migrations\n
vim database/migrations/2014_10_12_000000_create_posts_table.hpp`}
</CodeBlock>
</TabItem>
</Tabs>
And paste the following code.
#pragma once
#include <tom/migration.hpp>
namespace Migrations
{
struct CreatePostsTable : Migration
{
/*! Filename of the migration file. */
T_MIGRATION
/*! Run the migrations. */
void up() const override
{
Schema::create("posts", [](Blueprint &table)
{
table.id();
table.string(NAME);
table.timestamps();
});
}
/*! Reverse the migrations. */
void down() const override
{
Schema::dropIfExists("posts");
}
};
} // namespace Migrations
:::info
If you want, you can also build the `tom` application without the migrations, simply comment out the `migrations` method and the corresponding `#include "migrations/xyz.hpp"` files.
:::
### Seeders
If you have already built the `tom` application then you can generate a seeder using the [`make:seeder`](database/seeding.mdx#writing-seeders) command 😎.
```bash
tom make:seeder PostSeeder
```
The expected folders structure is described a few paragraphs [above](#folders-structure). The [`seeders.pri`](#seeders-source-files) file is used only by the `qmake` build system and is not needed with `CMake` builds.
Let's create the root seeder class manually.
<Tabs groupId={shell}>
<TabItem value={pwsh} label={pwsh_label}>
<CodeBlock className='language-powershell'>
{`mkdir database/seeders\n
vim database/seeders/databaseseeder.hpp`}
</CodeBlock>
</TabItem>
<TabItem value={bash} label={bash_label}>
<CodeBlock className='language-bash'>
{`mkdir -p database/seeders\n
vim database/seeders/databaseseeder.hpp`}
</CodeBlock>
</TabItem>
</Tabs>
And paste the following code.
#pragma once
#include <tom/seeder.hpp>
namespace Seeders
{
/*! Main database seeder. */
struct DatabaseSeeder : Seeder
{
/*! Run the database seeders. */
void run() override
{
DB::table("posts")->insert({
{{"name", "1. post"}},
{{"name", "2. post"}},
});
}
};
} // namespace Seeders
:::tip
You can create more seeder classes like this and use the `call<>()` method to invoke them as is described in the [Calling Additional Seeders](database/seeding.mdx#calling-additional-seeders) section.
:::
## Migrations with CMake
Create a folder for the `CMake` build.
<Tabs groupId={shell}>
<TabItem value={pwsh} label={pwsh_label}>
<CodeBlock className='language-powershell'>
{`cd ..
mkdir tom-builds-cmake/build-debug\n
cd tom`}
</CodeBlock>
</TabItem>
<TabItem value={bash} label={bash_label}>
<CodeBlock className='language-bash'>
{`cd ..
mkdir -p tom-builds-cmake/build-debug\n
cd tom`}
</CodeBlock>
</TabItem>
</Tabs>
### CMake project
Create `CMakeLists.txt` file with the following content. I leave the comments in the `CMakeLists.txt` file because it's not as simple as the `Hello world` example; to make it clear what's going on.
<Tabs groupId={shell}>
<TabItem value={pwsh} label={pwsh_label}>
<CodeBlock className='language-cmake'>
{`cmake_minimum_required(VERSION VERSION 3.20...3.24 FATAL_ERROR)\n
# Specify the C++ standard
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)\n
set(CMAKE_AUTOMOC ON)\n
# Tom command-line application
# ---\n
set(Tom_ns tom)
set(Tom_target tom)\n
file(REAL_PATH "../../TinyORM" TinyMainDir)\n
set(TinyOrmSourceDir "\${TinyMainDir}/TinyORM")
set(TinyOrmBuildDir "\${TinyMainDir}/TinyORM-builds-cmake/build-debug")\n
# TinyORM CMake modules (needed to set the executable version and RC file on Windows)
list(APPEND CMAKE_MODULE_PATH "\${TinyOrmSourceDir}/cmake/CommonModules")\n
# build tree
list(APPEND CMAKE_PREFIX_PATH "\${TinyOrmBuildDir}")\n
# Initialize Project Version
# ---\n
include(TinyHelpers)
tiny_read_version(TINY_VERSION
TINY_VERSION_MAJOR TINY_VERSION_MINOR TINY_VERSION_PATCH TINY_VERSION_TWEAK
VERSION_HEADER "\${TinyOrmSourceDir}/tom/include/tom/version.hpp"
PREFIX TINYTOM
HEADER_FOR "\${Tom_ns}"
)\n
# Basic project
# ---\n
project(\${Tom_ns}
DESCRIPTION "Tom console for TinyORM"
HOMEPAGE_URL "https://www.tinyorm.org"
LANGUAGES CXX
VERSION \${TINY_VERSION}
)\n
# Tom command-line application
# ---\n
add_executable(\${Tom_target}
main.cpp
)
add_executable(\${Tom_ns}::\${Tom_target} ALIAS \${Tom_target})\n
# Tom command-line application specific configuration
# ---\n
set_target_properties(\${Tom_target}
PROPERTIES
C_VISIBILITY_PRESET "hidden"
CXX_VISIBILITY_PRESET "hidden"
VISIBILITY_INLINES_HIDDEN YES
VERSION \${PROJECT_VERSION}
)\n
target_include_directories(\${Tom_target} PRIVATE
"\$<BUILD_INTERFACE:\${CMAKE_SOURCE_DIR}/database>"
)\n
# Tom command-line application defines
# ---\n
target_compile_definitions(\${Tom_target}
PRIVATE
PROJECT_TOM
)\n
# Windows resource and manifest files
# ---\n
# Find icons, tom/version.hpp, and Windows manifest file for MinGW
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
tiny_set_rc_flags("-I \\"\${TinyOrmSourceDir}/tom/resources\\"")
endif()\n
include(TinyResourceAndManifest)
tiny_resource_and_manifest(\${Tom_target}
OUTPUT_DIR "\${TINY_BUILD_GENDIR}/tmp/"
RESOURCES_DIR "\${TinyOrmSourceDir}/tom/resources"
)\n
# Resolve and link dependencies
# ---\n
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt\${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)
find_package(TinyOrm 0.16.0 CONFIG REQUIRED)\n
# Unconditional dependencies
target_link_libraries(\${Tom_target}
PRIVATE
Qt\${QT_VERSION_MAJOR}::Core
TinyOrm::TinyOrm
)`}
</CodeBlock>
</TabItem>
<TabItem value={bash} label={bash_label}>
<CodeBlock className='language-cmake'>
{`cmake_minimum_required(VERSION VERSION 3.20...3.24 FATAL_ERROR)\n
# Specify the C++ standard
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)\n
set(CMAKE_AUTOMOC ON)\n
# Tom command-line application
# ---\n
set(Tom_ns tom)
set(Tom_target tom)\n
file(REAL_PATH "../../TinyORM" TinyMainDir)\n
set(TinyOrmSourceDir "\${TinyMainDir}/TinyORM")
set(TinyOrmBuildDir "\${TinyMainDir}/TinyORM-builds-cmake/build-debug")\n
# TinyORM CMake modules (needed to set the executable version and RC file on Windows)
list(APPEND CMAKE_MODULE_PATH "\${TinyOrmSourceDir}/cmake/CommonModules")\n
# build tree
list(APPEND CMAKE_PREFIX_PATH "\${TinyOrmBuildDir}")\n
# Initialize Project Version
# ---\n
include(TinyHelpers)
tiny_read_version(TINY_VERSION
TINY_VERSION_MAJOR TINY_VERSION_MINOR TINY_VERSION_PATCH TINY_VERSION_TWEAK
VERSION_HEADER "\${TinyOrmSourceDir}/tom/include/tom/version.hpp"
PREFIX TINYTOM
HEADER_FOR "\${Tom_ns}"
)\n
# Basic project
# ---\n
project(\${Tom_ns}
DESCRIPTION "Tom console for TinyORM"
HOMEPAGE_URL "https://www.tinyorm.org"
LANGUAGES CXX
VERSION \${TINY_VERSION}
)\n
# Tom command-line application
# ---\n
add_executable(\${Tom_target}
main.cpp
)
add_executable(\${Tom_ns}::\${Tom_target} ALIAS \${Tom_target})\n
# Tom command-line application specific configuration
# ---\n
set_target_properties(\${Tom_target}
PROPERTIES
C_VISIBILITY_PRESET "hidden"
CXX_VISIBILITY_PRESET "hidden"
VISIBILITY_INLINES_HIDDEN YES
VERSION \${PROJECT_VERSION}
)\n
target_include_directories(\${Tom_target} PRIVATE
"\$<BUILD_INTERFACE:\${CMAKE_SOURCE_DIR}/database>"
)\n
# Tom command-line application defines
# ---\n
target_compile_definitions(\${Tom_target}
PRIVATE
PROJECT_TOM
)\n
# Windows resource and manifest files
# ---\n
# Find icons, tom/version.hpp, and Windows manifest file for MinGW
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
tiny_set_rc_flags("-I \\"\${TinyOrmSourceDir}/tom/resources\\"")
endif()\n
include(TinyResourceAndManifest)
tiny_resource_and_manifest(\${Tom_target}
OUTPUT_DIR "\${TINY_BUILD_GENDIR}/tmp/"
RESOURCES_DIR "\${TinyOrmSourceDir}/tom/resources"
)\n
# Resolve and link dependencies
# ---\n
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
find_package(Qt\${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)
find_package(TinyOrm 0.16.0 CONFIG REQUIRED)\n
# Unconditional dependencies
target_link_libraries(\${Tom_target}
PRIVATE
Qt\${QT_VERSION_MAJOR}::Core
TinyOrm::TinyOrm
)`}
</CodeBlock>
</TabItem>
</Tabs>
### Build migrations {#build-migrations-cmake}
Now you are ready to configure `tom` `CMake` application. Don't forget to prepare the build environment with the [`qtenv6.ps1`](building/tinyorm.mdx#windows-prerequisites) command if you are building with the `msvc`.
```bash
cd ../tom-builds-cmake/build-debug
```
<Tabs groupId={shell}>
<TabItem value={pwsh} label={pwsh_label}>
<CodeBlock className='language-powershell'>
{`cmake.exe \`
-S "${applicationFolderPath(pwsh)}/tom/tom" \`
-B "${applicationFolderPath(pwsh)}/tom/tom-builds-cmake/build-debug" \`
-G 'Ninja' \`
-D CMAKE_BUILD_TYPE:STRING='Debug' \`
-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${rootFolderPath(pwsh)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \`
-D CMAKE_INSTALL_PREFIX:PATH="${rootFolderPath(pwsh)}/tmp/tom"`}
</CodeBlock>
</TabItem>
<TabItem value={bash} label={bash_label}>
<CodeBlock className='language-bash'>
{`cmake \\
-S "${applicationFolderPath(bash)}/tom/tom" \\
-B "${applicationFolderPath(bash)}/tom/tom-builds-cmake/build-debug" \\
-G 'Ninja' \\
-D CMAKE_BUILD_TYPE:STRING='Debug' \\
-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${rootFolderPath(bash)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \\
-D CMAKE_INSTALL_PREFIX:PATH="${rootFolderPath(bash)}/tmp/tom"`}
</CodeBlock>
</TabItem>
</Tabs>
And build.
```bash
cmake --build . --target all
```
### Execute migrations {#execute-migrations-cmake}
Do not forget to add `TinyOrm0d.dll` on the path on Windows and on the `LD_LIBRARY_PATH` on Linux, so `tom` application can find it during execution, as is described [here](building/tinyorm.mdx#tinyorm-on-path-cmake).
<Tabs groupId={shell} name='tinyorm-on-path'>
<TabItem value={pwsh} label={pwsh_label}>
<CodeBlock className='language-powershell'>
{`$env:Path = "${applicationFolderPath(pwsh, false)}\\TinyORM\\TinyORM-builds-cmake\\build-debug;" + $env:Path`}
</CodeBlock>
</TabItem>
<TabItem value={bash} label={bash_label}>
<CodeBlock className='language-bash'>
{`export LD_LIBRARY_PATH=${applicationFolderPath(bash)}/TinyORM/TinyORM-builds-cmake/build-debug\${PATH:+:}$PATH`}
</CodeBlock>
</TabItem>
</Tabs>
Execute `tom` application.
<Tabs groupId={shell}>
<TabItem value={pwsh} label={pwsh_label}>
```powershell
.\tom.exe migrate:status
```
</TabItem>
<TabItem value={bash} label={bash_label}>
```bash
./tom migrate:status
```
</TabItem>
</Tabs>
The output will look something like this.
<img src={require('./assets/img/migrations/tom_migrate_status.png').default}
alt='Tom migrations - migrate:status command output' width='660' />
See also the [final thoughts](#finish) on how to verify the `tom` executable file properties.
Happy migrating 🎉👌
## Migrations with qmake
Create a folder for the `qmake` build.
<Tabs groupId={shell}>
<TabItem value={pwsh} label={pwsh_label}>
<CodeBlock className='language-powershell'>
{`cd ${applicationFolderPath(pwsh)}/tom\n
mkdir tom-builds-qmake`}
</CodeBlock>
</TabItem>
<TabItem value={bash} label={bash_label}>
<CodeBlock className='language-bash'>
{`cd ${applicationFolderPath(bash)}/tom\n
mkdir tom-builds-qmake`}
</CodeBlock>
</TabItem>
</Tabs>
The [`source code`](#source-code) is the same as for the `Migrations with CMake` console application.
### qmake project
Create `tom.pro` qmake file with the following content.
```bash
cd tom
vim tom.pro
```
:::tip
To paste a source code correctly in `vim`, press <kbd>Shift</kbd> + <kbd>p</kbd>.
:::
```qmake
QT *= core sql
QT -= gui
TEMPLATE = app
TARGET = tom
CONFIG *= console
DEFINES += PROJECT_TOM
SOURCES += $$PWD/main.cpp
# Database migrations
include($$PWD/database/migrations.pri)
# Database seeders
include($$PWD/database/seeders.pri)
# Configure TinyORM library for the migrations purposes
include($$TINY_MAIN_DIR/TinyORM/qmake/tom.pri)
# vcpkg - range-v3 and tabulate
win32-msvc: \
INCLUDEPATH += $$quote($$TINY_VCPKG_INSTALLED/x64-windows/include/)
mingw: \
QMAKE_CXXFLAGS += -isystem $$shell_quote($$TINY_VCPKG_INSTALLED/x64-mingw-dynamic/include/)
unix:!macx: \
QMAKE_CXXFLAGS += -isystem $$shell_quote($$TINY_VCPKG_INSTALLED/x64-linux/include/)
```
:::caution
The exact [folders structure](building/tinyorm.mdx#folders-structure) is crucial in this example because the paths to the `TinyORM` source and build folders are relative.
:::
:::tip
On Linux `-isystem` marks the directory as a system directory, it prevents warnings.
On Windows you can use `QMAKE_CXXFLAGS_WARN_ON = -external:anglebrackets -external:W0`, it applies a warning level 0 to the angel bracket includes; `#include <file>`.
:::
#### Configure using .qmake.conf
To correctly set a file properties as the version, description, ... you have to provide the path to the `TinyORM` qmake features (`.prf` files) which handle this correctly, this path is provided by the `QMAKEFEATURES` variable and can be set only in the `.qmake.conf` file.
Create `.qmake.conf` in the `tom` application root folder with the following content.
```qmake
TINY_MAIN_DIR = $$clean_path($$PWD/../../TinyORM)
# Name of this qmake variable is crucial
TINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyOrm-builds-qmake/build-TinyOrm-Desktop_Qt_6_3_1_MSVC2019_64bit-Debug)
# vcpkg - range-v3 and tabulate
TINY_VCPKG_INSTALLED = $$clean_path($$PWD/../../../vcpkg/installed)
QMAKEFEATURES *= $$quote($$TINY_MAIN_DIR/TinyORM/qmake/features)
```
:::info
Configuring with the `.qmake.conf` file has one big advantage that is that you do not have to modify the project files.
:::
#### Migrations source files
Create `database/migrations.pri` file and paste the following code.
```qmake
INCLUDEPATH += $$PWD
HEADERS += \
$$PWD/migrations/2014_10_12_000000_create_posts_table.hpp \
```
#### Seeders source files
Create `database/seeders.pri` file and paste the following code.
```qmake
INCLUDEPATH += $$PWD
HEADERS += \
$$PWD/seeders/databaseseeder.hpp \
```
### Build migrations {#build-migrations-qmake}
:::tip
I recommend creating a new `Session` in the `QtCreator IDE` as is described [here](building/tinyorm.mdx#open-qtcreator-ide).
:::
Now you can open the `tom.pro` project in the `QtCreator IDE`.
This will open the `Configure Project` tab, select some kit and update build folder paths to meet our [folders structure](building/tinyorm.mdx#folders-structure) or like you want.
<img src={require('./assets/img/migrations/qmake-configure_project.png').default}
alt='tom - QtCreator - Configure Project' width='760' />
You are ready to configure build options, hit <kbd>Ctrl</kbd>+<kbd>5</kbd> to open `Project Settings` tab and select `Build` in the left sidebar to open the `Build Settings`, it should look similar to the following picture.
<img src={require('./assets/img/migrations/qmake-build_settings.png').default}
className='no-blurry' alt='tom - QtCreator - Build Settings' width='760' />
Disable `QML debugging and profiling` and `Qt Quick Compiler`, they are not used.
In the left sidebar open `Dependencies` and check `TinyOrm` and `Synchronize configuration`, this setting ensures that the current project will be rebuilt correctly when the `TinyORM` library source code changes.
Everything is ready to build, you can press <kbd>Ctrl</kbd>+<kbd>b</kbd> to build the project.
### Execute migrations {#execute-migrations-qmake}
The `QtCreator` takes care about all the necessary configuration, sets up the build environment correctly and also prepends dependency libraries on the path on Windows and on the `LD_LIBRARY_PATH` on Linux.
Only one thing you might want to change is to run the `tom` application in the new terminal window. To do so, hit <kbd>Ctrl</kbd>+<kbd>5</kbd> to open the `Project Settings` tab and select `Run` in the left sidebar to open the `Run Settings`, then in the `Run` section select the `Run in terminal` checkbox.
You can also set the `Command line arguments` in this `Run` section, eg. the `migrate:status`.
To execute the `tom` application press <kbd>Ctrl</kbd> + <kbd>r</kbd>.
The output will look something like this.
<img src={require('./assets/img/migrations/tom_migrate_status.png').default}
alt='Tom migrations - migrate:status command output' width='660' />
Happy migrating 🎉👌
## Finish
As the last thing, you can check that all the file properties were correctly set by the [`rc`](https://docs.microsoft.com/en-us/windows/win32/menurc/resource-compiler) compiler.
Find the `tom.exe` file and press <kbd>Alt</kbd> + <kbd>Enter</kbd> to open the file properties. To check the executable manifest you can use eg. the [Resource Hacker](http://www.angusj.com/resourcehacker/).
<img src={require('./assets/img/migrations/tom_file_properties.png').default}
alt='tom.exe file properties detail' width='440' />