Skip to content

Commit 63f0800

Browse files
authored
Fixci (#72)
1 parent 9417dc7 commit 63f0800

17 files changed

Lines changed: 265 additions & 106 deletions

.github/copilot-instructions.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Copilot Instructions
2+
3+
## C++ coroutine lambdas — NEVER use captures
4+
5+
Lambda-coroutines (`[](...) -> ACoroTerminator { co_await ...; }`) must have an
6+
**empty capture list `[]`**. The lambda's closure object is a temporary that is
7+
destroyed at the first `co_await` suspension point. Any captured variable then
8+
becomes a dangling reference inside the coroutine frame, causing undefined
9+
behaviour and hard-to-reproduce crashes.
10+
11+
**Forbidden:**
12+
```cpp
13+
[this, finished, value]() -> ACoroTerminator {
14+
auto result = co_await APool::exec(...);
15+
// 'this', 'finished', 'value' are dangling here
16+
}();
17+
```
18+
19+
**Required — pass everything as named parameters:**
20+
```cpp
21+
[](MyClass *self, std::shared_ptr<QObject> finished, int value) -> ACoroTerminator {
22+
auto result = co_await APool::exec(...); // parameters live in the coroutine frame
23+
}(this, finished, value);
24+
```
25+
26+
Parameters are stored directly in the coroutine frame and remain valid for the
27+
entire lifetime of the coroutine.
28+
29+
The same rule applies to named lambda variables that are called immediately or
30+
stored and invoked later — no captures of any kind on any lambda that contains
31+
a `co_await` or `co_yield` expression.
32+
33+
Note: inner non-coroutine lambdas (e.g. `qScopeGuard([finished] {})`) are not
34+
coroutines and may capture normally.

.github/workflows/build.yml

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,18 @@ jobs:
1818
- windows-latest
1919
- macos-latest
2020
config:
21-
- qt_version: "6.4.2"
21+
- qt_version: "6.5.3"
2222
include:
2323
# Two Linux builds: one against libmysqlclient (MySQL 8+) and one
2424
# against libmariadb (MariaDB Connector/C) to catch type-mismatch
2525
# errors like the my_bool*/bool* incompatibility.
2626
- os: ubuntu-latest
2727
config:
28-
qt_version: "6.4.2"
28+
qt_version: "6.5.3"
2929
mysql_lib: libmysqlclient-dev
3030
- os: ubuntu-latest
3131
config:
32-
qt_version: "6.4.2"
32+
qt_version: "6.11.0"
3333
mysql_lib: libmariadb-dev
3434

3535
steps:
@@ -49,15 +49,62 @@ jobs:
4949
fi
5050
sudo apt install -y ${{ matrix.mysql_lib }}
5151
52+
# ── PostgreSQL ────────────────────────────────────────────────────
53+
sudo systemctl start postgresql.service
54+
# Create a superuser role matching the runner OS user so that
55+
# postgresql:/// (peer-auth, db == username) works without a password.
56+
sudo -u postgres createuser --superuser "$USER"
57+
createdb # creates database named after $USER
58+
echo "ASQL_PG_TEST_DB=postgresql:///" >> "$GITHUB_ENV"
59+
60+
# ── MySQL / MariaDB ───────────────────────────────────────────────
61+
# GitHub-hosted Ubuntu runners ship MySQL with root/root credentials.
62+
sudo systemctl start mysql.service
63+
mysql -u root -proot -e "CREATE DATABASE IF NOT EXISTS asql_test;"
64+
mysql -u root -proot -e \
65+
"CREATE USER IF NOT EXISTS 'asql'@'localhost' IDENTIFIED BY 'asql';"
66+
mysql -u root -proot -e \
67+
"GRANT ALL PRIVILEGES ON asql_test.* TO 'asql'@'localhost'; FLUSH PRIVILEGES;"
68+
echo "ASQL_MYSQL_TEST_DB=mysql://asql:asql@localhost/asql_test" >> "$GITHUB_ENV"
69+
5270
- name: Install dependencies on macOS
5371
if: runner.os == 'macOS'
5472
run: |
5573
brew install postgresql@16
74+
brew services start postgresql@16
75+
# Wait until the server accepts connections
76+
until pg_isready --host=localhost --port=5432; do sleep 1; done
77+
# Ensure a database exists for the runner user (required for postgresql:///)
78+
createdb || true
5679
57-
- name: Install PostgreSQL 16 with Chocolatey
80+
- name: Set up PostgreSQL on Windows
5881
if: runner.os == 'Windows'
82+
shell: pwsh
5983
run: |
60-
choco install postgresql --version=16.0 -y
84+
# PostgreSQL is pre-installed on windows-latest but stopped/disabled.
85+
# Find whichever version's service is present (14, 15, 16, ...).
86+
$pgSvc = Get-Service -Name "postgresql-x64-*" -ErrorAction SilentlyContinue |
87+
Select-Object -First 1
88+
if (-not $pgSvc) {
89+
Write-Error "No postgresql-x64-* service found on this runner."
90+
exit 1
91+
}
92+
Write-Host "Found service: $($pgSvc.Name)"
93+
Set-Service -Name $pgSvc.Name -StartupType Automatic
94+
Start-Service -Name $pgSvc.Name
95+
# Locate pg_isready / createdb via the PGBIN env var set by the image
96+
$pgBin = [System.Environment]::GetEnvironmentVariable('PGBIN')
97+
if (-not $pgBin) {
98+
# Fall back: find bin/ next to the service executable
99+
$pgBin = Split-Path (Get-WmiObject Win32_Service -Filter "Name='$($pgSvc.Name)'").PathName
100+
}
101+
& "$pgBin\pg_isready.exe" --host=localhost --port=5432 --timeout=30
102+
$env:PGPASSWORD = 'root'
103+
& "$pgBin\createdb.exe" -U postgres asql_test
104+
$pgDir = Split-Path $pgBin # C:\Program Files\PostgreSQL\14
105+
"ASQL_PG_TEST_DB=postgresql://postgres:root@localhost/asql_test" | `
106+
Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
107+
"PGDIR=$pgDir" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
61108
62109
- name: Install Qt with options and default aqtversion
63110
uses: jurplel/install-qt-action@v4
@@ -74,13 +121,13 @@ jobs:
74121
uses: ilammy/msvc-dev-cmd@v1
75122

76123
- name: Checkout sources
77-
uses: actions/checkout@v4
124+
uses: actions/checkout@v6
78125

79126
- name: Configure project (Shared Link)
80127
run: >
81128
cmake -S . -B ./build-shared -G Ninja
82129
-DCMAKE_BUILD_TYPE=Debug
83-
-DCMAKE_PREFIX_PATH="/opt/homebrew/opt/postgresql@16;C:\Program Files\PostgreSQL\16"
130+
-DCMAKE_PREFIX_PATH="/opt/homebrew/opt/postgresql@16;${{ env.PGDIR }}"
84131
-DENABLE_MAINTAINER_CFLAGS=${{ matrix.build_type == 'Debug' }}
85132
-DBUILD_SHARED_LIBS=ON
86133
-DASQL_DRIVER_MYSQL=${{ runner.os == 'Linux' }}
@@ -104,7 +151,7 @@ jobs:
104151
run: >
105152
cmake -S . -B ./build-static -G Ninja
106153
-DCMAKE_BUILD_TYPE=Debug
107-
-DCMAKE_PREFIX_PATH="/opt/homebrew/opt/postgresql@16;C:\Program Files\PostgreSQL\16"
154+
-DCMAKE_PREFIX_PATH="/opt/homebrew/opt/postgresql@16;${{ env.PGDIR }}"
108155
-DBUILD_SHARED_LIBS=OFF
109156
-DASQL_DRIVER_MYSQL=${{ runner.os == 'Linux' }}
110157
-DASQL_DRIVER_ODBC=${{ runner.os == 'Linux' }}

.github/workflows/documentation.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ jobs:
4040
doc-archives: 'qtcore'
4141

4242
- name: Checkout sources
43-
uses: actions/checkout@v4
43+
uses: actions/checkout@v6
4444
with:
4545
submodules: recursive
4646

.github/workflows/nightly.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,16 @@ jobs:
1313
fail-fast: false
1414
matrix:
1515
os:
16-
- ubuntu-24.04
16+
- ubuntu-latest
1717

1818
config:
1919
- name: clang-tidy
2020
cmake_arg: '-DCMAKE_CXX_CLANG_TIDY=clang-tidy'
21-
qt_version: "6.7.3"
21+
qt_version: "6.11.0"
2222

2323
- name: clazy
2424
cmake_arg: '-DCMAKE_CXX_COMPILER=clazy'
25-
qt_version: "6.7.3"
25+
qt_version: "6.11.0"
2626

2727
steps:
2828
- name: Install dependencies on Ubuntu
@@ -40,7 +40,7 @@ jobs:
4040
- name: Install ninja-build tool (must be after Qt due PATH changes)
4141
uses: turtlesec-no/get-ninja@main
4242

43-
- uses: actions/checkout@v4
43+
- uses: actions/checkout@v6
4444

4545
- name: Configure project
4646
run: >

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ include(GNUInstallDirs)
88
include(GenerateExportHeader)
99

1010
find_package(QT NAMES Qt6 COMPONENTS Core REQUIRED)
11-
find_package(Qt${QT_VERSION_MAJOR} 6.4.0 COMPONENTS Core REQUIRED)
11+
find_package(Qt${QT_VERSION_MAJOR} 6.5.0 COMPONENTS Core REQUIRED)
1212

1313
set(CMAKE_AUTOMOC ON)
1414

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Qt Async Sql library
2323
* Single row mode (useful for very large datasets)
2424

2525
## Requirements
26-
* Qt 6.4 or later
26+
* Qt 6.5 or later
2727
* C++23 capable compiler (g++-14 or newer is required).
2828

2929
## Usage

src/ADriverOdbc.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ QVariant AOdbcThread::columnValue(SQLHSTMT stmt, SQLUSMALLINT col, SQLSMALLINT s
360360
// SQL_TYPE_TIMESTAMP (datetime/datetime2) carries no timezone info.
361361
// Use Qt::LocalTime to match QSql ODBC behaviour: the value is returned as-is
362362
// without any UTC offset, so toString() won't append "Z".
363-
return QDateTime(date, time, Qt::LocalTime);
363+
return QDateTime(date, time, QTimeZone::LocalTime);
364364
}
365365

366366
default:

tests/CMakeLists.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ function(asql_test _testname _driver)
1919
add_executable(${_testname} ${_testname}.cpp)
2020
add_test(NAME ${_testname} COMMAND ${_testname})
2121
target_link_libraries(${_testname} PUBLIC ${_driver} coverage_test)
22+
if(WIN32)
23+
# On Windows with shared libs the project DLLs (ASqlQt6.dll, driver DLL)
24+
# live in CMAKE_RUNTIME_OUTPUT_DIRECTORY alongside the test executable.
25+
# Prepend that directory to PATH so the loader finds them.
26+
set_tests_properties(${_testname} PROPERTIES
27+
ENVIRONMENT_MODIFICATION
28+
"PATH=path_list_prepend:$<TARGET_FILE_DIR:${_testname}>")
29+
endif()
2230
endfunction()
2331

2432
# Shared OBJECT library with type round-trip test implementations.
@@ -43,12 +51,22 @@ function(asql_types_test _testname _driver)
4351
add_executable(${_testname} ${_testname}.cpp)
4452
add_test(NAME ${_testname} COMMAND ${_testname})
4553
target_link_libraries(${_testname} PUBLIC ${_driver} coverage_test types_test_common)
54+
if(WIN32)
55+
set_tests_properties(${_testname} PROPERTIES
56+
ENVIRONMENT_MODIFICATION
57+
"PATH=path_list_prepend:$<TARGET_FILE_DIR:${_testname}>")
58+
endif()
4659
endfunction()
4760

4861
function(asql_prepared_test _testname _driver)
4962
add_executable(${_testname} ${_testname}.cpp)
5063
add_test(NAME ${_testname} COMMAND ${_testname})
5164
target_link_libraries(${_testname} PUBLIC ${_driver} coverage_test prepared_test_common)
65+
if(WIN32)
66+
set_tests_properties(${_testname} PROPERTIES
67+
ENVIRONMENT_MODIFICATION
68+
"PATH=path_list_prepend:$<TARGET_FILE_DIR:${_testname}>")
69+
endif()
5270
endfunction()
5371

5472
if (ASQL_DRIVER_SQLITE)

tests/CoverageObject.hpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ private Q_SLOTS:
3030
do { \
3131
if (![](auto &&qt_lhs_arg, auto &&qt_rhs_arg) { \
3232
/* assumes that op does not actually move from qt_{lhs, rhs}_arg */ \
33-
return QTest::reportResult(std::forward<decltype(qt_lhs_arg)>(qt_lhs_arg) \
34-
op std::forward<decltype(qt_rhs_arg)>(qt_rhs_arg), \
35-
[&qt_lhs_arg] { return QTest::toString(qt_lhs_arg); }, \
36-
[&qt_rhs_arg] { return QTest::toString(qt_rhs_arg); }, \
37-
#lhs, \
38-
#rhs, \
39-
QTest::ComparisonOperation::opId, \
40-
__FILE__, \
41-
__LINE__); \
33+
const bool qt_result = std::forward<decltype(qt_lhs_arg)>(qt_lhs_arg) \
34+
op std::forward<decltype(qt_rhs_arg)>(qt_rhs_arg); \
35+
QT_WARNING_PUSH \
36+
QT_WARNING_DISABLE_DEPRECATED \
37+
return QTest::reportResult( \
38+
qt_result, [&qt_lhs_arg] { return QTest::toString(qt_lhs_arg); }, [&qt_rhs_arg] { \
39+
return QTest::toString(qt_rhs_arg); \
40+
}, #lhs, #rhs, QTest::ComparisonOperation::opId, __FILE__, __LINE__); \
41+
QT_WARNING_POP \
4242
}(lhs, rhs)) { \
4343
co_return; \
4444
} \

0 commit comments

Comments
 (0)