diff --git a/404.html b/404.html index 654ab3110..da2d3c85c 100644 --- a/404.html +++ b/404.html @@ -14,7 +14,7 @@ - + diff --git a/assets/js/8a8faf8d.15047ffd.js b/assets/js/8a8faf8d.66f1a0f2.js similarity index 68% rename from assets/js/8a8faf8d.15047ffd.js rename to assets/js/8a8faf8d.66f1a0f2.js index 744828673..42de9b822 100644 --- a/assets/js/8a8faf8d.15047ffd.js +++ b/assets/js/8a8faf8d.66f1a0f2.js @@ -1 +1 @@ -"use strict";(self.webpackChunktinyorm_org=self.webpackChunktinyorm_org||[]).push([[129],{6455:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>p,contentTitle:()=>u,default:()=>j,frontMatter:()=>h,metadata:()=>m,toc:()=>g});var s=i(4848),t=i(8453),a=i(8774),r=i(2364),l=i(9365),o=i(1470),d=i(7324),c=i(6694);const h={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"]},u="Building: Migrations",m={id:"building/migrations",title:"Building: Migrations",description:"How to compile the TinyORM migrations (tom) C++ console application on Windows and Linux.",source:"@site/docs/building/migrations.mdx",sourceDirName:"building",slug:"/building/migrations",permalink:"/building/migrations",draft:!1,unlisted:!1,tags:[],version:"current",sidebarPosition:3,frontMatter:{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"]},sidebar:"tinyormSidebar",previous:{title:"Hello world",permalink:"/building/hello-world"},next:{title:"\ud83d\udea9 Stability",permalink:"/stability"}},p={},g=[{value:"Introduction",id:"introduction",level:2},{value:"Install dependencies",id:"install-dependencies",level:2},{value:"Using vcpkg.json (manifest mode)",id:"using-vcpkg-json-manifest-mode",level:4},{value:"Using vcpkg install (manually)",id:"using-vcpkg-install-manually",level:4},{value:"Source code",id:"source-code",level:2},{value:"Main file",id:"main-file",level:3},{value:"Migrations",id:"migrations",level:3},{value:"Seeders",id:"seeders",level:3},{value:"Migrations with CMake",id:"migrations-with-cmake",level:2},{value:"CMake project",id:"cmake-project",level:3},{value:"Build migrations",id:"build-migrations-cmake",level:3},{value:"Execute migrations",id:"execute-migrations-cmake",level:3},{value:"Migrations with qmake",id:"migrations-with-qmake",level:2},{value:"qmake project",id:"qmake-project",level:3},{value:"Auto-configure using .qmake.conf and .env",id:"auto-configure-using-qmakeconf-and-env",level:4},{value:"Migrations source files",id:"migrations-source-files",level:4},{value:"Seeders source files",id:"seeders-source-files",level:4},{value:"Build migrations",id:"build-migrations-qmake",level:3},{value:"Execute migrations",id:"execute-migrations-qmake",level:3},{value:"Finish",id:"finish",level:2}];function x(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"building-migrations",children:"Building: Migrations"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#introduction",children:"Introduction"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#install-dependencies",children:"Install dependencies"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#using-vcpkg-json-manifest-mode",children:"Using vcpkg.json"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#using-vcpkg-install-manually",children:"Using vcpkg install"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#source-code",children:"Source code"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#main-file",children:"Main file"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#migrations",children:"Migrations"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#seeders",children:"Seeders"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#migrations-with-cmake",children:"Migrations with CMake"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#cmake-project",children:"CMake project"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#build-migrations-cmake",children:"Build migrations"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#execute-migrations-cmake",children:"Execute migrations"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#migrations-with-qmake",children:"Migrations with qmake"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#qmake-project",children:"qmake project"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#build-migrations-qmake",children:"Build migrations"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#execute-migrations-qmake",children:"Execute migrations"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#finish",children:"Finish"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)("div",{className:"api-stability alert alert--success",children:(0,s.jsxs)(n.p,{children:[(0,s.jsx)(a.A,{to:"/stability#stability-indexes",children:(0,s.jsx)(n.strong,{children:"Stability: 2"})})," - Stable"]})}),"\n",(0,s.jsxs)(n.p,{children:["We will try to create a working migrations console application called as ",(0,s.jsx)("abbr",{title:"TinyORM migrations",children:(0,s.jsx)(n.code,{children:"tom"})})," in the terminal with the ",(0,s.jsx)(n.code,{children:"CMake"})," and in the ",(0,s.jsx)(n.code,{children:"QtCreator IDE"})," with the ",(0,s.jsx)(n.code,{children:"qmake"})," build systems."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"tom"})," console application also expects the following ",(0,s.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:"folders structure"}),", let's create them."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:`cd ${(0,c.OZ)(d.b)}\nmkdir tom/tom\ncd tom`})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:`cd ${(0,c.OZ)(d.xj)}\nmkdir -p tom/tom\ncd tom`})})]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"TinyORM"})," source tree contains the ",(0,s.jsx)(n.code,{children:"tom"})," example application, you can inspire or look at the ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/tree/main/examples/tom",children:"source code"}),". Also, ",(0,s.jsx)(n.code,{children:"TinyORM"})," unit tests use a ",(0,s.jsx)(n.code,{children:"tom"})," migrations internally to create the database structure, internally called as the ",(0,s.jsxs)(n.a,{href:"https://github.com/silverqx/TinyORM/tree/main/tests/testdata_tom",children:[(0,s.jsx)(n.code,{children:"tom"})," migrations for unit tests"]}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["All these three console applications the ",(0,s.jsx)(n.code,{children:"tom"})," example, ",(0,s.jsx)(n.code,{children:"tom"})," migrations for unit tests, and the application described in this tutorial have practically identical source code (the main.cpp file)."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"tom"})," is able to generate ",(0,s.jsx)("a",{href:"https://en.wikipedia.org/wiki/Data_definition_language",title:"Data Definition Language",children:"DDL"})," queries for all the ",(0,s.jsx)(n.a,{href:"/database/getting-started#introduction",children:"supported databases"})," databases."]})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["You can see the ",(0,s.jsx)(n.a,{href:"/features-summary#tom-console-application",children:"Tom showcase image"})," of how the resulting ",(0,s.jsx)(n.code,{children:"tom"})," console application will look like."]})}),"\n",(0,s.jsx)(n.h2,{id:"install-dependencies",children:"Install dependencies"}),"\n",(0,s.jsxs)(n.p,{children:["First, install the ",(0,s.jsx)(n.code,{children:"vcpkg"})," package manager as is described ",(0,s.jsx)(n.a,{href:"/building/tinyorm#vcpkg",children:"here"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"range-v3"})," and ",(0,s.jsx)(n.code,{children:"tabulate"})," libraries are required dependencies because ",(0,s.jsx)(n.code,{children:"TinyORM"})," uses them in header files, you have to install them before you can use ",(0,s.jsx)(n.code,{children:"TinyORM"}),". The ",(0,s.jsx)(n.code,{children:"tabulate"})," library is only needed in the ",(0,s.jsx)(n.code,{children:"tom"})," migrations it's used by the ",(0,s.jsx)(n.code,{children:"migrate:status"})," command."]}),"\n",(0,s.jsxs)(n.p,{children:["There are two ways how to install the ",(0,s.jsx)(n.code,{children:"range-v3"})," and ",(0,s.jsx)(n.code,{children:"tabulate"})," libraries using ",(0,s.jsx)(n.code,{children:"vcpkg"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Also, don't forget to build the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library with the ",(0,s.jsx)(n.code,{children:"tom"})," source code enabled (it's enabled by default) as is described ",(0,s.jsx)(n.a,{href:"/building/tinyorm",children:"here"}),"."]}),"\n",(0,s.jsxs)(n.h4,{id:"using-vcpkg-json-manifest-mode",children:["Using vcpkg.json ",(0,s.jsx)("small",{children:"(manifest mode)"})]}),"\n",(0,s.jsxs)(n.p,{children:["Create a ",(0,s.jsx)(n.code,{children:"vcpkg.json"})," file with the following content. ",(0,s.jsx)(n.code,{children:"CMake"})," example below uses this method."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd tom\nvim vcpkg.json\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",metastring:"title='vcpkg.json'",children:'{\n "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json",\n "name": "tom",\n "version-semver": "0.1.0",\n "maintainers": "Silver Zachara ",\n "description": "Tom console application for TinyORM C++ library",\n "homepage": "https://github.com/silverqx/TinyORM",\n "documentation": "https://www.tinyorm.org/building/migrations",\n "supports": "!(uwp | arm | android | emscripten | osx | ios | xbox | freebsd | openbsd | wasm32)",\n "dependencies": [\n "range-v3",\n "tabulate"\n ]\n}\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Only ",(0,s.jsx)(n.code,{children:"CMake"})," via the ",(0,s.jsx)(n.code,{children:"toolchain file"})," supports this method."]})}),"\n",(0,s.jsxs)(n.h4,{id:"using-vcpkg-install-manually",children:["Using vcpkg install ",(0,s.jsx)("small",{children:"(manually)"})]}),"\n",(0,s.jsxs)(n.p,{children:["This method can be used with both ",(0,s.jsx)(n.code,{children:"CMake"})," and ",(0,s.jsx)(n.code,{children:"qmake"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd ../../vcpkg\n\nvcpkg search range-v3\nvcpkg search tabulate\nvcpkg install range-v3 tabulate\nvcpkg list\n"})}),"\n",(0,s.jsx)(n.h2,{id:"source-code",children:"Source code"}),"\n",(0,s.jsxs)(n.p,{children:["Let's start in the ",(0,s.jsx)(n.code,{children:"tom"})," project folder."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:`cd ${(0,c.OZ)(d.b)}/tom/tom`})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:`cd ${(0,c.OZ)(d.xj)}/tom/tom`})})]}),"\n",(0,s.jsx)(n.h3,{id:"main-file",children:"Main file"}),"\n",(0,s.jsxs)(n.p,{children:["Create ",(0,s.jsx)(n.code,{children:"main.cpp"})," source file."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"vim main.cpp\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["To paste a source code correctly in ",(0,s.jsx)(n.code,{children:"vim"}),", press ",(0,s.jsx)("kbd",{children:"Shift"})," + ",(0,s.jsx)("kbd",{children:"p"}),"."]})}),"\n",(0,s.jsx)(n.p,{children:"And paste the following code."}),"\n",(0,s.jsx)(a.A,{id:"string-constants-example"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-cpp",metastring:"title='main.cpp'",children:'#include \n\n#include \n\n#include "migrations/2014_10_12_000000_create_posts_table.hpp"\n\n#include "seeders/databaseseeder.hpp"\n\nusing Orm::DatabaseManager;\nusing Orm::DB;\n\nusing TomApplication = Tom::Application;\n\nusing namespace Migrations; // NOLINT(google-build-using-namespace)\nusing namespace Seeders; // NOLINT(google-build-using-namespace)\n\n/*! Create the database manager instance and add a database connection. */\nstd::shared_ptr setupDatabaseManager();\n\n/*! C++ main function. */\nint main(int argc, char *argv[])\n{\n try {\n // Ownership of the shared_ptr()\n auto db = setupDatabaseManager();\n\n return TomApplication(argc, argv, std::move(db), "TOM_EXAMPLE_ENV")\n .migrations()\n .seeders()\n // Fire it up \ud83d\udd25\ud83d\ude80\u2728\n .run();\n\n } catch (const std::exception &e) {\n\n TomApplication::logException(e);\n }\n\n return EXIT_FAILURE;\n}\n\nstd::shared_ptr setupDatabaseManager()\n{\n using namespace Orm::Constants; // NOLINT(google-build-using-namespace)\n\n // Ownership of the shared_ptr()\n return DB::create({\n {driver_, QMYSQL},\n {host_, qEnvironmentVariable("DB_MYSQL_HOST", H127001)},\n {port_, qEnvironmentVariable("DB_MYSQL_PORT", P3306)},\n {database_, qEnvironmentVariable("DB_MYSQL_DATABASE", EMPTY)},\n {username_, qEnvironmentVariable("DB_MYSQL_USERNAME", EMPTY)},\n {password_, qEnvironmentVariable("DB_MYSQL_PASSWORD", EMPTY)},\n {charset_, qEnvironmentVariable("DB_MYSQL_CHARSET", UTF8MB4)},\n {collation_, qEnvironmentVariable("DB_MYSQL_COLLATION", UTF8MB40900aici)},\n {timezone_, TZ00},\n /* Specifies what time zone all QDateTime-s will have, the overridden default is\n the QTimeZone::UTC, set to the QTimeZone::LocalTime or\n QtTimeZoneType::DontConvert to use the system local time. */\n {qt_timezone, QVariant::fromValue(QTimeZone::UTC)},\n {strict_, true},\n },\n QStringLiteral("tinyorm_tom_mysql")); // shell:connection\n}\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["If you have defined more database connections then you can tag the lines with the database connection names with the ",(0,s.jsx)(n.code,{children:"// shell:connection"})," comment and this connection names will be provided to the bash, zsh, pwsh completions for the ",(0,s.jsx)(n.code,{children:"--database="})," option \ud83d\ude0e, ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/examples/tom/main.cpp#L76",children:"example"}),"."]})}),"\n",(0,s.jsx)(n.h3,{id:"migrations",children:"Migrations"}),"\n",(0,s.jsxs)(n.p,{children:["If you have already built the ",(0,s.jsx)(n.code,{children:"tom"})," application then you can generate a migrations using the ",(0,s.jsx)(n.a,{href:"/database/migrations#generating-migrations",children:(0,s.jsx)(n.code,{children:"make:migration"})})," command \ud83d\ude0e."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"tom make:migration create_posts_table\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Below is the expected folders structure for the migrations. The ",(0,s.jsx)(n.a,{href:"#migrations-source-files",children:(0,s.jsx)(n.code,{children:"migrations.pri"})})," file is used only by the ",(0,s.jsx)(n.code,{children:"qmake"})," build system and is not needed with ",(0,s.jsx)(n.code,{children:"CMake"})," builds."]}),"\n",(0,s.jsx)(a.A,{id:"folders-structure"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-text",children:"tom/\n\u2514\u2500\u2500 database/\n \u251c\u2500\u2500 migrations/\n \u251c\u2500\u2500 seeders/\n \u251c\u2500\u2500 migrations.pri\n \u2514\u2500\u2500 seeders.pri\n"})}),"\n",(0,s.jsx)(n.p,{children:"Let's create the first migration manually."}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:"mkdir database/migrations\n\nvim database/migrations/2014_10_12_000000_create_posts_table.hpp"})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:"mkdir -p database/migrations\n\nvim database/migrations/2014_10_12_000000_create_posts_table.hpp"})})]}),"\n",(0,s.jsx)(n.p,{children:"And paste the following code."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-cpp",metastring:"title='database/migrations/2014_10_12_000000_create_posts_table.hpp'",children:'#pragma once\n\n#include \n\nnamespace Migrations\n{\n\n struct CreatePostsTable : Migration\n {\n /*! Filename of the migration file. */\n T_MIGRATION\n\n /*! Run the migrations. */\n void up() const override\n {\n Schema::create("posts", [](Blueprint &table)\n {\n table.id();\n\n table.string(NAME);\n table.timestamps();\n });\n }\n\n /*! Reverse the migrations. */\n void down() const override\n {\n Schema::dropIfExists("posts");\n }\n };\n\n} // namespace Migrations\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"TinyORM"})," source tree contains the ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/tests/database/migrations/2014_10_12_000000_create_posts_table.hpp#L5",children:(0,s.jsx)(n.code,{children:"CreatePostsTable"})})," example migration that also acts as the full-fledged example migration. It has defined and also nicely commented all possible features that migration classes can use or define."]})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["If you want, you can also build the ",(0,s.jsx)(n.code,{children:"tom"})," application without the migrations, simply comment out the ",(0,s.jsx)(n.code,{children:"migrations"})," method and the corresponding ",(0,s.jsx)(n.code,{children:'#include "migrations/xyz.hpp"'})," files."]})}),"\n",(0,s.jsx)(n.h3,{id:"seeders",children:"Seeders"}),"\n",(0,s.jsxs)(n.p,{children:["If you have already built the ",(0,s.jsx)(n.code,{children:"tom"})," application then you can generate a seeder using the ",(0,s.jsx)(n.a,{href:"/database/seeding#writing-seeders",children:(0,s.jsx)(n.code,{children:"make:seeder"})})," command \ud83d\ude0e."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"tom make:seeder PostSeeder\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The expected folders structure is described a few paragraphs ",(0,s.jsx)(n.a,{href:"#folders-structure",children:"above"}),". The ",(0,s.jsx)(n.a,{href:"#seeders-source-files",children:(0,s.jsx)(n.code,{children:"seeders.pri"})})," file is used only by the ",(0,s.jsx)(n.code,{children:"qmake"})," build system and is not needed with ",(0,s.jsx)(n.code,{children:"CMake"})," builds."]}),"\n",(0,s.jsx)(n.p,{children:"Let's create the root seeder class manually."}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:"mkdir database/seeders\n\nvim database/seeders/databaseseeder.hpp"})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:"mkdir -p database/seeders\n\nvim database/seeders/databaseseeder.hpp"})})]}),"\n",(0,s.jsx)(n.p,{children:"And paste the following code."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-cpp",metastring:"title='database/seeders/databaseseeder.hpp'",children:'#pragma once\n\n#include \n\nnamespace Seeders\n{\n\n /*! Main database seeder. */\n struct DatabaseSeeder : Seeder\n {\n /*! Run the database seeders. */\n void run() override\n {\n DB::table("posts")->insert({\n {{"name", "1. post"}},\n {{"name", "2. post"}},\n });\n }\n };\n\n} // namespace Seeders\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"TinyORM"})," source tree contains the ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/tests/database/seeders/databaseseeder.hpp#L8",children:(0,s.jsx)(n.code,{children:"DatabaseSeeder"})})," root seeder example class that also acts as the full-fledged example seeder. It has defined and also nicely commented all possible features that seeder classes can use or define."]})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can create more seeder classes like this and use the ",(0,s.jsx)(n.code,{children:"call<>()"})," method to invoke them as is described in the ",(0,s.jsx)(n.a,{href:"/database/seeding#calling-additional-seeders",children:"Calling Additional Seeders"})," section."]})}),"\n",(0,s.jsx)(n.h2,{id:"migrations-with-cmake",children:"Migrations with CMake"}),"\n",(0,s.jsxs)(n.p,{children:["Create a folder for the ",(0,s.jsx)(n.code,{children:"CMake"})," build."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:"cd ..\nmkdir tom-builds-cmake/build-debug\n\ncd tom"})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:"cd ..\nmkdir -p tom-builds-cmake/build-debug\n\ncd tom"})})]}),"\n",(0,s.jsx)(n.h3,{id:"cmake-project",children:"CMake project"}),"\n",(0,s.jsxs)(n.p,{children:["Create ",(0,s.jsx)(n.code,{children:"CMakeLists.txt"})," file with the following content. I leave the comments in the ",(0,s.jsx)(n.code,{children:"CMakeLists.txt"})," file because it's not as simple as the ",(0,s.jsx)(n.code,{children:"Hello world"})," example; to make it clear what's going on."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-cmake",metastring:"title='CMakeLists.txt'",children:'cmake_minimum_required(VERSION VERSION 3.22...3.30 FATAL_ERROR)\n\n# Specify the C++ standard\nset(CMAKE_CXX_STANDARD 20)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\n# Initialize variables\n# ---\n\nset(Tom_ns tom)\nset(Tom_target tom)\n\nfile(REAL_PATH "../../TinyORM" TinyMainDir)\n\nset(TinyOrmSourceDir "${TinyMainDir}/TinyORM")\nset(TinyOrmBuildDir "${TinyMainDir}/TinyORM-builds-cmake/build-debug")\n\n# TinyORM CMake modules (needed to set the executable version and RC file on Windows)\nlist(APPEND CMAKE_MODULE_PATH "${TinyOrmSourceDir}/cmake/CommonModules")\n\n# build tree\nlist(APPEND CMAKE_PREFIX_PATH "${TinyOrmBuildDir}")\n\n# Initialize Project Version\n# ---\n\ninclude(TinyHelpers)\ntiny_read_version(TINY_VERSION\n TINY_VERSION_MAJOR TINY_VERSION_MINOR TINY_VERSION_PATCH TINY_VERSION_TWEAK\n VERSION_HEADER "${TinyOrmSourceDir}/tom/include/tom/version.hpp"\n PREFIX TINYTOM\n HEADER_FOR "${Tom_ns}"\n)\n\n# Basic project\n# ---\n\nproject(${Tom_ns}\n DESCRIPTION "Tom console application for TinyORM C++ library"\n HOMEPAGE_URL "https://www.tinyorm.org"\n LANGUAGES CXX\n VERSION ${TINY_VERSION}\n)\n\n# Tom command-line application\n# ---\n\nadd_executable(${Tom_target}\n main.cpp\n)\nadd_executable(${Tom_ns}::${Tom_target} ALIAS ${Tom_target})\n\n# Tom command-line application specific configuration\n# ---\n\nset_target_properties(${Tom_target}\n PROPERTIES\n C_VISIBILITY_PRESET "hidden"\n CXX_VISIBILITY_PRESET "hidden"\n VISIBILITY_INLINES_HIDDEN YES\n VERSION ${PROJECT_VERSION}\n)\n\ntarget_include_directories(${Tom_target}\n PRIVATE "$"\n)\n\n# Tom command-line application defines\n# ---\n\ntarget_compile_definitions(${Tom_target}\n PRIVATE\n PROJECT_TOM\n)\n\n# Windows resource and manifest files\n# ---\n\n# Find icons, tom/version.hpp, and Windows manifest file for MinGW\nif(CMAKE_SYSTEM_NAME STREQUAL "Windows")\n tiny_set_rc_flags("-I \\"${TinyOrmSourceDir}/tom/resources\\"")\nendif()\n\ninclude(TinyResourceAndManifest)\ntiny_resource_and_manifest(${Tom_target}\n OUTPUT_DIR "${TINY_BUILD_GENDIR}/tmp/"\n RESOURCES_DIR "${TinyOrmSourceDir}/tom/resources"\n)\n\n# Resolve and link dependencies\n# ---\n\nfind_package(QT NAMES Qt6 COMPONENTS Core REQUIRED)\nfind_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)\nfind_package(TinyOrm 0.38.1 CONFIG REQUIRED)\n\n# Unconditional dependencies\ntarget_link_libraries(${Tom_target}\n PRIVATE\n # Never use versionless Qt targets\n Qt${QT_VERSION_MAJOR}::Core\n TinyOrm::TinyOrm\n)\n'})}),"\n",(0,s.jsx)(n.h3,{id:"build-migrations-cmake",children:"Build migrations"}),"\n",(0,s.jsxs)(n.p,{children:["Now you are ready to configure ",(0,s.jsx)(n.code,{children:"tom"})," ",(0,s.jsx)(n.code,{children:"CMake"})," application. Don't forget to prepare the build environment with the ",(0,s.jsx)(n.a,{href:"/building/tinyorm#windows-prerequisites",children:(0,s.jsx)(n.code,{children:"qtenv6.ps1"})})," command if you are building with the ",(0,s.jsx)(n.code,{children:"MSVC"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd ../tom-builds-cmake/build-debug\n"})}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:`cmake.exe \`\n-S "${(0,c.OZ)(d.b)}/tom/tom" \`\n-B "${(0,c.OZ)(d.b)}/tom/tom-builds-cmake/build-debug" \`\n-G 'Ninja' \`\n-D CMAKE_BUILD_TYPE:STRING='Debug' \`\n-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${(0,c.Sn)(d.b)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \`\n-D CMAKE_CXX_SCAN_FOR_MODULES:BOOL=OFF \`\n-D CMAKE_INSTALL_PREFIX:PATH="${(0,c.Sn)(d.b)}/tmp/tom"`})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:`cmake \\\n-S "${(0,c.OZ)(d.xj)}/tom/tom" \\\n-B "${(0,c.OZ)(d.xj)}/tom/tom-builds-cmake/build-debug" \\\n-G 'Ninja' \\\n-D CMAKE_BUILD_TYPE:STRING='Debug' \\\n-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${(0,c.Sn)(d.xj)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \\\n-D CMAKE_CXX_SCAN_FOR_MODULES:BOOL=OFF \\\n-D CMAKE_INSTALL_PREFIX:PATH="${(0,c.Sn)(d.xj)}/tmp/tom"`})})]}),"\n",(0,s.jsx)(n.p,{children:"And build."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cmake --build . --target all\n"})}),"\n",(0,s.jsx)(n.h3,{id:"execute-migrations-cmake",children:"Execute migrations"}),"\n",(0,s.jsxs)(n.p,{children:["Do not forget to add ",(0,s.jsx)(n.code,{children:"TinyOrm0d.dll"})," on the path on Windows and on the ",(0,s.jsx)(n.code,{children:"LD_LIBRARY_PATH"})," on Linux, so ",(0,s.jsx)(n.code,{children:"tom"})," application can find it during execution, as is described ",(0,s.jsx)(n.a,{href:"/building/tinyorm#tinyorm-on-path-cmake",children:"here"}),"."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,name:"tinyorm-on-path",children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:`$env:Path = "${(0,c.OZ)(d.b,!1)}\\TinyORM\\TinyORM-builds-cmake\\build-debug;" + $env:Path`})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:`export LD_LIBRARY_PATH=${(0,c.OZ)(d.xj)}/TinyORM/TinyORM-builds-cmake/build-debug\${PATH:+:}$PATH`})})]}),"\n",(0,s.jsxs)(n.p,{children:["Execute ",(0,s.jsx)(n.code,{children:"tom"})," application."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-powershell",children:".\\tom.exe migrate:status\n"})})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"./tom migrate:status\n"})})})]}),"\n",(0,s.jsx)(n.p,{children:"The output will look something like this."}),"\n",(0,s.jsx)("img",{src:i(53).A,alt:"Tom migrations - migrate:status command output",width:"660"}),"\n",(0,s.jsxs)(n.p,{children:["See also the ",(0,s.jsx)(n.a,{href:"#finish",children:"final thoughts"})," on how to verify the ",(0,s.jsx)(n.code,{children:"tom"})," executable file properties."]}),"\n",(0,s.jsx)(n.p,{children:"Happy migrating \ud83c\udf89\ud83d\udc4c"}),"\n",(0,s.jsx)(n.h2,{id:"migrations-with-qmake",children:"Migrations with qmake"}),"\n",(0,s.jsxs)(n.p,{children:["Create a folder for the ",(0,s.jsx)(n.code,{children:"qmake"})," build."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:`cd ${(0,c.OZ)(d.b)}/tom\n\nmkdir tom-builds-qmake`})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:`cd ${(0,c.OZ)(d.xj)}/tom\n\nmkdir tom-builds-qmake`})})]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"#source-code",children:(0,s.jsx)(n.code,{children:"source code"})})," is the same as for the ",(0,s.jsx)(n.code,{children:"Migrations with CMake"})," console application."]}),"\n",(0,s.jsx)(n.h3,{id:"qmake-project",children:"qmake project"}),"\n",(0,s.jsxs)(n.p,{children:["Create ",(0,s.jsx)(n.code,{children:"tom.pro"})," qmake file with the following content."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd tom\nvim tom.pro\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["To paste a source code correctly in ",(0,s.jsx)(n.code,{children:"vim"}),", press ",(0,s.jsx)("kbd",{children:"Shift"})," + ",(0,s.jsx)("kbd",{children:"p"}),"."]})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"title='tom.pro'",children:"QT -= gui\n\nTEMPLATE = app\nTARGET = tom\n\nCONFIG *= cmdline\n\nDEFINES *= PROJECT_TOM\n\nSOURCES += $$PWD/main.cpp\n\n# Database migrations\ninclude($$PWD/database/migrations.pri)\n# Database seeders\ninclude($$PWD/database/seeders.pri)\n\n# Auto-configure TinyORM library for the migrations purposes \ud83d\udd25\ninclude($$TINY_MAIN_DIR/TinyORM/qmake/tom.pri)\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:["The exact ",(0,s.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:"folders structure"})," is crucial in this example because the paths to the ",(0,s.jsx)(n.code,{children:"TinyORM"})," source and build folders are relative."]})}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsx)(n.p,{children:"Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!"})}),"\n",(0,s.jsxs)(n.h4,{id:"auto-configure-using-qmakeconf-and-env",children:[(0,s.jsx)(n.code,{children:"Auto-configure"})," using ",(0,s.jsx)(n.code,{children:".qmake.conf"})," and ",(0,s.jsx)(n.code,{children:".env"})]}),"\n",(0,s.jsxs)(n.p,{children:["If you want to have properly configured ",(0,s.jsx)(n.code,{children:"DEFINES"})," (C preprocessor macros), have Qt headers marked as system headers, or eg. have properly set properties of an executable file such as version and description, then you need to specify a path to the ",(0,s.jsx)(n.code,{children:"TinyORM"})," qmake features (",(0,s.jsx)(n.code,{children:".prf"})," files) which handle this correctly; this path is provided by the ",(0,s.jsx)(n.code,{children:"QMAKEFEATURES"})," variable and can only be set in the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," file."]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["Read the ",(0,s.jsx)(n.a,{href:"/building/tinyorm#consume-tinyorm-library-qmake",children:"Consume TinyOrm library (qmake)"})," section, as everything that is described in that section applies here as well."]})}),"\n",(0,s.jsxs)(n.p,{children:["Create the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," file in the ",(0,s.jsx)(n.code,{children:"tom"})," application root folder with the following content."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"title='.qmake.conf'",children:"# Path to the PARENT folder of the TinyORM source folder\nTINY_MAIN_DIR = $$clean_path($$PWD/../../TinyORM/)\n# To find .env and .env.$$QMAKE_PLATFORM files\nTINY_DOTENV_ROOT = $$PWD\n# Path to the current build tree (used to guess the TinyORM build tree)\n#TINY_BUILD_TREE = $$shadowed($$PWD)\n\n# To find .prf files, needed by eg. CONFIG += tiny_system_headers inline/extern_constants\nQMAKEFEATURES *= $$quote($$TINY_MAIN_DIR/TinyORM/qmake/features)\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Then, create a ",(0,s.jsx)("code",{children:".env.(win32|unix|mingw)"})," file in the ",(0,s.jsx)(n.code,{children:"tom"})," application root folder with the following content."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:".env.win32",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",children:"# Names and values of these qmake variables are crucial, they are used in the tom.pro\n# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!\n\n# Path to the TinyORM build folder\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_2_MSVC2022_64bit-Debug/)\n\n# Path to the vcpkg - range-v3 and tabulate\n# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty\nTINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)\nTINY_VCPKG_TRIPLET = x64-windows\n\n# Enable ccache wrapper\n#CONFIG *= ccache\n"})})}),(0,s.jsx)(l.A,{value:d.xj,label:".env.unix",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",children:"# Names and values of these qmake variables are crucial, they are used in the tom.pro\n# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!\n\n# Path to the TinyORM build folder\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_2_clang18_64bit_ccache-Debug/)\n\n# Path to the vcpkg - range-v3 and tabulate\n# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty\nTINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)\nTINY_VCPKG_TRIPLET = x64-linux\n\n# Use faster linker\nclang: CONFIG *= use_lld_linker\nelse: CONFIG *= use_gold_linker\n\n# Or use the mold linker\n#QMAKE_LFLAGS *= -fuse-ld=mold\n"})})}),(0,s.jsx)(l.A,{value:"mingw",label:".env.mingw",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",children:"# Names and values of these qmake variables are crucial, they are used in the tom.pro\n# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!\n\n# Path to the TinyORM build folder\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_2_MSYS2_UCRT64_clang_64bit-Debug/)\n\n# Path to the vcpkg - range-v3 and tabulate\n# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty\nTINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)\nTINY_VCPKG_TRIPLET = x64-mingw-dynamic\n\n# Enable ccache wrapper\n#CONFIG *= ccache\n\n# Use faster linker (for both GCC and Clang)\n# CONFIG *= use_lld_linker does not work on MinGW\nQMAKE_LFLAGS *= -fuse-ld=lld\n"})})})]}),"\n",(0,s.jsxs)(n.p,{children:["Don't forget to update the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," and ",(0,s.jsx)(n.code,{children:"TINY_VCPKG_ROOT"})," folder paths to your needs if you are not using the recommended ",(0,s.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:(0,s.jsx)(n.code,{children:"Folders structure"})}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["You can use the ",(0,s.jsxs)(n.a,{href:"/building/tinyorm#partial-guessing-of-the-tinyorm_build_tree",children:["Partial guessing of the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})]})," if you don't like to specify it manually. Just comment out the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," and uncomment the ",(0,s.jsx)(n.code,{children:"TINY_BUILD_TREE = $$shadowed($$PWD)"})," in the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," file."]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can entirely avoid the ",(0,s.jsx)(n.code,{children:".env"})," files, just move the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," to the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," or remove it by help of ",(0,s.jsxs)(n.a,{href:"/building/tinyorm#partial-guessing-of-the-tinyorm_build_tree",children:["Partial guessing of the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})]})," and set the ",(0,s.jsx)(n.code,{children:"VCPKG_ROOT"})," environment variable at system level as is described in ",(0,s.jsx)(n.a,{href:"/building/tinyorm#set-up-vcpkg-environment",children:(0,s.jsx)(n.code,{children:"Set up vcpkg environment"})}),"."]})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["Configuring by the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," and ",(0,s.jsx)(n.code,{children:".env"})," files has one big advantage, which is that you don't have to modify the project files."]})}),"\n",(0,s.jsx)(n.h4,{id:"migrations-source-files",children:"Migrations source files"}),"\n",(0,s.jsxs)(n.p,{children:["Create ",(0,s.jsx)(n.code,{children:"database/migrations.pri"})," file and paste the following code."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"title='database/migrations.pri'",children:"INCLUDEPATH *= $$PWD\n\nHEADERS += \\\n $$PWD/migrations/2014_10_12_000000_create_posts_table.hpp \\\n"})}),"\n",(0,s.jsx)(n.h4,{id:"seeders-source-files",children:"Seeders source files"}),"\n",(0,s.jsxs)(n.p,{children:["Create ",(0,s.jsx)(n.code,{children:"database/seeders.pri"})," file and paste the following code."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"title='database/seeders.pri'",children:"INCLUDEPATH *= $$PWD\n\nHEADERS += \\\n $$PWD/seeders/databaseseeder.hpp \\\n"})}),"\n",(0,s.jsx)(n.h3,{id:"build-migrations-qmake",children:"Build migrations"}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["I recommend creating a new ",(0,s.jsx)(n.code,{children:"Session"})," in the ",(0,s.jsx)(n.code,{children:"QtCreator IDE"})," as is described ",(0,s.jsx)(n.a,{href:"/building/tinyorm#open-qtcreator-ide",children:"here"}),"."]})}),"\n",(0,s.jsxs)(n.p,{children:["Now you can open the ",(0,s.jsx)(n.code,{children:"tom.pro"})," project in the ",(0,s.jsx)(n.code,{children:"QtCreator IDE"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["This will open the ",(0,s.jsx)(n.code,{children:"Configure Project"})," tab, select some kit and update build folder paths to meet our ",(0,s.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:"folders structure"})," or like you want."]}),"\n",(0,s.jsx)("img",{src:i(2394).A,alt:"tom - QtCreator - Configure Project",width:"760"}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can force the ",(0,s.jsx)(n.code,{children:"QtCreator"})," to generate a build folders structure as is described ",(0,s.jsx)(n.a,{href:"/building/tinyorm#qtcreator-default-build-directory",children:"here"}),"."]})}),"\n",(0,s.jsxs)(n.p,{children:["You are ready to configure build options, hit ",(0,s.jsx)("kbd",{children:"Ctrl"}),"+",(0,s.jsx)("kbd",{children:"5"})," to open ",(0,s.jsx)(n.code,{children:"Project Settings"})," tab and select ",(0,s.jsx)(n.code,{children:"Build"})," in the left sidebar to open the ",(0,s.jsx)(n.code,{children:"Build Settings"}),", it should look similar to the following picture."]}),"\n",(0,s.jsx)("img",{src:i(6106).A,className:"no-blurry",alt:"tom - QtCreator - Build Settings",width:"760"}),"\n",(0,s.jsxs)(n.p,{children:["Disable ",(0,s.jsx)(n.code,{children:"QML debugging and profiling"})," and ",(0,s.jsx)(n.code,{children:"Qt Quick Compiler"}),", they are not used."]}),"\n",(0,s.jsxs)(n.p,{children:["In the left sidebar open ",(0,s.jsx)(n.code,{children:"Dependencies"})," and check ",(0,s.jsx)(n.code,{children:"TinyORM"})," project and ",(0,s.jsx)(n.code,{children:"Synchronize configuration"}),", this setting ensures that the current project will be rebuilt correctly when the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library source code changes."]}),"\n",(0,s.jsxs)(n.p,{children:["Everything is ready to build, you can press ",(0,s.jsx)("kbd",{children:"Ctrl"}),"+",(0,s.jsx)("kbd",{children:"b"})," to build the project."]}),"\n",(0,s.jsx)(n.h3,{id:"execute-migrations-qmake",children:"Execute migrations"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"QtCreator"})," takes care of all the necessary configurations, sets up the build environment correctly, and also prepends dependency libraries on the system path on Windows and on the ",(0,s.jsx)(n.code,{children:"LD_LIBRARY_PATH"})," on Linux."]}),"\n",(0,s.jsxs)(n.p,{children:["The only thing you might want to change is to run the ",(0,s.jsx)(n.code,{children:"tom"})," application in the new terminal window. To do so, hit ",(0,s.jsx)("kbd",{children:"Ctrl"}),"+",(0,s.jsx)("kbd",{children:"5"})," to open the ",(0,s.jsx)(n.code,{children:"Project Settings"})," tab and select ",(0,s.jsx)(n.code,{children:"Run"})," in the left sidebar to open the ",(0,s.jsx)(n.code,{children:"Run Settings"}),", then in the ",(0,s.jsx)(n.code,{children:"Run"})," section select the ",(0,s.jsx)(n.code,{children:"Run in terminal"})," checkbox."]}),"\n",(0,s.jsxs)(n.p,{children:["You can also set the ",(0,s.jsx)(n.code,{children:"Command line arguments"})," in this ",(0,s.jsx)(n.code,{children:"Run"})," section, eg. the ",(0,s.jsx)(n.code,{children:"migrate:status"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["To execute the ",(0,s.jsx)(n.code,{children:"tom"})," application press ",(0,s.jsx)("kbd",{children:"Ctrl"})," + ",(0,s.jsx)("kbd",{children:"r"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The output will look ",(0,s.jsx)(n.strong,{children:"very similar"})," to this if you add more migrations."]}),"\n",(0,s.jsx)("img",{src:i(53).A,alt:"Tom migrations - migrate:status command output",width:"660"}),"\n",(0,s.jsx)(n.p,{children:"Happy migrating \ud83c\udf89\ud83d\udc4c"}),"\n",(0,s.jsx)(n.h2,{id:"finish",children:"Finish"}),"\n",(0,s.jsxs)(n.p,{children:["As the last thing, you can check that all the file properties were correctly set by the ",(0,s.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/windows/win32/menurc/resource-compiler",children:(0,s.jsx)(n.code,{children:"rc"})})," compiler."]}),"\n",(0,s.jsxs)(n.p,{children:["Find the ",(0,s.jsx)(n.code,{children:"tom.exe"})," file and press ",(0,s.jsx)("kbd",{children:"Alt"})," + ",(0,s.jsx)("kbd",{children:"Enter"})," to open the file properties. To check the executable manifest you can use eg. the ",(0,s.jsx)(n.a,{href:"http://www.angusj.com/resourcehacker/",children:"Resource Hacker"}),"."]}),"\n",(0,s.jsx)("img",{src:i(4679).A,alt:"tom.exe file properties detail",width:"440"})]})}function j(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(x,{...e})}):x(e)}},9365:(e,n,i)=>{i.d(n,{A:()=>r});i(6540);var s=i(4164);const t={tabItem:"tabItem_Ymn6"};var a=i(4848);function r(e){let{children:n,hidden:i,className:r}=e;return(0,a.jsx)("div",{role:"tabpanel",className:(0,s.A)(t.tabItem,r),hidden:i,children:n})}},1470:(e,n,i)=>{i.d(n,{A:()=>v});var s=i(6540),t=i(4164),a=i(3104),r=i(6347),l=i(205),o=i(7485),d=i(1682),c=i(679);function h(e){return s.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,s.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function u(e){const{values:n,children:i}=e;return(0,s.useMemo)((()=>{const e=n??function(e){return h(e).map((e=>{let{props:{value:n,label:i,attributes:s,default:t}}=e;return{value:n,label:i,attributes:s,default:t}}))}(i);return function(e){const n=(0,d.XI)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[n,i])}function m(e){let{value:n,tabValues:i}=e;return i.some((e=>e.value===n))}function p(e){let{queryString:n=!1,groupId:i}=e;const t=(0,r.W6)(),a=function(e){let{queryString:n=!1,groupId:i}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!i)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return i??null}({queryString:n,groupId:i});return[(0,o.aZ)(a),(0,s.useCallback)((e=>{if(!a)return;const n=new URLSearchParams(t.location.search);n.set(a,e),t.replace({...t.location,search:n.toString()})}),[a,t])]}function g(e){const{defaultValue:n,queryString:i=!1,groupId:t}=e,a=u(e),[r,o]=(0,s.useState)((()=>function(e){let{defaultValue:n,tabValues:i}=e;if(0===i.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!m({value:n,tabValues:i}))throw new Error(`Docusaurus error: The has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${i.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const s=i.find((e=>e.default))??i[0];if(!s)throw new Error("Unexpected error: 0 tabValues");return s.value}({defaultValue:n,tabValues:a}))),[d,h]=p({queryString:i,groupId:t}),[g,x]=function(e){let{groupId:n}=e;const i=function(e){return e?`docusaurus.tab.${e}`:null}(n),[t,a]=(0,c.Dv)(i);return[t,(0,s.useCallback)((e=>{i&&a.set(e)}),[i,a])]}({groupId:t}),j=(()=>{const e=d??g;return m({value:e,tabValues:a})?e:null})();(0,l.A)((()=>{j&&o(j)}),[j]);return{selectedValue:r,selectValue:(0,s.useCallback)((e=>{if(!m({value:e,tabValues:a}))throw new Error(`Can't select invalid tab value=${e}`);o(e),h(e),x(e)}),[h,x,a]),tabValues:a}}var x=i(2303);const j={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var b=i(4848);function f(e){let{className:n,block:i,selectedValue:s,selectValue:r,tabValues:l}=e;const o=[],{blockElementScrollPositionUntilNextRender:d}=(0,a.a_)(),c=e=>{const n=e.currentTarget,i=o.indexOf(n),t=l[i].value;t!==s&&(d(n),r(t))},h=e=>{let n=null;switch(e.key){case"Enter":c(e);break;case"ArrowRight":{const i=o.indexOf(e.currentTarget)+1;n=o[i]??o[0];break}case"ArrowLeft":{const i=o.indexOf(e.currentTarget)-1;n=o[i]??o[o.length-1];break}}n?.focus()};return(0,b.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,t.A)("tabs",{"tabs--block":i},n),children:l.map((e=>{let{value:n,label:i,attributes:a}=e;return(0,b.jsx)("li",{role:"tab",tabIndex:s===n?0:-1,"aria-selected":s===n,ref:e=>o.push(e),onKeyDown:h,onClick:c,...a,className:(0,t.A)("tabs__item",j.tabItem,a?.className,{"tabs__item--active":s===n}),children:i??n},n)}))})}function _(e){let{lazy:n,children:i,selectedValue:a}=e;const r=(Array.isArray(i)?i:[i]).filter(Boolean);if(n){const e=r.find((e=>e.props.value===a));return e?(0,s.cloneElement)(e,{className:(0,t.A)("margin-top--md",e.props.className)}):null}return(0,b.jsx)("div",{className:"margin-top--md",children:r.map(((e,n)=>(0,s.cloneElement)(e,{key:n,hidden:e.props.value!==a})))})}function T(e){const n=g(e);return(0,b.jsxs)("div",{className:(0,t.A)("tabs-container",j.tabList),children:[(0,b.jsx)(f,{...n,...e}),(0,b.jsx)(_,{...n,...e})]})}function v(e){const n=(0,x.A)();return(0,b.jsx)(T,{...e,children:h(e.children)},String(n))}},7324:(e,n,i)=>{i.d(n,{$E:()=>x,A3:()=>b,CW:()=>j,Dx:()=>c,F4:()=>u,Fi:()=>d,J_:()=>v,LQ:()=>f,Lf:()=>y,OO:()=>t,Q7:()=>_,b:()=>l,cy:()=>o,gg:()=>p,kl:()=>m,os:()=>h,pW:()=>a,ux:()=>g,vf:()=>s,xj:()=>r,xt:()=>T});const s="shell",t="database",a="application",r="bash",l="pwsh",o="zsh",d="maria",c="mysql",h="postgres",u="sqlite",m="application",p="bash",g="pwsh",x="zsh",j="MariaDB",b="MySQL",f="PostgreSQL",_="SQLite",T="tinyorm.org",v="$HOME/Code/c/",y="$env:USERPROFILE\\Code\\c\\"},6362:(e,n,i)=>{i.d(n,{A:()=>a});var s=i(6540),t=i(1838);function a(){const e=(0,s.useContext)(t.A);if(null!=e)return e;throw new Error("useRootFolderContext is used outside of Layout component.")}},6694:(e,n,i)=>{i.d(n,{OZ:()=>o,Sn:()=>r,T3:()=>c,bw:()=>d,nC:()=>h,np:()=>l});var s=i(6362),t=i(2303),a=i(7324);const r=function(e,n){return void 0===n&&(n=!0),u((0,s.A)().rootFolder[e]??d(e),e,n)},l=()=>(0,s.A)().rootFolder[a.pW]??d(a.pW),o=function(e,n){if(void 0===n&&(n=!0),null==e)throw new Error("The groupId in the applicationFolderPath() can not be empty.");const i=n||e!==a.b?"/":"\\";return u(r(e)+i+l(),e,n)};function d(e){if(null==e)throw new Error("The groupId in the folderDefaultValue() can not be empty.");if(!(0,t.A)())return"";switch(e){case a.b:return a.Lf;case a.xj:return a.J_;case a.pW:return a.xt;default:throw new Error(`No default value for '${e}' groupId in the folderDefaultValue().`)}}function c(e){return e===a.pW}function h(e,n){if(null==n||""===n)return n;const i="$ENV{$1}$2";switch(e){case a.b:return p(n).replace(/\$env:(.+?)(\/.*)/,i);case a.xj:return n.replace(/\$(.+?)(\/.*)/,i);default:throw new Error(`Unsupported shell type '${e}' in the convertToCmakeEnvVariable().`)}}function u(e,n,i){if(void 0===i&&(i=!0),null==e||""===e)return e;if(n!==a.b)return m(e);const s=m(e);return i?p(s):function(e){return null==e||""===e?e:e.replaceAll(/\/+/g,"\\")}(s)}function m(e){return null==e||""===e?e:e.replace(/[/\\]+$/,"")}function p(e){return null==e||""===e?e:e.replaceAll(/\\+(?! )/g,"/")}},6106:(e,n,i)=>{i.d(n,{A:()=>s});const s=i.p+"assets/images/qmake-build_settings-e10927d1c4ed852620f9eb7564198940.png"},2394:(e,n,i)=>{i.d(n,{A:()=>s});const s=i.p+"assets/images/qmake-configure_project-4721257090370204b0272d166512adef.png"},4679:(e,n,i)=>{i.d(n,{A:()=>s});const s=i.p+"assets/images/tom_file_properties-0df513c47ceadd5c09165e41c6b53086.png"},53:(e,n,i)=>{i.d(n,{A:()=>s});const s=i.p+"assets/images/tom_migrate_status-63c129a10bfe6bffe8d2d5ea280860e5.png"}}]); \ No newline at end of file +"use strict";(self.webpackChunktinyorm_org=self.webpackChunktinyorm_org||[]).push([[129],{6455:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>p,contentTitle:()=>u,default:()=>j,frontMatter:()=>h,metadata:()=>m,toc:()=>g});var s=i(4848),t=i(8453),a=i(8774),r=i(2364),l=i(9365),o=i(1470),d=i(7324),c=i(6694);const h={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"]},u="Building: Migrations",m={id:"building/migrations",title:"Building: Migrations",description:"How to compile the TinyORM migrations (tom) C++ console application on Windows and Linux.",source:"@site/docs/building/migrations.mdx",sourceDirName:"building",slug:"/building/migrations",permalink:"/building/migrations",draft:!1,unlisted:!1,tags:[],version:"current",sidebarPosition:3,frontMatter:{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"]},sidebar:"tinyormSidebar",previous:{title:"Hello world",permalink:"/building/hello-world"},next:{title:"\ud83d\udea9 Stability",permalink:"/stability"}},p={},g=[{value:"Introduction",id:"introduction",level:2},{value:"Install dependencies",id:"install-dependencies",level:2},{value:"Using vcpkg.json (manifest mode)",id:"using-vcpkg-json-manifest-mode",level:4},{value:"Using vcpkg install (manually)",id:"using-vcpkg-install-manually",level:4},{value:"Source code",id:"source-code",level:2},{value:"Main file",id:"main-file",level:3},{value:"Migrations",id:"migrations",level:3},{value:"Seeders",id:"seeders",level:3},{value:"Migrations with CMake",id:"migrations-with-cmake",level:2},{value:"CMake project",id:"cmake-project",level:3},{value:"Build migrations",id:"build-migrations-cmake",level:3},{value:"Execute migrations",id:"execute-migrations-cmake",level:3},{value:"Migrations with qmake",id:"migrations-with-qmake",level:2},{value:"qmake project",id:"qmake-project",level:3},{value:"Auto-configure using .qmake.conf and .env",id:"auto-configure-using-qmakeconf-and-env",level:4},{value:"Migrations source files",id:"migrations-source-files",level:4},{value:"Seeders source files",id:"seeders-source-files",level:4},{value:"Build migrations",id:"build-migrations-qmake",level:3},{value:"Execute migrations",id:"execute-migrations-qmake",level:3},{value:"Finish",id:"finish",level:2}];function x(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"building-migrations",children:"Building: Migrations"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#introduction",children:"Introduction"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#install-dependencies",children:"Install dependencies"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#using-vcpkg-json-manifest-mode",children:"Using vcpkg.json"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#using-vcpkg-install-manually",children:"Using vcpkg install"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#source-code",children:"Source code"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#main-file",children:"Main file"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#migrations",children:"Migrations"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#seeders",children:"Seeders"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#migrations-with-cmake",children:"Migrations with CMake"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#cmake-project",children:"CMake project"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#build-migrations-cmake",children:"Build migrations"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#execute-migrations-cmake",children:"Execute migrations"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#migrations-with-qmake",children:"Migrations with qmake"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#qmake-project",children:"qmake project"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#build-migrations-qmake",children:"Build migrations"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#execute-migrations-qmake",children:"Execute migrations"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#finish",children:"Finish"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)("div",{className:"api-stability alert alert--success",children:(0,s.jsxs)(n.p,{children:[(0,s.jsx)(a.A,{to:"/stability#stability-indexes",children:(0,s.jsx)(n.strong,{children:"Stability: 2"})})," - Stable"]})}),"\n",(0,s.jsxs)(n.p,{children:["We will try to create a working migrations console application called as ",(0,s.jsx)("abbr",{title:"TinyORM migrations",children:(0,s.jsx)(n.code,{children:"tom"})})," in the terminal with the ",(0,s.jsx)(n.code,{children:"CMake"})," and in the ",(0,s.jsx)(n.code,{children:"QtCreator IDE"})," with the ",(0,s.jsx)(n.code,{children:"qmake"})," build systems."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"tom"})," console application also expects the following ",(0,s.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:"folders structure"}),", let's create them."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:`cd ${(0,c.OZ)(d.b)}\nmkdir tom/tom\ncd tom`})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:`cd ${(0,c.OZ)(d.xj)}\nmkdir -p tom/tom\ncd tom`})})]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"TinyORM"})," source tree contains the ",(0,s.jsx)(n.code,{children:"tom"})," example application, you can inspire or look at the ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/tree/main/examples/tom",children:"source code"}),". Also, ",(0,s.jsx)(n.code,{children:"TinyORM"})," unit tests use a ",(0,s.jsx)(n.code,{children:"tom"})," migrations internally to create the database structure, internally called as the ",(0,s.jsxs)(n.a,{href:"https://github.com/silverqx/TinyORM/tree/main/tests/testdata_tom",children:[(0,s.jsx)(n.code,{children:"tom"})," migrations for unit tests"]}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["All these three console applications the ",(0,s.jsx)(n.code,{children:"tom"})," example, ",(0,s.jsx)(n.code,{children:"tom"})," migrations for unit tests, and the application described in this tutorial have practically identical source code (the main.cpp file)."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"tom"})," is able to generate ",(0,s.jsx)("a",{href:"https://en.wikipedia.org/wiki/Data_definition_language",title:"Data Definition Language",children:"DDL"})," queries for all the ",(0,s.jsx)(n.a,{href:"/database/getting-started#introduction",children:"supported databases"})," databases."]})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["You can see the ",(0,s.jsx)(n.a,{href:"/features-summary#tom-console-application",children:"Tom showcase image"})," of how the resulting ",(0,s.jsx)(n.code,{children:"tom"})," console application will look like."]})}),"\n",(0,s.jsx)(n.h2,{id:"install-dependencies",children:"Install dependencies"}),"\n",(0,s.jsxs)(n.p,{children:["First, install the ",(0,s.jsx)(n.code,{children:"vcpkg"})," package manager as is described ",(0,s.jsx)(n.a,{href:"/building/tinyorm#vcpkg",children:"here"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"range-v3"})," and ",(0,s.jsx)(n.code,{children:"tabulate"})," libraries are required dependencies because ",(0,s.jsx)(n.code,{children:"TinyORM"})," uses them in header files, you have to install them before you can use ",(0,s.jsx)(n.code,{children:"TinyORM"}),". The ",(0,s.jsx)(n.code,{children:"tabulate"})," library is only needed in the ",(0,s.jsx)(n.code,{children:"tom"})," migrations it's used by the ",(0,s.jsx)(n.code,{children:"migrate:status"})," command."]}),"\n",(0,s.jsxs)(n.p,{children:["There are two ways how to install the ",(0,s.jsx)(n.code,{children:"range-v3"})," and ",(0,s.jsx)(n.code,{children:"tabulate"})," libraries using ",(0,s.jsx)(n.code,{children:"vcpkg"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Also, don't forget to build the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library with the ",(0,s.jsx)(n.code,{children:"tom"})," source code enabled (it's enabled by default) as is described ",(0,s.jsx)(n.a,{href:"/building/tinyorm",children:"here"}),"."]}),"\n",(0,s.jsxs)(n.h4,{id:"using-vcpkg-json-manifest-mode",children:["Using vcpkg.json ",(0,s.jsx)("small",{children:"(manifest mode)"})]}),"\n",(0,s.jsxs)(n.p,{children:["Create a ",(0,s.jsx)(n.code,{children:"vcpkg.json"})," file with the following content. ",(0,s.jsx)(n.code,{children:"CMake"})," example below uses this method."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd tom\nvim vcpkg.json\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",metastring:"title='vcpkg.json'",children:'{\n "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json",\n "name": "tom",\n "version-semver": "0.1.0",\n "maintainers": "Silver Zachara ",\n "description": "Tom console application for TinyORM C++ library",\n "homepage": "https://github.com/silverqx/TinyORM",\n "documentation": "https://www.tinyorm.org/building/migrations",\n "supports": "!(uwp | arm | android | emscripten | osx | ios | xbox | freebsd | openbsd | wasm32)",\n "dependencies": [\n "range-v3",\n "tabulate"\n ]\n}\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Only ",(0,s.jsx)(n.code,{children:"CMake"})," via the ",(0,s.jsx)(n.code,{children:"toolchain file"})," supports this method."]})}),"\n",(0,s.jsxs)(n.h4,{id:"using-vcpkg-install-manually",children:["Using vcpkg install ",(0,s.jsx)("small",{children:"(manually)"})]}),"\n",(0,s.jsxs)(n.p,{children:["This method can be used with both ",(0,s.jsx)(n.code,{children:"CMake"})," and ",(0,s.jsx)(n.code,{children:"qmake"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd ../../vcpkg\n\nvcpkg search range-v3\nvcpkg search tabulate\nvcpkg install range-v3 tabulate\nvcpkg list\n"})}),"\n",(0,s.jsx)(n.h2,{id:"source-code",children:"Source code"}),"\n",(0,s.jsxs)(n.p,{children:["Let's start in the ",(0,s.jsx)(n.code,{children:"tom"})," project folder."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:`cd ${(0,c.OZ)(d.b)}/tom/tom`})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:`cd ${(0,c.OZ)(d.xj)}/tom/tom`})})]}),"\n",(0,s.jsx)(n.h3,{id:"main-file",children:"Main file"}),"\n",(0,s.jsxs)(n.p,{children:["Create ",(0,s.jsx)(n.code,{children:"main.cpp"})," source file."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"vim main.cpp\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["To paste a source code correctly in ",(0,s.jsx)(n.code,{children:"vim"}),", press ",(0,s.jsx)("kbd",{children:"Shift"})," + ",(0,s.jsx)("kbd",{children:"p"}),"."]})}),"\n",(0,s.jsx)(n.p,{children:"And paste the following code."}),"\n",(0,s.jsx)(a.A,{id:"string-constants-example"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-cpp",metastring:"title='main.cpp'",children:'#include \n\n#include \n\n#include "migrations/2014_10_12_000000_create_posts_table.hpp"\n\n#include "seeders/databaseseeder.hpp"\n\nusing Orm::DatabaseManager;\nusing Orm::DB;\n\nusing TomApplication = Tom::Application;\n\nusing namespace Migrations; // NOLINT(google-build-using-namespace)\nusing namespace Seeders; // NOLINT(google-build-using-namespace)\n\n/*! Create the database manager instance and add a database connection. */\nstd::shared_ptr setupDatabaseManager();\n\n/*! C++ main function. */\nint main(int argc, char *argv[])\n{\n try {\n // Ownership of the shared_ptr()\n auto db = setupDatabaseManager();\n\n return TomApplication(argc, argv, std::move(db), "TOM_EXAMPLE_ENV")\n .migrations()\n .seeders()\n // Fire it up \ud83d\udd25\ud83d\ude80\u2728\n .run();\n\n } catch (const std::exception &e) {\n\n TomApplication::logException(e);\n }\n\n return EXIT_FAILURE;\n}\n\nstd::shared_ptr setupDatabaseManager()\n{\n using namespace Orm::Constants; // NOLINT(google-build-using-namespace)\n\n // Ownership of the shared_ptr()\n return DB::create({\n {driver_, QMYSQL},\n {host_, qEnvironmentVariable("DB_MYSQL_HOST", H127001)},\n {port_, qEnvironmentVariable("DB_MYSQL_PORT", P3306)},\n {database_, qEnvironmentVariable("DB_MYSQL_DATABASE", EMPTY)},\n {username_, qEnvironmentVariable("DB_MYSQL_USERNAME", EMPTY)},\n {password_, qEnvironmentVariable("DB_MYSQL_PASSWORD", EMPTY)},\n {charset_, qEnvironmentVariable("DB_MYSQL_CHARSET", UTF8MB4)},\n {collation_, qEnvironmentVariable("DB_MYSQL_COLLATION", UTF8MB40900aici)},\n {timezone_, TZ00},\n /* Specifies what time zone all QDateTime-s will have, the overridden default is\n the QTimeZone::UTC, set to the QTimeZone::LocalTime or\n QtTimeZoneType::DontConvert to use the system local time. */\n {qt_timezone, QVariant::fromValue(QTimeZone::UTC)},\n {strict_, true},\n },\n QStringLiteral("tinyorm_tom_mysql")); // shell:connection\n}\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["If you have defined more database connections then you can tag the lines with the database connection names with the ",(0,s.jsx)(n.code,{children:"// shell:connection"})," comment and this connection names will be provided to the bash, zsh, pwsh completions for the ",(0,s.jsx)(n.code,{children:"--database="})," option \ud83d\ude0e, ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/examples/tom/main.cpp#L76",children:"example"}),"."]})}),"\n",(0,s.jsx)(n.h3,{id:"migrations",children:"Migrations"}),"\n",(0,s.jsxs)(n.p,{children:["If you have already built the ",(0,s.jsx)(n.code,{children:"tom"})," application then you can generate a migrations using the ",(0,s.jsx)(n.a,{href:"/database/migrations#generating-migrations",children:(0,s.jsx)(n.code,{children:"make:migration"})})," command \ud83d\ude0e."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"tom make:migration create_posts_table\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Below is the expected folders structure for the migrations. The ",(0,s.jsx)(n.a,{href:"#migrations-source-files",children:(0,s.jsx)(n.code,{children:"migrations.pri"})})," file is used only by the ",(0,s.jsx)(n.code,{children:"qmake"})," build system and is not needed with ",(0,s.jsx)(n.code,{children:"CMake"})," builds."]}),"\n",(0,s.jsx)(a.A,{id:"folders-structure"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-text",children:"tom/\n\u2514\u2500\u2500 database/\n \u251c\u2500\u2500 migrations/\n \u251c\u2500\u2500 seeders/\n \u251c\u2500\u2500 migrations.pri\n \u2514\u2500\u2500 seeders.pri\n"})}),"\n",(0,s.jsx)(n.p,{children:"Let's create the first migration manually."}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:"mkdir database/migrations\n\nvim database/migrations/2014_10_12_000000_create_posts_table.hpp"})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:"mkdir -p database/migrations\n\nvim database/migrations/2014_10_12_000000_create_posts_table.hpp"})})]}),"\n",(0,s.jsx)(n.p,{children:"And paste the following code."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-cpp",metastring:"title='database/migrations/2014_10_12_000000_create_posts_table.hpp'",children:'#pragma once\n\n#include \n\nnamespace Migrations\n{\n\n struct CreatePostsTable : Migration\n {\n /*! Filename of the migration file. */\n T_MIGRATION\n\n /*! Run the migrations. */\n void up() const override\n {\n Schema::create("posts", [](Blueprint &table)\n {\n table.id();\n\n table.string(NAME);\n table.timestamps();\n });\n }\n\n /*! Reverse the migrations. */\n void down() const override\n {\n Schema::dropIfExists("posts");\n }\n };\n\n} // namespace Migrations\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"TinyORM"})," source tree contains the ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/tests/database/migrations/2014_10_12_000000_create_posts_table.hpp#L5",children:(0,s.jsx)(n.code,{children:"CreatePostsTable"})})," example migration that also acts as the full-fledged example migration. It has defined and also nicely commented all possible features that migration classes can use or define."]})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["If you want, you can also build the ",(0,s.jsx)(n.code,{children:"tom"})," application without the migrations, simply comment out the ",(0,s.jsx)(n.code,{children:"migrations"})," method and the corresponding ",(0,s.jsx)(n.code,{children:'#include "migrations/xyz.hpp"'})," files."]})}),"\n",(0,s.jsx)(n.h3,{id:"seeders",children:"Seeders"}),"\n",(0,s.jsxs)(n.p,{children:["If you have already built the ",(0,s.jsx)(n.code,{children:"tom"})," application then you can generate a seeder using the ",(0,s.jsx)(n.a,{href:"/database/seeding#writing-seeders",children:(0,s.jsx)(n.code,{children:"make:seeder"})})," command \ud83d\ude0e."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"tom make:seeder PostSeeder\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The expected folders structure is described a few paragraphs ",(0,s.jsx)(n.a,{href:"#folders-structure",children:"above"}),". The ",(0,s.jsx)(n.a,{href:"#seeders-source-files",children:(0,s.jsx)(n.code,{children:"seeders.pri"})})," file is used only by the ",(0,s.jsx)(n.code,{children:"qmake"})," build system and is not needed with ",(0,s.jsx)(n.code,{children:"CMake"})," builds."]}),"\n",(0,s.jsx)(n.p,{children:"Let's create the root seeder class manually."}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:"mkdir database/seeders\n\nvim database/seeders/databaseseeder.hpp"})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:"mkdir -p database/seeders\n\nvim database/seeders/databaseseeder.hpp"})})]}),"\n",(0,s.jsx)(n.p,{children:"And paste the following code."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-cpp",metastring:"title='database/seeders/databaseseeder.hpp'",children:'#pragma once\n\n#include \n\nnamespace Seeders\n{\n\n /*! Main database seeder. */\n struct DatabaseSeeder : Seeder\n {\n /*! Run the database seeders. */\n void run() override\n {\n DB::table("posts")->insert({\n {{"name", "1. post"}},\n {{"name", "2. post"}},\n });\n }\n };\n\n} // namespace Seeders\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"TinyORM"})," source tree contains the ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/tests/database/seeders/databaseseeder.hpp#L8",children:(0,s.jsx)(n.code,{children:"DatabaseSeeder"})})," root seeder example class that also acts as the full-fledged example seeder. It has defined and also nicely commented all possible features that seeder classes can use or define."]})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can create more seeder classes like this and use the ",(0,s.jsx)(n.code,{children:"call<>()"})," method to invoke them as is described in the ",(0,s.jsx)(n.a,{href:"/database/seeding#calling-additional-seeders",children:"Calling Additional Seeders"})," section."]})}),"\n",(0,s.jsx)(n.h2,{id:"migrations-with-cmake",children:"Migrations with CMake"}),"\n",(0,s.jsxs)(n.p,{children:["Create a folder for the ",(0,s.jsx)(n.code,{children:"CMake"})," build."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:"cd ..\nmkdir tom-builds-cmake/build-debug\n\ncd tom"})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:"cd ..\nmkdir -p tom-builds-cmake/build-debug\n\ncd tom"})})]}),"\n",(0,s.jsx)(n.h3,{id:"cmake-project",children:"CMake project"}),"\n",(0,s.jsxs)(n.p,{children:["Create ",(0,s.jsx)(n.code,{children:"CMakeLists.txt"})," file with the following content. I leave the comments in the ",(0,s.jsx)(n.code,{children:"CMakeLists.txt"})," file because it's not as simple as the ",(0,s.jsx)(n.code,{children:"Hello world"})," example; to make it clear what's going on."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-cmake",metastring:"title='CMakeLists.txt'",children:'cmake_minimum_required(VERSION VERSION 3.22...3.30 FATAL_ERROR)\n\n# Specify the C++ standard\nset(CMAKE_CXX_STANDARD 20)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\n# Initialize variables\n# ---\n\nset(Tom_ns tom)\nset(Tom_target tom)\n\nfile(REAL_PATH "../../TinyORM" TinyMainDir)\n\nset(TinyOrmSourceDir "${TinyMainDir}/TinyORM")\nset(TinyOrmBuildDir "${TinyMainDir}/TinyORM-builds-cmake/build-debug")\n\n# TinyORM CMake modules (needed to set the executable version and RC file on Windows)\nlist(APPEND CMAKE_MODULE_PATH "${TinyOrmSourceDir}/cmake/CommonModules")\n\n# build tree\nlist(APPEND CMAKE_PREFIX_PATH "${TinyOrmBuildDir}")\n\n# Initialize Project Version\n# ---\n\ninclude(TinyHelpers)\ntiny_read_version(TINY_VERSION\n TINY_VERSION_MAJOR TINY_VERSION_MINOR TINY_VERSION_PATCH TINY_VERSION_TWEAK\n VERSION_HEADER "${TinyOrmSourceDir}/tom/include/tom/version.hpp"\n PREFIX TINYTOM\n HEADER_FOR "${Tom_ns}"\n)\n\n# Basic project\n# ---\n\nproject(${Tom_ns}\n DESCRIPTION "Tom console application for TinyORM C++ library"\n HOMEPAGE_URL "https://www.tinyorm.org"\n LANGUAGES CXX\n VERSION ${TINY_VERSION}\n)\n\n# Tom command-line application\n# ---\n\nadd_executable(${Tom_target}\n main.cpp\n)\nadd_executable(${Tom_ns}::${Tom_target} ALIAS ${Tom_target})\n\n# Tom command-line application specific configuration\n# ---\n\nset_target_properties(${Tom_target}\n PROPERTIES\n C_VISIBILITY_PRESET "hidden"\n CXX_VISIBILITY_PRESET "hidden"\n VISIBILITY_INLINES_HIDDEN YES\n VERSION ${PROJECT_VERSION}\n)\n\ntarget_include_directories(${Tom_target}\n PRIVATE "$"\n)\n\n# Tom command-line application defines\n# ---\n\ntarget_compile_definitions(${Tom_target}\n PRIVATE\n PROJECT_TOM\n)\n\n# Windows resource and manifest files\n# ---\n\n# Find icons, tom/version.hpp, and Windows manifest file for MinGW\nif(CMAKE_SYSTEM_NAME STREQUAL "Windows")\n tiny_set_rc_flags("-I \\"${TinyOrmSourceDir}/tom/resources\\"")\nendif()\n\ninclude(TinyResourceAndManifest)\ntiny_resource_and_manifest(${Tom_target}\n OUTPUT_DIR "${TINY_BUILD_GENDIR}/tmp/"\n RESOURCES_DIR "${TinyOrmSourceDir}/tom/resources"\n)\n\n# Resolve and link dependencies\n# ---\n\nfind_package(QT NAMES Qt6 COMPONENTS Core REQUIRED)\nfind_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)\nfind_package(TinyOrm 0.38.1 CONFIG REQUIRED)\n\n# Unconditional dependencies\ntarget_link_libraries(${Tom_target}\n PRIVATE\n # Never use versionless Qt targets\n Qt${QT_VERSION_MAJOR}::Core\n TinyOrm::TinyOrm\n)\n'})}),"\n",(0,s.jsx)(n.h3,{id:"build-migrations-cmake",children:"Build migrations"}),"\n",(0,s.jsxs)(n.p,{children:["Now you are ready to configure ",(0,s.jsx)(n.code,{children:"tom"})," ",(0,s.jsx)(n.code,{children:"CMake"})," application. Don't forget to prepare the build environment with the ",(0,s.jsx)(n.a,{href:"/building/tinyorm#windows-prerequisites",children:(0,s.jsx)(n.code,{children:"qtenv6.ps1"})})," command if you are building with the ",(0,s.jsx)(n.code,{children:"MSVC"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd ../tom-builds-cmake/build-debug\n"})}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:`cmake.exe \`\n-S "${(0,c.OZ)(d.b)}/tom/tom" \`\n-B "${(0,c.OZ)(d.b)}/tom/tom-builds-cmake/build-debug" \`\n-G 'Ninja' \`\n-D CMAKE_BUILD_TYPE:STRING='Debug' \`\n-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${(0,c.Sn)(d.b)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \`\n-D CMAKE_CXX_SCAN_FOR_MODULES:BOOL=OFF \`\n-D CMAKE_INSTALL_PREFIX:PATH="${(0,c.Sn)(d.b)}/tmp/tom"`})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:`cmake \\\n-S "${(0,c.OZ)(d.xj)}/tom/tom" \\\n-B "${(0,c.OZ)(d.xj)}/tom/tom-builds-cmake/build-debug" \\\n-G 'Ninja' \\\n-D CMAKE_BUILD_TYPE:STRING='Debug' \\\n-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${(0,c.Sn)(d.xj)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \\\n-D CMAKE_CXX_SCAN_FOR_MODULES:BOOL=OFF \\\n-D CMAKE_INSTALL_PREFIX:PATH="${(0,c.Sn)(d.xj)}/tmp/tom"`})})]}),"\n",(0,s.jsx)(n.p,{children:"And build."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cmake --build . --target all\n"})}),"\n",(0,s.jsx)(n.h3,{id:"execute-migrations-cmake",children:"Execute migrations"}),"\n",(0,s.jsxs)(n.p,{children:["Do not forget to add ",(0,s.jsx)(n.code,{children:"TinyOrm0d.dll"})," on the path on Windows and on the ",(0,s.jsx)(n.code,{children:"LD_LIBRARY_PATH"})," on Linux, so ",(0,s.jsx)(n.code,{children:"tom"})," application can find it during execution, as is described ",(0,s.jsx)(n.a,{href:"/building/tinyorm#tinyorm-on-path-cmake",children:"here"}),"."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,name:"tinyorm-on-path",children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:`$env:Path = "${(0,c.OZ)(d.b,!1)}\\TinyORM\\TinyORM-builds-cmake\\build-debug;" + $env:Path`})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:`export LD_LIBRARY_PATH=${(0,c.OZ)(d.xj)}/TinyORM/TinyORM-builds-cmake/build-debug\${PATH:+:}$PATH`})})]}),"\n",(0,s.jsxs)(n.p,{children:["Execute ",(0,s.jsx)(n.code,{children:"tom"})," application."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-powershell",children:".\\tom.exe migrate:status\n"})})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"./tom migrate:status\n"})})})]}),"\n",(0,s.jsx)(n.p,{children:"The output will look something like this."}),"\n",(0,s.jsx)("img",{src:i(53).A,alt:"Tom migrations - migrate:status command output",width:"660"}),"\n",(0,s.jsxs)(n.p,{children:["See also the ",(0,s.jsx)(n.a,{href:"#finish",children:"final thoughts"})," on how to verify the ",(0,s.jsx)(n.code,{children:"tom"})," executable file properties."]}),"\n",(0,s.jsx)(n.p,{children:"Happy migrating \ud83c\udf89\ud83d\udc4c"}),"\n",(0,s.jsx)(n.h2,{id:"migrations-with-qmake",children:"Migrations with qmake"}),"\n",(0,s.jsxs)(n.p,{children:["Create a folder for the ",(0,s.jsx)(n.code,{children:"qmake"})," build."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:d.ux,children:(0,s.jsx)(r.A,{className:"language-powershell",children:`cd ${(0,c.OZ)(d.b)}/tom\n\nmkdir tom-builds-qmake`})}),(0,s.jsx)(l.A,{value:d.xj,label:d.gg,children:(0,s.jsx)(r.A,{className:"language-bash",children:`cd ${(0,c.OZ)(d.xj)}/tom\n\nmkdir tom-builds-qmake`})})]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"#source-code",children:(0,s.jsx)(n.code,{children:"source code"})})," is the same as for the ",(0,s.jsx)(n.code,{children:"Migrations with CMake"})," console application."]}),"\n",(0,s.jsx)(n.h3,{id:"qmake-project",children:"qmake project"}),"\n",(0,s.jsxs)(n.p,{children:["Create ",(0,s.jsx)(n.code,{children:"tom.pro"})," qmake file with the following content."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd tom\nvim tom.pro\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["To paste a source code correctly in ",(0,s.jsx)(n.code,{children:"vim"}),", press ",(0,s.jsx)("kbd",{children:"Shift"})," + ",(0,s.jsx)("kbd",{children:"p"}),"."]})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"title='tom.pro'",children:"QT -= gui\n\nTEMPLATE = app\nTARGET = tom\n\nCONFIG *= cmdline\n\nDEFINES *= PROJECT_TOM\n\nSOURCES += $$PWD/main.cpp\n\n# Database migrations\ninclude($$PWD/database/migrations.pri)\n# Database seeders\ninclude($$PWD/database/seeders.pri)\n\n# Auto-configure TinyORM library for the migrations purposes \ud83d\udd25\ninclude($$TINY_MAIN_DIR/TinyORM/qmake/tom.pri)\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:["The exact ",(0,s.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:"folders structure"})," is crucial in this example because the paths to the ",(0,s.jsx)(n.code,{children:"TinyORM"})," source and build folders are relative."]})}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsx)(n.p,{children:"Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!"})}),"\n",(0,s.jsxs)(n.h4,{id:"auto-configure-using-qmakeconf-and-env",children:[(0,s.jsx)(n.code,{children:"Auto-configure"})," using ",(0,s.jsx)(n.code,{children:".qmake.conf"})," and ",(0,s.jsx)(n.code,{children:".env"})]}),"\n",(0,s.jsxs)(n.p,{children:["If you want to have properly configured ",(0,s.jsx)(n.code,{children:"DEFINES"})," (C preprocessor macros), have Qt headers marked as system headers, or eg. have properly set properties of an executable file such as version and description, then you need to specify a path to the ",(0,s.jsx)(n.code,{children:"TinyORM"})," qmake features (",(0,s.jsx)(n.code,{children:".prf"})," files) which handle this correctly; this path is provided by the ",(0,s.jsx)(n.code,{children:"QMAKEFEATURES"})," variable and can only be set in the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," file."]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["Read the ",(0,s.jsx)(n.a,{href:"/building/tinyorm#consume-tinyorm-library-qmake",children:"Consume TinyOrm library (qmake)"})," section, as everything that is described in that section applies here as well."]})}),"\n",(0,s.jsxs)(n.p,{children:["Create the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," file in the ",(0,s.jsx)(n.code,{children:"tom"})," application root folder with the following content."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"title='.qmake.conf'",children:"# Path to the PARENT folder of the TinyORM source folder\nTINY_MAIN_DIR = $$clean_path($$PWD/../../TinyORM/)\n# To find .env and .env.$$QMAKE_PLATFORM files\nTINY_DOTENV_ROOT = $$PWD\n# Path to the current build tree (used to guess the TinyORM build tree)\n#TINY_BUILD_TREE = $$shadowed($$PWD)\n\n# To find .prf files, needed by eg. CONFIG += tiny_system_headers inline/extern_constants\nQMAKEFEATURES *= $$quote($$TINY_MAIN_DIR/TinyORM/qmake/features)\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Then, create a ",(0,s.jsx)("code",{children:".env.(win32|unix|mingw)"})," file in the ",(0,s.jsx)(n.code,{children:"tom"})," application root folder with the following content."]}),"\n",(0,s.jsxs)(o.A,{groupId:d.vf,children:[(0,s.jsx)(l.A,{value:d.b,label:".env.win32",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",children:"# Names and values of these qmake variables are crucial, they are used in the tom.pro\n# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!\n\n# Path to the TinyORM build folder\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_2_MSVC2022_64bit-Debug/)\n\n# Path to the vcpkg - range-v3 and tabulate\n# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty\nTINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)\nTINY_VCPKG_TRIPLET = x64-windows\n\n# Enable ccache wrapper\n#CONFIG *= ccache\n"})})}),(0,s.jsx)(l.A,{value:d.xj,label:".env.unix",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",children:"# Names and values of these qmake variables are crucial, they are used in the tom.pro\n# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!\n\n# Path to the TinyORM build folder\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_2_clang18_64bit_ccache-Debug/)\n\n# Path to the vcpkg - range-v3 and tabulate\n# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty\nTINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)\nTINY_VCPKG_TRIPLET = x64-linux\n\n# Use LLD linker for Clang\nclang: CONFIG *= use_lld_linker\nelse: CONFIG *= use_gold_linker\n\n# Or use the mold linker\n#QMAKE_LFLAGS *= -fuse-ld=mold\n"})})}),(0,s.jsx)(l.A,{value:"mingw",label:".env.mingw",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",children:"# Names and values of these qmake variables are crucial, they are used in the tom.pro\n# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!\n\n# Path to the TinyORM build folder\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_2_MSYS2_UCRT64_clang_64bit-Debug/)\n\n# Path to the vcpkg - range-v3 and tabulate\n# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty\nTINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)\nTINY_VCPKG_TRIPLET = x64-mingw-dynamic\n\n# Enable ccache wrapper\n#CONFIG *= ccache\n\n# Use alternative linker (for both GCC and Clang)\n# CONFIG *= use_lld_linker does not work on MinGW\n#QMAKE_LFLAGS *= -fuse-ld=lld\n"})})})]}),"\n",(0,s.jsxs)(n.p,{children:["Don't forget to update the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," and ",(0,s.jsx)(n.code,{children:"TINY_VCPKG_ROOT"})," folder paths to your needs if you are not using the recommended ",(0,s.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:(0,s.jsx)(n.code,{children:"Folders structure"})}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["You can use the ",(0,s.jsxs)(n.a,{href:"/building/tinyorm#partial-guessing-of-the-tinyorm_build_tree",children:["Partial guessing of the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})]})," if you don't like to specify it manually. Just comment out the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," and uncomment the ",(0,s.jsx)(n.code,{children:"TINY_BUILD_TREE = $$shadowed($$PWD)"})," in the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," file."]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can entirely avoid the ",(0,s.jsx)(n.code,{children:".env"})," files, just move the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," to the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," or remove it by help of ",(0,s.jsxs)(n.a,{href:"/building/tinyorm#partial-guessing-of-the-tinyorm_build_tree",children:["Partial guessing of the ",(0,s.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})]})," and set the ",(0,s.jsx)(n.code,{children:"VCPKG_ROOT"})," environment variable at system level as is described in ",(0,s.jsx)(n.a,{href:"/building/tinyorm#set-up-vcpkg-environment",children:(0,s.jsx)(n.code,{children:"Set up vcpkg environment"})}),"."]})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["Configuring by the ",(0,s.jsx)(n.code,{children:".qmake.conf"})," and ",(0,s.jsx)(n.code,{children:".env"})," files has one big advantage, which is that you don't have to modify the project files."]})}),"\n",(0,s.jsx)(n.h4,{id:"migrations-source-files",children:"Migrations source files"}),"\n",(0,s.jsxs)(n.p,{children:["Create ",(0,s.jsx)(n.code,{children:"database/migrations.pri"})," file and paste the following code."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"title='database/migrations.pri'",children:"INCLUDEPATH *= $$PWD\n\nHEADERS += \\\n $$PWD/migrations/2014_10_12_000000_create_posts_table.hpp \\\n"})}),"\n",(0,s.jsx)(n.h4,{id:"seeders-source-files",children:"Seeders source files"}),"\n",(0,s.jsxs)(n.p,{children:["Create ",(0,s.jsx)(n.code,{children:"database/seeders.pri"})," file and paste the following code."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-qmake",metastring:"title='database/seeders.pri'",children:"INCLUDEPATH *= $$PWD\n\nHEADERS += \\\n $$PWD/seeders/databaseseeder.hpp \\\n"})}),"\n",(0,s.jsx)(n.h3,{id:"build-migrations-qmake",children:"Build migrations"}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["I recommend creating a new ",(0,s.jsx)(n.code,{children:"Session"})," in the ",(0,s.jsx)(n.code,{children:"QtCreator IDE"})," as is described ",(0,s.jsx)(n.a,{href:"/building/tinyorm#open-qtcreator-ide",children:"here"}),"."]})}),"\n",(0,s.jsxs)(n.p,{children:["Now you can open the ",(0,s.jsx)(n.code,{children:"tom.pro"})," project in the ",(0,s.jsx)(n.code,{children:"QtCreator IDE"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["This will open the ",(0,s.jsx)(n.code,{children:"Configure Project"})," tab, select some kit and update build folder paths to meet our ",(0,s.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:"folders structure"})," or like you want."]}),"\n",(0,s.jsx)("img",{src:i(2394).A,alt:"tom - QtCreator - Configure Project",width:"760"}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can force the ",(0,s.jsx)(n.code,{children:"QtCreator"})," to generate a build folders structure as is described ",(0,s.jsx)(n.a,{href:"/building/tinyorm#qtcreator-default-build-directory",children:"here"}),"."]})}),"\n",(0,s.jsxs)(n.p,{children:["You are ready to configure build options, hit ",(0,s.jsx)("kbd",{children:"Ctrl"}),"+",(0,s.jsx)("kbd",{children:"5"})," to open ",(0,s.jsx)(n.code,{children:"Project Settings"})," tab and select ",(0,s.jsx)(n.code,{children:"Build"})," in the left sidebar to open the ",(0,s.jsx)(n.code,{children:"Build Settings"}),", it should look similar to the following picture."]}),"\n",(0,s.jsx)("img",{src:i(6106).A,className:"no-blurry",alt:"tom - QtCreator - Build Settings",width:"760"}),"\n",(0,s.jsxs)(n.p,{children:["Disable ",(0,s.jsx)(n.code,{children:"QML debugging and profiling"})," and ",(0,s.jsx)(n.code,{children:"Qt Quick Compiler"}),", they are not used."]}),"\n",(0,s.jsxs)(n.p,{children:["In the left sidebar open ",(0,s.jsx)(n.code,{children:"Dependencies"})," and check ",(0,s.jsx)(n.code,{children:"TinyORM"})," project and ",(0,s.jsx)(n.code,{children:"Synchronize configuration"}),", this setting ensures that the current project will be rebuilt correctly when the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library source code changes."]}),"\n",(0,s.jsxs)(n.p,{children:["Everything is ready to build, you can press ",(0,s.jsx)("kbd",{children:"Ctrl"}),"+",(0,s.jsx)("kbd",{children:"b"})," to build the project."]}),"\n",(0,s.jsx)(n.h3,{id:"execute-migrations-qmake",children:"Execute migrations"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"QtCreator"})," takes care of all the necessary configurations, sets up the build environment correctly, and also prepends dependency libraries on the system path on Windows and on the ",(0,s.jsx)(n.code,{children:"LD_LIBRARY_PATH"})," on Linux."]}),"\n",(0,s.jsxs)(n.p,{children:["The only thing you might want to change is to run the ",(0,s.jsx)(n.code,{children:"tom"})," application in the new terminal window. To do so, hit ",(0,s.jsx)("kbd",{children:"Ctrl"}),"+",(0,s.jsx)("kbd",{children:"5"})," to open the ",(0,s.jsx)(n.code,{children:"Project Settings"})," tab and select ",(0,s.jsx)(n.code,{children:"Run"})," in the left sidebar to open the ",(0,s.jsx)(n.code,{children:"Run Settings"}),", then in the ",(0,s.jsx)(n.code,{children:"Run"})," section select the ",(0,s.jsx)(n.code,{children:"Run in terminal"})," checkbox."]}),"\n",(0,s.jsxs)(n.p,{children:["You can also set the ",(0,s.jsx)(n.code,{children:"Command line arguments"})," in this ",(0,s.jsx)(n.code,{children:"Run"})," section, eg. the ",(0,s.jsx)(n.code,{children:"migrate:status"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["To execute the ",(0,s.jsx)(n.code,{children:"tom"})," application press ",(0,s.jsx)("kbd",{children:"Ctrl"})," + ",(0,s.jsx)("kbd",{children:"r"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The output will look ",(0,s.jsx)(n.strong,{children:"very similar"})," to this if you add more migrations."]}),"\n",(0,s.jsx)("img",{src:i(53).A,alt:"Tom migrations - migrate:status command output",width:"660"}),"\n",(0,s.jsx)(n.p,{children:"Happy migrating \ud83c\udf89\ud83d\udc4c"}),"\n",(0,s.jsx)(n.h2,{id:"finish",children:"Finish"}),"\n",(0,s.jsxs)(n.p,{children:["As the last thing, you can check that all the file properties were correctly set by the ",(0,s.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/windows/win32/menurc/resource-compiler",children:(0,s.jsx)(n.code,{children:"rc"})})," compiler."]}),"\n",(0,s.jsxs)(n.p,{children:["Find the ",(0,s.jsx)(n.code,{children:"tom.exe"})," file and press ",(0,s.jsx)("kbd",{children:"Alt"})," + ",(0,s.jsx)("kbd",{children:"Enter"})," to open the file properties. To check the executable manifest you can use eg. the ",(0,s.jsx)(n.a,{href:"http://www.angusj.com/resourcehacker/",children:"Resource Hacker"}),"."]}),"\n",(0,s.jsx)("img",{src:i(4679).A,alt:"tom.exe file properties detail",width:"440"})]})}function j(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(x,{...e})}):x(e)}},9365:(e,n,i)=>{i.d(n,{A:()=>r});i(6540);var s=i(4164);const t={tabItem:"tabItem_Ymn6"};var a=i(4848);function r(e){let{children:n,hidden:i,className:r}=e;return(0,a.jsx)("div",{role:"tabpanel",className:(0,s.A)(t.tabItem,r),hidden:i,children:n})}},1470:(e,n,i)=>{i.d(n,{A:()=>v});var s=i(6540),t=i(4164),a=i(3104),r=i(6347),l=i(205),o=i(7485),d=i(1682),c=i(679);function h(e){return s.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,s.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function u(e){const{values:n,children:i}=e;return(0,s.useMemo)((()=>{const e=n??function(e){return h(e).map((e=>{let{props:{value:n,label:i,attributes:s,default:t}}=e;return{value:n,label:i,attributes:s,default:t}}))}(i);return function(e){const n=(0,d.XI)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[n,i])}function m(e){let{value:n,tabValues:i}=e;return i.some((e=>e.value===n))}function p(e){let{queryString:n=!1,groupId:i}=e;const t=(0,r.W6)(),a=function(e){let{queryString:n=!1,groupId:i}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!i)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return i??null}({queryString:n,groupId:i});return[(0,o.aZ)(a),(0,s.useCallback)((e=>{if(!a)return;const n=new URLSearchParams(t.location.search);n.set(a,e),t.replace({...t.location,search:n.toString()})}),[a,t])]}function g(e){const{defaultValue:n,queryString:i=!1,groupId:t}=e,a=u(e),[r,o]=(0,s.useState)((()=>function(e){let{defaultValue:n,tabValues:i}=e;if(0===i.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!m({value:n,tabValues:i}))throw new Error(`Docusaurus error: The has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${i.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const s=i.find((e=>e.default))??i[0];if(!s)throw new Error("Unexpected error: 0 tabValues");return s.value}({defaultValue:n,tabValues:a}))),[d,h]=p({queryString:i,groupId:t}),[g,x]=function(e){let{groupId:n}=e;const i=function(e){return e?`docusaurus.tab.${e}`:null}(n),[t,a]=(0,c.Dv)(i);return[t,(0,s.useCallback)((e=>{i&&a.set(e)}),[i,a])]}({groupId:t}),j=(()=>{const e=d??g;return m({value:e,tabValues:a})?e:null})();(0,l.A)((()=>{j&&o(j)}),[j]);return{selectedValue:r,selectValue:(0,s.useCallback)((e=>{if(!m({value:e,tabValues:a}))throw new Error(`Can't select invalid tab value=${e}`);o(e),h(e),x(e)}),[h,x,a]),tabValues:a}}var x=i(2303);const j={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var b=i(4848);function f(e){let{className:n,block:i,selectedValue:s,selectValue:r,tabValues:l}=e;const o=[],{blockElementScrollPositionUntilNextRender:d}=(0,a.a_)(),c=e=>{const n=e.currentTarget,i=o.indexOf(n),t=l[i].value;t!==s&&(d(n),r(t))},h=e=>{let n=null;switch(e.key){case"Enter":c(e);break;case"ArrowRight":{const i=o.indexOf(e.currentTarget)+1;n=o[i]??o[0];break}case"ArrowLeft":{const i=o.indexOf(e.currentTarget)-1;n=o[i]??o[o.length-1];break}}n?.focus()};return(0,b.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,t.A)("tabs",{"tabs--block":i},n),children:l.map((e=>{let{value:n,label:i,attributes:a}=e;return(0,b.jsx)("li",{role:"tab",tabIndex:s===n?0:-1,"aria-selected":s===n,ref:e=>o.push(e),onKeyDown:h,onClick:c,...a,className:(0,t.A)("tabs__item",j.tabItem,a?.className,{"tabs__item--active":s===n}),children:i??n},n)}))})}function _(e){let{lazy:n,children:i,selectedValue:a}=e;const r=(Array.isArray(i)?i:[i]).filter(Boolean);if(n){const e=r.find((e=>e.props.value===a));return e?(0,s.cloneElement)(e,{className:(0,t.A)("margin-top--md",e.props.className)}):null}return(0,b.jsx)("div",{className:"margin-top--md",children:r.map(((e,n)=>(0,s.cloneElement)(e,{key:n,hidden:e.props.value!==a})))})}function T(e){const n=g(e);return(0,b.jsxs)("div",{className:(0,t.A)("tabs-container",j.tabList),children:[(0,b.jsx)(f,{...n,...e}),(0,b.jsx)(_,{...n,...e})]})}function v(e){const n=(0,x.A)();return(0,b.jsx)(T,{...e,children:h(e.children)},String(n))}},7324:(e,n,i)=>{i.d(n,{$E:()=>x,A3:()=>b,CW:()=>j,Dx:()=>c,F4:()=>u,Fi:()=>d,J_:()=>v,LQ:()=>f,Lf:()=>y,OO:()=>t,Q7:()=>_,b:()=>l,cy:()=>o,gg:()=>p,kl:()=>m,os:()=>h,pW:()=>a,ux:()=>g,vf:()=>s,xj:()=>r,xt:()=>T});const s="shell",t="database",a="application",r="bash",l="pwsh",o="zsh",d="maria",c="mysql",h="postgres",u="sqlite",m="application",p="bash",g="pwsh",x="zsh",j="MariaDB",b="MySQL",f="PostgreSQL",_="SQLite",T="tinyorm.org",v="$HOME/Code/c/",y="$env:USERPROFILE\\Code\\c\\"},6362:(e,n,i)=>{i.d(n,{A:()=>a});var s=i(6540),t=i(1838);function a(){const e=(0,s.useContext)(t.A);if(null!=e)return e;throw new Error("useRootFolderContext is used outside of Layout component.")}},6694:(e,n,i)=>{i.d(n,{OZ:()=>o,Sn:()=>r,T3:()=>c,bw:()=>d,nC:()=>h,np:()=>l});var s=i(6362),t=i(2303),a=i(7324);const r=function(e,n){return void 0===n&&(n=!0),u((0,s.A)().rootFolder[e]??d(e),e,n)},l=()=>(0,s.A)().rootFolder[a.pW]??d(a.pW),o=function(e,n){if(void 0===n&&(n=!0),null==e)throw new Error("The groupId in the applicationFolderPath() can not be empty.");const i=n||e!==a.b?"/":"\\";return u(r(e)+i+l(),e,n)};function d(e){if(null==e)throw new Error("The groupId in the folderDefaultValue() can not be empty.");if(!(0,t.A)())return"";switch(e){case a.b:return a.Lf;case a.xj:return a.J_;case a.pW:return a.xt;default:throw new Error(`No default value for '${e}' groupId in the folderDefaultValue().`)}}function c(e){return e===a.pW}function h(e,n){if(null==n||""===n)return n;const i="$ENV{$1}$2";switch(e){case a.b:return p(n).replace(/\$env:(.+?)(\/.*)/,i);case a.xj:return n.replace(/\$(.+?)(\/.*)/,i);default:throw new Error(`Unsupported shell type '${e}' in the convertToCmakeEnvVariable().`)}}function u(e,n,i){if(void 0===i&&(i=!0),null==e||""===e)return e;if(n!==a.b)return m(e);const s=m(e);return i?p(s):function(e){return null==e||""===e?e:e.replaceAll(/\/+/g,"\\")}(s)}function m(e){return null==e||""===e?e:e.replace(/[/\\]+$/,"")}function p(e){return null==e||""===e?e:e.replaceAll(/\\+(?! )/g,"/")}},6106:(e,n,i)=>{i.d(n,{A:()=>s});const s=i.p+"assets/images/qmake-build_settings-e10927d1c4ed852620f9eb7564198940.png"},2394:(e,n,i)=>{i.d(n,{A:()=>s});const s=i.p+"assets/images/qmake-configure_project-4721257090370204b0272d166512adef.png"},4679:(e,n,i)=>{i.d(n,{A:()=>s});const s=i.p+"assets/images/tom_file_properties-0df513c47ceadd5c09165e41c6b53086.png"},53:(e,n,i)=>{i.d(n,{A:()=>s});const s=i.p+"assets/images/tom_migrate_status-63c129a10bfe6bffe8d2d5ea280860e5.png"}}]); \ No newline at end of file diff --git a/assets/js/feaee7f3.30e60f2d.js b/assets/js/feaee7f3.b34d2ce3.js similarity index 67% rename from assets/js/feaee7f3.30e60f2d.js rename to assets/js/feaee7f3.b34d2ce3.js index 6fefc2fc4..605eef113 100644 --- a/assets/js/feaee7f3.30e60f2d.js +++ b/assets/js/feaee7f3.b34d2ce3.js @@ -1 +1 @@ -"use strict";(self.webpackChunktinyorm_org=self.webpackChunktinyorm_org||[]).push([[983],{8781:(e,n,l)=>{l.r(n),l.d(n,{assets:()=>m,contentTitle:()=>u,default:()=>g,frontMatter:()=>h,metadata:()=>p,toc:()=>x});var i=l(4848),r=l(8453),t=l(8774),o=l(2364),a=l(9365),s=l(1470),d=l(7324),c=l(6694);const h={sidebar_position:2,sidebar_label:"Hello world",description:"Hello world example created in the terminal and QtCreator IDE.",keywords:["c++ orm","building","hello world","tinyorm"]},u="Building: Hello world",p={id:"building/hello-world",title:"Building: Hello world",description:"Hello world example created in the terminal and QtCreator IDE.",source:"@site/docs/building/hello-world.mdx",sourceDirName:"building",slug:"/building/hello-world",permalink:"/building/hello-world",draft:!1,unlisted:!1,tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2,sidebar_label:"Hello world",description:"Hello world example created in the terminal and QtCreator IDE.",keywords:["c++ orm","building","hello world","tinyorm"]},sidebar:"tinyormSidebar",previous:{title:"TinyORM",permalink:"/building/tinyorm"},next:{title:"Migrations",permalink:"/building/migrations"}},m={},x=[{value:"Introduction",id:"introduction",level:2},{value:"Prepare SQLite 3 database",id:"prepare-sqlite-3-database",level:2},{value:"Install dependencies",id:"install-dependencies",level:2},{value:"Using vcpkg.json (manifest mode)",id:"using-vcpkg-json-manifest-mode",level:4},{value:"Using vcpkg install (manually)",id:"using-vcpkg-install-manually",level:4},{value:"Source code",id:"source-code",level:2},{value:"Hello world with CMake",id:"hello-world-with-cmake",level:2},{value:"CMake project",id:"cmake-project",level:3},{value:"FetchContent",id:"fetchcontent",level:3},{value:"How FetchContent module works",id:"how-fetchcontent-module-works",level:4},{value:"Build Hello world",id:"build-hello-world-cmake",level:3},{value:"Execute Hello world",id:"execute-hello-world-cmake",level:3},{value:"Hello world with qmake",id:"hello-world-with-qmake",level:2},{value:"qmake project",id:"qmake-project",level:3},{value:"Auto-configure using .qmake.conf and .env",id:"auto-configure-using-qmake_conf-and-env",level:4},{value:"Build Hello world",id:"build-hello-world-qmake",level:3},{value:"Execute Hello world",id:"execute-hello-world-qmake",level:3}];function j(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"building-hello-world",children:"Building: Hello world"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#introduction",children:"Introduction"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#prepare-sqlite-3-database",children:"Prepare SQLite 3 database"})}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#install-dependencies",children:"Install dependencies"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#using-vcpkg-json-manifest-mode",children:"Using vcpkg.json"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#using-vcpkg-install-manually",children:"Using vcpkg install"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#source-code",children:"Source code"})}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#hello-world-with-cmake",children:"Hello world with CMake"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#cmake-project",children:"CMake project"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#fetchcontent",children:"FetchContent"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#build-hello-world-cmake",children:"Build Hello world"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#execute-hello-world-cmake",children:"Execute Hello world"})}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#hello-world-with-qmake",children:"Hello world with qmake"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#qmake-project",children:"qmake project"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#build-hello-world-qmake",children:"Build Hello world"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#execute-hello-world-qmake",children:"Execute Hello world"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)("div",{className:"api-stability alert alert--success",children:(0,i.jsxs)(n.p,{children:[(0,i.jsx)(t.A,{to:"/stability#stability-indexes",children:(0,i.jsx)(n.strong,{children:"Stability: 2"})})," - Stable"]})}),"\n",(0,i.jsxs)(n.p,{children:["We will try to create the simplest working console application, in the terminal with the ",(0,i.jsx)(n.code,{children:"CMake"})," and in the ",(0,i.jsx)(n.code,{children:"QtCreator IDE"})," with the ",(0,i.jsx)(n.code,{children:"qmake"})," build systems."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"HelloWorld"})," example also expects the following ",(0,i.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:"folders structure"}),", let's create them."]}),"\n",(0,i.jsxs)(s.A,{groupId:d.vf,children:[(0,i.jsx)(a.A,{value:d.b,label:d.ux,children:(0,i.jsx)(o.A,{className:"language-powershell",children:`cd ${(0,c.OZ)(d.b)}\nmkdir HelloWorld/HelloWorld\ncd HelloWorld`})}),(0,i.jsx)(a.A,{value:d.xj,label:d.gg,children:(0,i.jsx)(o.A,{className:"language-bash",children:`cd ${(0,c.OZ)(d.xj)}\nmkdir -p HelloWorld/HelloWorld\ncd HelloWorld`})})]}),"\n",(0,i.jsx)(n.h2,{id:"prepare-sqlite-3-database",children:"Prepare SQLite 3 database"}),"\n",(0,i.jsxs)(n.p,{children:["The easiest way to demonstrate the ",(0,i.jsx)(n.code,{children:"HelloWorld"})," example will be with a ",(0,i.jsx)(n.code,{children:"SQLite 3"})," database."]}),"\n",(0,i.jsxs)(n.p,{children:["Execute the following command in the terminal to create and insert two rows into the ",(0,i.jsx)(n.code,{children:"SQLite 3"})," database."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sqlite3 HelloWorld.sqlite3 \"\ncreate table posts(id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name VARCHAR NOT NULL);\ninsert into posts values(1, 'First Post');\ninsert into posts values(2, 'Second Post');\nselect * from posts;\"\n"})}),"\n",(0,i.jsx)(n.h2,{id:"install-dependencies",children:"Install dependencies"}),"\n",(0,i.jsxs)(n.p,{children:["First, install the ",(0,i.jsx)(n.code,{children:"vcpkg"})," package manager as is described ",(0,i.jsx)(n.a,{href:"/building/tinyorm#vcpkg",children:"here"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"range-v3"})," and ",(0,i.jsx)(n.code,{children:"tabulate"})," libraries are required dependencies because ",(0,i.jsx)(n.code,{children:"TinyORM"})," uses them in header files, you have to install them before you can use ",(0,i.jsx)(n.code,{children:"TinyORM"}),". The ",(0,i.jsx)(n.code,{children:"tabulate"})," library is only needed in the ",(0,i.jsx)(n.code,{children:"tom"})," migrations it's used by the ",(0,i.jsx)(n.code,{children:"migrate:status"})," command."]}),"\n",(0,i.jsxs)(n.p,{children:["There are two ways how to install the ",(0,i.jsx)(n.code,{children:"range-v3"})," and ",(0,i.jsx)(n.code,{children:"tabulate"})," libraries using ",(0,i.jsx)(n.code,{children:"vcpkg"}),"."]}),"\n",(0,i.jsxs)(n.h4,{id:"using-vcpkg-json-manifest-mode",children:["Using vcpkg.json ",(0,i.jsx)("small",{children:"(manifest mode)"})]}),"\n",(0,i.jsxs)(n.p,{children:["Create a ",(0,i.jsx)(n.code,{children:"vcpkg.json"})," file with the following content. ",(0,i.jsx)(n.code,{children:"CMake"})," example below uses this method."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd HelloWorld\nvim vcpkg.json\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",metastring:"title='vcpkg.json'",children:'{\n "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json",\n "name": "tinyorm-helloworld",\n "version-semver": "0.1.0",\n "maintainers": "Silver Zachara ",\n "description": "Hello world console application for TinyORM C++ library",\n "homepage": "https://github.com/silverqx/TinyORM",\n "documentation": "https://www.tinyorm.org/building/hello-world",\n "supports": "!(uwp | arm | android | emscripten | osx | ios | xbox | freebsd | openbsd | wasm32)",\n "dependencies": [\n "range-v3",\n "tabulate"\n ]\n}\n'})}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["Only ",(0,i.jsx)(n.code,{children:"CMake"})," via the ",(0,i.jsx)(n.code,{children:"toolchain file"})," supports this method."]})}),"\n",(0,i.jsxs)(n.h4,{id:"using-vcpkg-install-manually",children:["Using vcpkg install ",(0,i.jsx)("small",{children:"(manually)"})]}),"\n",(0,i.jsxs)(n.p,{children:["This method can be used with both ",(0,i.jsx)(n.code,{children:"CMake"})," and ",(0,i.jsx)(n.code,{children:"qmake"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd ../../vcpkg\n\nvcpkg search range-v3\nvcpkg search tabulate\nvcpkg install range-v3 tabulate\nvcpkg list\n"})}),"\n",(0,i.jsx)(n.h2,{id:"source-code",children:"Source code"}),"\n",(0,i.jsxs)(n.p,{children:["Let's start in the ",(0,i.jsx)(n.code,{children:"HelloWorld"})," project folder."]}),"\n",(0,i.jsxs)(s.A,{groupId:d.vf,children:[(0,i.jsx)(a.A,{value:d.b,label:d.ux,children:(0,i.jsx)(o.A,{className:"language-powershell",children:`cd ${(0,c.OZ)(d.b)}/HelloWorld/HelloWorld`})}),(0,i.jsx)(a.A,{value:d.xj,label:d.gg,children:(0,i.jsx)(o.A,{className:"language-bash",children:`cd ${(0,c.OZ)(d.xj)}/HelloWorld/HelloWorld`})})]}),"\n",(0,i.jsxs)(n.p,{children:["Create ",(0,i.jsx)(n.code,{children:"main.cpp"})," source file."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"vim main.cpp\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["To paste a source code correctly in ",(0,i.jsx)(n.code,{children:"vim"}),", press ",(0,i.jsx)("kbd",{children:"Shift"})," + ",(0,i.jsx)("kbd",{children:"p"}),"."]})}),"\n",(0,i.jsx)(n.p,{children:"And paste the following code."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-cpp",metastring:"title='main.cpp'",children:'#include \n#include \n\n#ifdef _WIN32\n# include \n#endif\n\n#include \n\nusing Orm::DB;\n\nint main(int argc, char *argv[])\n{\n#ifdef _WIN32\n SetConsoleOutputCP(CP_UTF8);\n// SetConsoleOutputCP(1250);\n#endif\n\n /* Needed from Qt v6.5.3 to avoid:\n qt.core.qobject.connect: QObject::connect(QObject, Unknown): invalid nullptr parameter */\n QCoreApplication app(argc, argv);\n\n // Ownership of a shared_ptr()\n auto manager = DB::create({\n {"driver", "QSQLITE"},\n {"database", qEnvironmentVariable("TINYORM_HELLOWORLD_DB_SQLITE_DATABASE",\n "../../HelloWorld.sqlite3")},\n {"check_database_exists", true},\n });\n\n auto posts = DB::select("select * from posts");\n\n while(posts.next())\n qDebug() << posts.value("id").toULongLong()\n << posts.value("name").toString();\n}\n'})}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"QSqlDatabase"})," depends on ",(0,i.jsx)(n.code,{children:"QCoreApplication"})," from ",(0,i.jsx)(n.code,{children:"Qt v6.5.3"})," so you must create the ",(0,i.jsx)(n.code,{children:"QCoreApplication"})," instance before you will call anything from the ",(0,i.jsx)(n.code,{children:"TinyORM"})," library. \ud83e\udee4 The change was made ",(0,i.jsx)(n.a,{href:"https://github.com/qt/qtbase/commit/8d2bdc9cd5482eace12ba7e45304857bd24db0e6#diff-1d355c25c0b0eddec2be48253407780c4dc510d986739aec61e1ec892ccaf86e",children:"here"}),"."]})}),"\n",(0,i.jsx)(n.h2,{id:"hello-world-with-cmake",children:"Hello world with CMake"}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["If something is not clear, you can still look at GitHub Action ",(0,i.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/tree/main/.github/workflows",children:(0,i.jsx)(n.code,{children:"workflows"})})," how the build is done."]})}),"\n",(0,i.jsxs)(n.p,{children:["Create a folder for the ",(0,i.jsx)(n.code,{children:"CMake"})," build."]}),"\n",(0,i.jsxs)(s.A,{groupId:d.vf,children:[(0,i.jsx)(a.A,{value:d.b,label:d.ux,children:(0,i.jsx)(o.A,{className:"language-powershell",children:"cd ..\nmkdir HelloWorld-builds-cmake/build-debug\n\ncd HelloWorld"})}),(0,i.jsx)(a.A,{value:d.xj,label:d.gg,children:(0,i.jsx)(o.A,{className:"language-bash",children:"cd ..\nmkdir -p HelloWorld-builds-cmake/build-debug\n\ncd HelloWorld"})})]}),"\n",(0,i.jsx)(n.h3,{id:"cmake-project",children:"CMake project"}),"\n",(0,i.jsxs)(n.p,{children:["Create ",(0,i.jsx)(n.code,{children:"CMakeLists.txt"})," file with the following content."]}),"\n",(0,i.jsxs)(s.A,{groupId:d.vf,children:[(0,i.jsx)(a.A,{value:d.b,label:d.ux,children:(0,i.jsx)(o.A,{className:"language-cmake",children:`cmake_minimum_required(VERSION VERSION 3.22...3.30 FATAL_ERROR)\n\nproject(HelloWorld LANGUAGES CXX)\n\n# build tree\nlist(APPEND CMAKE_PREFIX_PATH "${(0,c.nC)(d.b,(0,c.OZ)(d.b))}/TinyORM/TinyORM-builds-cmake/build-debug")\n\nset(CMAKE_CXX_STANDARD 20)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\nadd_executable(HelloWorld\n main.cpp\n)\n\nfind_package(QT NAMES Qt6 COMPONENTS Core REQUIRED)\nfind_package(Qt\${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)\nfind_package(TinyOrm 0.38.1 CONFIG REQUIRED)\n\ntarget_link_libraries(HelloWorld\n PRIVATE\n Qt\${QT_VERSION_MAJOR}::Core\n TinyOrm::TinyOrm\n)`})}),(0,i.jsx)(a.A,{value:d.xj,label:d.gg,children:(0,i.jsx)(o.A,{className:"language-cmake",children:`cmake_minimum_required(VERSION VERSION 3.22...3.30 FATAL_ERROR)\n\nproject(HelloWorld LANGUAGES CXX)\n\n# build tree\nlist(APPEND CMAKE_PREFIX_PATH "${(0,c.nC)(d.xj,(0,c.OZ)(d.xj))}/TinyORM/TinyORM-builds-cmake/build-debug")\n\nset(CMAKE_CXX_STANDARD 20)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\nadd_executable(HelloWorld\n main.cpp\n)\n\nfind_package(QT NAMES Qt6 COMPONENTS Core REQUIRED)\nfind_package(Qt\${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)\nfind_package(TinyOrm 0.38.1 CONFIG REQUIRED)\n\ntarget_link_libraries(HelloWorld\n PRIVATE\n Qt\${QT_VERSION_MAJOR}::Core\n TinyOrm::TinyOrm\n)`})})]}),"\n",(0,i.jsx)(n.h3,{id:"fetchcontent",children:"FetchContent"}),"\n",(0,i.jsxs)(n.p,{children:["If you don't have cloned and built the ",(0,i.jsx)(n.code,{children:"TinyORM"})," library, or you want to quickly try TinyORM without wasting time with cloning and building the TinyORM library, then you can use CMake's ",(0,i.jsx)(n.a,{href:"https://cmake.org/cmake/help/latest/module/FetchContent.html",children:(0,i.jsx)(n.code,{children:"FetchContent"})})," module that will do all of this for you."]}),"\n",(0,i.jsxs)(n.p,{children:["Instead of providing a path by the ",(0,i.jsx)(n.code,{children:"CMAKE_PREFIX_PATH"})," (or using the ",(0,i.jsx)(n.code,{children:"User Package Registry"}),") like in the example below:"]}),"\n",(0,i.jsxs)(s.A,{groupId:d.vf,children:[(0,i.jsx)(a.A,{value:d.b,label:d.ux,children:(0,i.jsx)(o.A,{className:"language-cmake",children:`# build tree\nlist(APPEND CMAKE_PREFIX_PATH "${(0,c.nC)(d.b,(0,c.OZ)(d.b))}/TinyORM/TinyORM-builds-cmake/build-debug")`})}),(0,i.jsx)(a.A,{value:d.xj,label:d.gg,children:(0,i.jsx)(o.A,{className:"language-cmake",children:`# build tree\nlist(APPEND CMAKE_PREFIX_PATH "${(0,c.nC)(d.xj,(0,c.OZ)(d.xj))}/TinyORM/TinyORM-builds-cmake/build-debug")`})})]}),"\n",(0,i.jsxs)(n.p,{children:["You can use the ",(0,i.jsx)(n.a,{href:"https://cmake.org/cmake/help/latest/module/FetchContent.html",children:(0,i.jsx)(n.code,{children:"FetchContent"})})," module like in the following example."]}),"\n",(0,i.jsxs)(s.A,{groupId:d.vf,children:[(0,i.jsx)(a.A,{value:d.b,label:d.ux,children:(0,i.jsx)(o.A,{className:"language-cmake",children:"cmake_minimum_required(VERSION VERSION 3.22...3.30 FATAL_ERROR)\n\nproject(HelloWorld LANGUAGES CXX)\n\nset(CMAKE_CXX_STANDARD 20)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\n# FetchContent method\ninclude(FetchContent)\nFetchContent_Declare(TinyOrm\n GIT_REPOSITORY https://github.com/silverqx/TinyORM.git\n GIT_TAG origin/main\n OVERRIDE_FIND_PACKAGE\n)\n# Here you can configure TinyORM CMake options\nset(MYSQL_PING OFF)\nset(TOM_EXAMPLE ON)\n\nadd_executable(HelloWorld\n main.cpp\n)\n\nfind_package(QT NAMES Qt6 COMPONENTS Core REQUIRED)\nfind_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)\nfind_package(TinyOrm 0.38.1 CONFIG REQUIRED)\n\ntarget_link_libraries(HelloWorld\n PRIVATE\n Qt${QT_VERSION_MAJOR}::Core\n TinyOrm::TinyOrm\n)"})}),(0,i.jsx)(a.A,{value:d.xj,label:d.gg,children:(0,i.jsx)(o.A,{className:"language-cmake",children:"cmake_minimum_required(VERSION VERSION 3.22...3.30 FATAL_ERROR)\n\nproject(HelloWorld LANGUAGES CXX)\n\nset(CMAKE_CXX_STANDARD 20)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\n# FetchContent method\ninclude(FetchContent)\nFetchContent_Declare(TinyOrm\n GIT_REPOSITORY https://github.com/silverqx/TinyORM.git\n GIT_TAG origin/main\n OVERRIDE_FIND_PACKAGE\n)\n# Here you can configure TinyORM CMake options\nset(MYSQL_PING OFF)\nset(TOM_EXAMPLE ON)\n\nadd_executable(HelloWorld\n main.cpp\n)\n\nfind_package(QT NAMES Qt6 COMPONENTS Core REQUIRED)\nfind_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)\nfind_package(TinyOrm 0.38.1 CONFIG REQUIRED)\n\ntarget_link_libraries(HelloWorld\n PRIVATE\n Qt${QT_VERSION_MAJOR}::Core\n TinyOrm::TinyOrm\n)"})})]}),"\n",(0,i.jsx)(n.h4,{id:"how-fetchcontent-module-works",children:"How FetchContent module works"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"FetchContent_Declare"})," command is like calling the git clone inside the build folder and then adding a cloned folder in a similar way as the ",(0,i.jsx)(n.code,{children:"add_subdirectory()"})," command does."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"FetchContent_MakeAvailable()"})," internally calls the ",(0,i.jsx)(n.code,{children:"find_package()"})," command or if you pass the ",(0,i.jsx)(n.code,{children:"OVERRIDE_FIND_PACKAGE"})," argument, then you don't have to call the the ",(0,i.jsx)(n.code,{children:"FetchContent_MakeAvailable"}),", but you must call the ",(0,i.jsx)(n.code,{children:"find_package( x.y.z CONFIG REQUIRED)"})," command manually."]}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["An advantage of the ",(0,i.jsx)(n.code,{children:"OVERRIDE_FIND_PACKAGE"})," argument is that you can call the ",(0,i.jsx)(n.code,{children:"find_package"})," command much later, and you can insert additional configurations between."]})}),"\n",(0,i.jsx)(n.h3,{id:"build-hello-world-cmake",children:"Build Hello world"}),"\n",(0,i.jsxs)(n.p,{children:["Now you are ready to configure ",(0,i.jsx)(n.code,{children:"HelloWorld"})," ",(0,i.jsx)(n.code,{children:"CMake"})," application."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd ../HelloWorld-builds-cmake/build-debug\n"})}),"\n",(0,i.jsxs)(s.A,{groupId:d.vf,children:[(0,i.jsx)(a.A,{value:d.b,label:d.ux,children:(0,i.jsx)(o.A,{className:"language-powershell",children:`cmake.exe \`\n-S "${(0,c.OZ)(d.b)}/HelloWorld/HelloWorld" \`\n-B "${(0,c.OZ)(d.b)}/HelloWorld/HelloWorld-builds-cmake/build-debug" \`\n-G 'Ninja' \`\n-D CMAKE_BUILD_TYPE:STRING='Debug' \`\n-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${(0,c.Sn)(d.b)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \`\n-D CMAKE_CXX_SCAN_FOR_MODULES:BOOL=OFF \`\n-D CMAKE_INSTALL_PREFIX:PATH="${(0,c.Sn)(d.b)}/tmp/HelloWorld"`})}),(0,i.jsx)(a.A,{value:d.xj,label:d.gg,children:(0,i.jsx)(o.A,{className:"language-bash",children:`cmake \\\n-S "${(0,c.OZ)(d.xj)}/HelloWorld/HelloWorld" \\\n-B "${(0,c.OZ)(d.xj)}/HelloWorld/HelloWorld-builds-cmake/build-debug" \\\n-G 'Ninja' \\\n-D CMAKE_BUILD_TYPE:STRING='Debug' \\\n-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${(0,c.Sn)(d.xj)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \\\n-D CMAKE_CXX_SCAN_FOR_MODULES:BOOL=OFF \\\n-D CMAKE_INSTALL_PREFIX:PATH="${(0,c.Sn)(d.xj)}/tmp/TinyORM"`})})]}),"\n",(0,i.jsx)(n.p,{children:"And build."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cmake --build . --target all\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["Enable the ",(0,i.jsx)(n.a,{href:"/building/tinyorm#cmake-strict_mode-option",children:(0,i.jsx)(n.code,{children:"TINYORM_STRICT_MODE"})})," environment variable to produce better code and to follow good code practices."]})}),"\n",(0,i.jsx)(n.h3,{id:"execute-hello-world-cmake",children:"Execute Hello world"}),"\n",(0,i.jsxs)(n.p,{children:["Do not forget to add ",(0,i.jsx)(n.code,{children:"TinyOrm0d.dll"})," on the path on Windows and on the ",(0,i.jsx)(n.code,{children:"LD_LIBRARY_PATH"})," on Linux, so ",(0,i.jsx)(n.code,{children:"HelloWorld"})," application can find it during execution, as is described ",(0,i.jsx)(n.a,{href:"/building/tinyorm#tinyorm-on-path-cmake",children:"here"}),"."]}),"\n",(0,i.jsxs)(s.A,{groupId:d.vf,name:"tinyorm-on-path",children:[(0,i.jsx)(a.A,{value:d.b,label:d.ux,children:(0,i.jsx)(o.A,{className:"language-powershell",children:`$env:Path = "${(0,c.OZ)(d.b,!1)}\\TinyORM\\TinyORM-builds-cmake\\build-debug;" + $env:Path`})}),(0,i.jsx)(a.A,{value:d.xj,label:d.gg,children:(0,i.jsx)(o.A,{className:"language-bash",children:`export LD_LIBRARY_PATH=${(0,c.OZ)(d.xj)}/TinyORM/TinyORM-builds-cmake/build-debug\${PATH:+:}$PATH`})})]}),"\n",(0,i.jsxs)(n.p,{children:["Execute ",(0,i.jsx)(n.code,{children:"HelloWorld"})," example."]}),"\n",(0,i.jsxs)(s.A,{groupId:d.vf,children:[(0,i.jsx)(a.A,{value:d.b,label:d.ux,children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-powershell",children:".\\HelloWorld.exe\n"})})}),(0,i.jsx)(a.A,{value:d.xj,label:d.gg,children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"./HelloWorld\n"})})})]}),"\n",(0,i.jsx)(n.p,{children:"The output will look like this."}),"\n",(0,i.jsx)(o.A,{className:"language-less",children:'Executed prepared query (6ms, -1 results, 0 affected, tinyorm_default) : select * from posts\n1 "First Post"\n2 "Second Post"'}),"\n",(0,i.jsx)(n.h2,{id:"hello-world-with-qmake",children:"Hello world with qmake"}),"\n",(0,i.jsxs)(n.p,{children:["Create a folder for the ",(0,i.jsx)(n.code,{children:"qmake"})," build."]}),"\n",(0,i.jsxs)(s.A,{groupId:d.vf,children:[(0,i.jsx)(a.A,{value:d.b,label:d.ux,children:(0,i.jsx)(o.A,{className:"language-powershell",children:`cd ${(0,c.OZ)(d.b)}/HelloWorld\n\nmkdir HelloWorld-builds-qmake`})}),(0,i.jsx)(a.A,{value:d.xj,label:d.gg,children:(0,i.jsx)(o.A,{className:"language-bash",children:`cd ${(0,c.OZ)(d.xj)}/HelloWorld\n\nmkdir HelloWorld-builds-qmake`})})]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"#source-code",children:(0,i.jsx)(n.code,{children:"source code"})})," is the same as for the ",(0,i.jsx)(n.code,{children:"HelloWorld CMake"})," example."]}),"\n",(0,i.jsx)(n.h3,{id:"qmake-project",children:"qmake project"}),"\n",(0,i.jsxs)(n.p,{children:["Create ",(0,i.jsx)(n.code,{children:"HelloWorld.pro"})," qmake file with the following content."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd HelloWorld\nvim HelloWorld.pro\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["To paste a source code correctly in ",(0,i.jsx)(n.code,{children:"vim"}),", press ",(0,i.jsx)("kbd",{children:"Shift"})," + ",(0,i.jsx)("kbd",{children:"p"}),"."]})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-qmake",metastring:"title='HelloWorld.pro'",children:"QT -= gui\n\nTEMPLATE = app\n\nCONFIG *= cmdline\n\nDEFINES *= PROJECT_TINYORM_HELLOWORLD\n\nSOURCES += $$PWD/main.cpp\n\n# Auto-configure TinyORM library \ud83d\udd25\ninclude($$TINY_MAIN_DIR/TinyORM/qmake/TinyOrm.pri)\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsxs)(n.p,{children:["The exact ",(0,i.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:"folders structure"})," is crucial in this example because the paths to the ",(0,i.jsx)(n.code,{children:"TinyORM"})," source and build folders are relative."]})}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsx)(n.p,{children:"Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!"})}),"\n",(0,i.jsxs)(n.h4,{id:"auto-configure-using-qmake_conf-and-env",children:[(0,i.jsx)(n.code,{children:"Auto-configure"})," using ",(0,i.jsx)(n.code,{children:".qmake.conf"})," and ",(0,i.jsx)(n.code,{children:".env"})]}),"\n",(0,i.jsxs)(n.p,{children:["If you want to have properly configured ",(0,i.jsx)(n.code,{children:"DEFINES"})," (C preprocessor macros) or have Qt headers marked as system headers, then you need to specify a path to the ",(0,i.jsx)(n.code,{children:"TinyORM"})," qmake features (",(0,i.jsx)(n.code,{children:".prf"})," files) which handle this correctly; this path is provided by the ",(0,i.jsx)(n.code,{children:"QMAKEFEATURES"})," variable and can only be set in the ",(0,i.jsx)(n.code,{children:".qmake.conf"})," file."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["Read the ",(0,i.jsx)(n.a,{href:"/building/tinyorm#consume-tinyorm-library-qmake",children:"Consume TinyOrm library (qmake)"})," section, as everything that is described in that section applies here as well."]})}),"\n",(0,i.jsxs)(n.p,{children:["Create the ",(0,i.jsx)(n.code,{children:".qmake.conf"})," file in the ",(0,i.jsx)(n.code,{children:"HelloWorld"})," project root folder with the following content."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-qmake",metastring:"title='.qmake.conf'",children:"# Path to the PARENT folder of the TinyORM source folder\nTINY_MAIN_DIR = $$clean_path($$PWD/../../TinyORM/)\n# To find .env and .env.$$QMAKE_PLATFORM files\nTINY_DOTENV_ROOT = $$PWD\n# Path to the current build tree (used to guess the TinyORM build tree)\n#TINY_BUILD_TREE = $$shadowed($$PWD)\n\n# To find .prf files, needed by eg. CONFIG += tiny_system_headers inline/extern_constants\nQMAKEFEATURES *= $$quote($$TINY_MAIN_DIR/TinyORM/qmake/features)\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Then, create a ",(0,i.jsx)("code",{children:".env.(win32|unix|mingw)"})," file in the ",(0,i.jsx)(n.code,{children:"HelloWorld"})," project root folder with the following content."]}),"\n",(0,i.jsxs)(s.A,{groupId:d.vf,children:[(0,i.jsx)(a.A,{value:d.b,label:".env.win32",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-qmake",children:"# Names and values of these qmake variables are crucial, they are used in HelloWorld.pro\n# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!\n\n# Path to the TinyORM build folder\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_2_MSVC2022_64bit-Debug/)\n\n# Path to the vcpkg - range-v3\n# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty\nTINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)\nTINY_VCPKG_TRIPLET = x64-windows\n\n# Enable ccache wrapper\n#CONFIG *= ccache\n"})})}),(0,i.jsx)(a.A,{value:d.xj,label:".env.unix",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-qmake",children:"# Names and values of these qmake variables are crucial, they are used in HelloWorld.pro\n# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!\n\n# Path to the TinyORM build folder\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_2_clang18_64bit_ccache-Debug/)\n\n# Path to the vcpkg - range-v3\n# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty\nTINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)\nTINY_VCPKG_TRIPLET = x64-linux\n\n# Use faster linker\nclang: CONFIG *= use_lld_linker\nelse: CONFIG *= use_gold_linker\n\n# Or use the mold linker\n#QMAKE_LFLAGS *= -fuse-ld=mold\n"})})}),(0,i.jsx)(a.A,{value:"mingw",label:".env.mingw",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-qmake",children:"# Names and values of these qmake variables are crucial, they are used in HelloWorld.pro\n# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!\n\n# Path to the TinyORM build folder\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_2_MSYS2_UCRT64_clang_64bit-Debug/)\n\n# Path to the vcpkg - range-v3\n# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty\nTINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)\nTINY_VCPKG_TRIPLET = x64-mingw-dynamic\n\n# Enable ccache wrapper\n#CONFIG *= ccache\n\n# Use faster linker (for both GCC and Clang)\n# CONFIG *= use_lld_linker does not work on MinGW\nQMAKE_LFLAGS *= -fuse-ld=lld\n"})})})]}),"\n",(0,i.jsxs)(n.p,{children:["Don't forget to update the ",(0,i.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," and ",(0,i.jsx)(n.code,{children:"TINY_VCPKG_ROOT"})," folder paths to your needs if you are not using the recommended ",(0,i.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:(0,i.jsx)(n.code,{children:"Folders structure"})}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["You can use the ",(0,i.jsxs)(n.a,{href:"/building/tinyorm#partial-guessing-of-the-tinyorm_build_tree",children:["Partial guessing of the ",(0,i.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})]})," if you don't like to specify it manually. Just comment out the ",(0,i.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," and uncomment the ",(0,i.jsx)(n.code,{children:"TINY_BUILD_TREE = $$shadowed($$PWD)"})," in the ",(0,i.jsx)(n.code,{children:".qmake.conf"})," file."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["You can entirely avoid the ",(0,i.jsx)(n.code,{children:".env"})," files, just move the ",(0,i.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," to the ",(0,i.jsx)(n.code,{children:".qmake.conf"})," or remove it by help of ",(0,i.jsxs)(n.a,{href:"/building/tinyorm#partial-guessing-of-the-tinyorm_build_tree",children:["Partial guessing of the ",(0,i.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})]})," and set the ",(0,i.jsx)(n.code,{children:"VCPKG_ROOT"})," environment variable at system level as is described in ",(0,i.jsx)(n.a,{href:"/building/tinyorm#set-up-vcpkg-environment",children:(0,i.jsx)(n.code,{children:"Set up vcpkg environment"})}),"."]})}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["Configuring by the ",(0,i.jsx)(n.code,{children:".qmake.conf"})," and ",(0,i.jsx)(n.code,{children:".env"})," files has one big advantage, which is that you don't have to modify the project files."]})}),"\n",(0,i.jsx)(n.h3,{id:"build-hello-world-qmake",children:"Build Hello world"}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["I recommend creating a new ",(0,i.jsx)(n.code,{children:"Session"})," in the ",(0,i.jsx)(n.code,{children:"QtCreator IDE"})," as is described ",(0,i.jsx)(n.a,{href:"/building/tinyorm#open-qtcreator-ide",children:"here"}),"."]})}),"\n",(0,i.jsxs)(n.p,{children:["Now you can open the ",(0,i.jsx)(n.code,{children:"HelloWorld.pro"})," project in the ",(0,i.jsx)(n.code,{children:"QtCreator IDE"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["This will open the ",(0,i.jsx)(n.code,{children:"Configure Project"})," tab, select some kit and update build folder paths to meet our ",(0,i.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:"folders structure"})," or like you want."]}),"\n",(0,i.jsx)("img",{src:l(3180).A,alt:"HelloWorld - QtCreator - Configure Project",width:"760"}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["You can force the ",(0,i.jsx)(n.code,{children:"QtCreator"})," to generate a build folders structure as is described ",(0,i.jsx)(n.a,{href:"/building/tinyorm#qtcreator-default-build-directory",children:"here"}),"."]})}),"\n",(0,i.jsxs)(n.p,{children:["You are ready to configure build options, hit ",(0,i.jsx)("kbd",{children:"Ctrl"}),"+",(0,i.jsx)("kbd",{children:"5"})," to open ",(0,i.jsx)(n.code,{children:"Project Settings"})," tab and select ",(0,i.jsx)(n.code,{children:"Build"})," in the left sidebar to open the ",(0,i.jsx)(n.code,{children:"Build Settings"}),", it should look similar to the following picture."]}),"\n",(0,i.jsx)("img",{src:l(7028).A,className:"no-blurry",alt:"HelloWorld - QtCreator - Build Settings",width:"760"}),"\n",(0,i.jsxs)(n.p,{children:["Disable ",(0,i.jsx)(n.code,{children:"QML debugging and profiling"})," and ",(0,i.jsx)(n.code,{children:"Qt Quick Compiler"}),", they are not used."]}),"\n",(0,i.jsxs)(n.p,{children:["In the left sidebar open ",(0,i.jsx)(n.code,{children:"Dependencies"})," and check ",(0,i.jsx)(n.code,{children:"TinyORM"})," project and ",(0,i.jsx)(n.code,{children:"Synchronize configuration"}),", this setting ensures that the current project will be rebuilt correctly when the ",(0,i.jsx)(n.code,{children:"TinyORM"})," library source code changes."]}),"\n",(0,i.jsxs)(n.p,{children:["Everything is ready to build, you can press ",(0,i.jsx)("kbd",{children:"Ctrl"}),"+",(0,i.jsx)("kbd",{children:"b"})," to build the project."]}),"\n",(0,i.jsx)(n.h3,{id:"execute-hello-world-qmake",children:"Execute Hello world"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"QtCreator"})," takes care of all the necessary configurations, sets up the build environment correctly, and also prepends dependency libraries on the system path on Windows and on the ",(0,i.jsx)(n.code,{children:"LD_LIBRARY_PATH"})," on Linux."]}),"\n",(0,i.jsxs)(n.p,{children:["The only thing you might want to change is to run the ",(0,i.jsx)(n.code,{children:"HelloWorld"})," example in the new terminal window. To do so, hit ",(0,i.jsx)("kbd",{children:"Ctrl"}),"+",(0,i.jsx)("kbd",{children:"5"})," to open the ",(0,i.jsx)(n.code,{children:"Project Settings"})," tab and select ",(0,i.jsx)(n.code,{children:"Run"})," in the left sidebar to open the ",(0,i.jsx)(n.code,{children:"Run Settings"}),", then in the ",(0,i.jsx)(n.code,{children:"Run"})," section select the ",(0,i.jsx)(n.code,{children:"Run in terminal"})," checkbox."]}),"\n",(0,i.jsxs)(n.p,{children:["To execute the ",(0,i.jsx)(n.code,{children:"HelloWorld"})," example press ",(0,i.jsx)("kbd",{children:"Ctrl"})," + ",(0,i.jsx)("kbd",{children:"r"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"The output will look like this."}),"\n",(0,i.jsx)(o.A,{className:"language-less",children:'Executed prepared query (6ms, -1 results, 0 affected, tinyorm_default) : select * from posts\n1 "First Post"\n2 "Second Post"'})]})}function g(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(j,{...e})}):j(e)}},9365:(e,n,l)=>{l.d(n,{A:()=>o});l(6540);var i=l(4164);const r={tabItem:"tabItem_Ymn6"};var t=l(4848);function o(e){let{children:n,hidden:l,className:o}=e;return(0,t.jsx)("div",{role:"tabpanel",className:(0,i.A)(r.tabItem,o),hidden:l,children:n})}},1470:(e,n,l)=>{l.d(n,{A:()=>y});var i=l(6540),r=l(4164),t=l(3104),o=l(6347),a=l(205),s=l(7485),d=l(1682),c=l(679);function h(e){return i.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,i.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function u(e){const{values:n,children:l}=e;return(0,i.useMemo)((()=>{const e=n??function(e){return h(e).map((e=>{let{props:{value:n,label:l,attributes:i,default:r}}=e;return{value:n,label:l,attributes:i,default:r}}))}(l);return function(e){const n=(0,d.XI)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[n,l])}function p(e){let{value:n,tabValues:l}=e;return l.some((e=>e.value===n))}function m(e){let{queryString:n=!1,groupId:l}=e;const r=(0,o.W6)(),t=function(e){let{queryString:n=!1,groupId:l}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!l)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return l??null}({queryString:n,groupId:l});return[(0,s.aZ)(t),(0,i.useCallback)((e=>{if(!t)return;const n=new URLSearchParams(r.location.search);n.set(t,e),r.replace({...r.location,search:n.toString()})}),[t,r])]}function x(e){const{defaultValue:n,queryString:l=!1,groupId:r}=e,t=u(e),[o,s]=(0,i.useState)((()=>function(e){let{defaultValue:n,tabValues:l}=e;if(0===l.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!p({value:n,tabValues:l}))throw new Error(`Docusaurus error: The has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${l.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const i=l.find((e=>e.default))??l[0];if(!i)throw new Error("Unexpected error: 0 tabValues");return i.value}({defaultValue:n,tabValues:t}))),[d,h]=m({queryString:l,groupId:r}),[x,j]=function(e){let{groupId:n}=e;const l=function(e){return e?`docusaurus.tab.${e}`:null}(n),[r,t]=(0,c.Dv)(l);return[r,(0,i.useCallback)((e=>{l&&t.set(e)}),[l,t])]}({groupId:r}),g=(()=>{const e=d??x;return p({value:e,tabValues:t})?e:null})();(0,a.A)((()=>{g&&s(g)}),[g]);return{selectedValue:o,selectValue:(0,i.useCallback)((e=>{if(!p({value:e,tabValues:t}))throw new Error(`Can't select invalid tab value=${e}`);s(e),h(e),j(e)}),[h,j,t]),tabValues:t}}var j=l(2303);const g={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var b=l(4848);function f(e){let{className:n,block:l,selectedValue:i,selectValue:o,tabValues:a}=e;const s=[],{blockElementScrollPositionUntilNextRender:d}=(0,t.a_)(),c=e=>{const n=e.currentTarget,l=s.indexOf(n),r=a[l].value;r!==i&&(d(n),o(r))},h=e=>{let n=null;switch(e.key){case"Enter":c(e);break;case"ArrowRight":{const l=s.indexOf(e.currentTarget)+1;n=s[l]??s[0];break}case"ArrowLeft":{const l=s.indexOf(e.currentTarget)-1;n=s[l]??s[s.length-1];break}}n?.focus()};return(0,b.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,r.A)("tabs",{"tabs--block":l},n),children:a.map((e=>{let{value:n,label:l,attributes:t}=e;return(0,b.jsx)("li",{role:"tab",tabIndex:i===n?0:-1,"aria-selected":i===n,ref:e=>s.push(e),onKeyDown:h,onClick:c,...t,className:(0,r.A)("tabs__item",g.tabItem,t?.className,{"tabs__item--active":i===n}),children:l??n},n)}))})}function _(e){let{lazy:n,children:l,selectedValue:t}=e;const o=(Array.isArray(l)?l:[l]).filter(Boolean);if(n){const e=o.find((e=>e.props.value===t));return e?(0,i.cloneElement)(e,{className:(0,r.A)("margin-top--md",e.props.className)}):null}return(0,b.jsx)("div",{className:"margin-top--md",children:o.map(((e,n)=>(0,i.cloneElement)(e,{key:n,hidden:e.props.value!==t})))})}function T(e){const n=x(e);return(0,b.jsxs)("div",{className:(0,r.A)("tabs-container",g.tabList),children:[(0,b.jsx)(f,{...n,...e}),(0,b.jsx)(_,{...n,...e})]})}function y(e){const n=(0,j.A)();return(0,b.jsx)(T,{...e,children:h(e.children)},String(n))}},7324:(e,n,l)=>{l.d(n,{$E:()=>j,A3:()=>b,CW:()=>g,Dx:()=>c,F4:()=>u,Fi:()=>d,J_:()=>y,LQ:()=>f,Lf:()=>k,OO:()=>r,Q7:()=>_,b:()=>a,cy:()=>s,gg:()=>m,kl:()=>p,os:()=>h,pW:()=>t,ux:()=>x,vf:()=>i,xj:()=>o,xt:()=>T});const i="shell",r="database",t="application",o="bash",a="pwsh",s="zsh",d="maria",c="mysql",h="postgres",u="sqlite",p="application",m="bash",x="pwsh",j="zsh",g="MariaDB",b="MySQL",f="PostgreSQL",_="SQLite",T="tinyorm.org",y="$HOME/Code/c/",k="$env:USERPROFILE\\Code\\c\\"},6362:(e,n,l)=>{l.d(n,{A:()=>t});var i=l(6540),r=l(1838);function t(){const e=(0,i.useContext)(r.A);if(null!=e)return e;throw new Error("useRootFolderContext is used outside of Layout component.")}},6694:(e,n,l)=>{l.d(n,{OZ:()=>s,Sn:()=>o,T3:()=>c,bw:()=>d,nC:()=>h,np:()=>a});var i=l(6362),r=l(2303),t=l(7324);const o=function(e,n){return void 0===n&&(n=!0),u((0,i.A)().rootFolder[e]??d(e),e,n)},a=()=>(0,i.A)().rootFolder[t.pW]??d(t.pW),s=function(e,n){if(void 0===n&&(n=!0),null==e)throw new Error("The groupId in the applicationFolderPath() can not be empty.");const l=n||e!==t.b?"/":"\\";return u(o(e)+l+a(),e,n)};function d(e){if(null==e)throw new Error("The groupId in the folderDefaultValue() can not be empty.");if(!(0,r.A)())return"";switch(e){case t.b:return t.Lf;case t.xj:return t.J_;case t.pW:return t.xt;default:throw new Error(`No default value for '${e}' groupId in the folderDefaultValue().`)}}function c(e){return e===t.pW}function h(e,n){if(null==n||""===n)return n;const l="$ENV{$1}$2";switch(e){case t.b:return m(n).replace(/\$env:(.+?)(\/.*)/,l);case t.xj:return n.replace(/\$(.+?)(\/.*)/,l);default:throw new Error(`Unsupported shell type '${e}' in the convertToCmakeEnvVariable().`)}}function u(e,n,l){if(void 0===l&&(l=!0),null==e||""===e)return e;if(n!==t.b)return p(e);const i=p(e);return l?m(i):function(e){return null==e||""===e?e:e.replaceAll(/\/+/g,"\\")}(i)}function p(e){return null==e||""===e?e:e.replace(/[/\\]+$/,"")}function m(e){return null==e||""===e?e:e.replaceAll(/\\+(?! )/g,"/")}},7028:(e,n,l)=>{l.d(n,{A:()=>i});const i=l.p+"assets/images/qmake-build_settings-ebdc6c0c056d11462096ff10cba682a1.png"},3180:(e,n,l)=>{l.d(n,{A:()=>i});const i=l.p+"assets/images/qmake-configure_project-8caf87e6af4452f0c28bd15c85c392fc.png"}}]); \ No newline at end of file +"use strict";(self.webpackChunktinyorm_org=self.webpackChunktinyorm_org||[]).push([[983],{8781:(e,n,l)=>{l.r(n),l.d(n,{assets:()=>m,contentTitle:()=>u,default:()=>g,frontMatter:()=>h,metadata:()=>p,toc:()=>x});var i=l(4848),r=l(8453),t=l(8774),o=l(2364),a=l(9365),s=l(1470),d=l(7324),c=l(6694);const h={sidebar_position:2,sidebar_label:"Hello world",description:"Hello world example created in the terminal and QtCreator IDE.",keywords:["c++ orm","building","hello world","tinyorm"]},u="Building: Hello world",p={id:"building/hello-world",title:"Building: Hello world",description:"Hello world example created in the terminal and QtCreator IDE.",source:"@site/docs/building/hello-world.mdx",sourceDirName:"building",slug:"/building/hello-world",permalink:"/building/hello-world",draft:!1,unlisted:!1,tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2,sidebar_label:"Hello world",description:"Hello world example created in the terminal and QtCreator IDE.",keywords:["c++ orm","building","hello world","tinyorm"]},sidebar:"tinyormSidebar",previous:{title:"TinyORM",permalink:"/building/tinyorm"},next:{title:"Migrations",permalink:"/building/migrations"}},m={},x=[{value:"Introduction",id:"introduction",level:2},{value:"Prepare SQLite 3 database",id:"prepare-sqlite-3-database",level:2},{value:"Install dependencies",id:"install-dependencies",level:2},{value:"Using vcpkg.json (manifest mode)",id:"using-vcpkg-json-manifest-mode",level:4},{value:"Using vcpkg install (manually)",id:"using-vcpkg-install-manually",level:4},{value:"Source code",id:"source-code",level:2},{value:"Hello world with CMake",id:"hello-world-with-cmake",level:2},{value:"CMake project",id:"cmake-project",level:3},{value:"FetchContent",id:"fetchcontent",level:3},{value:"How FetchContent module works",id:"how-fetchcontent-module-works",level:4},{value:"Build Hello world",id:"build-hello-world-cmake",level:3},{value:"Execute Hello world",id:"execute-hello-world-cmake",level:3},{value:"Hello world with qmake",id:"hello-world-with-qmake",level:2},{value:"qmake project",id:"qmake-project",level:3},{value:"Auto-configure using .qmake.conf and .env",id:"auto-configure-using-qmake_conf-and-env",level:4},{value:"Build Hello world",id:"build-hello-world-qmake",level:3},{value:"Execute Hello world",id:"execute-hello-world-qmake",level:3}];function j(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"building-hello-world",children:"Building: Hello world"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#introduction",children:"Introduction"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#prepare-sqlite-3-database",children:"Prepare SQLite 3 database"})}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#install-dependencies",children:"Install dependencies"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#using-vcpkg-json-manifest-mode",children:"Using vcpkg.json"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#using-vcpkg-install-manually",children:"Using vcpkg install"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#source-code",children:"Source code"})}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#hello-world-with-cmake",children:"Hello world with CMake"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#cmake-project",children:"CMake project"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#fetchcontent",children:"FetchContent"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#build-hello-world-cmake",children:"Build Hello world"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#execute-hello-world-cmake",children:"Execute Hello world"})}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#hello-world-with-qmake",children:"Hello world with qmake"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#qmake-project",children:"qmake project"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#build-hello-world-qmake",children:"Build Hello world"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#execute-hello-world-qmake",children:"Execute Hello world"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)("div",{className:"api-stability alert alert--success",children:(0,i.jsxs)(n.p,{children:[(0,i.jsx)(t.A,{to:"/stability#stability-indexes",children:(0,i.jsx)(n.strong,{children:"Stability: 2"})})," - Stable"]})}),"\n",(0,i.jsxs)(n.p,{children:["We will try to create the simplest working console application, in the terminal with the ",(0,i.jsx)(n.code,{children:"CMake"})," and in the ",(0,i.jsx)(n.code,{children:"QtCreator IDE"})," with the ",(0,i.jsx)(n.code,{children:"qmake"})," build systems."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"HelloWorld"})," example also expects the following ",(0,i.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:"folders structure"}),", let's create them."]}),"\n",(0,i.jsxs)(s.A,{groupId:d.vf,children:[(0,i.jsx)(a.A,{value:d.b,label:d.ux,children:(0,i.jsx)(o.A,{className:"language-powershell",children:`cd ${(0,c.OZ)(d.b)}\nmkdir HelloWorld/HelloWorld\ncd HelloWorld`})}),(0,i.jsx)(a.A,{value:d.xj,label:d.gg,children:(0,i.jsx)(o.A,{className:"language-bash",children:`cd ${(0,c.OZ)(d.xj)}\nmkdir -p HelloWorld/HelloWorld\ncd HelloWorld`})})]}),"\n",(0,i.jsx)(n.h2,{id:"prepare-sqlite-3-database",children:"Prepare SQLite 3 database"}),"\n",(0,i.jsxs)(n.p,{children:["The easiest way to demonstrate the ",(0,i.jsx)(n.code,{children:"HelloWorld"})," example will be with a ",(0,i.jsx)(n.code,{children:"SQLite 3"})," database."]}),"\n",(0,i.jsxs)(n.p,{children:["Execute the following command in the terminal to create and insert two rows into the ",(0,i.jsx)(n.code,{children:"SQLite 3"})," database."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sqlite3 HelloWorld.sqlite3 \"\ncreate table posts(id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name VARCHAR NOT NULL);\ninsert into posts values(1, 'First Post');\ninsert into posts values(2, 'Second Post');\nselect * from posts;\"\n"})}),"\n",(0,i.jsx)(n.h2,{id:"install-dependencies",children:"Install dependencies"}),"\n",(0,i.jsxs)(n.p,{children:["First, install the ",(0,i.jsx)(n.code,{children:"vcpkg"})," package manager as is described ",(0,i.jsx)(n.a,{href:"/building/tinyorm#vcpkg",children:"here"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"range-v3"})," and ",(0,i.jsx)(n.code,{children:"tabulate"})," libraries are required dependencies because ",(0,i.jsx)(n.code,{children:"TinyORM"})," uses them in header files, you have to install them before you can use ",(0,i.jsx)(n.code,{children:"TinyORM"}),". The ",(0,i.jsx)(n.code,{children:"tabulate"})," library is only needed in the ",(0,i.jsx)(n.code,{children:"tom"})," migrations it's used by the ",(0,i.jsx)(n.code,{children:"migrate:status"})," command."]}),"\n",(0,i.jsxs)(n.p,{children:["There are two ways how to install the ",(0,i.jsx)(n.code,{children:"range-v3"})," and ",(0,i.jsx)(n.code,{children:"tabulate"})," libraries using ",(0,i.jsx)(n.code,{children:"vcpkg"}),"."]}),"\n",(0,i.jsxs)(n.h4,{id:"using-vcpkg-json-manifest-mode",children:["Using vcpkg.json ",(0,i.jsx)("small",{children:"(manifest mode)"})]}),"\n",(0,i.jsxs)(n.p,{children:["Create a ",(0,i.jsx)(n.code,{children:"vcpkg.json"})," file with the following content. ",(0,i.jsx)(n.code,{children:"CMake"})," example below uses this method."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd HelloWorld\nvim vcpkg.json\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",metastring:"title='vcpkg.json'",children:'{\n "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json",\n "name": "tinyorm-helloworld",\n "version-semver": "0.1.0",\n "maintainers": "Silver Zachara ",\n "description": "Hello world console application for TinyORM C++ library",\n "homepage": "https://github.com/silverqx/TinyORM",\n "documentation": "https://www.tinyorm.org/building/hello-world",\n "supports": "!(uwp | arm | android | emscripten | osx | ios | xbox | freebsd | openbsd | wasm32)",\n "dependencies": [\n "range-v3",\n "tabulate"\n ]\n}\n'})}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["Only ",(0,i.jsx)(n.code,{children:"CMake"})," via the ",(0,i.jsx)(n.code,{children:"toolchain file"})," supports this method."]})}),"\n",(0,i.jsxs)(n.h4,{id:"using-vcpkg-install-manually",children:["Using vcpkg install ",(0,i.jsx)("small",{children:"(manually)"})]}),"\n",(0,i.jsxs)(n.p,{children:["This method can be used with both ",(0,i.jsx)(n.code,{children:"CMake"})," and ",(0,i.jsx)(n.code,{children:"qmake"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd ../../vcpkg\n\nvcpkg search range-v3\nvcpkg search tabulate\nvcpkg install range-v3 tabulate\nvcpkg list\n"})}),"\n",(0,i.jsx)(n.h2,{id:"source-code",children:"Source code"}),"\n",(0,i.jsxs)(n.p,{children:["Let's start in the ",(0,i.jsx)(n.code,{children:"HelloWorld"})," project folder."]}),"\n",(0,i.jsxs)(s.A,{groupId:d.vf,children:[(0,i.jsx)(a.A,{value:d.b,label:d.ux,children:(0,i.jsx)(o.A,{className:"language-powershell",children:`cd ${(0,c.OZ)(d.b)}/HelloWorld/HelloWorld`})}),(0,i.jsx)(a.A,{value:d.xj,label:d.gg,children:(0,i.jsx)(o.A,{className:"language-bash",children:`cd ${(0,c.OZ)(d.xj)}/HelloWorld/HelloWorld`})})]}),"\n",(0,i.jsxs)(n.p,{children:["Create ",(0,i.jsx)(n.code,{children:"main.cpp"})," source file."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"vim main.cpp\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["To paste a source code correctly in ",(0,i.jsx)(n.code,{children:"vim"}),", press ",(0,i.jsx)("kbd",{children:"Shift"})," + ",(0,i.jsx)("kbd",{children:"p"}),"."]})}),"\n",(0,i.jsx)(n.p,{children:"And paste the following code."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-cpp",metastring:"title='main.cpp'",children:'#include \n#include \n\n#ifdef _WIN32\n# include \n#endif\n\n#include \n\nusing Orm::DB;\n\nint main(int argc, char *argv[])\n{\n#ifdef _WIN32\n SetConsoleOutputCP(CP_UTF8);\n// SetConsoleOutputCP(1250);\n#endif\n\n /* Needed from Qt v6.5.3 to avoid:\n qt.core.qobject.connect: QObject::connect(QObject, Unknown): invalid nullptr parameter */\n QCoreApplication app(argc, argv);\n\n // Ownership of a shared_ptr()\n auto manager = DB::create({\n {"driver", "QSQLITE"},\n {"database", qEnvironmentVariable("TINYORM_HELLOWORLD_DB_SQLITE_DATABASE",\n "../../HelloWorld.sqlite3")},\n {"check_database_exists", true},\n });\n\n auto posts = DB::select("select * from posts");\n\n while(posts.next())\n qDebug() << posts.value("id").toULongLong()\n << posts.value("name").toString();\n}\n'})}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"QSqlDatabase"})," depends on ",(0,i.jsx)(n.code,{children:"QCoreApplication"})," from ",(0,i.jsx)(n.code,{children:"Qt v6.5.3"})," so you must create the ",(0,i.jsx)(n.code,{children:"QCoreApplication"})," instance before you will call anything from the ",(0,i.jsx)(n.code,{children:"TinyORM"})," library. \ud83e\udee4 The change was made ",(0,i.jsx)(n.a,{href:"https://github.com/qt/qtbase/commit/8d2bdc9cd5482eace12ba7e45304857bd24db0e6#diff-1d355c25c0b0eddec2be48253407780c4dc510d986739aec61e1ec892ccaf86e",children:"here"}),"."]})}),"\n",(0,i.jsx)(n.h2,{id:"hello-world-with-cmake",children:"Hello world with CMake"}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["If something is not clear, you can still look at GitHub Action ",(0,i.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/tree/main/.github/workflows",children:(0,i.jsx)(n.code,{children:"workflows"})})," how the build is done."]})}),"\n",(0,i.jsxs)(n.p,{children:["Create a folder for the ",(0,i.jsx)(n.code,{children:"CMake"})," build."]}),"\n",(0,i.jsxs)(s.A,{groupId:d.vf,children:[(0,i.jsx)(a.A,{value:d.b,label:d.ux,children:(0,i.jsx)(o.A,{className:"language-powershell",children:"cd ..\nmkdir HelloWorld-builds-cmake/build-debug\n\ncd HelloWorld"})}),(0,i.jsx)(a.A,{value:d.xj,label:d.gg,children:(0,i.jsx)(o.A,{className:"language-bash",children:"cd ..\nmkdir -p HelloWorld-builds-cmake/build-debug\n\ncd HelloWorld"})})]}),"\n",(0,i.jsx)(n.h3,{id:"cmake-project",children:"CMake project"}),"\n",(0,i.jsxs)(n.p,{children:["Create ",(0,i.jsx)(n.code,{children:"CMakeLists.txt"})," file with the following content."]}),"\n",(0,i.jsxs)(s.A,{groupId:d.vf,children:[(0,i.jsx)(a.A,{value:d.b,label:d.ux,children:(0,i.jsx)(o.A,{className:"language-cmake",children:`cmake_minimum_required(VERSION VERSION 3.22...3.30 FATAL_ERROR)\n\nproject(HelloWorld LANGUAGES CXX)\n\n# build tree\nlist(APPEND CMAKE_PREFIX_PATH "${(0,c.nC)(d.b,(0,c.OZ)(d.b))}/TinyORM/TinyORM-builds-cmake/build-debug")\n\nset(CMAKE_CXX_STANDARD 20)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\nadd_executable(HelloWorld\n main.cpp\n)\n\nfind_package(QT NAMES Qt6 COMPONENTS Core REQUIRED)\nfind_package(Qt\${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)\nfind_package(TinyOrm 0.38.1 CONFIG REQUIRED)\n\ntarget_link_libraries(HelloWorld\n PRIVATE\n Qt\${QT_VERSION_MAJOR}::Core\n TinyOrm::TinyOrm\n)`})}),(0,i.jsx)(a.A,{value:d.xj,label:d.gg,children:(0,i.jsx)(o.A,{className:"language-cmake",children:`cmake_minimum_required(VERSION VERSION 3.22...3.30 FATAL_ERROR)\n\nproject(HelloWorld LANGUAGES CXX)\n\n# build tree\nlist(APPEND CMAKE_PREFIX_PATH "${(0,c.nC)(d.xj,(0,c.OZ)(d.xj))}/TinyORM/TinyORM-builds-cmake/build-debug")\n\nset(CMAKE_CXX_STANDARD 20)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\nadd_executable(HelloWorld\n main.cpp\n)\n\nfind_package(QT NAMES Qt6 COMPONENTS Core REQUIRED)\nfind_package(Qt\${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)\nfind_package(TinyOrm 0.38.1 CONFIG REQUIRED)\n\ntarget_link_libraries(HelloWorld\n PRIVATE\n Qt\${QT_VERSION_MAJOR}::Core\n TinyOrm::TinyOrm\n)`})})]}),"\n",(0,i.jsx)(n.h3,{id:"fetchcontent",children:"FetchContent"}),"\n",(0,i.jsxs)(n.p,{children:["If you don't have cloned and built the ",(0,i.jsx)(n.code,{children:"TinyORM"})," library, or you want to quickly try TinyORM without wasting time with cloning and building the TinyORM library, then you can use CMake's ",(0,i.jsx)(n.a,{href:"https://cmake.org/cmake/help/latest/module/FetchContent.html",children:(0,i.jsx)(n.code,{children:"FetchContent"})})," module that will do all of this for you."]}),"\n",(0,i.jsxs)(n.p,{children:["Instead of providing a path by the ",(0,i.jsx)(n.code,{children:"CMAKE_PREFIX_PATH"})," (or using the ",(0,i.jsx)(n.code,{children:"User Package Registry"}),") like in the example below:"]}),"\n",(0,i.jsxs)(s.A,{groupId:d.vf,children:[(0,i.jsx)(a.A,{value:d.b,label:d.ux,children:(0,i.jsx)(o.A,{className:"language-cmake",children:`# build tree\nlist(APPEND CMAKE_PREFIX_PATH "${(0,c.nC)(d.b,(0,c.OZ)(d.b))}/TinyORM/TinyORM-builds-cmake/build-debug")`})}),(0,i.jsx)(a.A,{value:d.xj,label:d.gg,children:(0,i.jsx)(o.A,{className:"language-cmake",children:`# build tree\nlist(APPEND CMAKE_PREFIX_PATH "${(0,c.nC)(d.xj,(0,c.OZ)(d.xj))}/TinyORM/TinyORM-builds-cmake/build-debug")`})})]}),"\n",(0,i.jsxs)(n.p,{children:["You can use the ",(0,i.jsx)(n.a,{href:"https://cmake.org/cmake/help/latest/module/FetchContent.html",children:(0,i.jsx)(n.code,{children:"FetchContent"})})," module like in the following example."]}),"\n",(0,i.jsxs)(s.A,{groupId:d.vf,children:[(0,i.jsx)(a.A,{value:d.b,label:d.ux,children:(0,i.jsx)(o.A,{className:"language-cmake",children:"cmake_minimum_required(VERSION VERSION 3.22...3.30 FATAL_ERROR)\n\nproject(HelloWorld LANGUAGES CXX)\n\nset(CMAKE_CXX_STANDARD 20)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\n# FetchContent method\ninclude(FetchContent)\nFetchContent_Declare(TinyOrm\n GIT_REPOSITORY https://github.com/silverqx/TinyORM.git\n GIT_TAG origin/main\n OVERRIDE_FIND_PACKAGE\n)\n# Here you can configure TinyORM CMake options\nset(MYSQL_PING OFF)\nset(TOM_EXAMPLE ON)\n\nadd_executable(HelloWorld\n main.cpp\n)\n\nfind_package(QT NAMES Qt6 COMPONENTS Core REQUIRED)\nfind_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)\nfind_package(TinyOrm 0.38.1 CONFIG REQUIRED)\n\ntarget_link_libraries(HelloWorld\n PRIVATE\n Qt${QT_VERSION_MAJOR}::Core\n TinyOrm::TinyOrm\n)"})}),(0,i.jsx)(a.A,{value:d.xj,label:d.gg,children:(0,i.jsx)(o.A,{className:"language-cmake",children:"cmake_minimum_required(VERSION VERSION 3.22...3.30 FATAL_ERROR)\n\nproject(HelloWorld LANGUAGES CXX)\n\nset(CMAKE_CXX_STANDARD 20)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF)\n\n# FetchContent method\ninclude(FetchContent)\nFetchContent_Declare(TinyOrm\n GIT_REPOSITORY https://github.com/silverqx/TinyORM.git\n GIT_TAG origin/main\n OVERRIDE_FIND_PACKAGE\n)\n# Here you can configure TinyORM CMake options\nset(MYSQL_PING OFF)\nset(TOM_EXAMPLE ON)\n\nadd_executable(HelloWorld\n main.cpp\n)\n\nfind_package(QT NAMES Qt6 COMPONENTS Core REQUIRED)\nfind_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)\nfind_package(TinyOrm 0.38.1 CONFIG REQUIRED)\n\ntarget_link_libraries(HelloWorld\n PRIVATE\n Qt${QT_VERSION_MAJOR}::Core\n TinyOrm::TinyOrm\n)"})})]}),"\n",(0,i.jsx)(n.h4,{id:"how-fetchcontent-module-works",children:"How FetchContent module works"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"FetchContent_Declare"})," command is like calling the git clone inside the build folder and then adding a cloned folder in a similar way as the ",(0,i.jsx)(n.code,{children:"add_subdirectory()"})," command does."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"FetchContent_MakeAvailable()"})," internally calls the ",(0,i.jsx)(n.code,{children:"find_package()"})," command or if you pass the ",(0,i.jsx)(n.code,{children:"OVERRIDE_FIND_PACKAGE"})," argument, then you don't have to call the the ",(0,i.jsx)(n.code,{children:"FetchContent_MakeAvailable"}),", but you must call the ",(0,i.jsx)(n.code,{children:"find_package( x.y.z CONFIG REQUIRED)"})," command manually."]}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["An advantage of the ",(0,i.jsx)(n.code,{children:"OVERRIDE_FIND_PACKAGE"})," argument is that you can call the ",(0,i.jsx)(n.code,{children:"find_package"})," command much later, and you can insert additional configurations between."]})}),"\n",(0,i.jsx)(n.h3,{id:"build-hello-world-cmake",children:"Build Hello world"}),"\n",(0,i.jsxs)(n.p,{children:["Now you are ready to configure ",(0,i.jsx)(n.code,{children:"HelloWorld"})," ",(0,i.jsx)(n.code,{children:"CMake"})," application."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd ../HelloWorld-builds-cmake/build-debug\n"})}),"\n",(0,i.jsxs)(s.A,{groupId:d.vf,children:[(0,i.jsx)(a.A,{value:d.b,label:d.ux,children:(0,i.jsx)(o.A,{className:"language-powershell",children:`cmake.exe \`\n-S "${(0,c.OZ)(d.b)}/HelloWorld/HelloWorld" \`\n-B "${(0,c.OZ)(d.b)}/HelloWorld/HelloWorld-builds-cmake/build-debug" \`\n-G 'Ninja' \`\n-D CMAKE_BUILD_TYPE:STRING='Debug' \`\n-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${(0,c.Sn)(d.b)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \`\n-D CMAKE_CXX_SCAN_FOR_MODULES:BOOL=OFF \`\n-D CMAKE_INSTALL_PREFIX:PATH="${(0,c.Sn)(d.b)}/tmp/HelloWorld"`})}),(0,i.jsx)(a.A,{value:d.xj,label:d.gg,children:(0,i.jsx)(o.A,{className:"language-bash",children:`cmake \\\n-S "${(0,c.OZ)(d.xj)}/HelloWorld/HelloWorld" \\\n-B "${(0,c.OZ)(d.xj)}/HelloWorld/HelloWorld-builds-cmake/build-debug" \\\n-G 'Ninja' \\\n-D CMAKE_BUILD_TYPE:STRING='Debug' \\\n-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${(0,c.Sn)(d.xj)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \\\n-D CMAKE_CXX_SCAN_FOR_MODULES:BOOL=OFF \\\n-D CMAKE_INSTALL_PREFIX:PATH="${(0,c.Sn)(d.xj)}/tmp/TinyORM"`})})]}),"\n",(0,i.jsx)(n.p,{children:"And build."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cmake --build . --target all\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["Enable the ",(0,i.jsx)(n.a,{href:"/building/tinyorm#cmake-strict_mode-option",children:(0,i.jsx)(n.code,{children:"TINYORM_STRICT_MODE"})})," environment variable to produce better code and to follow good code practices."]})}),"\n",(0,i.jsx)(n.h3,{id:"execute-hello-world-cmake",children:"Execute Hello world"}),"\n",(0,i.jsxs)(n.p,{children:["Do not forget to add ",(0,i.jsx)(n.code,{children:"TinyOrm0d.dll"})," on the path on Windows and on the ",(0,i.jsx)(n.code,{children:"LD_LIBRARY_PATH"})," on Linux, so ",(0,i.jsx)(n.code,{children:"HelloWorld"})," application can find it during execution, as is described ",(0,i.jsx)(n.a,{href:"/building/tinyorm#tinyorm-on-path-cmake",children:"here"}),"."]}),"\n",(0,i.jsxs)(s.A,{groupId:d.vf,name:"tinyorm-on-path",children:[(0,i.jsx)(a.A,{value:d.b,label:d.ux,children:(0,i.jsx)(o.A,{className:"language-powershell",children:`$env:Path = "${(0,c.OZ)(d.b,!1)}\\TinyORM\\TinyORM-builds-cmake\\build-debug;" + $env:Path`})}),(0,i.jsx)(a.A,{value:d.xj,label:d.gg,children:(0,i.jsx)(o.A,{className:"language-bash",children:`export LD_LIBRARY_PATH=${(0,c.OZ)(d.xj)}/TinyORM/TinyORM-builds-cmake/build-debug\${PATH:+:}$PATH`})})]}),"\n",(0,i.jsxs)(n.p,{children:["Execute ",(0,i.jsx)(n.code,{children:"HelloWorld"})," example."]}),"\n",(0,i.jsxs)(s.A,{groupId:d.vf,children:[(0,i.jsx)(a.A,{value:d.b,label:d.ux,children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-powershell",children:".\\HelloWorld.exe\n"})})}),(0,i.jsx)(a.A,{value:d.xj,label:d.gg,children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"./HelloWorld\n"})})})]}),"\n",(0,i.jsx)(n.p,{children:"The output will look like this."}),"\n",(0,i.jsx)(o.A,{className:"language-less",children:'Executed prepared query (6ms, -1 results, 0 affected, tinyorm_default) : select * from posts\n1 "First Post"\n2 "Second Post"'}),"\n",(0,i.jsx)(n.h2,{id:"hello-world-with-qmake",children:"Hello world with qmake"}),"\n",(0,i.jsxs)(n.p,{children:["Create a folder for the ",(0,i.jsx)(n.code,{children:"qmake"})," build."]}),"\n",(0,i.jsxs)(s.A,{groupId:d.vf,children:[(0,i.jsx)(a.A,{value:d.b,label:d.ux,children:(0,i.jsx)(o.A,{className:"language-powershell",children:`cd ${(0,c.OZ)(d.b)}/HelloWorld\n\nmkdir HelloWorld-builds-qmake`})}),(0,i.jsx)(a.A,{value:d.xj,label:d.gg,children:(0,i.jsx)(o.A,{className:"language-bash",children:`cd ${(0,c.OZ)(d.xj)}/HelloWorld\n\nmkdir HelloWorld-builds-qmake`})})]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"#source-code",children:(0,i.jsx)(n.code,{children:"source code"})})," is the same as for the ",(0,i.jsx)(n.code,{children:"HelloWorld CMake"})," example."]}),"\n",(0,i.jsx)(n.h3,{id:"qmake-project",children:"qmake project"}),"\n",(0,i.jsxs)(n.p,{children:["Create ",(0,i.jsx)(n.code,{children:"HelloWorld.pro"})," qmake file with the following content."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd HelloWorld\nvim HelloWorld.pro\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["To paste a source code correctly in ",(0,i.jsx)(n.code,{children:"vim"}),", press ",(0,i.jsx)("kbd",{children:"Shift"})," + ",(0,i.jsx)("kbd",{children:"p"}),"."]})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-qmake",metastring:"title='HelloWorld.pro'",children:"QT -= gui\n\nTEMPLATE = app\n\nCONFIG *= cmdline\n\nDEFINES *= PROJECT_TINYORM_HELLOWORLD\n\nSOURCES += $$PWD/main.cpp\n\n# Auto-configure TinyORM library \ud83d\udd25\ninclude($$TINY_MAIN_DIR/TinyORM/qmake/TinyOrm.pri)\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsxs)(n.p,{children:["The exact ",(0,i.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:"folders structure"})," is crucial in this example because the paths to the ",(0,i.jsx)(n.code,{children:"TinyORM"})," source and build folders are relative."]})}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsx)(n.p,{children:"Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!"})}),"\n",(0,i.jsxs)(n.h4,{id:"auto-configure-using-qmake_conf-and-env",children:[(0,i.jsx)(n.code,{children:"Auto-configure"})," using ",(0,i.jsx)(n.code,{children:".qmake.conf"})," and ",(0,i.jsx)(n.code,{children:".env"})]}),"\n",(0,i.jsxs)(n.p,{children:["If you want to have properly configured ",(0,i.jsx)(n.code,{children:"DEFINES"})," (C preprocessor macros) or have Qt headers marked as system headers, then you need to specify a path to the ",(0,i.jsx)(n.code,{children:"TinyORM"})," qmake features (",(0,i.jsx)(n.code,{children:".prf"})," files) which handle this correctly; this path is provided by the ",(0,i.jsx)(n.code,{children:"QMAKEFEATURES"})," variable and can only be set in the ",(0,i.jsx)(n.code,{children:".qmake.conf"})," file."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["Read the ",(0,i.jsx)(n.a,{href:"/building/tinyorm#consume-tinyorm-library-qmake",children:"Consume TinyOrm library (qmake)"})," section, as everything that is described in that section applies here as well."]})}),"\n",(0,i.jsxs)(n.p,{children:["Create the ",(0,i.jsx)(n.code,{children:".qmake.conf"})," file in the ",(0,i.jsx)(n.code,{children:"HelloWorld"})," project root folder with the following content."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-qmake",metastring:"title='.qmake.conf'",children:"# Path to the PARENT folder of the TinyORM source folder\nTINY_MAIN_DIR = $$clean_path($$PWD/../../TinyORM/)\n# To find .env and .env.$$QMAKE_PLATFORM files\nTINY_DOTENV_ROOT = $$PWD\n# Path to the current build tree (used to guess the TinyORM build tree)\n#TINY_BUILD_TREE = $$shadowed($$PWD)\n\n# To find .prf files, needed by eg. CONFIG += tiny_system_headers inline/extern_constants\nQMAKEFEATURES *= $$quote($$TINY_MAIN_DIR/TinyORM/qmake/features)\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Then, create a ",(0,i.jsx)("code",{children:".env.(win32|unix|mingw)"})," file in the ",(0,i.jsx)(n.code,{children:"HelloWorld"})," project root folder with the following content."]}),"\n",(0,i.jsxs)(s.A,{groupId:d.vf,children:[(0,i.jsx)(a.A,{value:d.b,label:".env.win32",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-qmake",children:"# Names and values of these qmake variables are crucial, they are used in HelloWorld.pro\n# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!\n\n# Path to the TinyORM build folder\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_2_MSVC2022_64bit-Debug/)\n\n# Path to the vcpkg - range-v3\n# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty\nTINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)\nTINY_VCPKG_TRIPLET = x64-windows\n\n# Enable ccache wrapper\n#CONFIG *= ccache\n"})})}),(0,i.jsx)(a.A,{value:d.xj,label:".env.unix",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-qmake",children:"# Names and values of these qmake variables are crucial, they are used in HelloWorld.pro\n# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!\n\n# Path to the TinyORM build folder\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_2_clang18_64bit_ccache-Debug/)\n\n# Path to the vcpkg - range-v3\n# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty\nTINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)\nTINY_VCPKG_TRIPLET = x64-linux\n\n# Use LLD linker for Clang\nclang: CONFIG *= use_lld_linker\nelse: CONFIG *= use_gold_linker\n\n# Or use the mold linker\n#QMAKE_LFLAGS *= -fuse-ld=mold\n"})})}),(0,i.jsx)(a.A,{value:"mingw",label:".env.mingw",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-qmake",children:"# Names and values of these qmake variables are crucial, they are used in HelloWorld.pro\n# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!\n\n# Path to the TinyORM build folder\nTINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_2_MSYS2_UCRT64_clang_64bit-Debug/)\n\n# Path to the vcpkg - range-v3\n# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty\nTINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)\nTINY_VCPKG_TRIPLET = x64-mingw-dynamic\n\n# Enable ccache wrapper\n#CONFIG *= ccache\n\n# Use alternative linker (for both GCC and Clang)\n# CONFIG *= use_lld_linker does not work on MinGW\n#QMAKE_LFLAGS *= -fuse-ld=lld\n"})})})]}),"\n",(0,i.jsxs)(n.p,{children:["Don't forget to update the ",(0,i.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," and ",(0,i.jsx)(n.code,{children:"TINY_VCPKG_ROOT"})," folder paths to your needs if you are not using the recommended ",(0,i.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:(0,i.jsx)(n.code,{children:"Folders structure"})}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["You can use the ",(0,i.jsxs)(n.a,{href:"/building/tinyorm#partial-guessing-of-the-tinyorm_build_tree",children:["Partial guessing of the ",(0,i.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})]})," if you don't like to specify it manually. Just comment out the ",(0,i.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," and uncomment the ",(0,i.jsx)(n.code,{children:"TINY_BUILD_TREE = $$shadowed($$PWD)"})," in the ",(0,i.jsx)(n.code,{children:".qmake.conf"})," file."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["You can entirely avoid the ",(0,i.jsx)(n.code,{children:".env"})," files, just move the ",(0,i.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})," to the ",(0,i.jsx)(n.code,{children:".qmake.conf"})," or remove it by help of ",(0,i.jsxs)(n.a,{href:"/building/tinyorm#partial-guessing-of-the-tinyorm_build_tree",children:["Partial guessing of the ",(0,i.jsx)(n.code,{children:"TINYORM_BUILD_TREE"})]})," and set the ",(0,i.jsx)(n.code,{children:"VCPKG_ROOT"})," environment variable at system level as is described in ",(0,i.jsx)(n.a,{href:"/building/tinyorm#set-up-vcpkg-environment",children:(0,i.jsx)(n.code,{children:"Set up vcpkg environment"})}),"."]})}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["Configuring by the ",(0,i.jsx)(n.code,{children:".qmake.conf"})," and ",(0,i.jsx)(n.code,{children:".env"})," files has one big advantage, which is that you don't have to modify the project files."]})}),"\n",(0,i.jsx)(n.h3,{id:"build-hello-world-qmake",children:"Build Hello world"}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["I recommend creating a new ",(0,i.jsx)(n.code,{children:"Session"})," in the ",(0,i.jsx)(n.code,{children:"QtCreator IDE"})," as is described ",(0,i.jsx)(n.a,{href:"/building/tinyorm#open-qtcreator-ide",children:"here"}),"."]})}),"\n",(0,i.jsxs)(n.p,{children:["Now you can open the ",(0,i.jsx)(n.code,{children:"HelloWorld.pro"})," project in the ",(0,i.jsx)(n.code,{children:"QtCreator IDE"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["This will open the ",(0,i.jsx)(n.code,{children:"Configure Project"})," tab, select some kit and update build folder paths to meet our ",(0,i.jsx)(n.a,{href:"/building/tinyorm#folders-structure",children:"folders structure"})," or like you want."]}),"\n",(0,i.jsx)("img",{src:l(3180).A,alt:"HelloWorld - QtCreator - Configure Project",width:"760"}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["You can force the ",(0,i.jsx)(n.code,{children:"QtCreator"})," to generate a build folders structure as is described ",(0,i.jsx)(n.a,{href:"/building/tinyorm#qtcreator-default-build-directory",children:"here"}),"."]})}),"\n",(0,i.jsxs)(n.p,{children:["You are ready to configure build options, hit ",(0,i.jsx)("kbd",{children:"Ctrl"}),"+",(0,i.jsx)("kbd",{children:"5"})," to open ",(0,i.jsx)(n.code,{children:"Project Settings"})," tab and select ",(0,i.jsx)(n.code,{children:"Build"})," in the left sidebar to open the ",(0,i.jsx)(n.code,{children:"Build Settings"}),", it should look similar to the following picture."]}),"\n",(0,i.jsx)("img",{src:l(7028).A,className:"no-blurry",alt:"HelloWorld - QtCreator - Build Settings",width:"760"}),"\n",(0,i.jsxs)(n.p,{children:["Disable ",(0,i.jsx)(n.code,{children:"QML debugging and profiling"})," and ",(0,i.jsx)(n.code,{children:"Qt Quick Compiler"}),", they are not used."]}),"\n",(0,i.jsxs)(n.p,{children:["In the left sidebar open ",(0,i.jsx)(n.code,{children:"Dependencies"})," and check ",(0,i.jsx)(n.code,{children:"TinyORM"})," project and ",(0,i.jsx)(n.code,{children:"Synchronize configuration"}),", this setting ensures that the current project will be rebuilt correctly when the ",(0,i.jsx)(n.code,{children:"TinyORM"})," library source code changes."]}),"\n",(0,i.jsxs)(n.p,{children:["Everything is ready to build, you can press ",(0,i.jsx)("kbd",{children:"Ctrl"}),"+",(0,i.jsx)("kbd",{children:"b"})," to build the project."]}),"\n",(0,i.jsx)(n.h3,{id:"execute-hello-world-qmake",children:"Execute Hello world"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"QtCreator"})," takes care of all the necessary configurations, sets up the build environment correctly, and also prepends dependency libraries on the system path on Windows and on the ",(0,i.jsx)(n.code,{children:"LD_LIBRARY_PATH"})," on Linux."]}),"\n",(0,i.jsxs)(n.p,{children:["The only thing you might want to change is to run the ",(0,i.jsx)(n.code,{children:"HelloWorld"})," example in the new terminal window. To do so, hit ",(0,i.jsx)("kbd",{children:"Ctrl"}),"+",(0,i.jsx)("kbd",{children:"5"})," to open the ",(0,i.jsx)(n.code,{children:"Project Settings"})," tab and select ",(0,i.jsx)(n.code,{children:"Run"})," in the left sidebar to open the ",(0,i.jsx)(n.code,{children:"Run Settings"}),", then in the ",(0,i.jsx)(n.code,{children:"Run"})," section select the ",(0,i.jsx)(n.code,{children:"Run in terminal"})," checkbox."]}),"\n",(0,i.jsxs)(n.p,{children:["To execute the ",(0,i.jsx)(n.code,{children:"HelloWorld"})," example press ",(0,i.jsx)("kbd",{children:"Ctrl"})," + ",(0,i.jsx)("kbd",{children:"r"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"The output will look like this."}),"\n",(0,i.jsx)(o.A,{className:"language-less",children:'Executed prepared query (6ms, -1 results, 0 affected, tinyorm_default) : select * from posts\n1 "First Post"\n2 "Second Post"'})]})}function g(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(j,{...e})}):j(e)}},9365:(e,n,l)=>{l.d(n,{A:()=>o});l(6540);var i=l(4164);const r={tabItem:"tabItem_Ymn6"};var t=l(4848);function o(e){let{children:n,hidden:l,className:o}=e;return(0,t.jsx)("div",{role:"tabpanel",className:(0,i.A)(r.tabItem,o),hidden:l,children:n})}},1470:(e,n,l)=>{l.d(n,{A:()=>y});var i=l(6540),r=l(4164),t=l(3104),o=l(6347),a=l(205),s=l(7485),d=l(1682),c=l(679);function h(e){return i.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,i.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function u(e){const{values:n,children:l}=e;return(0,i.useMemo)((()=>{const e=n??function(e){return h(e).map((e=>{let{props:{value:n,label:l,attributes:i,default:r}}=e;return{value:n,label:l,attributes:i,default:r}}))}(l);return function(e){const n=(0,d.XI)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[n,l])}function p(e){let{value:n,tabValues:l}=e;return l.some((e=>e.value===n))}function m(e){let{queryString:n=!1,groupId:l}=e;const r=(0,o.W6)(),t=function(e){let{queryString:n=!1,groupId:l}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!l)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return l??null}({queryString:n,groupId:l});return[(0,s.aZ)(t),(0,i.useCallback)((e=>{if(!t)return;const n=new URLSearchParams(r.location.search);n.set(t,e),r.replace({...r.location,search:n.toString()})}),[t,r])]}function x(e){const{defaultValue:n,queryString:l=!1,groupId:r}=e,t=u(e),[o,s]=(0,i.useState)((()=>function(e){let{defaultValue:n,tabValues:l}=e;if(0===l.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!p({value:n,tabValues:l}))throw new Error(`Docusaurus error: The has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${l.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const i=l.find((e=>e.default))??l[0];if(!i)throw new Error("Unexpected error: 0 tabValues");return i.value}({defaultValue:n,tabValues:t}))),[d,h]=m({queryString:l,groupId:r}),[x,j]=function(e){let{groupId:n}=e;const l=function(e){return e?`docusaurus.tab.${e}`:null}(n),[r,t]=(0,c.Dv)(l);return[r,(0,i.useCallback)((e=>{l&&t.set(e)}),[l,t])]}({groupId:r}),g=(()=>{const e=d??x;return p({value:e,tabValues:t})?e:null})();(0,a.A)((()=>{g&&s(g)}),[g]);return{selectedValue:o,selectValue:(0,i.useCallback)((e=>{if(!p({value:e,tabValues:t}))throw new Error(`Can't select invalid tab value=${e}`);s(e),h(e),j(e)}),[h,j,t]),tabValues:t}}var j=l(2303);const g={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var b=l(4848);function f(e){let{className:n,block:l,selectedValue:i,selectValue:o,tabValues:a}=e;const s=[],{blockElementScrollPositionUntilNextRender:d}=(0,t.a_)(),c=e=>{const n=e.currentTarget,l=s.indexOf(n),r=a[l].value;r!==i&&(d(n),o(r))},h=e=>{let n=null;switch(e.key){case"Enter":c(e);break;case"ArrowRight":{const l=s.indexOf(e.currentTarget)+1;n=s[l]??s[0];break}case"ArrowLeft":{const l=s.indexOf(e.currentTarget)-1;n=s[l]??s[s.length-1];break}}n?.focus()};return(0,b.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,r.A)("tabs",{"tabs--block":l},n),children:a.map((e=>{let{value:n,label:l,attributes:t}=e;return(0,b.jsx)("li",{role:"tab",tabIndex:i===n?0:-1,"aria-selected":i===n,ref:e=>s.push(e),onKeyDown:h,onClick:c,...t,className:(0,r.A)("tabs__item",g.tabItem,t?.className,{"tabs__item--active":i===n}),children:l??n},n)}))})}function _(e){let{lazy:n,children:l,selectedValue:t}=e;const o=(Array.isArray(l)?l:[l]).filter(Boolean);if(n){const e=o.find((e=>e.props.value===t));return e?(0,i.cloneElement)(e,{className:(0,r.A)("margin-top--md",e.props.className)}):null}return(0,b.jsx)("div",{className:"margin-top--md",children:o.map(((e,n)=>(0,i.cloneElement)(e,{key:n,hidden:e.props.value!==t})))})}function T(e){const n=x(e);return(0,b.jsxs)("div",{className:(0,r.A)("tabs-container",g.tabList),children:[(0,b.jsx)(f,{...n,...e}),(0,b.jsx)(_,{...n,...e})]})}function y(e){const n=(0,j.A)();return(0,b.jsx)(T,{...e,children:h(e.children)},String(n))}},7324:(e,n,l)=>{l.d(n,{$E:()=>j,A3:()=>b,CW:()=>g,Dx:()=>c,F4:()=>u,Fi:()=>d,J_:()=>y,LQ:()=>f,Lf:()=>k,OO:()=>r,Q7:()=>_,b:()=>a,cy:()=>s,gg:()=>m,kl:()=>p,os:()=>h,pW:()=>t,ux:()=>x,vf:()=>i,xj:()=>o,xt:()=>T});const i="shell",r="database",t="application",o="bash",a="pwsh",s="zsh",d="maria",c="mysql",h="postgres",u="sqlite",p="application",m="bash",x="pwsh",j="zsh",g="MariaDB",b="MySQL",f="PostgreSQL",_="SQLite",T="tinyorm.org",y="$HOME/Code/c/",k="$env:USERPROFILE\\Code\\c\\"},6362:(e,n,l)=>{l.d(n,{A:()=>t});var i=l(6540),r=l(1838);function t(){const e=(0,i.useContext)(r.A);if(null!=e)return e;throw new Error("useRootFolderContext is used outside of Layout component.")}},6694:(e,n,l)=>{l.d(n,{OZ:()=>s,Sn:()=>o,T3:()=>c,bw:()=>d,nC:()=>h,np:()=>a});var i=l(6362),r=l(2303),t=l(7324);const o=function(e,n){return void 0===n&&(n=!0),u((0,i.A)().rootFolder[e]??d(e),e,n)},a=()=>(0,i.A)().rootFolder[t.pW]??d(t.pW),s=function(e,n){if(void 0===n&&(n=!0),null==e)throw new Error("The groupId in the applicationFolderPath() can not be empty.");const l=n||e!==t.b?"/":"\\";return u(o(e)+l+a(),e,n)};function d(e){if(null==e)throw new Error("The groupId in the folderDefaultValue() can not be empty.");if(!(0,r.A)())return"";switch(e){case t.b:return t.Lf;case t.xj:return t.J_;case t.pW:return t.xt;default:throw new Error(`No default value for '${e}' groupId in the folderDefaultValue().`)}}function c(e){return e===t.pW}function h(e,n){if(null==n||""===n)return n;const l="$ENV{$1}$2";switch(e){case t.b:return m(n).replace(/\$env:(.+?)(\/.*)/,l);case t.xj:return n.replace(/\$(.+?)(\/.*)/,l);default:throw new Error(`Unsupported shell type '${e}' in the convertToCmakeEnvVariable().`)}}function u(e,n,l){if(void 0===l&&(l=!0),null==e||""===e)return e;if(n!==t.b)return p(e);const i=p(e);return l?m(i):function(e){return null==e||""===e?e:e.replaceAll(/\/+/g,"\\")}(i)}function p(e){return null==e||""===e?e:e.replace(/[/\\]+$/,"")}function m(e){return null==e||""===e?e:e.replaceAll(/\\+(?! )/g,"/")}},7028:(e,n,l)=>{l.d(n,{A:()=>i});const i=l.p+"assets/images/qmake-build_settings-ebdc6c0c056d11462096ff10cba682a1.png"},3180:(e,n,l)=>{l.d(n,{A:()=>i});const i=l.p+"assets/images/qmake-configure_project-8caf87e6af4452f0c28bd15c85c392fc.png"}}]); \ No newline at end of file diff --git a/assets/js/runtime~main.04a383d2.js b/assets/js/runtime~main.23a0e3c5.js similarity index 58% rename from assets/js/runtime~main.04a383d2.js rename to assets/js/runtime~main.23a0e3c5.js index f03f2501b..47aa2454c 100644 --- a/assets/js/runtime~main.04a383d2.js +++ b/assets/js/runtime~main.23a0e3c5.js @@ -1 +1 @@ -(()=>{"use strict";var e,a,t,r,o,n={},f={};function d(e){var a=f[e];if(void 0!==a)return a.exports;var t=f[e]={exports:{}};return n[e].call(t.exports,t,t.exports,d),t.exports}d.m=n,e=[],d.O=(a,t,r,o)=>{if(!t){var n=1/0;for(i=0;i=o)&&Object.keys(d.O).every((e=>d.O[e](t[b])))?t.splice(b--,1):(f=!1,o0&&e[i-1][2]>o;i--)e[i]=e[i-1];e[i]=[t,r,o]},d.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return d.d(a,{a:a}),a},t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,d.t=function(e,r){if(1&r&&(e=this(e)),8&r)return e;if("object"==typeof e&&e){if(4&r&&e.__esModule)return e;if(16&r&&"function"==typeof e.then)return e}var o=Object.create(null);d.r(o);var n={};a=a||[null,t({}),t([]),t(t)];for(var f=2&r&&e;"object"==typeof f&&!~a.indexOf(f);f=t(f))Object.getOwnPropertyNames(f).forEach((a=>n[a]=()=>e[a]));return n.default=()=>e,d.d(o,n),o},d.d=(e,a)=>{for(var t in a)d.o(a,t)&&!d.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:a[t]})},d.f={},d.e=e=>Promise.all(Object.keys(d.f).reduce(((a,t)=>(d.f[t](e,a),a)),[])),d.u=e=>"assets/js/"+({27:"d459b1c4",48:"a94703ab",82:"5b254f70",98:"a7bd4aaa",117:"3dd307b5",129:"8a8faf8d",138:"1a4e3797",153:"1222ea4e",170:"ba3d4959",205:"b4f71b2f",258:"cb1e72f9",295:"21dc2778",304:"62a1276f",395:"0ab078a9",401:"17896441",467:"e3ac21cb",485:"59b1a96c",567:"22dd74f7",638:"7333c691",647:"5e95c892",742:"aba21aa0",755:"a4d3e054",871:"fb313d4e",957:"c141421f",976:"6356d98b",983:"feaee7f3",995:"cbe663fe"}[e]||e)+"."+{27:"ce3bf5fd",48:"34d838b2",82:"e884e04f",98:"e71dd57d",117:"b96ad197",129:"15047ffd",138:"675e6533",153:"9aaae761",158:"811bb36f",170:"dc30419f",205:"e4f96dcd",237:"da9a0891",258:"d9a03d3d",295:"1bac1858",304:"052e6f7b",395:"ae63e1f9",401:"b87ba7c0",416:"a3ad28f7",446:"d7af1da2",467:"fc49fa7b",485:"d742244a",567:"069dac02",638:"84bb69f7",647:"f92788a2",742:"cb1d9d7d",755:"6b43ed91",871:"afd496da",913:"3fa60236",957:"2356f0d5",976:"382c6edd",983:"30e60f2d",995:"bedb7f84"}[e]+".js",d.miniCssF=e=>{},d.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),d.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),r={},o="tinyorm.org:",d.l=(e,a,t,n)=>{if(r[e])r[e].push(a);else{var f,b;if(void 0!==t)for(var c=document.getElementsByTagName("script"),i=0;i{f.onerror=f.onload=null,clearTimeout(s);var o=r[e];if(delete r[e],f.parentNode&&f.parentNode.removeChild(f),o&&o.forEach((e=>e(t))),a)return a(t)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:f}),12e4);f.onerror=l.bind(null,f.onerror),f.onload=l.bind(null,f.onload),b&&document.head.appendChild(f)}},d.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},d.p="/",d.gca=function(e){return e={17896441:"401",d459b1c4:"27",a94703ab:"48","5b254f70":"82",a7bd4aaa:"98","3dd307b5":"117","8a8faf8d":"129","1a4e3797":"138","1222ea4e":"153",ba3d4959:"170",b4f71b2f:"205",cb1e72f9:"258","21dc2778":"295","62a1276f":"304","0ab078a9":"395",e3ac21cb:"467","59b1a96c":"485","22dd74f7":"567","7333c691":"638","5e95c892":"647",aba21aa0:"742",a4d3e054:"755",fb313d4e:"871",c141421f:"957","6356d98b":"976",feaee7f3:"983",cbe663fe:"995"}[e]||e,d.p+d.u(e)},(()=>{var e={354:0,869:0};d.f.j=(a,t)=>{var r=d.o(e,a)?e[a]:void 0;if(0!==r)if(r)t.push(r[2]);else if(/^(354|869)$/.test(a))e[a]=0;else{var o=new Promise(((t,o)=>r=e[a]=[t,o]));t.push(r[2]=o);var n=d.p+d.u(a),f=new Error;d.l(n,(t=>{if(d.o(e,a)&&(0!==(r=e[a])&&(e[a]=void 0),r)){var o=t&&("load"===t.type?"missing":t.type),n=t&&t.target&&t.target.src;f.message="Loading chunk "+a+" failed.\n("+o+": "+n+")",f.name="ChunkLoadError",f.type=o,f.request=n,r[1](f)}}),"chunk-"+a,a)}},d.O.j=a=>0===e[a];var a=(a,t)=>{var r,o,n=t[0],f=t[1],b=t[2],c=0;if(n.some((a=>0!==e[a]))){for(r in f)d.o(f,r)&&(d.m[r]=f[r]);if(b)var i=b(d)}for(a&&a(t);c{"use strict";var e,a,t,r,o,n={},f={};function b(e){var a=f[e];if(void 0!==a)return a.exports;var t=f[e]={exports:{}};return n[e].call(t.exports,t,t.exports,b),t.exports}b.m=n,e=[],b.O=(a,t,r,o)=>{if(!t){var n=1/0;for(i=0;i=o)&&Object.keys(b.O).every((e=>b.O[e](t[d])))?t.splice(d--,1):(f=!1,o0&&e[i-1][2]>o;i--)e[i]=e[i-1];e[i]=[t,r,o]},b.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return b.d(a,{a:a}),a},t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,b.t=function(e,r){if(1&r&&(e=this(e)),8&r)return e;if("object"==typeof e&&e){if(4&r&&e.__esModule)return e;if(16&r&&"function"==typeof e.then)return e}var o=Object.create(null);b.r(o);var n={};a=a||[null,t({}),t([]),t(t)];for(var f=2&r&&e;"object"==typeof f&&!~a.indexOf(f);f=t(f))Object.getOwnPropertyNames(f).forEach((a=>n[a]=()=>e[a]));return n.default=()=>e,b.d(o,n),o},b.d=(e,a)=>{for(var t in a)b.o(a,t)&&!b.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:a[t]})},b.f={},b.e=e=>Promise.all(Object.keys(b.f).reduce(((a,t)=>(b.f[t](e,a),a)),[])),b.u=e=>"assets/js/"+({27:"d459b1c4",48:"a94703ab",82:"5b254f70",98:"a7bd4aaa",117:"3dd307b5",129:"8a8faf8d",138:"1a4e3797",153:"1222ea4e",170:"ba3d4959",205:"b4f71b2f",258:"cb1e72f9",295:"21dc2778",304:"62a1276f",395:"0ab078a9",401:"17896441",467:"e3ac21cb",485:"59b1a96c",567:"22dd74f7",638:"7333c691",647:"5e95c892",742:"aba21aa0",755:"a4d3e054",871:"fb313d4e",957:"c141421f",976:"6356d98b",983:"feaee7f3",995:"cbe663fe"}[e]||e)+"."+{27:"ce3bf5fd",48:"34d838b2",82:"e884e04f",98:"e71dd57d",117:"b96ad197",129:"66f1a0f2",138:"675e6533",153:"9aaae761",158:"811bb36f",170:"dc30419f",205:"e4f96dcd",237:"da9a0891",258:"d9a03d3d",295:"1bac1858",304:"052e6f7b",395:"ae63e1f9",401:"b87ba7c0",416:"a3ad28f7",446:"d7af1da2",467:"fc49fa7b",485:"d742244a",567:"069dac02",638:"84bb69f7",647:"f92788a2",742:"cb1d9d7d",755:"6b43ed91",871:"afd496da",913:"3fa60236",957:"2356f0d5",976:"382c6edd",983:"b34d2ce3",995:"bedb7f84"}[e]+".js",b.miniCssF=e=>{},b.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),b.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),r={},o="tinyorm.org:",b.l=(e,a,t,n)=>{if(r[e])r[e].push(a);else{var f,d;if(void 0!==t)for(var c=document.getElementsByTagName("script"),i=0;i{f.onerror=f.onload=null,clearTimeout(s);var o=r[e];if(delete r[e],f.parentNode&&f.parentNode.removeChild(f),o&&o.forEach((e=>e(t))),a)return a(t)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:f}),12e4);f.onerror=l.bind(null,f.onerror),f.onload=l.bind(null,f.onload),d&&document.head.appendChild(f)}},b.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},b.p="/",b.gca=function(e){return e={17896441:"401",d459b1c4:"27",a94703ab:"48","5b254f70":"82",a7bd4aaa:"98","3dd307b5":"117","8a8faf8d":"129","1a4e3797":"138","1222ea4e":"153",ba3d4959:"170",b4f71b2f:"205",cb1e72f9:"258","21dc2778":"295","62a1276f":"304","0ab078a9":"395",e3ac21cb:"467","59b1a96c":"485","22dd74f7":"567","7333c691":"638","5e95c892":"647",aba21aa0:"742",a4d3e054:"755",fb313d4e:"871",c141421f:"957","6356d98b":"976",feaee7f3:"983",cbe663fe:"995"}[e]||e,b.p+b.u(e)},(()=>{var e={354:0,869:0};b.f.j=(a,t)=>{var r=b.o(e,a)?e[a]:void 0;if(0!==r)if(r)t.push(r[2]);else if(/^(354|869)$/.test(a))e[a]=0;else{var o=new Promise(((t,o)=>r=e[a]=[t,o]));t.push(r[2]=o);var n=b.p+b.u(a),f=new Error;b.l(n,(t=>{if(b.o(e,a)&&(0!==(r=e[a])&&(e[a]=void 0),r)){var o=t&&("load"===t.type?"missing":t.type),n=t&&t.target&&t.target.src;f.message="Loading chunk "+a+" failed.\n("+o+": "+n+")",f.name="ChunkLoadError",f.type=o,f.request=n,r[1](f)}}),"chunk-"+a,a)}},b.O.j=a=>0===e[a];var a=(a,t)=>{var r,o,n=t[0],f=t[1],d=t[2],c=0;if(n.some((a=>0!==e[a]))){for(r in f)b.o(f,r)&&(b.m[r]=f[r]);if(d)var i=d(b)}for(a&&a(t);cgtag("config","AW-989655383"),gtag("event","conversion",{send_to:"AW-989655383/vDYzCM--ks4DENfi89cD"}) - + @@ -123,7 +123,7 @@

.qmake.conf
# Path to the PARENT folder of the TinyORM source folder
TINY_MAIN_DIR = $$clean_path($$PWD/../../TinyORM/)
# To find .env and .env.$$QMAKE_PLATFORM files
TINY_DOTENV_ROOT = $$PWD
# Path to the current build tree (used to guess the TinyORM build tree)
#TINY_BUILD_TREE = $$shadowed($$PWD)

# To find .prf files, needed by eg. CONFIG += tiny_system_headers inline/extern_constants
QMAKEFEATURES *= $$quote($$TINY_MAIN_DIR/TinyORM/qmake/features)

Then, create a .env.(win32|unix|mingw) file in the HelloWorld project root folder with the following content.

-
# Names and values of these qmake variables are crucial, they are used in HelloWorld.pro
# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!

# Path to the TinyORM build folder
TINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_2_MSVC2022_64bit-Debug/)

# Path to the vcpkg - range-v3
# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty
TINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)
TINY_VCPKG_TRIPLET = x64-windows

# Enable ccache wrapper
#CONFIG *= ccache
+
# Names and values of these qmake variables are crucial, they are used in HelloWorld.pro
# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!

# Path to the TinyORM build folder
TINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_2_MSVC2022_64bit-Debug/)

# Path to the vcpkg - range-v3
# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty
TINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)
TINY_VCPKG_TRIPLET = x64-windows

# Enable ccache wrapper
#CONFIG *= ccache

Don't forget to update the TINYORM_BUILD_TREE and TINY_VCPKG_ROOT folder paths to your needs if you are not using the recommended Folders structure.

You can use the Partial guessing of the TINYORM_BUILD_TREE if you don't like to specify it manually. Just comment out the TINYORM_BUILD_TREE and uncomment the TINY_BUILD_TREE = $$shadowed($$PWD) in the .qmake.conf file.

tip

You can entirely avoid the .env files, just move the TINYORM_BUILD_TREE to the .qmake.conf or remove it by help of Partial guessing of the TINYORM_BUILD_TREE and set the VCPKG_ROOT environment variable at system level as is described in Set up vcpkg environment.

diff --git a/building/migrations.html b/building/migrations.html index b59f89bb5..2084c65a1 100644 --- a/building/migrations.html +++ b/building/migrations.html @@ -14,7 +14,7 @@ - + @@ -143,7 +143,7 @@

.qmake.conf
# Path to the PARENT folder of the TinyORM source folder
TINY_MAIN_DIR = $$clean_path($$PWD/../../TinyORM/)
# To find .env and .env.$$QMAKE_PLATFORM files
TINY_DOTENV_ROOT = $$PWD
# Path to the current build tree (used to guess the TinyORM build tree)
#TINY_BUILD_TREE = $$shadowed($$PWD)

# To find .prf files, needed by eg. CONFIG += tiny_system_headers inline/extern_constants
QMAKEFEATURES *= $$quote($$TINY_MAIN_DIR/TinyORM/qmake/features)

Then, create a .env.(win32|unix|mingw) file in the tom application root folder with the following content.

-
# Names and values of these qmake variables are crucial, they are used in the tom.pro
# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!

# Path to the TinyORM build folder
TINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_2_MSVC2022_64bit-Debug/)

# Path to the vcpkg - range-v3 and tabulate
# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty
TINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)
TINY_VCPKG_TRIPLET = x64-windows

# Enable ccache wrapper
#CONFIG *= ccache
+
# Names and values of these qmake variables are crucial, they are used in the tom.pro
# Please pay special attention to letter casing in paths, especially TinyOrm vs TinyORM!

# Path to the TinyORM build folder
TINYORM_BUILD_TREE = $$quote($$TINY_MAIN_DIR/TinyORM-builds-qmake/build-TinyORM-Desktop_Qt_6_7_2_MSVC2022_64bit-Debug/)

# Path to the vcpkg - range-v3 and tabulate
# Will use the TINY_VCPKG_ROOT or VCPKG_ROOT environment variable if is empty
TINY_VCPKG_ROOT = $$clean_path($$PWD/../../../vcpkg/)
TINY_VCPKG_TRIPLET = x64-windows

# Enable ccache wrapper
#CONFIG *= ccache

Don't forget to update the TINYORM_BUILD_TREE and TINY_VCPKG_ROOT folder paths to your needs if you are not using the recommended Folders structure.

You can use the Partial guessing of the TINYORM_BUILD_TREE if you don't like to specify it manually. Just comment out the TINYORM_BUILD_TREE and uncomment the TINY_BUILD_TREE = $$shadowed($$PWD) in the .qmake.conf file.

tip

You can entirely avoid the .env files, just move the TINYORM_BUILD_TREE to the .qmake.conf or remove it by help of Partial guessing of the TINYORM_BUILD_TREE and set the VCPKG_ROOT environment variable at system level as is described in Set up vcpkg environment.

diff --git a/building/tinyorm.html b/building/tinyorm.html index 983d7aa5d..7d0f51227 100644 --- a/building/tinyorm.html +++ b/building/tinyorm.html @@ -14,7 +14,7 @@ - + diff --git a/database/getting-started.html b/database/getting-started.html index 1e32437c0..6bb73f334 100644 --- a/database/getting-started.html +++ b/database/getting-started.html @@ -14,7 +14,7 @@ - + diff --git a/database/migrations.html b/database/migrations.html index dc5950a51..757b99e60 100644 --- a/database/migrations.html +++ b/database/migrations.html @@ -14,7 +14,7 @@ - + diff --git a/database/query-builder.html b/database/query-builder.html index 4e13f2f62..5426b78a1 100644 --- a/database/query-builder.html +++ b/database/query-builder.html @@ -14,7 +14,7 @@ - + diff --git a/database/seeding.html b/database/seeding.html index 3ccd920a6..a6b6cb485 100644 --- a/database/seeding.html +++ b/database/seeding.html @@ -14,7 +14,7 @@ - + diff --git a/dependencies.html b/dependencies.html index aaf181106..38042bc80 100644 --- a/dependencies.html +++ b/dependencies.html @@ -14,7 +14,7 @@ - + diff --git a/donations.html b/donations.html index 2cd21fdc2..50a549597 100644 --- a/donations.html +++ b/donations.html @@ -14,7 +14,7 @@ - + diff --git a/features-summary.html b/features-summary.html index 581d0129e..526f50fb6 100644 --- a/features-summary.html +++ b/features-summary.html @@ -14,7 +14,7 @@ - + diff --git a/index.html b/index.html index 3d2a5b513..b7443ddb1 100644 --- a/index.html +++ b/index.html @@ -14,7 +14,7 @@ - + diff --git a/search.html b/search.html index 4f4e41bfe..f396d97d8 100644 --- a/search.html +++ b/search.html @@ -14,7 +14,7 @@ - + diff --git a/stability.html b/stability.html index bba4ebb0b..57ce82250 100644 --- a/stability.html +++ b/stability.html @@ -14,7 +14,7 @@ - + diff --git a/supported-compilers.html b/supported-compilers.html index 2991159d4..df32609ff 100644 --- a/supported-compilers.html +++ b/supported-compilers.html @@ -14,7 +14,7 @@ - + diff --git a/tinydrivers/getting-started.html b/tinydrivers/getting-started.html index 67f5a1970..a714cd3cd 100644 --- a/tinydrivers/getting-started.html +++ b/tinydrivers/getting-started.html @@ -14,7 +14,7 @@ - + diff --git a/tinyorm/casts.html b/tinyorm/casts.html index 0004e46c0..6b43c4301 100644 --- a/tinyorm/casts.html +++ b/tinyorm/casts.html @@ -14,7 +14,7 @@ - + diff --git a/tinyorm/collections.html b/tinyorm/collections.html index 8e478a259..992c2f542 100644 --- a/tinyorm/collections.html +++ b/tinyorm/collections.html @@ -14,7 +14,7 @@ - + diff --git a/tinyorm/getting-started.html b/tinyorm/getting-started.html index 3c2de17b7..6759047da 100644 --- a/tinyorm/getting-started.html +++ b/tinyorm/getting-started.html @@ -14,7 +14,7 @@ - + diff --git a/tinyorm/relationships.html b/tinyorm/relationships.html index e2872ab0b..7c2d1e8b5 100644 --- a/tinyorm/relationships.html +++ b/tinyorm/relationships.html @@ -14,7 +14,7 @@ - + diff --git a/tinyorm/serialization.html b/tinyorm/serialization.html index 7a7d71137..7129ed39e 100644 --- a/tinyorm/serialization.html +++ b/tinyorm/serialization.html @@ -14,7 +14,7 @@ - +