Skip to content
Merged
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
63 changes: 0 additions & 63 deletions .github/patches/testbox-full-null.patch

This file was deleted.

1 change: 0 additions & 1 deletion .github/workflows/cron.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ jobs:
- name: Install dependencies
run: |
box install
git apply --unidiff-zero .github/patches/testbox-full-null.patch
git apply --unidiff-zero .github/patches/mementifier-full-null.patch
box config set modules.commandbox-dotenv.checkEnvPreServerStart=false
box install ${{ matrix.coldbox }} --noSave
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ jobs:
- name: Install dependencies
run: |
box install
git apply --unidiff-zero .github/patches/testbox-full-null.patch
git apply --unidiff-zero .github/patches/mementifier-full-null.patch
box config set modules.commandbox-dotenv.checkEnvPreServerStart=false
box install ${{ matrix.coldbox }} --noSave
Expand Down
2 changes: 1 addition & 1 deletion box.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
},
"devDependencies":{
"coldbox":"^8.0.0",
"testbox":"^7.0.0",
"testbox":"^7.1.0",
"cfcollection":"^3.6.4",
"cfmigrations":"^5.0.0"
},
Expand Down
4 changes: 3 additions & 1 deletion dsl/QuickServiceDSL.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ component {
public any function process( required struct definition ) {
return variables.injector.getInstance(
name = "BaseService@quick",
initArguments = { entity : variables.injector.getInstance( listRest( arguments.definition.dsl, ":" ) ) }
initArguments = {
entity : variables.injector.getInstance( listRest( arguments.definition.dsl, ":" ) )
}
);
}

Expand Down
46 changes: 32 additions & 14 deletions models/BaseEntity.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ component accessors="true" {
metadataInspection();
if ( !variables._loadShallow ) {
setUpMementifier();
fireEvent( "instanceReady", { entity : this } );
fireEvent( "instanceReady", { entity : this } );
}
}

Expand Down Expand Up @@ -1172,7 +1172,7 @@ component accessors="true" {
*/
public any function markLoaded() {
variables._loaded = true;
fireEvent( "postLoad", { entity : this } );
fireEvent( "postLoad", { entity : this } );
return this;
}

Expand Down Expand Up @@ -1510,7 +1510,7 @@ component accessors="true" {
*/
public any function fresh() {
var hasRefreshQuery = variables.keyExists( "_refreshQuery" ) && !isNull( variables._refreshQuery );
var freshEntity = hasRefreshQuery ? variables._refreshQuery.clone().offset( 0 ) : newQuery();
var freshEntity = newRefreshQuery();
freshEntity.from( tableName() );
var entityKeyNames = keyNames();
var entityKeyValues = keyValues();
Expand All @@ -1521,6 +1521,9 @@ component accessors="true" {
}
freshQB.addNestedWhereQuery( freshConstraints );
var freshData = freshEntity.first();
if ( isStruct( freshData ) && structIsEmpty( freshData ) ) {
return javacast( "null", "" );
}
if ( !isStruct( freshData ) || structKeyExists( freshData, "isQuickEntity" ) ) {
return freshData;
}
Expand All @@ -1537,9 +1540,7 @@ component accessors="true" {
public any function refresh() {
variables._relationshipsData = {};
variables._relationshipsLoaded = {};
var refreshedEntity = !variables.keyExists( "_refreshQuery" ) || isNull( variables._refreshQuery ) ? newQuery() : variables._refreshQuery
.clone()
.offset( 0 );
var refreshedEntity = newRefreshQuery();
refreshedEntity.from( tableName() );
var entityKeyNames = keyNames();
var entityKeyValues = keyValues();
Expand All @@ -1558,6 +1559,23 @@ component accessors="true" {
return this;
}

/**
* Reuse loaded projections, but refresh by key under current global scopes
* rather than the original query's filters, whose values may have changed.
*/
private any function newRefreshQuery() {
var scopedQuery = newQuery();
if ( !variables.keyExists( "_refreshQuery" ) || isNull( variables._refreshQuery ) ) {
return scopedQuery;
}
var globalQuery = scopedQuery.activateGlobalScopes().getQB();
var refreshQuery = variables._refreshQuery.clone().offset( 0 );
refreshQuery.setWheres( globalQuery.getWheres() );
var refreshBindings = refreshQuery.getRawBindings();
refreshBindings.where = globalQuery.getRawBindings().where;
return refreshQuery;
}

/**
* Return a clone of this entity.
*
Expand Down Expand Up @@ -1950,7 +1968,7 @@ component accessors="true" {
*/
public any function delete() {
guardReadOnly();
fireEvent( "preDelete", { entity : this } );
fireEvent( "preDelete", { entity : this } );
guardAgainstNotLoaded(
"This instance is not loaded so it cannot be deleted. " &
"Did you maybe mean to use `deleteAll`?"
Expand All @@ -1968,12 +1986,12 @@ component accessors="true" {
deleteQuery.updateAll( { "#column#" : deletedDate } );
assignAttribute( column, deletedDate );
assignOriginalAttributes( retrieveAttributesData() );
fireEvent( "postDelete", { entity : this } );
fireEvent( "postDelete", { entity : this } );
return this;
}

forceDelete( fireEvents = false );
fireEvent( "postDelete", { entity : this } );
fireEvent( "postDelete", { entity : this } );
return this;
}

Expand All @@ -1984,7 +2002,7 @@ component accessors="true" {
guardReadOnly();
guardAgainstNotLoaded( "This instance is not loaded so it cannot be force deleted." );
if ( arguments.fireEvents ) {
fireEvent( "preDelete", { entity : this } );
fireEvent( "preDelete", { entity : this } );
}

var deleteQuery = newQuery().withoutGlobalScope( "softDeletes" );
Expand All @@ -2008,7 +2026,7 @@ component accessors="true" {

variables._loaded = false;
if ( arguments.fireEvents ) {
fireEvent( "postDelete", { entity : this } );
fireEvent( "postDelete", { entity : this } );
}
return this;
}
Expand Down Expand Up @@ -2456,7 +2474,7 @@ component accessors="true" {
invoke(
this,
relationshipMethod,
{ entity : relatedEntity }
{ entity : relatedEntity }
);
}
fireEvent(
Expand Down Expand Up @@ -3967,7 +3985,7 @@ component accessors="true" {

param variables._queryOptions = {};
if ( variables._queryOptions.isEmpty() && variables._meta.originalMetadata.keyExists( "datasource" ) ) {
variables._queryOptions = { datasource : variables._meta.originalMetadata.datasource };
variables._queryOptions = { datasource : variables._meta.originalMetadata.datasource };
}
variables._readonly = variables._meta.readonly;
variables._softDeletes = variables._meta.softDeletes;
Expand Down Expand Up @@ -4723,7 +4741,7 @@ component accessors="true" {
invoke(
this,
arguments.eventName,
{ eventData : arguments.eventData }
{ eventData : arguments.eventData }
);
}
announceInterceptionPoint( "quick" & arguments.eventName, arguments.eventData );
Expand Down
16 changes: 4 additions & 12 deletions models/QuickBuilder.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ component accessors="true" transientCache="false" {
}

for ( var keyColumn in getEntity().keyColumns() ) {
var qualifiedKey = getEntity().qualifyColumn( keyColumn );
var qualifiedKey = qualifyColumnForQuery( keyColumn, variables.qb );
var hasKey = false;
for ( var column in selectedColumns ) {
if ( column.type == "simple" && compareNoCase( column.value, qualifiedKey ) == 0 ) {
Expand Down Expand Up @@ -1344,17 +1344,9 @@ component accessors="true" transientCache="false" {
return result;
}

throw(
type = "QuickMissingMethod",
message = arrayToList(
[
"Quick couldn't figure out what to do with [#arguments.missingMethodName#].",
"We tried checking columns, aliases, scopes, and relationships locally.",
"We also forwarded the call on to qb to see if it could do anything with it, but it couldn't."
],
" "
)
);
// A delegated method may succeed without returning a value (for example,
// qb's existence assertions). Missing methods already throw from qb.
return;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions resources/testing/FactoryManager.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ component {
variables.factories[ arguments.name ] = variables.wirebox.getInstance(
name = "#variables.factoryPath#.#arguments.name#Factory",
initArguments = {
entityProvider : variables.wirebox.getInstance(
entityProvider : variables.wirebox.getInstance(
dsl = "provider:#arguments.name#",
targetObject = this
),
context : variables.context
context : variables.context
}
);
}
Expand Down
4 changes: 2 additions & 2 deletions tests/resources/factories/UserFactory.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ component extends="quick.resources.testing.Factory" {
}

any function administrator() {
return state( { type : "admin" } );
return state( { type : "admin" } );
}

any function wired() {
return state( { firstName : isObject( variables.wirebox ) ? "Injected" : "Missing" } );
return state( { firstName : isObject( variables.wirebox ) ? "Injected" : "Missing" } );
}

}
6 changes: 4 additions & 2 deletions tests/specs/integration/BaseEntity/ChildClassSpec.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -378,15 +378,17 @@ component extends="tests.resources.ModuleIntegrationSpec" {
// comment id 4 = internal comment
var internalComment = getInstance( "Comment" )
.findOrFail( 4 )
.update( { reason : "Super private, ya know?" } );
.update( { reason : "Super private, ya know?" } );

var uInternalComment = getInstance( "Comment" ).findOrFail( 4 );

expect( uInternalComment ).toBeInstanceOf( "internalComment" );
expect( uInternalComment.getReason() ).toBe( "Super private, ya know?" );

// comment id 5 = picture comment
var pictureComment = getInstance( "Comment" ).findOrFail( 5 ).update( { filename : "Lenna.jpeg" } );
var pictureComment = getInstance( "Comment" )
.findOrFail( 5 )
.update( { filename : "Lenna.jpeg" } );

var uPictureComment = getInstance( "Comment" ).findOrFail( 5 );

Expand Down
27 changes: 26 additions & 1 deletion tests/specs/integration/BaseEntity/ColumnsSpec.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ component extends="tests.resources.ModuleIntegrationSpec" {

it( "translates attributes to their column names", function() {
expect( function() {
getInstance( "Link" ).create( { url : "https://example.com" } );
getInstance( "Link" ).create( { url : "https://example.com" } );
} ).notToThrow();
} );

Expand All @@ -124,6 +124,31 @@ component extends="tests.resources.ModuleIntegrationSpec" {
expect( user.getUsername() ).toBe( "elpete" );
} );

it( "qualifies automatically selected keys with a derived table alias", function() {
var users = getInstance( "User" )
.newQuery()
.fromSub( "selected_users", getInstance( "User" ).select( [ "id", "username" ] ) )
.reselect( "selected_users.username" )
.orderBy( "selected_users.id" )
.get();
expect( users[ 1 ].getId() ).toBe( 1 );
expect( users[ 1 ].getUsername() ).toBe( "elpete" );
} );

it( "does not add the original table key when a derived key is already selected", function() {
var users = getInstance( "User" )
.newQuery()
.fromSub( "selected_users", getInstance( "User" ).select( [ "id", "username" ] ) )
.reselect( [
"selected_users.id",
"selected_users.username"
] )
.orderBy( "selected_users.id" )
.get();
expect( users[ 1 ].getId() ).toBe( 1 );
expect( users[ 1 ].getUsername() ).toBe( "elpete" );
} );

it( "preserves every composite key column when selecting specific columns", function() {
var composite = getInstance( "Composite" ).select( "a" ).findOrFail( [ 1, 2 ] );

Expand Down
Loading