Skip to content

feat: Add SQLite compiletime native bindings#450

Open
Donach wants to merge 2 commits into
wurstscript:masterfrom
Donach:feature/sqlite-externs
Open

feat: Add SQLite compiletime native bindings#450
Donach wants to merge 2 commits into
wurstscript:masterfrom
Donach:feature/sqlite-externs

Conversation

@Donach

@Donach Donach commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Adds native @extern declarations for compiletime SQLite database operations in wurst/file/SQLite.wurst.

High-level API

  • SqlResult: Dynamic column storage using ArrayList<string>.
  • SqliteDb: OOP connection wrapper supporting raw and parameterised queries (execPrepared, selectPrepared, selectFirstPrepared, existsPrepared).
  • SQL: Configurable singleton wrapper.

Acceptance Criteria

Exposed Native Functions:

  • sqlite_open(string path) returns int
  • sqlite_prepare(int conn, string q) returns int
  • sqlite_bind_int(int stmt, int idx, int val)
  • sqlite_bind_real(int stmt, int idx, real val)
  • sqlite_bind_string(int stmt, int idx, string val)
  • sqlite_step(int stmt) returns boolean
  • sqlite_column_count(int stmt) returns int
  • sqlite_column_int(int stmt, int idx) returns int
  • sqlite_column_real(int stmt, int idx) returns real
  • sqlite_column_string(int stmt, int idx) returns string
  • sqlite_reset(int stmt)
  • sqlite_finalize(int stmt)
  • sqlite_close(int conn)
  • sqlite_exec(int conn, string q)

Comment thread wurst/file/SQLite.wurst Outdated

/** A row returned from a SELECT query. Access columns by index via col(). */
public class SqlResult
string array[2000] cols

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Big array members are not a good idea in wurst, I think just use ArrayList here and for select and remove LinkedList import.

@Frotty

Frotty commented Jul 22, 2026

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7db7067e44

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread wurst/file/SQLite.wurst Outdated

/** A row returned from a SELECT query. Access columns by index via col(). */
public class SqlResult
string array[2000] cols

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use dynamic storage for row columns

Because Wurst implements sized class-member arrays by generating one backing array per element, this declaration emits 2000 backing arrays/accessor branches for every project that uses SqlResult, even when a query returns only one or two columns. That is a large code-size/compile-time cost in a stdlib wrapper and makes every col() access go through the generated dispatcher; store the actual column values in a dynamic list/ArrayList instead of a 2000-slot member array.

Useful? React with 👍 / 👎.

@Donach
Donach force-pushed the feature/sqlite-externs branch from 7db7067 to 81cd773 Compare July 22, 2026 20:33
@Donach

Donach commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

Updated this PR with the requested fixes:

  1. Parameterized Queries: Added execPrepared, selectPrepared, selectFirstPrepared, and existsPrepared methods on SqliteDb and SQL using sqlite_prepare and sqlite_bind_string to prevent SQL injection.
  2. Column Count Timing: Fixed sqlite_column_count timing by calling it after the first sqlite_step call when ResultSet metadata is present.
  3. Dynamic Column Storage: Updated SqlResult to store row values in a dynamic ArrayList<string> rather than a fixed 2000-element member array to avoid Wurst's array-backing code generation overhead.
  4. Test Annotations: Unified all test annotations to lower-case @test.
  5. Acceptance Criteria: Noted dependency on upstream WurstScript PR #1180.

Reborn Reviewer added 2 commits July 23, 2026 00:12
Adds @extern declarations for compiletime SQLite JDBC bindings exposed by
the WurstScript compiler (requires wurstscript/WurstScript PR #1180).

Native functions: sqlite_open, sqlite_prepare, sqlite_bind_*, sqlite_step,
sqlite_column_*, sqlite_reset, sqlite_finalize, sqlite_close, sqlite_exec.

High-level API:
- SqlResult: row accessor with col, colInt, colReal, colBool helpers
- SqliteDb: OOP connection wrapper with select, selectFirst, exists, count
- SQL: configurable singleton for single-database workflows

Parameterised query support:
- execPrepared, selectPrepared, selectFirstPrepared, existsPrepared
- Prevents SQL injection by using sqlite_prepare + sqlite_bind_string
- Includes injection prevention test

Fixes vs original draft:
- Moved sqlite_column_count after first sqlite_step (JDBC ResultSet
  metadata requires an executed statement)
- Added parameterised query variants to prevent SQL injection
- Added comprehensive doc comments about error behaviour and upstream dep
- Unified test annotations to @test (lowercase)
- Removed unused ErrorHandling import
- Fixed array size to use literal (WurstScript requirement)
Because Wurst implements sized class-member arrays by generating one
backing array per element, the previous 2000-slot member array
in SqlResult emitted massive code and compiled slowly.
This refactors SqlResult to use a dynamic ArrayList<string> to store
only the actual returned columns.

Additionally updates all LinkedList usages to ArrayList to match.
@Donach
Donach force-pushed the feature/sqlite-externs branch from 81cd773 to 59480f1 Compare July 22, 2026 22:12
@Frotty

Frotty commented Jul 23, 2026

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 59480f1d1e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread wurst/file/SQLite.wurst
Comment on lines +165 to +166
for p in params
sqlite_bind_string(stmt, idx, p)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Replace ArrayList foreach with index loops

When prepared queries are used, this iterates an ArrayList<string> with for p in params, but ArrayList in this repo does not expose an iterator and is documented/implemented for index-based traversal only. That makes the new SQLite package fail to typecheck as soon as this method is compiled; the same pattern is repeated in the new tests over rows, so these should be changed to for i = 0 to params.size() - 1 / params.get(i) style loops.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants