Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
da96b10
Refactor Android tests (#123)
qiaoyuang Sep 17, 2026
06bcbb7
Rename @PrimaryKey's parameter from `isAutoincrement` to `autoIncrement`
qiaoyuang Sep 27, 2026
4231b08
Propagate the @DBRow entity's visibility to the generated table objec…
qiaoyuang Oct 1, 2026
1e066a7
Document that DatabaseScope defers execution to scope exit (B5)
qiaoyuang Oct 1, 2026
e7747e9
Fix the index examples referencing a non-existent `KClass.table` (B8)
qiaoyuang Oct 1, 2026
26cee52
Rename the ALERT_* DSL APIs to ALTER_* (B9)
qiaoyuang Oct 1, 2026
9582b25
Fix the ALTER operations emitting "ALERT TABLE", and rewrite their te…
qiaoyuang Oct 1, 2026
a278016
Generate each SetClause property with its own column's nullability (B12)
qiaoyuang Oct 1, 2026
e599cb2
Let a @PrimaryKey's nullability decide who supplies its value (B2)
qiaoyuang Oct 1, 2026
096cafb
Reject a @CompositePrimaryKey on a single property (B14)
qiaoyuang Oct 1, 2026
ed000c4
Declare the columns of a composite primary key NOT NULL (B4)
qiaoyuang Oct 1, 2026
b15d963
Require @Default for an ON ... SET DEFAULT foreign key (B13)
qiaoyuang Oct 1, 2026
30b52a6
Leave computed properties of a @DBRow class out of the table (B16)
qiaoyuang Oct 1, 2026
5e6a202
Reject a @DBRow property whose type no column can hold (B15)
qiaoyuang Oct 1, 2026
7514270
Suppress DSL_MARKER_APPLIED_TO_WRONG_TARGET where SQLlin applies its …
qiaoyuang Oct 1, 2026
362f10a
Generate a safe call only for a nullable enum column's setter (B18)
qiaoyuang Oct 1, 2026
cb5d95c
Mark the SQL string functions added in 2.2.0 with @FunctionDslMaker (…
qiaoyuang Oct 1, 2026
c0d02e2
Mark the SET DEFAULT requirement as a breaking change in the change l…
qiaoyuang Oct 1, 2026
531f7f2
Document the KSP task dependencies and the generated object's name (B19)
qiaoyuang Oct 1, 2026
96d05b5
Bug fixes for 2.4.0 in sqllin-dsl and sqllin-processor (#124)
qiaoyuang Oct 2, 2026
8b35e84
Revert "Bug fixes for 2.4.0 in sqllin-dsl and sqllin-processor (#124)"
qiaoyuang Oct 2, 2026
524e1d1
Merge pull request #125 from ctripcorp/revert/squash-merge-124
qiaoyuang Oct 2, 2026
c510fc4
Merge pull request #126 from ctripcorp/feature/bug-fixes-2.4.0
qiaoyuang Oct 2, 2026
d1c2d42
Add INSERT_OR_IGNORE (N2)
qiaoyuang Oct 2, 2026
bda5d27
Add projection to SELECT (N4)
qiaoyuang Oct 2, 2026
0ba59f8
Add result columns to SELECT (N5)
qiaoyuang Oct 2, 2026
41ae7b7
Add upsert to the roadmap as low priority (N3)
qiaoyuang Oct 2, 2026
3592f2d
Update AGP to 9.4.1, KSP to 2.3.12 and androidx.annotation to 1.11.0
qiaoyuang Oct 2, 2026
365123b
Add INSERT INTO ... SELECT and Table.withName (N9)
qiaoyuang Oct 3, 2026
3eb7342
Add value conversion functions to the roadmap
qiaoyuang Oct 3, 2026
c6b6cd7
Add UNION of other result types to the roadmap as high priority (B20)
qiaoyuang Oct 3, 2026
907351d
Escape the string arguments of SQL functions (B22)
qiaoyuang Oct 3, 2026
2220147
Don't qualify functions compared with another element (B21)
qiaoyuang Oct 3, 2026
3e2c4e0
Merge pull request #127 from ctripcorp/feature/new-features-2.4.0
qiaoyuang Oct 3, 2026
512a390
Set the version to 2.4.0 and its release date
qiaoyuang Oct 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 18 additions & 49 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ jobs:
run: ./gradlew :sqllin-driver:assemble -PonCICD

- name: Run sqllin-driver macOS Arm64 Tests
run: ./gradlew :sqllin-driver-test:cleanMacosArm64Test :sqllin-driver-test:macosArm64Test --stacktrace
run: ./gradlew :sqllin-driver:cleanMacosArm64Test :sqllin-driver:macosArm64Test --stacktrace

- name: Run sqllin-driver JVM Unit Tests on macOS Arm64
run: ./gradlew :sqllin-driver-test:cleanJvmTest :sqllin-driver-test:jvmTest --stacktrace
run: ./gradlew :sqllin-driver:cleanJvmTest :sqllin-driver:jvmTest --stacktrace

- name: Build sqllin-dsl
run: ./gradlew :sqllin-dsl:assemble -PonCICD
Expand Down Expand Up @@ -164,10 +164,10 @@ jobs:
run: ./gradlew :sqllin-driver:linuxX64MainKlibrary :sqllin-driver:jvmJar

- name: Run sqllin-driver Linux X64 Tests
run: ./gradlew :sqllin-driver-test:cleanLinuxX64Test :sqllin-driver-test:linuxX64Test --stacktrace
run: ./gradlew :sqllin-driver:cleanLinuxX64Test :sqllin-driver:linuxX64Test --stacktrace

- name: Run sqllin-driver JVM Unit Tests on Linux X64
run: ./gradlew :sqllin-driver-test:cleanJvmTest :sqllin-driver-test:jvmTest --stacktrace
run: ./gradlew :sqllin-driver:cleanJvmTest :sqllin-driver:jvmTest --stacktrace

- name: Build sqllin-processor
run: ./gradlew :sqllin-processor:assemble
Expand Down Expand Up @@ -198,15 +198,6 @@ jobs:
build-android-and-test:
runs-on: ubuntu-latest
timeout-minutes: 60
strategy:
matrix:
include:
- api-level: 26
target: default
device: pixel_2
- api-level: 36
target: google_apis
device: pixel_6

steps:
- name: Checkout
Expand All @@ -227,52 +218,30 @@ jobs:
- name: Build Android
run: ./gradlew :sqllin-driver:assembleAndroidMain :sqllin-dsl:assembleAndroidMain

- name: AVD Cache
- name: Cache Robolectric Android-All Jars
uses: actions/cache@v4
id: avd-cache
with:
path: |
~/.android/avd/*
~/.android/adb*
key: avd-${{ matrix.api-level }}

- name: Create AVD and Generate Snapshot for Caching
if: steps.avd-cache.outputs.cache-hit != 'true'
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
target: ${{ matrix.target }}
arch: x86_64
profile: ${{ matrix.device }}
emulator-build: 15368433
force-avd-creation: false
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: true
script: echo "Generated AVD snapshot for caching."

- name: Run Android Instrumented Tests
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
target: ${{ matrix.target }}
arch: x86_64
profile: ${{ matrix.device }}
emulator-build: 15368433
force-avd-creation: false
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: true
script: ./gradlew :sqllin-driver-test:connectedAndroidDeviceTest --stacktrace & ./gradlew :sqllin-dsl-test:connectedAndroidDeviceTest --stacktrace
path: ~/.m2/repository/org/robolectric
key: ${{ runner.os }}-robolectric-${{ hashFiles('gradle/libs.versions.toml') }}
restore-keys: |
${{ runner.os }}-robolectric-

- name: Run sqllin-driver Android Unit Tests
run: ./gradlew :sqllin-driver:testAndroidHostTest --stacktrace

- name: Run sqllin-dsl Android Unit Tests
run: ./gradlew :sqllin-dsl-test:testAndroidHostTest --stacktrace

- name: Upload sqllin-driver Reports
uses: actions/upload-artifact@v4
with:
name: Test-Reports-Android-driver-API${{ matrix.api-level }}
name: Test-Reports-Android-driver
path: sqllin-driver/build/reports
if: failure()

- name: Upload sqllin-dsl Reports
uses: actions/upload-artifact@v4
with:
name: Test-Reports-Android-dsl-API${{ matrix.api-level }}
path: sqllin-dsl/build/reports
name: Test-Reports-Android-dsl
path: sqllin-dsl-test/build/reports
if: failure()
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ local.properties
/sqllin-driver/build
/sqllin-dsl/build
/sqllin-processor/build
/sqllin-driver-test/build
/sqllin-dsl-test/build
/sample/build
*.podspec
Expand Down
47 changes: 47 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,53 @@

- Date format: YYYY-MM-dd

## 2.4.0 / 2026-10-03

### All

* Update `Kotlin`'s version to `2.4.20`
* Update `AGP`'s version to `9.4.1`
* Migrate the Android instrumented tests to `Robolectric`, they now run on the JVM as host unit tests against `API 26` and `API 37`, and no longer need an emulator
* Move the `sqllin-driver` tests back into the `sqllin-driver` module's `commonTest`, and remove the `sqllin-driver-test` module

### sqllin-dsl

* New DSL API: `DatabaseScope#INSERT_OR_IGNORE` for SQL syntax `INSERT OR IGNORE`
* New DSL API: projection, which reads `SELECT` results into a narrower `@Serializable` type naming the columns to select, given as the type argument of the clause function: `X<R>()`, `WHERE<R>(...)`, `ORDER_BY<R>(...)`, `LIMIT<R>(...)` and `GROUP_BY<R>(...)`, after `SELECT` or `SELECT_DISTINCT`. A type that doesn't fit the table is rejected with an `IllegalArgumentException` when the statement is built. To support it, the public `DatabaseScope#select` functions now take a result type separate from the table's; this is source-compatible, but on Kotlin/Native a library compiled against an earlier version may have to be recompiled
* New DSL API: result columns, which select expressions such as aggregate functions into properties of a result type with `AS`, as in `table SELECT listOf(count(X) AS AuthorStats::books, sum(pages) AS AuthorStats::totalPages) GROUP_BY author`, or `table SELECT (count(X) AS BookCount::books)` for a single one. The result type's other properties are read from their columns, as in a projection. They work after `SELECT` and `SELECT_DISTINCT`, followed by `WHERE`, `GROUP_BY`, `ORDER_BY` and `LIMIT`. A property must have the type of its expression's values, which is checked at compile time, and be nullable when its expression can be `NULL`, which is checked when the statement is built. An aggregate query without `GROUP BY` returns a row even when no rows match, in which every column and every aggregate function except `count` is `NULL`; as `GROUP_BY` can still follow when the statement is built, this is checked when the scope ends, before any of its statements runs
* New DSL API: `INSERT`, `INSERT_OR_IGNORE` and `INSERT_OR_REPLACE` taking a `SelectStatement` of the table's row type, for SQL syntax `INSERT INTO ... SELECT`, as in `ArchiveTable INSERT (PersonTable SELECT WHERE<Archive>(PersonTable.age GT 60))`. Every column is inserted, the primary key copied as it is selected. The `SELECT` becomes part of the `INSERT`, so it no longer runs on its own
* New API: `Table#withName`, which returns a table with the same structure under another name. With `INSERT INTO ... SELECT`, it rebuilds a table in a migration, for a change `ALTER TABLE` can't make, such as adding a constraint, or dropping a column on SQLite older than 3.35, which on Android means below API 34. The guide to modifying the database now describes the procedure, and documents `INSERT_OR_IGNORE` and `INSERT_OR_REPLACE`
* **Breaking change**: `ClauseElement`, `ClauseNumber` and `ClauseString` now take a type parameter, the type of their values, such as `ClauseNumber<Int>` for an `Int` column and `ClauseNumber<Long>` for `count(X)`, which is what lets `AS` check the type of a property. Code that only uses the DSL is unaffected; code that names these types has to add a type argument, such as `ClauseElement<*>` where any element is accepted. The public constructors of `ClauseNumber`, `ClauseString`, `ClauseBoolean`, `ClauseBlob` and `ClauseEnum`, which the generated table objects call, now take whether the column is nullable instead of whether the element is a function. The generated code is regenerated by the build, but on Kotlin/Native a library compiled against an earlier version has to be recompiled
* **Breaking change**: The SQL functions now return elements of the type of the values SQLite returns for them: `count`, `length`, `instr` and `random` a `ClauseNumber<Long>`, `avg` and `round` a `ClauseNumber<Double>`, the string functions and `group_concat` a `ClauseString<String>`, and `max`, `min` and `abs` an element of the same kind and type as their argument. So `max` and `min` of a String column are now a `ClauseString`, compared with strings in `HAVING`, where they used to be a `ClauseNumber`. `sum` is overloaded by the type of its column: of a column of integers or Booleans it is a `ClauseNumber<Long>`, and of a `Float` or `Double` column a `ClauseNumber<Double>`. A `sum` of a String, BLOB, enum or `ULong` column no longer compiles; the last because SQLite stores a `ULong` above `Long.MAX_VALUE` as a negative number, which made the sum wrong
* Fix documentation: the SQL functions guide listed a `sign` function, which isn't available, and its `HAVING (count(X) > 2)` example didn't compile; it is `HAVING (count(X) GT 2)`. It no longer says that functions can only be used in conditions
* **Breaking change**: The parameter of annotation `@PrimaryKey` renamed from `isAutoincrement` to `autoIncrement`, aligning it with the name already used in the documentation and with the naming of the other annotations. Call sites using the named argument `@PrimaryKey(isAutoincrement = true)` must be updated to `@PrimaryKey(autoIncrement = true)`; positional usage such as `@PrimaryKey(true)` is unaffected
* **Breaking change**: The nullability of a `@PrimaryKey` property now decides who supplies its value. A `Long?` key is assigned by the database, as before. A non-null `Long` key is now allowed: it remains an `INTEGER PRIMARY KEY`, a rowid alias, but is supplied by the caller and written by every `INSERT`. A key of any other type must be non-null and is declared `NOT NULL`. Previously every `@PrimaryKey` was forced to be nullable, against the annotation's own documentation, and because SQLite does not let `PRIMARY KEY` imply `NOT NULL` on such a column, a `String` key could hold `NULL` in any number of rows. `autoIncrement = true` now requires a `Long?` key, and a `ULong?` key, which used to be stored as `NULL` because it was left out of `INSERT` without being a rowid alias, is now rejected. To migrate, drop the `?` from any non-`Long` `@PrimaryKey`; a single-column `@CompositePrimaryKey` that only existed to hold a caller-supplied `Long` key can become `@PrimaryKey val id: Long`
* **Breaking change**: `@CompositePrimaryKey` now requires at least two properties. A single-column primary key is declared with `@PrimaryKey`, which for a `Long` key maps to `INTEGER`, a rowid alias, where a single-column `@CompositePrimaryKey` mapped it to `BIGINT`. To migrate, replace a lone `@CompositePrimaryKey` with `@PrimaryKey`
* **Breaking change**: The DSL APIs `ALERT_ADD_COLUMN` and `ALERT_RENAME_TABLE_TO` renamed to `ALTER_ADD_COLUMN` and `ALTER_RENAME_TABLE_TO`, correcting a misspelling of the SQL keyword `ALTER`. The internal `Alert` operation object is renamed to `Alter` accordingly
* Fix: the ALTER operations emitted the invalid keyword `ALERT TABLE` instead of `ALTER TABLE`, so `ALTER_ADD_COLUMN`, `ALTER_RENAME_TABLE_TO`, `RENAME_COLUMN` and `DROP_COLUMN` all failed at runtime and had never worked. The tests that covered them swallowed the failure, which is why it went unnoticed
* Fix documentation: the KDoc of `DatabaseScope` now states that statement execution is deferred until the scope exits, and its example no longer reads a `SelectStatement`'s results while the scope is still open, which throws
* Fix documentation: the `CREATE_INDEX` and `CREATE_UNIQUE_INDEX` examples referenced a `KClass.table` extension that does not exist in the library, and referred to columns by property reference instead of through the generated table object
* Fix: the SQL string functions added in 2.2.0, `substr`, `trim`, `ltrim`, `rtrim`, `replace`, `instr` and `printf`, now carry the same DSL marker as the other SQL functions, so IntelliJ IDEA highlights their calls the same way
* Fix documentation: the installation guide now declares the task dependencies the generated code needs, as SQLlin's own builds always did. Without them Gradle fails the build, in particular when another KSP processor runs in the same module. It also states that each generated object is named after its class with a `Table` suffix, not after the table
* Fix: the string arguments of `replace`, `instr`, `printf` and `group_concat` were put into the SQL between single quotes without escaping, so a `'` in one broke the statement, and a crafted one could change what the statement does, such as making a condition true for every row. A `'` is now escaped as `''`, the only escape SQLite has in a string literal, so any string stays a literal
* Fix: a comparison between two elements, such as `length(name) GT pages` or `HAVING (max(pages) GT min(pages))`, qualified both with their table's name even when one was a function, producing invalid SQL such as `book.length(name)`. A function is now written as it is

### sqllin-driver

* Update `sqlite-jdbc`'s version to `3.53.4.0`

### sqllin-processor

* Update `KSP`'s version to `2.3.12`
* Fix: the visibility of the class annotated with `@DBRow` is now propagated to the generated table object. An `internal` `@DBRow` class used to produce a `public` object, which failed to compile with `EXPOSED_SUPER_CLASS`, `EXPOSED_FUNCTION_RETURN_TYPE` and `EXPOSED_RECEIVER_TYPE`. A `@DBRow` class that is neither `public` nor `internal` is now reported as an error
* Fix: every `SetClause` property generated for a column declared after a nullable `Long` `@PrimaryKey` was typed nullable regardless of the column's own declaration, so `UPDATE ... SET { column = null }` compiled against `NOT NULL` columns and failed only at runtime. Each property now takes the nullability its own column declares
* Fix: the columns of a `@CompositePrimaryKey` are now declared `NOT NULL`. SQLite, unlike standard SQL, does not let a table-level `PRIMARY KEY` imply it on a rowid table, so such a key used to accept `NULL`, and any number of rows sharing the same key once a `NULL` was part of it. SQLlin itself could not write those `NULL`s, but anything else writing to the database could, and SQLlin then read them back as `0` or an empty string. This only changes the schema of tables created from now on; an existing table keeps its schema, as SQLite cannot add `NOT NULL` to an existing column
* **Breaking change**: an `ON_DELETE_SET_DEFAULT` or `ON_UPDATE_SET_DEFAULT` foreign key now requires the column to declare `@Default`, as the documentation always said. On `@References` the check was inverted: it accepted a non-null column without a default, whose parent row then could not be deleted (`NOT NULL constraint failed`), and rejected a nullable one. On `@ForeignKey` groups there was no check at all, so a nullable column without a default compiled and was set to `NULL`; that is now rejected too. To migrate, add `@Default` to the column, or use `ON_DELETE_SET_NULL` / `ON_UPDATE_SET_NULL` where setting it to `NULL` is the intent. Both checks hold whichever order `@Default` and the foreign key annotation are written in
* Fix: a computed property of a `@DBRow` class, one without a backing field such as `val title: String get() = ...`, no longer becomes a column. kotlinx.serialization doesn't serialize such a property, but it was given a `NOT NULL` column that `INSERT` never wrote, so every insert failed with `NOT NULL constraint failed`, and an accessor that looked its column up past the end of the serializer's descriptor
* Fix: a `@DBRow` property of a type no column can hold, such as a `List`, is now a compile-time error naming the property. It used to be skipped silently: left out of `CREATE TABLE` while its serializer still wrote and read it, so `INSERT` and `SELECT` failed at runtime with "no column named", and as the last property it left a trailing comma that made `CREATE TABLE` itself fail. Annotate such a property with `kotlinx.serialization.Transient` to keep it out of the table
* Fix: the generated table objects no longer produce a `DSL_MARKER_APPLIED_TO_WRONG_TARGET` warning for every column, which Kotlin 2.3.20 and later report in the module that compiles them. Their `@ColumnNameDslMaker` is there for IntelliJ IDEA's DSL highlighting rather than for the compiler's DSL scope control, so the warning is now suppressed on each generated object
* Fix: the generated `SetClause` setter of a non-null enum column no longer uses a safe call, `value?.ordinal`, which the module compiling the generated code reported as unnecessary. Only a nullable enum column keeps it

## 2.3.0 / 2026-08-20

### All
Expand Down
15 changes: 13 additions & 2 deletions ROADMAP.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
# SQLlin Roadmap

## High Priority

* Support observable queries that return a `Flow` re-emitting whenever the tables they read change, e.g. to invalidate a Paging source
* Support UNION of SELECTs whose result type isn't the table's row type, such as projections, result columns and joins. `UNION` is typed by the table's row type but reads the rows into its first SELECT's result type, so using the results of such a union fails with a `ClassCastException`

## Medium Priority

* Support WASM platform DSL
* Support CREATE VIRTUAL TABLE DSL
* Support CREATE VIEW DSL
* Support CREATE TRIGGER DSL
* Support JOIN sub-query DSL
* Support more functions
* Support more functions, such as `coalesce` and `ifnull`, as well as `CAST` and literal values in expressions, e.g. to convert data while copying it to a rebuilt table with `INSERT INTO ... SELECT`
* Support type converters: store a property of any type through a serializer that encodes it to a type SQLite supports, with type-safe WHERE and SET on its column, e.g. to store instances of kotlinx.datetime

## Low Priority

* Support store instances of kotlinx.datetime
* Support CHECK keyword
* Support using a query's results within the same transaction, so that a read-modify-write is one transaction
* Support upsert, `INSERT ... ON CONFLICT (target) DO UPDATE` and `DO NOTHING`, which updates the conflicting row in place where `INSERT OR REPLACE` deletes and re-inserts it

## Supported

* Support INSERT INTO ... SELECT (2.4.0 ✅)
* Support SQL functions in SELECT results (2.4.0 ✅)
* Support SELECT projection (2.4.0 ✅)
* Support INSERT OR IGNORE (2.4.0 ✅)
* Support INSERT OR REPLACE (2.3.0 ✅)
* Support FOREIGN KEY DSL (2.2.0 ✅)
* Support CREATE INDEX DSL (2.2.0 ✅)
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
VERSION=2.3.0
VERSION=2.4.0
GROUP_ID=com.ctrip.kotlin

#Maven Publishing Information
Expand Down
13 changes: 13 additions & 0 deletions gradle/gradle-daemon-jvm.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#This file is generated by updateDaemonJvm
toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/b96cc4b9c59b5bff244af296e50d5ea3/redirect
toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/fdfa2f9fadcf75fb9616fde209d60b55/redirect
toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/b96cc4b9c59b5bff244af296e50d5ea3/redirect
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/fdfa2f9fadcf75fb9616fde209d60b55/redirect
toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/97b61e8788c7490a5f53d8951b11ea7a/redirect
toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/feb8af2956f2e263086e0a8f9a1df390/redirect
toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/b96cc4b9c59b5bff244af296e50d5ea3/redirect
toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/fdfa2f9fadcf75fb9616fde209d60b55/redirect
toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/eff42deed1d8947129a4e66cd07a89f4/redirect
toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/8fe418192094ee8db0da620bcb6b1629/redirect
toolchainVendor=JETBRAINS
toolchainVersion=25
Loading
Loading