diff --git a/404.html b/404.html index 7d2bab0fc..3a3187163 100644 --- a/404.html +++ b/404.html @@ -14,7 +14,7 @@ - +
diff --git a/assets/js/0ab078a9.eaba5272.js b/assets/js/0ab078a9.eaba5272.js deleted file mode 100644 index 6300a43aa..000000000 --- a/assets/js/0ab078a9.eaba5272.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunktinyorm_org=self.webpackChunktinyorm_org||[]).push([[395],{993:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>O,contentTitle:()=>_,default:()=>I,frontMatter:()=>T,metadata:()=>v,toc:()=>R});var s=i(4848),d=i(8453),r=i(8774),l=i(6684),c=i(2364),t=i(9365),o=i(1470),a=i(5556),h=i.n(a),x=i(6694);function j(e){let{groupId:n}=e;return(0,s.jsx)("span",{children:(0,x.OZ)(n)})}j.propTypes={groupId:h().string.isRequired};const u=j;var p=i(4164),m=i(6362);const b={rootFolderInput:"rootFolderInput_ottS",input:"input_OR7e",application:"application_fjej"};function f(e){let{groupId:n,label:i}=e;const{rootFolder:d,setRootFolder:r}=(0,m.A)(),l=(0,x.T3)(n),c=l?"application":"root",t=l?"\nThis folder name is common for all shells (eg. pwsh, bash, ...)":"";return(0,s.jsx)("form",{name:"tinyorm-root-folder-form",className:(0,p.A)(b.rootFolderInput,b[n],n),onSubmit:e=>{e.preventDefault(),e.stopPropagation()},children:(0,s.jsx)("input",{name:"tinyorm-root-folder-input",className:(0,p.A)(b.input,b[n],n),placeholder:`Enter ${c} folder...`,title:`This ${c} folder will be used in all ${i} examples at tinyorm.org${t}`,onChange:e=>{r(n,e.target.value)},value:d[n]??(0,x.bw)(n)})})}f.propTypes={groupId:h().string.isRequired,label:h().string.isRequired};const g=f;var y=i(7324);const T={sidebar_position:0,sidebar_label:"TinyORM",hide_table_of_contents:!0,description:"How to compile the TinyORM C++ library on Windows and Linux.",keywords:["c++ orm","building","tinyorm"]},_="Building: TinyORM",v={id:"building/tinyorm",title:"Building: TinyORM",description:"How to compile the TinyORM C++ library on Windows and Linux.",source:"@site/docs/building/tinyorm.mdx",sourceDirName:"building",slug:"/building/tinyorm",permalink:"/building/tinyorm",draft:!1,unlisted:!1,tags:[],version:"current",sidebarPosition:0,frontMatter:{sidebar_position:0,sidebar_label:"TinyORM",hide_table_of_contents:!0,description:"How to compile the TinyORM C++ library on Windows and Linux.",keywords:["c++ orm","building","tinyorm"]},sidebar:"tinyormSidebar",previous:{title:"Getting Started",permalink:"/tinydrivers/getting-started"},next:{title:"Hello world",permalink:"/building/hello-world"}},O={},R=[{value:"Introduction",id:"introduction",level:2},{value:"Common Prerequisites",id:"common-prerequisites",level:4},{value:"Windows Prerequisites",id:"windows-prerequisites",level:4},{value:"Build environment scripts",id:"build-environment-scripts",level:5},{value:"Allow symbolic links unprivileged",id:"allow-symbolic-links-unprivileged",level:5},{value:"Folders structure",id:"folders-structure",level:2},{value:"Getting started",id:"getting-started",level:2},{value:"vcpkg",id:"vcpkg",level:2},{value:"Set upvcpkg
environment",id:"set-up-vcpkg-environment",level:4},{value:"C preprocessor macros",id:"c-preprocessor-macros",level:2},{value:"Building with CMake",id:"building-with-cmake",level:2},{value:"Configure & Build (cmake)",id:"configure-and-build-cmake",level:3},{value:"CMake STRICT_MODE
option",id:"cmake-strict_mode-option",level:5},{value:"Build TinyORM",id:"build-tinyorm",level:4},{value:"CMake build options",id:"cmake-build-options",level:3},{value:"Consume TinyOrm library (cmake)",id:"consume-tinyorm-library-cmake",level:3},{value:"Building with qmake",id:"building-with-qmake",level:2},{value:"Install dependencies",id:"install-dependencies",level:3},{value:"Configure & Build (qmake)",id:"configure-and-build-qmake",level:3},{value:"Open QtCreator IDE",id:"open-qtcreator-ide",level:4},{value:"Configure TinyORM",id:"configure-tinyorm",level:4},{value:"Auto-configuration and tiny_dotenv",id:"auto-configuration-and-tiny_dotenv",level:5},{value:"Manual configuration (conf.pri)",id:"manual-configuration-confpri",level:5},{value:"Opening TinyORM.pro (main project file)",id:"opening-tinyormpro-main-project-file",level:5},{value:"Build TinyORM",id:"build-tinyorm-1",level:4},{value:"qmake build options",id:"qmake-build-options",level:3},{value:"Consume TinyOrm library (qmake)",id:"consume-tinyorm-library-qmake",level:3},{value:"Requirements",id:"requirements",level:4},{value:"QMAKEFEATURES
",id:"qmakefeatures",level:5},{value:"Variables affecting TinyOrm.pri
",id:"variables-affecting-tinyormpri",level:5},{value:"Manual configuration examples",id:"manual-configuration-examples",level:5},{value:"Auto-configuration internals",id:"auto-configuration-internals",level:3},{value:"Environment files",id:"environment-files",level:4},{value:"Partial guessing of the TINYORM_BUILD_TREE
",id:"partial-guessing-of-the-tinyorm_build_tree",level:4},{value:"Manual configuration internals",id:"manual-configuration-internals",level:3},{value:"Ccache support",id:"ccache-support",level:2}];function M(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"building-tinyorm",children:"Building: TinyORM"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#introduction",children:"Introduction"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#common-prerequisites",children:"Common Prerequisites"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#windows-prerequisites",children:"Windows Prerequisites"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#folders-structure",children:"Folders structure"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#getting-started",children:"Getting started"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#vcpkg",children:"vcpkg"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#c-preprocessor-macros",children:"C preprocessor macros"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#building-with-cmake",children:"Building with CMake"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#configure-and-build-cmake",children:"Configure & Build"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#cmake-build-options",children:"CMake build options"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#consume-tinyorm-library-cmake",children:"Consume TinyOrm library"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#building-with-qmake",children:"Building with qmake"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#install-dependencies",children:"Install dependencies"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#configure-and-build-qmake",children:"Configure & Build"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#qmake-build-options",children:"qmake build options"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#consume-tinyorm-library-qmake",children:"Consume TinyOrm library"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#auto-configuration-internals",children:"Auto-configuration internals"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#environment-files",children:"Environment files"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#manual-configuration-internals",children:"Manual configuration internals"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#ccache-support",children:"Ccache support"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsxs)(n.p,{children:["The build systems supported out of the box are ",(0,s.jsx)(n.code,{children:"CMake"})," and ",(0,s.jsx)(n.code,{children:"qmake"}),"."]}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["All examples below assume that ",(0,s.jsx)(n.code,{children:"pwsh"})," runs on ",(0,s.jsx)(n.code,{children:"Windows"})," and ",(0,s.jsx)(n.code,{children:"bash"})," runs on ",(0,s.jsx)(n.code,{children:"Linux"}),"."]})}),"\n",(0,s.jsx)(n.h4,{id:"common-prerequisites",children:"Common Prerequisites"}),"\n",(0,s.jsxs)(n.p,{children:["Install the required ",(0,s.jsx)(n.a,{href:"/dependencies",children:"dependencies"})," before starting."]}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"QSqlDatabase"})," depends on ",(0,s.jsx)(n.code,{children:"QCoreApplication"})," from ",(0,s.jsx)(n.code,{children:"Qt v6.5.3"})," so you must create the ",(0,s.jsx)(n.code,{children:"QCoreApplication"})," instance before you will call anything from the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library. \ud83e\udee4 The change was made ",(0,s.jsx)(n.a,{href:"https://github.com/qt/qtbase/commit/8d2bdc9cd5482eace12ba7e45304857bd24db0e6#diff-1d355c25c0b0eddec2be48253407780c4dc510d986739aec61e1ec892ccaf86e",children:"here"}),"."]})}),"\n",(0,s.jsx)(n.h4,{id:"windows-prerequisites",children:"Windows Prerequisites"}),"\n",(0,s.jsx)(n.h5,{id:"build-environment-scripts",children:"Build environment scripts"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"Visual Studio"})," does not provide ",(0,s.jsx)(n.code,{children:"vcvars"})," scripts for ",(0,s.jsx)(n.code,{children:"pwsh"}),", you can use ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/tree/main/tools/vcvars64.ps1",children:(0,s.jsx)(n.code,{children:"vcvars64.ps1"})})," provided by ",(0,s.jsx)(n.code,{children:"TinyORM"})," in the ",(0,s.jsx)(n.code,{children:"tools/"})," folder. Place them on the ",(0,s.jsx)(n.code,{children:"$env:Path"})," user/system path and they will be available system-wide."]}),"\n",(0,s.jsxs)(n.p,{children:["The same is true for the ",(0,s.jsx)(n.code,{children:"Qt Framework"}),", it doesn't provide ",(0,s.jsx)(n.code,{children:"qtenv"})," scripts for ",(0,s.jsx)(n.code,{children:"pwsh"})," too. You can create your own script, place it on the ",(0,s.jsx)(n.code,{children:"$env:Path"})," user/system path and it will be available system-wide."]}),"\n",(0,s.jsxs)(n.p,{children:["Here is one simple example for ",(0,s.jsx)(n.code,{children:"pwsh"}),"."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:"qtenv6.ps1",label:"qtenv6.ps1",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-powershell",children:"#!/usr/bin/env pwsh\n\nSet-StrictMode -Version 3.0\n\nWrite-Host 'Setting up environment for Qt 6.7.0 usage...' -ForegroundColor Magenta\nWrite-Host\n\n$Script:QtRoot = $env:TINY_QT_ROOT ?? 'C:\\Qt'\n\n$env:Path = \"$Script:QtRoot\\6.7.0\\msvc2019_64\\bin;\" + $env:Path\n\n. vcvars64.ps1\n"})})}),(0,s.jsx)(t.A,{value:"qtenv5.ps1",label:"qtenv5.ps1",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-powershell",children:"#!/usr/bin/env pwsh\n\nSet-StrictMode -Version 3.0\n\nWrite-Host 'Setting up environment for Qt 5.15.2 usage...' -ForegroundColor Magenta\nWrite-Host\n\n$Script:QtRoot = $env:TINY_QT_ROOT ?? 'C:\\Qt'\n\n$env:Path = \"$Script:QtRoot\\5.15.2\\msvc2019_64\\bin;\" + $env:Path\n\n. vcvars64.ps1\n"})})})]}),"\n",(0,s.jsxs)(n.p,{children:["And here for ",(0,s.jsx)(n.code,{children:"Linux"}),"."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:"qtenv6",label:"qtenv6",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'echo \'Setting up environment for Qt 6.7.0 usage...\'\n\nQtRoot="${TINY_QT_ROOT:-/opt/Qt}"\n\nexport PATH="$QtRoot/6.7.0/gcc_64/bin"${PATH:+:}$PATH\nexport LD_LIBRARY_PATH="$QtRoot/6.7.0/gcc_64/lib"${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH\n'})})}),(0,s.jsx)(t.A,{value:"qtenv5",label:"qtenv5",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'echo \'Setting up environment for Qt 5.15.2 usage...\'\n\nQtRoot="${TINY_QT_ROOT:-/opt/Qt}"\n\nexport PATH="$QtRoot/5.15.2/gcc_64/bin"${PATH:+:}$PATH\nexport LD_LIBRARY_PATH="$QtRoot/5.15.2/gcc_64/lib"${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH\n'})})})]}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["These scripts consider the ",(0,s.jsx)(n.code,{children:"TINY_QT_ROOT"})," environment variable that should point to the ",(0,s.jsx)(n.code,{children:"Qt"})," installation folder, you can define this environment variable globally in your OS."]})}),"\n",(0,s.jsx)(n.h5,{id:"allow-symbolic-links-unprivileged",children:"Allow symbolic links unprivileged"}),"\n",(0,s.jsxs)(n.p,{children:["Open ",(0,s.jsx)(n.code,{children:"Local Security Policy"}),", go to ",(0,s.jsx)(n.code,{children:"Local Policies - User Rights Assignment"}),", open ",(0,s.jsx)(n.code,{children:"Create symbolic links"})," and add your user account or user group, restart when it doesn't apply immediately."]}),"\n",(0,s.jsx)(n.h2,{id:"folders-structure",children:"Folders structure"}),"\n",(0,s.jsxs)(n.p,{children:["All ",(0,s.jsx)(n.code,{children:"tinyorm.org"})," examples are based on the following folders structure. The ",(0,s.jsx)(n.code,{children:"tom"})," folder will contain a ",(0,s.jsx)(n.a,{href:"/building/migrations",children:"migrations console application"}),"."]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can set the root and application folder paths in the form below and they will be used across the whole ",(0,s.jsx)(n.a,{href:"http://www.tinyorm.org",children:"www.tinyorm.org"})," website. \ud83e\udd73 The pwsh shell is supposed to use on Windows and the bash shell on Linux, but it is not a requirement."]})}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsxs)(t.A,{value:y.b,label:y.ux,className:"tiny-tree",children:[(0,s.jsx)("div",{className:"tiny-root-folder-info-wrapper",children:(0,s.jsxs)(n.p,{children:[(0,s.jsx)("span",{className:"tiny-root-folder-info-prefix",children:"Current pwsh path"}),"\xa0",(0,s.jsx)(u,{groupId:y.b})]})}),(0,s.jsx)(g,{groupId:y.b,label:y.ux}),(0,s.jsx)(g,{groupId:y.pW,label:y.kl}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-text",children:"\n\n\n\u251c\u2500\u2500\n\u2502 \u251c\u2500\u2500 HelloWorld/\n\u2502 | \u251c\u2500\u2500 HelloWorld/\n\u2502 | \u251c\u2500\u2500 HelloWorld-builds-cmake/\n\u2502 | | \u2514\u2500\u2500 build-debug/\n\u2502 | \u2514\u2500\u2500 HelloWorld-builds-qmake/\n\u2502 | \u2514\u2500\u2500 build-debug/\n\u2502 \u251c\u2500\u2500 TinyORM/\n\u2502 | \u251c\u2500\u2500 TinyORM/\n\u2502 | \u251c\u2500\u2500 TinyORM-builds-cmake/\n\u2502 | \u2502 \u251c\u2500\u2500 build-gcc-debug/\n\u2502 | \u2502 \u251c\u2500\u2500 build-gcc-release/\n\u2502 | \u2502 \u2514\u2500\u2500 build-clang-debug/\n\u2502 | \u2514\u2500\u2500 TinyORM-builds-qmake/\n\u2502 | \u251c\u2500\u2500 build-debug/\n\u2502 | \u251c\u2500\u2500 build-TinyORM-Desktop_Qt_5_15_2_MSVC2019_64bit-Debug/\n\u2502 | \u2514\u2500\u2500 build-TinyORM-Desktop_Qt_5_15_2_MSYS2_UCRT64_64bit-Release/\n\u2502 \u2514\u2500\u2500 tom/\n\u2502 \u251c\u2500\u2500 tom/\n\u2502 \u2502 \u2514\u2500\u2500 database/\n\u2502 \u2502 \u251c\u2500\u2500 migrations/\n\u2502 \u2502 \u251c\u2500\u2500 seeders/\n\u2502 \u2502 \u251c\u2500\u2500 migrations.pri\n\u2502 \u2502 \u2514\u2500\u2500 seeders.pri\n\u2502 \u251c\u2500\u2500 tom-builds-cmake/\n\u2502 \u2502 \u2514\u2500\u2500 build-TinyORM-Desktop_Qt_6_7_0_MSVC2019_64bit-Debug/\n\u2502 \u2514\u2500\u2500 tom-builds-qmake/\n\u2502 \u251c\u2500\u2500 build-TinyORM-Desktop_Qt_5_15_3_MSYS2_UCRT64_64bit-Release/\n\u2502 \u2514\u2500\u2500 build-TinyORM-Desktop_Qt_6_7_0_MSVC2019_64bit-Debug/\n\u251c\u2500\u2500 tmp/\n\u2514\u2500\u2500 vcpkg/\n"})})]}),(0,s.jsxs)(t.A,{value:y.xj,label:y.gg,className:"tiny-tree",children:[(0,s.jsx)("div",{className:"tiny-root-folder-info-wrapper",children:(0,s.jsxs)(n.p,{children:[(0,s.jsx)("span",{className:"tiny-root-folder-info-prefix",children:"Current bash path"}),"\xa0",(0,s.jsx)(u,{groupId:y.xj})]})}),(0,s.jsx)(g,{groupId:y.xj,label:y.gg}),(0,s.jsx)(g,{groupId:y.pW,label:y.pW}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-text",children:"\n\n\n\u251c\u2500\u2500\n\u2502 \u251c\u2500\u2500 HelloWorld/\n\u2502 | \u251c\u2500\u2500 HelloWorld/\n\u2502 | \u251c\u2500\u2500 HelloWorld-builds-cmake/\n\u2502 | | \u2514\u2500\u2500 build-debug/\n\u2502 | \u2514\u2500\u2500 HelloWorld-builds-qmake/\n\u2502 | \u2514\u2500\u2500 build-debug/\n\u2502 \u251c\u2500\u2500 TinyORM/\n\u2502 | \u251c\u2500\u2500 TinyORM/\n\u2502 | \u251c\u2500\u2500 TinyORM-builds-cmake/\n\u2502 | \u2502 \u251c\u2500\u2500 build-gcc-debug/\n\u2502 | \u2502 \u251c\u2500\u2500 build-gcc-release/\n\u2502 | \u2502 \u2514\u2500\u2500 build-clang-debug/\n\u2502 | \u2514\u2500\u2500 TinyORM-builds-qmake/\n\u2502 | \u251c\u2500\u2500 build-debug/\n\u2502 | \u251c\u2500\u2500 build-TinyORM-Desktop_Qt_5_15_2_GCC_64bit-Debug/\n\u2502 | \u2514\u2500\u2500 build-TinyORM-Desktop_Qt_5_15_2_clang13_64bit_ccache-Release/\n\u2502 \u2514\u2500\u2500 tom/\n\u2502 \u251c\u2500\u2500 tom/\n\u2502 \u2502 \u2514\u2500\u2500 database/\n\u2502 \u2502 \u251c\u2500\u2500 migrations/\n\u2502 \u2502 \u251c\u2500\u2500 seeders/\n\u2502 \u2502 \u251c\u2500\u2500 migrations.pri\n\u2502 \u2502 \u2514\u2500\u2500 seeders.pri\n\u2502 \u251c\u2500\u2500 tom-builds-cmake/\n\u2502 \u2502 \u2514\u2500\u2500 build-TinyORM-Desktop_Qt_6_7_0_clang14_64bit_ccache-Debug/\n\u2502 \u2514\u2500\u2500 tom-builds-qmake/\n\u2502 \u251c\u2500\u2500 build-TinyORM-Desktop_Qt_6_7_0_GCC_64bit-Debug/\n\u2502 \u2514\u2500\u2500 build-TinyORM-Desktop_Qt_6_7_0_clang14_64bit_ccache-Release/\n\u251c\u2500\u2500 tmp/\n\u2514\u2500\u2500 vcpkg/\n"})})]})]}),"\n",(0,s.jsx)(n.admonition,{type:"danger",children:(0,s.jsxs)(n.p,{children:["Avoid paths with spaces with the ",(0,s.jsx)(n.code,{children:"qmake"})," build system, it will not compile."]})}),"\n",(0,s.jsx)(r.A,{id:"qtcreator-default-build-directory"}),"\n",(0,s.jsxs)(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 above."]}),(0,s.jsxs)(n.p,{children:["To generate the required folders structure set the ",(0,s.jsx)(n.code,{children:"Settings"})," - ",(0,s.jsx)(n.code,{children:"Build & Run"})," - ",(0,s.jsx)(n.code,{children:"Default Build Properties"})," - ",(0,s.jsx)(n.code,{children:"Default build directory"})," to:",(0,s.jsx)("br",{}),"\n",(0,s.jsx)(n.code,{children:'../%{Project:Name}-builds-%{BuildSystem:Name}/%{JS: Util.asciify("build-%{Project:Name}-%{Kit:FileSystemName}-%{BuildConfig:Name}")}'})]})]}),"\n",(0,s.jsx)(n.h2,{id:"getting-started",children:"Getting started"}),"\n",(0,s.jsxs)(n.p,{children:["Prepare compilation environment, we need to put the Qt Framework and Visual Studio MSVC compiler on the path on Windows. The compiler is already on the path on Linux and you can export ",(0,s.jsx)(n.code,{children:"PATH"})," and ",(0,s.jsx)(n.code,{children:"LD_LIBRARY_PATH"})," for Qt Framework, or use our ",(0,s.jsx)(n.code,{children:"qtenvX"})," scripts described above."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`mkdir ${(0,x.Sn)(y.b)}\ncd ${(0,x.Sn)(y.b)}\n$env:Path = 'C:\\Qt\\6.7.0\\msvc2019_64\\bin;' + $env:Path\nvcvars64.ps1`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`mkdir -p ${(0,x.Sn)(y.xj)}\ncd ${(0,x.Sn)(y.xj)}\nexport PATH=/opt/Qt/6.7.0/gcc_64/bin\${PATH:+:}$PATH\nexport LD_LIBRARY_PATH=/opt/Qt/6.7.0/gcc_64/lib\${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH`})})]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can also use the ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/tools/Add-FolderOnPath.ps1",children:(0,s.jsx)(n.code,{children:"tools/Add-FolderOnPath.ps1"})})," pwsh script to fastly prepend a path or ",(0,s.jsx)("abbr",{title:"Current working directory",children:"pwd"})," on the system ",(0,s.jsx)(n.code,{children:"PATH"}),"."]})}),"\n",(0,s.jsx)(n.h2,{id:"vcpkg",children:"vcpkg"}),"\n",(0,s.jsxs)(n.p,{children:["Installing the ",(0,s.jsx)(n.code,{children:"vcpkg"})," is highly recommended, it simplifies installation of the ",(0,s.jsx)(n.code,{children:"range-v3"})," and ",(0,s.jsx)(n.code,{children:"tabulate"})," dependencies."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-powershell",children:"git clone git@github.com:microsoft/vcpkg.git\ncd vcpkg\n.\\bootstrap-vcpkg.bat\n"})})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone git@github.com:microsoft/vcpkg.git\ncd vcpkg\n./bootstrap-vcpkg.sh\n"})})})]}),"\n",(0,s.jsxs)(n.p,{children:["Add ",(0,s.jsx)(n.code,{children:"vcpkg"})," on the system path, add the following to the ",(0,s.jsx)(n.code,{children:".bashrc"})," or ",(0,s.jsx)(n.code,{children:".zshrc"})," on Linux."]}),"\n",(0,s.jsx)(c.A,{className:"language-bash",children:`export PATH=${(0,x.Sn)(y.xj)}/vcpkg\${PATH:+:}$PATH`}),"\n",(0,s.jsxs)(n.p,{children:["On Windows, open the ",(0,s.jsx)(n.code,{children:"Environment variables"})," dialog and add ",(0,s.jsx)(n.code,{children:"vcpkg"})," on the user ",(0,s.jsx)(n.code,{children:"PATH"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Or you can export it for the current session only."}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`$env:Path = "${(0,x.Sn)(y.b,!1)}\\vcpkg;" + $env:Path`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`export PATH=${(0,x.Sn)(y.xj)}/vcpkg\${PATH:+:}$PATH`})})]}),"\n",(0,s.jsxs)(n.h4,{id:"set-up-vcpkg-environment",children:["Set up ",(0,s.jsx)(n.code,{children:"vcpkg"})," environment"]}),"\n",(0,s.jsxs)(n.p,{children:["To export ",(0,s.jsx)(n.code,{children:"vcpkg"})," environment variables globally, add it to the ",(0,s.jsx)(n.code,{children:".bashrc"})," or ",(0,s.jsx)(n.code,{children:".zshrc"})," on Linux, and you can use the ",(0,s.jsx)(n.code,{children:"Environment variables"})," dialog on Windows."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:"title='Linux'",children:'export VCPKG_DEFAULT_TRIPLET=x64-linux\n#export VCPKG_DEFAULT_HOST_TRIPLET=x64-linux\nexport VCPKG_MAX_CONCURRENCY=11\nexport VCPKG_OVERLAY_PORTS="$HOME/.local/share/vcpkg/ports"\nexport VCPKG_OVERLAY_TRIPLETS="$HOME/.local/share/vcpkg/triplets"\nexport VCPKG_ROOT="$HOME/Code/c/vcpkg"\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["It is recommended to define these variables globally because the ",(0,s.jsx)(n.code,{children:"CMake"})," and ",(0,s.jsx)(n.code,{children:"qmake"})," build system are able to detect the ",(0,s.jsx)(n.code,{children:"vcpkg"})," installation from them so you don't have to configure them manually to detect the ",(0,s.jsx)(n.code,{children:"vcpkg"})," installation."]})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["On Windows, it's always better to create these types of variables as user variables instead of system variables in the ",(0,s.jsx)(n.code,{children:"Environment variables"})," dialog."]})}),"\n",(0,s.jsx)(n.h2,{id:"c-preprocessor-macros",children:"C preprocessor macros"}),"\n",(0,s.jsxs)(n.p,{children:["The following table summarizes all the C preprocessor macros defined in the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library. These C macros are configured by ",(0,s.jsx)(n.code,{children:"CMake"})," or ",(0,s.jsx)(n.code,{children:"qmake"})," build systems. They are not sorted alphabetically, but they are sorted by how significant they are."]}),"\n",(0,s.jsxs)(n.p,{children:["In the ",(0,s.jsx)(n.code,{children:"CMake"})," build system, all the C macros are auto-detected / auto-configured or controlled by ",(0,s.jsx)(n.a,{href:"#cmake-build-options",children:(0,s.jsx)(n.code,{children:"CMake build options"})}),", so you don't have to care too much about them."]}),"\n",(0,s.jsxs)(n.p,{children:["In the ",(0,s.jsx)(n.code,{children:"qmake"})," build is important whether you are building ",(0,s.jsx)(n.code,{children:"TinyORM"})," library or you are building your application and linking against ",(0,s.jsx)(n.code,{children:"TinyORM"})," library. When you are building the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library, all the C macros are auto-detected / auto-configured or controlled by ",(0,s.jsx)(n.a,{href:"#qmake-build-options",children:(0,s.jsx)(n.code,{children:"qmake build options"})}),", so you don't have to care too much about them."]}),"\n",(0,s.jsxs)(n.p,{children:["But a special situation is when you are building your application / library and you are linking against ",(0,s.jsx)(n.code,{children:"TinyORM"})," library. In this particular case, you must configure all these C macros manually! For this reason, the ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/qmake/TinyOrm.pri",children:(0,s.jsx)(n.code,{children:"TinyOrm.pri"})})," has been created, so that's not a big deal either. Little more info ",(0,s.jsx)(n.a,{href:"#consume-tinyorm-library-qmake",children:"here"}),"."]}),"\n",(0,s.jsx)("div",{id:"apitable-c-macros",children:(0,s.jsx)(l.A,{children:(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"C Macro Name"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_LINKING_SHARED"})}),(0,s.jsxs)(n.td,{children:[(0,s.jsx)("u",{children:(0,s.jsx)(n.strong,{children:"Must"})})," be defined when you are linking against ",(0,s.jsx)(n.code,{children:"TinyORM"})," shared build (",(0,s.jsx)(n.code,{children:"dll"})," library), exported classes and functions will be tagged with ",(0,s.jsx)(n.code,{children:"__declspec(dllimport)"})," on ",(0,s.jsx)(n.code,{children:"msvc"})," and ",(0,s.jsx)(n.code,{children:'visibility("default")'})," on ",(0,s.jsx)(n.code,{children:"GCC >= 4"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_BUILDING_SHARED"})}),(0,s.jsxs)(n.td,{children:["Defined when ",(0,s.jsx)(n.code,{children:"TinyORM"})," is built as a ",(0,s.jsx)(n.code,{children:"dll"})," library (shared build)."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_DEBUG"})}),(0,s.jsx)(n.td,{children:"Defined in the debug build."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_NO_DEBUG"})}),(0,s.jsx)(n.td,{children:"Defined in the release build."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_DEBUG_SQL"})}),(0,s.jsx)(n.td,{children:"Defined in the debug build."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_NO_DEBUG_SQL"})}),(0,s.jsx)(n.td,{children:"Defined in the release build."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_MYSQL_PING"})}),(0,s.jsxs)(n.td,{children:["Enable ",(0,s.jsx)(n.code,{children:"Orm::MySqlConnection::pingDatabase()"})," method.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined when ",(0,s.jsx)(n.a,{href:"#mysql_ping",children:(0,s.jsx)(n.code,{children:"mysql_ping"})})," ",(0,s.jsx)("small",{children:"(qmake)"})," / ",(0,s.jsx)(n.a,{href:"#MYSQL_PING",children:(0,s.jsx)(n.code,{children:"MYSQL_PING"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration ",(0,s.jsx)(n.code,{children:"build option"})," is enabled."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_DISABLE_ORM"})}),(0,s.jsxs)(n.td,{children:["Controls the compilation of all ",(0,s.jsx)(n.code,{children:"ORM-related"})," source code, when this macro is ",(0,s.jsx)(n.code,{children:"defined"}),", then only the ",(0,s.jsx)(n.code,{children:"query builder"})," without ",(0,s.jsx)(n.code,{children:"ORM"})," is compiled. Also excludes ",(0,s.jsx)(n.code,{children:"ORM-related"})," unit tests.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined when ",(0,s.jsx)(n.a,{href:"#disable_orm",children:(0,s.jsx)(n.code,{children:"disable_orm"})})," ",(0,s.jsx)("small",{children:"(qmake)"})," / ",(0,s.jsx)(n.a,{href:"#ORM",children:(0,s.jsx)(n.code,{children:"ORM"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration ",(0,s.jsx)(n.code,{children:"build option"})," is enabled ",(0,s.jsx)("small",{children:"(qmake)"})," / disabled ",(0,s.jsx)("small",{children:"(cmake)"}),"."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_EXTERN_CONSTANTS"})}),(0,s.jsxs)(n.td,{children:["Defined when extern constants are used. Extern constants are enabled by default for shared builds and disabled for static builds.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Described at ",(0,s.jsx)(n.a,{href:"#extern_constants",children:(0,s.jsx)(n.code,{children:"qmake"})})," / ",(0,s.jsx)(n.a,{href:"#INLINE_CONSTANTS",children:(0,s.jsx)(n.code,{children:"CMake"})})," how it works."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_INLINE_CONSTANTS"})}),(0,s.jsxs)(n.td,{children:["Defined when global inline constants are used.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined when ",(0,s.jsx)(n.a,{href:"#inline_constants",children:(0,s.jsx)(n.code,{children:"inline_constants"})})," ",(0,s.jsx)("small",{children:"(qmake)"})," / ",(0,s.jsx)(n.a,{href:"#INLINE_CONSTANTS",children:(0,s.jsx)(n.code,{children:"INLINE_CONSTANTS"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration ",(0,s.jsx)(n.code,{children:"build option"})," is enabled."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_TESTS_CODE"})}),(0,s.jsxs)(n.td,{children:["Enable code needed by unit tests, eg. connection overriding in the ",(0,s.jsx)(n.code,{children:"Orm::Tiny::Model"}),".",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined when ",(0,s.jsx)(n.a,{href:"#build_tests",children:(0,s.jsx)(n.code,{children:"build_tests"})})," ",(0,s.jsx)("small",{children:"(qmake)"})," / ",(0,s.jsx)(n.a,{href:"#BUILD_TESTS",children:(0,s.jsx)(n.code,{children:"BUILD_TESTS"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration ",(0,s.jsx)(n.code,{children:"build option"})," is enabled."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_DISABLE_THREAD_LOCAL"})}),(0,s.jsxs)(n.td,{children:["Remove all ",(0,s.jsx)(n.a,{href:"https://en.cppreference.com/w/c/language/storage_duration",children:(0,s.jsx)(n.code,{children:"thread_local"})})," storage duration specifiers, it disables multi-threading support.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined when ",(0,s.jsx)(n.a,{href:"#disable_thread_local",children:(0,s.jsx)(n.code,{children:"disable_thread_local"})})," ",(0,s.jsx)("small",{children:"(qmake)"})," / ",(0,s.jsx)(n.a,{href:"#DISABLE_THREAD_LOCAL",children:(0,s.jsx)(n.code,{children:"DISABLE_THREAD_LOCAL"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration ",(0,s.jsx)(n.code,{children:"build option"})," is enabled."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYTOM_MIGRATIONS_DIR"})}),(0,s.jsxs)(n.td,{children:["Default migrations path for the ",(0,s.jsx)(n.code,{children:"make:migration"})," command, can be an absolute or relative path (to the ",(0,s.jsx)("abbr",{title:"Current working directory",children:"pwd"}),").",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Default value: ",(0,s.jsx)(n.code,{children:"database/migrations"})," ",(0,s.jsx)("small",{children:"(relative to the pwd)"})]}),(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined by ",(0,s.jsx)(n.a,{href:"#TOM_MIGRATIONS_DIR",children:(0,s.jsx)(n.code,{children:"TOM_MIGRATIONS_DIR"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration build option.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["(qmake note) You can use ",(0,s.jsx)(n.code,{children:'DEFINES += TINYTOM_MIGRATIONS_DIR="\\"database/migrations\\""'})," on the command-line or set it in the ",(0,s.jsx)(n.strong,{children:"main"})," ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/conf.pri.example#L65-L70",children:(0,s.jsx)(n.code,{children:"conf.pri"})})," file."]})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYTOM_MODELS_DIR"})}),(0,s.jsxs)(n.td,{children:["Default models path for the ",(0,s.jsx)(n.code,{children:"make:model"})," command, can be an absolute or relative path (to the ",(0,s.jsx)("abbr",{title:"Current working directory",children:"pwd"}),").",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Default value: ",(0,s.jsx)(n.code,{children:"database/models"})," ",(0,s.jsx)("small",{children:"(relative to the pwd)"})]}),(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined by ",(0,s.jsx)(n.a,{href:"#TOM_MODELS_DIR",children:(0,s.jsx)(n.code,{children:"TOM_MODELS_DIR"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration build option.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["(qmake note) You can use ",(0,s.jsx)(n.code,{children:'DEFINES += TINYTOM_MODELS_DIR="\\"database/models\\""'})," on the command-line or set it in the ",(0,s.jsx)(n.strong,{children:"main"})," ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/conf.pri.example#L72-L73",children:(0,s.jsx)(n.code,{children:"conf.pri"})})," file."]})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYTOM_SEEDERS_DIR"})}),(0,s.jsxs)(n.td,{children:["Default seeders path for the ",(0,s.jsx)(n.code,{children:"make:seeder"})," command, can be an absolute or relative path (to the ",(0,s.jsx)("abbr",{title:"Current working directory",children:"pwd"}),").",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Default value: ",(0,s.jsx)(n.code,{children:"database/seeders"})," ",(0,s.jsx)("small",{children:"(relative to the pwd)"})]}),(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined by ",(0,s.jsx)(n.a,{href:"#TOM_SEEDERS_DIR",children:(0,s.jsx)(n.code,{children:"TOM_SEEDERS_DIR"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration build option.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["(qmake note) You can use ",(0,s.jsx)(n.code,{children:'DEFINES += TINYTOM_SEEDERS_DIR="\\"database/seeders\\""'})," on the command-line or set it in the ",(0,s.jsx)(n.strong,{children:"main"})," ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/conf.pri.example#L75-L76",children:(0,s.jsx)(n.code,{children:"conf.pri"})})," file."]})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_USING_PCH"})}),(0,s.jsxs)(n.td,{children:["Defined if building with precompiled headers.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Controlled by ",(0,s.jsx)(n.a,{href:"#precompile_header",children:(0,s.jsx)(n.code,{children:"qmake"})})," / ",(0,s.jsx)(n.a,{href:"#CMAKE_DISABLE_PRECOMPILE_HEADERS",children:(0,s.jsx)(n.code,{children:"CMake"})}),"."]})]})]})]})]})})}),"\n",(0,s.jsx)(n.h2,{id:"building-with-cmake",children:"Building with CMake"}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["If something is not clear, you can still look at GitHub Action ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/tree/main/.github/workflows",children:(0,s.jsx)(n.code,{children:"workflows"})})," how a building is done."]})}),"\n",(0,s.jsxs)(n.p,{children:["First, create a basic folder structure and then clone the ",(0,s.jsx)(n.code,{children:"TinyORM"})," project."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`cd ${(0,x.Sn)(y.b)}\nmkdir ${(0,x.np)()}/TinyORM/TinyORM-builds-cmake/build-debug\n\ncd ${(0,x.np)()}/TinyORM\ngit clone git@github.com:silverqx/TinyORM.git`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`cd ${(0,x.Sn)(y.xj)}\nmkdir -p ${(0,x.np)()}/TinyORM/TinyORM-builds-cmake/build-debug\n\ncd ${(0,x.np)()}/TinyORM\ngit clone git@github.com:silverqx/TinyORM.git`})})]}),"\n",(0,s.jsxs)(n.h3,{id:"configure-and-build-cmake",children:["Configure & Build ",(0,s.jsx)("small",{children:"(cmake)"})]}),"\n",(0,s.jsxs)(n.p,{children:["Now you are ready to configure the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd TinyORM-builds-cmake/build-debug\n"})}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`cmake.exe \`\n-S "${(0,x.OZ)(y.b)}/TinyORM/TinyORM" \`\n-B "${(0,x.OZ)(y.b)}/TinyORM/TinyORM-builds-cmake/build-debug" \`\n-G 'Ninja' \`\n-D CMAKE_BUILD_TYPE:STRING='Debug' \`\n-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${(0,x.Sn)(y.b)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \`\n-D CMAKE_CXX_SCAN_FOR_MODULES:BOOL=OFF \`\n-D CMAKE_INSTALL_PREFIX:PATH="${(0,x.Sn)(y.b)}/tmp/TinyORM" \`\n-D BUILD_TESTS:BOOL=OFF \`\n-D MATCH_EQUAL_EXPORTED_BUILDTREE:BOOL=ON \`\n-D MYSQL_PING:BOOL=OFF \`\n-D TOM:BOOL=ON \`\n-D TOM_EXAMPLE:BOOL=OFF \`\n-D VERBOSE_CONFIGURE:BOOL=ON`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`cmake \\\n-S "${(0,x.OZ)(y.xj)}/TinyORM/TinyORM" \\\n-B "${(0,x.OZ)(y.xj)}/TinyORM/TinyORM-builds-cmake/build-debug" \\\n-G 'Ninja' \\\n-D CMAKE_BUILD_TYPE:STRING='Debug' \\\n-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${(0,x.Sn)(y.xj)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \\\n-D CMAKE_CXX_SCAN_FOR_MODULES:BOOL=OFF \\\n-D CMAKE_INSTALL_PREFIX:PATH="${(0,x.Sn)(y.xj)}/tmp/TinyORM" \\\n-D VERBOSE_CONFIGURE:BOOL=ON \\\n-D BUILD_TESTS:BOOL=OFF \\\n-D MYSQL_PING:BOOL=OFF \\\n-D TOM:BOOL=ON \\\n-D TOM_EXAMPLE:BOOL=OFF \\\n-D MATCH_EQUAL_EXPORTED_BUILDTREE:BOOL=ON`})})]}),"\n",(0,s.jsxs)(n.h5,{id:"cmake-strict_mode-option",children:["CMake ",(0,s.jsx)(n.code,{children:"STRICT_MODE"})," option"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"STRICT_MODE"})," ",(0,s.jsx)(n.code,{children:"CMake"})," configuration option was added in ",(0,s.jsx)(n.code,{children:"TinyORM"})," ",(0,s.jsx)(n.code,{children:"v0.37.3"}),". This option was added to avoid the propagation of aggressive strict warning compiler/linker options and Qt definitions from the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library to user code through the ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/cmake/CommonModules/TinyCommon.cmake",children:(0,s.jsx)(n.code,{children:"TinyOrm::CommonConfig"})})," interface library."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"TinyORM"})," uses the strictest warning level options, virtually anything that can be enabled is enabled to produce a better code. I highly recommend enabling this option to produce better code and to follow good practices. It also helps to follow the ",(0,s.jsx)(n.code,{children:"ISOCPP"})," ",(0,s.jsx)(n.a,{href:"https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines",children:"C++ Core Guidelines"})," standards."]}),"\n",(0,s.jsxs)(n.p,{children:["If you want to enable these strict warning options in your code, you can enable the ",(0,s.jsx)(n.code,{children:"STRICT_MODE"})," ",(0,s.jsx)(n.code,{children:"CMake"})," configuration option and they will be propagated to your code. You can also enabled it globally using the ",(0,s.jsx)(n.code,{children:"TINYORM_STRICT_MODE"})," environment variable, and the value of this environment variable will be picked up during initial CMake configuration as the default value for the ",(0,s.jsx)(n.code,{children:"STRICT_MODE"})," ",(0,s.jsx)(n.code,{children:"CMake"})," configuration option."]}),"\n",(0,s.jsxs)(n.p,{children:["You can achieve the same result by manually linking against the ",(0,s.jsx)(n.code,{children:"TinyOrm::CommonConfig"})," interface library when the ",(0,s.jsx)(n.code,{children:"STRICT_MODE"})," is set to ",(0,s.jsx)(n.code,{children:"OFF"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-cmake",children:"target_link_libraries(vcpkg
environment",id:"set-up-vcpkg-environment",level:4},{value:"C preprocessor macros",id:"c-preprocessor-macros",level:2},{value:"Building with CMake",id:"building-with-cmake",level:2},{value:"Configure & Build (cmake)",id:"configure-and-build-cmake",level:3},{value:"CMake STRICT_MODE
option",id:"cmake-strict_mode-option",level:5},{value:"Build TinyORM",id:"build-tinyorm",level:4},{value:"CMake build options",id:"cmake-build-options",level:3},{value:"Consume TinyOrm library (cmake)",id:"consume-tinyorm-library-cmake",level:3},{value:"Building with qmake",id:"building-with-qmake",level:2},{value:"Install dependencies",id:"install-dependencies",level:3},{value:"Configure & Build (qmake)",id:"configure-and-build-qmake",level:3},{value:"Open QtCreator IDE",id:"open-qtcreator-ide",level:4},{value:"Configure TinyORM",id:"configure-tinyorm",level:4},{value:"Auto-configuration and tiny_dotenv",id:"auto-configuration-and-tiny_dotenv",level:5},{value:"Manual configuration (conf.pri)",id:"manual-configuration-confpri",level:5},{value:"Opening TinyORM.pro (main project file)",id:"opening-tinyormpro-main-project-file",level:5},{value:"Build TinyORM",id:"build-tinyorm-1",level:4},{value:"qmake build options",id:"qmake-build-options",level:3},{value:"Consume TinyOrm library (qmake)",id:"consume-tinyorm-library-qmake",level:3},{value:"Requirements",id:"requirements",level:4},{value:"QMAKEFEATURES
",id:"qmakefeatures",level:5},{value:"Variables affecting TinyOrm.pri
",id:"variables-affecting-tinyormpri",level:5},{value:"Manual configuration examples",id:"manual-configuration-examples",level:5},{value:"Auto-configuration internals",id:"auto-configuration-internals",level:3},{value:"Environment files",id:"environment-files",level:4},{value:"Partial guessing of the TINYORM_BUILD_TREE
",id:"partial-guessing-of-the-tinyorm_build_tree",level:4},{value:"Manual configuration internals",id:"manual-configuration-internals",level:3},{value:"Ccache support",id:"ccache-support",level:2}];function M(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"building-tinyorm",children:"Building: TinyORM"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#introduction",children:"Introduction"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#common-prerequisites",children:"Common Prerequisites"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#windows-prerequisites",children:"Windows Prerequisites"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#folders-structure",children:"Folders structure"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#getting-started",children:"Getting started"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#vcpkg",children:"vcpkg"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#c-preprocessor-macros",children:"C preprocessor macros"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#building-with-cmake",children:"Building with CMake"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#configure-and-build-cmake",children:"Configure & Build"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#cmake-build-options",children:"CMake build options"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#consume-tinyorm-library-cmake",children:"Consume TinyOrm library"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#building-with-qmake",children:"Building with qmake"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#install-dependencies",children:"Install dependencies"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#configure-and-build-qmake",children:"Configure & Build"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#qmake-build-options",children:"qmake build options"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#consume-tinyorm-library-qmake",children:"Consume TinyOrm library"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#auto-configuration-internals",children:"Auto-configuration internals"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#environment-files",children:"Environment files"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#manual-configuration-internals",children:"Manual configuration internals"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#ccache-support",children:"Ccache support"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsxs)(n.p,{children:["The build systems supported out of the box are ",(0,s.jsx)(n.code,{children:"CMake"})," and ",(0,s.jsx)(n.code,{children:"qmake"}),"."]}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["All examples below assume that ",(0,s.jsx)(n.code,{children:"pwsh"})," runs on ",(0,s.jsx)(n.code,{children:"Windows"})," and ",(0,s.jsx)(n.code,{children:"bash"})," runs on ",(0,s.jsx)(n.code,{children:"Linux"}),"."]})}),"\n",(0,s.jsx)(n.h4,{id:"common-prerequisites",children:"Common Prerequisites"}),"\n",(0,s.jsxs)(n.p,{children:["Install the required ",(0,s.jsx)(n.a,{href:"/dependencies",children:"dependencies"})," before starting."]}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"QSqlDatabase"})," depends on ",(0,s.jsx)(n.code,{children:"QCoreApplication"})," from ",(0,s.jsx)(n.code,{children:"Qt v6.5.3"})," so you must create the ",(0,s.jsx)(n.code,{children:"QCoreApplication"})," instance before you will call anything from the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library. \ud83e\udee4 The change was made ",(0,s.jsx)(n.a,{href:"https://github.com/qt/qtbase/commit/8d2bdc9cd5482eace12ba7e45304857bd24db0e6#diff-1d355c25c0b0eddec2be48253407780c4dc510d986739aec61e1ec892ccaf86e",children:"here"}),"."]})}),"\n",(0,s.jsx)(n.h4,{id:"windows-prerequisites",children:"Windows Prerequisites"}),"\n",(0,s.jsx)(n.h5,{id:"build-environment-scripts",children:"Build environment scripts"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"Visual Studio"})," does not provide ",(0,s.jsx)(n.code,{children:"vcvars"})," scripts for ",(0,s.jsx)(n.code,{children:"pwsh"}),", you can use ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/tree/main/tools/vcvars64.ps1",children:(0,s.jsx)(n.code,{children:"vcvars64.ps1"})})," provided by ",(0,s.jsx)(n.code,{children:"TinyORM"})," in the ",(0,s.jsx)(n.code,{children:"tools/"})," folder. Place them on the ",(0,s.jsx)(n.code,{children:"$env:Path"})," user/system path and they will be available system-wide."]}),"\n",(0,s.jsxs)(n.p,{children:["The same is true for the ",(0,s.jsx)(n.code,{children:"Qt Framework"}),", it doesn't provide ",(0,s.jsx)(n.code,{children:"qtenv"})," scripts for ",(0,s.jsx)(n.code,{children:"pwsh"})," too. You can create your own script, place it on the ",(0,s.jsx)(n.code,{children:"$env:Path"})," user/system path and it will be available system-wide."]}),"\n",(0,s.jsxs)(n.p,{children:["Here is one simple example for ",(0,s.jsx)(n.code,{children:"pwsh"}),"."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:"qtenv6.ps1",label:"qtenv6.ps1",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-powershell",children:"#!/usr/bin/env pwsh\n\nSet-StrictMode -Version 3.0\n\nWrite-Host 'Setting up environment for Qt 6.7.0 usage...' -ForegroundColor Magenta\nWrite-Host\n\n$Script:QtRoot = $env:TINY_QT_ROOT ?? 'C:\\Qt'\n\n$env:Path = \"$Script:QtRoot\\6.7.0\\msvc2019_64\\bin;\" + $env:Path\n\n. vcvars64.ps1\n"})})}),(0,s.jsx)(t.A,{value:"qtenv5.ps1",label:"qtenv5.ps1",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-powershell",children:"#!/usr/bin/env pwsh\n\nSet-StrictMode -Version 3.0\n\nWrite-Host 'Setting up environment for Qt 5.15.2 usage...' -ForegroundColor Magenta\nWrite-Host\n\n$Script:QtRoot = $env:TINY_QT_ROOT ?? 'C:\\Qt'\n\n$env:Path = \"$Script:QtRoot\\5.15.2\\msvc2019_64\\bin;\" + $env:Path\n\n. vcvars64.ps1\n"})})})]}),"\n",(0,s.jsxs)(n.p,{children:["And here for ",(0,s.jsx)(n.code,{children:"Linux"}),"."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:"qtenv6",label:"qtenv6",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'echo \'Setting up environment for Qt 6.7.0 usage...\'\n\nQtRoot="${TINY_QT_ROOT:-/opt/Qt}"\n\nexport PATH="$QtRoot/6.7.0/gcc_64/bin"${PATH:+:}$PATH\nexport LD_LIBRARY_PATH="$QtRoot/6.7.0/gcc_64/lib"${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH\n'})})}),(0,s.jsx)(t.A,{value:"qtenv5",label:"qtenv5",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'echo \'Setting up environment for Qt 5.15.2 usage...\'\n\nQtRoot="${TINY_QT_ROOT:-/opt/Qt}"\n\nexport PATH="$QtRoot/5.15.2/gcc_64/bin"${PATH:+:}$PATH\nexport LD_LIBRARY_PATH="$QtRoot/5.15.2/gcc_64/lib"${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH\n'})})})]}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["These scripts consider the ",(0,s.jsx)(n.code,{children:"TINY_QT_ROOT"})," environment variable that should point to the ",(0,s.jsx)(n.code,{children:"Qt"})," installation folder, you can define this environment variable globally in your OS."]})}),"\n",(0,s.jsx)(n.h5,{id:"allow-symbolic-links-unprivileged",children:"Allow symbolic links unprivileged"}),"\n",(0,s.jsxs)(n.p,{children:["Open ",(0,s.jsx)(n.code,{children:"Local Security Policy"}),", go to ",(0,s.jsx)(n.code,{children:"Local Policies - User Rights Assignment"}),", open ",(0,s.jsx)(n.code,{children:"Create symbolic links"})," and add your user account or user group, restart when it doesn't apply immediately."]}),"\n",(0,s.jsx)(n.h2,{id:"folders-structure",children:"Folders structure"}),"\n",(0,s.jsxs)(n.p,{children:["All ",(0,s.jsx)(n.code,{children:"tinyorm.org"})," examples are based on the following folders structure. The ",(0,s.jsx)(n.code,{children:"tom"})," folder will contain a ",(0,s.jsx)(n.a,{href:"/building/migrations",children:"migrations console application"}),"."]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can set the root and application folder paths in the form below and they will be used across the whole ",(0,s.jsx)(n.a,{href:"http://www.tinyorm.org",children:"www.tinyorm.org"})," website. \ud83e\udd73 The pwsh shell is supposed to use on Windows and the bash shell on Linux, but it is not a requirement."]})}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsxs)(t.A,{value:y.b,label:y.ux,className:"tiny-tree",children:[(0,s.jsx)("div",{className:"tiny-root-folder-info-wrapper",children:(0,s.jsxs)(n.p,{children:[(0,s.jsx)("span",{className:"tiny-root-folder-info-prefix",children:"Current pwsh path"}),"\xa0",(0,s.jsx)(u,{groupId:y.b})]})}),(0,s.jsx)(g,{groupId:y.b,label:y.ux}),(0,s.jsx)(g,{groupId:y.pW,label:y.kl}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-text",children:"\n\n\n\u251c\u2500\u2500\n\u2502 \u251c\u2500\u2500 HelloWorld/\n\u2502 | \u251c\u2500\u2500 HelloWorld/\n\u2502 | \u251c\u2500\u2500 HelloWorld-builds-cmake/\n\u2502 | | \u2514\u2500\u2500 build-debug/\n\u2502 | \u2514\u2500\u2500 HelloWorld-builds-qmake/\n\u2502 | \u2514\u2500\u2500 build-debug/\n\u2502 \u251c\u2500\u2500 TinyORM/\n\u2502 | \u251c\u2500\u2500 TinyORM/\n\u2502 | \u251c\u2500\u2500 TinyORM-builds-cmake/\n\u2502 | \u2502 \u251c\u2500\u2500 build-gcc-debug/\n\u2502 | \u2502 \u251c\u2500\u2500 build-gcc-release/\n\u2502 | \u2502 \u2514\u2500\u2500 build-clang-debug/\n\u2502 | \u2514\u2500\u2500 TinyORM-builds-qmake/\n\u2502 | \u251c\u2500\u2500 build-debug/\n\u2502 | \u251c\u2500\u2500 build-TinyORM-Desktop_Qt_5_15_2_MSVC2019_64bit-Debug/\n\u2502 | \u2514\u2500\u2500 build-TinyORM-Desktop_Qt_5_15_2_MSYS2_UCRT64_64bit-Release/\n\u2502 \u2514\u2500\u2500 tom/\n\u2502 \u251c\u2500\u2500 tom/\n\u2502 \u2502 \u2514\u2500\u2500 database/\n\u2502 \u2502 \u251c\u2500\u2500 migrations/\n\u2502 \u2502 \u251c\u2500\u2500 seeders/\n\u2502 \u2502 \u251c\u2500\u2500 migrations.pri\n\u2502 \u2502 \u2514\u2500\u2500 seeders.pri\n\u2502 \u251c\u2500\u2500 tom-builds-cmake/\n\u2502 \u2502 \u2514\u2500\u2500 build-TinyORM-Desktop_Qt_6_7_0_MSVC2019_64bit-Debug/\n\u2502 \u2514\u2500\u2500 tom-builds-qmake/\n\u2502 \u251c\u2500\u2500 build-TinyORM-Desktop_Qt_5_15_3_MSYS2_UCRT64_64bit-Release/\n\u2502 \u2514\u2500\u2500 build-TinyORM-Desktop_Qt_6_7_0_MSVC2019_64bit-Debug/\n\u251c\u2500\u2500 tmp/\n\u2514\u2500\u2500 vcpkg/\n"})})]}),(0,s.jsxs)(t.A,{value:y.xj,label:y.gg,className:"tiny-tree",children:[(0,s.jsx)("div",{className:"tiny-root-folder-info-wrapper",children:(0,s.jsxs)(n.p,{children:[(0,s.jsx)("span",{className:"tiny-root-folder-info-prefix",children:"Current bash path"}),"\xa0",(0,s.jsx)(u,{groupId:y.xj})]})}),(0,s.jsx)(g,{groupId:y.xj,label:y.gg}),(0,s.jsx)(g,{groupId:y.pW,label:y.pW}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-text",children:"\n\n\n\u251c\u2500\u2500\n\u2502 \u251c\u2500\u2500 HelloWorld/\n\u2502 | \u251c\u2500\u2500 HelloWorld/\n\u2502 | \u251c\u2500\u2500 HelloWorld-builds-cmake/\n\u2502 | | \u2514\u2500\u2500 build-debug/\n\u2502 | \u2514\u2500\u2500 HelloWorld-builds-qmake/\n\u2502 | \u2514\u2500\u2500 build-debug/\n\u2502 \u251c\u2500\u2500 TinyORM/\n\u2502 | \u251c\u2500\u2500 TinyORM/\n\u2502 | \u251c\u2500\u2500 TinyORM-builds-cmake/\n\u2502 | \u2502 \u251c\u2500\u2500 build-gcc-debug/\n\u2502 | \u2502 \u251c\u2500\u2500 build-gcc-release/\n\u2502 | \u2502 \u2514\u2500\u2500 build-clang-debug/\n\u2502 | \u2514\u2500\u2500 TinyORM-builds-qmake/\n\u2502 | \u251c\u2500\u2500 build-debug/\n\u2502 | \u251c\u2500\u2500 build-TinyORM-Desktop_Qt_5_15_2_GCC_64bit-Debug/\n\u2502 | \u2514\u2500\u2500 build-TinyORM-Desktop_Qt_5_15_2_clang13_64bit_ccache-Release/\n\u2502 \u2514\u2500\u2500 tom/\n\u2502 \u251c\u2500\u2500 tom/\n\u2502 \u2502 \u2514\u2500\u2500 database/\n\u2502 \u2502 \u251c\u2500\u2500 migrations/\n\u2502 \u2502 \u251c\u2500\u2500 seeders/\n\u2502 \u2502 \u251c\u2500\u2500 migrations.pri\n\u2502 \u2502 \u2514\u2500\u2500 seeders.pri\n\u2502 \u251c\u2500\u2500 tom-builds-cmake/\n\u2502 \u2502 \u2514\u2500\u2500 build-TinyORM-Desktop_Qt_6_7_0_clang14_64bit_ccache-Debug/\n\u2502 \u2514\u2500\u2500 tom-builds-qmake/\n\u2502 \u251c\u2500\u2500 build-TinyORM-Desktop_Qt_6_7_0_GCC_64bit-Debug/\n\u2502 \u2514\u2500\u2500 build-TinyORM-Desktop_Qt_6_7_0_clang14_64bit_ccache-Release/\n\u251c\u2500\u2500 tmp/\n\u2514\u2500\u2500 vcpkg/\n"})})]})]}),"\n",(0,s.jsx)(n.admonition,{type:"danger",children:(0,s.jsxs)(n.p,{children:["Avoid paths with spaces with the ",(0,s.jsx)(n.code,{children:"qmake"})," build system, it will not compile."]})}),"\n",(0,s.jsx)(r.A,{id:"qtcreator-default-build-directory"}),"\n",(0,s.jsxs)(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 above."]}),(0,s.jsxs)(n.p,{children:["To generate the required folders structure set the ",(0,s.jsx)(n.code,{children:"Settings"})," - ",(0,s.jsx)(n.code,{children:"Build & Run"})," - ",(0,s.jsx)(n.code,{children:"Default Build Properties"})," - ",(0,s.jsx)(n.code,{children:"Default build directory"})," to:",(0,s.jsx)("br",{}),"\n",(0,s.jsx)(n.code,{children:'../%{Project:Name}-builds-%{BuildSystem:Name}/%{JS: Util.asciify("build-%{Project:Name}-%{Kit:FileSystemName}-%{BuildConfig:Name}")}'})]})]}),"\n",(0,s.jsx)(n.h2,{id:"getting-started",children:"Getting started"}),"\n",(0,s.jsxs)(n.p,{children:["Prepare compilation environment, we need to put the Qt Framework and Visual Studio MSVC compiler on the path on Windows. The compiler is already on the path on Linux and you can export ",(0,s.jsx)(n.code,{children:"PATH"})," and ",(0,s.jsx)(n.code,{children:"LD_LIBRARY_PATH"})," for Qt Framework, or use our ",(0,s.jsx)(n.code,{children:"qtenvX"})," scripts described above."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`mkdir ${(0,x.Sn)(y.b)}\ncd ${(0,x.Sn)(y.b)}\n$env:Path = 'C:\\Qt\\6.7.0\\msvc2019_64\\bin;' + $env:Path\nvcvars64.ps1`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`mkdir -p ${(0,x.Sn)(y.xj)}\ncd ${(0,x.Sn)(y.xj)}\nexport PATH=/opt/Qt/6.7.0/gcc_64/bin\${PATH:+:}$PATH\nexport LD_LIBRARY_PATH=/opt/Qt/6.7.0/gcc_64/lib\${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH`})})]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can also use the ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/tools/Add-FolderOnPath.ps1",children:(0,s.jsx)(n.code,{children:"tools/Add-FolderOnPath.ps1"})})," pwsh script to fastly prepend a path or ",(0,s.jsx)("abbr",{title:"Current working directory",children:"pwd"})," on the system ",(0,s.jsx)(n.code,{children:"PATH"}),"."]})}),"\n",(0,s.jsx)(n.h2,{id:"vcpkg",children:"vcpkg"}),"\n",(0,s.jsxs)(n.p,{children:["Installing the ",(0,s.jsx)(n.code,{children:"vcpkg"})," is highly recommended, it simplifies installation of the ",(0,s.jsx)(n.code,{children:"range-v3"})," and ",(0,s.jsx)(n.code,{children:"tabulate"})," dependencies."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-powershell",children:"git clone git@github.com:microsoft/vcpkg.git\ncd vcpkg\n.\\bootstrap-vcpkg.bat\n"})})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone git@github.com:microsoft/vcpkg.git\ncd vcpkg\n./bootstrap-vcpkg.sh\n"})})})]}),"\n",(0,s.jsxs)(n.p,{children:["Add ",(0,s.jsx)(n.code,{children:"vcpkg"})," on the system path, add the following to the ",(0,s.jsx)(n.code,{children:".bashrc"})," or ",(0,s.jsx)(n.code,{children:".zshrc"})," on Linux."]}),"\n",(0,s.jsx)(c.A,{className:"language-bash",children:`export PATH=${(0,x.Sn)(y.xj)}/vcpkg\${PATH:+:}$PATH`}),"\n",(0,s.jsxs)(n.p,{children:["On Windows, open the ",(0,s.jsx)(n.code,{children:"Environment variables"})," dialog and add ",(0,s.jsx)(n.code,{children:"vcpkg"})," on the user ",(0,s.jsx)(n.code,{children:"PATH"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Or you can export it for the current session only."}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`$env:Path = "${(0,x.Sn)(y.b,!1)}\\vcpkg;" + $env:Path`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`export PATH=${(0,x.Sn)(y.xj)}/vcpkg\${PATH:+:}$PATH`})})]}),"\n",(0,s.jsxs)(n.h4,{id:"set-up-vcpkg-environment",children:["Set up ",(0,s.jsx)(n.code,{children:"vcpkg"})," environment"]}),"\n",(0,s.jsxs)(n.p,{children:["To export ",(0,s.jsx)(n.code,{children:"vcpkg"})," environment variables globally, add it to the ",(0,s.jsx)(n.code,{children:".bashrc"})," or ",(0,s.jsx)(n.code,{children:".zshrc"})," on Linux, and you can use the ",(0,s.jsx)(n.code,{children:"Environment variables"})," dialog on Windows."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",metastring:"title='Linux'",children:'export VCPKG_DEFAULT_TRIPLET=x64-linux\n#export VCPKG_DEFAULT_HOST_TRIPLET=x64-linux\nexport VCPKG_MAX_CONCURRENCY=11\nexport VCPKG_OVERLAY_PORTS="$HOME/.local/share/vcpkg/ports"\nexport VCPKG_OVERLAY_TRIPLETS="$HOME/.local/share/vcpkg/triplets"\nexport VCPKG_ROOT="$HOME/Code/c/vcpkg"\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["It is recommended to define these variables globally because the ",(0,s.jsx)(n.code,{children:"CMake"})," and ",(0,s.jsx)(n.code,{children:"qmake"})," build system are able to detect the ",(0,s.jsx)(n.code,{children:"vcpkg"})," installation from them so you don't have to configure them manually to detect the ",(0,s.jsx)(n.code,{children:"vcpkg"})," installation."]})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["On Windows, it's always better to create these types of variables as user variables instead of system variables in the ",(0,s.jsx)(n.code,{children:"Environment variables"})," dialog."]})}),"\n",(0,s.jsx)(n.h2,{id:"c-preprocessor-macros",children:"C preprocessor macros"}),"\n",(0,s.jsxs)(n.p,{children:["The following table summarizes all the C preprocessor macros defined in the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library. These C macros are configured by ",(0,s.jsx)(n.code,{children:"CMake"})," or ",(0,s.jsx)(n.code,{children:"qmake"})," build systems. They are not sorted alphabetically, but they are sorted by how significant they are."]}),"\n",(0,s.jsxs)(n.p,{children:["In the ",(0,s.jsx)(n.code,{children:"CMake"})," build system, all the C macros are auto-detected / auto-configured or controlled by ",(0,s.jsx)(n.a,{href:"#cmake-build-options",children:(0,s.jsx)(n.code,{children:"CMake build options"})}),", so you don't have to care too much about them."]}),"\n",(0,s.jsxs)(n.p,{children:["In the ",(0,s.jsx)(n.code,{children:"qmake"})," build is important whether you are building ",(0,s.jsx)(n.code,{children:"TinyORM"})," library or you are building your application and linking against ",(0,s.jsx)(n.code,{children:"TinyORM"})," library. When you are building the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library, all the C macros are auto-detected / auto-configured or controlled by ",(0,s.jsx)(n.a,{href:"#qmake-build-options",children:(0,s.jsx)(n.code,{children:"qmake build options"})}),", so you don't have to care too much about them."]}),"\n",(0,s.jsxs)(n.p,{children:["But a special situation is when you are building your application / library and you are linking against ",(0,s.jsx)(n.code,{children:"TinyORM"})," library. In this particular case, you must configure all these C macros manually! For this reason, the ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/qmake/TinyOrm.pri",children:(0,s.jsx)(n.code,{children:"TinyOrm.pri"})})," has been created, so that's not a big deal either. Little more info ",(0,s.jsx)(n.a,{href:"#consume-tinyorm-library-qmake",children:"here"}),"."]}),"\n",(0,s.jsx)("div",{id:"apitable-c-macros",children:(0,s.jsx)(l.A,{children:(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"C Macro Name"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_LINKING_SHARED"})}),(0,s.jsxs)(n.td,{children:[(0,s.jsx)("u",{children:(0,s.jsx)(n.strong,{children:"Must"})})," be defined when you are linking against ",(0,s.jsx)(n.code,{children:"TinyORM"})," shared build (",(0,s.jsx)(n.code,{children:"dll"})," library), exported classes and functions will be tagged with ",(0,s.jsx)(n.code,{children:"__declspec(dllimport)"})," on ",(0,s.jsx)(n.code,{children:"msvc"})," and ",(0,s.jsx)(n.code,{children:'visibility("default")'})," on ",(0,s.jsx)(n.code,{children:"GCC >= 4"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_BUILDING_SHARED"})}),(0,s.jsxs)(n.td,{children:["Defined when ",(0,s.jsx)(n.code,{children:"TinyORM"})," is built as a ",(0,s.jsx)(n.code,{children:"dll"})," library (shared build)."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_DEBUG"})}),(0,s.jsx)(n.td,{children:"Defined in the debug build."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_NO_DEBUG"})}),(0,s.jsx)(n.td,{children:"Defined in the release build."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_DEBUG_SQL"})}),(0,s.jsx)(n.td,{children:"Defined in the debug build."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_NO_DEBUG_SQL"})}),(0,s.jsx)(n.td,{children:"Defined in the release build."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_MYSQL_PING"})}),(0,s.jsxs)(n.td,{children:["Enable ",(0,s.jsx)(n.code,{children:"Orm::MySqlConnection::pingDatabase()"})," method.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined when ",(0,s.jsx)(n.a,{href:"#mysql_ping",children:(0,s.jsx)(n.code,{children:"mysql_ping"})})," ",(0,s.jsx)("small",{children:"(qmake)"})," / ",(0,s.jsx)(n.a,{href:"#MYSQL_PING",children:(0,s.jsx)(n.code,{children:"MYSQL_PING"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration ",(0,s.jsx)(n.code,{children:"build option"})," is enabled."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_DISABLE_ORM"})}),(0,s.jsxs)(n.td,{children:["Controls the compilation of all ",(0,s.jsx)(n.code,{children:"ORM-related"})," source code, when this macro is ",(0,s.jsx)(n.code,{children:"defined"}),", then only the ",(0,s.jsx)(n.code,{children:"query builder"})," without ",(0,s.jsx)(n.code,{children:"ORM"})," is compiled. Also excludes ",(0,s.jsx)(n.code,{children:"ORM-related"})," unit tests.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined when ",(0,s.jsx)(n.a,{href:"#disable_orm",children:(0,s.jsx)(n.code,{children:"disable_orm"})})," ",(0,s.jsx)("small",{children:"(qmake)"})," / ",(0,s.jsx)(n.a,{href:"#ORM",children:(0,s.jsx)(n.code,{children:"ORM"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration ",(0,s.jsx)(n.code,{children:"build option"})," is enabled ",(0,s.jsx)("small",{children:"(qmake)"})," / disabled ",(0,s.jsx)("small",{children:"(cmake)"}),"."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_EXTERN_CONSTANTS"})}),(0,s.jsxs)(n.td,{children:["Defined when extern constants are used. Extern constants are enabled by default for shared builds and disabled for static builds.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Described at ",(0,s.jsx)(n.a,{href:"#extern_constants",children:(0,s.jsx)(n.code,{children:"qmake"})})," / ",(0,s.jsx)(n.a,{href:"#INLINE_CONSTANTS",children:(0,s.jsx)(n.code,{children:"CMake"})})," how it works."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_INLINE_CONSTANTS"})}),(0,s.jsxs)(n.td,{children:["Defined when global inline constants are used.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined when ",(0,s.jsx)(n.a,{href:"#inline_constants",children:(0,s.jsx)(n.code,{children:"inline_constants"})})," ",(0,s.jsx)("small",{children:"(qmake)"})," / ",(0,s.jsx)(n.a,{href:"#INLINE_CONSTANTS",children:(0,s.jsx)(n.code,{children:"INLINE_CONSTANTS"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration ",(0,s.jsx)(n.code,{children:"build option"})," is enabled."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_TESTS_CODE"})}),(0,s.jsxs)(n.td,{children:["Enable code needed by unit tests, eg. connection overriding in the ",(0,s.jsx)(n.code,{children:"Orm::Tiny::Model"}),".",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined when ",(0,s.jsx)(n.a,{href:"#build_tests",children:(0,s.jsx)(n.code,{children:"build_tests"})})," ",(0,s.jsx)("small",{children:"(qmake)"})," / ",(0,s.jsx)(n.a,{href:"#BUILD_TESTS",children:(0,s.jsx)(n.code,{children:"BUILD_TESTS"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration ",(0,s.jsx)(n.code,{children:"build option"})," is enabled."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_DISABLE_THREAD_LOCAL"})}),(0,s.jsxs)(n.td,{children:["Remove all ",(0,s.jsx)(n.a,{href:"https://en.cppreference.com/w/c/language/storage_duration",children:(0,s.jsx)(n.code,{children:"thread_local"})})," storage duration specifiers, it disables multi-threading support.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined when ",(0,s.jsx)(n.a,{href:"#disable_thread_local",children:(0,s.jsx)(n.code,{children:"disable_thread_local"})})," ",(0,s.jsx)("small",{children:"(qmake)"})," / ",(0,s.jsx)(n.a,{href:"#DISABLE_THREAD_LOCAL",children:(0,s.jsx)(n.code,{children:"DISABLE_THREAD_LOCAL"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration ",(0,s.jsx)(n.code,{children:"build option"})," is enabled."]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYTOM_MIGRATIONS_DIR"})}),(0,s.jsxs)(n.td,{children:["Default migrations path for the ",(0,s.jsx)(n.code,{children:"make:migration"})," command, can be an absolute or relative path (to the ",(0,s.jsx)("abbr",{title:"Current working directory",children:"pwd"}),").",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Default value: ",(0,s.jsx)(n.code,{children:"database/migrations"})," ",(0,s.jsx)("small",{children:"(relative to the pwd)"})]}),(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined by ",(0,s.jsx)(n.a,{href:"#TOM_MIGRATIONS_DIR",children:(0,s.jsx)(n.code,{children:"TOM_MIGRATIONS_DIR"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration build option.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["(qmake note) You can use ",(0,s.jsx)(n.code,{children:'DEFINES += TINYTOM_MIGRATIONS_DIR="\\"database/migrations\\""'})," on the command-line or set it in the ",(0,s.jsx)(n.strong,{children:"main"})," ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/conf.pri.example#L65-L70",children:(0,s.jsx)(n.code,{children:"conf.pri"})})," file."]})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYTOM_MODELS_DIR"})}),(0,s.jsxs)(n.td,{children:["Default models path for the ",(0,s.jsx)(n.code,{children:"make:model"})," command, can be an absolute or relative path (to the ",(0,s.jsx)("abbr",{title:"Current working directory",children:"pwd"}),").",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Default value: ",(0,s.jsx)(n.code,{children:"database/models"})," ",(0,s.jsx)("small",{children:"(relative to the pwd)"})]}),(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined by ",(0,s.jsx)(n.a,{href:"#TOM_MODELS_DIR",children:(0,s.jsx)(n.code,{children:"TOM_MODELS_DIR"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration build option.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["(qmake note) You can use ",(0,s.jsx)(n.code,{children:'DEFINES += TINYTOM_MODELS_DIR="\\"database/models\\""'})," on the command-line or set it in the ",(0,s.jsx)(n.strong,{children:"main"})," ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/conf.pri.example#L72-L73",children:(0,s.jsx)(n.code,{children:"conf.pri"})})," file."]})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYTOM_SEEDERS_DIR"})}),(0,s.jsxs)(n.td,{children:["Default seeders path for the ",(0,s.jsx)(n.code,{children:"make:seeder"})," command, can be an absolute or relative path (to the ",(0,s.jsx)("abbr",{title:"Current working directory",children:"pwd"}),").",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Default value: ",(0,s.jsx)(n.code,{children:"database/seeders"})," ",(0,s.jsx)("small",{children:"(relative to the pwd)"})]}),(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Defined by ",(0,s.jsx)(n.a,{href:"#TOM_SEEDERS_DIR",children:(0,s.jsx)(n.code,{children:"TOM_SEEDERS_DIR"})})," ",(0,s.jsx)("small",{children:"(cmake)"})," configuration build option.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["(qmake note) You can use ",(0,s.jsx)(n.code,{children:'DEFINES += TINYTOM_SEEDERS_DIR="\\"database/seeders\\""'})," on the command-line or set it in the ",(0,s.jsx)(n.strong,{children:"main"})," ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/conf.pri.example#L75-L76",children:(0,s.jsx)(n.code,{children:"conf.pri"})})," file."]})]})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"TINYORM_USING_PCH"})}),(0,s.jsxs)(n.td,{children:["Defined if building with precompiled headers.",(0,s.jsx)("br",{}),(0,s.jsxs)("small",{children:["Controlled by ",(0,s.jsx)(n.a,{href:"#qmake-precompile_header",children:(0,s.jsx)(n.code,{children:"qmake"})})," / ",(0,s.jsx)(n.a,{href:"#CMAKE_DISABLE_PRECOMPILE_HEADERS",children:(0,s.jsx)(n.code,{children:"CMake"})}),"."]})]})]})]})]})})}),"\n",(0,s.jsx)(n.h2,{id:"building-with-cmake",children:"Building with CMake"}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["If something is not clear, you can still look at GitHub Action ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/tree/main/.github/workflows",children:(0,s.jsx)(n.code,{children:"workflows"})})," how a building is done."]})}),"\n",(0,s.jsxs)(n.p,{children:["First, create a basic folder structure and then clone the ",(0,s.jsx)(n.code,{children:"TinyORM"})," project."]}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`cd ${(0,x.Sn)(y.b)}\nmkdir ${(0,x.np)()}/TinyORM/TinyORM-builds-cmake/build-debug\n\ncd ${(0,x.np)()}/TinyORM\ngit clone git@github.com:silverqx/TinyORM.git`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`cd ${(0,x.Sn)(y.xj)}\nmkdir -p ${(0,x.np)()}/TinyORM/TinyORM-builds-cmake/build-debug\n\ncd ${(0,x.np)()}/TinyORM\ngit clone git@github.com:silverqx/TinyORM.git`})})]}),"\n",(0,s.jsxs)(n.h3,{id:"configure-and-build-cmake",children:["Configure & Build ",(0,s.jsx)("small",{children:"(cmake)"})]}),"\n",(0,s.jsxs)(n.p,{children:["Now you are ready to configure the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd TinyORM-builds-cmake/build-debug\n"})}),"\n",(0,s.jsxs)(o.A,{groupId:y.vf,children:[(0,s.jsx)(t.A,{value:y.b,label:y.ux,children:(0,s.jsx)(c.A,{className:"language-powershell",children:`cmake.exe \`\n-S "${(0,x.OZ)(y.b)}/TinyORM/TinyORM" \`\n-B "${(0,x.OZ)(y.b)}/TinyORM/TinyORM-builds-cmake/build-debug" \`\n-G 'Ninja' \`\n-D CMAKE_BUILD_TYPE:STRING='Debug' \`\n-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${(0,x.Sn)(y.b)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \`\n-D CMAKE_CXX_SCAN_FOR_MODULES:BOOL=OFF \`\n-D CMAKE_INSTALL_PREFIX:PATH="${(0,x.Sn)(y.b)}/tmp/TinyORM" \`\n-D BUILD_TESTS:BOOL=OFF \`\n-D MATCH_EQUAL_EXPORTED_BUILDTREE:BOOL=ON \`\n-D MYSQL_PING:BOOL=OFF \`\n-D TOM:BOOL=ON \`\n-D TOM_EXAMPLE:BOOL=OFF \`\n-D VERBOSE_CONFIGURE:BOOL=ON`})}),(0,s.jsx)(t.A,{value:y.xj,label:y.gg,children:(0,s.jsx)(c.A,{className:"language-bash",children:`cmake \\\n-S "${(0,x.OZ)(y.xj)}/TinyORM/TinyORM" \\\n-B "${(0,x.OZ)(y.xj)}/TinyORM/TinyORM-builds-cmake/build-debug" \\\n-G 'Ninja' \\\n-D CMAKE_BUILD_TYPE:STRING='Debug' \\\n-D CMAKE_TOOLCHAIN_FILE:FILEPATH="${(0,x.Sn)(y.xj)}/vcpkg/scripts/buildsystems/vcpkg.cmake" \\\n-D CMAKE_CXX_SCAN_FOR_MODULES:BOOL=OFF \\\n-D CMAKE_INSTALL_PREFIX:PATH="${(0,x.Sn)(y.xj)}/tmp/TinyORM" \\\n-D VERBOSE_CONFIGURE:BOOL=ON \\\n-D BUILD_TESTS:BOOL=OFF \\\n-D MYSQL_PING:BOOL=OFF \\\n-D TOM:BOOL=ON \\\n-D TOM_EXAMPLE:BOOL=OFF \\\n-D MATCH_EQUAL_EXPORTED_BUILDTREE:BOOL=ON`})})]}),"\n",(0,s.jsxs)(n.h5,{id:"cmake-strict_mode-option",children:["CMake ",(0,s.jsx)(n.code,{children:"STRICT_MODE"})," option"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"STRICT_MODE"})," ",(0,s.jsx)(n.code,{children:"CMake"})," configuration option was added in ",(0,s.jsx)(n.code,{children:"TinyORM"})," ",(0,s.jsx)(n.code,{children:"v0.37.3"}),". This option was added to avoid the propagation of aggressive strict warning compiler/linker options and Qt definitions from the ",(0,s.jsx)(n.code,{children:"TinyORM"})," library to user code through the ",(0,s.jsx)(n.a,{href:"https://github.com/silverqx/TinyORM/blob/main/cmake/CommonModules/TinyCommon.cmake",children:(0,s.jsx)(n.code,{children:"TinyOrm::CommonConfig"})})," interface library."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"TinyORM"})," uses the strictest warning level options, virtually anything that can be enabled is enabled to produce a better code. I highly recommend enabling this option to produce better code and to follow good practices. It also helps to follow the ",(0,s.jsx)(n.code,{children:"ISOCPP"})," ",(0,s.jsx)(n.a,{href:"https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines",children:"C++ Core Guidelines"})," standards."]}),"\n",(0,s.jsxs)(n.p,{children:["If you want to enable these strict warning options in your code, you can enable the ",(0,s.jsx)(n.code,{children:"STRICT_MODE"})," ",(0,s.jsx)(n.code,{children:"CMake"})," configuration option and they will be propagated to your code. You can also enabled it globally using the ",(0,s.jsx)(n.code,{children:"TINYORM_STRICT_MODE"})," environment variable, and the value of this environment variable will be picked up during initial CMake configuration as the default value for the ",(0,s.jsx)(n.code,{children:"STRICT_MODE"})," ",(0,s.jsx)(n.code,{children:"CMake"})," configuration option."]}),"\n",(0,s.jsxs)(n.p,{children:["You can achieve the same result by manually linking against the ",(0,s.jsx)(n.code,{children:"TinyOrm::CommonConfig"})," interface library when the ",(0,s.jsx)(n.code,{children:"STRICT_MODE"})," is set to ",(0,s.jsx)(n.code,{children:"OFF"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-cmake",children:"target_link_libraries(Shared
library build",id:"the-shared-library-build",level:5},{value:"The Static
build",id:"the-static-build",level:5},{value:"The Loadable
SQL drivers build",id:"the-loadable-sql-drivers-build",level:5},{value:"CMake
/qmake
build options",id:"cmakeqmake-build-options",level:4},{value:"For CMake
",id:"for-cmake",level:5},{value:"For qmake
",id:"for-qmake",level:5},{value:"Performance",id:"performance",level:3},{value:"Internals",id:"internals",level:2},{value:"SqlDatabase",id:"sqldatabase",level:5},{value:"Namespaces",id:"namespaces",level:5},{value:"Documentation",id:"documentation",level:5}];function o(e){const i={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(i.h1,{id:"tinydrivers-getting-started",children:"TinyDrivers: Getting Started"}),"\n",(0,r.jsxs)(i.ul,{children:["\n",(0,r.jsx)(i.li,{children:(0,r.jsx)(i.a,{href:"#introduction",children:"Introduction"})}),"\n",(0,r.jsxs)(i.li,{children:[(0,r.jsx)(i.a,{href:"#differences-from-qtsql",children:"Differences from QtSql"}),"\n",(0,r.jsxs)(i.ul,{children:["\n",(0,r.jsx)(i.li,{children:(0,r.jsx)(i.a,{href:"#build-system",children:"Build system"})}),"\n",(0,r.jsx)(i.li,{children:(0,r.jsx)(i.a,{href:"#performance",children:"Performance"})}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(i.li,{children:(0,r.jsx)(i.a,{href:"#internals",children:"Internals"})}),"\n"]}),"\n",(0,r.jsx)(i.h2,{id:"introduction",children:"Introduction"}),"\n",(0,r.jsxs)(i.p,{children:["The ",(0,r.jsx)(i.code,{children:"TinyDrivers"})," library is an underlying SQL database layer for ",(0,r.jsx)(i.code,{children:"TinyORM"}),". It can be used instead of the ",(0,r.jsx)(i.code,{children:"QtSql"})," module, can be ",(0,r.jsx)("u",{children:(0,r.jsx)(i.strong,{children:"swapped"})})," at compile time, and has ",(0,r.jsx)(i.strong,{children:"1:1"})," API as the ",(0,r.jsx)(i.code,{children:"QtSql"})," module. \ud83d\ude2e Swapping is controlled by the ",(0,r.jsx)(i.code,{children:"qmake"})," and ",(0,r.jsx)(i.code,{children:"CMake"})," build system options."]}),"\n",(0,r.jsxs)(i.p,{children:["It was designed to drop the ",(0,r.jsx)(i.code,{children:"QtSql"})," dependency while maintaining backward compatibility and without the need for any code changes after the swap."]}),"\n",(0,r.jsx)(i.h5,{id:"features-summary",children:"Features summary"}),"\n",(0,r.jsxs)(i.ul,{children:["\n",(0,r.jsx)(i.li,{children:"both, normal and prepared statements are supported"}),"\n",(0,r.jsxs)(i.li,{children:["TLS/SSL connections using ",(0,r.jsx)(i.a,{href:"https://dev.mysql.com/doc/c-api/en/mysql-options.html",children:(0,r.jsx)(i.code,{children:"MYSQL_OPT_SSL_MODE"})})," (verify_ca, verify_identity) \ud83d\udd25"]}),"\n",(0,r.jsxs)(i.li,{children:["setting many other connection options (see ",(0,r.jsx)(i.a,{href:"https://github.com/silverqx/TinyORM/blob/main/drivers/mysql/src/orm/drivers/mysql/mysqldriver_p.cpp",children:(0,r.jsx)(i.code,{children:"mysqldriver_p.cpp"})}),")"]}),"\n",(0,r.jsxs)(i.li,{children:["building and linking against the ",(0,r.jsx)(i.a,{href:"https://mariadb.com/kb/en/mariadb-connector-c/",children:(0,r.jsx)(i.code,{children:"MariaDB Connector/C"})})]}),"\n",(0,r.jsx)(i.li,{children:"transactions"}),"\n",(0,r.jsxs)(i.li,{children:["re-using the current ",(0,r.jsx)(i.code,{children:"SqlQuery"})," instance to re-execute the same or another query"]}),"\n",(0,r.jsx)(i.li,{children:"detaching from the result set (associated to release memory)"}),"\n",(0,r.jsxs)(i.li,{children:["query size, number of affected rows, last inserted ID, testing ",(0,r.jsx)(i.code,{children:"isNull()"}),", ..."]}),"\n",(0,r.jsxs)(i.li,{children:["all ",(0,r.jsx)(i.strong,{children:"3366 unit tests"})," passed \ud83d\ude2e"]}),"\n"]}),"\n",(0,r.jsx)(i.admonition,{type:"info",children:(0,r.jsxs)(i.p,{children:["Currently, only the ",(0,r.jsx)(i.code,{children:"MySQL"})," database driver is supported and finished."]})}),"\n",(0,r.jsx)(i.admonition,{type:"info",children:(0,r.jsxs)(i.p,{children:[(0,r.jsx)(i.code,{children:"TinyDrivers"})," can only be built with ",(0,r.jsx)(i.code,{children:"Qt v6"}),", ",(0,r.jsx)(i.code,{children:"Qt v5.15"})," isn't supported."]})}),"\n",(0,r.jsx)(i.admonition,{type:"note",children:(0,r.jsxs)(i.p,{children:[(0,r.jsx)(i.code,{children:"TinyDrivers"})," library supports both build systems ",(0,r.jsx)(i.code,{children:"qmake"})," and also ",(0,r.jsx)(i.code,{children:"CMake"}),"."]})}),"\n",(0,r.jsx)(i.h2,{id:"differences-from-qtsql",children:"Differences from QtSql"}),"\n",(0,r.jsxs)(i.p,{children:[(0,r.jsx)(i.code,{children:"TinyDrivers"})," doesn't return errors the the same way as the ",(0,r.jsx)(i.code,{children:"QtSql"})," module, which means return a ",(0,r.jsx)(i.code,{children:"bool"})," and if it's the result ",(0,r.jsx)(i.code,{children:"false"})," then obtain the ",(0,r.jsx)(i.code,{children:"SqlError"})," instance using the ",(0,r.jsx)(i.code,{children:"lastError()"})," method from ",(0,r.jsx)(i.code,{children:"SqlDatabase"})," or ",(0,r.jsx)(i.code,{children:"SqlQuery"})," instances. Instead, it throws exceptions, and methods returning a ",(0,r.jsx)(i.code,{children:"bool"})," type to report an error state always return ",(0,r.jsx)(i.code,{children:"true"}),"."]}),"\n",(0,r.jsx)(i.h5,{id:"naming-conventions",children:"Naming conventions"}),"\n",(0,r.jsxs)(i.ul,{children:["\n",(0,r.jsxs)(i.li,{children:[(0,r.jsx)(i.code,{children:"QtSql"})," ",(0,r.jsx)("small",{children:"module"})," -> ",(0,r.jsx)(i.code,{children:"TinyDrivers"})," ",(0,r.jsx)("small",{children:"library"})]}),"\n",(0,r.jsxs)(i.li,{children:[(0,r.jsx)(i.code,{children:"QMYSQL"})," ",(0,r.jsx)("small",{children:"driver"})," -> ",(0,r.jsx)(i.code,{children:"TinyMySql"})," ",(0,r.jsx)("small",{children:"driver"})]}),"\n"]}),"\n",(0,r.jsx)(i.h5,{id:"mysql-driver",children:"MySQL driver"}),"\n",(0,r.jsxs)(i.p,{children:["The following describes the differences between ",(0,r.jsx)(i.code,{children:"QMYSQL"})," and ",(0,r.jsx)(i.code,{children:"TinyMySql"})," drivers."]}),"\n",(0,r.jsxs)(i.p,{children:["The ",(0,r.jsx)(i.code,{children:"QMYSQL"})," driver doesn't support setting ",(0,r.jsx)(i.code,{children:"MySQL"})," non-flag ",(0,r.jsx)(i.a,{href:"https://dev.mysql.com/doc/c-api/en/mysql-options.html",children:"connection options"})," like ",(0,r.jsx)(i.code,{children:"MYSQL_OPT_RECONNECT"})," without the value, it needs to be defined with value like ",(0,r.jsx)(i.code,{children:"=1"})," or ",(0,r.jsx)(i.code,{children:"=TRUE"})," (case-sensitive), only real flag options like ",(0,r.jsx)(i.code,{children:"CLIENT_INTERACTIVE"})," can be set without the value and ",(0,r.jsx)(i.code,{children:"="})," character."]}),"\n",(0,r.jsxs)(i.p,{children:["On the other hand, the ",(0,r.jsx)(i.code,{children:"TinyMySql"})," driver allows setting non-flag ",(0,r.jsx)(i.a,{href:"https://dev.mysql.com/doc/c-api/en/mysql-options.html",children:"connection options"})," options without the value and ",(0,r.jsx)(i.code,{children:"="})," character, which are considered enabled (ON or TRUE)."]}),"\n",(0,r.jsx)(i.h5,{id:"removed-features",children:"Removed features"}),"\n",(0,r.jsxs)(i.p,{children:["Simulation of prepared statements while calling ",(0,r.jsx)(i.code,{children:"SqlQuery::exec(QString)"}),", this functionality is useless because you can call regular prepared statements using ",(0,r.jsx)(i.code,{children:"SqlQuery::prepare(QString)"})," and then ",(0,r.jsx)(i.code,{children:"SqlQuery::exec()"}),"."]}),"\n",(0,r.jsx)(i.h5,{id:"missing-features",children:"Missing features"}),"\n",(0,r.jsxs)(i.p,{children:["Fetching multiple result sets using ",(0,r.jsx)(i.code,{children:"SqlQuery::nextResult()"}),". Multiple statement queries are supported they will be executed correctly (they can return multiple result sets), but only the first result set can be fetched currently. However, destroying multiple result sets is handled correctly."]}),"\n",(0,r.jsx)(i.h3,{id:"build-system",children:"Build system"}),"\n",(0,r.jsxs)(i.p,{children:["Another difference is that you can build the ",(0,r.jsx)(i.code,{children:"TinyDrivers"})," and its SQL drivers (",(0,r.jsx)(i.code,{children:"TinyMySql"}),") in 3 different ways; ",(0,r.jsx)(i.code,{children:"Shared"}),", ",(0,r.jsx)(i.code,{children:"Static"}),", and as a ",(0,r.jsx)(i.code,{children:"Loadable"})," library at runtime using ",(0,r.jsx)(i.code,{children:"LoadLibrary()"})," on Windows or ",(0,r.jsx)(i.code,{children:"dlopen()"})," on Linux."]}),"\n",(0,r.jsxs)(i.h5,{id:"the-shared-library-build",children:["The ",(0,r.jsx)(i.code,{children:"Shared"})," library build"]}),"\n",(0,r.jsxs)(i.p,{children:["It builds two shared libraries, the ",(0,r.jsx)(i.code,{children:"TinyDrivers"})," shared library that contains the core/common code and the ",(0,r.jsx)(i.code,{children:"TinyMySql"})," shared library that contains ",(0,r.jsx)(i.code,{children:"MySQL"})," implementation. The ",(0,r.jsx)(i.code,{children:"TinyOrm"})," links only against the ",(0,r.jsx)(i.code,{children:"TinyDrivers"})," shared library and ",(0,r.jsx)(i.code,{children:"TinyMySql"})," is a private implementation."]}),"\n",(0,r.jsxs)(i.h5,{id:"the-static-build",children:["The ",(0,r.jsx)(i.code,{children:"Static"})," build"]}),"\n",(0,r.jsxs)(i.p,{children:["It builds one ",(0,r.jsx)(i.code,{children:"TinyDrivers"})," static archive that contains the core/common code and SQL drivers (",(0,r.jsx)(i.code,{children:"TinyMySql"}),"). This static library is linked or merged into the ",(0,r.jsx)(i.code,{children:"TinyOrm"})," shared or static library (both variants are supported)."]}),"\n",(0,r.jsxs)(i.h5,{id:"the-loadable-sql-drivers-build",children:["The ",(0,r.jsx)(i.code,{children:"Loadable"})," SQL drivers build"]}),"\n",(0,r.jsxs)(i.p,{children:["It builds two shared libraries, the ",(0,r.jsx)(i.code,{children:"TinyDrivers"})," shared library that contains the core/common code and ",(0,r.jsx)(i.code,{children:"TinyMySql"})," shared library (module) that contains ",(0,r.jsx)(i.code,{children:"MySQL"})," implementation that is loaded at runtime using ",(0,r.jsx)(i.code,{children:"LoadLibrary()"})," on Windows or ",(0,r.jsx)(i.code,{children:"dlopen()"})," on Linux. The SQL driver library loader throws an exception if it cannot find this library at runtime."]}),"\n",(0,r.jsx)(i.admonition,{type:"info",children:(0,r.jsxs)(i.p,{children:["The ",(0,r.jsx)(i.code,{children:"TinyMySql"})," links directly against the ",(0,r.jsx)(i.code,{children:"MySQL C connector"})," (",(0,r.jsx)(i.code,{children:"libmysql"})," or ",(0,r.jsx)(i.code,{children:"mysqlclient"})," library)."]})}),"\n",(0,r.jsxs)(i.h4,{id:"cmakeqmake-build-options",children:[(0,r.jsx)(i.code,{children:"CMake"}),"/",(0,r.jsx)(i.code,{children:"qmake"})," build options"]}),"\n",(0,r.jsxs)(i.h5,{id:"for-cmake",children:["For ",(0,r.jsx)(i.code,{children:"CMake"})]}),"\n",(0,r.jsxs)(i.p,{children:["See ",(0,r.jsx)(i.a,{href:"/building/tinyorm#cmake-build-options",children:"CMake build options"}),", related ",(0,r.jsx)(i.code,{children:"CMake"})," build options are:",(0,r.jsx)("br",{}),(0,r.jsx)(i.a,{href:"/building/tinyorm#BUILD_DRIVERS",children:(0,r.jsx)(i.code,{children:"BUILD_DRIVERS"})}),", ",(0,r.jsx)(i.a,{href:"/building/tinyorm#BUILD_MYSQL_DRIVER",children:(0,r.jsx)(i.code,{children:"BUILD_MYSQL_DRIVER"})}),", and ",(0,r.jsx)(i.a,{href:"/building/tinyorm#DRIVERS_TYPE",children:(0,r.jsx)(i.code,{children:"DRIVERS_TYPE"})})]}),"\n",(0,r.jsxs)(i.p,{children:["To control shared and static build use ",(0,r.jsx)(i.a,{href:"https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html",children:(0,r.jsx)(i.code,{children:"BUILD_SHARED_LIBS"})})," ",(0,r.jsx)(i.code,{children:"CMake"})," configuration option."]}),"\n",(0,r.jsxs)(i.h5,{id:"for-qmake",children:["For ",(0,r.jsx)(i.code,{children:"qmake"})]}),"\n",(0,r.jsxs)(i.p,{children:["See ",(0,r.jsx)(i.a,{href:"/building/tinyorm#qmake-build-options",children:"qmake build options"}),", related ",(0,r.jsx)(i.code,{children:"qmake"})," configuration options are:",(0,r.jsx)("br",{}),(0,r.jsx)(i.a,{href:"/building/tinyorm#build_loadable_drivers",children:(0,r.jsx)(i.code,{children:"build_loadable_drivers"})}),", ",(0,r.jsx)(i.a,{href:"/building/tinyorm#build_mysql_driver",children:(0,r.jsx)(i.code,{children:"build_mysql_driver"})}),", ",(0,r.jsx)(i.a,{href:"/building/tinyorm#build_shared_drivers",children:(0,r.jsx)(i.code,{children:"build_shared_drivers"})}),", and ",(0,r.jsx)(i.a,{href:"/building/tinyorm#build_static_drivers",children:(0,r.jsx)(i.code,{children:"build_static_drivers"})})]}),"\n",(0,r.jsxs)(i.p,{children:["To control shared and static build use ",(0,r.jsx)(i.a,{href:"/building/tinyorm#static",children:(0,r.jsx)(i.code,{children:"static"})})," ",(0,r.jsx)(i.code,{children:"qmake"})," ",(0,r.jsx)(i.a,{href:"https://doc.qt.io/qt/qmake-variable-reference.html#config",children:"configuration option"}),"."]}),"\n",(0,r.jsx)(i.h3,{id:"performance",children:"Performance"}),"\n",(0,r.jsxs)(i.p,{children:["Performance is several milliseconds faster compared to ",(0,r.jsx)(i.code,{children:"QtSql"})," with the ",(0,r.jsx)(i.code,{children:"QMYSQL"})," driver. It was tuned using the ",(0,r.jsx)(i.code,{children:"KCacheGrind"})," to be so. It's ~40ms faster on ",(0,r.jsx)(i.a,{href:"https://github.com/silverqx/TinyOrmPlayground",children:(0,r.jsx)(i.code,{children:"TinyOrmPlayground"})})," project with ",(0,r.jsx)(i.strong,{children:"620"})," database queries compiled using ",(0,r.jsx)(i.code,{children:"GCC v13.2.1"})," Debug build on Linux. Similar results can be expected on other platforms but it's not guaranteed."]}),"\n",(0,r.jsxs)(i.p,{children:["This means performance is very similar to ",(0,r.jsx)(i.code,{children:"QtSql"}),". There is not much to speed up because ",(0,r.jsx)(i.code,{children:"TinyDrivers"})," code is swift and 90% of the time is spent inside the ",(0,r.jsx)(i.a,{href:"https://dev.mysql.com/doc/c-api/en/",children:(0,r.jsx)(i.code,{children:"MySQL C API"})})," because we always have to wait for the database server, especially when creating database connections using eg. ",(0,r.jsx)(i.a,{href:"https://dev.mysql.com/doc/c-api/en/mysql-real-connect.html",children:(0,r.jsx)(i.code,{children:"mysql_real_connect()"})})," (this function is king among the slowest functions \ud83d\ude0e, which is understandable of course)."]}),"\n",(0,r.jsx)(i.h2,{id:"internals",children:"Internals"}),"\n",(0,r.jsxs)(i.p,{children:[(0,r.jsx)(i.code,{children:"TinyDrivers"})," internal design can be divided into 3 different layers:"]}),"\n",(0,r.jsxs)(i.ul,{children:["\n",(0,r.jsx)(i.li,{children:"Driver layer"}),"\n",(0,r.jsx)(i.li,{children:"SQL API layer"}),"\n",(0,r.jsx)(i.li,{children:"Public API layer"}),"\n"]}),"\n",(0,r.jsxs)(i.p,{children:["The Driver layer is eg. ",(0,r.jsx)(i.code,{children:"TinyMySql"})," library which is responsible for communicating with the underlying database driver (eg. ",(0,r.jsx)(i.a,{href:"https://dev.mysql.com/doc/c-api/en/",children:(0,r.jsx)(i.code,{children:"MySQL C API"})}),")."]}),"\n",(0,r.jsx)(i.p,{children:"The SQL API layer is a semi-layer that glues everything up and sits between the Public interface API and the Driver layer."}),"\n",(0,r.jsxs)(i.p,{children:["The Public interface API layer are the end classes like ",(0,r.jsx)(i.code,{children:"SqlDatabase"})," and ",(0,r.jsx)(i.code,{children:"SqlQuery"})," which are exposed to the end user."]}),"\n",(0,r.jsx)(i.h5,{id:"sqldatabase",children:"SqlDatabase"}),"\n",(0,r.jsxs)(i.p,{children:["One more thing worth mentioning is the ",(0,r.jsx)(i.code,{children:"SqlDatabase"})," API. It's one class that has two responsibilities! All static methods act as the database connection manager and an instance of the ",(0,r.jsx)(i.code,{children:"SqlDatabase"})," represents a physical database connection. It's not a good design because it breaks the ",(0,r.jsx)(i.a,{href:"https://en.wikipedia.org/wiki/Single_responsibility_principle",children:"Single Responsibility principle"}),", but it's what it is."]}),"\n",(0,r.jsx)(i.h5,{id:"namespaces",children:"Namespaces"}),"\n",(0,r.jsxs)(i.p,{children:[(0,r.jsx)(i.code,{children:"TinyDrivers"})," classes are defined in the ",(0,r.jsx)(i.code,{children:"Orm::Drivers"})," namespace and ",(0,r.jsx)(i.code,{children:"TinyMySql"})," classes in the ",(0,r.jsx)(i.code,{children:"Orm::Drivers::MySql"})," namespace."]}),"\n",(0,r.jsx)(i.h5,{id:"documentation",children:"Documentation"}),"\n",(0,r.jsxs)(i.p,{children:["For all other APIs you can follow the ",(0,r.jsx)(i.a,{href:"https://doc.qt.io/qt/qtsql-index.html",children:"QtSql documentation"})," as the API is 1:1. The exception is of course the build system, ",(0,r.jsx)(i.code,{children:"TinyOrm"})," has its own build system that doesn't follow the ",(0,r.jsx)(i.code,{children:"QtSql"})," module."]})]})}function h(e={}){const{wrapper:i}={...(0,s.R)(),...e.components};return i?(0,r.jsx)(i,{...e,children:(0,r.jsx)(o,{...e})}):o(e)}},8453:(e,i,n)=>{n.d(i,{R:()=>t,x:()=>l});var r=n(6540);const s={},d=r.createContext(s);function t(e){const i=r.useContext(d);return r.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function l(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:t(e.components),r.createElement(d.Provider,{value:i},e.children)}}}]);
\ No newline at end of file
+"use strict";(self.webpackChunktinyorm_org=self.webpackChunktinyorm_org||[]).push([[258],{4028:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>a,contentTitle:()=>t,default:()=>h,frontMatter:()=>d,metadata:()=>l,toc:()=>c});var r=n(4848),s=n(8453);const d={sidebar_position:0,sidebar_label:"Getting Started",description:"The TinyDrivers library is an underlying SQL database layer for TinyORM. It can be used instead of the QtSql module, can be swapped at compile time, and has 1:1 API as the QtSql module. Swapping is controlled by the qmake and CMake build system options. It was designed to drop the QtSql dependency while maintaining backward compatibility and without the need for any code changes after the swap.",keywords:["c++ orm","database","getting started","tinydrivers","sql drivers"]},t="TinyDrivers: Getting Started",l={id:"tinydrivers/getting-started",title:"TinyDrivers: Getting Started",description:"The TinyDrivers library is an underlying SQL database layer for TinyORM. It can be used instead of the QtSql module, can be swapped at compile time, and has 1:1 API as the QtSql module. Swapping is controlled by the qmake and CMake build system options. It was designed to drop the QtSql dependency while maintaining backward compatibility and without the need for any code changes after the swap.",source:"@site/docs/tinydrivers/getting-started.mdx",sourceDirName:"tinydrivers",slug:"/tinydrivers/getting-started",permalink:"/tinydrivers/getting-started",draft:!1,unlisted:!1,tags:[],version:"current",sidebarPosition:0,frontMatter:{sidebar_position:0,sidebar_label:"Getting Started",description:"The TinyDrivers library is an underlying SQL database layer for TinyORM. It can be used instead of the QtSql module, can be swapped at compile time, and has 1:1 API as the QtSql module. Swapping is controlled by the qmake and CMake build system options. It was designed to drop the QtSql dependency while maintaining backward compatibility and without the need for any code changes after the swap.",keywords:["c++ orm","database","getting started","tinydrivers","sql drivers"]},sidebar:"tinyormSidebar",previous:{title:"Serialization",permalink:"/tinyorm/serialization"},next:{title:"TinyORM",permalink:"/building/tinyorm"}},a={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Features summary",id:"features-summary",level:5},{value:"Differences from QtSql",id:"differences-from-qtsql",level:2},{value:"Naming conventions",id:"naming-conventions",level:5},{value:"MySQL driver",id:"mysql-driver",level:5},{value:"Removed features",id:"removed-features",level:5},{value:"Missing features",id:"missing-features",level:5},{value:"Build system",id:"build-system",level:3},{value:"The Shared
library build",id:"the-shared-library-build",level:5},{value:"The Static
build",id:"the-static-build",level:5},{value:"The Loadable
SQL drivers build",id:"the-loadable-sql-drivers-build",level:5},{value:"CMake
/qmake
build options",id:"cmakeqmake-build-options",level:4},{value:"For CMake
",id:"for-cmake",level:5},{value:"For qmake
",id:"for-qmake",level:5},{value:"Performance",id:"performance",level:3},{value:"Internals",id:"internals",level:2},{value:"SqlDatabase",id:"sqldatabase",level:5},{value:"Namespaces",id:"namespaces",level:5},{value:"Documentation",id:"documentation",level:5}];function o(e){const i={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(i.h1,{id:"tinydrivers-getting-started",children:"TinyDrivers: Getting Started"}),"\n",(0,r.jsxs)(i.ul,{children:["\n",(0,r.jsx)(i.li,{children:(0,r.jsx)(i.a,{href:"#introduction",children:"Introduction"})}),"\n",(0,r.jsxs)(i.li,{children:[(0,r.jsx)(i.a,{href:"#differences-from-qtsql",children:"Differences from QtSql"}),"\n",(0,r.jsxs)(i.ul,{children:["\n",(0,r.jsx)(i.li,{children:(0,r.jsx)(i.a,{href:"#build-system",children:"Build system"})}),"\n",(0,r.jsx)(i.li,{children:(0,r.jsx)(i.a,{href:"#performance",children:"Performance"})}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(i.li,{children:(0,r.jsx)(i.a,{href:"#internals",children:"Internals"})}),"\n"]}),"\n",(0,r.jsx)(i.h2,{id:"introduction",children:"Introduction"}),"\n",(0,r.jsxs)(i.p,{children:["The ",(0,r.jsx)(i.code,{children:"TinyDrivers"})," library is an underlying SQL database layer for ",(0,r.jsx)(i.code,{children:"TinyORM"}),". It can be used instead of the ",(0,r.jsx)(i.code,{children:"QtSql"})," module, can be ",(0,r.jsx)("u",{children:(0,r.jsx)(i.strong,{children:"swapped"})})," at compile time, and has ",(0,r.jsx)(i.strong,{children:"1:1"})," API as the ",(0,r.jsx)(i.code,{children:"QtSql"})," module. \ud83d\ude2e Swapping is controlled by the ",(0,r.jsx)(i.code,{children:"qmake"})," and ",(0,r.jsx)(i.code,{children:"CMake"})," build system options."]}),"\n",(0,r.jsxs)(i.p,{children:["It was designed to drop the ",(0,r.jsx)(i.code,{children:"QtSql"})," dependency while maintaining backward compatibility and without the need for any code changes after the swap."]}),"\n",(0,r.jsx)(i.h5,{id:"features-summary",children:"Features summary"}),"\n",(0,r.jsxs)(i.ul,{children:["\n",(0,r.jsx)(i.li,{children:"both, normal and prepared statements are supported"}),"\n",(0,r.jsxs)(i.li,{children:["TLS/SSL connections using ",(0,r.jsx)(i.a,{href:"https://dev.mysql.com/doc/c-api/en/mysql-options.html",children:(0,r.jsx)(i.code,{children:"MYSQL_OPT_SSL_MODE"})})," (verify_ca, verify_identity) \ud83d\udd25"]}),"\n",(0,r.jsxs)(i.li,{children:["setting many other connection options (see ",(0,r.jsx)(i.a,{href:"https://github.com/silverqx/TinyORM/blob/main/drivers/mysql/src/orm/drivers/mysql/mysqldriver_p.cpp",children:(0,r.jsx)(i.code,{children:"mysqldriver_p.cpp"})}),")"]}),"\n",(0,r.jsxs)(i.li,{children:["building and linking against the ",(0,r.jsx)(i.a,{href:"https://mariadb.com/kb/en/mariadb-connector-c/",children:(0,r.jsx)(i.code,{children:"MariaDB Connector/C"})})]}),"\n",(0,r.jsx)(i.li,{children:"transactions"}),"\n",(0,r.jsxs)(i.li,{children:["re-using the current ",(0,r.jsx)(i.code,{children:"SqlQuery"})," instance to re-execute the same or another query"]}),"\n",(0,r.jsx)(i.li,{children:"detaching from the result set (associated to release memory)"}),"\n",(0,r.jsxs)(i.li,{children:["query size, number of affected rows, last inserted ID, testing ",(0,r.jsx)(i.code,{children:"isNull()"}),", ..."]}),"\n",(0,r.jsxs)(i.li,{children:["all ",(0,r.jsx)(i.strong,{children:"3366 unit tests"})," passed \ud83d\ude2e"]}),"\n"]}),"\n",(0,r.jsx)(i.admonition,{type:"info",children:(0,r.jsxs)(i.p,{children:["Currently, only the ",(0,r.jsx)(i.code,{children:"MySQL"})," database driver is supported and finished."]})}),"\n",(0,r.jsx)(i.admonition,{type:"info",children:(0,r.jsxs)(i.p,{children:[(0,r.jsx)(i.code,{children:"TinyDrivers"})," can only be built with ",(0,r.jsx)(i.code,{children:"Qt v6"}),", ",(0,r.jsx)(i.code,{children:"Qt v5.15"})," isn't supported."]})}),"\n",(0,r.jsx)(i.admonition,{type:"note",children:(0,r.jsxs)(i.p,{children:[(0,r.jsx)(i.code,{children:"TinyDrivers"})," library supports both build systems ",(0,r.jsx)(i.code,{children:"qmake"})," and also ",(0,r.jsx)(i.code,{children:"CMake"}),"."]})}),"\n",(0,r.jsx)(i.h2,{id:"differences-from-qtsql",children:"Differences from QtSql"}),"\n",(0,r.jsxs)(i.p,{children:[(0,r.jsx)(i.code,{children:"TinyDrivers"})," doesn't return errors the the same way as the ",(0,r.jsx)(i.code,{children:"QtSql"})," module, which means return a ",(0,r.jsx)(i.code,{children:"bool"})," and if it's the result ",(0,r.jsx)(i.code,{children:"false"})," then obtain the ",(0,r.jsx)(i.code,{children:"SqlError"})," instance using the ",(0,r.jsx)(i.code,{children:"lastError()"})," method from ",(0,r.jsx)(i.code,{children:"SqlDatabase"})," or ",(0,r.jsx)(i.code,{children:"SqlQuery"})," instances. Instead, it throws exceptions, and methods returning a ",(0,r.jsx)(i.code,{children:"bool"})," type to report an error state always return ",(0,r.jsx)(i.code,{children:"true"}),"."]}),"\n",(0,r.jsx)(i.h5,{id:"naming-conventions",children:"Naming conventions"}),"\n",(0,r.jsxs)(i.ul,{children:["\n",(0,r.jsxs)(i.li,{children:[(0,r.jsx)(i.code,{children:"QtSql"})," ",(0,r.jsx)("small",{children:"module"})," -> ",(0,r.jsx)(i.code,{children:"TinyDrivers"})," ",(0,r.jsx)("small",{children:"library"})]}),"\n",(0,r.jsxs)(i.li,{children:[(0,r.jsx)(i.code,{children:"QMYSQL"})," ",(0,r.jsx)("small",{children:"driver"})," -> ",(0,r.jsx)(i.code,{children:"TinyMySql"})," ",(0,r.jsx)("small",{children:"driver"})]}),"\n"]}),"\n",(0,r.jsx)(i.h5,{id:"mysql-driver",children:"MySQL driver"}),"\n",(0,r.jsxs)(i.p,{children:["The following describes the differences between ",(0,r.jsx)(i.code,{children:"QMYSQL"})," and ",(0,r.jsx)(i.code,{children:"TinyMySql"})," drivers."]}),"\n",(0,r.jsxs)(i.p,{children:["The ",(0,r.jsx)(i.code,{children:"QMYSQL"})," driver doesn't support setting ",(0,r.jsx)(i.code,{children:"MySQL"})," non-flag ",(0,r.jsx)(i.a,{href:"https://dev.mysql.com/doc/c-api/en/mysql-options.html",children:"connection options"})," like ",(0,r.jsx)(i.code,{children:"MYSQL_OPT_RECONNECT"})," without the value, it needs to be defined with value like ",(0,r.jsx)(i.code,{children:"=1"})," or ",(0,r.jsx)(i.code,{children:"=TRUE"})," (case-sensitive), only real flag options like ",(0,r.jsx)(i.code,{children:"CLIENT_INTERACTIVE"})," can be set without the value and ",(0,r.jsx)(i.code,{children:"="})," character."]}),"\n",(0,r.jsxs)(i.p,{children:["On the other hand, the ",(0,r.jsx)(i.code,{children:"TinyMySql"})," driver allows setting non-flag ",(0,r.jsx)(i.a,{href:"https://dev.mysql.com/doc/c-api/en/mysql-options.html",children:"connection options"})," options without the value and ",(0,r.jsx)(i.code,{children:"="})," character, which are considered enabled (ON or TRUE)."]}),"\n",(0,r.jsx)(i.h5,{id:"removed-features",children:"Removed features"}),"\n",(0,r.jsxs)(i.p,{children:["Simulation of prepared statements while calling ",(0,r.jsx)(i.code,{children:"SqlQuery::exec(QString)"}),", this functionality is useless because you can call regular prepared statements using ",(0,r.jsx)(i.code,{children:"SqlQuery::prepare(QString)"})," and then ",(0,r.jsx)(i.code,{children:"SqlQuery::exec()"}),"."]}),"\n",(0,r.jsx)(i.h5,{id:"missing-features",children:"Missing features"}),"\n",(0,r.jsxs)(i.p,{children:["Fetching multiple result sets using ",(0,r.jsx)(i.code,{children:"SqlQuery::nextResult()"}),". Multiple statement queries are supported they will be executed correctly (they can return multiple result sets), but only the first result set can be fetched currently. However, destroying multiple result sets is handled correctly."]}),"\n",(0,r.jsx)(i.h3,{id:"build-system",children:"Build system"}),"\n",(0,r.jsxs)(i.p,{children:["Another difference is that you can build the ",(0,r.jsx)(i.code,{children:"TinyDrivers"})," and its SQL drivers (",(0,r.jsx)(i.code,{children:"TinyMySql"}),") in 3 different ways; ",(0,r.jsx)(i.code,{children:"Shared"}),", ",(0,r.jsx)(i.code,{children:"Static"}),", and as a ",(0,r.jsx)(i.code,{children:"Loadable"})," library at runtime using ",(0,r.jsx)(i.code,{children:"LoadLibrary()"})," on Windows or ",(0,r.jsx)(i.code,{children:"dlopen()"})," on Linux."]}),"\n",(0,r.jsxs)(i.h5,{id:"the-shared-library-build",children:["The ",(0,r.jsx)(i.code,{children:"Shared"})," library build"]}),"\n",(0,r.jsxs)(i.p,{children:["It builds two shared libraries, the ",(0,r.jsx)(i.code,{children:"TinyDrivers"})," shared library that contains the core/common code and the ",(0,r.jsx)(i.code,{children:"TinyMySql"})," shared library that contains ",(0,r.jsx)(i.code,{children:"MySQL"})," implementation. The ",(0,r.jsx)(i.code,{children:"TinyOrm"})," links only against the ",(0,r.jsx)(i.code,{children:"TinyDrivers"})," shared library and ",(0,r.jsx)(i.code,{children:"TinyMySql"})," is a private implementation."]}),"\n",(0,r.jsxs)(i.h5,{id:"the-static-build",children:["The ",(0,r.jsx)(i.code,{children:"Static"})," build"]}),"\n",(0,r.jsxs)(i.p,{children:["It builds one ",(0,r.jsx)(i.code,{children:"TinyDrivers"})," static archive that contains the core/common code and SQL drivers (",(0,r.jsx)(i.code,{children:"TinyMySql"}),"). This static library is linked or merged into the ",(0,r.jsx)(i.code,{children:"TinyOrm"})," shared or static library (both variants are supported)."]}),"\n",(0,r.jsxs)(i.h5,{id:"the-loadable-sql-drivers-build",children:["The ",(0,r.jsx)(i.code,{children:"Loadable"})," SQL drivers build"]}),"\n",(0,r.jsxs)(i.p,{children:["It builds two shared libraries, the ",(0,r.jsx)(i.code,{children:"TinyDrivers"})," shared library that contains the core/common code and ",(0,r.jsx)(i.code,{children:"TinyMySql"})," shared library (module) that contains ",(0,r.jsx)(i.code,{children:"MySQL"})," implementation that is loaded at runtime using ",(0,r.jsx)(i.code,{children:"LoadLibrary()"})," on Windows or ",(0,r.jsx)(i.code,{children:"dlopen()"})," on Linux. The SQL driver library loader throws an exception if it cannot find this library at runtime."]}),"\n",(0,r.jsx)(i.admonition,{type:"info",children:(0,r.jsxs)(i.p,{children:["The ",(0,r.jsx)(i.code,{children:"TinyMySql"})," links directly against the ",(0,r.jsx)(i.code,{children:"MySQL C connector"})," (",(0,r.jsx)(i.code,{children:"libmysql"})," or ",(0,r.jsx)(i.code,{children:"mysqlclient"})," library)."]})}),"\n",(0,r.jsxs)(i.h4,{id:"cmakeqmake-build-options",children:[(0,r.jsx)(i.code,{children:"CMake"}),"/",(0,r.jsx)(i.code,{children:"qmake"})," build options"]}),"\n",(0,r.jsxs)(i.h5,{id:"for-cmake",children:["For ",(0,r.jsx)(i.code,{children:"CMake"})]}),"\n",(0,r.jsxs)(i.p,{children:["See ",(0,r.jsx)(i.a,{href:"/building/tinyorm#cmake-build-options",children:"CMake build options"}),", related ",(0,r.jsx)(i.code,{children:"CMake"})," build options are:",(0,r.jsx)("br",{}),(0,r.jsx)(i.a,{href:"/building/tinyorm#BUILD_DRIVERS",children:(0,r.jsx)(i.code,{children:"BUILD_DRIVERS"})}),", ",(0,r.jsx)(i.a,{href:"/building/tinyorm#BUILD_MYSQL_DRIVER",children:(0,r.jsx)(i.code,{children:"BUILD_MYSQL_DRIVER"})}),", and ",(0,r.jsx)(i.a,{href:"/building/tinyorm#DRIVERS_TYPE",children:(0,r.jsx)(i.code,{children:"DRIVERS_TYPE"})})]}),"\n",(0,r.jsxs)(i.p,{children:["To control shared and static build use ",(0,r.jsx)(i.a,{href:"https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html",children:(0,r.jsx)(i.code,{children:"BUILD_SHARED_LIBS"})})," ",(0,r.jsx)(i.code,{children:"CMake"})," configuration option."]}),"\n",(0,r.jsxs)(i.h5,{id:"for-qmake",children:["For ",(0,r.jsx)(i.code,{children:"qmake"})]}),"\n",(0,r.jsxs)(i.p,{children:["See ",(0,r.jsx)(i.a,{href:"/building/tinyorm#qmake-build-options",children:"qmake build options"}),", related ",(0,r.jsx)(i.code,{children:"qmake"})," configuration options are:",(0,r.jsx)("br",{}),(0,r.jsx)(i.a,{href:"/building/tinyorm#build_loadable_drivers",children:(0,r.jsx)(i.code,{children:"build_loadable_drivers"})}),", ",(0,r.jsx)(i.a,{href:"/building/tinyorm#build_mysql_driver",children:(0,r.jsx)(i.code,{children:"build_mysql_driver"})}),", ",(0,r.jsx)(i.a,{href:"/building/tinyorm#build_shared_drivers",children:(0,r.jsx)(i.code,{children:"build_shared_drivers"})}),", and ",(0,r.jsx)(i.a,{href:"/building/tinyorm#build_static_drivers",children:(0,r.jsx)(i.code,{children:"build_static_drivers"})})]}),"\n",(0,r.jsxs)(i.p,{children:["To control shared and static build use ",(0,r.jsx)(i.a,{href:"/building/tinyorm#qmake-static",children:(0,r.jsx)(i.code,{children:"static"})})," ",(0,r.jsx)(i.code,{children:"qmake"})," ",(0,r.jsx)(i.a,{href:"https://doc.qt.io/qt/qmake-variable-reference.html#config",children:"configuration option"}),"."]}),"\n",(0,r.jsx)(i.h3,{id:"performance",children:"Performance"}),"\n",(0,r.jsxs)(i.p,{children:["Performance is several milliseconds faster compared to ",(0,r.jsx)(i.code,{children:"QtSql"})," with the ",(0,r.jsx)(i.code,{children:"QMYSQL"})," driver. It was tuned using the ",(0,r.jsx)(i.code,{children:"KCacheGrind"})," to be so. It's ~40ms faster on ",(0,r.jsx)(i.a,{href:"https://github.com/silverqx/TinyOrmPlayground",children:(0,r.jsx)(i.code,{children:"TinyOrmPlayground"})})," project with ",(0,r.jsx)(i.strong,{children:"620"})," database queries compiled using ",(0,r.jsx)(i.code,{children:"GCC v13.2.1"})," Debug build on Linux. Similar results can be expected on other platforms but it's not guaranteed."]}),"\n",(0,r.jsxs)(i.p,{children:["This means performance is very similar to ",(0,r.jsx)(i.code,{children:"QtSql"}),". There is not much to speed up because ",(0,r.jsx)(i.code,{children:"TinyDrivers"})," code is swift and 90% of the time is spent inside the ",(0,r.jsx)(i.a,{href:"https://dev.mysql.com/doc/c-api/en/",children:(0,r.jsx)(i.code,{children:"MySQL C API"})})," because we always have to wait for the database server, especially when creating database connections using eg. ",(0,r.jsx)(i.a,{href:"https://dev.mysql.com/doc/c-api/en/mysql-real-connect.html",children:(0,r.jsx)(i.code,{children:"mysql_real_connect()"})})," (this function is king among the slowest functions \ud83d\ude0e, which is understandable of course)."]}),"\n",(0,r.jsx)(i.h2,{id:"internals",children:"Internals"}),"\n",(0,r.jsxs)(i.p,{children:[(0,r.jsx)(i.code,{children:"TinyDrivers"})," internal design can be divided into 3 different layers:"]}),"\n",(0,r.jsxs)(i.ul,{children:["\n",(0,r.jsx)(i.li,{children:"Driver layer"}),"\n",(0,r.jsx)(i.li,{children:"SQL API layer"}),"\n",(0,r.jsx)(i.li,{children:"Public API layer"}),"\n"]}),"\n",(0,r.jsxs)(i.p,{children:["The Driver layer is eg. ",(0,r.jsx)(i.code,{children:"TinyMySql"})," library which is responsible for communicating with the underlying database driver (eg. ",(0,r.jsx)(i.a,{href:"https://dev.mysql.com/doc/c-api/en/",children:(0,r.jsx)(i.code,{children:"MySQL C API"})}),")."]}),"\n",(0,r.jsx)(i.p,{children:"The SQL API layer is a semi-layer that glues everything up and sits between the Public interface API and the Driver layer."}),"\n",(0,r.jsxs)(i.p,{children:["The Public interface API layer are the end classes like ",(0,r.jsx)(i.code,{children:"SqlDatabase"})," and ",(0,r.jsx)(i.code,{children:"SqlQuery"})," which are exposed to the end user."]}),"\n",(0,r.jsx)(i.h5,{id:"sqldatabase",children:"SqlDatabase"}),"\n",(0,r.jsxs)(i.p,{children:["One more thing worth mentioning is the ",(0,r.jsx)(i.code,{children:"SqlDatabase"})," API. It's one class that has two responsibilities! All static methods act as the database connection manager and an instance of the ",(0,r.jsx)(i.code,{children:"SqlDatabase"})," represents a physical database connection. It's not a good design because it breaks the ",(0,r.jsx)(i.a,{href:"https://en.wikipedia.org/wiki/Single_responsibility_principle",children:"Single Responsibility principle"}),", but it's what it is."]}),"\n",(0,r.jsx)(i.h5,{id:"namespaces",children:"Namespaces"}),"\n",(0,r.jsxs)(i.p,{children:[(0,r.jsx)(i.code,{children:"TinyDrivers"})," classes are defined in the ",(0,r.jsx)(i.code,{children:"Orm::Drivers"})," namespace and ",(0,r.jsx)(i.code,{children:"TinyMySql"})," classes in the ",(0,r.jsx)(i.code,{children:"Orm::Drivers::MySql"})," namespace."]}),"\n",(0,r.jsx)(i.h5,{id:"documentation",children:"Documentation"}),"\n",(0,r.jsxs)(i.p,{children:["For all other APIs you can follow the ",(0,r.jsx)(i.a,{href:"https://doc.qt.io/qt/qtsql-index.html",children:"QtSql documentation"})," as the API is 1:1. The exception is of course the build system, ",(0,r.jsx)(i.code,{children:"TinyOrm"})," has its own build system that doesn't follow the ",(0,r.jsx)(i.code,{children:"QtSql"})," module."]})]})}function h(e={}){const{wrapper:i}={...(0,s.R)(),...e.components};return i?(0,r.jsx)(i,{...e,children:(0,r.jsx)(o,{...e})}):o(e)}},8453:(e,i,n)=>{n.d(i,{R:()=>t,x:()=>l});var r=n(6540);const s={},d=r.createContext(s);function t(e){const i=r.useContext(d);return r.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function l(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:t(e.components),r.createElement(d.Provider,{value:i},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/e3ac21cb.3a5ccd42.js b/assets/js/e3ac21cb.3a5ccd42.js
new file mode 100644
index 000000000..65dabe815
--- /dev/null
+++ b/assets/js/e3ac21cb.3a5ccd42.js
@@ -0,0 +1 @@
+"use strict";(self.webpackChunktinyorm_org=self.webpackChunktinyorm_org||[]).push([[467],{7759:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>p,frontMatter:()=>d,metadata:()=>o,toc:()=>c});var r=t(4848),i=t(8453),s=t(8774);const d={sidebar_position:1,sidebar_label:"\ud83d\udd27 Dependencies",hide_table_of_contents:!0,description:"Library dependencies are MySQL Connector/C 8, range-v3 >=0.11.0, tabulate and the Qt framework version used during development was 5.15.2 and >=6.2. The code was developed on MSVC 16.9-16.11, MSVC 17.2-17.9, GCC 10.2-14.1, and Clang 11-16.",keywords:["c++ orm","dependencies","tinyorm"]},a="Dependencies",o={id:"dependencies",title:"Dependencies",description:"Library dependencies are MySQL Connector/C 8, range-v3 >=0.11.0, tabulate and the Qt framework version used during development was 5.15.2 and >=6.2. The code was developed on MSVC 16.9-16.11, MSVC 17.2-17.9, GCC 10.2-14.1, and Clang 11-16.",source:"@site/docs/dependencies.mdx",sourceDirName:".",slug:"/dependencies",permalink:"/dependencies",draft:!1,unlisted:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1,sidebar_label:"\ud83d\udd27 Dependencies",hide_table_of_contents:!0,description:"Library dependencies are MySQL Connector/C 8, range-v3 >=0.11.0, tabulate and the Qt framework version used during development was 5.15.2 and >=6.2. The code was developed on MSVC 16.9-16.11, MSVC 17.2-17.9, GCC 10.2-14.1, and Clang 11-16.",keywords:["c++ orm","dependencies","tinyorm"]},sidebar:"tinyormSidebar",previous:{title:"\ud83d\udd25 Prologue",permalink:"/"},next:{title:"\ud83d\ude80 Supported Compilers",permalink:"/supported-compilers"}},l={},c=[{value:"Required",id:"required",level:5},{value:"Optional",id:"optional",level:5},{value:"Install dependencies",id:"install-dependencies",level:3}];function h(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h3:"h3",h5:"h5",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"dependencies",children:"Dependencies"}),"\n",(0,r.jsx)(n.p,{children:"The code was developed on MSVC 16.9-16.11, MSVC 17.2-17.9, GCC 10.2-14.1, and Clang 11-18, so may be assumed it will work on future releases of these compilers. Minimum required ISO C++ standard is C++20.\nThe Qt framework version used during development was 5.15.2 and >=6.2."}),"\n",(0,r.jsx)(n.h5,{id:"required",children:"Required"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"minimum ISO C++ standard is C++20"}),"\n",(0,r.jsxs)(n.li,{children:[">= ",(0,r.jsx)(n.a,{href:"https://www.qt.io/download-qt-installer",children:"Qt Framework 5.15.2"})," - ",(0,r.jsx)(n.a,{href:"https://doc.qt.io/qt-5/qtcore-module.html",children:(0,r.jsx)(n.code,{children:"QtCore"})})," and ",(0,r.jsx)(n.a,{href:"https://doc.qt.io/qt-5/qtsql-index.html",children:(0,r.jsx)(n.code,{children:"QtSql"})})," modules"]}),"\n",(0,r.jsxs)(n.li,{children:[">= ",(0,r.jsx)(n.a,{href:"https://www.qt.io/download-qt-installer",children:"Qt Framework 6.2"})," - ",(0,r.jsx)(n.a,{href:"https://doc.qt.io/qt-6/qtcore-module.html",children:(0,r.jsx)(n.code,{children:"QtCore"})})," and ",(0,r.jsx)(n.a,{href:"https://doc.qt.io/qt-6/qtsql-index.html",children:(0,r.jsx)(n.code,{children:"QtSql"})})," modules"]}),"\n",(0,r.jsxs)(n.li,{children:[">= ",(0,r.jsx)(n.a,{href:"https://github.com/ericniebler/range-v3",children:"range-v3 0.11.0"})]}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://github.com/p-ranav/tabulate",children:"tabulate"})}),"\n"]}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsxs)(n.p,{children:["Be aware that the standard support for the last release of the ",(0,r.jsx)(n.strong,{children:"Qt 5"})," series ended on ",(0,r.jsx)(n.strong,{children:"26. May 2023"}),". [",(0,r.jsx)(n.a,{href:"https://endoflife.date/qt",children:"1"}),"][",(0,r.jsx)(n.a,{href:"https://www.qt.io/blog/qt-5.15-support-ends",children:"2"}),"]"]})}),"\n",(0,r.jsx)(n.h5,{id:"optional",children:"Optional"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[">= ",(0,r.jsx)(n.a,{href:"https://dev.mysql.com/downloads/c-api/",children:"MySQL Connector/C 8"})," - used only for the ",(0,r.jsx)(n.a,{href:"https://dev.mysql.com/doc/c-api/8.3/en/mysql-ping.html",children:(0,r.jsx)(n.code,{children:"mysql_ping"})})," function and provided by ",(0,r.jsx)(n.a,{href:"https://dev.mysql.com/downloads/mysql/",children:"MySQL 8 Server"})]}),"\n"]}),"\n",(0,r.jsx)(n.admonition,{type:"info",children:(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"TinyORM"})," will support ",(0,r.jsx)(n.code,{children:"Qt"})," versions that aren't ",(0,r.jsx)(n.a,{href:"https://endoflife.date/qt",children:"end-of-life"}),"."]})}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["You can view the supported database servers in the ",(0,r.jsx)(n.a,{href:"/database/getting-started#introduction",children:"Database - Getting Started"})," section."]})}),"\n",(0,r.jsx)(n.h3,{id:"install-dependencies",children:"Install dependencies"}),"\n",(0,r.jsxs)(n.p,{children:["On ",(0,r.jsx)(n.code,{children:"Linux"}),", you can install dependencies with the package manager."]}),"\n",(0,r.jsxs)("small",{children:[(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-text",metastring:"title='MySQL C library'",children:"Arch - pacman -S mariadb-libs\nGentoo - emerge dev-db/mysql (package.use: -server -perl)\nUbuntu - apt install libmysqlclient-dev\n"})}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-text",metastring:"title='range-v3 library (header only)'",children:"Arch - pacman -S range-v3\nGentoo - emerge dev-cpp/range-v3\nUbuntu - apt install librange-v3-dev\n"})}),(0,r.jsx)(s.A,{id:"linux-installation-ccache"}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-text",metastring:"title='ccache'",children:"Arch - pacman -S ccache\nGentoo - emerge dev-util/ccache\nUbuntu - apt install ccache\n"})})]})]})}function p(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>d,x:()=>a});var r=t(6540);const i={},s=r.createContext(i);function d(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/e3ac21cb.4453d725.js b/assets/js/e3ac21cb.4453d725.js
deleted file mode 100644
index 59eb89187..000000000
--- a/assets/js/e3ac21cb.4453d725.js
+++ /dev/null
@@ -1 +0,0 @@
-"use strict";(self.webpackChunktinyorm_org=self.webpackChunktinyorm_org||[]).push([[467],{7759:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var r=t(4848),d=t(8453);const i={sidebar_position:1,sidebar_label:"\ud83d\udd27 Dependencies",hide_table_of_contents:!0,description:"Library dependencies are MySQL Connector/C 8, range-v3 >=0.11.0, tabulate and the Qt framework version used during development was 5.15.2 and >=6.2. The code was developed on MSVC 16.9-16.11, MSVC 17.2-17.9, GCC 10.2-14.1, and Clang 11-16.",keywords:["c++ orm","dependencies","tinyorm"]},s="Dependencies",a={id:"dependencies",title:"Dependencies",description:"Library dependencies are MySQL Connector/C 8, range-v3 >=0.11.0, tabulate and the Qt framework version used during development was 5.15.2 and >=6.2. The code was developed on MSVC 16.9-16.11, MSVC 17.2-17.9, GCC 10.2-14.1, and Clang 11-16.",source:"@site/docs/dependencies.mdx",sourceDirName:".",slug:"/dependencies",permalink:"/dependencies",draft:!1,unlisted:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1,sidebar_label:"\ud83d\udd27 Dependencies",hide_table_of_contents:!0,description:"Library dependencies are MySQL Connector/C 8, range-v3 >=0.11.0, tabulate and the Qt framework version used during development was 5.15.2 and >=6.2. The code was developed on MSVC 16.9-16.11, MSVC 17.2-17.9, GCC 10.2-14.1, and Clang 11-16.",keywords:["c++ orm","dependencies","tinyorm"]},sidebar:"tinyormSidebar",previous:{title:"\ud83d\udd25 Prologue",permalink:"/"},next:{title:"\ud83d\ude80 Supported Compilers",permalink:"/supported-compilers"}},o={},l=[{value:"Required",id:"required",level:5},{value:"Optional",id:"optional",level:5},{value:"Install dependencies",id:"install-dependencies",level:3}];function c(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h3:"h3",h5:"h5",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,d.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"dependencies",children:"Dependencies"}),"\n",(0,r.jsx)(n.p,{children:"The code was developed on MSVC 16.9-16.11, MSVC 17.2-17.9, GCC 10.2-14.1, and Clang 11-18, so may be assumed it will work on future releases of these compilers. Minimum required ISO C++ standard is C++20.\nThe Qt framework version used during development was 5.15.2 and >=6.2."}),"\n",(0,r.jsx)(n.h5,{id:"required",children:"Required"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"minimum ISO C++ standard is C++20"}),"\n",(0,r.jsxs)(n.li,{children:[">= ",(0,r.jsx)(n.a,{href:"https://www.qt.io/download-qt-installer",children:"Qt Framework 5.15.2"})," - ",(0,r.jsx)(n.a,{href:"https://doc.qt.io/qt-5/qtcore-module.html",children:(0,r.jsx)(n.code,{children:"QtCore"})})," and ",(0,r.jsx)(n.a,{href:"https://doc.qt.io/qt-5/qtsql-index.html",children:(0,r.jsx)(n.code,{children:"QtSql"})})," modules"]}),"\n",(0,r.jsxs)(n.li,{children:[">= ",(0,r.jsx)(n.a,{href:"https://www.qt.io/download-qt-installer",children:"Qt Framework 6.2"})," - ",(0,r.jsx)(n.a,{href:"https://doc.qt.io/qt-6/qtcore-module.html",children:(0,r.jsx)(n.code,{children:"QtCore"})})," and ",(0,r.jsx)(n.a,{href:"https://doc.qt.io/qt-6/qtsql-index.html",children:(0,r.jsx)(n.code,{children:"QtSql"})})," modules"]}),"\n",(0,r.jsxs)(n.li,{children:[">= ",(0,r.jsx)(n.a,{href:"https://github.com/ericniebler/range-v3",children:"range-v3 0.11.0"})]}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://github.com/p-ranav/tabulate",children:"tabulate"})}),"\n"]}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsxs)(n.p,{children:["Be aware that the standard support for the last release of the ",(0,r.jsx)(n.strong,{children:"Qt 5"})," series ended on ",(0,r.jsx)(n.strong,{children:"26. May 2023"}),". [",(0,r.jsx)(n.a,{href:"https://endoflife.date/qt",children:"1"}),"][",(0,r.jsx)(n.a,{href:"https://www.qt.io/blog/qt-5.15-support-ends",children:"2"}),"]"]})}),"\n",(0,r.jsx)(n.h5,{id:"optional",children:"Optional"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[">= ",(0,r.jsx)(n.a,{href:"https://dev.mysql.com/downloads/c-api/",children:"MySQL Connector/C 8"})," - used only for the ",(0,r.jsx)(n.a,{href:"https://dev.mysql.com/doc/c-api/8.3/en/mysql-ping.html",children:(0,r.jsx)(n.code,{children:"mysql_ping"})})," function and provided by ",(0,r.jsx)(n.a,{href:"https://dev.mysql.com/downloads/mysql/",children:"MySQL 8 Server"})]}),"\n"]}),"\n",(0,r.jsx)(n.admonition,{type:"info",children:(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"TinyORM"})," will support ",(0,r.jsx)(n.code,{children:"Qt"})," versions that aren't ",(0,r.jsx)(n.a,{href:"https://endoflife.date/qt",children:"end-of-life"}),"."]})}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["You can view the supported database servers in the ",(0,r.jsx)(n.a,{href:"/database/getting-started#introduction",children:"Database - Getting Started"})," section."]})}),"\n",(0,r.jsx)(n.h3,{id:"install-dependencies",children:"Install dependencies"}),"\n",(0,r.jsxs)(n.p,{children:["On ",(0,r.jsx)(n.code,{children:"Linux"}),", you can install dependencies with the package manager."]}),"\n",(0,r.jsxs)("small",{children:[(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-text",metastring:"title='MySQL C library'",children:"Arch - pacman -S mariadb-libs\nGentoo - emerge dev-db/mysql (package.use: -server -perl)\nUbuntu - apt install libmysqlclient-dev\n"})}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-text",metastring:"title='range-v3 library (header only)'",children:"Arch - pacman -S range-v3\nGentoo - emerge dev-cpp/range-v3\nUbuntu - apt install librange-v3-dev\n"})}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-text",metastring:"title='ccache'",children:"Arch - pacman -S ccache\nGentoo - emerge dev-util/ccache\nUbuntu - apt install ccache\n"})})]})]})}function h(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>a});var r=t(6540);const d={},i=r.createContext(d);function s(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:s(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]);
\ No newline at end of file
diff --git a/assets/js/runtime~main.d99c90e6.js b/assets/js/runtime~main.503b8af3.js
similarity index 95%
rename from assets/js/runtime~main.d99c90e6.js
rename to assets/js/runtime~main.503b8af3.js
index e96bcc221..28542050e 100644
--- a/assets/js/runtime~main.d99c90e6.js
+++ b/assets/js/runtime~main.503b8af3.js
@@ -1 +1 @@
-(()=>{"use strict";var e,a,t,r,o,n={},f={};function c(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,c),t.exports}c.m=n,e=[],c.O=(a,t,r,o)=>{if(!t){var n=1/0;for(i=0;iIn the CMake
build system, all the C macros are auto-detected / auto-configured or controlled by CMake build options
, so you don't have to care too much about them.
In the qmake
build is important whether you are building TinyORM
library or you are building your application and linking against TinyORM
library. When you are building the TinyORM
library, all the C macros are auto-detected / auto-configured or controlled by qmake build options
, so you don't have to care too much about them.
But a special situation is when you are building your application / library and you are linking against TinyORM
library. In this particular case, you must configure all these C macros manually! For this reason, the TinyOrm.pri
has been created, so that's not a big deal either. Little more info here.
C Macro Name | Description |
---|---|
TINYORM_LINKING_SHARED | Must be defined when you are linking against TinyORM shared build (dll library), exported classes and functions will be tagged with __declspec(dllimport) on msvc and visibility("default") on GCC >= 4 . |
TINYORM_BUILDING_SHARED | Defined when TinyORM is built as a dll library (shared build). |
TINYORM_DEBUG | Defined in the debug build. |
TINYORM_NO_DEBUG | Defined in the release build. |
TINYORM_DEBUG_SQL | Defined in the debug build. |
TINYORM_NO_DEBUG_SQL | Defined in the release build. |
TINYORM_MYSQL_PING | Enable Orm::MySqlConnection::pingDatabase() method.Defined when mysql_ping (qmake) / MYSQL_PING (cmake) configuration build option is enabled. |
TINYORM_DISABLE_ORM | Controls the compilation of all ORM-related source code, when this macro is defined , then only the query builder without ORM is compiled. Also excludes ORM-related unit tests.Defined when disable_orm (qmake) / ORM (cmake) configuration build option is enabled (qmake) / disabled (cmake). |
TINYORM_EXTERN_CONSTANTS | Defined when extern constants are used. Extern constants are enabled by default for shared builds and disabled for static builds. Described at qmake / CMake how it works. |
TINYORM_INLINE_CONSTANTS | Defined when global inline constants are used. Defined when inline_constants (qmake) / INLINE_CONSTANTS (cmake) configuration build option is enabled. |
TINYORM_TESTS_CODE | Enable code needed by unit tests, eg. connection overriding in the Orm::Tiny::Model .Defined when build_tests (qmake) / BUILD_TESTS (cmake) configuration build option is enabled. |
TINYORM_DISABLE_THREAD_LOCAL | Remove all thread_local storage duration specifiers, it disables multi-threading support.Defined when disable_thread_local (qmake) / DISABLE_THREAD_LOCAL (cmake) configuration build option is enabled. |
TINYTOM_MIGRATIONS_DIR | Default migrations path for the make:migration command, can be an absolute or relative path (to the pwd).Default value: database/migrations (relative to the pwd)Defined by TOM_MIGRATIONS_DIR (cmake) configuration build option.(qmake note) You can use DEFINES += TINYTOM_MIGRATIONS_DIR="\"database/migrations\"" on the command-line or set it in the main conf.pri file. |
TINYTOM_MODELS_DIR | Default models path for the make:model command, can be an absolute or relative path (to the pwd).Default value: database/models (relative to the pwd)Defined by TOM_MODELS_DIR (cmake) configuration build option.(qmake note) You can use DEFINES += TINYTOM_MODELS_DIR="\"database/models\"" on the command-line or set it in the main conf.pri file. |
TINYTOM_SEEDERS_DIR | Default seeders path for the make:seeder command, can be an absolute or relative path (to the pwd).Default value: database/seeders (relative to the pwd)Defined by TOM_SEEDERS_DIR (cmake) configuration build option.(qmake note) You can use DEFINES += TINYTOM_SEEDERS_DIR="\"database/seeders\"" on the command-line or set it in the main conf.pri file. |
TINYORM_USING_PCH | Defined if building with precompiled headers. Controlled by qmake / CMake . |
C Macro Name | Description |
---|---|
TINYORM_LINKING_SHARED | Must be defined when you are linking against TinyORM shared build (dll library), exported classes and functions will be tagged with __declspec(dllimport) on msvc and visibility("default") on GCC >= 4 . |
TINYORM_BUILDING_SHARED | Defined when TinyORM is built as a dll library (shared build). |
TINYORM_DEBUG | Defined in the debug build. |
TINYORM_NO_DEBUG | Defined in the release build. |
TINYORM_DEBUG_SQL | Defined in the debug build. |
TINYORM_NO_DEBUG_SQL | Defined in the release build. |
TINYORM_MYSQL_PING | Enable Orm::MySqlConnection::pingDatabase() method.Defined when mysql_ping (qmake) / MYSQL_PING (cmake) configuration build option is enabled. |
TINYORM_DISABLE_ORM | Controls the compilation of all ORM-related source code, when this macro is defined , then only the query builder without ORM is compiled. Also excludes ORM-related unit tests.Defined when disable_orm (qmake) / ORM (cmake) configuration build option is enabled (qmake) / disabled (cmake). |
TINYORM_EXTERN_CONSTANTS | Defined when extern constants are used. Extern constants are enabled by default for shared builds and disabled for static builds. Described at qmake / CMake how it works. |
TINYORM_INLINE_CONSTANTS | Defined when global inline constants are used. Defined when inline_constants (qmake) / INLINE_CONSTANTS (cmake) configuration build option is enabled. |
TINYORM_TESTS_CODE | Enable code needed by unit tests, eg. connection overriding in the Orm::Tiny::Model .Defined when build_tests (qmake) / BUILD_TESTS (cmake) configuration build option is enabled. |
TINYORM_DISABLE_THREAD_LOCAL | Remove all thread_local storage duration specifiers, it disables multi-threading support.Defined when disable_thread_local (qmake) / DISABLE_THREAD_LOCAL (cmake) configuration build option is enabled. |
TINYTOM_MIGRATIONS_DIR | Default migrations path for the make:migration command, can be an absolute or relative path (to the pwd).Default value: database/migrations (relative to the pwd)Defined by TOM_MIGRATIONS_DIR (cmake) configuration build option.(qmake note) You can use DEFINES += TINYTOM_MIGRATIONS_DIR="\"database/migrations\"" on the command-line or set it in the main conf.pri file. |
TINYTOM_MODELS_DIR | Default models path for the make:model command, can be an absolute or relative path (to the pwd).Default value: database/models (relative to the pwd)Defined by TOM_MODELS_DIR (cmake) configuration build option.(qmake note) You can use DEFINES += TINYTOM_MODELS_DIR="\"database/models\"" on the command-line or set it in the main conf.pri file. |
TINYTOM_SEEDERS_DIR | Default seeders path for the make:seeder command, can be an absolute or relative path (to the pwd).Default value: database/seeders (relative to the pwd)Defined by TOM_SEEDERS_DIR (cmake) configuration build option.(qmake note) You can use DEFINES += TINYTOM_SEEDERS_DIR="\"database/seeders\"" on the command-line or set it in the main conf.pri file. |
TINYORM_USING_PCH | Defined if building with precompiled headers. Controlled by qmake / CMake . |
If something is not clear, you can still look at GitHub Action workflows
how a building is done.
First, create a basic folder structure and then clone the TinyORM
project.
Everything is ready for build, you can press Ctrl+b to build the project.
Advanced TinyORM
options.
Important qmake
options.
The TinyOrm.pri
file is available to simplify the integration of the TinyORM
library into your application. It sets up and configures the CONFIG
and DEFINES
qmake variables, adds the TinyORM
, tom
, and vcpkg
header files on the system INCLUDEPATH
(cross-platform using the -isystem
or -imsvc
), links against the TinyORM shared
or static
library using the LIBS
.
You can use it to configure the TinyORM
library when you are linking against it. It does a very similar thing like the CMake's Find Modules
feature.
The TinyORM supports the ccache
out of the box for all supported compilers. For qmake you can enable it using the CONFIG+=ccache
on Linux or CONFIG+=tiny_ccache_win32
on Windows. For CMake you can set the CMAKE_CXX_COMPILER_LAUNCHER=ccache
.
On Linux
it's clear, the ccache is fully supported and works also with the precompiled headers
. But was necessary to add some workarounds to the qmake
/CMake
build systems to make out of the box support on Windows
. When you enable the ccache
on Windows
then the build system disables precompiled headers
and replaces the -Zi
compiler option with the -Z7
(link to the issue).
You can install the ccache using the scoop install ccache
command on Windows.
The TinyORM supports the ccache
out of the box for all supported compilers. For qmake
you can enable it using the CONFIG+=ccache
and for CMake
you can set the CMAKE_CXX_COMPILER_LAUNCHER=ccache
.
On Linux
it's clear, the ccache
is fully supported and works also with the precompiled headers
. But was necessary to add some workarounds to the qmake
/CMake
build systems to make out of the box support on Windows
. When you enable the ccache
on Windows
then the build system disables precompiled headers
and replaces the -Zi
compiler option with the -Z7
(link to the issue).
You can install the ccache
using the scoop install ccache
command on Windows. See the Dependencies page for how to install ccache
on Linux.