From 89fc7c81dff9b353106d1dcde00bb3a932957cac Mon Sep 17 00:00:00 2001 From: Github Actions Date: Wed, 19 Apr 2023 13:22:55 +0000 Subject: [PATCH 01/21] Version bump --- box.json | 20 +- changelog.md | 535 +++++++++++++++++++++++++-------------------------- 2 files changed, 277 insertions(+), 278 deletions(-) diff --git a/box.json b/box.json index e206659..43c8900 100644 --- a/box.json +++ b/box.json @@ -1,6 +1,6 @@ { "name":"ColdBox ORM Extensions", - "version":"4.4.0", + "version":"4.5.0", "location":"https://downloads.ortussolutions.com/ortussolutions/coldbox-modules/cborm/@build.version@/cborm-@build.version@.zip", "author":"Ortus Solutions 2022-NOV-17 ### Fixed -* Removal of `lazy` annotations that conflict with cb7 lazy properties +- Removal of `lazy` annotations that conflict with cb7 lazy properties ## [v4.3.1] => 2022-NOV-16 ### Fixed -* Updated `processState()` to `announce()` on all tests +- Updated `processState()` to `announce()` on all tests ## [v4.3.0] => 2022-NOV-16 ### Changed -* Updated `processState()` to `announce()` to stay compliant +- Updated `processState()` to `announce()` to stay compliant ## [v4.2.0] => 2022-NOV-16 ### Changed -* Updated `announceInterception()` to `announce()` to stay compliant +- Updated `announceInterception()` to `announce()` to stay compliant ## [v4.1.0] => 2022-NOV-10 ### Changed -* Updated the way the populator is retrieved so we can be forwards compatible +- Updated the way the populator is retrieved so we can be forwards compatible ## [v4.0.0] => 2022-OCT-10 ### Added -* Upgraded all dependencies to major bumps +- Upgraded all dependencies to major bumps ### Changed -* Dropped ACF2016 Support +- Dropped ACF2016 Support ## [v3.9.0] => 2022-AUG-10 ### Added -* New `when( boolean, success, fail )` fluent construct for `ActiveEntity`, `VirtualEntityService` and the `BaseORMService` to allow for fluent chaining of operations on an entity or it's service. -* Migration to new ColdBox Virtual App Testing approaches -* Removed unecessary on load logging to increase performance -* Hibernate 5.4 on Lucee experimental testing +- New `when( boolean, success, fail )` fluent construct for `ActiveEntity`, `VirtualEntityService` and the `BaseORMService` to allow for fluent chaining of operations on an entity or it's service. +- Migration to new ColdBox Virtual App Testing approaches +- Removed unecessary on load logging to increase performance +- Hibernate 5.4 on Lucee experimental testing ### Fixed -* `countWhere()` invalid SQL exception if no arguments are provided: https://github.com/coldbox-modules/cborm/pull/54 +- `countWhere()` invalid SQL exception if no arguments are provided: ## [v3.8.0] => 2022-MAR-09 ### Fixed -* CBORM-32 - Non-Primary DSN Entities not found. Multi-datasource discovery of entities using virtual services and active entity. This was a regresion since version 1.5. This brings back multi-datasource support for active entity, and virtual entity services. https://github.com/coldbox-modules/cborm/pull/52 -* Detached `Subqueries` was marked as a singleton when indeed it was indeed a transient. This could have created scoping issues on subquery based detached criteria building. -* Varscoping issues in `BaseBuilder` detached projections -* `DetachedCriteriaBuilder` was not passing the `datasource` to native criteria objects +- CBORM-32 - Non-Primary DSN Entities not found. Multi-datasource discovery of entities using virtual services and active entity. This was a regresion since version 1.5. This brings back multi-datasource support for active entity, and virtual entity services. +- Detached `Subqueries` was marked as a singleton when indeed it was indeed a transient. This could have created scoping issues on subquery based detached criteria building. +- Varscoping issues in `BaseBuilder` detached projections +- `DetachedCriteriaBuilder` was not passing the `datasource` to native criteria objects ### Added -* Root `docker-compose.yml` to startup MySQL, or PostgreSQL in docker, for further hacking and testing. -* Java proxy caching to avoid Lucee OSGi issues and increase Java object building performance -* New method in the BaseOrmService: `buildJavaProxy()` which leverages our `JavaProxyBuilder` -* Lazy loading of SQL Helper in criteria queries -* New module template guidelines and CI -* Leverage WireBox aliases for contstruction of internal objects -* Tons of internal docs and links to hibernate docs +- Root `docker-compose.yml` to startup MySQL, or PostgreSQL in docker, for further hacking and testing. +- Java proxy caching to avoid Lucee OSGi issues and increase Java object building performance +- New method in the BaseOrmService: `buildJavaProxy()` which leverages our `JavaProxyBuilder` +- Lazy loading of SQL Helper in criteria queries +- New module template guidelines and CI +- Leverage WireBox aliases for contstruction of internal objects +- Tons of internal docs and links to hibernate docs ## [v3.7.0] => 2022-JAN-13 ### Added -* [CBORM-29](https://ortussolutions.atlassian.net/browse/CBORM-29) Allow SQL projections to be functions containing commas +- [CBORM-29](https://ortussolutions.atlassian.net/browse/CBORM-29) Allow SQL projections to be functions containing commas ## [v3.6.0] => 2022-JAN-10 ### Added -* Removed usage of interface on DSL. Causes more issues than anything with multiple engines. +- Removed usage of interface on DSL. Causes more issues than anything with multiple engines. ### Changed -* Renamed default object DSL +- Renamed default object DSL ## [v3.5.1] => 2022-JAN-10 ### Fixed -* Removed usage of interface on DSL. Causes more issues than anything with multiple engines. +- Removed usage of interface on DSL. Causes more issues than anything with multiple engines. ## [v3.5.0] => 2021-DEC-16 ### Fixed -* [CBORM-20](https://ortussolutions.atlassian.net/browse/CBORM-20) ActiveEntity `evict()` had the wrong method and arguments delegated to the parent class. -* [CBORM-9](https://ortussolutions.atlassian.net/browse/CBORM-9) ACF2021 - org.hibernate.SessionFactory.getAllClassMetadata is no longer supported +- [CBORM-20](https://ortussolutions.atlassian.net/browse/CBORM-20) ActiveEntity `evict()` had the wrong method and arguments delegated to the parent class. +- [CBORM-9](https://ortussolutions.atlassian.net/browse/CBORM-9) ACF2021 - org.hibernate.SessionFactory.getAllClassMetadata is no longer supported ### Improved -* [CBORM-14](https://ortussolutions.atlassian.net/browse/CBORM-14) Inline datasource discovery in base orm service to get a performance boost -* [CBORM-13](https://ortussolutions.atlassian.net/browse/CBORM-13) virtual entity service double creating the orm utility, use the parent one instead of duplicating the effort -* [CBORM-12](https://ortussolutions.atlassian.net/browse/CBORM-12) Lazy load the getORMUtil\(\) and use it only when required. +- [CBORM-14](https://ortussolutions.atlassian.net/browse/CBORM-14) Inline datasource discovery in base orm service to get a performance boost +- [CBORM-13](https://ortussolutions.atlassian.net/browse/CBORM-13) virtual entity service double creating the orm utility, use the parent one instead of duplicating the effort +- [CBORM-12](https://ortussolutions.atlassian.net/browse/CBORM-12) Lazy load the getORMUtil() and use it only when required. ### Added -* [CBORM-22](https://ortussolutions.atlassian.net/browse/CBORM-22) New orm util support method: setupHibernateLogging\(\) thanks to michael born -* [CBORM-19](https://ortussolutions.atlassian.net/browse/CBORM-19) Added a `isInTransaction()` util helper method to all the orm services. -* [CBORM-18](https://ortussolutions.atlassian.net/browse/CBORM-18) New ORM events based on Hibernate 5.4 Events: `ORMFlush, ORMAutoFlush, ORMPreFlush, ORMDirtyCheck, ORMEvict, and ORMClear` -* [CBORM-17](https://ortussolutions.atlassian.net/browse/CBORM-17) Hibernate 5.4 support for lucee new extension -* [CBORM-16](https://ortussolutions.atlassian.net/browse/CBORM-16) Adobe 2021 support and testing automations -* [CBORM-15](https://ortussolutions.atlassian.net/browse/CBORM-15) Migration to github actions -* [CBORM-11](https://ortussolutions.atlassian.net/browse/CBORM-11) Allow Criteria Builder Get\(\) and getOrFail\(\) Methods to Return Projection List Properties -* [CBORM-21](https://ortussolutions.atlassian.net/browse/CBORM-21) New cfformating rules +- [CBORM-22](https://ortussolutions.atlassian.net/browse/CBORM-22) New orm util support method: setupHibernateLogging() thanks to michael born +- [CBORM-19](https://ortussolutions.atlassian.net/browse/CBORM-19) Added a `isInTransaction()` util helper method to all the orm services. +- [CBORM-18](https://ortussolutions.atlassian.net/browse/CBORM-18) New ORM events based on Hibernate 5.4 Events: `ORMFlush, ORMAutoFlush, ORMPreFlush, ORMDirtyCheck, ORMEvict, and ORMClear` +- [CBORM-17](https://ortussolutions.atlassian.net/browse/CBORM-17) Hibernate 5.4 support for lucee new extension +- [CBORM-16](https://ortussolutions.atlassian.net/browse/CBORM-16) Adobe 2021 support and testing automations +- [CBORM-15](https://ortussolutions.atlassian.net/browse/CBORM-15) Migration to github actions +- [CBORM-11](https://ortussolutions.atlassian.net/browse/CBORM-11) Allow Criteria Builder Get() and getOrFail() Methods to Return Projection List Properties +- [CBORM-21](https://ortussolutions.atlassian.net/browse/CBORM-21) New cfformating rules ### Compatibility -* If you upgrade your lucee ORM extension to use Hibernate 5.4, all positional paramters in HQL using `?` has been deprecated. You will have to use the `?x` approach where `x` is a number according to the position in the sql: +- If you upgrade your lucee ORM extension to use Hibernate 5.4, all positional paramters in HQL using `?` has been deprecated. You will have to use the `?x` approach where `x` is a number according to the position in the sql: ```sql // Old Syntax @@ -148,285 +150,278 @@ from Person p where p.name like ?1 and p.isStatus = ?2 ``` - ## [v3.4.0] => 2021-APR-27 ### Added -* Support for Adobe 2021 on resource loader +- Support for Adobe 2021 on resource loader ## [v3.3.0] => 2021-APR-27 ### Added -* New `eventPrefix` setting so you can prefix the resource REST CRUD events with whatever you like. -* Useful exceptions when `results` struct does not have the required keys -* Ability to override the name of the method to use for persistence on the ORM services. Using the `variables.saveMethod` property or the `savemethod` argument. -* Ability to override the name of the method to use for deleting entities on the ORM services. Using the `variables.deleteMethod` property or the `deleteMethod` argument. -* cbSwagger docs +- New `eventPrefix` setting so you can prefix the resource REST CRUD events with whatever you like. +- Useful exceptions when `results` struct does not have the required keys +- Ability to override the name of the method to use for persistence on the ORM services. Using the `variables.saveMethod` property or the `savemethod` argument. +- Ability to override the name of the method to use for deleting entities on the ORM services. Using the `variables.deleteMethod` property or the `deleteMethod` argument. +- cbSwagger docs ### Changed -* Added ACF2016 compatibilities on elvis operator which sucks on ACF2016 -* Avoid using member function son some arrays to allow for working with Java arrays +- Added ACF2016 compatibilities on elvis operator which sucks on ACF2016 +- Avoid using member function son some arrays to allow for working with Java arrays ## [v3.2.1] => 2021-MAR-31 ### Fixed -* Wrong object to get the event handler manager when doing execute query calls +- Wrong object to get the event handler manager when doing execute query calls ## [v3.2.0] => 2021-MAR-31 ### Added -* Exposed a `getSQLHelper()` from criterias to allow for usage of formmatting of sql -* New interception points: `beforeOrmExecuteQuery, afterOrmExecuteQuery` from the base orm service: `executeQuery()` method +- Exposed a `getSQLHelper()` from criterias to allow for usage of formmatting of sql +- New interception points: `beforeOrmExecuteQuery, afterOrmExecuteQuery` from the base orm service: `executeQuery()` method ### Fixed -* Moved `afterCriteriaBuilderList` event before results conversions +- Moved `afterCriteriaBuilderList` event before results conversions ## [v3.1.0] => 2021-MAR-30 ### Added -* Env templates using new lucee bundles and mysql 8 support -* New interception point: `afterCriteriaBuilderGet`, `beforeCriteriaBuilderGet` called after/before criteria `get()` calls +- Env templates using new lucee bundles and mysql 8 support +- New interception point: `afterCriteriaBuilderGet`, `beforeCriteriaBuilderGet` called after/before criteria `get()` calls ### Fixed -* Fixed http to https for downloads -* Fixed watcher pathing +- Fixed http to https for downloads +- Fixed watcher pathing ## [v3.0.0] => 2021-FEB-12 ### Added -* [CBORM-3] - Updated cbValidation to v3 to suppport cbi18n v2 -* [CBORM-4] - asQuery update to default it to false -* [CBORM-5] - Document v3 variant in the docs +- [CBORM-3] - Updated cbValidation to v3 to suppport cbi18n v2 +- [CBORM-4] - asQuery update to default it to false +- [CBORM-5] - Document v3 variant in the docs ## Improved -* [CBORM-6] - Source code cleanups by applying formatting rules +- [CBORM-6] - Source code cleanups by applying formatting rules ### Fixed -* [CBORM-2] - isDirty() not working with ActiveEntity due to missing entity passed +- [CBORM-2] - isDirty() not working with ActiveEntity due to missing entity passed ## [v2.6.0] => 2020-NOV-25 ### Added -* Entities are now created, auto-wired and THEN populated when using the `new()` method instead of being auto-wired after population. -* Made `processEntityInjection()` public on the ORM Event Handler so it can be reused in other locations -* `processEntityInjection()` returns the passed entity so you can do chaining -* `getOrFail()` now includes in the `extendedInfo` the actual entity that caused the exception -* Formatting according to new rules -* Updated changelogs to new standards -* Added auto-publishing of changelogs to github -* Pinning to ColdBox 6 for base testing -* ColdBox 6 graceful shutdowns for tests -* Base Test Case for all tests for faster executions and cleanup due to base reusability +- Entities are now created, auto-wired and THEN populated when using the `new()` method instead of being auto-wired after population. +- Made `processEntityInjection()` public on the ORM Event Handler so it can be reused in other locations +- `processEntityInjection()` returns the passed entity so you can do chaining +- `getOrFail()` now includes in the `extendedInfo` the actual entity that caused the exception +- Formatting according to new rules +- Updated changelogs to new standards +- Added auto-publishing of changelogs to github +- Pinning to ColdBox 6 for base testing +- ColdBox 6 graceful shutdowns for tests +- Base Test Case for all tests for faster executions and cleanup due to base reusability ### Fixed -* Typo on `ORMUtilSupport` when detecting datasources, if you passed a default it would never be used -* `postNew` was not using the actual entity name so we where hitting performance on lookups for name -* compose relationships was `false` for resource handler and it needed to be `true` -* Increased timeouts for tests, due to Adobe issues with long compile times in latest patch levels that suck! -* Unique validator test was clearing the full app scope and trigger multiple testing issues +- Typo on `ORMUtilSupport` when detecting datasources, if you passed a default it would never be used +- `postNew` was not using the actual entity name so we where hitting performance on lookups for name +- compose relationships was `false` for resource handler and it needed to be `true` +- Increased timeouts for tests, due to Adobe issues with long compile times in latest patch levels that suck! +- Unique validator test was clearing the full app scope and trigger multiple testing issues ## [v2.5.0] => 2020-APR-20 -* `Features` : Introduction of the automatic resource handler for ORM Entities based on ColdBox's 6 resources and RestHandler -* `Improvement` : Natively allow for nested transactions and savepoints by not doing preemptive transaction commits when using transactions. -* `Bug` : Fix on `getOrFail()` where if the id was 0, it would still return an empty object. -* `Task` : Added formatting via cfformat +- `Features` : Introduction of the automatic resource handler for ORM Entities based on ColdBox's 6 resources and RestHandler +- `Improvement` : Natively allow for nested transactions and savepoints by not doing preemptive transaction commits when using transactions. +- `Bug` : Fix on `getOrFail()` where if the id was 0, it would still return an empty object. +- `Task` : Added formatting via cfformat ## [v2.4.0] => 2020-JAN-31 -* `Feature` : Upgraded to `cbValidation` 2.0.0 -* `Feature` : Updated the unique validator to match 2.0.0 standards -* `Feature` : Upgraded to `mementifier` 2.0.0 +- `Feature` : Upgraded to `cbValidation` 2.0.0 +- `Feature` : Updated the unique validator to match 2.0.0 standards +- `Feature` : Upgraded to `mementifier` 2.0.0 ## [v2.3.0] -* `improvement` : In `executeQuery()` Determine if we are in a UPDATE, INSERT or DELETE, if we do, just return the results instead of a stream or query as the result is always numeric, the rows that were altered. -* `bug` : Fixed `asStream` typo on `executeQuery()` -* `bug` : Missing ACF2016 compat on tests +- `improvement` : In `executeQuery()` Determine if we are in a UPDATE, INSERT or DELETE, if we do, just return the results instead of a stream or query as the result is always numeric, the rows that were altered. +- `bug` : Fixed `asStream` typo on `executeQuery()` +- `bug` : Missing ACF2016 compat on tests ## [v2.2.1] -* `bug` : virtual entity service still had `entity` required for casting methods +- `bug` : virtual entity service still had `entity` required for casting methods ## [v2.2.0] -* `Feature`: New function for criteria query `when( boolean, target )` that you can use to build functional criterias without the use of if statements. - -``` -newCriteria() - .when( isBoolean( arguments.isPublished ), function( c ){ - // Published bit - c.isEq( "isPublished", isPublished ); - // Published eq true evaluate other params - if( isPublished ){ - c.isLt( "publishedDate", now() ) - .$or( c.restrictions.isNull( "expireDate" ), c.restrictions.isGT( "expireDate", now() ) ) - .isEq( "passwordProtection","" ); - } - } ) - .when( !isNull( arguments.showInSearch ), function( criteria ){ - c.isEq( "showInSearch", showInSearch ); - } ) - .list() -``` - -* `Feature`: Missing `nullValue()` is BaseBuilder class -* `Feature`: Added new criteria query `peek( closure )` function to allow for peeking into the building process. Pass in your closure that receives the criteria and interact with it. -* `Feature`: Added a `validateOrFail()` to the active entity, which if the validation fails it will throw an exception or return back to you the same entity validated now. -* `Improvement`: Better documentation for `deleteById()` since it does bulk deletion, which does not do any type of cascading. -* `Improvement`: `isValid()` in active entity missing `includeFields` argument -* `Improvement`: Timeout hints for criteria builder -* `Improvement`: Updated exception type for criteria builder `get()` -* `Bug`: ACF2016 issues with elvis operator. -* `Bug`: `getOrFail()` had an invalid throw statement +- `Feature`: New function for criteria query `when( boolean, target )` that you can use to build functional criterias without the use of if statements. + + + newCriteria() + .when( isBoolean( arguments.isPublished ), function( c ){ + // Published bit + c.isEq( "isPublished", isPublished ); + // Published eq true evaluate other params + if( isPublished ){ + c.isLt( "publishedDate", now() ) + .$or( c.restrictions.isNull( "expireDate" ), c.restrictions.isGT( "expireDate", now() ) ) + .isEq( "passwordProtection","" ); + } + } ) + .when( !isNull( arguments.showInSearch ), function( criteria ){ + c.isEq( "showInSearch", showInSearch ); + } ) + .list() + +- `Feature`: Missing `nullValue()` is BaseBuilder class +- `Feature`: Added new criteria query `peek( closure )` function to allow for peeking into the building process. Pass in your closure that receives the criteria and interact with it. +- `Feature`: Added a `validateOrFail()` to the active entity, which if the validation fails it will throw an exception or return back to you the same entity validated now. +- `Improvement`: Better documentation for `deleteById()` since it does bulk deletion, which does not do any type of cascading. +- `Improvement`: `isValid()` in active entity missing `includeFields` argument +- `Improvement`: Timeout hints for criteria builder +- `Improvement`: Updated exception type for criteria builder `get()` +- `Bug`: ACF2016 issues with elvis operator. +- `Bug`: `getOrFail()` had an invalid throw statement ## [v2.1.0] -* Change `populate()` in ActiveEntity so the target is the last argument so you can just pass a struct as the first argument [#29](https://github.com/coldbox-modules/cborm/issues/29) -* Make the `save()` operation return the saved entity or array of entities instead of the BaseORM service [#28](https://github.com/coldbox-modules/cborm/issues/28) +- Change `populate()` in ActiveEntity so the target is the last argument so you can just pass a struct as the first argument [#29](https://github.com/coldbox-modules/cborm/issues/29) +- Make the `save()` operation return the saved entity or array of entities instead of the BaseORM service [#28](https://github.com/coldbox-modules/cborm/issues/28) ## [v2.0.0] ### Compatibility Updates -* You will need to move the `orm` configuration structure in your `config/ColdBox.cfc` to the `moduleSettings` struct and rename it to `cborm` to standardize it to module settings. +- You will need to move the `orm` configuration structure in your `config/ColdBox.cfc` to the `moduleSettings` struct and rename it to `cborm` to standardize it to module settings. -``` -moduleSettings = { - cborm = { - inject = { - enabled = true, - includes = "", - excludes = "" - } - } + moduleSettings = { -}; -``` + cborm = { + inject = { + enabled = true, + includes = "", + excludes = "" + } + } + + }; -* `deleteByQuery()` reworked entirely to do native bulk delete queries. It now also returns the number of records removed -* The `evict()` method was renamed to `evictCollection()` to better satisfy the same contract in hibernate -* The `evictEntity()` method was renamed to `evict()` to better satisfay the same contract in hibernate -* Removed `byExample` on many listing methods +- `deleteByQuery()` reworked entirely to do native bulk delete queries. It now also returns the number of records removed +- The `evict()` method was renamed to `evictCollection()` to better satisfy the same contract in hibernate +- The `evictEntity()` method was renamed to `evict()` to better satisfay the same contract in hibernate +- Removed `byExample` on many listing methods ### General Updates -* **Mementifier** is now a dependency for cborm (www.forgebox.io/view/mementifier), which can be used for producing state out of ORM entities for auditing or building JSON Api's. -* **cbStreams** is now a dependency for cborm (www.forgebox.io/view/cbstreams), all criteria queries and major listing methods support the return of streams instead of array of objects -* Full Null Support -* Performance update on creating active entities as datasource discovery has been reworked -* Updated build process to latest in Ortus template -* Dropped Railo, Lucee 4.5, ACF11 support -* More direct scoping for performance updates -* Optimized EventHandler so it is lighter and quicker when doing orm injections -* Documented all functions with extra examples and notes and hibernate references -* ColdBox 5 and 4 discrete ORM Injection DSLs +- **Mementifier** is now a dependency for cborm (www.forgebox.io/view/mementifier), which can be used for producing state out of ORM entities for auditing or building JSON Api's. +- **cbStreams** is now a dependency for cborm (www.forgebox.io/view/cbstreams), all criteria queries and major listing methods support the return of streams instead of array of objects +- Full Null Support +- Performance update on creating active entities as datasource discovery has been reworked +- Updated build process to latest in Ortus template +- Dropped Railo, Lucee 4.5, ACF11 support +- More direct scoping for performance updates +- Optimized EventHandler so it is lighter and quicker when doing orm injections +- Documented all functions with extra examples and notes and hibernate references +- ColdBox 5 and 4 discrete ORM Injection DSLs ### Criteria Queries -* They have been adapted to work with Hibernate 3, 4 and 5 -* New fail fast method for `get()` -> `getOrFail()` to throw an entity not found exception -* New alias methods for controlling the result transformations `asStruct(), asStream(), asDistinct()` that will apply result transformers for you instead of doing `.resultTransformer( c.ALIAS_TO_ENTITY_MAP )`, whish is long and boring, or return to you a java stream via cbStreams. -* When calling native restrictions, no more reflection is used to discover the restriction type thus increasing over 70% in performance when creating criteria queries -* You can now negate any criteria restriction by prefixing it with a `not`. So you can do: `.notEq(), notBetween(), notIsNull(), notIsIn()` and much more. -* The `list()` method has a new `asStream` boolean argument that if true, will return the results as a cbStream. ((www.forgebox.io/view/cbStreams)) -* New Methods: `idCast()` and `autoCast()` added for quick casting of values -* New method: `queryHint()` so you can add your own vendor specific query hints for optimizers. -* New method: `comment( string )` so you can add arbitrary comments to the generated SQL, great for debugging -* `sqlRestriction()` deprecated in favor of the shorthand notation: `sql()` -* The `sql()` restriction now supports binding positional parameters. You can pass them in an array and we will infer the types: `sql( "id = ? and isActive = ?", [ "123", true ] )`. Or you can pass in a struct of `{value:"", type:""}` instead: +- They have been adapted to work with Hibernate 3, 4 and 5 +- New fail fast method for `get()` -> `getOrFail()` to throw an entity not found exception +- New alias methods for controlling the result transformations `asStruct(), asStream(), asDistinct()` that will apply result transformers for you instead of doing `.resultTransformer( c.ALIAS_TO_ENTITY_MAP )`, whish is long and boring, or return to you a java stream via cbStreams. +- When calling native restrictions, no more reflection is used to discover the restriction type thus increasing over 70% in performance when creating criteria queries +- You can now negate any criteria restriction by prefixing it with a `not`. So you can do: `.notEq(), notBetween(), notIsNull(), notIsIn()` and much more. +- The `list()` method has a new `asStream` boolean argument that if true, will return the results as a cbStream. ((www.forgebox.io/view/cbStreams)) +- New Methods: `idCast()` and `autoCast()` added for quick casting of values +- New method: `queryHint()` so you can add your own vendor specific query hints for optimizers. +- New method: `comment( string )` so you can add arbitrary comments to the generated SQL, great for debugging +- `sqlRestriction()` deprecated in favor of the shorthand notation: `sql()` +- The `sql()` restriction now supports binding positional parameters. You can pass them in an array and we will infer the types: `sql( "id = ? and isActive = ?", [ "123", true ] )`. Or you can pass in a struct of `{value:"", type:""}` instead: -``` -restrictions.sql( "userName = ? and firstName like ?", [ - { value : "joe", type : "string" }, - { value : "%joe%", type : "string" } -] ); -``` -The available types are the following which match the Hibernate Types + restrictions.sql( "userName = ? and firstName like ?", [ + { value : "joe", type : "string" }, + { value : "%joe%", type : "string" } + ] ); -``` -this.TYPES = { - "string" : "StringType", - "clob" : "ClobType", - "text" : "TextType", - "char" : "ChareacterType", - "boolean" : "BooleanType", - "yesno" : "YesNoType", - "truefalse" : "TrueFalseType", - "byte" : "ByteType", - "short" : "ShortType", - "integer" : "IntegerType", - "long" : "LongType", - "float" : "FloatType", - "double" : "DoubleType", - "bigInteger" : "BigIntegerType", - "bigDecimal" : "BigDecimalType", - "timestamp" : "TimestampType", - "time" : "TimeType", - "date" : "DateType", - "calendar" : "CalendarType", - "currency" : "CurrencyType", - "locale" : "LocaleType", - "timezone" : "TimeZoneType", - "url" : "UrlType", - "class" : "ClassType", - "blob" : "BlobType", - "binary" : "BinaryType", - "uuid" : "UUIDCharType", - "serializable" : "SerializableType" -}; -``` - -* Detached Criteria builder now has a `maxResults( maxResults )` method to limit the results by -* Detached Criteria sql projections now take aliases into account -* SQL Projections and SQL Group By projections now respect aliases +The available types are the following which match the Hibernate Types + this.TYPES = { + "string" : "StringType", + "clob" : "ClobType", + "text" : "TextType", + "char" : "ChareacterType", + "boolean" : "BooleanType", + "yesno" : "YesNoType", + "truefalse" : "TrueFalseType", + "byte" : "ByteType", + "short" : "ShortType", + "integer" : "IntegerType", + "long" : "LongType", + "float" : "FloatType", + "double" : "DoubleType", + "bigInteger" : "BigIntegerType", + "bigDecimal" : "BigDecimalType", + "timestamp" : "TimestampType", + "time" : "TimeType", + "date" : "DateType", + "calendar" : "CalendarType", + "currency" : "CurrencyType", + "locale" : "LocaleType", + "timezone" : "TimeZoneType", + "url" : "UrlType", + "class" : "ClassType", + "blob" : "BlobType", + "binary" : "BinaryType", + "uuid" : "UUIDCharType", + "serializable" : "SerializableType" + }; + +- Detached Criteria builder now has a `maxResults( maxResults )` method to limit the results by +- Detached Criteria sql projections now take aliases into account +- SQL Projections and SQL Group By projections now respect aliases ### Base ORM Service -* New Fail fast methods: `getOrFail() proxies to get(), findOrFail() proxies to findIt()` that if not entity is produced will throw a `EntityNotFound` exception -* All listing methods can now return the results as a cbStream by passing the `asStream` boolean argument. -* Removed `criteriaCount(), criteriaQuery()` from BaseService, this was the legacy criteria builder approach, please use `newCriteria()` instead. -* Update `getEntityGivenName` to support ACF2018 -* Lazy loading `BeanPopulator` for performance on creations -* Lazy loading `ORMEventHandler` for performance on creations -* Lazy loading `restrictions` for performance on creations -* Base service can now be initialized with a `datasource`, or uses the default one declared -* Added optional `datasource` to many listing methods -* Added consistency on querying options to all major functions to include `ignoreCase, sorting and timeouts`. -* Added ability to `getAll()` to retrieve read only entities using the `readOnly` argument. -* The `getAll()` method has a new `properties` argument that if passed will allow you to retrieve an array of structs according to the passed in properties. -* New method: `idCast( entity, id )` to auto cast your entity `id` value to java type automatically for you, no more javacasting -* New method: `autoCast( entity, propertyName, value )` to auto cast any value for any entity property automatically, no more javacasting. -* New method: `getKeyValue( entity )` which will give you the value of the entity's unique identifier -* New method: `isDirty( entity )` which will let you know if the entity has dirty values or has its values changed since loaded from the db -* New method: `getEntityMetadata( entity )` which will return to you the hibernate's metadata for a specific entity. -* `getPropertyNames()` argument of `entityname` renamed to `entity` to allow not only for a name but an actual entity as well. -* `getTableName()` argument of `entityname` renamed to `entity` to allow not only for a name but an actual entity as well. -* `getKey()` argument of `entityname` renamed to `entity` to allow not only for a name but an actual entity as well. -* ORM Encapsulation of hibernate metadata retrieval via `getEntityMetadata()` -* `deleteByQuery()` reworked entirely to do native bulk delete queries. It now also returns the number of records removed -* `deleteWhere()` missing flush argument, added datasource as well -* New properties: `wirebox` : a WireBox reference already injected, `logger` : a prepared logger for the class, `datasource` The default datasource or constructed datasource for the class. -* Logging of all activity now available via the `debug` level, even for dynamic methods. -* Refactored all dynamic finders and counters to their own class, which improves not only performance but weight of orm service based entities. -* All dynamic method calls can now return cbStreams as the results -* All dynamic method calls accept a structure as an argument or named as `options` that can have the following keys now: +- New Fail fast methods: `getOrFail() proxies to get(), findOrFail() proxies to findIt()` that if not entity is produced will throw a `EntityNotFound` exception +- All listing methods can now return the results as a cbStream by passing the `asStream` boolean argument. +- Removed `criteriaCount(), criteriaQuery()` from BaseService, this was the legacy criteria builder approach, please use `newCriteria()` instead. +- Update `getEntityGivenName` to support ACF2018 +- Lazy loading `BeanPopulator` for performance on creations +- Lazy loading `ORMEventHandler` for performance on creations +- Lazy loading `restrictions` for performance on creations +- Base service can now be initialized with a `datasource`, or uses the default one declared +- Added optional `datasource` to many listing methods +- Added consistency on querying options to all major functions to include `ignoreCase, sorting and timeouts`. +- Added ability to `getAll()` to retrieve read only entities using the `readOnly` argument. +- The `getAll()` method has a new `properties` argument that if passed will allow you to retrieve an array of structs according to the passed in properties. +- New method: `idCast( entity, id )` to auto cast your entity `id` value to java type automatically for you, no more javacasting +- New method: `autoCast( entity, propertyName, value )` to auto cast any value for any entity property automatically, no more javacasting. +- New method: `getKeyValue( entity )` which will give you the value of the entity's unique identifier +- New method: `isDirty( entity )` which will let you know if the entity has dirty values or has its values changed since loaded from the db +- New method: `getEntityMetadata( entity )` which will return to you the hibernate's metadata for a specific entity. +- `getPropertyNames()` argument of `entityname` renamed to `entity` to allow not only for a name but an actual entity as well. +- `getTableName()` argument of `entityname` renamed to `entity` to allow not only for a name but an actual entity as well. +- `getKey()` argument of `entityname` renamed to `entity` to allow not only for a name but an actual entity as well. +- ORM Encapsulation of hibernate metadata retrieval via `getEntityMetadata()` +- `deleteByQuery()` reworked entirely to do native bulk delete queries. It now also returns the number of records removed +- `deleteWhere()` missing flush argument, added datasource as well +- New properties: `wirebox` : a WireBox reference already injected, `logger` : a prepared logger for the class, `datasource` The default datasource or constructed datasource for the class. +- Logging of all activity now available via the `debug` level, even for dynamic methods. +- Refactored all dynamic finders and counters to their own class, which improves not only performance but weight of orm service based entities. +- All dynamic method calls can now return cbStreams as the results +- All dynamic method calls accept a structure as an argument or named as `options` that can have the following keys now: ```json { @@ -445,7 +440,7 @@ this.TYPES = { results = ormservice.findByLastLoginBetween( "User", "01/01/2008", "11/01/2008", { sortBy="LastName" } ); ``` -* All dynamic finders/counters values are autocasted, you no longer need to cast the values, we will do this for you. You can turn it off via the `autocast:false` in the options to the calls.# +- All dynamic finders/counters values are autocasted, you no longer need to cast the values, we will do this for you. You can turn it off via the `autocast:false` in the options to the calls.# ## [Virtual Entity Service] @@ -455,68 +450,72 @@ Remember this entity extends Base Service, so we get all the features above plus Remember this entity extends the Virtual Service, so we get all the features above plus the following: -* Faster creation speeds due to lazy loading of dependencies and better datasource determination. -* `refresh(), merge(), evict()` refactored to encapsulate login in the base orm service and not itself +- Faster creation speeds due to lazy loading of dependencies and better datasource determination. +- `refresh(), merge(), evict()` refactored to encapsulate login in the base orm service and not itself ## 1.5.0 -* Performance improvements for criteria building as we now build up the dialect and support structs -* ACF 2018 Support via Hibernate 5 -* Update to leverage new module template schema -* Updated readme from old text +- Performance improvements for criteria building as we now build up the dialect and support structs +- ACF 2018 Support via Hibernate 5 +- Update to leverage new module template schema +- Updated readme from old text ## 1.4.0 -* ColdBox 5 Support -* Dependency updates -* Some syntax updates -* Fix `getKey()` return typing to allow composite keys: https://github.com/coldbox-modules/cborm/pull/21 -* Update to module standard template -* Updated dependencies +- ColdBox 5 Support +- Dependency updates +- Some syntax updates +- Fix `getKey()` return typing to allow composite keys: +- Update to module standard template +- Updated dependencies ## 1.3.0 -* Pass the target value as the rejected value for Unique validator -* Travis Updates -* Dependency updates -* Lucee 5 exceptions on ORM Util due to abstract keyword +- Pass the target value as the rejected value for Unique validator +- Travis Updates +- Dependency updates +- Lucee 5 exceptions on ORM Util due to abstract keyword ## 1.2.2 -* Travis updates -* COLDBOX-460 Dynamic finders fixed by always adding datasource attribute to hql query -* Fixes an interface error on AC11 startup +- Travis updates +- COLDBOX-460 Dynamic finders fixed by always adding datasource attribute to hql query +- Fixes an interface error on AC11 startup ## 1.2.1 -* Fixed box.json version number +- Fixed box.json version number ## 1.2.0 -* BaseORMService.merge doesn't seem to merge entities back into session #10 -* Variable scoping in SQLHelper.cfc bug #9 -* Update build process to leverage Travis -* Updated `cbvalidation` to v1.1.0 -* Build cleanup -* Replaced `StringBuffer` with `StringBuilder` for performance +- BaseORMService.merge doesn't seem to merge entities back into session #10 +- Variable scoping in SQLHelper.cfc bug #9 +- Update build process to leverage Travis +- Updated `cbvalidation` to v1.1.0 +- Build cleanup +- Replaced `StringBuffer` with `StringBuilder` for performance ## 1.1.0 -* Updated cbvalidation dependency -* Prevent conditionals from being stripped from property names -* Updated build for api docs and commandbox usage for dependencies -* ORM Unique validation not working +- Updated cbvalidation dependency +- Prevent conditionals from being stripped from property names +- Updated build for api docs and commandbox usage for dependencies +- ORM Unique validation not working ## 1.0.2 -* updates to all dependencies -* production ignore lists +- updates to all dependencies +- production ignore lists ## 1.0.1 -* https://ortussolutions.atlassian.net/browse/CCM-15 CF11Compat - arrayContainsNoCase() Is not a function -* Lucee support +- CF11Compat - arrayContainsNoCase() Is not a function +- Lucee support ## 1.0.0 -* Create first module version +- Create first module version + +[Unreleased]: https://github.com/coldbox-modules/cborm/compare/v4.4.0...HEAD + +[4.4.0]: https://github.com/coldbox-modules/cborm/compare/13af593fa8a7bf2c4396e9be9d0dd0bb6899e935...v4.4.0 From ce09f3b3c48392fab4eca76ca59e5895f9279c52 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Wed, 19 Apr 2023 15:30:20 +0200 Subject: [PATCH 02/21] adding 2023 testing --- .github/workflows/tests.yml | 3 +++ server-adobe@2023.json | 29 +++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 server-adobe@2023.json diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 53be6b6..08a3f3a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -22,6 +22,9 @@ jobs: coldboxVersion: [ "^6.0.0" ] experimental: [ false ] include: + - cfengine: "adobe@2023" + coldboxVersion: "^6.0.0" + experimental: true - cfengine: "lucee-hibernate@5.4" coldboxVersion: "^6.0.0" experimental: true diff --git a/server-adobe@2023.json b/server-adobe@2023.json new file mode 100644 index 0000000..565f79d --- /dev/null +++ b/server-adobe@2023.json @@ -0,0 +1,29 @@ +{ + "name":"@MODULE_NAME@-adobe@2023", + "app":{ + "serverHomeDirectory":".engine/adobe2023", + "cfengine":"adobe@2023.0.0-beta.1" + }, + "web":{ + "http":{ + "port":"60299" + }, + "rewrites":{ + "enable":"true" + }, + "webroot": "test-harness", + "aliases":{ + "/moduleroot/@MODULE_NAME@":"../" + } + }, + "jvm":{ + "heapSize":"1024" + }, + "openBrowser":"false", + "cfconfig": { + "file" : ".cfconfig.json" + }, + "scripts" : { + "onServerInstall":"cfpm install zip,debugger" + } +} From 80c42e20bc4a0ac4710532e2ef8d717712b2b2a1 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Wed, 19 Apr 2023 15:32:40 +0200 Subject: [PATCH 03/21] missing packages --- server-adobe@2023.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-adobe@2023.json b/server-adobe@2023.json index 565f79d..16f53ed 100644 --- a/server-adobe@2023.json +++ b/server-adobe@2023.json @@ -24,6 +24,6 @@ "file" : ".cfconfig.json" }, "scripts" : { - "onServerInstall":"cfpm install zip,debugger" + "onServerInstall":"cfpm install zip,debugger,mysql,orm,postgresql,sqlserver,feed" } } From a36b25bd0afe6d817d055d11edb80883c03605f4 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Wed, 19 Apr 2023 18:03:52 +0200 Subject: [PATCH 04/21] oops had the wrong servername --- server-adobe@2023.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server-adobe@2023.json b/server-adobe@2023.json index 16f53ed..9ebec68 100644 --- a/server-adobe@2023.json +++ b/server-adobe@2023.json @@ -1,5 +1,5 @@ { - "name":"@MODULE_NAME@-adobe@2023", + "name":"cborm-adobe@2023", "app":{ "serverHomeDirectory":".engine/adobe2023", "cfengine":"adobe@2023.0.0-beta.1" @@ -13,7 +13,7 @@ }, "webroot": "test-harness", "aliases":{ - "/moduleroot/@MODULE_NAME@":"../" + "/moduleroot/cborm":"../" } }, "jvm":{ From 7d3da59fbf25184ecc0d251e95fe1e63a3948a74 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 20 Apr 2023 14:57:34 +0200 Subject: [PATCH 05/21] small syntax updates to changelog and contribs --- .github/workflows/release.yml | 28 ++- .vscode/tasks.json | 33 +++ CONTRIBUTING.md | 8 +- changelog.md | 394 +++++++++++++++++----------------- 4 files changed, 261 insertions(+), 202 deletions(-) create mode 100644 .vscode/tasks.json diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9d3504d..6219288 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -58,6 +58,8 @@ jobs: - name: Build ${{ env.MODULE_ID }} run: | + npm install -g markdownlint-cli + markdownlint changelog.md --fix box install commandbox-docbox box task run taskfile=build/Build target=run :version=${{ env.VERSION }} :projectName=${{ env.MODULE_ID }} :buildID=${{ github.run_number }} :branch=${{ env.BRANCH }} @@ -87,9 +89,33 @@ jobs: .artifacts/**/* changelog.md + - name: Upload Binaries to S3 + uses: jakejarvis/s3-sync-action@master + with: + args: --acl public-read + env: + AWS_S3_BUCKET: "downloads.ortussolutions.com" + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_ACCESS_SECRET }} + SOURCE_DIR: ".artifacts/${{ env.MODULE_ID }}" + DEST_DIR: "ortussolutions/coldbox-modules/${{ env.MODULE_ID }}" + + - name: Upload API Docs to S3 + uses: jakejarvis/s3-sync-action@master + with: + args: --acl public-read + env: + AWS_S3_BUCKET: "apidocs.ortussolutions.com" + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_ACCESS_SECRET }} + SOURCE_DIR: ".tmp/apidocs" + DEST_DIR: "coldbox-modules/${{ env.MODULE_ID }}/${{ env.VERSION }}" + - name: Publish To ForgeBox run: | - cd .tmp/${{ env.MODULE_ID }} && box forgebox publish --force + cd .tmp/${{ env.MODULE_ID }} + cat box.json + box forgebox publish --force - name: Create Github Release uses: taiki-e/create-gh-release-action@v1.6.2 diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..6092c9d --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,33 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Run CommandBox Task", + "type": "shell", + "command": "box task run ${relativeFile}", + "group": { + "kind": "build", + "isDefault": true + }, + "presentation": { + "reveal": "always", + "panel": "new" + }, + "problemMatcher": [] + }, + { + "label": "Run TestBox Bundle", + "type": "shell", + "command": "box testbox run bundles=${relativeFile} --!recurse", + "group": { + "kind": "build", + "isDefault": true + }, + "presentation": { + "reveal": "always", + "panel": "new" + }, + "problemMatcher": [] + } + ] +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9e0f1be..b150498 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# CBSecurity Contributing Guide +# cborm Contributing Guide Hola amigo! I'm really excited that you are interested in contributing to our project. Before submitting your contribution, please make sure to take a moment and read through the following guidelines: @@ -27,7 +27,7 @@ This project is open source, and as such, the maintainers give their free time t Each of the main standalone frameworks in ColdBox has its separate locations for submitting bug reports. Please make sure also that if you submit a pull request, you link it to the appropriate issue. -https://github.com/coldbox-modules/cbsecurity +https://github.com/coldbox-modules/cborm If you file a bug report, your issue should contain a title, a clear description of the issue, a way to replicate the issue, and any support files that we might need to replicate your issue. The goal of a bug report is to make it easy for yourself - and others - to replicate the bug and develop a fix for it. All issues that do not contain a way to replicate will not be addressed. @@ -81,8 +81,8 @@ You can support ColdBox and all of our Open Source initiatives at Ortus Solution Thank you to all the people who have already contributed to ColdBox! We: heart: : heart: : heart: love you! - - + + Made with [contributors-img](https://contrib.rocks) diff --git a/changelog.md b/changelog.md index 3e5edfa..9f8fc89 100644 --- a/changelog.md +++ b/changelog.md @@ -11,132 +11,132 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Github Actions updated -- Github support files -- ColdBox 7+ automated testing -- More test scenarios and test cleanups +- Github Actions updated +- Github support files +- ColdBox 7+ automated testing +- More test scenarios and test cleanups ## [v4.3.2] => 2022-NOV-17 ### Fixed -- Removal of `lazy` annotations that conflict with cb7 lazy properties +- Removal of `lazy` annotations that conflict with cb7 lazy properties ## [v4.3.1] => 2022-NOV-16 ### Fixed -- Updated `processState()` to `announce()` on all tests +- Updated `processState()` to `announce()` on all tests ## [v4.3.0] => 2022-NOV-16 ### Changed -- Updated `processState()` to `announce()` to stay compliant +- Updated `processState()` to `announce()` to stay compliant ## [v4.2.0] => 2022-NOV-16 ### Changed -- Updated `announceInterception()` to `announce()` to stay compliant +- Updated `announceInterception()` to `announce()` to stay compliant ## [v4.1.0] => 2022-NOV-10 ### Changed -- Updated the way the populator is retrieved so we can be forwards compatible +- Updated the way the populator is retrieved so we can be forwards compatible ## [v4.0.0] => 2022-OCT-10 ### Added -- Upgraded all dependencies to major bumps +- Upgraded all dependencies to major bumps ### Changed -- Dropped ACF2016 Support +- Dropped ACF2016 Support ## [v3.9.0] => 2022-AUG-10 ### Added -- New `when( boolean, success, fail )` fluent construct for `ActiveEntity`, `VirtualEntityService` and the `BaseORMService` to allow for fluent chaining of operations on an entity or it's service. -- Migration to new ColdBox Virtual App Testing approaches -- Removed unecessary on load logging to increase performance -- Hibernate 5.4 on Lucee experimental testing +- New `when( boolean, success, fail )` fluent construct for `ActiveEntity`, `VirtualEntityService` and the `BaseORMService` to allow for fluent chaining of operations on an entity or it's service. +- Migration to new ColdBox Virtual App Testing approaches +- Removed unecessary on load logging to increase performance +- Hibernate 5.4 on Lucee experimental testing ### Fixed -- `countWhere()` invalid SQL exception if no arguments are provided: +- `countWhere()` invalid SQL exception if no arguments are provided: ## [v3.8.0] => 2022-MAR-09 ### Fixed -- CBORM-32 - Non-Primary DSN Entities not found. Multi-datasource discovery of entities using virtual services and active entity. This was a regresion since version 1.5. This brings back multi-datasource support for active entity, and virtual entity services. -- Detached `Subqueries` was marked as a singleton when indeed it was indeed a transient. This could have created scoping issues on subquery based detached criteria building. -- Varscoping issues in `BaseBuilder` detached projections -- `DetachedCriteriaBuilder` was not passing the `datasource` to native criteria objects +- CBORM-32 - Non-Primary DSN Entities not found. Multi-datasource discovery of entities using virtual services and active entity. This was a regresion since version 1.5. This brings back multi-datasource support for active entity, and virtual entity services. +- Detached `Subqueries` was marked as a singleton when indeed it was indeed a transient. This could have created scoping issues on subquery based detached criteria building. +- Varscoping issues in `BaseBuilder` detached projections +- `DetachedCriteriaBuilder` was not passing the `datasource` to native criteria objects ### Added -- Root `docker-compose.yml` to startup MySQL, or PostgreSQL in docker, for further hacking and testing. -- Java proxy caching to avoid Lucee OSGi issues and increase Java object building performance -- New method in the BaseOrmService: `buildJavaProxy()` which leverages our `JavaProxyBuilder` -- Lazy loading of SQL Helper in criteria queries -- New module template guidelines and CI -- Leverage WireBox aliases for contstruction of internal objects -- Tons of internal docs and links to hibernate docs +- Root `docker-compose.yml` to startup MySQL, or PostgreSQL in docker, for further hacking and testing. +- Java proxy caching to avoid Lucee OSGi issues and increase Java object building performance +- New method in the BaseOrmService: `buildJavaProxy()` which leverages our `JavaProxyBuilder` +- Lazy loading of SQL Helper in criteria queries +- New module template guidelines and CI +- Leverage WireBox aliases for contstruction of internal objects +- Tons of internal docs and links to hibernate docs ## [v3.7.0] => 2022-JAN-13 ### Added -- [CBORM-29](https://ortussolutions.atlassian.net/browse/CBORM-29) Allow SQL projections to be functions containing commas +- [CBORM-29](https://ortussolutions.atlassian.net/browse/CBORM-29) Allow SQL projections to be functions containing commas ## [v3.6.0] => 2022-JAN-10 ### Added -- Removed usage of interface on DSL. Causes more issues than anything with multiple engines. +- Removed usage of interface on DSL. Causes more issues than anything with multiple engines. ### Changed -- Renamed default object DSL +- Renamed default object DSL ## [v3.5.1] => 2022-JAN-10 ### Fixed -- Removed usage of interface on DSL. Causes more issues than anything with multiple engines. +- Removed usage of interface on DSL. Causes more issues than anything with multiple engines. ## [v3.5.0] => 2021-DEC-16 ### Fixed -- [CBORM-20](https://ortussolutions.atlassian.net/browse/CBORM-20) ActiveEntity `evict()` had the wrong method and arguments delegated to the parent class. -- [CBORM-9](https://ortussolutions.atlassian.net/browse/CBORM-9) ACF2021 - org.hibernate.SessionFactory.getAllClassMetadata is no longer supported +- [CBORM-20](https://ortussolutions.atlassian.net/browse/CBORM-20) ActiveEntity `evict()` had the wrong method and arguments delegated to the parent class. +- [CBORM-9](https://ortussolutions.atlassian.net/browse/CBORM-9) ACF2021 - org.hibernate.SessionFactory.getAllClassMetadata is no longer supported ### Improved -- [CBORM-14](https://ortussolutions.atlassian.net/browse/CBORM-14) Inline datasource discovery in base orm service to get a performance boost -- [CBORM-13](https://ortussolutions.atlassian.net/browse/CBORM-13) virtual entity service double creating the orm utility, use the parent one instead of duplicating the effort -- [CBORM-12](https://ortussolutions.atlassian.net/browse/CBORM-12) Lazy load the getORMUtil() and use it only when required. +- [CBORM-14](https://ortussolutions.atlassian.net/browse/CBORM-14) Inline datasource discovery in base orm service to get a performance boost +- [CBORM-13](https://ortussolutions.atlassian.net/browse/CBORM-13) virtual entity service double creating the orm utility, use the parent one instead of duplicating the effort +- [CBORM-12](https://ortussolutions.atlassian.net/browse/CBORM-12) Lazy load the getORMUtil() and use it only when required. ### Added -- [CBORM-22](https://ortussolutions.atlassian.net/browse/CBORM-22) New orm util support method: setupHibernateLogging() thanks to michael born -- [CBORM-19](https://ortussolutions.atlassian.net/browse/CBORM-19) Added a `isInTransaction()` util helper method to all the orm services. -- [CBORM-18](https://ortussolutions.atlassian.net/browse/CBORM-18) New ORM events based on Hibernate 5.4 Events: `ORMFlush, ORMAutoFlush, ORMPreFlush, ORMDirtyCheck, ORMEvict, and ORMClear` -- [CBORM-17](https://ortussolutions.atlassian.net/browse/CBORM-17) Hibernate 5.4 support for lucee new extension -- [CBORM-16](https://ortussolutions.atlassian.net/browse/CBORM-16) Adobe 2021 support and testing automations -- [CBORM-15](https://ortussolutions.atlassian.net/browse/CBORM-15) Migration to github actions -- [CBORM-11](https://ortussolutions.atlassian.net/browse/CBORM-11) Allow Criteria Builder Get() and getOrFail() Methods to Return Projection List Properties -- [CBORM-21](https://ortussolutions.atlassian.net/browse/CBORM-21) New cfformating rules +- [CBORM-22](https://ortussolutions.atlassian.net/browse/CBORM-22) New orm util support method: setupHibernateLogging() thanks to michael born +- [CBORM-19](https://ortussolutions.atlassian.net/browse/CBORM-19) Added a `isInTransaction()` util helper method to all the orm services. +- [CBORM-18](https://ortussolutions.atlassian.net/browse/CBORM-18) New ORM events based on Hibernate 5.4 Events: `ORMFlush, ORMAutoFlush, ORMPreFlush, ORMDirtyCheck, ORMEvict, and ORMClear` +- [CBORM-17](https://ortussolutions.atlassian.net/browse/CBORM-17) Hibernate 5.4 support for lucee new extension +- [CBORM-16](https://ortussolutions.atlassian.net/browse/CBORM-16) Adobe 2021 support and testing automations +- [CBORM-15](https://ortussolutions.atlassian.net/browse/CBORM-15) Migration to github actions +- [CBORM-11](https://ortussolutions.atlassian.net/browse/CBORM-11) Allow Criteria Builder Get() and getOrFail() Methods to Return Projection List Properties +- [CBORM-21](https://ortussolutions.atlassian.net/browse/CBORM-21) New cfformating rules ### Compatibility -- If you upgrade your lucee ORM extension to use Hibernate 5.4, all positional paramters in HQL using `?` has been deprecated. You will have to use the `?x` approach where `x` is a number according to the position in the sql: +- If you upgrade your lucee ORM extension to use Hibernate 5.4, all positional paramters in HQL using `?` has been deprecated. You will have to use the `?x` approach where `x` is a number according to the position in the sql: ```sql // Old Syntax @@ -154,117 +154,117 @@ where p.name like ?1 and p.isStatus = ?2 ### Added -- Support for Adobe 2021 on resource loader +- Support for Adobe 2021 on resource loader ## [v3.3.0] => 2021-APR-27 ### Added -- New `eventPrefix` setting so you can prefix the resource REST CRUD events with whatever you like. -- Useful exceptions when `results` struct does not have the required keys -- Ability to override the name of the method to use for persistence on the ORM services. Using the `variables.saveMethod` property or the `savemethod` argument. -- Ability to override the name of the method to use for deleting entities on the ORM services. Using the `variables.deleteMethod` property or the `deleteMethod` argument. -- cbSwagger docs +- New `eventPrefix` setting so you can prefix the resource REST CRUD events with whatever you like. +- Useful exceptions when `results` struct does not have the required keys +- Ability to override the name of the method to use for persistence on the ORM services. Using the `variables.saveMethod` property or the `savemethod` argument. +- Ability to override the name of the method to use for deleting entities on the ORM services. Using the `variables.deleteMethod` property or the `deleteMethod` argument. +- cbSwagger docs ### Changed -- Added ACF2016 compatibilities on elvis operator which sucks on ACF2016 -- Avoid using member function son some arrays to allow for working with Java arrays +- Added ACF2016 compatibilities on elvis operator which sucks on ACF2016 +- Avoid using member function son some arrays to allow for working with Java arrays ## [v3.2.1] => 2021-MAR-31 ### Fixed -- Wrong object to get the event handler manager when doing execute query calls +- Wrong object to get the event handler manager when doing execute query calls ## [v3.2.0] => 2021-MAR-31 ### Added -- Exposed a `getSQLHelper()` from criterias to allow for usage of formmatting of sql -- New interception points: `beforeOrmExecuteQuery, afterOrmExecuteQuery` from the base orm service: `executeQuery()` method +- Exposed a `getSQLHelper()` from criterias to allow for usage of formmatting of sql +- New interception points: `beforeOrmExecuteQuery, afterOrmExecuteQuery` from the base orm service: `executeQuery()` method ### Fixed -- Moved `afterCriteriaBuilderList` event before results conversions +- Moved `afterCriteriaBuilderList` event before results conversions ## [v3.1.0] => 2021-MAR-30 ### Added -- Env templates using new lucee bundles and mysql 8 support -- New interception point: `afterCriteriaBuilderGet`, `beforeCriteriaBuilderGet` called after/before criteria `get()` calls +- Env templates using new lucee bundles and mysql 8 support +- New interception point: `afterCriteriaBuilderGet`, `beforeCriteriaBuilderGet` called after/before criteria `get()` calls ### Fixed -- Fixed http to https for downloads -- Fixed watcher pathing +- Fixed http to https for downloads +- Fixed watcher pathing ## [v3.0.0] => 2021-FEB-12 ### Added -- [CBORM-3] - Updated cbValidation to v3 to suppport cbi18n v2 -- [CBORM-4] - asQuery update to default it to false -- [CBORM-5] - Document v3 variant in the docs +- [CBORM-3] - Updated cbValidation to v3 to suppport cbi18n v2 +- [CBORM-4] - asQuery update to default it to false +- [CBORM-5] - Document v3 variant in the docs ## Improved -- [CBORM-6] - Source code cleanups by applying formatting rules +- [CBORM-6] - Source code cleanups by applying formatting rules ### Fixed -- [CBORM-2] - isDirty() not working with ActiveEntity due to missing entity passed +- [CBORM-2] - isDirty() not working with ActiveEntity due to missing entity passed ## [v2.6.0] => 2020-NOV-25 ### Added -- Entities are now created, auto-wired and THEN populated when using the `new()` method instead of being auto-wired after population. -- Made `processEntityInjection()` public on the ORM Event Handler so it can be reused in other locations -- `processEntityInjection()` returns the passed entity so you can do chaining -- `getOrFail()` now includes in the `extendedInfo` the actual entity that caused the exception -- Formatting according to new rules -- Updated changelogs to new standards -- Added auto-publishing of changelogs to github -- Pinning to ColdBox 6 for base testing -- ColdBox 6 graceful shutdowns for tests -- Base Test Case for all tests for faster executions and cleanup due to base reusability +- Entities are now created, auto-wired and THEN populated when using the `new()` method instead of being auto-wired after population. +- Made `processEntityInjection()` public on the ORM Event Handler so it can be reused in other locations +- `processEntityInjection()` returns the passed entity so you can do chaining +- `getOrFail()` now includes in the `extendedInfo` the actual entity that caused the exception +- Formatting according to new rules +- Updated changelogs to new standards +- Added auto-publishing of changelogs to github +- Pinning to ColdBox 6 for base testing +- ColdBox 6 graceful shutdowns for tests +- Base Test Case for all tests for faster executions and cleanup due to base reusability ### Fixed -- Typo on `ORMUtilSupport` when detecting datasources, if you passed a default it would never be used -- `postNew` was not using the actual entity name so we where hitting performance on lookups for name -- compose relationships was `false` for resource handler and it needed to be `true` -- Increased timeouts for tests, due to Adobe issues with long compile times in latest patch levels that suck! -- Unique validator test was clearing the full app scope and trigger multiple testing issues +- Typo on `ORMUtilSupport` when detecting datasources, if you passed a default it would never be used +- `postNew` was not using the actual entity name so we where hitting performance on lookups for name +- compose relationships was `false` for resource handler and it needed to be `true` +- Increased timeouts for tests, due to Adobe issues with long compile times in latest patch levels that suck! +- Unique validator test was clearing the full app scope and trigger multiple testing issues ## [v2.5.0] => 2020-APR-20 -- `Features` : Introduction of the automatic resource handler for ORM Entities based on ColdBox's 6 resources and RestHandler -- `Improvement` : Natively allow for nested transactions and savepoints by not doing preemptive transaction commits when using transactions. -- `Bug` : Fix on `getOrFail()` where if the id was 0, it would still return an empty object. -- `Task` : Added formatting via cfformat +- `Features` : Introduction of the automatic resource handler for ORM Entities based on ColdBox's 6 resources and RestHandler +- `Improvement` : Natively allow for nested transactions and savepoints by not doing preemptive transaction commits when using transactions. +- `Bug` : Fix on `getOrFail()` where if the id was 0, it would still return an empty object. +- `Task` : Added formatting via cfformat ## [v2.4.0] => 2020-JAN-31 -- `Feature` : Upgraded to `cbValidation` 2.0.0 -- `Feature` : Updated the unique validator to match 2.0.0 standards -- `Feature` : Upgraded to `mementifier` 2.0.0 +- `Feature` : Upgraded to `cbValidation` 2.0.0 +- `Feature` : Updated the unique validator to match 2.0.0 standards +- `Feature` : Upgraded to `mementifier` 2.0.0 ## [v2.3.0] -- `improvement` : In `executeQuery()` Determine if we are in a UPDATE, INSERT or DELETE, if we do, just return the results instead of a stream or query as the result is always numeric, the rows that were altered. -- `bug` : Fixed `asStream` typo on `executeQuery()` -- `bug` : Missing ACF2016 compat on tests +- `improvement` : In `executeQuery()` Determine if we are in a UPDATE, INSERT or DELETE, if we do, just return the results instead of a stream or query as the result is always numeric, the rows that were altered. +- `bug` : Fixed `asStream` typo on `executeQuery()` +- `bug` : Missing ACF2016 compat on tests ## [v2.2.1] -- `bug` : virtual entity service still had `entity` required for casting methods +- `bug` : virtual entity service still had `entity` required for casting methods ## [v2.2.0] -- `Feature`: New function for criteria query `when( boolean, target )` that you can use to build functional criterias without the use of if statements. +- `Feature`: New function for criteria query `when( boolean, target )` that you can use to build functional criterias without the use of if statements. newCriteria() @@ -283,26 +283,26 @@ where p.name like ?1 and p.isStatus = ?2 } ) .list() -- `Feature`: Missing `nullValue()` is BaseBuilder class -- `Feature`: Added new criteria query `peek( closure )` function to allow for peeking into the building process. Pass in your closure that receives the criteria and interact with it. -- `Feature`: Added a `validateOrFail()` to the active entity, which if the validation fails it will throw an exception or return back to you the same entity validated now. -- `Improvement`: Better documentation for `deleteById()` since it does bulk deletion, which does not do any type of cascading. -- `Improvement`: `isValid()` in active entity missing `includeFields` argument -- `Improvement`: Timeout hints for criteria builder -- `Improvement`: Updated exception type for criteria builder `get()` -- `Bug`: ACF2016 issues with elvis operator. -- `Bug`: `getOrFail()` had an invalid throw statement +- `Feature`: Missing `nullValue()` is BaseBuilder class +- `Feature`: Added new criteria query `peek( closure )` function to allow for peeking into the building process. Pass in your closure that receives the criteria and interact with it. +- `Feature`: Added a `validateOrFail()` to the active entity, which if the validation fails it will throw an exception or return back to you the same entity validated now. +- `Improvement`: Better documentation for `deleteById()` since it does bulk deletion, which does not do any type of cascading. +- `Improvement`: `isValid()` in active entity missing `includeFields` argument +- `Improvement`: Timeout hints for criteria builder +- `Improvement`: Updated exception type for criteria builder `get()` +- `Bug`: ACF2016 issues with elvis operator. +- `Bug`: `getOrFail()` had an invalid throw statement ## [v2.1.0] -- Change `populate()` in ActiveEntity so the target is the last argument so you can just pass a struct as the first argument [#29](https://github.com/coldbox-modules/cborm/issues/29) -- Make the `save()` operation return the saved entity or array of entities instead of the BaseORM service [#28](https://github.com/coldbox-modules/cborm/issues/28) +- Change `populate()` in ActiveEntity so the target is the last argument so you can just pass a struct as the first argument [#29](https://github.com/coldbox-modules/cborm/issues/29) +- Make the `save()` operation return the saved entity or array of entities instead of the BaseORM service [#28](https://github.com/coldbox-modules/cborm/issues/28) ## [v2.0.0] ### Compatibility Updates -- You will need to move the `orm` configuration structure in your `config/ColdBox.cfc` to the `moduleSettings` struct and rename it to `cborm` to standardize it to module settings. +- You will need to move the `orm` configuration structure in your `config/ColdBox.cfc` to the `moduleSettings` struct and rename it to `cborm` to standardize it to module settings. moduleSettings = { @@ -317,37 +317,37 @@ where p.name like ?1 and p.isStatus = ?2 }; -- `deleteByQuery()` reworked entirely to do native bulk delete queries. It now also returns the number of records removed -- The `evict()` method was renamed to `evictCollection()` to better satisfy the same contract in hibernate -- The `evictEntity()` method was renamed to `evict()` to better satisfay the same contract in hibernate -- Removed `byExample` on many listing methods +- `deleteByQuery()` reworked entirely to do native bulk delete queries. It now also returns the number of records removed +- The `evict()` method was renamed to `evictCollection()` to better satisfy the same contract in hibernate +- The `evictEntity()` method was renamed to `evict()` to better satisfay the same contract in hibernate +- Removed `byExample` on many listing methods ### General Updates -- **Mementifier** is now a dependency for cborm (www.forgebox.io/view/mementifier), which can be used for producing state out of ORM entities for auditing or building JSON Api's. -- **cbStreams** is now a dependency for cborm (www.forgebox.io/view/cbstreams), all criteria queries and major listing methods support the return of streams instead of array of objects -- Full Null Support -- Performance update on creating active entities as datasource discovery has been reworked -- Updated build process to latest in Ortus template -- Dropped Railo, Lucee 4.5, ACF11 support -- More direct scoping for performance updates -- Optimized EventHandler so it is lighter and quicker when doing orm injections -- Documented all functions with extra examples and notes and hibernate references -- ColdBox 5 and 4 discrete ORM Injection DSLs +- **Mementifier** is now a dependency for cborm (www.forgebox.io/view/mementifier), which can be used for producing state out of ORM entities for auditing or building JSON Api's. +- **cbStreams** is now a dependency for cborm (www.forgebox.io/view/cbstreams), all criteria queries and major listing methods support the return of streams instead of array of objects +- Full Null Support +- Performance update on creating active entities as datasource discovery has been reworked +- Updated build process to latest in Ortus template +- Dropped Railo, Lucee 4.5, ACF11 support +- More direct scoping for performance updates +- Optimized EventHandler so it is lighter and quicker when doing orm injections +- Documented all functions with extra examples and notes and hibernate references +- ColdBox 5 and 4 discrete ORM Injection DSLs ### Criteria Queries -- They have been adapted to work with Hibernate 3, 4 and 5 -- New fail fast method for `get()` -> `getOrFail()` to throw an entity not found exception -- New alias methods for controlling the result transformations `asStruct(), asStream(), asDistinct()` that will apply result transformers for you instead of doing `.resultTransformer( c.ALIAS_TO_ENTITY_MAP )`, whish is long and boring, or return to you a java stream via cbStreams. -- When calling native restrictions, no more reflection is used to discover the restriction type thus increasing over 70% in performance when creating criteria queries -- You can now negate any criteria restriction by prefixing it with a `not`. So you can do: `.notEq(), notBetween(), notIsNull(), notIsIn()` and much more. -- The `list()` method has a new `asStream` boolean argument that if true, will return the results as a cbStream. ((www.forgebox.io/view/cbStreams)) -- New Methods: `idCast()` and `autoCast()` added for quick casting of values -- New method: `queryHint()` so you can add your own vendor specific query hints for optimizers. -- New method: `comment( string )` so you can add arbitrary comments to the generated SQL, great for debugging -- `sqlRestriction()` deprecated in favor of the shorthand notation: `sql()` -- The `sql()` restriction now supports binding positional parameters. You can pass them in an array and we will infer the types: `sql( "id = ? and isActive = ?", [ "123", true ] )`. Or you can pass in a struct of `{value:"", type:""}` instead: +- They have been adapted to work with Hibernate 3, 4 and 5 +- New fail fast method for `get()` -> `getOrFail()` to throw an entity not found exception +- New alias methods for controlling the result transformations `asStruct(), asStream(), asDistinct()` that will apply result transformers for you instead of doing `.resultTransformer( c.ALIAS_TO_ENTITY_MAP )`, whish is long and boring, or return to you a java stream via cbStreams. +- When calling native restrictions, no more reflection is used to discover the restriction type thus increasing over 70% in performance when creating criteria queries +- You can now negate any criteria restriction by prefixing it with a `not`. So you can do: `.notEq(), notBetween(), notIsNull(), notIsIn()` and much more. +- The `list()` method has a new `asStream` boolean argument that if true, will return the results as a cbStream. ((www.forgebox.io/view/cbStreams)) +- New Methods: `idCast()` and `autoCast()` added for quick casting of values +- New method: `queryHint()` so you can add your own vendor specific query hints for optimizers. +- New method: `comment( string )` so you can add arbitrary comments to the generated SQL, great for debugging +- `sqlRestriction()` deprecated in favor of the shorthand notation: `sql()` +- The `sql()` restriction now supports binding positional parameters. You can pass them in an array and we will infer the types: `sql( "id = ? and isActive = ?", [ "123", true ] )`. Or you can pass in a struct of `{value:"", type:""}` instead: restrictions.sql( "userName = ? and firstName like ?", [ @@ -388,40 +388,40 @@ The available types are the following which match the Hibernate Types "serializable" : "SerializableType" }; -- Detached Criteria builder now has a `maxResults( maxResults )` method to limit the results by -- Detached Criteria sql projections now take aliases into account -- SQL Projections and SQL Group By projections now respect aliases +- Detached Criteria builder now has a `maxResults( maxResults )` method to limit the results by +- Detached Criteria sql projections now take aliases into account +- SQL Projections and SQL Group By projections now respect aliases ### Base ORM Service -- New Fail fast methods: `getOrFail() proxies to get(), findOrFail() proxies to findIt()` that if not entity is produced will throw a `EntityNotFound` exception -- All listing methods can now return the results as a cbStream by passing the `asStream` boolean argument. -- Removed `criteriaCount(), criteriaQuery()` from BaseService, this was the legacy criteria builder approach, please use `newCriteria()` instead. -- Update `getEntityGivenName` to support ACF2018 -- Lazy loading `BeanPopulator` for performance on creations -- Lazy loading `ORMEventHandler` for performance on creations -- Lazy loading `restrictions` for performance on creations -- Base service can now be initialized with a `datasource`, or uses the default one declared -- Added optional `datasource` to many listing methods -- Added consistency on querying options to all major functions to include `ignoreCase, sorting and timeouts`. -- Added ability to `getAll()` to retrieve read only entities using the `readOnly` argument. -- The `getAll()` method has a new `properties` argument that if passed will allow you to retrieve an array of structs according to the passed in properties. -- New method: `idCast( entity, id )` to auto cast your entity `id` value to java type automatically for you, no more javacasting -- New method: `autoCast( entity, propertyName, value )` to auto cast any value for any entity property automatically, no more javacasting. -- New method: `getKeyValue( entity )` which will give you the value of the entity's unique identifier -- New method: `isDirty( entity )` which will let you know if the entity has dirty values or has its values changed since loaded from the db -- New method: `getEntityMetadata( entity )` which will return to you the hibernate's metadata for a specific entity. -- `getPropertyNames()` argument of `entityname` renamed to `entity` to allow not only for a name but an actual entity as well. -- `getTableName()` argument of `entityname` renamed to `entity` to allow not only for a name but an actual entity as well. -- `getKey()` argument of `entityname` renamed to `entity` to allow not only for a name but an actual entity as well. -- ORM Encapsulation of hibernate metadata retrieval via `getEntityMetadata()` -- `deleteByQuery()` reworked entirely to do native bulk delete queries. It now also returns the number of records removed -- `deleteWhere()` missing flush argument, added datasource as well -- New properties: `wirebox` : a WireBox reference already injected, `logger` : a prepared logger for the class, `datasource` The default datasource or constructed datasource for the class. -- Logging of all activity now available via the `debug` level, even for dynamic methods. -- Refactored all dynamic finders and counters to their own class, which improves not only performance but weight of orm service based entities. -- All dynamic method calls can now return cbStreams as the results -- All dynamic method calls accept a structure as an argument or named as `options` that can have the following keys now: +- New Fail fast methods: `getOrFail() proxies to get(), findOrFail() proxies to findIt()` that if not entity is produced will throw a `EntityNotFound` exception +- All listing methods can now return the results as a cbStream by passing the `asStream` boolean argument. +- Removed `criteriaCount(), criteriaQuery()` from BaseService, this was the legacy criteria builder approach, please use `newCriteria()` instead. +- Update `getEntityGivenName` to support ACF2018 +- Lazy loading `BeanPopulator` for performance on creations +- Lazy loading `ORMEventHandler` for performance on creations +- Lazy loading `restrictions` for performance on creations +- Base service can now be initialized with a `datasource`, or uses the default one declared +- Added optional `datasource` to many listing methods +- Added consistency on querying options to all major functions to include `ignoreCase, sorting and timeouts`. +- Added ability to `getAll()` to retrieve read only entities using the `readOnly` argument. +- The `getAll()` method has a new `properties` argument that if passed will allow you to retrieve an array of structs according to the passed in properties. +- New method: `idCast( entity, id )` to auto cast your entity `id` value to java type automatically for you, no more javacasting +- New method: `autoCast( entity, propertyName, value )` to auto cast any value for any entity property automatically, no more javacasting. +- New method: `getKeyValue( entity )` which will give you the value of the entity's unique identifier +- New method: `isDirty( entity )` which will let you know if the entity has dirty values or has its values changed since loaded from the db +- New method: `getEntityMetadata( entity )` which will return to you the hibernate's metadata for a specific entity. +- `getPropertyNames()` argument of `entityname` renamed to `entity` to allow not only for a name but an actual entity as well. +- `getTableName()` argument of `entityname` renamed to `entity` to allow not only for a name but an actual entity as well. +- `getKey()` argument of `entityname` renamed to `entity` to allow not only for a name but an actual entity as well. +- ORM Encapsulation of hibernate metadata retrieval via `getEntityMetadata()` +- `deleteByQuery()` reworked entirely to do native bulk delete queries. It now also returns the number of records removed +- `deleteWhere()` missing flush argument, added datasource as well +- New properties: `wirebox` : a WireBox reference already injected, `logger` : a prepared logger for the class, `datasource` The default datasource or constructed datasource for the class. +- Logging of all activity now available via the `debug` level, even for dynamic methods. +- Refactored all dynamic finders and counters to their own class, which improves not only performance but weight of orm service based entities. +- All dynamic method calls can now return cbStreams as the results +- All dynamic method calls accept a structure as an argument or named as `options` that can have the following keys now: ```json { @@ -440,7 +440,7 @@ The available types are the following which match the Hibernate Types results = ormservice.findByLastLoginBetween( "User", "01/01/2008", "11/01/2008", { sortBy="LastName" } ); ``` -- All dynamic finders/counters values are autocasted, you no longer need to cast the values, we will do this for you. You can turn it off via the `autocast:false` in the options to the calls.# +- All dynamic finders/counters values are autocasted, you no longer need to cast the values, we will do this for you. You can turn it off via the `autocast:false` in the options to the calls.# ## [Virtual Entity Service] @@ -450,71 +450,71 @@ Remember this entity extends Base Service, so we get all the features above plus Remember this entity extends the Virtual Service, so we get all the features above plus the following: -- Faster creation speeds due to lazy loading of dependencies and better datasource determination. -- `refresh(), merge(), evict()` refactored to encapsulate login in the base orm service and not itself +- Faster creation speeds due to lazy loading of dependencies and better datasource determination. +- `refresh(), merge(), evict()` refactored to encapsulate login in the base orm service and not itself ## 1.5.0 -- Performance improvements for criteria building as we now build up the dialect and support structs -- ACF 2018 Support via Hibernate 5 -- Update to leverage new module template schema -- Updated readme from old text +- Performance improvements for criteria building as we now build up the dialect and support structs +- ACF 2018 Support via Hibernate 5 +- Update to leverage new module template schema +- Updated readme from old text ## 1.4.0 -- ColdBox 5 Support -- Dependency updates -- Some syntax updates -- Fix `getKey()` return typing to allow composite keys: -- Update to module standard template -- Updated dependencies +- ColdBox 5 Support +- Dependency updates +- Some syntax updates +- Fix `getKey()` return typing to allow composite keys: +- Update to module standard template +- Updated dependencies ## 1.3.0 -- Pass the target value as the rejected value for Unique validator -- Travis Updates -- Dependency updates -- Lucee 5 exceptions on ORM Util due to abstract keyword +- Pass the target value as the rejected value for Unique validator +- Travis Updates +- Dependency updates +- Lucee 5 exceptions on ORM Util due to abstract keyword ## 1.2.2 -- Travis updates -- COLDBOX-460 Dynamic finders fixed by always adding datasource attribute to hql query -- Fixes an interface error on AC11 startup +- Travis updates +- COLDBOX-460 Dynamic finders fixed by always adding datasource attribute to hql query +- Fixes an interface error on AC11 startup ## 1.2.1 -- Fixed box.json version number +- Fixed box.json version number ## 1.2.0 -- BaseORMService.merge doesn't seem to merge entities back into session #10 -- Variable scoping in SQLHelper.cfc bug #9 -- Update build process to leverage Travis -- Updated `cbvalidation` to v1.1.0 -- Build cleanup -- Replaced `StringBuffer` with `StringBuilder` for performance +- BaseORMService.merge doesn't seem to merge entities back into session #10 +- Variable scoping in SQLHelper.cfc bug #9 +- Update build process to leverage Travis +- Updated `cbvalidation` to v1.1.0 +- Build cleanup +- Replaced `StringBuffer` with `StringBuilder` for performance ## 1.1.0 -- Updated cbvalidation dependency -- Prevent conditionals from being stripped from property names -- Updated build for api docs and commandbox usage for dependencies -- ORM Unique validation not working +- Updated cbvalidation dependency +- Prevent conditionals from being stripped from property names +- Updated build for api docs and commandbox usage for dependencies +- ORM Unique validation not working ## 1.0.2 -- updates to all dependencies -- production ignore lists +- updates to all dependencies +- production ignore lists ## 1.0.1 -- CF11Compat - arrayContainsNoCase() Is not a function -- Lucee support +- CF11Compat - arrayContainsNoCase() Is not a function +- Lucee support ## 1.0.0 -- Create first module version +- Create first module version [Unreleased]: https://github.com/coldbox-modules/cborm/compare/v4.4.0...HEAD From 033d75212b54f490dcc2f9e395da5280fc37c48c Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 20 Apr 2023 18:55:04 +0200 Subject: [PATCH 06/21] fixing changelog for automated builds --- changelog.md | 99 +++++++++++++++++++++++++++------------------------- 1 file changed, 51 insertions(+), 48 deletions(-) diff --git a/changelog.md b/changelog.md index 9f8fc89..6f391ad 100644 --- a/changelog.md +++ b/changelog.md @@ -304,18 +304,19 @@ where p.name like ?1 and p.isStatus = ?2 - You will need to move the `orm` configuration structure in your `config/ColdBox.cfc` to the `moduleSettings` struct and rename it to `cborm` to standardize it to module settings. - - moduleSettings = { - - cborm = { - inject = { - enabled = true, - includes = "", - excludes = "" - } - } - - }; +```js +moduleSettings = { + + cborm = { + inject = { + enabled = true, + includes = "", + excludes = "" + } + } + +}; +``` - `deleteByQuery()` reworked entirely to do native bulk delete queries. It now also returns the number of records removed - The `evict()` method was renamed to `evictCollection()` to better satisfy the same contract in hibernate @@ -350,43 +351,47 @@ where p.name like ?1 and p.isStatus = ?2 - The `sql()` restriction now supports binding positional parameters. You can pass them in an array and we will infer the types: `sql( "id = ? and isActive = ?", [ "123", true ] )`. Or you can pass in a struct of `{value:"", type:""}` instead: - restrictions.sql( "userName = ? and firstName like ?", [ - { value : "joe", type : "string" }, - { value : "%joe%", type : "string" } - ] ); +```js +restrictions.sql( "userName = ? and firstName like ?", [ + { value : "joe", type : "string" }, + { value : "%joe%", type : "string" } +] ); +``` The available types are the following which match the Hibernate Types - this.TYPES = { - "string" : "StringType", - "clob" : "ClobType", - "text" : "TextType", - "char" : "ChareacterType", - "boolean" : "BooleanType", - "yesno" : "YesNoType", - "truefalse" : "TrueFalseType", - "byte" : "ByteType", - "short" : "ShortType", - "integer" : "IntegerType", - "long" : "LongType", - "float" : "FloatType", - "double" : "DoubleType", - "bigInteger" : "BigIntegerType", - "bigDecimal" : "BigDecimalType", - "timestamp" : "TimestampType", - "time" : "TimeType", - "date" : "DateType", - "calendar" : "CalendarType", - "currency" : "CurrencyType", - "locale" : "LocaleType", - "timezone" : "TimeZoneType", - "url" : "UrlType", - "class" : "ClassType", - "blob" : "BlobType", - "binary" : "BinaryType", - "uuid" : "UUIDCharType", - "serializable" : "SerializableType" - }; +```js +this.TYPES = { + "string" : "StringType", + "clob" : "ClobType", + "text" : "TextType", + "char" : "ChareacterType", + "boolean" : "BooleanType", + "yesno" : "YesNoType", + "truefalse" : "TrueFalseType", + "byte" : "ByteType", + "short" : "ShortType", + "integer" : "IntegerType", + "long" : "LongType", + "float" : "FloatType", + "double" : "DoubleType", + "bigInteger" : "BigIntegerType", + "bigDecimal" : "BigDecimalType", + "timestamp" : "TimestampType", + "time" : "TimeType", + "date" : "DateType", + "calendar" : "CalendarType", + "currency" : "CurrencyType", + "locale" : "LocaleType", + "timezone" : "TimeZoneType", + "url" : "UrlType", + "class" : "ClassType", + "blob" : "BlobType", + "binary" : "BinaryType", + "uuid" : "UUIDCharType", + "serializable" : "SerializableType" +}; +``` - Detached Criteria builder now has a `maxResults( maxResults )` method to limit the results by - Detached Criteria sql projections now take aliases into account @@ -516,6 +521,4 @@ Remember this entity extends the Virtual Service, so we get all the features abo - Create first module version -[Unreleased]: https://github.com/coldbox-modules/cborm/compare/v4.4.0...HEAD - [4.4.0]: https://github.com/coldbox-modules/cborm/compare/13af593fa8a7bf2c4396e9be9d0dd0bb6899e935...v4.4.0 From 0454a20a64dfd0218e8cfa810b2582ec877eebaf Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 20 Apr 2023 19:11:42 +0200 Subject: [PATCH 07/21] github support files --- .github/ISSUE_TEMPLATE/BUG_REPORT.md | 33 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/FEATURE_REQUEST.md | 18 +++++++++++++ .github/PULL_REQUEST_TEMPLATE.md | 29 ++++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/BUG_REPORT.md create mode 100644 .github/ISSUE_TEMPLATE/FEATURE_REQUEST.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.md b/.github/ISSUE_TEMPLATE/BUG_REPORT.md new file mode 100644 index 0000000..300232e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.md @@ -0,0 +1,33 @@ +--- +name: Bug report +about: Create a report to help us improve +--- + + + +## What are the steps to reproduce this issue? + +1. … +2. … +3. … + +## What happens? + +… + +## What were you expecting to happen? + +… + +## Any logs, error output, etc? + +… + +## Any other comments? + +… + +## What versions are you using? + +**Operating System:** … +**Package Version:** … diff --git a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md new file mode 100644 index 0000000..c10946f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md @@ -0,0 +1,18 @@ +--- +name: Feature Request +about: Request a new feature or enhancement +--- + + + +## Summary + + + +## Detailed Description + + + +## Possible Implementation Ideas + + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..e8bd9f9 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,29 @@ +# Description + +Please include a summary of the changes and which issue(s) is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. + +**Please note that all PRs must have tests attached to them** + +IMPORTANT: Please review the [CONTRIBUTING.md](../CONTRIBUTING.md) file for detailed contributing guidelines. + +## Issues + +All PRs must have an accompanied issue. Please make sure you created it and linked it here. + +## Type of change + +Please delete options that are not relevant. + +- [ ] Bug Fix +- [ ] Improvement +- [ ] New Feature +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] This change requires a documentation update + +## Checklist + +- [ ] My code follows the style guidelines of this project [cfformat](../.cfformat.json) +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation +- [ ] I have added tests that prove my fix is effective or that my feature works +- [ ] New and existing unit tests pass locally with my changes From 97ea7ee484736861d158b357627992c6ce5de16d Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 24 Jun 2024 17:31:45 +0200 Subject: [PATCH 08/21] fixing markdown --- .markdownlint.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.markdownlint.json b/.markdownlint.json index 3707fcb..cd13022 100644 --- a/.markdownlint.json +++ b/.markdownlint.json @@ -8,8 +8,7 @@ "no-multiple-blanks": { "maximum": 2 }, - "no-duplicate-header" : { - "siblings_only" : true - }, + "no-duplicate-header" : false, + "no-duplicate-heading" : false, "no-inline-html" : false } From 460c26c5e682f045808279ec59c899c30907d5d6 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 24 Jun 2024 17:45:34 +0200 Subject: [PATCH 09/21] adobe 2023 server support --- box.json | 5 ++++- server-adobe@2023.json | 12 ++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/box.json b/box.json index 43c8900..0304813 100644 --- a/box.json +++ b/box.json @@ -57,12 +57,15 @@ "start:lucee":"server start serverConfigFile=server-lucee@5.json", "start:2018":"server start serverConfigFile=server-adobe@2018.json", "start:2021":"server start serverConfigFile=server-adobe@2021.json", + "start:2023":"server start serverConfigFile=server-adobe@2023.json", "stop:lucee":"server stop serverConfigFile=server-lucee@5.json", "stop:2018":"server stop serverConfigFile=server-adobe@2018.json", "stop:2021":"server stop serverConfigFile=server-adobe@2021.json", + "stop:2023":"server stop serverConfigFile=server-adobe@2023.json", "logs:lucee":"server log serverConfigFile=server-lucee@5.json --follow", "logs:2018":"server log serverConfigFile=server-adobe@2018.json --follow", - "logs:2021":"server log serverConfigFile=server-adobe@2021.json --follow" + "logs:2021":"server log serverConfigFile=server-adobe@2021.json --follow", + "logs:2023":"server log serverConfigFile=server-adobe@2023.json --follow" }, "installPaths":{ "cbvalidation":"modules/cbvalidation/", diff --git a/server-adobe@2023.json b/server-adobe@2023.json index 9ebec68..2b533ae 100644 --- a/server-adobe@2023.json +++ b/server-adobe@2023.json @@ -11,8 +11,8 @@ "rewrites":{ "enable":"true" }, - "webroot": "test-harness", - "aliases":{ + "webroot":"test-harness", + "aliases":{ "/moduleroot/cborm":"../" } }, @@ -20,10 +20,10 @@ "heapSize":"1024" }, "openBrowser":"false", - "cfconfig": { - "file" : ".cfconfig.json" - }, - "scripts" : { + "cfconfig":{ + "file":".cfconfig.json" + }, + "scripts":{ "onServerInstall":"cfpm install zip,debugger,mysql,orm,postgresql,sqlserver,feed" } } From cabd6621fee0bf75c23697d32dc03ceebb6b9f44 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 24 Jun 2024 17:45:43 +0200 Subject: [PATCH 10/21] remvoed old deprecated --- server-lucee-hibernate@5.4.json | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 server-lucee-hibernate@5.4.json diff --git a/server-lucee-hibernate@5.4.json b/server-lucee-hibernate@5.4.json deleted file mode 100644 index c3c8f67..0000000 --- a/server-lucee-hibernate@5.4.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name":"cborm-lucee-hibernate@5", - "app":{ - "serverHomeDirectory":".engine/lucee5", - "cfengine":"lucee@5.3.9-SNAPSHOT+3" - }, - "web":{ - "http":{ - "port":"60299" - }, - "rewrites":{ - "enable":"true" - }, - "webroot":"test-harness", - "aliases":{ - "/moduleroot/cborm":"./" - } - }, - "jvm":{ - "heapSize":"1024", - "args":"-Dlucee.extensions='https://ext.lucee.org/hibernate-orm-5.4.29.15-BETA.lex'" - }, - "openBrowser":"false", - "cfconfig": { - "file" : ".cfconfig.json" - } -} From 3b2e9c2867ec0b620f3fbff34fc1b616389dbd13 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 24 Jun 2024 17:45:53 +0200 Subject: [PATCH 11/21] lucee 6 support --- server-lucee@6.json | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 server-lucee@6.json diff --git a/server-lucee@6.json b/server-lucee@6.json new file mode 100644 index 0000000..d039567 --- /dev/null +++ b/server-lucee@6.json @@ -0,0 +1,26 @@ +{ + "name":"cborm-lucee@6", + "app":{ + "serverHomeDirectory":".engine/lucee6", + "cfengine":"lucee@6" + }, + "web":{ + "http":{ + "port":"60299" + }, + "rewrites":{ + "enable":"true" + }, + "webroot":"test-harness", + "aliases":{ + "/moduleroot/cborm":"./" + } + }, + "jvm":{ + "heapSize":"1024" + }, + "openBrowser":"false", + "cfconfig":{ + "file":".cfconfig.json" + } +} From 9933fb4ec9308fb636bfdba7f184c3fe8de7fffa Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 24 Jun 2024 18:00:02 +0200 Subject: [PATCH 12/21] ### Added - Tons of updates to automated testing - Automated tewsting for Lucee 6 - Automated testing for Adobe 2023 ### Changed - Changed the way of creating base criteria queries due to Adobe bug. --- .github/workflows/release.yml | 18 +++++++++--------- .github/workflows/tests.yml | 22 +++++++++------------- changelog.md | 10 ++++++++++ models/BaseORMService.cfc | 2 +- server-lucee@5.json | 3 +++ server-lucee@6.json | 3 +++ 6 files changed, 35 insertions(+), 23 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6219288..883457c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,7 +29,7 @@ jobs: runs-on: ubuntu-20.04 steps: - name: Checkout Repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup CommandBox uses: Ortus-Solutions/setup-commandbox@v2.0.1 @@ -50,7 +50,7 @@ jobs: fi - name: Update changelog [unreleased] with latest version - uses: thomaseizinger/keep-a-changelog-new-release@1.3.0 + uses: thomaseizinger/keep-a-changelog-new-release@3.0.0 if: env.SNAPSHOT == 'false' with: changelogPath: ./changelog.md @@ -64,7 +64,7 @@ jobs: box task run taskfile=build/Build target=run :version=${{ env.VERSION }} :projectName=${{ env.MODULE_ID }} :buildID=${{ github.run_number }} :branch=${{ env.BRANCH }} - name: Commit Changelog To Master - uses: EndBug/add-and-commit@v9.1.1 + uses: EndBug/add-and-commit@v9.1.4 if: env.SNAPSHOT == 'false' with: author_name: Github Actions @@ -73,7 +73,7 @@ jobs: add: changelog.md - name: Tag Version - uses: rickstaa/action-create-tag@v1.6.1 + uses: rickstaa/action-create-tag@v1.7.2 if: env.SNAPSHOT == 'false' with: tag: "v${{ env.VERSION }}" @@ -82,7 +82,7 @@ jobs: - name: Upload Build Artifacts if: success() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{ env.MODULE_ID }} path: | @@ -118,7 +118,7 @@ jobs: box forgebox publish --force - name: Create Github Release - uses: taiki-e/create-gh-release-action@v1.6.2 + uses: taiki-e/create-gh-release-action@v1.8.2 continue-on-error: true if: env.SNAPSHOT == 'false' with: @@ -138,7 +138,7 @@ jobs: steps: # Checkout development - name: Checkout Repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: development @@ -148,7 +148,7 @@ jobs: forgeboxAPIKey: ${{ secrets.FORGEBOX_TOKEN }} - name: Download build artifacts - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: ${{ env.MODULE_ID }} path: .tmp @@ -165,7 +165,7 @@ jobs: # Commit it back to development - name: Commit Version Bump - uses: EndBug/add-and-commit@v9.1.1 + uses: EndBug/add-and-commit@v9.1.4 with: author_name: Github Actions author_email: info@ortussolutions.com diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 08a3f3a..f4d368d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -18,29 +18,25 @@ jobs: strategy: fail-fast: false matrix: - cfengine: [ "lucee@5", "adobe@2018", "adobe@2021" ] - coldboxVersion: [ "^6.0.0" ] + cfengine: [ "lucee@5", "lucee@6", "adobe@2018", "adobe@2021", "adobe@2023" ] + coldboxVersion: [ "^6.0.0", "^7.0.0" ] experimental: [ false ] include: - - cfengine: "adobe@2023" - coldboxVersion: "^6.0.0" - experimental: true - - cfengine: "lucee-hibernate@5.4" - coldboxVersion: "^6.0.0" - experimental: true - coldboxVersion: "be" cfengine: "lucee@5" experimental: true - coldboxVersion: "be" - cfengine: "adobe@2018" + cfengine: "lucee@6" + experimental: true + - coldboxVersion: "be" + cfengine: "adobe@2023" experimental: true - coldboxVersion: "be" cfengine: "adobe@2021" experimental: true steps: - name: Checkout Repository - uses: actions/checkout@v3 - + uses: actions/checkout@v4 - name: Setup Java uses: actions/setup-java@v3 @@ -98,7 +94,7 @@ jobs: - name: Upload Test Results to Artifacts if: always() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: test-results-${{ matrix.cfengine }}-${{ matrix.coldboxVersion }} path: | @@ -111,7 +107,7 @@ jobs: - name: Upload Debug Logs To Artifacts if: ${{ failure() }} - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Failure Debugging Info - ${{ matrix.cfengine }} - ${{ matrix.coldboxVersion }} path: | diff --git a/changelog.md b/changelog.md index 6f391ad..77bd1fc 100644 --- a/changelog.md +++ b/changelog.md @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Tons of updates to automated testing +- Automated tewsting for Lucee 6 +- Automated testing for Adobe 2023 + +### Changed + +- Changed the way of creating base criteria queries due to Adobe bug. + ## [4.4.0] - 2023-04-19 ### Added diff --git a/models/BaseORMService.cfc b/models/BaseORMService.cfc index 0d0d157..f5b73b3 100644 --- a/models/BaseORMService.cfc +++ b/models/BaseORMService.cfc @@ -1917,7 +1917,7 @@ process( // mix in yourself as a dependency arguments.ormService = this; // create new criteria builder, it's a transient - return variables.wirebox.getInstance( "CriteriaBuilder@cborm", arguments ); + return new criterion.CriteriaBuilder( argumentCollection = arguments ); } diff --git a/server-lucee@5.json b/server-lucee@5.json index b5e6ec5..57c55d6 100644 --- a/server-lucee@5.json +++ b/server-lucee@5.json @@ -22,5 +22,8 @@ "openBrowser":"false", "cfconfig":{ "file":".cfconfig.json" + }, + "env":{ + "LUCEE_EXTENSIONS":"D062D72F-F8A2-46F0-8CBC91325B2F067B" } } diff --git a/server-lucee@6.json b/server-lucee@6.json index d039567..b82e8c8 100644 --- a/server-lucee@6.json +++ b/server-lucee@6.json @@ -22,5 +22,8 @@ "openBrowser":"false", "cfconfig":{ "file":".cfconfig.json" + }, + "env":{ + "LUCEE_EXTENSIONS":"D062D72F-F8A2-46F0-8CBC91325B2F067B" } } From 9c98f4c79739f8008aaf173b48da7e8a7d91fa5a Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 24 Jun 2024 19:37:53 +0200 Subject: [PATCH 13/21] - Lucee detection of transaction was incorrect. - The way support for the orm utilities are created and stored. --- changelog.md | 11 +- models/util/CFORMUtil.cfc | 25 --- models/util/LuceeORMUtil.cfc | 39 ---- models/util/ORMUtilFactory.cfc | 22 ++- models/util/support/AdobeORMUtil.cfc | 25 +++ models/util/support/BoxLangORMUtil.cfc | 15 ++ models/util/{ => support}/IORMUtil.cfc | 3 + models/util/support/LuceeORMUtil.cfc | 77 ++++++++ models/util/{ => support}/ORMUtilSupport.cfc | 54 ++---- server-adobe@2023.json | 2 +- server-lucee@5.json | 2 +- test-harness/box.json | 2 +- test-harness/tests/index.cfm | 168 ++++++++++++------ test-harness/tests/resources/BaseTest.cfc | 27 ++- .../tests/specs/util/ORMUtilFactoryTest.cfc | 19 +- .../tests/specs/util/ORMUtilSupportTest.cfc | 28 --- test-harness/tests/specs/util/ORMUtilTest.cfc | 62 ------- .../specs/util/support/AdobeORMUtilTest.cfc | 10 ++ .../specs/util/support/LuceeORMUtilTest.cfc | 10 ++ .../ORMUtilSupportTest.cfc} | 45 +++-- 20 files changed, 352 insertions(+), 294 deletions(-) delete mode 100644 models/util/CFORMUtil.cfc delete mode 100644 models/util/LuceeORMUtil.cfc create mode 100644 models/util/support/AdobeORMUtil.cfc create mode 100644 models/util/support/BoxLangORMUtil.cfc rename models/util/{ => support}/IORMUtil.cfc (86%) create mode 100644 models/util/support/LuceeORMUtil.cfc rename models/util/{ => support}/ORMUtilSupport.cfc (74%) delete mode 100644 test-harness/tests/specs/util/ORMUtilSupportTest.cfc delete mode 100755 test-harness/tests/specs/util/ORMUtilTest.cfc create mode 100755 test-harness/tests/specs/util/support/AdobeORMUtilTest.cfc create mode 100644 test-harness/tests/specs/util/support/LuceeORMUtilTest.cfc rename test-harness/tests/specs/util/{CFORMUtilTest.cfc => support/ORMUtilSupportTest.cfc} (53%) mode change 100755 => 100644 diff --git a/changelog.md b/changelog.md index 77bd1fc..8328b42 100644 --- a/changelog.md +++ b/changelog.md @@ -9,14 +9,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Tons of updates to automated testing -- Automated tewsting for Lucee 6 -- Automated testing for Adobe 2023 +- Tons of updates to automated testing. +- Automated tewsting for Lucee 6. +- Automated testing for Adobe 2023. ### Changed +- The way support for the orm utilities are created and stored. - Changed the way of creating base criteria queries due to Adobe bug. +### Fixed + +- Lucee detection of transaction was incorrect. + ## [4.4.0] - 2023-04-19 ### Added diff --git a/models/util/CFORMUtil.cfc b/models/util/CFORMUtil.cfc deleted file mode 100644 index 0bdfdd3..0000000 --- a/models/util/CFORMUtil.cfc +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp - * www.ortussolutions.com - * --- - * - * Adobe CF Based ORM Utility - * - * @author Luis Majano & Mike McKellip - */ -component implements="cborm.models.util.IORMUtil" extends="cborm.models.util.ORMUtilSupport" { - - /** - * Retrieve the entity mode in effect for this session. - * - * @ormSession Pass the hibernate ORM session - * - * @return https://docs.jboss.org/hibernate/core/3.5/javadocs/org/hibernate/EntityMode.html - */ - any function getSessionEntityMode( required ormSession, required entity ){ - return arguments.ormSession - .getEntityPersister( arguments.ormSession.getEntityName( arguments.entity ), arguments.entity ) - .getEntityMode(); - } - -} diff --git a/models/util/LuceeORMUtil.cfc b/models/util/LuceeORMUtil.cfc deleted file mode 100644 index 5c276ac..0000000 --- a/models/util/LuceeORMUtil.cfc +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp - * www.ortussolutions.com - * --- - * - * Lucee Based ORM Utility - * - * @author Luis Majano & Mike McKellip - */ -component extends="cborm.models.util.ORMUtilSupport" implements="cborm.models.util.IORMUtil" { - - /** - * Get hibernate session object - * - * @datasource optional datasource - * @override - */ - any function getSession( string datasource ){ - return ( !isNull( arguments.datasource ) ? ormGetSession( arguments.datasource ) : ormGetSession() ); - } - - /** - * Retrieve the entity mode in effect for this session. - * - * @ormSession Pass the hibernate ORM session - * - * @return https://docs.jboss.org/hibernate/orm/5.4/javadocs/org/hibernate/EntityMode.html - */ - any function getSessionEntityMode( required ormSession, required entity ){ - if ( listFirst( getHibernateVersion(), "." ) >= 5 ) { - return arguments.ormSession - .getEntityPersister( arguments.ormSession.getEntityName( arguments.entity ), arguments.entity ) - .getEntityMode(); - } else { - return arguments.ormSession.getEntityMode(); - } - } - -} diff --git a/models/util/ORMUtilFactory.cfc b/models/util/ORMUtilFactory.cfc index 3062805..2f4b50e 100644 --- a/models/util/ORMUtilFactory.cfc +++ b/models/util/ORMUtilFactory.cfc @@ -7,23 +7,33 @@ * * @author Luis Majano & Mike McKellip */ -import cborm.models.util.*; +import cborm.models.util.support.*; component { + this.isBoxLang = server.keyExists( "boxlang" ); + this.isLucee = server.keyExists( "lucee" ); + this.isAdobe = server.coldfusion.productname == "ColdFusion Server"; + /** * Get the ORM Utility object * * @return IORMUtil */ function getORMUtil(){ - // Adobe ColdFusion - if ( getPlatform() == "ColdFusion Server" ) { - return new CFORMUtil(); + + if( this.isAdobe ){ + return new AdobeORMUtil(); + } + + if( this.isLucee ){ + return new LuceeORMUtil(); + } + + if( this.isBoxLang ){ + return new BoxLangORMUtil(); } - // Lucee Support - return new LuceeORMUtil(); } /** diff --git a/models/util/support/AdobeORMUtil.cfc b/models/util/support/AdobeORMUtil.cfc new file mode 100644 index 0000000..f0b716d --- /dev/null +++ b/models/util/support/AdobeORMUtil.cfc @@ -0,0 +1,25 @@ +/** + * Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * + * The Adobe based ORM utility support + * + * @author Luis Majano & Mike McKellip + */ +component + implements="IORMUtil" + extends="ORMUtilSupport" { + + /** + * Cross-engine transaction detection. + * Useful for preventing nested transactions. + * + * @see https://dev.lucee.org/t/determine-if-code-is-inside-cftransaction/7358 + */ + public boolean function isInTransaction(){ + var transactionObj = createObject( "java", "coldfusion.tagext.sql.TransactionTag" ); + return !isNull( transactionObj.getCurrent() ); + } + +} diff --git a/models/util/support/BoxLangORMUtil.cfc b/models/util/support/BoxLangORMUtil.cfc new file mode 100644 index 0000000..a7d4b39 --- /dev/null +++ b/models/util/support/BoxLangORMUtil.cfc @@ -0,0 +1,15 @@ +/** + * Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * + * The BoxLang based ORM utility support + * + * @author Luis Majano & Mike McKellip + */ +component + implements="IORMUtil" + extends="ORMUtilSupport" { + + +} diff --git a/models/util/IORMUtil.cfc b/models/util/support/IORMUtil.cfc similarity index 86% rename from models/util/IORMUtil.cfc rename to models/util/support/IORMUtil.cfc index d446f58..a707256 100644 --- a/models/util/IORMUtil.cfc +++ b/models/util/support/IORMUtil.cfc @@ -17,5 +17,8 @@ interface { string function getDefaultDatasource(); any function getEntityMetadata( required string entityName, required string datasource ); any function getSessionEntityMode( required ormSession, required entity ); + boolean function isInTransaction(); + string function getHibernateVersion(); + void function setupHibernateLogging( level = "WARN" ); } diff --git a/models/util/support/LuceeORMUtil.cfc b/models/util/support/LuceeORMUtil.cfc new file mode 100644 index 0000000..aaa902f --- /dev/null +++ b/models/util/support/LuceeORMUtil.cfc @@ -0,0 +1,77 @@ +/** + * Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * + * Lucee Based ORM Utility + * + * @author Luis Majano & Mike McKellip + */ +component + implements="IORMUtil" + extends="ORMUtilSupport"{ + + /** + * Get hibernate session object + * + * @datasource optional datasource + * @override + */ + any function getSession( string datasource ){ + return ( !isNull( arguments.datasource ) ? ormGetSession( arguments.datasource ) : ormGetSession() ); + } + + /** + * Work around the insanity of Lucee's custom Hibernate jar, + * which has a bad MANIFEST.MF with no specified `Implementation-Version` config. + */ + public string function getHibernateVersion(){ + return createObject( "java", "org.hibernate.Version" ) + .getClass() + .getClassLoader() + .getBundle() + .getVersion() + .toString(); + } + + /** + * Cross-engine transaction detection. + * Useful for preventing nested transactions. + * + * @see https://dev.lucee.org/t/determine-if-code-is-inside-cftransaction/7358 + */ + public boolean function isInTransaction(){ + return IsWithinTransaction(); + } + + /** + * Sets up Hibernate logging levels and redirects logs to system out. + * + * @level The logging level to set in hibernate: ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF, TRACE + */ + void function setupHibernateLogging( level = "WARN" ){ + /** + * Resolves Hibernate ConcurrentModificationException when flushing an entity save with one-to-many relationships. + * + * @see https://access.redhat.com/solutions/29774 + * @see https://michaelborn.me/entry/resolving-concurrent-exceptions-in-hibernate-logger + */ + var Logger = createObject( "java", "org.apache.log4j.Logger" ); + var log4jLevel = createObject( "java", "org.apache.log4j.Level" ); + var hibernateLog = Logger.getLogger( "org.hibernate" ); + hibernateLog.setLevel( log4jLevel[ arguments.level ] ); + + /** + * Redirect all Hibernate logs to system.out + */ + var printWriter = getPageContext().getConfig().getOutWriter(); + var layout = createObject( "java", "lucee.commons.io.log.log4j.layout.ClassicLayout" ); + var consoleAppender = createObject( "java", "lucee.commons.io.log.log4j.appender.ConsoleAppender" ).init( + printWriter, + layout + ); + hibernateLog.addAppender( consoleAppender ); + writeDump( var = "** Lucee Hibernate Logging Redirected", output = "console" ); + } + +} diff --git a/models/util/ORMUtilSupport.cfc b/models/util/support/ORMUtilSupport.cfc similarity index 74% rename from models/util/ORMUtilSupport.cfc rename to models/util/support/ORMUtilSupport.cfc index 1aa72b0..38703d0 100644 --- a/models/util/ORMUtilSupport.cfc +++ b/models/util/support/ORMUtilSupport.cfc @@ -3,7 +3,7 @@ * www.ortussolutions.com * --- * - * An agnostic CFML Engine utility class + * An agnostic CFML Engine utility class for working with Hibernate ORM. * * @author Luis Majano & Mike McKellip */ @@ -25,20 +25,6 @@ component singleton { var log4jLevel = createObject( "java", "org.apache.log4j.Level" ); var hibernateLog = Logger.getLogger( "org.hibernate" ); hibernateLog.setLevel( log4jLevel[ arguments.level ] ); - - /** - * Redirect all Hibernate logs to system.out - */ - if ( listFindNoCase( "Lucee", server.coldfusion.productname ) ) { - var printWriter = getPageContext().getConfig().getOutWriter(); - var layout = createObject( "java", "lucee.commons.io.log.log4j.layout.ClassicLayout" ); - var consoleAppender = createObject( "java", "lucee.commons.io.log.log4j.appender.ConsoleAppender" ).init( - printWriter, - layout - ); - hibernateLog.addAppender( consoleAppender ); - writeDump( var = "** Lucee Hibernate Logging Redirected", output = "console" ); - } } /** @@ -55,9 +41,11 @@ component singleton { } /** - * Get session + * Get the hibernate session * * @datasource Optional datsource + * + * @return org.hibernate.Session */ any function getSession( string datasource ){ if ( !isNull( arguments.datasource ) ) { @@ -179,37 +167,23 @@ component singleton { } /** - * Work around the insanity of Lucee's custom Hibernate jar, - * which has a bad MANIFEST.MF with no specified `Implementation-Version` config. + * Get the Hibernate version */ public string function getHibernateVersion(){ - var version = createObject( "java", "org.hibernate.Version" ); - - if ( version.getVersionString() != "[WORKING]" ) { - return version.getVersionString(); - } else { - return version - .getClass() - .getClassLoader() - .getBundle() - .getVersion() - .toString(); - } + return createObject( "java", "org.hibernate.Version" ).getVersionString(); } /** - * Cross-engine transaction detection. - * Useful for preventing nested transactions. + * Retrieve the entity mode in effect for this session. + * + * @ormSession Pass the hibernate ORM session * - * @see https://dev.lucee.org/t/determine-if-code-is-inside-cftransaction/7358 + * @return https://docs.jboss.org/hibernate/core/3.5/javadocs/org/hibernate/EntityMode.html */ - public boolean function isInTransaction(){ - if ( listFindNoCase( "Lucee", server.coldfusion.productname ) ) { - return ormGetSession().isTransactionInProgress(); - } else { - var transactionObj = createObject( "java", "coldfusion.tagext.sql.TransactionTag" ); - return !isNull( transactionObj.getCurrent() ); - } + any function getSessionEntityMode( required ormSession, required entity ){ + return arguments.ormSession + .getEntityPersister( arguments.ormSession.getEntityName( arguments.entity ), arguments.entity ) + .getEntityMode(); } } diff --git a/server-adobe@2023.json b/server-adobe@2023.json index 2b533ae..cfe0e6c 100644 --- a/server-adobe@2023.json +++ b/server-adobe@2023.json @@ -2,7 +2,7 @@ "name":"cborm-adobe@2023", "app":{ "serverHomeDirectory":".engine/adobe2023", - "cfengine":"adobe@2023.0.0-beta.1" + "cfengine":"adobe@2023" }, "web":{ "http":{ diff --git a/server-lucee@5.json b/server-lucee@5.json index 57c55d6..b31e261 100644 --- a/server-lucee@5.json +++ b/server-lucee@5.json @@ -23,7 +23,7 @@ "cfconfig":{ "file":".cfconfig.json" }, - "env":{ + "env":{ "LUCEE_EXTENSIONS":"D062D72F-F8A2-46F0-8CBC91325B2F067B" } } diff --git a/test-harness/box.json b/test-harness/box.json index f0af021..971819d 100644 --- a/test-harness/box.json +++ b/test-harness/box.json @@ -5,10 +5,10 @@ "private":true, "description":"", "dependencies":{ + "coldbox":"^7.0.0", "cbvalidation":"^4.0.0", "mementifier":"^3.0.0", "cbstreams":"^2.0.0", - "coldbox":"be", "cbpaginator":"^2.0.0" }, "devDependencies":{ diff --git a/test-harness/tests/index.cfm b/test-harness/tests/index.cfm index 0ccfa80..a91c040 100644 --- a/test-harness/tests/index.cfm +++ b/test-harness/tests/index.cfm @@ -1,53 +1,49 @@ - - - - - - - - - - + + // No cf debugging + cfsetting( showdebugoutput="false" ); + // Path Navigation + param name="url.path" default=""; + // Root Tests Directory + rootMapping = "/tests/specs"; + rootPath = expandPath( rootMapping ); + targetPath = rootPath; + // Append navigation path + if( len( url.path ) ){ + targetPath = getCanonicalPath( rootpath & "/" & url.path ); + // Avoid traversals + if( !findNoCase( rootpath, targetPath ) ){ + targetPath = rootpath; + } + } + // Get the actual execution path + executePath = rootMapping & ( len( url.path ) ? "/#url.path#" : "/" ); - - - - - - - - - - - - - - - #testbox.init( directory=rootMapping & url.path ).run()# - -

Invalid incoming directory: #rootMapping & url.path#

-
- - -
- - - - - - - - - - - - - + // Directory Runner + if( !isNull( url.action ) ){ + if( directoryExists( targetPath ) ){ + writeOutput( "#new testbox.system.TestBox( directory=executePath ).run()#" ); + } else { + writeOutput( "

Invalid Directory: #encodeForHTML( targetPath )#

" ); + } + abort; + } + // Get target path listing + qResults = directoryList( targetPath, false, "query", "", "name" ); + // Get the back path + if( len( url.path ) ){ + backPath = url.path.listToArray( "/\" ); + backPath.pop(); + backPath = backPath.toList( "/" ); + } + // TestBox Assets + ASSETS_DIR = expandPath( "/testbox/system/reports/assets" ); + TESTBOX_VERSION = new testBox.system.TestBox().getVersion(); +
- + TestBox Browser @@ -56,51 +52,105 @@ - -
+ +

- v#testbox.getVersion()# + v#TESTBOX_VERSION#
- + + +
+ + +
+
+

Availble Test Runners:

+

+ Below is a listing of the runners matching the "runner*.cfm" pattern. +

+ + + + #runners.name# + +
+
+ +

TestBox Test Browser:

- Below is a listing of the files and folders starting from your root #rootPath#. You can click on individual tests in order to execute them + Below is a listing of the files and folders starting from your root #rootMapping#. You can click on individual tests in order to execute them or click on the Run All button on your left and it will execute a directory runner from the visible folder.

- Contents: #executePath# - -

+ #targetPath.replace( rootPath, "" )# + + + + + + +
+
+ + - - ✚ #qResults.name#
+ + &##x271A; #qResults.name# + +
- target="_blank"
>#qResults.name#
+ + #qResults.name# + +
- target="_blank"
>#qResults.name#
+ + #qResults.name# + +
- #qResults.name#
+ #qResults.name# +
@@ -112,4 +162,4 @@ - \ No newline at end of file + diff --git a/test-harness/tests/resources/BaseTest.cfc b/test-harness/tests/resources/BaseTest.cfc index e4a2715..be1ef5f 100644 --- a/test-harness/tests/resources/BaseTest.cfc +++ b/test-harness/tests/resources/BaseTest.cfc @@ -13,9 +13,6 @@ component extends="coldbox.system.testing.BaseTestCase" appMapping="/root" { function beforeAll(){ super.beforeAll(); getWireBox().autowire( this ); - - var ormUtil = createMock( "cborm.models.util.ORMUtilSupport" ); - debug( "Hibernate version is: #ormUtil.getHibernateVersion()#" ); } // executes after all suites+specs in the run() method @@ -36,11 +33,31 @@ component extends="coldbox.system.testing.BaseTestCase" appMapping="/root" { } function isCF(){ - return ( structKeyExists( server, "lucee" ) ? false : true ); + return server.coldfusion.productname == "ColdFusion Server"; + } + + function notCF(){ + return !isCF(); + } + + function isLucee(){ + return server.keyExists( "lucee" ); + } + + function notLucee(){ + return !isLucee(); + } + + function isBoxLang(){ + return server.keyExists( "boxlang" ); + } + + function notBoxLang(){ + return !isBoxLang(); } function isCF2018Plus(){ - if ( !structKeyExists( server, "lucee" ) && listFirst( server.coldfusion.productVersion ) >= 2018 ) { + if ( isCF() && listFirst( server.coldfusion.productVersion ) >= 2018 ) { return true; } return false; diff --git a/test-harness/tests/specs/util/ORMUtilFactoryTest.cfc b/test-harness/tests/specs/util/ORMUtilFactoryTest.cfc index b41caaa..52a0d07 100755 --- a/test-harness/tests/specs/util/ORMUtilFactoryTest.cfc +++ b/test-harness/tests/specs/util/ORMUtilFactoryTest.cfc @@ -1,7 +1,7 @@ /** * My BDD Test */ -component extends="testbox.system.BaseSpec" { +component extends="tests.resources.BaseTest" { /*********************************** LIFE CYCLE Methods ***********************************/ @@ -17,22 +17,27 @@ component extends="testbox.system.BaseSpec" { /*********************************** BDD SUITES ***********************************/ function run(){ - // all your suites go here. describe( "ORM Util Factory", function(){ it( title = "can get adobe instance", + body = function(){ + var u = factory.getORMUtil(); + expect( u ).toBeInstanceOf( "cborm.models.util.support.CFORMUtil" ); + }, + skip = !isCF() + ); + + it( + title = "can get lucee instance", body = function(){ factory.$( "getPlatform", "ColdFusion Server" ); var u = factory.getORMUtil(); - expect( u ).toBeInstanceOf( "cborm.models.util.CFORMUtil" ); + expect( u ).toBeInstanceOf( "cborm.models.util.support.LuceeORMUtil" ); }, - skip = isLucee + skip = !isLucee() ); } ); - } - function isLucee(){ - return structKeyExists( server, "lucee" ); } } diff --git a/test-harness/tests/specs/util/ORMUtilSupportTest.cfc b/test-harness/tests/specs/util/ORMUtilSupportTest.cfc deleted file mode 100644 index 67c5abf..0000000 --- a/test-harness/tests/specs/util/ORMUtilSupportTest.cfc +++ /dev/null @@ -1,28 +0,0 @@ -component extends="tests.resources.BaseTest" { - - function setup(){ - variables.ormUtil = createMock( "cborm.models.util.ORMUtilSupport" ); - } - - function testIsInTransaction(){ - assertEquals( ormutil.isInTransaction(), false ); - - transaction { - assertEquals( ormutil.isInTransaction(), true ); - } - - assertEquals( ormutil.isInTransaction(), false ); - - transaction { - ormGetSession(); - var test = entityLoad( "User", { firstName : "Luis" }, true ); - assertEquals( ormutil.isInTransaction(), true ); - ormFlush(); - assertEquals( ormutil.isInTransaction(), true ); - } - - ormFlush(); - assertEquals( ormutil.isInTransaction(), false ); - } - -} diff --git a/test-harness/tests/specs/util/ORMUtilTest.cfc b/test-harness/tests/specs/util/ORMUtilTest.cfc deleted file mode 100755 index 0e925a2..0000000 --- a/test-harness/tests/specs/util/ORMUtilTest.cfc +++ /dev/null @@ -1,62 +0,0 @@ -component extends="tests.resources.BaseTest" skip="isCF" { - - function setup(){ - ormUtil = createMock( "cborm.models.util.LuceeORMUtil" ); - } - - function testflush(){ - ormutil.flush(); - } - - function testGetSession(){ - t = ormutil.getSession(); - } - - function testgetSessionFactory(){ - t = ormutil.getSessionFactory(); - } - - function testclearSession(){ - t = ormutil.clearSession(); - } - - function testcloseSession(){ - t = ormutil.closeSession(); - } - - function testevictQueries(){ - t = ormutil.evictQueries(); - t = ormutil.evictQueries( "users" ); - } - - function testGetEntityDatasource(){ - d = ormutil.getEntityDatasource( "User" ); - assertEquals( "coolblog", d ); - - d = ormutil.getEntityDatasource( entityNew( "User" ) ); - assertEquals( "coolblog", d ); - - d = ormutil.getEntityDatasource( entityNew( "Category" ) ); - assertEquals( "coolblog", d ); - } - - function testGetDefaultDatasource(){ - assertEquals( "coolblog", ormutil.getDefaultDatasource() ); - } - - function testGetHibernateVersion(){ - debug( ormutil.getHibernateVersion() ); - /** - * ! LUCEE-ONLY - */ - var hibernateExtension = extensionList().filter( function( extension ){ - return extension.name == "Hibernate ORM Engine"; - } ); - if ( listContains( hibernateExtension.version, "5.4.29" ) > 0 ) { - assertEquals( "5.4.29.1", ormutil.getHibernateVersion() ); - } else { - assertEquals( "3.5.5-Final", ormutil.getHibernateVersion() ); - } - } - -} diff --git a/test-harness/tests/specs/util/support/AdobeORMUtilTest.cfc b/test-harness/tests/specs/util/support/AdobeORMUtilTest.cfc new file mode 100755 index 0000000..fe983d7 --- /dev/null +++ b/test-harness/tests/specs/util/support/AdobeORMUtilTest.cfc @@ -0,0 +1,10 @@ +component extends="ORMUtilSupportTest" skip="notCF" { + + function setup(){ + super.setup(); + ormUtil = createMock( "cborm.models.util.support.AdobeORMUtil" ); + // CF ENGINE MUST HAVE coolblog as a DSN + dsn = "coolblog"; + } + +} diff --git a/test-harness/tests/specs/util/support/LuceeORMUtilTest.cfc b/test-harness/tests/specs/util/support/LuceeORMUtilTest.cfc new file mode 100644 index 0000000..87f9ff5 --- /dev/null +++ b/test-harness/tests/specs/util/support/LuceeORMUtilTest.cfc @@ -0,0 +1,10 @@ +component extends="ORMUtilSupportTest" skip="notLucee" { + + function setup(){ + super.setup(); + ormUtil = createMock( "cborm.models.util.support.LuceeORMUtil" ); + // CF ENGINE MUST HAVE coolblog as a DSN + dsn = "coolblog"; + } + +} diff --git a/test-harness/tests/specs/util/CFORMUtilTest.cfc b/test-harness/tests/specs/util/support/ORMUtilSupportTest.cfc old mode 100755 new mode 100644 similarity index 53% rename from test-harness/tests/specs/util/CFORMUtilTest.cfc rename to test-harness/tests/specs/util/support/ORMUtilSupportTest.cfc index bcb3d74..000aeb7 --- a/test-harness/tests/specs/util/CFORMUtilTest.cfc +++ b/test-harness/tests/specs/util/support/ORMUtilSupportTest.cfc @@ -1,10 +1,24 @@ -component extends="tests.resources.BaseTest" skip="isLucee" { +component extends="tests.resources.BaseTest" skip="true"{ - function setup(){ - super.setup(); - ormUtil = createMock( "cborm.models.util.CFORMUtil" ); - // CF ENGINE MUST HAVE coolblog as a DSN - dsn = "coolblog"; + function testIsInTransaction(){ + assertEquals( false, ormutil.isInTransaction(), "no transaction" ); + + transaction { + assertEquals( true, ormutil.isInTransaction(), "simple transaction" ); + } + + assertEquals( false, ormutil.isInTransaction(), "outside transaction" ); + + transaction { + ormGetSession(); + var test = entityLoad( "User", { firstName : "Luis" }, true ); + assertEquals( true, ormutil.isInTransaction(), "second transaction" ); + ormFlush(); + assertEquals( true, ormutil.isInTransaction(), "second transaction" ); + } + + ormFlush(); + assertEquals( false, ormutil.isInTransaction() ); } function testflush(){ @@ -14,12 +28,16 @@ component extends="tests.resources.BaseTest" skip="isLucee" { function testGetSession(){ t = ormutil.getSession(); + expect( t ).notToBeNull(); t = ormutil.getSession( dsn ); + expect( t ).notToBeNull(); } function testgetSessionFactory(){ t = ormutil.getSessionFactory(); + expect( t ).notToBeNull(); t = ormutil.getSessionFactory( dsn ); + expect( t ).notToBeNull(); } function testclearSession(){ @@ -53,17 +71,10 @@ component extends="tests.resources.BaseTest" skip="isLucee" { assertEquals( "coolblog", ormutil.getDefaultDatasource() ); } - function isLucee(){ - return structKeyExists( server, "lucee" ); - } - - function testGetHibernateVersion(){ - debug( ormutil.getHibernateVersion() ); - - // Fragile test: These will need updating if (and only if) the engines upgrade the installed Hibernate version - if ( listFirst( server.coldfusion.productVersion ) == 2018 ) { - assertEquals( "5.2.11.SNAPSHOT", ormutil.getHibernateVersion() ); - } + function testgetHibernateVersion(){ + t = ormutil.getHibernateVersion(); + debug( t ); + expect( t ).notToBeEmpty(); } } From 7a4c42ffd03dbd62ac37287238a4cdf667196944 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 24 Jun 2024 19:45:13 +0200 Subject: [PATCH 14/21] - Lucee detection of transaction was incorrect - SQL Helper not using the appropriate engine helper --- changelog.md | 4 +++- models/sql/SQLHelper.cfc | 4 ++-- models/util/support/LuceeORMUtil.cfc | 13 ------------- 3 files changed, 5 insertions(+), 16 deletions(-) diff --git a/changelog.md b/changelog.md index 8328b42..6d638c3 100644 --- a/changelog.md +++ b/changelog.md @@ -20,7 +20,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- Lucee detection of transaction was incorrect. +- Lucee Hibernate version was incorrect +- Lucee detection of transaction was incorrect +- SQL Helper not using the appropriate engine helper ## [4.4.0] - 2023-04-19 diff --git a/models/sql/SQLHelper.cfc b/models/sql/SQLHelper.cfc index 7c795f2..09128a5 100644 --- a/models/sql/SQLHelper.cfc +++ b/models/sql/SQLHelper.cfc @@ -48,7 +48,7 @@ component accessors="true" { variables.criteriaImpl = variables.cb.getNativeCriteria(); variables.ormSession = variables.criteriaImpl.getSession(); variables.ormFactory = variables.ormSession.getFactory(); - variables.ormUtil = new cborm.models.util.ORMUtilSupport(); + variables.ormUtil = new cborm.models.util.ORMUtilFactory().getORMUtil(); // Load Hibernate Properties Accordingly to version setupHibernateProperties(); @@ -65,7 +65,7 @@ component accessors="true" { * Setup hibernate class properties according to Hibernate version with CFML Engine */ private function setupHibernateProperties(){ - // get formatter for sql string beautification: ACF vs Lucee + // get formatter for sql string beautification variables.hibernateVersion = listFirst( variables.ormUtil.getHibernateVersion(), "." ); switch ( variables.hibernateVersion ) { case "3": diff --git a/models/util/support/LuceeORMUtil.cfc b/models/util/support/LuceeORMUtil.cfc index aaa902f..35775b2 100644 --- a/models/util/support/LuceeORMUtil.cfc +++ b/models/util/support/LuceeORMUtil.cfc @@ -21,19 +21,6 @@ component return ( !isNull( arguments.datasource ) ? ormGetSession( arguments.datasource ) : ormGetSession() ); } - /** - * Work around the insanity of Lucee's custom Hibernate jar, - * which has a bad MANIFEST.MF with no specified `Implementation-Version` config. - */ - public string function getHibernateVersion(){ - return createObject( "java", "org.hibernate.Version" ) - .getClass() - .getClassLoader() - .getBundle() - .getVersion() - .toString(); - } - /** * Cross-engine transaction detection. * Useful for preventing nested transactions. From e811b996f8072cb357be25f80091fcacbf1886f9 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 24 Jun 2024 19:59:08 +0200 Subject: [PATCH 15/21] all tests green locally --- models/util/support/AdobeORMUtil.cfc | 16 ++++++++++++++++ test-harness/tests/specs/BaseORMServiceTest.cfc | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/models/util/support/AdobeORMUtil.cfc b/models/util/support/AdobeORMUtil.cfc index f0b716d..5f491a0 100644 --- a/models/util/support/AdobeORMUtil.cfc +++ b/models/util/support/AdobeORMUtil.cfc @@ -22,4 +22,20 @@ component return !isNull( transactionObj.getCurrent() ); } + public string function getHibernateVersion(){ + // Dumb Adobe proxy crap + var version = createObject( "java", "org.hibernate.Version" ); + + if ( version.getVersionString() != "[WORKING]" ) { + return version.getVersionString(); + } else { + return version + .getClass() + .getClassLoader() + .getBundle() + .getVersion() + .toString(); + } + } + } diff --git a/test-harness/tests/specs/BaseORMServiceTest.cfc b/test-harness/tests/specs/BaseORMServiceTest.cfc index fbc75fe..00e50f6 100755 --- a/test-harness/tests/specs/BaseORMServiceTest.cfc +++ b/test-harness/tests/specs/BaseORMServiceTest.cfc @@ -26,7 +26,7 @@ testCatID = "3A2C516C-41CE-41D3-A9224EA690ED1128"; test2 = [ "1", "2" ]; - variables.ormUtil = createMock( "cborm.models.util.ORMUtilSupport" ); + variables.ormUtil = new cborm.models.util.ORMUtilFactory().getORMUtil(); } function testCountByDynamically(){ From bffa3da4f0d1b59963ae84c11a6e588a8ac527d5 Mon Sep 17 00:00:00 2001 From: lmajano Date: Mon, 24 Jun 2024 17:59:44 +0000 Subject: [PATCH 16/21] Apply cfformat changes --- models/util/ORMUtilFactory.cfc | 12 +++---- models/util/support/AdobeORMUtil.cfc | 6 ++-- models/util/support/BoxLangORMUtil.cfc | 4 +-- models/util/support/LuceeORMUtil.cfc | 8 ++--- .../tests/specs/util/ORMUtilFactoryTest.cfc | 1 - .../specs/util/support/ORMUtilSupportTest.cfc | 34 +++++++++++++++---- 6 files changed, 38 insertions(+), 27 deletions(-) diff --git a/models/util/ORMUtilFactory.cfc b/models/util/ORMUtilFactory.cfc index 2f4b50e..87c0f64 100644 --- a/models/util/ORMUtilFactory.cfc +++ b/models/util/ORMUtilFactory.cfc @@ -12,8 +12,8 @@ import cborm.models.util.support.*; component { this.isBoxLang = server.keyExists( "boxlang" ); - this.isLucee = server.keyExists( "lucee" ); - this.isAdobe = server.coldfusion.productname == "ColdFusion Server"; + this.isLucee = server.keyExists( "lucee" ); + this.isAdobe = server.coldfusion.productname == "ColdFusion Server"; /** * Get the ORM Utility object @@ -21,19 +21,17 @@ component { * @return IORMUtil */ function getORMUtil(){ - - if( this.isAdobe ){ + if ( this.isAdobe ) { return new AdobeORMUtil(); } - if( this.isLucee ){ + if ( this.isLucee ) { return new LuceeORMUtil(); } - if( this.isBoxLang ){ + if ( this.isBoxLang ) { return new BoxLangORMUtil(); } - } /** diff --git a/models/util/support/AdobeORMUtil.cfc b/models/util/support/AdobeORMUtil.cfc index 5f491a0..4c8ebbf 100644 --- a/models/util/support/AdobeORMUtil.cfc +++ b/models/util/support/AdobeORMUtil.cfc @@ -7,9 +7,7 @@ * * @author Luis Majano & Mike McKellip */ -component - implements="IORMUtil" - extends="ORMUtilSupport" { +component implements="IORMUtil" extends="ORMUtilSupport" { /** * Cross-engine transaction detection. @@ -24,7 +22,7 @@ component public string function getHibernateVersion(){ // Dumb Adobe proxy crap - var version = createObject( "java", "org.hibernate.Version" ); + var version = createObject( "java", "org.hibernate.Version" ); if ( version.getVersionString() != "[WORKING]" ) { return version.getVersionString(); diff --git a/models/util/support/BoxLangORMUtil.cfc b/models/util/support/BoxLangORMUtil.cfc index a7d4b39..8599637 100644 --- a/models/util/support/BoxLangORMUtil.cfc +++ b/models/util/support/BoxLangORMUtil.cfc @@ -7,9 +7,7 @@ * * @author Luis Majano & Mike McKellip */ -component - implements="IORMUtil" - extends="ORMUtilSupport" { +component implements="IORMUtil" extends="ORMUtilSupport" { } diff --git a/models/util/support/LuceeORMUtil.cfc b/models/util/support/LuceeORMUtil.cfc index 35775b2..5b12272 100644 --- a/models/util/support/LuceeORMUtil.cfc +++ b/models/util/support/LuceeORMUtil.cfc @@ -7,15 +7,13 @@ * * @author Luis Majano & Mike McKellip */ -component - implements="IORMUtil" - extends="ORMUtilSupport"{ +component implements="IORMUtil" extends="ORMUtilSupport" { /** * Get hibernate session object * * @datasource optional datasource - * @override + * @override */ any function getSession( string datasource ){ return ( !isNull( arguments.datasource ) ? ormGetSession( arguments.datasource ) : ormGetSession() ); @@ -28,7 +26,7 @@ component * @see https://dev.lucee.org/t/determine-if-code-is-inside-cftransaction/7358 */ public boolean function isInTransaction(){ - return IsWithinTransaction(); + return isWithinTransaction(); } /** diff --git a/test-harness/tests/specs/util/ORMUtilFactoryTest.cfc b/test-harness/tests/specs/util/ORMUtilFactoryTest.cfc index 52a0d07..f819c81 100755 --- a/test-harness/tests/specs/util/ORMUtilFactoryTest.cfc +++ b/test-harness/tests/specs/util/ORMUtilFactoryTest.cfc @@ -37,7 +37,6 @@ component extends="tests.resources.BaseTest" { skip = !isLucee() ); } ); - } } diff --git a/test-harness/tests/specs/util/support/ORMUtilSupportTest.cfc b/test-harness/tests/specs/util/support/ORMUtilSupportTest.cfc index 000aeb7..6d3b4eb 100644 --- a/test-harness/tests/specs/util/support/ORMUtilSupportTest.cfc +++ b/test-harness/tests/specs/util/support/ORMUtilSupportTest.cfc @@ -1,24 +1,44 @@ -component extends="tests.resources.BaseTest" skip="true"{ +component extends="tests.resources.BaseTest" skip="true" { function testIsInTransaction(){ - assertEquals( false, ormutil.isInTransaction(), "no transaction" ); + assertEquals( + false, + ormutil.isInTransaction(), + "no transaction" + ); transaction { - assertEquals( true, ormutil.isInTransaction(), "simple transaction" ); + assertEquals( + true, + ormutil.isInTransaction(), + "simple transaction" + ); } - assertEquals( false, ormutil.isInTransaction(), "outside transaction" ); + assertEquals( + false, + ormutil.isInTransaction(), + "outside transaction" + ); transaction { ormGetSession(); var test = entityLoad( "User", { firstName : "Luis" }, true ); - assertEquals( true, ormutil.isInTransaction(), "second transaction" ); + assertEquals( + true, + ormutil.isInTransaction(), + "second transaction" + ); ormFlush(); - assertEquals( true, ormutil.isInTransaction(), "second transaction" ); + assertEquals( + true, + ormutil.isInTransaction(), + "second transaction" + ); } ormFlush(); - assertEquals( false, ormutil.isInTransaction() ); + assertEquals( false, ormutil.isInTransaction() ); } function testflush(){ From 8bfc233ed567f3cb19919b502d8eb734a5392d26 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 24 Jun 2024 20:10:07 +0200 Subject: [PATCH 17/21] fix tests --- test-harness/tests/specs/util/ORMUtilFactoryTest.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-harness/tests/specs/util/ORMUtilFactoryTest.cfc b/test-harness/tests/specs/util/ORMUtilFactoryTest.cfc index f819c81..910cb6f 100755 --- a/test-harness/tests/specs/util/ORMUtilFactoryTest.cfc +++ b/test-harness/tests/specs/util/ORMUtilFactoryTest.cfc @@ -22,7 +22,7 @@ component extends="tests.resources.BaseTest" { title = "can get adobe instance", body = function(){ var u = factory.getORMUtil(); - expect( u ).toBeInstanceOf( "cborm.models.util.support.CFORMUtil" ); + expect( u ).toBeInstanceOf( "cborm.models.util.support.AdobeORMUtil" ); }, skip = !isCF() ); From 238c0c0af90708726e97100d24759699b0996611 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 24 Jun 2024 20:12:43 +0200 Subject: [PATCH 18/21] removing some more test debug --- test-harness/tests/specs/BaseORMServiceTest.cfc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test-harness/tests/specs/BaseORMServiceTest.cfc b/test-harness/tests/specs/BaseORMServiceTest.cfc index 00e50f6..c852da2 100755 --- a/test-harness/tests/specs/BaseORMServiceTest.cfc +++ b/test-harness/tests/specs/BaseORMServiceTest.cfc @@ -100,7 +100,7 @@ function testClear(){ test = entityLoad( "User" ); stats = ormservice.getSessionStatistics(); - debug( stats ); + //debug( stats ); ormservice.clear(); @@ -154,7 +154,7 @@ // Test with arguments. user = ormService.new( entityName = "User", properties = { firstName : "luis", lastName : "majano" } ); - debug( user ); + //debug( user ); assertEquals( "luis", user.getFirstName() ); assertEquals( "majano", user.getLastName() ); } @@ -162,7 +162,7 @@ function testNewWithProperties(){ // Test Porperties user = ormService.new( "User", { firstName : "pio", lastName : "majano" } ); - debug( user ); + //debug( user ); assertEquals( "pio", user.getFirstName() ); assertEquals( "majano", user.getLastName() ); } @@ -245,7 +245,7 @@ test.setDescription( "dirty dirty" ); var properties = ormService.getDirtyPropertyNames( test ); - debug( properties ); + //debug( properties ); expect( properties ).toHaveLength( 2 ); } @@ -298,7 +298,7 @@ ormCloseSession(); } var test = entityLoad( "Category", { category : "unittest" } ); - debug( test ); + //debug( test ); ormservice.delete( entity = test[ 1 ], transactional = false ); ormFlush(); ormservice.clear(); @@ -616,7 +616,7 @@ function testExecuteQuery(){ var test = ormservice.executeQuery( query = "from Category" ); - debug( test ); + //debug( test ); assertTrue( isArray( test ) ); assertTrue( arrayLen( test ) ); From 51b3a4966274d1fb41aa27c8574f65d41b73a6b4 Mon Sep 17 00:00:00 2001 From: lmajano Date: Mon, 24 Jun 2024 18:13:38 +0000 Subject: [PATCH 19/21] Apply cfformat changes --- test-harness/tests/specs/BaseORMServiceTest.cfc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test-harness/tests/specs/BaseORMServiceTest.cfc b/test-harness/tests/specs/BaseORMServiceTest.cfc index c852da2..970fc34 100755 --- a/test-harness/tests/specs/BaseORMServiceTest.cfc +++ b/test-harness/tests/specs/BaseORMServiceTest.cfc @@ -100,7 +100,7 @@ function testClear(){ test = entityLoad( "User" ); stats = ormservice.getSessionStatistics(); - //debug( stats ); + // debug( stats ); ormservice.clear(); @@ -154,7 +154,7 @@ // Test with arguments. user = ormService.new( entityName = "User", properties = { firstName : "luis", lastName : "majano" } ); - //debug( user ); + // debug( user ); assertEquals( "luis", user.getFirstName() ); assertEquals( "majano", user.getLastName() ); } @@ -162,7 +162,7 @@ function testNewWithProperties(){ // Test Porperties user = ormService.new( "User", { firstName : "pio", lastName : "majano" } ); - //debug( user ); + // debug( user ); assertEquals( "pio", user.getFirstName() ); assertEquals( "majano", user.getLastName() ); } @@ -245,7 +245,7 @@ test.setDescription( "dirty dirty" ); var properties = ormService.getDirtyPropertyNames( test ); - //debug( properties ); + // debug( properties ); expect( properties ).toHaveLength( 2 ); } @@ -298,7 +298,7 @@ ormCloseSession(); } var test = entityLoad( "Category", { category : "unittest" } ); - //debug( test ); + // debug( test ); ormservice.delete( entity = test[ 1 ], transactional = false ); ormFlush(); ormservice.clear(); @@ -616,7 +616,7 @@ function testExecuteQuery(){ var test = ormservice.executeQuery( query = "from Category" ); - //debug( test ); + // debug( test ); assertTrue( isArray( test ) ); assertTrue( arrayLen( test ) ); From 6de27e850cc49351e03ba23c0ba1646b6b095bd3 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 24 Jun 2024 20:18:04 +0200 Subject: [PATCH 20/21] removed lucee6 as cborm is broken --- .github/workflows/tests.yml | 2 +- changelog.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f4d368d..7b8eaab 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -18,7 +18,7 @@ jobs: strategy: fail-fast: false matrix: - cfengine: [ "lucee@5", "lucee@6", "adobe@2018", "adobe@2021", "adobe@2023" ] + cfengine: [ "lucee@5", "adobe@2018", "adobe@2021", "adobe@2023" ] coldboxVersion: [ "^6.0.0", "^7.0.0" ] experimental: [ false ] include: diff --git a/changelog.md b/changelog.md index 6d638c3..ffd075e 100644 --- a/changelog.md +++ b/changelog.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Tons of updates to automated testing. -- Automated tewsting for Lucee 6. +- Automated tewsting for Lucee 6 as experimental, since it's broken. - Automated testing for Adobe 2023. ### Changed From 38f54c7772fcc821b413453049111c98414733e2 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Mon, 24 Jun 2024 20:26:11 +0200 Subject: [PATCH 21/21] apidocs issues --- build/Build.cfc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build/Build.cfc b/build/Build.cfc index ee9366e..b15a671 100644 --- a/build/Build.cfc +++ b/build/Build.cfc @@ -12,6 +12,7 @@ component { variables.cwd = getCWD().reReplace( "\.$", "" ); variables.artifactsDir = cwd & "/.artifacts"; variables.buildDir = cwd & "/.tmp"; + variables.apidDocsDir = variables.buildDir & "/apidocs"; variables.apiDocsURL = "http://localhost:60299/apidocs/"; variables.testRunner = "http://localhost:60299/tests/runner.cfm"; @@ -31,7 +32,8 @@ component { // Cleanup + Init Build Directories [ variables.buildDir, - variables.artifactsDir + variables.artifactsDir, + variables.apidDocsDir ].each( function( item ){ if ( directoryExists( item ) ) { directoryDelete( item, true );