Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
+ __postgres:__ normalize cast shorthand in default expressions
([0d60086](https://github.com/coldbox-modules/qb/commit/0d600861475e80c769ddcfc9fb649ea8453a169a))

# v13.0.20

### feat

+ __moduleconfig:__ Add shouldWrapValues module setting, applied to configured grammar at module load
([0000000](https://github.com/coldbox-modules/qb/commit/0000000))

# v13.0.19
## 19 Feb 2026 — 19:37:21 UTC
Expand Down
8 changes: 8 additions & 0 deletions ModuleConfig.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ component {
"validateOperatorsAndCombinators": true,
"collectQueryLog": true,
"convertEmptyStringsToNull": true,
"shouldWrapValues": true,
"validateQueryParamStructKeys": true,
"numericSQLType": "NUMERIC",
"integerSQLType": "INTEGER",
Expand Down Expand Up @@ -72,6 +73,13 @@ component {
.map( alias = "SchemaBuilder@qb", force = true )
.to( "qb.models.Schema.SchemaBuilder" )
.initArg( name = "grammar", ref = settings.defaultGrammar );

// Apply shouldWrapValues setting to the configured grammar singleton.
// When defaultGrammar is AutoDiscover@qb, the setting is forwarded via
// onMissingMethod to whatever concrete grammar AutoDiscover resolves at runtime.
if ( structKeyExists( settings, "shouldWrapValues" ) ) {
wirebox.getInstance( settings.defaultGrammar ).setShouldWrapValues( settings.shouldWrapValues );
}
}

}
61 changes: 61 additions & 0 deletions tests/specs/Query/ShouldWrapValuesSpec.cfc
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
component extends="testbox.system.BaseSpec" {

function run() {
describe( "shouldWrapValues setting", function() {

it( "defaults to true in BaseGrammar", function() {
var utils = getMockBox().createMock( "qb.models.Query.QueryUtils" ).init();
var grammar = getMockBox().createMock( "qb.models.Grammars.PostgresGrammar" ).init( utils );

expect( grammar.getShouldWrapValues() ).toBeTrue( "shouldWrapValues should default to true" );
} );

it( "wraps identifiers in double quotes when shouldWrapValues is true", function() {
var utils = getMockBox().createMock( "qb.models.Query.QueryUtils" ).init();
var grammar = getMockBox().createMock( "qb.models.Grammars.PostgresGrammar" ).init( utils );
grammar.setShouldWrapValues( true );

var builder = getMockBox().createMock( "qb.models.Query.QueryBuilder" ).init( grammar );

var sql = builder.from( "users" ).select( "name" ).toSQL();

expect( sql ).toBe( 'SELECT "name" FROM "users"' );

sql = builder.from( "users" ).select( "id" ).where( "email", "test@test.com" ).toSQL( withBindings = true );

expect( sql ).toBe( 'SELECT "id" FROM "users" WHERE "email" = ?' );
} );

it( "does not wrap identifiers when shouldWrapValues is false", function() {
var utils = getMockBox().createMock( "qb.models.Query.QueryUtils" ).init();
var grammar = getMockBox().createMock( "qb.models.Grammars.PostgresGrammar" ).init( utils );
grammar.setShouldWrapValues( false );

var builder = getMockBox().createMock( "qb.models.Query.QueryBuilder" ).init( grammar );

var sql = builder.from( "users" ).select( "name" ).toSQL();

expect( sql ).toBe( "SELECT name FROM users" );

sql = builder.from( "users" ).select( "id" ).where( "email", "test@test.com" ).toSQL();

expect( sql ).toBe( "SELECT id FROM users WHERE email = ?" );
} );

it( "per-query withoutWrappingValues overrides grammar default", function() {
var utils = getMockBox().createMock( "qb.models.Query.QueryUtils" ).init();
var grammar = getMockBox().createMock( "qb.models.Grammars.PostgresGrammar" ).init( utils );
grammar.setShouldWrapValues( true );

var builder = getMockBox().createMock( "qb.models.Query.QueryBuilder" ).init( grammar );

// Grammar default is true, but per-query override to false
var sql = builder.withoutWrappingValues().from( "users" ).select( "name" ).toSQL();

expect( sql ).toBe( "SELECT name FROM users" );
} );

} );
}

}
Loading