BoxLang 🚀 A New JVM Dynamic Language Learn More...

quick

v10.0.0 Modules


Build Status

A CFML ORM Engine

Why?

Quick was built out of lessons learned and persistent challenges in developing complex RDBMS applications using built-in Hibernate ORM in CFML.

  • Hibernate ORM error messages often obfuscate the actual cause of the error because they are provided directly by the Java classes.
  • Complex CFML Hibernate ORM applications can consume significant memory and processing resources, making them cost-prohibitive and inefficient when used in microservices architecture.
  • Hibernate ORM is tied to the engine releases. This means that updates come infrequently and may be costly for non-OSS engine users.
  • Hibernate ORM is built in Java. This limits contributions from CFML developers who don't know Java or don't feel comfortable contributing to a Java project.
  • Hibernate ORM doesn't take advantage of a lot of dynamic- and meta-programming available in CFML. (Tools like CBORM have helped to bridge this gap.)

We can do better.

What?

Quick is an ORM (Object Relational Mapper) written in CFML for CFML. It provides an ActiveRecord implementation for working with your database. With it you can map database tables to components, create relationships between components, query and manipulate data, and persist all your changes to your database.

Prerequisites

You need the following configured before using Quick:

  • Configure a default datasource in your CFML engine
  • ColdBox 6+
  • Add a mapping for quick in your Application.cfc
  • Configure your BaseGrammar in config/ColdBox.cfc

See Getting Started for more details.

Supported Databases

Quick supports all databases supported by qb.

Example

Here's a "quick" example to whet your appetite.

We'll show the database structure using a migrations file. This isn't required to use quick, but it is highly recommended.

// 2017_11_10_122835_create_users_table.cfc
component {

    function up() {
        schema.create( "users", function( table ) {
            table.increments( "id" );
            table.string( "username" ).unique();
            table.string( "email" ).unique();
            table.string( "password" );
            table.timestamp( "createdDate" );
            table.timestamp( "updatedDate" );
        } );
    }

}
// User
component extends="quick.models.BaseEntity" {

    // the name of the table is the pluralized version of the model
    // this can be configured on a per-entity basis

}
// handlers/Users.cfc
component {

    // /users/:id
    function show( event, rc, prc ) {
        // this finds the User with an id of 1 and retrieves it
        prc.user = getInstance( "User" ).findOrFail( rc.id );
        event.setView( "users/show" );
    }

}
<!-- views/users/show.cfm -->
<cfoutput>
    <h1>Hi, #prc.user.getUsername()#!</h1>
</cfoutput>

Now that you've seen an example, dig in to what you can do with Quick!

Tests and Contributing

To run the tests, first clone this repo and run a box install.

Quick's test suite runs specifically on MySQL, so you will need a MySQL database to run the tests. If you do not have one, Docker provides an easy way to start one.

docker run -d --name quick -p 3306:3306 -e MYSQL_RANDOM_ROOT_PASSWORD=yes -e MYSQL_DATABASE=quick -e MYSQL_USER=quick -e MYSQL_PASSWORD=quick mysql:5

Finally, copy the .env.example file to .env and fill in the values for your database.

Prior Art, Acknowledgements, and Thanks

Quick is backed by qb. Without qb, there is no Quick.

Quick is inspired heavily by Eloquent in Laravel. Thank you Taylor Otwell and the Laravel community for a great library.

Development of Quick is sponsored by Ortus Solutions. Thank you Ortus Solutions for investing in the future of CFML.

Community and Support

Join us in our Ortus Community and become a valuable member of this project Quick ORM. We are looking forward to hearing from you!

v10.0.0

08 Oct 2024 — 06:05: 50 UTC

BREAKING

v9.0.3

04 Oct 2024 — 17:13: 58 UTC

fix

  • ChildEntity: Ensure single table inheritance columns are not duplicated (2a37ead)

v9.0.2

24 Sep 2024 — 18:55: 51 UTC

fix

  • HasOneThrough: Add missing matchOne method (a09196e)
  • ChildEntities: Fix qualifying column on discriminated joined entities (d3559bc)

v9.0.1

12 Jun 2024 — 21:45: 58 UTC

fix

  • BaseEntity: Fixed issue with NULL values being inserted into identity columns for MSSQL (4ae80fa)

v9.0.0

31 May 2024 — 22:18: 55 UTC

BREAKING

  • Relationships: Return default entities for non-matched eager loaded entites (b1212de)
  • Child Entities: Fix casting for discriminated entities (288b81b)

chore

  • tests: Only test against Lucee 6 in cron tests (940ed80)
  • tests: Add in Adobe 2023 and ColdBox 7 to the testing matrix (cd3c8da)

feat

  • Relationships: Get a new filled instance of a relationship by calling the fill method on the relationship object (a2da133)
  • Events: Add newAttributes and originalAttributes to the preUpdate event (4dd8496)
  • Relationships: Add additional fetch methods to all relationships (9709b2f)
  • Casts: Allow specifying virtual attributes with a cast (a57d092)

fix

  • Relationships: Clear the relationship cache for a relationship when using the relationship setter (f49b099)
  • BaseEntity: Only computed attributes hash from persistent attributes (164b047)
  • Relationships: Fix naming collision with newEntity function and variable name. (81aedbb)
  • BaseEntity: Handle null values when assigning to attributes (ba3a2f4)
  • HasOneOrMany: Allow returning a new non-persisted entity (084a089)

other

  • *: Fixed issue null check would never pass (38005c9)
  • *: Update JsonCast.cfc (b92fc0a)
  • *: -fixed regression for issue #203 (45095ad)
  • *: remove hydrate in favor of manually assigning attributes (c87cb9c)
  • *: Fixed issue where virtualAttributes were not being applied to discriminated child entities when loading through the parent (149aa9e)

v8.0.3

19 Apr 2024 — 21:16: 01 UTC

fix

  • ModuleConfig: Support qb's SqlCommenter (66799c6)

v8.0.2

26 Mar 2024 — 22:12: 23 UTC

fix

  • Relationships: Handle skipping constraints when a relationship is defined with other relationships (62fa4a4)

v8.0.1

26 Mar 2024 — 20:03: 50 UTC

fix

  • BaseEntity: Make the withoutRelationshipConstraints check more resilient (4aedbac)

v8.0.0

26 Mar 2024 — 19:33: 41 UTC

BREAKING

  • Relationship: Required the relationship name when disabling constraints to match on (dff52d6)

v7.4.4

26 Mar 2024 — 18:11: 18 UTC

fix

  • HasManyThrough: Fix for thread safety when loading multiple relationships off of a single entity (9e49f55)

v7.4.3

22 Mar 2024 — 03:08: 47 UTC

fix

  • HasManyDeep: Fix qualifying column issue (72723b1)

v7.4.2

20 Mar 2024 — 22:55: 50 UTC

fix

  • HasManyDeep: Remove duplicate join from addCompareConstraints (a9fa07e)

v7.4.1

19 Mar 2024 — 17:54: 52 UTC

fix

  • box.json: Upgrade to latest str dependency (582e4cc)

v7.4.0

18 Mar 2024 — 16:41: 44 UTC

chore

  • tests: Remove extra debug logs from tests (1ba3ca0)

feat

  • HasManyThrough: The hasManyThrough function now returns HasManyDeep relationships (1af491a)
  • Relationships: New hasManyDeep and hasManyDeepBuilder relationships. (5331b36)

fix

  • HasManyThrough: Keep constraints of through entities for hasManyThrough relationships (3f3de36)
  • HasManyThrough: Keep constraints on final related entities in hasManyThrough (95a53d3)
  • IRelationship: Update type hints to satisfy IRelationship interface (026d7e0)

other

v7.3.2

05 Feb 2024 — 20:23: 02 UTC

fix

  • BaseEntity: Use the interceptor approach instead of wirebox:targetId to support CommandBox (164247d)

v7.3.1

03 Jan 2024 — 17:58: 04 UTC

fix

  • Discriminators: Fix where discriminated entities could use the wrong qualified column name in the join with the parent entity. (682aa03)

v7.3.0

21 Dec 2023 — 19:13: 38 UTC

chore

  • tests: add test case for checking null attributes on newly created entities (638754a)
  • tests: add test case for deleteAll off of a hasMany relationship (1626bc5)
  • tests: add test case for belongsToMany withCount (8bfad62)
  • tests: add test case for firstOrNew with aliases and columns (5dc81bf)

feat

  • QuickBuilder: Return optional QuickBuilder instances for withCount and withSum (e1b17cf)

fix

  • BaseEntity: Fix clearAttribute when not setting to null (4018d54)
  • QuickBuilder: Fix using a query builder instance to define a subselect (8ac6ba7)

other

  • *: fix: revert server.json change (4182c55)

v7.2.0

15 Sep 2023 — 20:07: 44 UTC

feat

  • QuickQB: Allow defaultOptions for underlying QuickQB (a1e282f)

v4.1.5

02 Nov 2020 — 12:24: 13 UTC

fix

  • HasOne: Provide initialThroughConstraints for hasOne relationships (7b3b8d0)

v4.1.4

30 Oct 2020 — 18:35: 59 UTC

chore

  • Tests: Add test for dynamic subselect relationships (fdf97eb)

fix

  • Relationship: Don't include orders when doing a count on a relationship (#126) (313c594)

v4.1.3

10 Sep 2020 — 16:11: 22 UTC

chore

  • Testing: Migrate to new database fixtures setup (e65add5)

v4.1.2

04 Sep 2020 — 15:33: 44 UTC

fix

  • Casts: Fix for retaining cast cache when creating entities (835beee)

v4.1.1

03 Sep 2020 — 03:48: 53 UTC

chore

  • Format: Format with CFFormat (621ce6c)

fix

  • Cast: Preserve casted value after saving (8680b1d)

v4.1.0

28 Aug 2020 — 20:59: 11 UTC

feat

  • BaseEntity: Allow for child entities included discriminated entities (28bf5e2)

fix

  • KeyType: Look up returning values by column name not by alias (f1a0832)

v4.0.2

13 Aug 2020 — 05:45: 22 UTC

fix

  • EagerLoading: Skip eager loading when no keys are found (8b83529)
  • Relationships: Only apply CONCAT when needed (db220e2)

v4.0.1

04 Aug 2020 — 21:26: 55 UTC

fix

  • Relationships: Remove DISTINCT in favor of WHERE EXISTS (a051c98)

v4.0.0

24 Jul 2020 — 15:14: 31 UTC

BREAKING

  • Scopes: Scopes with an OR combinator are automatically grouped (3183f6d)

chore

  • docs: Fix broken link from README to official docs (6881634)

feat

  • Relationships: Add a withCount method to easily add relationship counts to entities (8524ef8)
  • QuickBuilder: Automatically scope whereHas and whereDoesntHave callbacks (38b8a46)

fix

  • ErrorMessages: Improve error message when attempting to set relationships on unloaded entities (fe4ad26)
  • Relationships: Fix addSubselect and *manyThrough overflows and bugs (ab8e121)
  • BelongsTo: If all the foreign keys are null, skip the database and return the default entity or null (287e990)
  • BelongsTo: Reference provided localKeys instead of pulling them from the related entity (43f47aa)
  • HasManyThrough: Swap final compare constraints in nested query (22d1728)

v3.1.7

10 Jul 2020 — 16:04: 10 UTC

fix

  • tests: Correct jQuery link in test runner (#95) (7bb1b3d)

v3.1.6

29 Jun 2020 — 19:19: 44 UTC

fix

  • QuickBuilder: Allow expressions in basic where clauses (f267c2f)
  • BaseEntity: Fix delete naming collision (c7dca98)

v3.1.5

24 Jun 2020 — 00:24: 50 UTC

fix

  • QuickBuilder: Add an alias to with (5491ba7)

v3.1.4

19 Jun 2020 — 05:58: 34 UTC

fix

  • QuickBuilder: Fix stack overflow on nested relationship checks (16bae19)

v3.1.3

19 Jun 2020 — 05:44: 30 UTC

fix

  • QuickBuilder: Configured tables are now used for qualifying columns (76bb1f7)

v3.1.2

29 May 2020 — 18:03: 15 UTC

fix

  • BelongsToMany: Remove unnecessary nesting in compare queries (97e3a88)

v3.1.1

28 May 2020 — 22:05: 51 UTC

fix

  • Relationships: Fix orWhereHas methods when querying nested relationships (8262bb3)

v3.1.0

28 May 2020 — 21:25: 33 UTC

feat

  • JSONCast: Add support for JSON casting (137701a)

v3.0.4

27 May 2020 — 05:41: 15 UTC

fix

  • CBORMCompatEntity: Updates for coldbox@6 (1f10fde)

v3.0.3

13 May 2020 — 17:24: 08 UTC

chore

fix

  • Casts: Optimize cast caching (2f9b510)

v3.0.2

11 May 2020 — 20:02: 26 UTC

fix

  • EagerLoading: Apply custom sqltypes during eager loading (c9633d3)

v3.0.1

08 May 2020 — 22:04: 29 UTC

fix

  • BaseEntity: Account for null values in fill (3f8bc2c)
  • Memento: Swap structAppend order for a Lucee bug (1e0d217)

v3.0.0

06 May 2020 — 19:01: 56 UTC

BREAKING

  • QuickBuilder: Prevent duplicate joins by default (a8ac022)
  • BaseEntity: Enforce accessors for entities (ad16248)
  • BaseEntity: Remove virtual inheritance (3b026b1)
  • BaseEntity: Improve virtual column support (5ebc42c)

chore

  • CI: CI debugging (1111603)
  • CI: CI debugging (19b3053)
  • CI: CI debugging (6280040)
  • CI: CI debugging (75bcb64)
  • CI: CI debugging (fda269a)
  • CI: CI debugging (5662bdc)
  • CI: CI debugging (7716222)
  • CI: CI debugging. :-( (1912c2a)
  • CI: Add qb mapping for tests (45c5238)
  • CI: Fix overriding coldbox@be installation (c4f9ae0)
  • CI: Publish API docs after publishing a new version (690b95d)
  • CI: Adjust CI builds to test bleeding edge on cron jobs (0ffdafc)
  • CI: Clean up .travis.yml (d5753b5)

feat

  • Interceptors: Fire the postLoad event for all entities (a480ef2)
  • ErrorMessages: Improve error message when accessing relationships on unloaded entities (d43f699)

fix

  • BaseEntity: Rename is and isNot to isSameAs and isNotSameAs for better ACF compatibility (fff27a1)
  • BaseEntity: Improved hasRelationship check (4064619)
  • QuickBuilder: Fix nested whereHas with belongsToMany Relationships (99f957e)
  • BaseEntity: Fix for virtual columns trying to be updated (5f13e4f)
  • BaseEntity: Qualify all column names and correctly return eager loaded belongsToMany Relationships (09f9c64)
  • BaseEntity: Forward updateOrInsert calls to updateOrCreate (888fa22)
  • Memento: Ensure virtual columns are included in mementos by default (6c72a46)
  • BaseEntity: qualify columns when using fresh and refresh (1cce0a2)
  • QuickBuilder: Clear orders when querying releationships (d77c781)
  • GlobalScopes: Ensure global scopes are only applied once per query (664b288)
  • BaseEntity: Duplicate metadata struct when creating new entities (5c06fa4)
  • BaseEntity: Fix double applying of global scopes (b374caa)
  • BaseEntity: Default polymorphicBelongsTo name to the relation method name (72352d6)

other

refactor

  • BaseEntity: Clean up virtual column naming (88d8237)

v2.5.7

26 Feb 2020 — 00:16: 25 UTC

other

  • *: docs: Fix link to Gitbook from README (5a8cf6a)

v2.5.6

19 Feb 2020 — 22:22: 10 UTC

fix

  • BaseEntity: Correctly use the grammar annotation (2312e9e)

v2.5.5

13 Feb 2020 — 17:30: 08 UTC

other

  • *: chore: Use forgeboxStorage (ad6c413)

v2.5.4

20 Dec 2019 — 06:20: 30 UTC

fix

  • CBORMCompat: Pass along query options in compat methods (9a2739e)

v2.5.3

11 Dec 2019 — 21:40: 12 UTC

fix

  • BaseEntity: Revert calling setters when hydrating entities (670fadb)

v2.5.2

09 Dec 2019 — 17:57: 41 UTC

fix

  • BaseEntity: Pass the entity to when closures (96a8f3a)

v2.5.1

05 Dec 2019 — 04:55: 20 UTC

fix

  • BaseEntity: Account for null values with custom setters (685e175)
  • BaseEntity: Reset underlying query when resetting entity (83a6fdb)

v2.5.0

04 Dec 2019 — 21:53: 02 UTC

feat

  • BaseEntity: Allow entities to define a custom collection type. (9135eee)

v2.4.3

19 Nov 2019 — 07:59: 46 UTC

fix

  • BaseEntity: Avoid stack overflow with getMemento and custom getters (7c9e073)

v2.4.2

08 Nov 2019 — 00:45: 47 UTC

fix

  • memento: Use available getters for the memento (ba562c3)

v2.4.1

07 Nov 2019 — 16:58: 47 UTC

fix

  • memento: Correctly serialize array relationships by default (479dabc)

v2.4.0

06 Nov 2019 — 22:25: 58 UTC

chore

  • dependencies: Update TestBox to version 3 (a0dd6ab)

feat

  • setters: Apply setters when hydrating the entity from the database (e4a0158)
  • ErrorMessages: Improve error messages for not loaded entities (f3f2e2d)
  • Scopes: Query scopes can return any value (358e977)

v2.3.1

06 Nov 2019 — 21:45: 40 UTC

chore

  • build: Adjust travis testbox run (790df84)

fix

  • tests: Fix strange test error on Lucee 5 with nested describe blocks (305e0a2)
  • BaseEntity: Return the correct memento with accessors on (59614a0)

v2.3.0

08 Jul 2019 — 15:46: 12 UTC

feat

  • BaseEntity: Add flag to ignore non-existing attributes to fill (428b31a)

v2.2.3

17 Jun 2019 — 15:06: 40 UTC

fix

  • BaseEntity: Temporary fix for extra values in data (821a054)

v2.2.2

14 Jun 2019 — 05:10: 05 UTC

perf

  • BaseEntity: Better caching of metadata (27b6ec3)

v2.2.1

14 Jun 2019 — 04:37: 21 UTC

chore

  • build: Use openjdk8 in Travis builds (d8f7d41)

other

  • *: docs: Fix Getting Started 404 (5c9eddd)

v2.2.0

29 May 2019 — 03:27: 23 UTC

feat

  • Relationships: Add fetch methods to all Relationships (61a6035)

v2.1.3

14 May 2019 — 01:57: 33 UTC

tests

  • Relationships: Prove relationship setters use the cache (953d653)

v2.1.2

07 May 2019 — 07:07: 20 UTC

fix

  • VirtualInheritance: Certify virtual inheritance support (e105f18)

v2.1.1

03 May 2019 — 22:58: 37 UTC

fix

  • Subselect: Return the entity after executing a subselect (87e5a7a)

v2.1.0

03 May 2019 — 22:25: 30 UTC

feat

  • Relationships: Relationships can be set using relationship setters (e1e21a8)
  • Relationships: Allow saving of ids as well as entities (3f30131)
  • HasMany: Many entities can be saved to a hasMany relationship at once (c9f8f47)
  • Scopes: Register global scopes for entities (995706b)
  • Subselects: Add subselect helper (cf13ddd)

fix

  • Relationships: Make mapping foreign keys optional (708506d)

v1.3.2

30 Apr 2019 — 19:52: 39 UTC

chore

v1.3.1

30 Apr 2019 — 19:43: 23 UTC

chore

docs

  • README: Document that all fields need to be mapped (ecece5c)

v1.3.0

22 Aug 2018 — 19:58: 30 UTC

chore

feat

  • BaseEntity: Enable per entity datasources and grammars (561f368)
  • KeyType: Add AssignedKey Type (897277d)

v1.2.0

19 Jul 2018 — 22:43: 54 UTC

chore

  • build: Fix spotty gpg key (c3c5a18)
  • build: Test adobe@2018 on CI (299d5b0)

feat

  • Scopes: Allow scopes to call other scopes (07bbde1)

v1.1.2

02 Jul 2018 — 17:22: 46 UTC

chore

  • build: Set location automatically on version update (183b05a)

fix

  • BaseEntity: Only set loaded for attributes successfully retrieved from the database (665a78a)

v1.1.1

02 Jul 2018 — 16:54: 21 UTC

fix

  • Relationships: correct detach function name (5dceb17)

other

v1.1.0

06 Jun 2018 — 20:50: 16 UTC

chore

  • box.json: remove package scripts in favor of commandbox-semantic-release (aafe02a)

feat

  • attributes: better guarding against non-existent attributes (0566e35)
  • Columns: Allow attributes to set a sqltype (8c3db73)
  • Relationships: pass arguments through to relationships (5962a19)

fix

  • Update: don't include the key in the SET clause (846ff78)

other

  • *: Enable commandbox-semantic-release (e34f966)

$ box install quick

No collaborators yet.
     
  • {{ getFullDate("2018-04-25T23:02:25Z") }}
  • {{ getFullDate("2024-10-08T06:05:55Z") }}
  • 17,252
  • 183,094