@neverinfamous/mysql-mcp 2.3.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +1 -0
- package/.gitattributes +18 -0
- package/.github/workflows/codeql.yml +2 -10
- package/.github/workflows/docker-publish.yml +15 -13
- package/CHANGELOG.md +287 -1
- package/DOCKER_README.md +100 -265
- package/Dockerfile +5 -0
- package/README.md +124 -59
- package/VERSION +1 -1
- package/dist/__tests__/mocks/adapter.d.ts.map +1 -1
- package/dist/__tests__/mocks/adapter.js +2 -0
- package/dist/__tests__/mocks/adapter.js.map +1 -1
- package/dist/adapters/DatabaseAdapter.d.ts.map +1 -1
- package/dist/adapters/DatabaseAdapter.js +50 -9
- package/dist/adapters/DatabaseAdapter.js.map +1 -1
- package/dist/adapters/mysql/MySQLAdapter.d.ts +6 -0
- package/dist/adapters/mysql/MySQLAdapter.d.ts.map +1 -1
- package/dist/adapters/mysql/MySQLAdapter.js +8 -0
- package/dist/adapters/mysql/MySQLAdapter.js.map +1 -1
- package/dist/adapters/mysql/SchemaManager.js +16 -15
- package/dist/adapters/mysql/SchemaManager.js.map +1 -1
- package/dist/adapters/mysql/prompts/index.js +10 -20
- package/dist/adapters/mysql/prompts/index.js.map +1 -1
- package/dist/adapters/mysql/prompts/proxysqlSetup.js +1 -1
- package/dist/adapters/mysql/resources/docstore.d.ts.map +1 -1
- package/dist/adapters/mysql/resources/docstore.js +10 -7
- package/dist/adapters/mysql/resources/docstore.js.map +1 -1
- package/dist/adapters/mysql/resources/events.js +11 -8
- package/dist/adapters/mysql/resources/events.js.map +1 -1
- package/dist/adapters/mysql/resources/indexes.d.ts.map +1 -1
- package/dist/adapters/mysql/resources/indexes.js +12 -15
- package/dist/adapters/mysql/resources/indexes.js.map +1 -1
- package/dist/adapters/mysql/resources/innodb.d.ts.map +1 -1
- package/dist/adapters/mysql/resources/innodb.js +20 -17
- package/dist/adapters/mysql/resources/innodb.js.map +1 -1
- package/dist/adapters/mysql/resources/locks.d.ts.map +1 -1
- package/dist/adapters/mysql/resources/locks.js +9 -6
- package/dist/adapters/mysql/resources/locks.js.map +1 -1
- package/dist/adapters/mysql/resources/performance.d.ts.map +1 -1
- package/dist/adapters/mysql/resources/performance.js +15 -15
- package/dist/adapters/mysql/resources/performance.js.map +1 -1
- package/dist/adapters/mysql/resources/spatial.d.ts.map +1 -1
- package/dist/adapters/mysql/resources/spatial.js +9 -6
- package/dist/adapters/mysql/resources/spatial.js.map +1 -1
- package/dist/adapters/mysql/resources/sysschema.d.ts.map +1 -1
- package/dist/adapters/mysql/resources/sysschema.js +12 -9
- package/dist/adapters/mysql/resources/sysschema.js.map +1 -1
- package/dist/adapters/mysql/tools/admin/backup.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/admin/backup.js +170 -121
- package/dist/adapters/mysql/tools/admin/backup.js.map +1 -1
- package/dist/adapters/mysql/tools/admin/maintenance.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/admin/maintenance.js +106 -57
- package/dist/adapters/mysql/tools/admin/maintenance.js.map +1 -1
- package/dist/adapters/mysql/tools/admin/monitoring.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/admin/monitoring.js +183 -101
- package/dist/adapters/mysql/tools/admin/monitoring.js.map +1 -1
- package/dist/adapters/mysql/tools/cluster/group-replication.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/cluster/group-replication.js +164 -120
- package/dist/adapters/mysql/tools/cluster/group-replication.js.map +1 -1
- package/dist/adapters/mysql/tools/cluster/innodb-cluster.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/cluster/innodb-cluster.js +212 -145
- package/dist/adapters/mysql/tools/cluster/innodb-cluster.js.map +1 -1
- package/dist/adapters/mysql/tools/codemode/index.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/codemode/index.js +6 -4
- package/dist/adapters/mysql/tools/codemode/index.js.map +1 -1
- package/dist/adapters/mysql/tools/core.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/core.js +152 -29
- package/dist/adapters/mysql/tools/core.js.map +1 -1
- package/dist/adapters/mysql/tools/docstore.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/docstore.js +340 -163
- package/dist/adapters/mysql/tools/docstore.js.map +1 -1
- package/dist/adapters/mysql/tools/events.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/events.js +284 -198
- package/dist/adapters/mysql/tools/events.js.map +1 -1
- package/dist/adapters/mysql/tools/json/core.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/json/core.js +11 -39
- package/dist/adapters/mysql/tools/json/core.js.map +1 -1
- package/dist/adapters/mysql/tools/json/enhanced.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/json/enhanced.js +15 -33
- package/dist/adapters/mysql/tools/json/enhanced.js.map +1 -1
- package/dist/adapters/mysql/tools/json/helpers.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/json/helpers.js +13 -24
- package/dist/adapters/mysql/tools/json/helpers.js.map +1 -1
- package/dist/adapters/mysql/tools/partitioning.js +3 -0
- package/dist/adapters/mysql/tools/partitioning.js.map +1 -1
- package/dist/adapters/mysql/tools/performance/analysis.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/performance/analysis.js +89 -60
- package/dist/adapters/mysql/tools/performance/analysis.js.map +1 -1
- package/dist/adapters/mysql/tools/performance/optimization.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/performance/optimization.js +151 -127
- package/dist/adapters/mysql/tools/performance/optimization.js.map +1 -1
- package/dist/adapters/mysql/tools/proxysql.d.ts +1 -1
- package/dist/adapters/mysql/tools/proxysql.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/proxysql.js +289 -176
- package/dist/adapters/mysql/tools/proxysql.js.map +1 -1
- package/dist/adapters/mysql/tools/replication.js +75 -49
- package/dist/adapters/mysql/tools/replication.js.map +1 -1
- package/dist/adapters/mysql/tools/roles.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/roles.js +224 -182
- package/dist/adapters/mysql/tools/roles.js.map +1 -1
- package/dist/adapters/mysql/tools/router.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/router.js +168 -67
- package/dist/adapters/mysql/tools/router.js.map +1 -1
- package/dist/adapters/mysql/tools/schema/constraints.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/schema/constraints.js +21 -3
- package/dist/adapters/mysql/tools/schema/constraints.js.map +1 -1
- package/dist/adapters/mysql/tools/schema/management.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/schema/management.js +61 -14
- package/dist/adapters/mysql/tools/schema/management.js.map +1 -1
- package/dist/adapters/mysql/tools/schema/routines.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/schema/routines.js +27 -4
- package/dist/adapters/mysql/tools/schema/routines.js.map +1 -1
- package/dist/adapters/mysql/tools/schema/scheduled_events.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/schema/scheduled_events.js +24 -3
- package/dist/adapters/mysql/tools/schema/scheduled_events.js.map +1 -1
- package/dist/adapters/mysql/tools/schema/triggers.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/schema/triggers.js +23 -2
- package/dist/adapters/mysql/tools/schema/triggers.js.map +1 -1
- package/dist/adapters/mysql/tools/schema/views.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/schema/views.js +47 -7
- package/dist/adapters/mysql/tools/schema/views.js.map +1 -1
- package/dist/adapters/mysql/tools/security/audit.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/security/audit.js +102 -34
- package/dist/adapters/mysql/tools/security/audit.js.map +1 -1
- package/dist/adapters/mysql/tools/security/data-protection.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/security/data-protection.js +264 -205
- package/dist/adapters/mysql/tools/security/data-protection.js.map +1 -1
- package/dist/adapters/mysql/tools/security/encryption.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/security/encryption.js +137 -104
- package/dist/adapters/mysql/tools/security/encryption.js.map +1 -1
- package/dist/adapters/mysql/tools/shell/backup.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/shell/backup.js +71 -59
- package/dist/adapters/mysql/tools/shell/backup.js.map +1 -1
- package/dist/adapters/mysql/tools/shell/restore.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/shell/restore.js +61 -47
- package/dist/adapters/mysql/tools/shell/restore.js.map +1 -1
- package/dist/adapters/mysql/tools/spatial/geometry.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/spatial/geometry.js +19 -5
- package/dist/adapters/mysql/tools/spatial/geometry.js.map +1 -1
- package/dist/adapters/mysql/tools/spatial/operations.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/spatial/operations.js +42 -17
- package/dist/adapters/mysql/tools/spatial/operations.js.map +1 -1
- package/dist/adapters/mysql/tools/spatial/queries.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/spatial/queries.js +109 -57
- package/dist/adapters/mysql/tools/spatial/queries.js.map +1 -1
- package/dist/adapters/mysql/tools/spatial/setup.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/spatial/setup.js +103 -50
- package/dist/adapters/mysql/tools/spatial/setup.js.map +1 -1
- package/dist/adapters/mysql/tools/stats/comparative.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/stats/comparative.js +128 -79
- package/dist/adapters/mysql/tools/stats/comparative.js.map +1 -1
- package/dist/adapters/mysql/tools/stats/descriptive.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/stats/descriptive.js +174 -102
- package/dist/adapters/mysql/tools/stats/descriptive.js.map +1 -1
- package/dist/adapters/mysql/tools/sysschema/activity.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/sysschema/activity.js +50 -25
- package/dist/adapters/mysql/tools/sysschema/activity.js.map +1 -1
- package/dist/adapters/mysql/tools/sysschema/performance.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/sysschema/performance.js +121 -66
- package/dist/adapters/mysql/tools/sysschema/performance.js.map +1 -1
- package/dist/adapters/mysql/tools/sysschema/resources.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/sysschema/resources.js +101 -64
- package/dist/adapters/mysql/tools/sysschema/resources.js.map +1 -1
- package/dist/adapters/mysql/tools/text/fulltext.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/text/fulltext.js +18 -32
- package/dist/adapters/mysql/tools/text/fulltext.js.map +1 -1
- package/dist/adapters/mysql/tools/transactions.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/transactions.js +48 -23
- package/dist/adapters/mysql/tools/transactions.js.map +1 -1
- package/dist/adapters/mysql/types/proxysql-types.d.ts +15 -0
- package/dist/adapters/mysql/types/proxysql-types.d.ts.map +1 -1
- package/dist/adapters/mysql/types/proxysql-types.js +33 -1
- package/dist/adapters/mysql/types/proxysql-types.js.map +1 -1
- package/dist/adapters/mysql/types/router-types.d.ts +1 -1
- package/dist/adapters/mysql/types/router-types.js +1 -1
- package/dist/adapters/mysql/types/router-types.js.map +1 -1
- package/dist/adapters/mysql/types/shell-types.js +2 -2
- package/dist/adapters/mysql/types/shell-types.js.map +1 -1
- package/dist/adapters/mysql/types.d.ts +485 -21
- package/dist/adapters/mysql/types.d.ts.map +1 -1
- package/dist/adapters/mysql/types.js +546 -19
- package/dist/adapters/mysql/types.js.map +1 -1
- package/dist/auth/scopes.js +1 -1
- package/dist/auth/scopes.js.map +1 -1
- package/dist/codemode/api.d.ts +3 -2
- package/dist/codemode/api.d.ts.map +1 -1
- package/dist/codemode/api.js +80 -5
- package/dist/codemode/api.js.map +1 -1
- package/dist/codemode/sandbox-factory.js +1 -1
- package/dist/codemode/sandbox-factory.js.map +1 -1
- package/dist/codemode/types.d.ts +26 -0
- package/dist/codemode/types.d.ts.map +1 -1
- package/dist/codemode/types.js +2 -0
- package/dist/codemode/types.js.map +1 -1
- package/dist/codemode/worker-sandbox.d.ts +4 -2
- package/dist/codemode/worker-sandbox.d.ts.map +1 -1
- package/dist/codemode/worker-sandbox.js +66 -7
- package/dist/codemode/worker-sandbox.js.map +1 -1
- package/dist/codemode/worker-script.d.ts +3 -0
- package/dist/codemode/worker-script.d.ts.map +1 -1
- package/dist/codemode/worker-script.js +128 -75
- package/dist/codemode/worker-script.js.map +1 -1
- package/dist/constants/ServerInstructions.d.ts +1 -1
- package/dist/constants/ServerInstructions.d.ts.map +1 -1
- package/dist/constants/ServerInstructions.js +37 -31
- package/dist/constants/ServerInstructions.js.map +1 -1
- package/dist/filtering/ToolConstants.d.ts +1 -1
- package/dist/filtering/ToolConstants.d.ts.map +1 -1
- package/dist/filtering/ToolConstants.js +1 -2
- package/dist/filtering/ToolConstants.js.map +1 -1
- package/dist/pool/ConnectionPool.d.ts.map +1 -1
- package/dist/pool/ConnectionPool.js.map +1 -1
- package/dist/transports/http.d.ts.map +1 -1
- package/dist/transports/http.js +6 -0
- package/dist/transports/http.js.map +1 -1
- package/dist/utils/validators.d.ts +1 -1
- package/dist/utils/validators.d.ts.map +1 -1
- package/dist/utils/validators.js.map +1 -1
- package/package.json +4 -4
- package/releases/v2.3.0-release-notes.md +20 -20
- package/releases/v2.3.1-release-notes.md +34 -0
- package/releases/v3.0.0-release-notes.md +81 -0
- package/src/__tests__/mocks/adapter.ts +3 -0
- package/src/__tests__/perf.test.ts +6 -6
- package/src/adapters/DatabaseAdapter.ts +58 -9
- package/src/adapters/__tests__/DatabaseAdapter.test.ts +89 -8
- package/src/adapters/mysql/MySQLAdapter.ts +17 -2
- package/src/adapters/mysql/SchemaManager.ts +21 -21
- package/src/adapters/mysql/__tests__/MySQLAdapter.test.ts +1 -1
- package/src/adapters/mysql/prompts/index.ts +12 -22
- package/src/adapters/mysql/prompts/proxysqlSetup.ts +1 -1
- package/src/adapters/mysql/resources/docstore.ts +13 -10
- package/src/adapters/mysql/resources/events.ts +12 -12
- package/src/adapters/mysql/resources/indexes.ts +17 -19
- package/src/adapters/mysql/resources/innodb.ts +23 -22
- package/src/adapters/mysql/resources/locks.ts +9 -7
- package/src/adapters/mysql/resources/performance.ts +23 -18
- package/src/adapters/mysql/resources/spatial.ts +9 -7
- package/src/adapters/mysql/resources/sysschema.ts +12 -11
- package/src/adapters/mysql/tools/__tests__/core.test.ts +126 -55
- package/src/adapters/mysql/tools/__tests__/docstore.test.ts +459 -88
- package/src/adapters/mysql/tools/__tests__/events.test.ts +281 -103
- package/src/adapters/mysql/tools/__tests__/proxysql.test.ts +128 -28
- package/src/adapters/mysql/tools/__tests__/replication.test.ts +48 -2
- package/src/adapters/mysql/tools/__tests__/roles.test.ts +15 -18
- package/src/adapters/mysql/tools/__tests__/router.test.ts +32 -5
- package/src/adapters/mysql/tools/__tests__/security.test.ts +126 -2
- package/src/adapters/mysql/tools/__tests__/security_injection.test.ts +84 -76
- package/src/adapters/mysql/tools/__tests__/security_integration.test.ts +47 -50
- package/src/adapters/mysql/tools/__tests__/spatial.test.ts +11 -10
- package/src/adapters/mysql/tools/__tests__/spatial_handler.test.ts +54 -38
- package/src/adapters/mysql/tools/__tests__/stats.test.ts +285 -152
- package/src/adapters/mysql/tools/__tests__/transactions.test.ts +13 -13
- package/src/adapters/mysql/tools/admin/__tests__/backup.test.ts +171 -25
- package/src/adapters/mysql/tools/admin/__tests__/maintenance.test.ts +240 -4
- package/src/adapters/mysql/tools/admin/__tests__/monitoring-summary.test.ts +274 -0
- package/src/adapters/mysql/tools/admin/__tests__/monitoring.test.ts +94 -5
- package/src/adapters/mysql/tools/admin/backup.ts +193 -143
- package/src/adapters/mysql/tools/admin/maintenance.ts +118 -69
- package/src/adapters/mysql/tools/admin/monitoring.ts +201 -125
- package/src/adapters/mysql/tools/cluster/__tests__/group-replication.test.ts +69 -0
- package/src/adapters/mysql/tools/cluster/__tests__/innodb-cluster.test.ts +141 -0
- package/src/adapters/mysql/tools/cluster/group-replication.ts +172 -132
- package/src/adapters/mysql/tools/cluster/innodb-cluster.ts +231 -157
- package/src/adapters/mysql/tools/codemode/__tests__/codemode-tool.test.ts +227 -0
- package/src/adapters/mysql/tools/codemode/index.ts +5 -3
- package/src/adapters/mysql/tools/core.ts +152 -38
- package/src/adapters/mysql/tools/docstore.ts +422 -205
- package/src/adapters/mysql/tools/events.ts +334 -233
- package/src/adapters/mysql/tools/json/__tests__/core.test.ts +20 -0
- package/src/adapters/mysql/tools/json/__tests__/enhanced.test.ts +82 -50
- package/src/adapters/mysql/tools/json/__tests__/helpers.test.ts +42 -3
- package/src/adapters/mysql/tools/json/core.ts +21 -42
- package/src/adapters/mysql/tools/json/enhanced.ts +22 -37
- package/src/adapters/mysql/tools/json/helpers.ts +21 -25
- package/src/adapters/mysql/tools/partitioning.ts +3 -0
- package/src/adapters/mysql/tools/performance/__tests__/analysis.test.ts +98 -5
- package/src/adapters/mysql/tools/performance/__tests__/optimization-coverage.test.ts +515 -0
- package/src/adapters/mysql/tools/performance/__tests__/optimization.test.ts +187 -0
- package/src/adapters/mysql/tools/performance/analysis.ts +95 -69
- package/src/adapters/mysql/tools/performance/optimization.ts +182 -153
- package/src/adapters/mysql/tools/proxysql.ts +314 -209
- package/src/adapters/mysql/tools/replication.ts +84 -57
- package/src/adapters/mysql/tools/roles.ts +274 -226
- package/src/adapters/mysql/tools/router.ts +181 -85
- package/src/adapters/mysql/tools/schema/__tests__/constraints.test.ts +13 -0
- package/src/adapters/mysql/tools/schema/__tests__/management.test.ts +60 -25
- package/src/adapters/mysql/tools/schema/__tests__/scheduled_events.test.ts +11 -0
- package/src/adapters/mysql/tools/schema/__tests__/triggers.test.ts +25 -4
- package/src/adapters/mysql/tools/schema/__tests__/views.test.ts +46 -14
- package/src/adapters/mysql/tools/schema/constraints.ts +22 -3
- package/src/adapters/mysql/tools/schema/management.ts +60 -15
- package/src/adapters/mysql/tools/schema/routines.ts +26 -4
- package/src/adapters/mysql/tools/schema/scheduled_events.ts +25 -3
- package/src/adapters/mysql/tools/schema/triggers.ts +27 -2
- package/src/adapters/mysql/tools/schema/views.ts +46 -8
- package/src/adapters/mysql/tools/security/__tests__/audit.test.ts +90 -4
- package/src/adapters/mysql/tools/security/audit.ts +113 -39
- package/src/adapters/mysql/tools/security/data-protection.ts +293 -233
- package/src/adapters/mysql/tools/security/encryption.ts +172 -139
- package/src/adapters/mysql/tools/shell/__tests__/backup.test.ts +29 -0
- package/src/adapters/mysql/tools/shell/backup.ts +90 -73
- package/src/adapters/mysql/tools/shell/restore.ts +62 -48
- package/src/adapters/mysql/tools/spatial/__tests__/operations.test.ts +22 -14
- package/src/adapters/mysql/tools/spatial/__tests__/queries.test.ts +65 -51
- package/src/adapters/mysql/tools/spatial/geometry.ts +23 -7
- package/src/adapters/mysql/tools/spatial/operations.ts +60 -31
- package/src/adapters/mysql/tools/spatial/queries.ts +142 -65
- package/src/adapters/mysql/tools/spatial/setup.ts +121 -55
- package/src/adapters/mysql/tools/stats/__tests__/comparative.test.ts +12 -10
- package/src/adapters/mysql/tools/stats/comparative.ts +150 -98
- package/src/adapters/mysql/tools/stats/descriptive.ts +204 -127
- package/src/adapters/mysql/tools/sysschema/__tests__/error-paths.test.ts +222 -0
- package/src/adapters/mysql/tools/sysschema/__tests__/performance.test.ts +45 -0
- package/src/adapters/mysql/tools/sysschema/__tests__/resources.test.ts +6 -3
- package/src/adapters/mysql/tools/sysschema/activity.ts +52 -27
- package/src/adapters/mysql/tools/sysschema/performance.ts +132 -68
- package/src/adapters/mysql/tools/sysschema/resources.ts +105 -67
- package/src/adapters/mysql/tools/text/__tests__/fulltext.test.ts +45 -17
- package/src/adapters/mysql/tools/text/fulltext.ts +27 -38
- package/src/adapters/mysql/tools/transactions.ts +49 -24
- package/src/adapters/mysql/types/proxysql-types.ts +38 -1
- package/src/adapters/mysql/types/router-types.ts +1 -1
- package/src/adapters/mysql/types/shell-types.ts +2 -2
- package/src/adapters/mysql/types.ts +632 -19
- package/src/auth/__tests__/scopes.test.ts +2 -2
- package/src/auth/scopes.ts +1 -1
- package/src/codemode/__tests__/api.test.ts +417 -0
- package/src/codemode/__tests__/sandbox-factory.test.ts +158 -0
- package/src/codemode/__tests__/sandbox.test.ts +301 -0
- package/src/codemode/__tests__/security.test.ts +368 -0
- package/src/codemode/__tests__/worker-sandbox.test.ts +179 -0
- package/src/codemode/__tests__/worker-script.test.ts +226 -0
- package/src/codemode/api.ts +89 -5
- package/src/codemode/sandbox-factory.ts +1 -1
- package/src/codemode/types.ts +34 -0
- package/src/codemode/worker-sandbox.ts +74 -7
- package/src/codemode/worker-script.ts +157 -86
- package/src/constants/ServerInstructions.ts +37 -31
- package/src/filtering/ToolConstants.ts +1 -2
- package/src/filtering/__tests__/ToolFilter.test.ts +9 -9
- package/src/pool/ConnectionPool.ts +4 -1
- package/src/transports/__tests__/http.test.ts +15 -3
- package/src/transports/http.ts +12 -0
- package/src/utils/validators.ts +2 -1
- package/vitest.config.ts +3 -1
- package/CODE_MODE.md +0 -245
|
@@ -4,7 +4,11 @@
|
|
|
4
4
|
* Tools for managing MySQL's built-in Event Scheduler.
|
|
5
5
|
* 6 tools total.
|
|
6
6
|
*/
|
|
7
|
-
import { z } from "zod";
|
|
7
|
+
import { z, ZodError } from "zod";
|
|
8
|
+
/** Extract human-readable messages from a ZodError instead of raw JSON array */
|
|
9
|
+
function formatZodError(error) {
|
|
10
|
+
return error.issues.map((i) => i.message).join("; ");
|
|
11
|
+
}
|
|
8
12
|
// =============================================================================
|
|
9
13
|
// Zod Schemas
|
|
10
14
|
// =============================================================================
|
|
@@ -12,23 +16,14 @@ const EventCreateSchema = z.object({
|
|
|
12
16
|
name: z.string().describe("Event name"),
|
|
13
17
|
schedule: z
|
|
14
18
|
.object({
|
|
15
|
-
type: z.
|
|
19
|
+
type: z.string().describe("Event schedule type"),
|
|
16
20
|
executeAt: z
|
|
17
21
|
.string()
|
|
18
22
|
.optional()
|
|
19
23
|
.describe('For ONE TIME: timestamp to execute (e.g., "2024-12-31 23:59:59")'),
|
|
20
24
|
interval: z.number().optional().describe("For RECURRING: interval value"),
|
|
21
25
|
intervalUnit: z
|
|
22
|
-
.
|
|
23
|
-
"YEAR",
|
|
24
|
-
"QUARTER",
|
|
25
|
-
"MONTH",
|
|
26
|
-
"DAY",
|
|
27
|
-
"HOUR",
|
|
28
|
-
"MINUTE",
|
|
29
|
-
"WEEK",
|
|
30
|
-
"SECOND",
|
|
31
|
-
])
|
|
26
|
+
.string()
|
|
32
27
|
.optional()
|
|
33
28
|
.describe("For RECURRING: interval unit"),
|
|
34
29
|
starts: z.string().optional().describe("For RECURRING: start timestamp"),
|
|
@@ -37,7 +32,7 @@ const EventCreateSchema = z.object({
|
|
|
37
32
|
.describe("Event schedule configuration"),
|
|
38
33
|
body: z.string().describe("SQL statement(s) to execute"),
|
|
39
34
|
onCompletion: z
|
|
40
|
-
.
|
|
35
|
+
.string()
|
|
41
36
|
.default("NOT PRESERVE")
|
|
42
37
|
.describe("What to do after event completes"),
|
|
43
38
|
enabled: z.boolean().default(true).describe("Whether event is enabled"),
|
|
@@ -49,28 +44,17 @@ const EventAlterSchema = z.object({
|
|
|
49
44
|
newName: z.string().optional().describe("New event name (for rename)"),
|
|
50
45
|
schedule: z
|
|
51
46
|
.object({
|
|
52
|
-
type: z.
|
|
47
|
+
type: z.string().optional(),
|
|
53
48
|
executeAt: z.string().optional(),
|
|
54
49
|
interval: z.number().optional(),
|
|
55
|
-
intervalUnit: z
|
|
56
|
-
.enum([
|
|
57
|
-
"YEAR",
|
|
58
|
-
"QUARTER",
|
|
59
|
-
"MONTH",
|
|
60
|
-
"DAY",
|
|
61
|
-
"HOUR",
|
|
62
|
-
"MINUTE",
|
|
63
|
-
"WEEK",
|
|
64
|
-
"SECOND",
|
|
65
|
-
])
|
|
66
|
-
.optional(),
|
|
50
|
+
intervalUnit: z.string().optional(),
|
|
67
51
|
starts: z.string().optional(),
|
|
68
52
|
ends: z.string().optional(),
|
|
69
53
|
})
|
|
70
54
|
.optional()
|
|
71
55
|
.describe("New schedule configuration"),
|
|
72
56
|
body: z.string().optional().describe("New SQL statement(s)"),
|
|
73
|
-
onCompletion: z.
|
|
57
|
+
onCompletion: z.string().optional(),
|
|
74
58
|
enabled: z.boolean().optional().describe("Enable or disable event"),
|
|
75
59
|
comment: z.string().optional(),
|
|
76
60
|
});
|
|
@@ -123,71 +107,106 @@ function createEventCreateTool(adapter) {
|
|
|
123
107
|
readOnlyHint: false,
|
|
124
108
|
},
|
|
125
109
|
handler: async (params, _context) => {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (existsCheck.rows && existsCheck.rows.length > 0) {
|
|
110
|
+
try {
|
|
111
|
+
const { name, schedule, body, onCompletion, enabled, comment, ifNotExists, } = EventCreateSchema.parse(params);
|
|
112
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {
|
|
113
|
+
return { success: false, error: "Invalid event name" };
|
|
114
|
+
}
|
|
115
|
+
// Validate enum fields at handler level
|
|
116
|
+
const validScheduleTypes = ["ONE TIME", "RECURRING"];
|
|
117
|
+
if (!validScheduleTypes.includes(schedule.type)) {
|
|
135
118
|
return {
|
|
136
|
-
success:
|
|
137
|
-
|
|
138
|
-
reason: "Event already exists",
|
|
139
|
-
eventName: name,
|
|
119
|
+
success: false,
|
|
120
|
+
error: `Invalid schedule type: '${schedule.type}' — expected one of: ${validScheduleTypes.join(", ")}`,
|
|
140
121
|
};
|
|
141
122
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
throw new Error("executeAt is required for ONE TIME events");
|
|
149
|
-
}
|
|
150
|
-
sql += `AT '${schedule.executeAt}'`;
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
if (schedule.interval === undefined ||
|
|
154
|
-
schedule.interval === null ||
|
|
155
|
-
schedule.intervalUnit === undefined ||
|
|
156
|
-
schedule.intervalUnit === null) {
|
|
157
|
-
throw new Error("interval and intervalUnit are required for RECURRING events");
|
|
123
|
+
const validOnCompletion = ["PRESERVE", "NOT PRESERVE"];
|
|
124
|
+
if (!validOnCompletion.includes(onCompletion)) {
|
|
125
|
+
return {
|
|
126
|
+
success: false,
|
|
127
|
+
error: `Invalid onCompletion: '${onCompletion}' — expected one of: ${validOnCompletion.join(", ")}`,
|
|
128
|
+
};
|
|
158
129
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
130
|
+
if (ifNotExists) {
|
|
131
|
+
const existsCheck = await adapter.executeQuery("SELECT EVENT_NAME FROM information_schema.EVENTS WHERE EVENT_SCHEMA = DATABASE() AND EVENT_NAME = ?", [name]);
|
|
132
|
+
if (existsCheck.rows && existsCheck.rows.length > 0) {
|
|
133
|
+
return {
|
|
134
|
+
success: true,
|
|
135
|
+
skipped: true,
|
|
136
|
+
reason: "Event already exists",
|
|
137
|
+
eventName: name,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
162
140
|
}
|
|
163
|
-
|
|
164
|
-
|
|
141
|
+
const ifNotExistsClause = ifNotExists ? "IF NOT EXISTS " : "";
|
|
142
|
+
let sql = `CREATE EVENT ${ifNotExistsClause}\`${name}\`\nON SCHEDULE `;
|
|
143
|
+
if (schedule.type === "ONE TIME") {
|
|
144
|
+
if (!schedule.executeAt) {
|
|
145
|
+
return {
|
|
146
|
+
success: false,
|
|
147
|
+
error: "executeAt is required for ONE TIME events",
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
sql += `AT '${schedule.executeAt}'`;
|
|
165
151
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
152
|
+
else {
|
|
153
|
+
if (schedule.interval === undefined ||
|
|
154
|
+
schedule.interval === null ||
|
|
155
|
+
schedule.intervalUnit === undefined ||
|
|
156
|
+
schedule.intervalUnit === null) {
|
|
157
|
+
return {
|
|
158
|
+
success: false,
|
|
159
|
+
error: "interval and intervalUnit are required for RECURRING events",
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
const validUnits = [
|
|
163
|
+
"YEAR",
|
|
164
|
+
"QUARTER",
|
|
165
|
+
"MONTH",
|
|
166
|
+
"DAY",
|
|
167
|
+
"HOUR",
|
|
168
|
+
"MINUTE",
|
|
169
|
+
"WEEK",
|
|
170
|
+
"SECOND",
|
|
171
|
+
];
|
|
172
|
+
if (!validUnits.includes(schedule.intervalUnit)) {
|
|
173
|
+
return {
|
|
174
|
+
success: false,
|
|
175
|
+
error: `Invalid intervalUnit: '${schedule.intervalUnit}' — expected one of: ${validUnits.join(", ")}`,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
sql += `EVERY ${String(schedule.interval)} ${schedule.intervalUnit}`;
|
|
179
|
+
if (schedule.starts) {
|
|
180
|
+
sql += ` STARTS '${schedule.starts}'`;
|
|
181
|
+
}
|
|
182
|
+
if (schedule.ends) {
|
|
183
|
+
sql += ` ENDS '${schedule.ends}'`;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
sql += `\nON COMPLETION ${onCompletion}`;
|
|
187
|
+
if (!enabled) {
|
|
188
|
+
sql += "\nDISABLE";
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
sql += "\nENABLE";
|
|
192
|
+
}
|
|
193
|
+
if (comment) {
|
|
194
|
+
sql += `\nCOMMENT '${comment.replace(/'/g, "''")}'`;
|
|
195
|
+
}
|
|
196
|
+
sql += `\nDO ${body}`;
|
|
179
197
|
await adapter.executeQuery(sql);
|
|
180
198
|
return { success: true, eventName: name };
|
|
181
199
|
}
|
|
182
200
|
catch (error) {
|
|
201
|
+
if (error instanceof ZodError) {
|
|
202
|
+
return { success: false, error: formatZodError(error) };
|
|
203
|
+
}
|
|
183
204
|
const message = error instanceof Error ? error.message : String(error);
|
|
184
205
|
if (message.toLowerCase().includes("already exists")) {
|
|
185
|
-
return {
|
|
186
|
-
success: false,
|
|
187
|
-
reason: `Event '${name}' already exists`,
|
|
188
|
-
};
|
|
206
|
+
return { success: false, error: "Event already exists" };
|
|
189
207
|
}
|
|
190
|
-
|
|
208
|
+
const cleaned = message.replace(/^(Query failed: )?(Execute failed: )?/i, "");
|
|
209
|
+
return { success: false, error: cleaned };
|
|
191
210
|
}
|
|
192
211
|
},
|
|
193
212
|
};
|
|
@@ -207,74 +226,113 @@ function createEventAlterTool(adapter) {
|
|
|
207
226
|
readOnlyHint: false,
|
|
208
227
|
},
|
|
209
228
|
handler: async (params, _context) => {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
229
|
+
try {
|
|
230
|
+
const { name, newName, schedule, body, onCompletion, enabled, comment, } = EventAlterSchema.parse(params);
|
|
231
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {
|
|
232
|
+
return { success: false, error: "Invalid event name" };
|
|
233
|
+
}
|
|
234
|
+
// Validate enum fields at handler level
|
|
235
|
+
if (onCompletion !== undefined) {
|
|
236
|
+
const validOnCompletion = ["PRESERVE", "NOT PRESERVE"];
|
|
237
|
+
if (!validOnCompletion.includes(onCompletion)) {
|
|
238
|
+
return {
|
|
239
|
+
success: false,
|
|
240
|
+
error: `Invalid onCompletion: '${onCompletion}' — expected one of: ${validOnCompletion.join(", ")}`,
|
|
241
|
+
};
|
|
223
242
|
}
|
|
224
|
-
scheduleClause += `AT '${schedule.executeAt}'`;
|
|
225
243
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
244
|
+
let sql = `ALTER EVENT \`${name}\``;
|
|
245
|
+
const clauses = [];
|
|
246
|
+
if (schedule?.type) {
|
|
247
|
+
// Validate schedule.type
|
|
248
|
+
const validScheduleTypes = ["ONE TIME", "RECURRING"];
|
|
249
|
+
if (!validScheduleTypes.includes(schedule.type)) {
|
|
250
|
+
return {
|
|
251
|
+
success: false,
|
|
252
|
+
error: `Invalid schedule type: '${schedule.type}' — expected one of: ${validScheduleTypes.join(", ")}`,
|
|
253
|
+
};
|
|
232
254
|
}
|
|
233
|
-
scheduleClause
|
|
234
|
-
if (schedule.
|
|
235
|
-
|
|
255
|
+
let scheduleClause = "ON SCHEDULE ";
|
|
256
|
+
if (schedule.type === "ONE TIME") {
|
|
257
|
+
if (!schedule.executeAt) {
|
|
258
|
+
return {
|
|
259
|
+
success: false,
|
|
260
|
+
error: "executeAt is required for ONE TIME events",
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
scheduleClause += `AT '${schedule.executeAt}'`;
|
|
236
264
|
}
|
|
237
|
-
|
|
238
|
-
|
|
265
|
+
else {
|
|
266
|
+
if (schedule.interval === undefined ||
|
|
267
|
+
schedule.interval === null ||
|
|
268
|
+
schedule.intervalUnit === undefined ||
|
|
269
|
+
schedule.intervalUnit === null) {
|
|
270
|
+
return {
|
|
271
|
+
success: false,
|
|
272
|
+
error: "interval and intervalUnit are required for RECURRING events",
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
const validUnits = [
|
|
276
|
+
"YEAR",
|
|
277
|
+
"QUARTER",
|
|
278
|
+
"MONTH",
|
|
279
|
+
"DAY",
|
|
280
|
+
"HOUR",
|
|
281
|
+
"MINUTE",
|
|
282
|
+
"WEEK",
|
|
283
|
+
"SECOND",
|
|
284
|
+
];
|
|
285
|
+
if (!validUnits.includes(schedule.intervalUnit)) {
|
|
286
|
+
return {
|
|
287
|
+
success: false,
|
|
288
|
+
error: `Invalid intervalUnit: '${schedule.intervalUnit}' — expected one of: ${validUnits.join(", ")}`,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
scheduleClause += `EVERY ${String(schedule.interval)} ${schedule.intervalUnit}`;
|
|
292
|
+
if (schedule.starts) {
|
|
293
|
+
scheduleClause += ` STARTS '${schedule.starts}'`;
|
|
294
|
+
}
|
|
295
|
+
if (schedule.ends) {
|
|
296
|
+
scheduleClause += ` ENDS '${schedule.ends}'`;
|
|
297
|
+
}
|
|
239
298
|
}
|
|
299
|
+
clauses.push(scheduleClause);
|
|
240
300
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
if (onCompletion) {
|
|
244
|
-
clauses.push(`ON COMPLETION ${onCompletion}`);
|
|
245
|
-
}
|
|
246
|
-
if (newName) {
|
|
247
|
-
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(newName)) {
|
|
248
|
-
throw new Error("Invalid new event name");
|
|
301
|
+
if (onCompletion) {
|
|
302
|
+
clauses.push(`ON COMPLETION ${onCompletion}`);
|
|
249
303
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
304
|
+
if (newName) {
|
|
305
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(newName)) {
|
|
306
|
+
return { success: false, error: "Invalid new event name" };
|
|
307
|
+
}
|
|
308
|
+
clauses.push(`RENAME TO \`${newName}\``);
|
|
309
|
+
}
|
|
310
|
+
if (enabled !== undefined) {
|
|
311
|
+
clauses.push(enabled ? "ENABLE" : "DISABLE");
|
|
312
|
+
}
|
|
313
|
+
if (comment !== undefined) {
|
|
314
|
+
clauses.push(`COMMENT '${comment.replace(/'/g, "''")}'`);
|
|
315
|
+
}
|
|
316
|
+
if (body) {
|
|
317
|
+
clauses.push(`DO ${body}`);
|
|
318
|
+
}
|
|
319
|
+
if (clauses.length === 0) {
|
|
320
|
+
return { success: false, error: "No modifications specified" };
|
|
321
|
+
}
|
|
322
|
+
sql += "\n" + clauses.join("\n");
|
|
266
323
|
await adapter.executeQuery(sql);
|
|
267
324
|
return { success: true, eventName: newName ?? name };
|
|
268
325
|
}
|
|
269
326
|
catch (error) {
|
|
327
|
+
if (error instanceof ZodError) {
|
|
328
|
+
return { success: false, error: formatZodError(error) };
|
|
329
|
+
}
|
|
270
330
|
const message = error instanceof Error ? error.message : String(error);
|
|
271
331
|
if (message.toLowerCase().includes("unknown event")) {
|
|
272
|
-
return {
|
|
273
|
-
success: false,
|
|
274
|
-
reason: `Event '${name}' does not exist`,
|
|
275
|
-
};
|
|
332
|
+
return { success: false, error: "Event does not exist" };
|
|
276
333
|
}
|
|
277
|
-
|
|
334
|
+
const cleaned = message.replace(/^(Query failed: )?(Execute failed: )?/i, "");
|
|
335
|
+
return { success: false, error: cleaned };
|
|
278
336
|
}
|
|
279
337
|
},
|
|
280
338
|
};
|
|
@@ -295,37 +353,35 @@ function createEventDropTool(adapter) {
|
|
|
295
353
|
destructiveHint: true,
|
|
296
354
|
},
|
|
297
355
|
handler: async (params, _context) => {
|
|
298
|
-
const { name, ifExists } = EventDropSchema.parse(params);
|
|
299
|
-
// Validate event name
|
|
300
|
-
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {
|
|
301
|
-
throw new Error("Invalid event name");
|
|
302
|
-
}
|
|
303
|
-
// Pre-check event existence for informative messaging
|
|
304
|
-
if (ifExists) {
|
|
305
|
-
const existsCheck = await adapter.executeQuery("SELECT EVENT_NAME FROM information_schema.EVENTS WHERE EVENT_SCHEMA = DATABASE() AND EVENT_NAME = ?", [name]);
|
|
306
|
-
if (!existsCheck.rows || existsCheck.rows.length === 0) {
|
|
307
|
-
return {
|
|
308
|
-
success: true,
|
|
309
|
-
skipped: true,
|
|
310
|
-
reason: "Event did not exist",
|
|
311
|
-
eventName: name,
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
const ifExistsClause = ifExists ? "IF EXISTS " : "";
|
|
316
356
|
try {
|
|
357
|
+
const { name, ifExists } = EventDropSchema.parse(params);
|
|
358
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {
|
|
359
|
+
return { success: false, error: "Invalid event name" };
|
|
360
|
+
}
|
|
361
|
+
if (ifExists) {
|
|
362
|
+
const existsCheck = await adapter.executeQuery("SELECT EVENT_NAME FROM information_schema.EVENTS WHERE EVENT_SCHEMA = DATABASE() AND EVENT_NAME = ?", [name]);
|
|
363
|
+
if (!existsCheck.rows || existsCheck.rows.length === 0) {
|
|
364
|
+
return {
|
|
365
|
+
success: true,
|
|
366
|
+
skipped: true,
|
|
367
|
+
reason: "Event did not exist",
|
|
368
|
+
eventName: name,
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
const ifExistsClause = ifExists ? "IF EXISTS " : "";
|
|
317
373
|
await adapter.executeQuery(`DROP EVENT ${ifExistsClause}\`${name}\``);
|
|
318
374
|
return { success: true, eventName: name };
|
|
319
375
|
}
|
|
320
376
|
catch (error) {
|
|
377
|
+
if (error instanceof ZodError) {
|
|
378
|
+
return { success: false, error: formatZodError(error) };
|
|
379
|
+
}
|
|
321
380
|
const message = error instanceof Error ? error.message : String(error);
|
|
322
381
|
if (message.toLowerCase().includes("unknown event")) {
|
|
323
|
-
return {
|
|
324
|
-
success: false,
|
|
325
|
-
reason: `Event '${name}' does not exist`,
|
|
326
|
-
};
|
|
382
|
+
return { success: false, error: "Event does not exist" };
|
|
327
383
|
}
|
|
328
|
-
|
|
384
|
+
return { success: false, error: message };
|
|
329
385
|
}
|
|
330
386
|
},
|
|
331
387
|
};
|
|
@@ -346,15 +402,16 @@ function createEventListTool(adapter) {
|
|
|
346
402
|
idempotentHint: true,
|
|
347
403
|
},
|
|
348
404
|
handler: async (params, _context) => {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
405
|
+
try {
|
|
406
|
+
const { schema, includeDisabled } = EventListSchema.parse(params);
|
|
407
|
+
// P154: Schema existence check when explicitly provided
|
|
408
|
+
if (schema) {
|
|
409
|
+
const schemaCheck = await adapter.executeQuery("SELECT SCHEMA_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = ?", [schema]);
|
|
410
|
+
if (!schemaCheck.rows || schemaCheck.rows.length === 0) {
|
|
411
|
+
return { exists: false, schema };
|
|
412
|
+
}
|
|
355
413
|
}
|
|
356
|
-
|
|
357
|
-
let query = `
|
|
414
|
+
let query = `
|
|
358
415
|
SELECT
|
|
359
416
|
EVENT_NAME as name,
|
|
360
417
|
EVENT_SCHEMA as schemaName,
|
|
@@ -372,16 +429,24 @@ function createEventListTool(adapter) {
|
|
|
372
429
|
FROM information_schema.EVENTS
|
|
373
430
|
WHERE EVENT_SCHEMA = COALESCE(?, DATABASE())
|
|
374
431
|
`;
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
432
|
+
const queryParams = [schema ?? null];
|
|
433
|
+
if (!includeDisabled) {
|
|
434
|
+
query += " AND STATUS = 'ENABLED'";
|
|
435
|
+
}
|
|
436
|
+
query += " ORDER BY EVENT_NAME";
|
|
437
|
+
const result = await adapter.executeQuery(query, queryParams);
|
|
438
|
+
return {
|
|
439
|
+
events: result.rows,
|
|
440
|
+
count: result.rows?.length ?? 0,
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
catch (error) {
|
|
444
|
+
if (error instanceof ZodError) {
|
|
445
|
+
return { success: false, error: formatZodError(error) };
|
|
446
|
+
}
|
|
447
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
448
|
+
return { success: false, error: message };
|
|
378
449
|
}
|
|
379
|
-
query += " ORDER BY EVENT_NAME";
|
|
380
|
-
const result = await adapter.executeQuery(query, queryParams);
|
|
381
|
-
return {
|
|
382
|
-
events: result.rows,
|
|
383
|
-
count: result.rows?.length ?? 0,
|
|
384
|
-
};
|
|
385
450
|
},
|
|
386
451
|
};
|
|
387
452
|
}
|
|
@@ -401,15 +466,16 @@ function createEventStatusTool(adapter) {
|
|
|
401
466
|
idempotentHint: true,
|
|
402
467
|
},
|
|
403
468
|
handler: async (params, _context) => {
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
469
|
+
try {
|
|
470
|
+
const { name, schema } = EventStatusSchema.parse(params);
|
|
471
|
+
// P154: Schema existence check when explicitly provided
|
|
472
|
+
if (schema) {
|
|
473
|
+
const schemaCheck = await adapter.executeQuery("SELECT SCHEMA_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = ?", [schema]);
|
|
474
|
+
if (!schemaCheck.rows || schemaCheck.rows.length === 0) {
|
|
475
|
+
return { exists: false, schema };
|
|
476
|
+
}
|
|
410
477
|
}
|
|
411
|
-
|
|
412
|
-
const query = `
|
|
478
|
+
const query = `
|
|
413
479
|
SELECT
|
|
414
480
|
EVENT_NAME as name,
|
|
415
481
|
EVENT_SCHEMA as schemaName,
|
|
@@ -432,11 +498,22 @@ function createEventStatusTool(adapter) {
|
|
|
432
498
|
WHERE EVENT_SCHEMA = COALESCE(?, DATABASE())
|
|
433
499
|
AND EVENT_NAME = ?
|
|
434
500
|
`;
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
501
|
+
const result = await adapter.executeQuery(query, [
|
|
502
|
+
schema ?? null,
|
|
503
|
+
name,
|
|
504
|
+
]);
|
|
505
|
+
if (!result.rows || result.rows.length === 0) {
|
|
506
|
+
return { exists: false, name };
|
|
507
|
+
}
|
|
508
|
+
return result.rows[0];
|
|
509
|
+
}
|
|
510
|
+
catch (error) {
|
|
511
|
+
if (error instanceof ZodError) {
|
|
512
|
+
return { success: false, error: formatZodError(error) };
|
|
513
|
+
}
|
|
514
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
515
|
+
return { success: false, error: message };
|
|
438
516
|
}
|
|
439
|
-
return result.rows[0];
|
|
440
517
|
},
|
|
441
518
|
};
|
|
442
519
|
}
|
|
@@ -456,18 +533,19 @@ function createSchedulerStatusTool(adapter) {
|
|
|
456
533
|
idempotentHint: true,
|
|
457
534
|
},
|
|
458
535
|
handler: async (_params, _context) => {
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
536
|
+
try {
|
|
537
|
+
// Get scheduler status
|
|
538
|
+
const statusResult = await adapter.executeQuery("SHOW VARIABLES LIKE 'event_scheduler'");
|
|
539
|
+
// Get event counts by status
|
|
540
|
+
const countResult = await adapter.executeQuery(`
|
|
463
541
|
SELECT
|
|
464
542
|
STATUS as status,
|
|
465
543
|
COUNT(*) as count
|
|
466
544
|
FROM information_schema.EVENTS
|
|
467
545
|
GROUP BY STATUS
|
|
468
546
|
`);
|
|
469
|
-
|
|
470
|
-
|
|
547
|
+
// Get recently executed events
|
|
548
|
+
const recentResult = await adapter.executeQuery(`
|
|
471
549
|
SELECT
|
|
472
550
|
EVENT_NAME as name,
|
|
473
551
|
EVENT_SCHEMA as schemaName,
|
|
@@ -477,13 +555,21 @@ function createSchedulerStatusTool(adapter) {
|
|
|
477
555
|
ORDER BY LAST_EXECUTED DESC
|
|
478
556
|
LIMIT 10
|
|
479
557
|
`);
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
558
|
+
const schedulerStatus = statusResult.rows?.[0];
|
|
559
|
+
return {
|
|
560
|
+
schedulerEnabled: schedulerStatus?.["Value"] === "ON",
|
|
561
|
+
schedulerStatus: schedulerStatus?.["Value"] ?? "UNKNOWN",
|
|
562
|
+
eventCounts: countResult.rows ?? [],
|
|
563
|
+
recentlyExecuted: recentResult.rows ?? [],
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
catch (error) {
|
|
567
|
+
if (error instanceof ZodError) {
|
|
568
|
+
return { success: false, error: formatZodError(error) };
|
|
569
|
+
}
|
|
570
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
571
|
+
return { success: false, error: message };
|
|
572
|
+
}
|
|
487
573
|
},
|
|
488
574
|
};
|
|
489
575
|
}
|