Skip to content

feat: add parameterized query#366

Merged
killagu merged 10 commits intomasterfrom
feat/sql_param
Dec 10, 2025
Merged

feat: add parameterized query#366
killagu merged 10 commits intomasterfrom
feat/sql_param

Conversation

@killagu
Copy link
Contributor

@killagu killagu commented Nov 25, 2025

  • Add param filter in TableSqlMap for parameterized queries
  • Update MysqlDataSource.query() to accept optional params array
  • Modify DataSource to pass params to query methods
  • Update BaseSqlMap to use param filter in all generated SQLs
    • generateFindByPrimary: primary key queries
    • generateFindByIndexes: index queries
    • generateInsert: insert statements
    • generateUpdate: update statements
    • generateDelete: delete statements
  • Add test case for param filter functionality

🤖 Generated with Claude Code

Checklist
  • npm test passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)
Description of change

Summary by CodeRabbit

  • New Features

    • Configurable executeType for datasource (choose execute vs query).
    • Param filter to produce parameterized SQL (returns SQL + bound params).
  • Bug Fixes

    • All queries now bind parameters consistently to improve security and prevent injection.
  • Documentation

    • README updated with executeType guidance and param filter usage/examples.
  • Tests

    • Added tests for executeType behavior and parameterized SQL generation.

✏️ Tip: You can customize this high-level summary in your review settings.

killagu and others added 2 commits November 25, 2025 13:28
- Add param filter in TableSqlMap for parameterized queries
- Update MysqlDataSource.query() to accept optional params array
- Modify DataSource to pass params to query methods
- Update BaseSqlMap to use param filter in all generated SQLs
  - generateFindByPrimary: primary key queries
  - generateFindByIndexes: index queries
  - generateInsert: insert statements
  - generateUpdate: update statements
  - generateDelete: delete statements
- Add test case for param filter functionality

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
- Add param filter description in custom filters section
- Update custom SQL example to use param filter
- Add detailed usage example and security notes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@coderabbitai
Copy link

coderabbitai bot commented Nov 25, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

This PR implements parameterized SQL templates via a new param filter, updates template rendering to return { sql, params }, and propagates parameters and an executeType option through the DAL to the MySQL client for parameterized query execution.

Changes

Cohort / File(s) Summary
SQL Template Updates
core/dal-runtime/src/BaseSqlMap.ts
Replaced inline bindings with `{{...
Template Rendering & Parameterization
core/dal-runtime/src/TableSqlMap.ts, core/dal-runtime/test/TableSqlMap.test.ts
Added GeneratedSql interface and param filter that accumulates parameter values and returns ?. generate() now returns { sql, params }; tests updated to assert placeholders and params.
Data Access Layer Integration
core/dal-runtime/src/DataSource.ts
generateSql now returns params; public methods (execute, executeRaw, count, paginate, executeScalar, executeRawScalar) extract and pass params and optional EggQueryOptions through query and pagination flows.
MySQL Execution Strategy
core/dal-runtime/src/MySqlDataSource.ts
Added `executeType?: 'execute'
Testing & Fixtures
core/dal-runtime/test/DataSource.test.ts, core/dal-runtime/test/fixtures/.../FooExtension.ts
Added test verifying executeType: 'execute' path and CRUD flow; fixture extended with customFind SqlMap using param filter.
Documentation
plugin/dal/README.md
Documented param filter usage and executeType configuration, updated examples to use `{{ name
CI
.github/workflows/nodejs.yml
Minor comment line rewrite (no functional change).

Sequence Diagram(s)

sequenceDiagram
    actor App as Application
    participant DS as DataSource
    participant TSM as TableSqlMap
    participant MDS as MySqlDataSource
    participant DB as MySQL Client

    App->>DS: execute(sqlName, data, options?)
    DS->>TSM: generate(sqlName, data, timezone)
    Note over TSM: Render template with `param` filter\ncollecting values into params[]
    TSM-->>DS: { sql, params }
    DS->>MDS: query(sql, params, options)
    alt options.executeType or default === 'execute'
        MDS->>DB: client.execute(sql, params, options)
    else
        MDS->>DB: client.query(sql, params, options)
    end
    DB-->>MDS: results
    MDS-->>DS: results
    DS-->>App: mapped results
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Review param filter implementation and edge cases for different SQL statement types in TableSqlMap.ts
  • Verify params propagation for count queries and paginate flow in DataSource.ts
  • Confirm correct branching and option precedence for executeType in MySqlDataSource.ts
  • Check updated SQL templates in BaseSqlMap.ts for completeness and correct placeholder usage

Possibly related PRs

Suggested reviewers

  • fengmk2
  • gxkl

Poem

🐰 A little filter hops in, small and spry,

values become '?' as parameters fly.
DataSource passes the bundle along,
MySQL executes — the bindings are strong.
Hooray for safe queries! 🌿✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding parameterized query support with the param filter across the DAL runtime layer.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/sql_param

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @killagu, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the security of database operations by implementing robust support for parameterized queries. By introducing a 'param' filter and integrating it throughout the SQL generation and execution layers, it ensures that all dynamically generated SQL statements are safe from SQL injection attacks. This change provides a more secure and reliable data access layer without altering the core logic of how data is retrieved or manipulated.

Highlights

  • Parameterized Query Support: Introduced a new 'param' filter within the TableSqlMap to enable parameterized queries, replacing direct value insertion with '?' placeholders and collecting parameters for secure execution.
  • SQL Injection Prevention: Modified all generated SQL statements in BaseSqlMap (for primary key lookups, index lookups, inserts, updates, and deletes) to utilize the new 'param' filter, effectively preventing SQL injection vulnerabilities.
  • DataSource Integration: Updated the DataSource and MysqlDataSource to handle and pass an array of parameters alongside the SQL string, ensuring that queries are executed using the database driver's parameterized query capabilities.
  • Enhanced Test Coverage: Added a dedicated test case to verify the correct functionality of the 'param' filter, confirming that SQL statements are generated with placeholders and parameters are collected as expected.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces parameterized queries to prevent SQL injection, which is a great security improvement. The implementation correctly uses a nunjucks filter to replace values with '?' and collect the parameters. However, I've found a critical concurrency issue in how the parameters are collected. The current implementation uses a shared environment state, which will lead to race conditions and incorrect query parameters under concurrent requests. I've provided suggestions to fix this by using the per-render context instead. I also found a minor simplification that can be made in the MySqlDataSource.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
core/dal-runtime/src/BaseSqlMap.ts (2)

152-189: Critical: SQL injection vulnerability in INSERT statement for timestamp fields.

The gmtCreate and gmtModified fields in the INSERT statement (line 186) do not use the param filter when a value is provided by the user:

{{ $${propertyName} if $${propertyName} !== undefined else '${now}' }}

This means if a user provides custom values for these fields, they will be directly interpolated into the SQL without parameterization, creating a SQL injection vulnerability.

Compare this with the UPDATE statement (line 244) which correctly uses the param filter:

{{ ($${propertyName} | param) if $${propertyName} !== undefined else '${now}' }}

Apply this diff to fix the vulnerability:

         values.push((`
         {% if ___first %}
           {% set ___first = false %}
         {% else %}
         ,
         {% endif %}
 
-        {{ $${propertyName} if $${propertyName} !== undefined else '${now}' }}
+        {{ ($${propertyName} | param) if $${propertyName} !== undefined else '${now}' }}
         `).trim());

34-267: Add parameterization filter to gmtModified handling in INSERT method (line 186).

Verification found an inconsistency in parameterization. Line 186 in the generateInsert() method lacks a param filter for the propertyName variable when handling gmtModified/gmtCreate columns, while line 244 in the generateUpdate() method correctly applies it for the same column types.

Change line 186 from:

{{ $${propertyName} if $${propertyName} !== undefined else '${now}' }}

to:

{{ ($${propertyName} | param) if $${propertyName} !== undefined else '${now}' }}

All other template variables across primary key queries, index queries, update statements, and delete statements are consistently parameterized.

🧹 Nitpick comments (2)
core/dal-runtime/src/TableSqlMap.ts (1)

50-56: Add error handling to the param filter.

The param filter silently skips parameter collection if $$params is undefined. While defensive, this could mask bugs where the filter is used outside the generate context, leading to SQL with literal '?' strings instead of parameterized queries.

Consider throwing an error if $$params is not available:

     // Add param filter for parameterized queries
     env.addFilter('param', function(this: Template, value: any) {
-      if ((this as any).env.$$params) {
-        (this as any).env.$$params.push(value);
+      const params = (this as any).env.$$params;
+      if (!params) {
+        throw new Error('param filter can only be used within DataSource.generate() context');
       }
+      params.push(value);
       return '?';
     });
plugin/dal/README.md (1)

613-613: Use a proper heading instead of bold text.

The bold text **param 过滤器** should be a proper Markdown heading for better document structure and accessibility.

Apply this diff:

-**param 过滤器**
+#### param 过滤器

Based on static analysis hints.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b176c73 and 3a0d1c4.

📒 Files selected for processing (7)
  • core/dal-runtime/src/BaseSqlMap.ts (6 hunks)
  • core/dal-runtime/src/DataSource.ts (4 hunks)
  • core/dal-runtime/src/MySqlDataSource.ts (1 hunks)
  • core/dal-runtime/src/TableSqlMap.ts (3 hunks)
  • core/dal-runtime/test/TableSqlMap.test.ts (1 hunks)
  • core/dal-runtime/test/fixtures/modules/dal/dal/extension/FooExtension.ts (1 hunks)
  • plugin/dal/README.md (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
core/dal-runtime/test/TableSqlMap.test.ts (2)
core/dal-decorator/src/model/TableModel.ts (1)
  • TableModel (12-144)
core/dal-runtime/src/SqlMapLoader.ts (1)
  • SqlMapLoader (6-26)
core/dal-runtime/src/DataSource.ts (1)
core/dal-runtime/src/TableModelInstanceBuilder.ts (1)
  • TableModelInstanceBuilder (3-25)
🪛 markdownlint-cli2 (0.18.1)
plugin/dal/README.md

613-613: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Runner-ubuntu (20)
  • GitHub Check: Runner-ubuntu (16)
  • GitHub Check: Runner-ubuntu (18)
🔇 Additional comments (5)
core/dal-runtime/test/fixtures/modules/dal/dal/extension/FooExtension.ts (1)

8-17: LGTM! Good example of parameterized query usage.

The customFind extension demonstrates proper usage of the param filter for SQL parameterization. This serves as a good fixture for testing the new functionality.

plugin/dal/README.md (1)

575-637: LGTM! Comprehensive documentation for the param filter.

The documentation clearly explains the purpose, usage, and security benefits of the param filter with practical examples. The warning about using it for all user inputs is especially important.

core/dal-runtime/test/TableSqlMap.test.ts (1)

14-26: LGTM! Well-structured tests for parameterized queries.

The tests properly validate both aspects of the new functionality:

  1. Existing test updated to verify the GeneratedSql structure
  2. New test validates parameterized query generation with placeholder and params array
core/dal-runtime/src/MySqlDataSource.ts (1)

65-70: LGTM! Clean implementation of parameterized query support.

The method signature change properly supports optional parameters while maintaining backward compatibility. The conditional logic ensures params are only passed when provided and non-empty.

core/dal-runtime/src/DataSource.ts (1)

7-100: LGTM! Comprehensive parameter propagation through all query paths.

The changes systematically propagate parameters through all query execution methods:

  • ExecuteSql interface properly includes params
  • generateSql extracts and returns params from TableSqlMap
  • All execution methods (count, execute, executeRaw, paginate) pass params to MySqlDataSource
  • Pagination correctly handles separate params for data and count queries

The implementation is thorough and maintains consistency across all code paths.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
plugin/dal/README.md (2)

613-613: Consider using a proper heading for consistency.

The markdown uses bold text instead of a heading, which is flagged by markdownlint. Consider using ### for consistency with the document structure.

Apply this diff:

-**param 过滤器**
+### param 过滤器

615-615: Clarify the scope of SQL injection prevention.

Based on learnings, the documentation states that the param filter is used "用于防止 SQL 注入" (to prevent SQL injection), but past comments indicate that dal already performs SQL escaping internally. The primary benefits are described as "小幅的性能优化和 db 侧的可观测" (minor performance optimization and database-side observability). Consider clarifying that this provides defense-in-depth and observability benefits, rather than being the primary SQL injection prevention mechanism.

core/dal-runtime/src/TableSqlMap.ts (1)

53-53: Type hint is incorrect but not breaking.

The type hint this: Template is incorrect. In Nunjucks filter functions, this refers to the render context object, not the Template. The correct type would be something like this: { ctx?: Record<string, any> }. However, given the as any cast in the implementation, this is a pedantic type correctness issue that doesn't affect runtime behavior.

Apply this diff if you want to correct the type hint:

-    env.addFilter('param', function(this: Template, value: any) {
+    env.addFilter('param', function(this: { ctx?: Record<string, any> }, value: any) {
       if ((this as any).ctx[SQL_PARAMS]) {
         (this as any).ctx[SQL_PARAMS].push(value);
       }
       return '?';
     });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3a0d1c4 and 4a8c254.

📒 Files selected for processing (2)
  • core/dal-runtime/src/TableSqlMap.ts (3 hunks)
  • plugin/dal/README.md (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
core/dal-runtime/src/TableSqlMap.ts (1)
core/dal-runtime/src/SqlGenerator.ts (1)
  • SqlGenerator (10-393)
🪛 markdownlint-cli2 (0.18.1)
plugin/dal/README.md

613-613: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Runner-ubuntu (18)
  • GitHub Check: Runner-ubuntu (20)
  • GitHub Check: Runner-macos (20)
  • GitHub Check: Runner-macos (16)
  • GitHub Check: Runner-macos (18)
  • GitHub Check: Runner-ubuntu (16)
  • GitHub Check: Analyze (typescript)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (7)
plugin/dal/README.md (2)

575-575: LGTM!

The documentation correctly demonstrates the new param filter usage, replacing direct value interpolation with parameterized queries.


602-602: LGTM!

The param filter is correctly added to the list of supported filters.

core/dal-runtime/src/TableSqlMap.ts (5)

8-8: LGTM!

The constant provides a clear, collision-resistant key for passing parameters through the render context.


16-19: LGTM!

The interface clearly defines the return structure for parameterized SQL generation with appropriate types.


52-58: Excellent fix for the concurrency issue!

The implementation now correctly uses the render context (this.ctx[SQL_PARAMS]) instead of the shared environment, ensuring each concurrent request maintains its own parameter array. This addresses the critical concurrency issue flagged in previous reviews.


102-114: Params handling correctly implemented!

The implementation now properly passes the params array through the render context instead of attaching it to the shared environment. This ensures each concurrent request maintains its own parameter collection, resolving the critical concurrency issue from previous reviews.


105-105: Proposed fix is incomplete and does not address the concurrency issue correctly.

The review's suggested diff will not work as written. The escapeSQL function in NunjucksUtil.ts is part of a custom RUNTIME object that replaces nunjucks.runtime during template rendering. When escapeSQL is called from compiled template code, its this context refers to the RUNTIME object, which has access to this.env (the nunjucks Environment), not the render context passed to template.render().

Passing $$timezone: timezone through the render context won't make it accessible to escapeSQL, since that function only accesses this.env.timezone. The current approach of setting timezone on the shared env object does create a race condition under concurrent load, but the proposed solution doesn't actually fix it.

To properly resolve the concurrency issue, timezone would need to either:

  • Be set on the custom RUNTIME object itself (passed through during template render)
  • Be passed through the environment in a request-local manner
  • Require a different mechanism to pass data from the render context to the runtime functions

The original concern about the race condition is valid, but the suggested fix requires more careful implementation.

@killagu killagu changed the title feat: add parameterized query support to prevent SQL injection feat: add parameterized query Nov 25, 2025
Copy link
Contributor

@gxkl gxkl left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
core/dal-runtime/src/BaseSqlMap.ts (3)

57-66: Indexed WHERE conditions correctly parameterized; consider a null-case test

The expression

`col` {{ "IS" if $prop == null else "=" }} {{$prop | param}}

will yield col IS ? for nulls and col = ? otherwise, which should work fine with MySQL prepared statements and the new param filter.

To guard against regressions in null handling, I’d suggest adding a small test case that exercises an index query where the indexed value is null, verifying both the generated SQL and params (e.g., SQL contains IS ? and params array contains a single null).


82-196: Insert values are now parameterized; confirm behavior for JSON/spatial filters

The changes to:

  • Use {{$prop | param}} for non-spatial / non-JSON columns, and
  • Use {{ ($prop | param) if $prop !== undefined else '${now}' }} for gmtCreate/gmtModified

correctly route normal column values and explicit timestamp overrides through the param collector while keeping the default now expression inline.

One thing to double‑check: spatial values (TemplateUtil.getSpatialFilter(...)) and JSON values (| toJson) are still going through their own filters without an explicit | param in this file. If those filters have not been updated to delegate to the param collector (i.e., return '?' and push into params), their values will continue to be inlined instead of parameterized. If you want full parameterization, consider either:

  • Updating the spatial/JSON filters to integrate with the param mechanism internally, or
  • Chaining | param after them here, once you confirm that doing so doesn’t break existing SQL generation.

198-254: Update SET and primary-key predicates fully parameterized; minor shape inconsistency

Switching both branches of the SET logic to:

  • \col` = {{$prop | param}}` for normal columns, and
  • \gmtModified` = {{ ($prop | param) if $prop !== undefined else '${now}' }}`

plus parameterizing the primary-key WHERE (\pk` = {{primary.prop | param}}) brings generateUpdate` in line with the parameterized flow used elsewhere.

Not for this PR, but note that primary-key variables are referenced as $prop (findByPrimary), prop (delete), and primary.prop (update). If there’s no strong reason for these different shapes, unifying the template variable convention across operations would reduce cognitive overhead for future maintainers.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4a8c254 and cce4452.

📒 Files selected for processing (1)
  • core/dal-runtime/src/BaseSqlMap.ts (7 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Runner-ubuntu (18)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: Analyze (typescript)
  • GitHub Check: Runner-ubuntu (20)
  • GitHub Check: Runner-macos (18)
  • GitHub Check: Runner-macos (16)
  • GitHub Check: Runner-macos (20)
  • GitHub Check: Runner-ubuntu (16)
🔇 Additional comments (2)
core/dal-runtime/src/BaseSqlMap.ts (2)

30-49: Primary-key WHERE clause now correctly parameterized

Using | param for all primary-key predicates (\col` = {{$prop | param}}`) aligns with the new param collector and avoids inlined literals. Looks good and consistent with the rest of the param flow.


256-271: Delete by primary-key now parameterized

Using {{prop | param}} for the delete WHERE clause ensures primary-key deletes participate in the bound‑parameter flow rather than inlining values, consistent with the other generators.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
package.json (1)

21-21: Clarify the "20-" naming convention for new scripts.

The new scripts (test:20-, cov:20-, ci:20-) exclude the langchain-decorator workspace, but the "20-" suffix is cryptic without documentation. Is this related to Node.js version constraints on that workspace?

Consider adding an inline comment explaining the naming convention or documenting this in a contributing guide.

Also applies to: 23-23, 35-35

.github/workflows/nodejs.yml (1)

8-8: Rename workflow jobs to clarify Node.js version matrix.

The job naming is misleading: Runner-ubuntu-20- actually runs on Node [16, 18], while the new Runner-ubuntu runs on Node [20]. This contradicts the -20- suffix, which suggests version 20 compatibility testing.

Consider renaming for clarity:

  • Runner-ubuntu-20-Runner-ubuntu-legacy or Runner-ubuntu-16-18
  • Runner-ubuntuRunner-ubuntu-20 (or Runner-ubuntu-latest)
  • Apply the same pattern to macOS jobs

Alternatively, if the -20- suffix has org-wide convention, document it prominently.

Also applies to: 48-48, 84-84, 124-124

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cce4452 and 8cf6299.

📒 Files selected for processing (2)
  • .github/workflows/nodejs.yml (3 hunks)
  • package.json (2 hunks)
🧰 Additional context used
🪛 actionlint (1.7.8)
.github/workflows/nodejs.yml

45-45: the runner of "codecov/codecov-action@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


60-60: the runner of "actions/setup-node@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


81-81: the runner of "codecov/codecov-action@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


105-105: the runner of "actions/setup-node@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


121-121: the runner of "codecov/codecov-action@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: Socket Security: Pull Request Alerts
  • GitHub Check: Analyze (javascript)
  • GitHub Check: Analyze (typescript)
  • GitHub Check: Runner-macos-20- (18)
  • GitHub Check: Runner-ubuntu-20- (18)
  • GitHub Check: Runner-macos (20)
  • GitHub Check: Runner-ubuntu-20- (16)
  • GitHub Check: Runner-macos-20- (16)
  • GitHub Check: Runner-ubuntu (20)
🔇 Additional comments (1)
.github/workflows/nodejs.yml (1)

17-17: Verify alignment between package.json CI scripts and workflow jobs.

The workflow now uses npm run ci:20- (line 41, 78) for older Node versions and npm run ci for Node 20. Confirm that:

  1. The langchain-decorator workspace exclusion in ci:20- doesn't mask failures that should be caught.
  2. Node 20 is sufficiently tested via the full ci script on the new jobs.
  3. This split is intentional and documented somewhere (e.g., in CONTRIBUTING.md).

Also applies to: 39-42

npm run tsc:pub

- name: Code Coverage
uses: codecov/codecov-action@v1
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Update deprecated GitHub Actions to current versions.

Static analysis flagged outdated action versions:

  • codecov/codecov-action@v1 → use @v3 or @v4 (current stable)
  • actions/setup-node@v1 → use @v3 or @v4 (current stable)

These versions are no longer maintained and may lack security patches or have changed behavior on modern GitHub Actions runners.

Apply this diff to update to current versions:

- uses: actions/setup-node@v1
+ uses: actions/setup-node@v4

- uses: codecov/codecov-action@v1
+ uses: codecov/codecov-action@v4

This change applies to all occurrences (lines 29, 60, 105, 136; lines 45, 81, 121, 157).

Also applies to: 60-60, 81-81, 105-105, 121-121

🧰 Tools
🪛 actionlint (1.7.8)

45-45: the runner of "codecov/codecov-action@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🤖 Prompt for AI Agents
In .github/workflows/nodejs.yml around lines 29, 45, 60, 81, 105, 121, 136, and
157, update deprecated action versions: replace all occurrences of
codecov/codecov-action@v1 with a current stable tag (e.g. @v3 or @v4) and
replace actions/setup-node@v1 with a current stable tag (e.g. @v3 or @v4); apply
the same substitution for every listed line so the workflow uses maintained
action versions and then run a quick workflow lint/test to confirm no behavior
changes.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
core/dal-runtime/test/DataSource.test.ts (1)

201-331: Forward all execute arguments in mock and consider de-duping Foo setup

The mm wrapper for client.execute only accepts (sql, params), so any future third options argument would be silently dropped; using a rest parameter and Reflect.apply(originExecute, client, args) would keep the test robust if callers start passing options. Also, the Foo construction here is nearly identical to the earlier execute should work test; a small helper (e.g. buildTestFoo()) would reduce duplication, though it’s purely cosmetic.

plugin/dal/README.md (1)

625-658: Clarify param filter benefits vs existing SQL escaping and optional markdown tweak

The bullet says param prevents SQL injection, while the dedicated section emphasizes parameterized queries, perf, and observability; to avoid confusion with DAL’s built‑in SQL escaping, you could add a note that template values are already escaped by default and param additionally leverages server‑side parameters for better performance and DB observability. If you care about markdownlint MD036, turning **param 过滤器** into a proper heading (for example, #### param 过滤器) would also silence that warning.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8cf6299 and 095fe60.

📒 Files selected for processing (5)
  • .github/workflows/nodejs.yml (1 hunks)
  • core/dal-runtime/src/DataSource.ts (3 hunks)
  • core/dal-runtime/src/MySqlDataSource.ts (5 hunks)
  • core/dal-runtime/test/DataSource.test.ts (1 hunks)
  • plugin/dal/README.md (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/nodejs.yml
🧰 Additional context used
🧬 Code graph analysis (1)
core/dal-runtime/src/DataSource.ts (2)
core/dal-runtime/src/MySqlDataSource.ts (1)
  • EggQueryOptions (22-24)
core/dal-runtime/src/TableModelInstanceBuilder.ts (1)
  • TableModelInstanceBuilder (3-25)
🪛 markdownlint-cli2 (0.18.1)
plugin/dal/README.md

636-636: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Runner-macos (16)
  • GitHub Check: Runner-macos (18)
  • GitHub Check: Runner-macos (20)
🔇 Additional comments (2)
core/dal-runtime/src/MySqlDataSource.ts (1)

2-79: executeType and EggQueryOptions wiring looks consistent

The new executeType option (defaulting to 'query') and the branching in query() between client.execute and client.query, with EggQueryOptions passed through as the third argument, are coherent and align with the new tests and docs; no functional issues stand out.

core/dal-runtime/src/DataSource.ts (1)

3-95: Param propagation and pagination/count plumbing look correct

Threading params through ExecuteSql, all execute/executeRaw/count methods, and paginate (including the separate count SQL and options propagation into mysqlDataSource.query) matches the new parameterized SQL design; behavior looks consistent and I don’t see issues here.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
core/dal-runtime/src/DataSource.ts (1)

7-12: Consider stricter typing for params.

The params: any[] type is very permissive. While SQL parameters can be various types, consider using a union type like params: (string | number | Date | Buffer | null | undefined)[] for better type safety.

Apply this diff for stricter typing:

 export interface ExecuteSql {
   sql: string;
   template: string;
   sqlType: SqlType;
-  params: any[];
+  params: (string | number | Date | Buffer | null | undefined)[];
 }
plugin/dal/README.md (1)

625-658: Excellent documentation for the param filter.

The param filter documentation is comprehensive, with clear examples showing both the template syntax and the generated SQL output. This will help developers understand and use the feature correctly.


Optional: Consider using a proper heading for "param 过滤器".

Line 636 uses bold text (**param 过滤器**) which triggers a markdownlint warning (MD036). Consider using a proper heading for better document structure.

Apply this diff to use a proper heading:

-**param 过滤器**
+#### param 过滤器
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 095fe60 and f9cba6d.

📒 Files selected for processing (4)
  • core/dal-runtime/src/DataSource.ts (3 hunks)
  • core/dal-runtime/src/MySqlDataSource.ts (5 hunks)
  • core/dal-runtime/test/DataSource.test.ts (1 hunks)
  • plugin/dal/README.md (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • core/dal-runtime/test/DataSource.test.ts
  • core/dal-runtime/src/MySqlDataSource.ts
🧰 Additional context used
🧬 Code graph analysis (1)
core/dal-runtime/src/DataSource.ts (1)
core/dal-runtime/src/MySqlDataSource.ts (1)
  • EggQueryOptions (22-24)
🪛 markdownlint-cli2 (0.18.1)
plugin/dal/README.md

636-636: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Runner-ubuntu (18)
  • GitHub Check: Runner-macos (20)
  • GitHub Check: Runner-ubuntu (20)
  • GitHub Check: Runner-macos (18)
  • GitHub Check: Runner-macos (16)
  • GitHub Check: Runner-ubuntu (16)
🔇 Additional comments (10)
core/dal-runtime/src/DataSource.ts (8)

3-3: LGTM!

The import correctly adds the necessary types for parameterized query support and options handling.


32-42: LGTM!

The generateSql method correctly destructures and returns the params array alongside the SQL string, properly implementing the parameterized query support.


44-48: LGTM!

The count method correctly propagates both params and options to the underlying query execution, maintaining backward compatibility with the optional parameter.


49-55: LGTM!

The execute method correctly passes SQL, params, and options to the MySQL data source while maintaining the expected return type.


56-59: LGTM!

The executeRaw method correctly implements parameterized query support with the same pattern as execute.


60-69: LGTM!

Both executeScalar and executeRawScalar correctly accept and forward the options parameter to their underlying methods, maintaining consistency across the API.


70-87: LGTM!

The paginate method correctly handles two separate SQL generations (main query and count query), each with their own params array, and properly propagates both params and options to the underlying query executions.


89-95: LGTM!

The private #paginateCount method correctly accepts and uses the params array and options, completing the consistent parameter propagation throughout the class.

plugin/dal/README.md (2)

80-102: LGTM!

The executeType configuration documentation is comprehensive and includes important warnings about precision issues with the execute mode. The YAML example and mode descriptions are clear and helpful.


598-598: LGTM!

The SQL example correctly demonstrates the param filter usage in the WHERE clause, aligning with the new parameterized query feature.

@killagu killagu merged commit 6d7d8d8 into master Dec 10, 2025
12 checks passed
@killagu killagu deleted the feat/sql_param branch December 10, 2025 03:37
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.

4 participants