Files
TinyORM/docs/building/migrations.mdx
2022-07-09 06:24:45 +02:00

786 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},
{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-builds-cmake/build-debug`}
</CodeBlock>
</TabItem>
<TabItem value={bash} label={bash_label}>
<CodeBlock className='language-bash'>
{`cd ..
mkdir -p tom-builds-cmake/build-debug\n
cd tom-builds-cmake/build-debug`}
</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.23 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.2.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.23 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.2.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' />