v2.1.1 - Named Placeholders Support for mysql2 Compatibility Layer
New Features
Named Placeholders Support
We're excited to announce full support for named placeholders (:name syntax) in the mysql2 compatibility layer! This feature brings the popular mysql2 library's namedPlaceholders option to the Data API Client, making your queries more readable and maintainable.
Why Named Placeholders?
Instead of positional placeholders:
await connection.query(
'SELECT * FROM users WHERE name = ? AND age > ? AND email = ?',
['Alice', 25, 'alice@example.com']
)Use descriptive named placeholders:
await connection.query(
'SELECT * FROM users WHERE name = :name AND age > :age AND email = :email',
{ name: 'Alice', age: 25, email: 'alice@example.com' }
)Key Features
Connection-Level Configuration
Enable named placeholders globally for a connection or pool:
import { createMySQLConnection } from 'data-api-client/compat/mysql2'
const connection = createMySQLConnection({
resourceArn: 'arn:aws:rds:us-east-1:xxx:cluster:my-cluster',
secretArn: 'arn:aws:secretsmanager:us-east-1:xxx:secret:mySecret',
database: 'myDatabase',
namedPlaceholders: true // Enable named placeholders
})
// All queries can now use named placeholders
await connection.query(
'INSERT INTO users (name, email, age) VALUES (:name, :email, :age)',
{ name: 'Bob', email: 'bob@example.com', age: 30 }
)Query-Level Override
Enable or disable named placeholders per query, overriding the connection setting:
// Connection without namedPlaceholders
const connection = createMySQLConnection({ /* ... */ })
// Enable for specific query
await connection.query(
{
sql: 'SELECT * FROM users WHERE username = :username AND age > :minAge',
namedPlaceholders: true // Enable for this query only
},
{ username: 'john_doe', minAge: 25 }
)
// Or disable for a specific query (when connection has it enabled)
await connection.query(
{
sql: 'SELECT * FROM users WHERE id = ?',
namedPlaceholders: false // Use positional placeholders
},
[123]
)Full Feature Support
✅ All Query Types - Works with SELECT, INSERT, UPDATE, DELETE
✅ Duplicate References - Same parameter can be used multiple times in a query
✅ Transactions - Full support for beginTransaction(), commit(), rollback()
✅ Connection Pools - Works with both direct pool queries and getConnection()
✅ Callback Style - Compatible with both Promise and callback APIs
✅ Numeric Parameters - Supports numeric parameter names like :1, :2
✅ NULL Values - Proper handling of null parameter values
Usage Examples
Basic Usage
import { createMySQLConnection } from 'data-api-client/compat/mysql2'
const connection = createMySQLConnection({
resourceArn: 'arn:...',
secretArn: 'arn:...',
database: 'myDatabase',
namedPlaceholders: true
})
// SELECT
const [users] = await connection.query(
'SELECT * FROM users WHERE age > :minAge AND active = :active',
{ minAge: 25, active: true }
)
// INSERT
await connection.query(
'INSERT INTO users (name, email) VALUES (:name, :email)',
{ name: 'Alice', email: 'alice@example.com' }
)
// UPDATE
await connection.query(
'UPDATE users SET age = :newAge WHERE id = :id',
{ id: 123, newAge: 31 }
)
// DELETE
await connection.query(
'DELETE FROM users WHERE id = :id',
{ id: 456 }
)With Transactions
await connection.beginTransaction()
try {
await connection.query(
'INSERT INTO orders (user_id, total) VALUES (:userId, :total)',
{ userId: 123, total: 99.99 }
)
await connection.query(
'UPDATE users SET last_order = NOW() WHERE id = :userId',
{ userId: 123 }
)
await connection.commit()
} catch (err) {
await connection.rollback()
throw err
}With Connection Pools
import { createMySQLPool } from 'data-api-client/compat/mysql2'
const pool = createMySQLPool({
resourceArn: 'arn:...',
secretArn: 'arn:...',
database: 'myDatabase',
namedPlaceholders: true
})
// Direct pool query
const [products] = await pool.query(
'SELECT * FROM products WHERE category = :category AND price < :maxPrice',
{ category: 'electronics', maxPrice: 500 }
)
// Get connection from pool
const connection = await pool.getConnection()
const [orders] = await connection.query(
'SELECT * FROM orders WHERE user_id = :userId',
{ userId: 123 }
)
connection.release()Duplicate Parameter References
// Same parameter used multiple times
await connection.query(
'SELECT * FROM users WHERE name = :name OR email = :name',
{ name: 'alice' }
)
// SQL: SELECT * FROM users WHERE name = ? OR email = ?
// Values: ['alice', 'alice']Mixed Usage (Query-Level Override)
// Connection defaults to positional placeholders
const connection = createMySQLConnection({ /* ... */ })
// Use positional placeholders (default)
await connection.query('SELECT * FROM users WHERE id = ?', [123])
// Enable named placeholders for specific query
await connection.query(
{ sql: 'SELECT * FROM users WHERE name = :name', namedPlaceholders: true },
{ name: 'Alice' }
)Configuration
Add the namedPlaceholders option to your connection or pool configuration:
| Option | Type | Default | Description |
|---|---|---|---|
namedPlaceholders |
boolean |
false |
Enable named placeholders (:name syntax) for mysql2 compatibility layer. When true, parameters use object format. |
You can also set namedPlaceholders per query in the query options object to override the connection-level setting.
Testing
This release includes comprehensive testing:
- 118 unit tests passing
- 49 integration tests passing (20 new tests for named placeholders)
- Verified with Aurora Serverless MySQL clusters
- Tested with transactions, pools, and callback styles
Documentation
See the Named Placeholders Support section in the README for complete documentation and examples.
Backward Compatibility
This feature is 100% backward compatible:
namedPlaceholdersdefaults tofalse- Existing code using positional
?placeholders continues to work unchanged - No breaking changes
- Opt-in feature
Bug Fixes
No bug fixes in this release.
What's Changed
- feat(mysql2): add namedPlaceholders configuration option in 6785281
- feat(mysql2): implement namedPlaceholders support in 7172f3c
- test(mysql2): add namedPlaceholders integration tests in cf604d7
- docs(mysql2): document namedPlaceholders feature in 06de888
Full Changelog: v2.1.0...v2.1.1
Credits
Feature implemented to resolve issue #142 - Support for namedPlaceholders in mysql2 compatibility layer.
Installation
npm install data-api-client@2.1.1Or update your package.json:
{
"dependencies": {
"data-api-client": "^2.1.1"
}
}🔗 Links
Note: This release maintains full compatibility with Aurora Serverless v1, Aurora Serverless v2, and Aurora provisioned clusters. The feature works seamlessly with ORMs like Drizzle and Kysely.