arrow-left

Only this pageAll pages
gitbookPowered by GitBook
1 of 33

6.4.0

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Query Builder

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Schema Builder

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

What's New?

hashtag
6.4.0

  • Allow Expressions (query.raw) in update statements.

Contributing & Filing Issues

We welcome all types of contributions, following the specification. And please take a look at our wonderful contributors on the !

The most common type of contribution is to fix an incorrect SQL generation for a database grammar.

To debug what SQL is being ran, you can always call toSQL on any QueryBuilder or SchemaBuilder object. Additionally, you can listen to the preQBExecute interception point for the generated SQL.

Each of the database grammars have two tests β€”
{Grammar}QueryBuilderSpec.cfc
and
{Grammar}SchemaBuilderSpec.cfc
. These tests run the same qb syntax across the different grammars. In each test are methods that return SQL strings like so:

If you find an issue with the SQL generated from a grammar, please file a pull request with the correct SQL in these tests. It's okay if you don't submit a fix as well. (But we'd greatly appreciate it!) Doing so will help expedite the fix.

If you want to add support for a new database grammar, simply copy these two tests from an existing grammar, rename them, change the getBuilder method to return your new grammar, and fill out the SQL as it should be. That will guide your implementation to be 100% compatible with the other grammars in qb.

all-contributorsarrow-up-right
README
// MSSQLQueryBuilderSpec.cfc
function orWhere() {
    // If just a string is returned, we assume the bindings is an empty array ([])
    return {
        sql = "SELECT * FROM [users] WHERE [id] = ? OR [email] = ?",
        bindings = [ 1, "foo" ]
    };
}
// OracleSchemaBuilderSpec.cfc
function boolean() {
    // returns an array since schema builder can execute multiple statements.
    return [ "CREATE TABLE ""USERS"" (""ACTIVE"" NUMBER(1, 0) NOT NULL)" ];
}

Selects

hashtag
Specifying A Select Clause

Of course, you may not always want to select all columns from a database table. Using the from method, you can specify a custom from clause for the query:

Individual columns can contain fully-qualified names (i.e. "some_table.some_column"), fully-qualified names with table aliases (i.e. "alias.some_column"), and even set column aliases themselves (i.e. "some_column AS c"). Columns can be a single column, a list or columns (comma-separated), or an array of columns.

Aggregates

The query builder also provides a variety of aggregate methods such as count, max, min, and sum. You may call any of these methods after constructing your query:

Of course, you may combine these methods with other clauses:

var getResults = query.from('users')
    .count();
writeDump(getResults);
var getResults = query.from('users')
    .max('age');
writeDump(getResults);
var getResults = query.from('users')
    .min('age');
writeDump(getResults);
var getResults = query.from('users')
    .where('active', '=', 1)
    .max('age');
writeDump(getResults);

The distinct method allows you to force the query to return distinct results:

(Note that distinct applies to the entire query, not just certain fields.)

If you already have a query builder instance and you wish to add a column to its existing select clause, you may use the addSelect method:

var getResults = query.from('users')
    .get('name,email,age');
writeDump(getResults);
var getResults = query.from('users')
    .get('name as myAccountName,users.email,age');
writeDump(getResults);
var getResults = query.from('users as myTableAlias')
    .get( columns = ['name as myAccountName' ,'myTableAlias.email' ,'age'], options= { datasource='myOtherDatasource'} );
writeDump(getResults);
var getResults = query.from('users')
    .select('email')
    .distinct();
writeDump(getResults);
var getResults = query.from('users')
    .where('age','>=','18');
getResults = getResults.addSelect('name,email,age').get();
writeDump(getResults);

Inserts

The query builder also provides an insert method for inserting records into the database table. The insert method accepts an array of column names and values:

//qb
var addRecords = query.from( "users" )
        .insert( values = { "name" = "Robert", "email" = "[email protected]", "age" = 55 } );
writeDump(addRecords);

//sql
INSERT INTO `users` (`age`, `email`, `name`) VALUES (55, `[email protected]`, `Robert`)

You may even insert several records into the table with a single call to insert by passing an array of structs. Each struct represents a row to be inserted into the table:

You can also insert records by strong typing them just like using cfqueryParam. Just adhere to the same syntax: { value : "", cfsqltype : "" } (https://cfdocs.org/cfqueryparamarrow-up-right)

hashtag
Returning

Certain grammars have the ability to return values from an insert statement. That can be useful if you use your built-in database functions to generate primary keys that you want to retrieve.

If you attempt to use returning on grammars that do not support it, you will recieve a UnsupportedOperation exception.

Deletes

The query builder may also be used to delete records from the table via the delete method. You may constrain delete statements by adding where clauses before calling the delete method:

This utilizes the where clause on a column other than the ID:

New Query

A query builder is a stateful, transient object. That means that if you want to execute two different queries, you need two separate instances of QueryBuilder.

An easy way to get a new query builder is to use the newQuery method available on the builder.

The newQuery method will keep the current grammar, return format, and utils attached to the called query builder.

//qb
var addRecords = query.from( "users" )
.insert( values = [
        { "name" = "Robert", "email" = "[email protected]", "age" = 55 },
        { "name" = "Jessica", "email" = "[email protected]", "age" = 31 },
        { "name" = "Ross", "email" = "[email protected]", "age" = 9 }
    ] );
writeDump(addRecords);

//sql
INSERT INTO `users` (`age`, `email`, `name`)
VALUES (55, `[email protected]`, `Robert`),
        (31, `[email protected]`, `Jessica`),
        (9, `[email protected]`, `Ross`)
//qb
var addRecords = query
        .from( "users" )
        .insert( values = { 
                "name" = "Robert", 
                "email" = "[email protected]", 
                "age" = { value : 55, cfsqltype : "integer" },
                "createdDate" = { value : now(), cfsqltype : "timestamp" }
        } );
writeDump(addRecords);
// qb
var addRecords = query.from( "users" )
    .returning( "id" )
    .insert( { "name" = "Robert", "email" = "[email protected]", "age" = 55 } );
writeDump(addRecords);

// Postgres
INSERT INTO "users" ("age", "email", "name")
VALUES (55, "[email protected]", "Robert")
RETURNING "id"

// MSSQL
INSERT INTO [users] ([age], [email], [name])
OUTPUT INSERTED.[id]
VALUES (55, "[email protected]", "Robert")
//qb
var deleteRecords = query.from( "users" )
    .whereID( 10 )
    .delete();
writeDump(deleteRecords);

//sql
DELETE FROM `users` WHERE `ID` = 10;
//qb
var deleteRecords = query.from( "users" )
    .where( 'age', '>', 50 )
    .delete();
writeDump(deleteRecords);

//sql
DELETE FROM `users` WHERE `age` > 50
// This will cause you pain and grief...

var user = query.from( "users" )
  .where( "username", rc.username )
  .first();

var posts = query.from( "posts" ).get();
// This will error because `username` is not a column in `posts`.
// This will cause you pain and grief...

var user = query.from( "users" )
  .where( "username", rc.username )
  .first();

var posts = query.newQuery().from( "posts" ).get();
// This will work as we expect it to.

Updates

Of course, in addition to inserting records into the database, the query builder can also update existing records using the update method. The update method, like the insert method, accepts an array of column and value pairs containing the columns to be updated. You may constrain the update query using where clauses:

//qb
var addRecords = query.from( "users" )
    .whereID( 10 )
    .update(  { "name" = "Roberto", "email" = "[email protected]", "age" = 55 });
writeDump(addRecords);

//sql
UPDATE `users` SET `age` = 55, `email` = `[email protected]`, `name` = `Roberto` WHERE `ID` = 10

You can also use Expressions inside an update statement:

query.from( "posts" )
    .whereID( 10 )
    .update( { "likes" = query.raw( "likes + 1" ) } );
    
// SQL:      UPDATE `posts` SET `likes` = likes + 1 WHERE `ID` = ?
// Bindings: [ 10 ]

hashtag
Updating Null values

Null values can be inserted by using queryparam syntax:

if you are using Lucee with full null support the following (easier) syntax is also allowed:

query.from("user")
		.whereId( 10 )
		.update( {
			manager_FK = { value = "", null=true },
		} )
query.from("user")
		.whereId( 10 )
		.update( {
			manager_FK = { value = null },
		} )

From

Queries come in many varietiesβ€”from the basic to extremely complex. In order to provide you maximum flexibility there are several ways to define the source table for you query.

hashtag
Using the from() method

The most common method for defining the source table is using the from() method. For the majority of queries, the from() method is all you need. It's syntax is very easy:

This would return all columns from the users table.

NOTE: Alternatively, you can use the table() method as an alias to from().

hashtag
Declaring a table alias

Optionally you can specify an alias for the table by using the syntax:

This would parse the string users as u and convert it into the correct syntax for current grammar.

Alternatively, you can use the ANSI SQL shorthand and leave out the as keyword:

hashtag
Defining the from clause using raw SQL

Sometimes you need more control over your from clause in order to add grammar specific instructions, such as adding SQL Server table hints to your queries.

If you need complete control over your from clause you can use the fromRaw().

For example, to provide a table hint for a SQL Server query you could use:

Since the fromRaw() takes your string verbatim, it's important that you make sure your SQL declaration is escaped properly. Failure to properly escape your table names may result in SQL errors.

NOTE: Using the fromRaw() will most likely tie your code to a specific database, so think carefully before using the fromRaw() method if you want your project to be database agnostic.

hashtag
Adding bindings to your raw from clause

Many database engines allow you to define User Defined Functions. For example, SQL Server allows you to define UDFs that will return a table. In these type of cases, it may be necessary to bind parameters to your from clause.

You can bind parameters to the fromRaw() method by passing a secondary argument that is an array of the parameters to bind:

hashtag
Derived tables

Complex queries often contain derived tables. Derived tables are essentially a temporal table defined as a subquery in the from statement.

You can build queries that comprise of derived tables by using the fromSub() method, which requires two arguments:

  • The alias to use for the derived table (which is how you reference your query)

  • Either a QueryBuilder instances or closure defining the subquery

hashtag
Defining a derived table using a closure

The simplest way to create a derived table is by using a closure to define the subquery:

hashtag
Defining a derived table using a QueryBuilder instance

Alternatively you can supply a QueryBuilder instance to the fromSub() method:

Clone

At times you may need to duplicate a query. Perhaps you need the count of all the records before paginating it. Using clone you have a performant way to duplicate a query

var q1 = query.from( "users" ).where( "firstName", "like", "Jo%" );
var q2 = q1.clone();
q2.getFrom(); // "users"

//qb
var getResults = query.from('users').get();

//sql
SELECT * FROM `users`
//qb
var getResults = query.from('users as u').get();

//sql
SELECT * FROM `users` AS `u`
//qb
var getResults = query.from('users u').get();

//sql
SELECT * FROM `users` AS `u`
//qb
var getResults = query.fromRaw('[users] u (nolock)').get();

//sql
SELECT * FROM [users] u (nolock)
//qb
var getResults = query
    .fromRaw('dbo.generateDateTable(?, ?, ?) as dt', ['2017-01-01', '2017-12-31', 'm'])
    .get()
;

//sql
SELECT * FROM dbo.generateDateTable('2017-01-01', '2017-12-31', 'm') as dt
//qb
var getResults = query
    .select('firstName', 'lastName')
    .fromSub('u', function (q){
        q
            .select('lName as lastName', 'fName as firstName')
            .from('users')
            .where('age', '>=', 21)
        ;
    })
    .orderBy('lastName')
    .get()
;

//sql
SELECT `firstName`, `lastName` FROM (SELECT `lName` as `lastName`, `fName` as `firstName` FROM `users` WHERE `age` >= 21) AS `u` ORDER BY `lastName`
//qb
var derivedQA = query
    .select('lName as lastName', 'fName as firstName')
    .from('users')
    .where('age', '>=', 21)
;

var getResults = query
    .select('firstName', 'lastName')
    .fromSub('u', derivedQA)
    .orderBy('lastName')
    .get()
;

//sql
SELECT `firstName`, `lastName` FROM (SELECT `lName` as `lastName`, `fName` as `firstName` FROM `users` WHERE `age` >= 21) AS `u` ORDER BY `lastName`

Ordering, Grouping & Limit

hashtag
orderBy

The orderBy method allows you to sort the result of the query by a given column. The first argument to the orderBy method should be the column you wish to sort by, while the second argument controls the direction of the sort and may be either asc or desc:

circle-info

If you want to order by multiple columns, you can call orderBy multiple times.

hashtag
groupBy / having

The groupBy and having methods may be used to group the query results. The having method's signature is similar to that of the where method:

hashtag
take / limit

To limit the number of results returned from the query, you may use the take method:

Alternatively, you may use the limit method:

hashtag
offset

To offset the number of results returned from the query, use the offset method:

hashtag
forPage

Combine limit and offset in one method. Pass the current page number and the number of results per page (limit) and we'll calculate the rest.

Return Format

You can influence the return format of the result in two ways.

By default, qb returns an array of structs as the result of your query. This is the same as specifiying array as your returnFormat:

moduleSettings = {
    qb = {
        returnFormat = "array"
    }
};

You can get the original query object that CFML generates by setting the returnFormat to query:

moduleSettings = {
    qb = {
        returnFormat = "query"
    }
};

If you want complete control over your return result, you can provide a closure as a returnFormat. The results of the closure will be returned as the results of the builder.

Unions

The query builder also lets you create union statements on your queries. When merging multiple queries together using a union statement, there are two methods you can use merge the queries together:

  • union() β€” This method builds a SQL statement using the ANSI SQL union clause which combines two SQL queries into a single resultset containing all the matching rows. The two queries must have the same defined columns and compatible data types or the SQL engine will generate an error. The union clause only returns unique rows.

  • unionAll() β€” This builds a SQL statement using the union all clause. This is the same as union but includes duplicate rows.

The union methods take either a Query Builder instance or a closure, which you use to define a new QueryBuilder instance.

Union statements are added in the order in which the union methods are invoked, but the union statements can be in any order in your API call stack. This means you can safely declare your union method calls before the select, from and orderBy calls on the source Query Builder instance.

IMPORTANT: The QueryBuilder instances passed to a union statement cannot contain a defined order. Any use of the orderBy() method on the unioned QueryBuilder instances will result in an exception. To order the results, add an orderBy() call to the parent source Query Builder instance.

hashtag
Simple union using a callback

The easiest way to combine union the results of multiple queries is by using a callback to the union methods:

hashtag
Using a Query Builder instance

Alternatively, you can use another Query Builder instance and pass it to the union methods:

hashtag
union all

If you want to make sure that all duplicate rows are returned, use the unionAll() method instead of union():

hashtag
Ordering union queries

To order a union query, only the parent query object can contain an orderBy() directive. If any of the Query Builder instances passed to a union method contain an orderBy directive an exception will be thrown when you attempt to either execute the query or generate the SQL.

The follow shows how to order the results:

NOTE: The orderBy() call does have to be after the calls to the union methods.

hashtag
Multiple union statements

Your query can contain multiple union methods:

//qb
var getResults = query.from('users')
    .where('age','>=','18')
    .orderBy('modifiedDate','desc')
    .get();
writeDump(getResults);

//sql
SELECT * FROM `users` WHERE `age` >= 18 ORDER BY `modifiedDate` DESC
moduleSettings = {
    qb = {
        returnFormat = function( q ) {
            return application.wirebox.getInstance(
                name = "Collection",
                initArguments = { collection = q }
            );
        }
    }
};
//qb
var getResults = query.from('users')
    .groupBy('FK_departmentID')
    .having('age','>','21')
    .orderBy('age','desc')
    .get();
writeDump(getResults);

//sql
SELECT * FROM `users` GROUP BY `FK_departmentID` HAVING `age` > 21 ORDER BY `age` DESC
//qb
var getResults = query.from('users')
    .where('age','>=','18')
    .orderBy('modifiedDate','desc')
    .take(5)
    .get();
writeDump(getResults);

//sql
SELECT * FROM `users` WHERE `age` >= ? ORDER BY `modifiedDate` DESC LIMIT 5
//qb
var getResults = query.from('users')
    .where('age','>=','18')
    .orderBy('modifiedDate','desc')
    .limit(5)
    .get();
writeDump(getResults);

//sql
SELECT * FROM `users` WHERE `age` >= ? ORDER BY `modifiedDate` DESC LIMIT 5
// This will return rows 26 through 50
query.from( "users" )
    .offset( 25 )
    .limit( 25 )
    .get();
// This will return records 51 to 75
query.from( "users" )
    .forPage( 3, 25 )
    .get();
//qb
var getResults = query
        .select('title')
        .from('blogs')
        .whereIn('id', [1, 2, 3])
        .union(function (q){
            q
                .select('title')
                .from('blogs-archive')
                .whereIn('id', [1, 2, 3])
            ;
        })
    .get();
writeDump(getResults);

//sql
SELECT `title` FROM `blogs` WHERE `id` IN (1, 2, 3) UNION SELECT `title` FROM `blogs-archive` WHERE `id` IN (1, 2, 3)
var unionQB = query
    .select('title')
    .from('blogs-archive')
    .whereIn('id', [1, 2, 3])
;

//qb
var getResults = query
        .select('title')
        .from('blogs')
        .whereIn('id', [1, 2, 3])
        .union(unionQB)
    .get();
writeDump(getResults);

//sql
SELECT `title` FROM `blogs` WHERE `id` IN (1, 2, 3) UNION SELECT `title` FROM `blogs-archive` WHERE `id` IN (1, 2, 3)
//qb
var getResults = query
        .select('title')
        .from('blogs')
        .whereIn('id', [1, 2, 3])
        .unionAll(function (q){
            q
                .select('title')
                .from('blogs-archive')
                .whereIn('id', [1, 2, 3])
            ;
        })
    .get();
writeDump(getResults);

//sql
SELECT `title` FROM `blogs` WHERE `id` IN (1, 2, 3) UNION ALL SELECT `title` FROM `blogs-archive` WHERE `id` IN (1, 2, 3)
//qb
var getResults = query
        .select('title')
        .from('blogs')
        .whereIn('id', [1, 2, 3])
        .union(function (q){
            q
                .select('title')
                .from('blogs-archive')
                .whereIn('id', [1, 2, 3])
            ;
        })
        .orderBy("title", "desc")
    .get();
writeDump(getResults);

//sql
SELECT `title` FROM `blogs` WHERE `id` IN (1, 2, 3) UNION SELECT `title` FROM `blogs-archive` WHERE `id` IN (1, 2, 3) ORDER BY `title` DESC
//qb
var getResults = query
        .select('title')
        .from('blogs')
        .whereIn('id', [1, 2, 3])
        // order can be *before* union statements
        .orderBy("title", "desc")
        .unionAll(function (q){
            q
                .select('title')
                .from('blogs-archive-1990-decade')
                .whereIn('id', [1, 2, 3])
            ;
        })
        .unionAll(function (q){
            q
                .select('title')
                .from('blogs-archive-2000-decade')
                .whereIn('id', [1, 2, 3])
            ;
        })
    .get();
writeDump(getResults);

//sql
SELECT `title` FROM `blogs` WHERE `id` IN (1, 2, 3) UNION ALL SELECT `title` FROM `blogs-archive-1990-decade` WHERE `id` IN (1, 2, 3) UNION ALL SELECT `title` FROM `blogs-archive-2000-decade` WHERE `id` IN (1, 2, 3) ORDER BY `title` DESC

Introduction

All Contributors
Master Branch Build Status
Development Branch Build Status

hashtag
Introduction

qb is a fluent query builder for CFML. It is heavily inspired by Eloquentarrow-up-right from Laravelarrow-up-right.

Using qb, you can:

  • Quickly scaffold simple queries

  • Make complex, out-of-order queries possible

  • Abstract away differences between database engines

hashtag
Requirements

  • Adobe ColdFusion 11+

  • Lucee 4.5+

qb supports four major database grammars:

  • MSSQL (MSSQLGrammar)

  • MySQL (MySQLGrammar)

  • Oracle (OracleGrammar

hashtag
Installation

Installation is easy through and . Simply type box install qb to get started.

hashtag
Code Samples

Compare these two examples:

The differences become even more stark when we introduce more complexity:

With qb you can easily handle setting order by statements before the columns you want or join statements after a where clause:

qb enables you to explore new ways of organizing your code by letting you pass around a query builder object that will compile down to the right SQL without you having to keep track of the order, whitespace, or other SQL gotchas!

Here's a gist with an example of the powerful models you can create with this!

hashtag
Usage

To start a new query, instantiate a new Builder: wirebox.getInstance('QueryBuilder@qb').

By default, qb uses a generic Grammar. You can specify your specific grammar in ColdBox by setting the defaultGrammar in your moduleSettings.

If you are not using WireBox, just make sure to wire up the Builder object with the correct grammar:

hashtag
Return Format

You can influence the return format of the result in two ways.

By default, qb returns an array of structs as the result of your query. You can turn this behavior off by setting builder.setReturningArrays( false ) for one-offs or setting returningArrays = false in your ColdBox config.

If you want complete control over your return result, you can provide a closure as a returnFormat. The results of the closure will be returned as the results of the builder.

hashtag
Interception Points

Two interception points are available from QB: preQBExecute and postQBExecute. These fire before and after the queryExecute call, respectively. The following information is available in the interceptData struct:

hashtag
Contributors

Thanks goes to these wonderful people ():

This project follows the specification. Contributions of any kind welcome!

)
  • Postgres (PostgresGrammar)

  • Name

    Type

    Description

    sql

    String

    The sql string to execute

    bindings

    Struct

    The struct of bindings (keys and values) for the query

    options

    Struct

    Any options to pass along to queryExecute

    CommandBoxarrow-up-right
    ForgeBoxarrow-up-right
    https://gist.github.com/elpete/80d641b98025f16059f6476561d88202arrow-up-right
    emoji keyarrow-up-right
    all-contributorsarrow-up-right
    // Plain old CFML
    q = queryExecute("SELECT * FROM users");
    
    // qb
    query = wirebox.getInstance('QueryBuilder@qb');
    q = query.from('users').get();
    // Plain old CFML
    q = queryExecute(
        "SELECT * FROM posts WHERE published_at IS NOT NULL AND author_id IN ?",
        [ { value = '5,10,27', cfsqltype = 'CF_SQL_NUMERIC', list = true } ]
    );
    
    // qb
    query = wirebox.getInstance('QueryBuilder@qb');
    q = query.from('posts')
             .whereNotNull('published_at')
             .whereIn('author_id', [5, 10, 27])
             .get();
    query = wirebox.getInstance('QueryBuilder@qb');
    q = query.from('posts')
             .orderBy('published_at')
             .select('post_id', 'author_id', 'title', 'body')
             .whereLike('author', 'Ja%')
             .join('authors', 'authors.id', '=', 'posts.author_id')
             .get();
    
    // Becomes
    
    q = queryExecute(
        "SELECT post_id, author_id, title, body FROM posts INNER JOIN authors ON authors.id = posts.author_id WHERE author LIKE ? ORDER BY published_at",
        [ { value = 'Ja%', cfsqltype = 'CF_SQL_VARCHAR', list = false, null = false } ]
    );
    moduleSettings = {
        qb = {
            defaultGrammar = "MySQLGrammar"
        }
    };
    var grammar = new qb.models.Query.Grammars.MySQLGrammar();
    var builder = new qb.models.Query.Builder( grammar );
    moduleSettings = {
        qb = {
            returningArrays = false
        }
    };
    moduleSettings = {
        qb = {
            returnFormat = function( q ) {
                return application.wirebox.getInstance(
                    name = "Collection",
                    initArguments = { collection = q }
                );
            }
        }
    };
    πŸ“
    πŸ“–arrow-up-right
    πŸ’¬
    πŸ“
    πŸ›arrow-up-right
    πŸ’»arrow-up-right
    🎨
    πŸ“–arrow-up-right
    πŸ’‘
    πŸ‘€
    πŸ“’
    ⚠️arrow-up-right
    πŸ›arrow-up-right
    πŸ’»arrow-up-right
    πŸ“–arrow-up-right
    πŸ›arrow-up-right
    πŸ’»arrow-up-right
    πŸ’¬
    πŸ’»arrow-up-right
    πŸ’»arrow-up-right

    Where Clauses

    Base

    AND

    OR

    where()

    andWhere()

    orWhere()

    whereBetween()

    andWhereBetween()

    orWhereBetween()

    whereColumn()

    andWhereColumn()

    orWhereColumn()

    hashtag
    Parameters

    By default, the correct sql type will be inferred from your parameters. If you pass a number, CF_SQL_NUMERIC will be used. If it is a date, CF_SQL_TIMESTAMP, and so forth. If you need more control, you can always pass a struct with the parameters you would pass to cfqueryparam.

    hashtag
    Simple Where Clauses

    You may use the where method on a query builder instance to add where clauses to the query. The most basic call to where requires three arguments. The first argument is the name of the column. The second argument is an operator, which can be any of the database's supported operators. Finally, the third argument is the value to evaluate against the column.

    For example, here is a query that verifies the value of the "age" column is greater than or equal to 18:

    For convenience, if you simply want to verify that a column is equal to a given value, you may pass the value directly as the second argument to the where method:

    Of course, you may use a variety of other operators when writing a where clause:

    hashtag
    Or Statements

    You may chain where constraints together as well as add or clauses to the query. The orWhere method accepts the same arguments as the where method:

    hashtag
    Additional Where Clauses

    whereBetween / whereNotBetween

    The whereBetween method verifies that a column's value is between two values:

    The whereNotBetween method verifies that a column's value lies outside of two values:

    whereIn / whereNotIn (sub-queries)

    The whereIn method verifies that a given column's value is contained within the provided array or QueryBuilder object:

    Array:

    QueryBuilder (fetch all users whose age is in the all_ages table with a value between 17 and 21):

    The whereNotIn method verifies that the given column's value is not contained in the provided array of QueryBuilder object:

    whereNull / whereNotNull

    The whereNull method verifies that the value of the given column is NULL:

    The whereNotNull method verifies that the column's value is not NULL:

    whereExists / whereNotExists

    The whereExists method:

    whereColumn

    The whereColumn method may be used to verify that two columns are equal:

    You may also pass a comparison operator to the method:

    WHERE (a = ? OR b = ?) AND c = ?

    Here is an example of how to strategically place parentheses with OR using closures.

    Column Constraints

    A TableIndex can be created directly from a or from a existing . The TableIndex includes methods for further configuring the index which is required when defining foreign keys.

    hashtag
    references

    Set the referencing column for a foreign key relationship. For example, id

    Installation & Usage

    hashtag
    Installation

    Installation is easy through and . Simply type box install qb to get started.

    whereExists()

    andWhereExists()

    orWhereExists()

    whereIn()

    andWhereIn()

    orWhereIn()

    whereNotBetween()

    andWhereNotBetween()

    orWhereNotBetween()

    whereNotExists()

    andWhereNotExists()

    orWhereNotExists()

    whereNotIn()

    andWhereNotIn()

    orWhereNotIn()

    whereNotNull()

    andWhereNotNull()

    orWhereNotNull()

    whereNull()

    andWhereNull()

    orWhereNull()

    whereRaw()

    andWhereRaw()

    orWhereRaw()

    for a
    country_id
    column.

    Argument

    Type

    Required

    Default

    Description

    columns

    any

    true

    A column or array of columns that represents the foreign key reference.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    onTable

    Sets the referencing table for a foreign key relationship. For example, countries for a country_id column.

    Argument

    Type

    Required

    Default

    Description

    table

    string

    true

    The referencing table name.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    onUpdate

    Set the strategy for updating foreign keys when the parent key is updated.

    Argument

    Type

    Required

    Default

    Description

    option

    string

    true

    The strategy to use. Available values are: RESTRICT, CASCADE, SET NULL, NO ACTION, SET DEFAULT

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    onDelete

    Set the strategy for updating foreign keys when the parent key is deleted.

    Argument

    Type

    Required

    Default

    Description

    option

    string

    true

    The strategy to use. Available values are: RESTRICT, CASCADE, SET NULL, NO ACTION, SET DEFAULT

    Example:

    SchemaBuilder

    SQL (MySQL)

    Blueprint
    Column
    hashtag
    Usage

    To start a new query, instantiate a new Builder: wirebox.getInstance('QueryBuilder@qb').

    By default, qb uses a generic Grammar. You can specify your specific grammar in ColdBox by setting the defaultGrammar in your moduleSettings.

    If you are not using WireBox, just make sure to wire up the Builder object with the correct grammar:

    hashtag
    Integrating With FW/1

    Note: These instructions assume a basic knowledge of FW/1, a working FW/1 application structure with qb installed in the /subsystems directory (manually or via CommandBox), and a database configured to run with your application.

    hashtag
    Wiring Up With DI/1

    Once the application structure is setup, now we need to wire up qb to a bean factory using DI/1.

    First we will add a mapping in Application.cfc.

    Next we need to tell DI/1 where qb's components are and how to reference them for later use in the application. We can do so by defining the configuration settings in the variables.framework.subsystems struct in Application.cfc. The example below makes use of a load listener to declare each component instance and pass in any constructor arguments.

    hashtag
    Usage In Your FW/1 Application

    Now that everything is configured, you can launch your application with CommandBox by entering start in the terminal or use whatever method you're accustomed to.

    To access qb from your application's code, you can call on it by using getBeanFactory().

    hashtag
    For further instructions on getting started with qb & FW/1, refer to this blog postarrow-up-right.

    CommandBoxarrow-up-right
    ForgeBoxarrow-up-right
    //qb
    var getResults = query.from('users')
        .where('age','>=', { value = 18, cfsqltype = "CF_SQL_INTEGER" })
        .get();
    writeDump(getResults);
    
    //sql
    SELECT * FROM `users` WHERE `age` >= 18
    //qb
    var getResults = query.from('users')
        .where('age','>=','18')
        .get();
    writeDump(getResults);
    
    //sql
    SELECT * FROM `users` WHERE `age` >= 18
    //qb
    var getResults = query.from('users')
        .where('age','18')
        .get();
    writeDump(getResults);
    
    //sql
    SELECT * FROM `users` WHERE `age` = 18
    //qb
    var getResults = query.from('users')
        .where('age','>=','18')
        .get();
    writeDump(getResults);
    
    //sql
    SELECT * FROM `users` WHERE `age` >= 18
    
    //qb
    var getResults = query.from('users')
        .where('age','<>','18')
        .get();
    writeDump(getResults);
    
    //sql
    SELECT * FROM `users` WHERE `age` <> 18
    
    
    //qb
    var getResults = query.from('users')
        .where('name','like','A%')
        .get();
    writeDump(getResults);
    
    //sql
    SELECT * FROM `users` WHERE `name` LIKE 'A%'
    //qb
    var getResults = query.from('users')
        .where('name','like','A%')
        .orWhere('age','>','30')
        .get();
    writeDump(getResults);
    
    //sql
    SELECT * FROM `users` WHERE `name` LIKE 'A%' OR `age` > 30
    //qb
    var getResults = query.from('users')
        .whereBetween('age','18','21')
        .get();
    writeDump(getResults);
    
    //sql
    SELECT * FROM `users` WHERE `age` BETWEEN 18 AND 21
    //qb
    var getResults = query.from('users')
        .whereNotBetween('age','18','21')
        .get();
    writeDump(getResults);
    
    //sql
    SELECT * FROM `users` WHERE `age` NOT BETWEEN 18 AND 21
    var getResults = query.from('users')
        .whereIn('age',[ 17, 18, 19, 20, 21 ])
        .get();
    writeDump(getResults);
    var getResults = query.from('users')
           .whereIn('age', function ( subQuery ) {
            return subQuery.select( "age" )
            .from( "all_ages" )
            .whereBetween("age","17","21");
        })
        .get();
    writeDump(getResults);
    var getResults = query.from('users')
        .whereNotIn('age',[ 17, 18, 19, 20, 21 ])
        .get();
    writeDump(getResults);
    //qb
    var getResults = query.from('users')
        .whereNull('modifiedDate')
        .get();
    writeDump(getResults);
    
    //sql
    SELECT * FROM `users` WHERE `modifiedDate` IS NULL
    //qb
    var getResults = query.from('users')
        .whereNotNull('modifiedDate')
        .get();
    writeDump(getResults);
    
    //sql
    SELECT * FROM `users` WHERE `modifiedDate` IS NOT NULL
    //qb
    var getResults = query.from('users')
        .whereExists( function( q ) {
            q.select( q.raw( 1 ) ).from( "departments" )
                .where( "departments.ID", "=", q.raw( '"users.FK_departmentID"' ) );
        })
        .get();
    writeDump(getResults);
    
    //sql
    SELECT * FROM `users` WHERE EXISTS (SELECT 1 FROM `departments` WHERE `departments`.`ID` = "users.FK_departmentID")
    //qb
    var getResults = query.from('users')
        .whereColumn('modifiedDate','createdDate')
        .get();
    writeDump(getResults);
    
    //sql
    SELECT * FROM `users` WHERE `modifiedDate` = `createdDate`
    //qb
    var getResults = query.from('users')
        .whereColumn('modifiedDate','<>','createdDate')
        .get();
    writeDump(getResults);
    
    //sql
    SELECT * FROM `users` WHERE `modifiedDate` <> `createdDate`
    //qb
    var getResults = query.from('users')
        .where( function( q ) {
            q.where( "a", 1 ).orWhere( "b", 2 );
        } )
        .where( "c", 3 );
    writeDump(getResults);
    
    // sql
    SELECT * FROM `users` WHERE (a = ? OR b = ?) AND c = ?
    schema.create( "users", function( table ) {
        table.unsignedInteger( "country_id" ).references( "id" ).onTable( "countries" );
    } );
    CREATE TABLE `users` (
        `country_id` INTEGER UNSIGNED NOT NULL,
        CONSTRAINT `fk_users_country_id` FOREIGN KEY (`country_id`) REFERENCES `countries` (`id`) ON UPDATE NO ACTION ON DELETE NO ACTION
    )
    schema.create( "users", function( table ) {
        table.unsignedInteger( "country_id" ).references( "id" ).onTable( "countries" );
    } );
    CREATE TABLE `users` (
        `country_id` INTEGER UNSIGNED NOT NULL,
        CONSTRAINT `fk_users_country_id` FOREIGN KEY (`country_id`) REFERENCES `countries` (`id`) ON UPDATE NO ACTION ON DELETE NO ACTION
    )
    schema.create( "users", function( table ) {
        table.unsignedInteger( "country_id" )
            .references( "id" )
            .onTable( "countries" )
            .onUpdate( "CASCADE" );
    } );
    CREATE TABLE `users` (
        `country_id` INTEGER UNSIGNED NOT NULL,
        CONSTRAINT `fk_users_country_id` FOREIGN KEY (`country_id`) REFERENCES `countries` (`id`) ON UPDATE CASCADE ON DELETE NO ACTION
    )
    schema.create( "users", function( table ) {
        table.unsignedInteger( "country_id" )
            .references( "id" )
            .onTable( "countries" )
            .onDelete( "SET NULL" );
    } );
    CREATE TABLE `users` (
        `country_id` INTEGER UNSIGNED NOT NULL,
        CONSTRAINT `fk_users_country_id` FOREIGN KEY (`country_id`) REFERENCES `countries` (`id`) ON UPDATE NO ACTION ON DELETE SET NULL
    )
    moduleSettings = {
        qb = {
            defaultGrammar = "MySQLGrammar"
        }
    };
    var grammar = new qb.models.Grammars.MySQLGrammar();
    var builder = new qb.models.Query.QueryBuilder( grammar );
    this.mappings = {
        "/qb" = expandPath("./subsystems/qb")
    };
    qb = {
      diLocations = "/qb/models",
      diConfig = {
        loadListener = function( di1 ) {
          di1.declare( "BaseGrammar" ).instanceOf( "qb.models.Query.Grammars.Grammar" ).done()
             .declare( "MySQLGrammar" ).instanceOf( "qb.models.Query.Grammars.MySQLGrammar" ).done()
             .declare( "QueryUtils" ).instanceOf( "qb.models.Query.QueryUtils" ).done()
             .declare( "QueryBuilder" ).instanceOf( "qb.models.Query.QueryBuilder" )
             .withOverrides({
                grammar = di1.getBean( "MySQLGrammar" ),
                utils = di1.getBean( "QueryUtils" ),
                returnFormat = "array"
             })
             .asTransient();
        }
      }
    }
    // Create an instance of qb
    builder = getBeanFactory( "qb" ).getBean( "QueryBuilder" );
    // Query the database
    posts = builder.from( "Posts" ).get();
    posts = builder.from( "Posts" ).where( "IsDraft", "=", 0 ).get();

    Migration Guide

    hashtag
    v5.0.0

    Version v5.0.0 brings support for SchemaBuilder inside qb. To avoid naming confusion, Builder was renamed to QueryBuilder. Any references in your code to

    Builder@qb
    need to be updated to
    QueryBuilder@qb
    .

    Common Table Expressions (i.e. CTEs)

    Common Table Expressions (CTEs) are powerful SQL concept that allow you to create re-usable temporal resultset, which can be referenced as a table within your SQL. CTEs are available in many common database engines and are available in latest versions of all of the support grammars.

    CTEs come in two basic types:

    • Non-recursive β€” These are statements that do not reference themselves, in simplified terms they are like a derived table that can be referenced by a user-defined name.

    • Recursive β€” Recursive CTEs reference themselves and are generally used for creating hierarchical dataβ€”such as creating a parent/child relationship within a table.

    While all of the grammars currently support CTEs, there is enough difference between the various databases implementations of CTEs that unless your CTEs are fairly basic, using CTEs within your project will most likely tie your project to a specific database, unless you account for the differences in your code.

    However, CTEs are can be extremely useful to solve certain use cases.

    To add CTEs to your queries, you have two methods available:

    • with() β€” Allows you to define a non-recursive CTE.

    • withRecursive() β€” Allows you to define a recursive CTE.

    NOTE: Some database engines require the recursive keyword is implemented anytime at least one of your CTEs is recursive, but some database engines (e.g. SQL Server and Oracle) do not require the keyword. For engines that do not require the recursive keyword the grammar will manage adding the keyword if necessary. If your query does use recursion, you should always use the withRecursive() method to avoid issues with other grammars.

    hashtag
    Simple CTE using a closure

    Building a CTE is as easy as using the with() method with a closure:

    hashtag
    Simple CTE using a QueryBuilder instance

    Alternatively, you can use a QueryBuilder instance instead of a closure:

    hashtag
    Multiple CTEs

    A single query can reference multiple CTEs:

    hashtag
    Recursive CTEs

    IMPORTANT β€” The way the SQL in a recursive CTEs are written, using them in your code is likely to lock in you in to a specific database engine, unless you structure your code to build the correct SQL based on the current grammar being used.

    Here is an example of building a recursive CTE using SQL Server which would return all parent/child rows and show their generation/level depth:

    // qb
    var getResults = query
        .with('UserCTE', function (q){
            q
                .select('fName as firstName', 'lName as lastName')
                .from('users')
                .where('disabled', 0)
            ;
        })
        .from('UserCTE')
        .get();
    writeDump(getResults);
    
    // sql
    WITH `UserCTE` AS (
        SELECT
            `fName` as `firstName`,
            `lName` as `lastName`
        FROM `users`
        WHERE `disabled` = 0
    ) SELECT * FROM `UserCTE`
    // qb
    var cte = query
        .select('fName as firstName', 'lName as lastName')
        .from('users')
        .where('disabled', 0)
    ;
    
    var getResults = query
        .with('UserCTE', cte)
        .from('UserCTE')
        .get();
    writeDump(getResults);
    
    // sql
    WITH `UserCTE` AS (
        SELECT
            `fName` as `firstName`,
            `lName` as `lastName`
        FROM `users`
        WHERE `disabled` = 0
    )
    SELECT * FROM `UserCTE`
    // qb
    var getResults = query
        .with('UserCTE', function (q){
            q
                .select('id', 'fName as firstName', 'lName as lastName')
                .from('users')
                .where('disabled', 0)
            ;
        })
        .with('BlogCTE', function (q){
            q
                .from('blogs')
                .where('disabled', 0)
            ;
        })
        .from('BlogCTE as b')
        .join('UserCTE as u', 'b.Creator', 'u.id')
        .get();
    writeDump(getResults);
    
    // sql
    WITH `UserCTE` AS (
        SELECT
            `id`,
            `fName` as `firstName`,
            `lName` as `lastName`
        FROM `users`
        WHERE `disabled` = 0
    ),
    `BlogCTE` AS (
        SELECT *
        FROM `blogs`
        WHERE `disabled` = 0
    )
    SELECT *
    FROM `BlogCTE` AS `b`
    INNER JOIN `UserCTE` AS `u`
    ON `b`.`Creator` = `u`.`id`
    // qb
    var getResults = query
        .withRecursive('Hierarchy', function (q){
            q
                // get the parent rows only
                .select('Id', 'ParentId', 'Name', q.raw('0 AS [Generation]'))
                .from('Sample')
                .whereNull('ParentId')
                // use recursion to join the child rows to their parents
                .unionAll(function (q){
                    q
                        .select('child.Id', 'child.ParentId', 'child.Name', q.raw('[parent].[Generation] + 1'))
                        .from("Sample as child)
                        .join("Hierarchy as parent", "child.ParentId", "parent.Id")
                    ;
                })
            ;
        }, ['Id', 'ParentId', 'Name', 'Generation'])
        .from('Hierarchy')
        .get();
    writeDump(getResults);
    
    // sql
    ;WITH [Hierarchy] ([Id], [ParentId], [Name], [Generation]) AS (SELECT [Id], [ParentId], [Name], 0 AS [Generation] FROM [Sample] WHERE [ParentId] IS NULL UNION ALL SELECT [child].[Id], [child].[ParentId], [child].[Name], [parent].[Generation] + 1 FROM [Sample] AS [child] INNER JOIN [Hierarchy] AS [parent] ON [child].[ParentId] = [parent].[Id]) SELECT * FROM [Hierarchy]

    Interception Points

    Two interception points are available from QB: preQBExecute and postQBExecute. These fire before and after the queryExecute call, respectively. The following information is available in the interceptData struct:

    Name

    Type

    Description

    sql

    Retrieving Results

    Usage## Retrieving Results

    hashtag
    Retrieving All Rows From A Table

    The get method returns an Array of Structs by default. Both columns

    String

    The sql string to execute

    bindings

    Struct

    The struct of bindings (keys and values) for the query

    options

    Struct

    Any options to pass along to queryExecute

    and
    options
    are optional.

    hashtag
    Retrieving A Single Row / Column From A Table

    If you just need to retrieve a single row from the database table, you may use the first method. This method will return a single record (a Struct by default). If no row is found an empty Struct will be returned by default.

    If you don't even need an entire row, you may extract a single value from each record using the values method. This method will return the value of the column directly:

    If you only need a single column for the first record returned, use the value function:

    hashtag
    Options parameter: Retrieving results from alternative datasources

    In application.cfc you can specify your default datasource which will be used by qb. If you want to retrieve data from other datasources you can specify this in all retrieval functions by using the extra options parameter such as:

    If you also want to use a non-default SQL Grammar you have to specify this when creating your querybuilder, e.g

    public any function get( any columns, struct options = {} )
    // qb
    var getAllResults = query.from( "users" ).get();
    writeDump( getAllResults );
    
    // sql
    // select * from users
    
    // more qb examples
    var getAllResults = query.from( "users" )
        .get(
            columns = [ "Id", "Name" ],
            options = { datasource = "myAdditionalDatasource" }
        );
    //qb
    var getResults = query.from('users')
        .first();
    writeDump(getResults);
    
    //sql
    select * from users limit(1)
    public any function first( struct options = {} )
    query.from( "users" ).values( "email" );
    // [ "[email protected]", "[email protected]", "[email protected]", ... ]
    public any function values( required string column, struct options = {} );
    query.from( "users" ).value( "email" );
    // "[email protected]"
    public any function value( required string column, struct options = {} );
    //qb
    var getAllResults = query.from('users')
        .get( options={ datasource= 'MyOtherDatasourceName'} );
    writeDump(getAllResults);
    var query =  wirebox.getInstance('QueryBuilder@qb')
        .setGrammar( wirebox.getInstance('MSSQLGrammar@qb') );

    Conditionals

    hashtag
    Basic if and else

    If you store the builder object in a variable, you can use if and else statements like you would expect.

    This works, but breaks chainability. A better way is to use the when helper method.

    hashtag
    when

    Name

    Type

    Required

    Default

    Description

    condition

    boolean

    true

    The condition to switch on.

    onTrue

    Closure

    true

    We can rewrite the above query like so:

    Nice. We keep chainability this way and reduce the number of temporary variables we need.

    Overview

    QB ships with a schema builder to help you build your database objects. This provides a few benefits:

    • The syntax is expressive and fluent, making it easy to understand what is being executed

    • The syntax is database-agnostic. Specific quirks are isolated in a Grammar file, making it easy to migrate between engines.

    You start with a SchemaBuilder object. The SchemaBuilder takes the same Grammar that a QueryBuilder takes.

    Note: the SchemaBuilder is a transient, and a new one should be created for each operation.

    The SchemaBuilder has four main methods to start your database object creation:

    hashtag

    Create a new table in the database.

    The majority of the work comes from calling methods on the Blueprint object. A Blueprint defines the and for your tables.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag

    Alter an existing table in the database.

    In addition to using the and off of the passed-in Blueprint object, the Blueprint contains helpers such as addConstraint, removeConstraint, addColumn, renameColumn, and dropColumn to assist in altering existing tables.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag

    Drop a table from the database.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    Additionally, there are a few utility methods defined on SchemaBuilder as well:

    hashtag
    rename

    Rename a table from an old name to a new name

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    hasTable

    Check if a table exists in the database.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    hasColumn

    Check if a column exists in a table in the database.

    Example:

    SchemaBuilder

    SQL (MySQL)

    var builder = builder.from( "posts" );
    if ( rc.recent ) {
        builder.orderBy( "published_date", "desc" );
    }
    var results = builder.get();
    var results = builder.from( "posts" )
        .when( rc.recent, function( q ) {
            q.orderBy( "published_date", "desc" );
        } )
        .get();

    The callback to execute if the condition is true. It is passed the builder object as the only parameter.

    onFalse

    Closure

    false

    function( q ) { return q; }

    The callback to execute if the conditions is false. It is passed the builder object as the only parameter.

    options

    struct

    false

    {}

    Options to pass to queryExecute.

    execute

    boolean

    false

    true

    Run the query immediately after building it.

    options

    struct

    false

    {}

    Options to pass to queryExecute.

    execute

    boolean

    false

    true

    Run the query immediately after building it.

    execute

    boolean

    false

    true

    Run the query immediately after building it.

    options

    struct

    false

    {}

    Options to pass to queryExecute.

    execute

    boolean

    false

    true

    Run the query immediately after building it.

    execute

    boolean

    false

    true

    Run the query immediately after building it.

    options

    struct

    false

    {}

    Options to pass to queryExecute.

    execute

    boolean

    false

    true

    Run the query immediately after building it.

    Argument

    Type

    Required

    Default

    Description

    table

    string

    true

    The name of the table to create.

    callback

    function

    true

    Argument

    Type

    Required

    Default

    Description

    table

    string

    true

    The name of the table to alter.

    callback

    function

    true

    Argument

    Type

    Required

    Default

    Description

    table

    string

    true

    The name of the table to drop.

    options

    struct

    false

    {}

    Argument

    Type

    Required

    Default

    Description

    from

    string

    true

    The old table name.

    to

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name of the table to check.

    options

    struct

    false

    {}

    Argument

    Type

    Required

    Default

    Description

    table

    string

    true

    The name of the table to check for the column in.

    column

    string

    true

    createarrow-up-right
    columnsarrow-up-right
    indexesarrow-up-right
    alterarrow-up-right
    columnsarrow-up-right
    indexesarrow-up-right
    drop and dropIfExistsarrow-up-right

    A callback function used to define the table body. It is passed a Blueprint as the only argument.

    A callback function used to define the changes to the table. It is passed a Blueprint as the only argument.

    Options to pass to queryExecute.

    The new table name.

    Options to pass to queryExecute.

    The column to check for in the table.

    // manually
    var schema = new qb.models.schema.SchemaBuilder(
        new qb.models.grammars.MySQLGrammar()
    );
    
    // WireBox
    var schema = wirebox.getInstance( "SchemaBuilder@qb" );
    schema.create( "users", function( table ) {
        table.increments( "id" );
        table.string( "email" );
        table.string( "password" );
        table.timestamp( "created_date" ).nullable();
        table.timestamp( "modified_date" ).nullable();
    } );
    CREATE TABLE `users` (
        `id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
        `email` VARCHAR(255) NOT NULL,
        `password` VARCHAR(255) NOT NULL,
        `created_date` TIMESTAMP,
        `modified_date` TIMESTAMP,
        CONSTRAINT `pk_users_id` PRIMARY KEY (`id`)
    )
    schema.alter( "users", function( table ) {
        table.addConstraint( table.unique( "username" ) );
        table.dropColumn( "last_logged_in" );
    } );
    ALTER TABLE `users` ADD CONSTRAINT `unq_users_username` UNIQUE (`username`);
    ALTER TABLE `users` DROP COLUMN `last_logged_in`;
    schema.drop( "user_logins" );
    DROP TABLE `user_logins`
    schema.rename( "posts", "blog_posts" );
    RENAME TABLE `posts` TO `blog_posts`
    schema.hasTable( "users" );
    SELECT 1
    FROM `information_schema`.`tables`
    WHERE `table_name` = 'users'
    schema.hasColumn( "users", "last_logged_in" );
    SELECT 1
    FROM `information_schema`.`columns`
    WHERE `table_name` = 'users'
        AND `column_name` = 'last_logged_in'

    Alter

    The alter method loads up an existing table in order to make modifications. These modifications may include adding, renaming, or dropping columns and constraints.

    To begin altering an existing table, call the alter method off of the SchemaBuilder. This method takes a callback as the second parameter that is passed a Blueprint object, much like the create method.

    Argument

    Type

    Required

    Calling multiple methods inside a single alter callback creates multiple SQL statements to be executed. qb takes care of this execution for you by default.

    The following methods off of Blueprint let you modify the table inside the callback:

    hashtag
    addColumn

    Add a new column to an existing table. Takes a Column instance as the only argument.

    Any instance of Column is valid like those returned by the (integer, string, etc.) as well as the (unsigned, nullable, etc.).

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    dropColumn

    Drop a column on an existing table.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    modifyColumn

    Modify an existing column on a table.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    renameColumn

    Rename a column on a table. A full Column instance is required as the second argument for Grammars that need to redeclare the column definition when renaming.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    addConstraint

    Add an index or key to an existing table. Any TableIndex instance is valid, like those created by the (unique, index, primaryKey, etc.).

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    dropConstraint

    Drop an existing table constraint.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    renameConstraint

    Rename an existing table constraint.

    Example:

    SchemaBuilder

    SQL (MySQL)

    Column Modifiers

    When creating a column from the Blueprint object, a Column object is returned. This column gives you access to a few modifier commands to further configure the column.

    Methods

    hashtag
    comment

    Attach a comment to the column.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    default

    Sets a default value for the column.

    Note: The value is not escaped, allowing you to specify functions like NOW() or literals like 1. To specify a literal string, wrap the value in quotes.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    nullable

    Sets the column to allow null values.

    All columns are created as NOT NULL by default. As such, there is no notNull method.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    primaryKey

    Adds the column as a primary key for the table.

    The primaryKey method returns a Additional methods can be chained off of it.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    references

    Creates a foreign key constraint for the column.

    IMPORTANT: Additional configuration of the foreign constraint is done by calling methods on the returned

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    unsigned

    Sets the column as unsigned.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    unique

    Sets the column to have the UNIQUE constraint.

    Example:

    SchemaBuilder

    SQL (MySQL)

    Default

    Description

    table

    string

    true

    The name of the table to alter.

    callback

    function

    true

    A callback function used to define the alterations to the table. It is passed a Blueprint as the only argument.

    options

    struct

    false

    {}

    Options to pass to queryExecute.

    execute

    boolean

    false

    true

    Run the query immediately after building it.

    Argument

    Type

    Required

    Default

    Description

    column

    Column

    true

    A column object to add to the table.

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name of the column to drop.

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name of the column to modify.

    column

    Column

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The current name of a column.

    column

    Column

    true

    Argument

    Type

    Required

    Default

    Description

    constraint

    TableIndex

    true

    The TableIndex instance to add to the table.

    Argument

    Type

    Required

    Default

    Description

    name

    string OR TableIndex

    true

    The name of the constraint to drop. You can alternatively pass a TableIndex instance to use the dynamic name generated.

    Argument

    Type

    Required

    Default

    Description

    oldName

    string OR TableIndex

    true

    The old or current name of the constraint to rename. You can alternatively pass a TableIndex instance to use the dynamic name generated.

    newName

    string OR TableIndex

    true

    column methods
    column modifier methods
    index methods

    A column object to replace the named column.

    A column object with the new column name and definition.

    The new name of the constraint. You can alternatively pass a TableIndex instance to use the dynamic name generated.

    primaryKey

    references

    unsigned

    unique

    Argument

    Type

    Required

    Default

    Description

    comment

    string

    true

    The comment text.

    Argument

    Type

    Required

    Default

    Description

    value

    string

    true

    The default value.

    Argument

    Type

    Required

    Default

    Description

    No arguments

    Argument

    Type

    Required

    Default

    Description

    indexName

    string

    false

    A derived name built from the table name and column name.

    The name to use for the primary key constraint.

    Argument

    Type

    Required

    Default

    Description

    value

    string

    true

    The default value.

    Argument

    Type

    Required

    Default

    Description

    No arguments

    Argument

    Type

    Required

    Default

    Description

    No arguments

    TableIndex instance.arrow-up-right
    TableIndex instance.arrow-up-right
    comment
    default
    nullable
    schema.alter( "users", function( table ) {
        table.addColumn( table.boolean( "is_active" ) );
    } );
    ALTER TABLE `users` ADD `is_active` TINYINT(1) NOT NULL
    schema.alter( "users", function( table ) {
        table.dropColumn( "username" );
    } );
    ALTER TABLE `users` DROP COLUMN `username`
    schema.alter( "users", function( table ) {
        table.modifyColumn( "name", table.string( "username" ) );
    } );
    ALTER TABLE `users` CHANGE `name` `username` VARCHAR(255) NOT NULL
    schema.alter( "users", function( table ) {
        table.renameColumn( "name", table.string( "username" ) );
    } );
    ALTER TABLE `users` CHANGE `name` `username` VARCHAR(255) NOT NULL
    schema.alter( "users", function( table ) {
        table.addConstraint( table.unique( "username" ) );
    } );
    ALTER TABLE `users` ADD CONSTRAINT `unq_users_username` UNIQUE (`username`)
    schema.alter( "users", function( table ) {
        table.dropConstraint( "unq_users_full_name" );
        table.dropConstraint( table.unique( "username" ) );
    } );
    ALTER TABLE `users` DROP INDEX `unq_users_full_name`
    ALTER TABLE `users` DROP INDEX `unq_users_username`
    schema.alter( "users", function( table ) {
        table.renameConstraint( "unq_users_first_name_last_name", "unq_users_full_name" );
    } );
    ALTER TABLE `users` RENAME INDEX `unq_users_first_name_last_name` TO `unq_users_full_name`
    schema.create( "users", function( table ) {
        table.integer( "age" ).comment( "Do not lie about your age" );
    } );
    CREATE TABLE `users` (
        `age` INTEGER NOT NULL COMMENT `Do not lie about your age`
    )
    schema.create( "users", function( table ) {
        table.boolean( "is_active" ).default( 1 );
        table.timestamp( "created_date" ).default( "NOW()" );
        table.string( "country" ).default( "'USA'" );
    } );
    CREATE TABLE `users` (
        `is_active` TINYINT(1) DEFAULT 1,
        `created_date` TIMESTAMP DEFAULT NOW(),
        `country` VARCHAR(255) DEFAULT 'USA'
    )
    schema.create( "users", function( table ) {
        table.timestamp( "last_logged_in" ).nullable()
    } );
    CREATE TABLE `users` (
        `last_logged_in` TIMESTAMP
    )
    schema.create( "users", function( table ) {
        table.uuid( "id" ).primaryKey();
    } );
    CREATE TABLE `users` (
        `id` CHAR(35) NOT NULL,
        CONSTAINT `pk_users_id` PRIMARY KEY (`id`)
    )
    schema.create( "users", function( table ) {
        table.unsignedInteger( "country_id" ).references( "id" ).onTable( "countries" ).onDelete( "cascade" );
    } );
    CREATE TABLE `users` (
        `country_id` INTEGER UNSIGNED NOT NULL,
        CONSTRAINT `fk_users_country_id` FOREIGN KEY (`country_id`) REFERENCES `countries` (`id`) ON UPDATE NO ACTION ON DELETE CASCADE
    )
    schema.create( "users", function( table ) {
        table.integer( age" ).unsigned();
    } );
    CREATE TABLE `users` (
        `age` INTEGER UNSIGNED NOT NULL
    )
    schema.create( "email", function( table ) {
        table.string( email" ).unique();
    } );
    CREATE TABLE `users` (
        `email` VARCHAR(255) NOT NULL UNIQUE
    )

    Joins

    hashtag
    Inner Join Clause

    The query builder may also be used to write join statements. To perform a basic "inner join", you may use the join method on a query builder instance. The first argument passed to the join method is the name of the table you need to join to, while the remaining arguments specify the column constraints for the join. Of course, as you can see, you can join to multiple tables in a single query:

    hashtag
    Joining using raw SQL

    Sometimes you need more control over your join clause in order to add grammar specific instructions, such as adding SQL Server table hints to your queries.

    If you need complete control over your join clause you can use the joinRaw() method

    Since the joinRaw() takes your string verbatim, it's important that you make sure your SQL declaration is escaped properly. Failure to properly escape your table names may result in SQL errors.

    NOTE: Using the joinRaw() will most likely tie your code to a specific database, so think carefully before using the joinRaw() method if you want your project to be database agnostic.

    NOTE: All of the join methods have a *Raw equivalent method. This means you can use leftJoinRaw(), rightJoinRaw(), etc.

    hashtag
    Complex (multi-conditional) Join Clause

    For a compound join clause, pass in the name of the table as the first argument (just as before) but instead of passing the remaining arguments describing the single join clause, we'll pass a single closure with a joinClause argument. Consider a (contrived) example where our users and blogs had to match not only ID but also type:

    hashtag
    Left/Right Join Clause

    If you would like to perform a "left/right join" instead of an "inner join", use the leftJoin / rightJoin method. The leftJoin / rightJoin method has the same signature as the join method:

    hashtag
    Cross Join Clause

    To perform a "cross join" use the crossJoin method with the name of the table you wish to cross join to. Cross joins generate a cartesian product between the first table and the joined table:

    hashtag
    Joining using Derived Tables

    Complex queries often contain derived tables, which are temporal, subqueries defined inline within your SQL.

    To join your main table to a derived table you can use the joinSub() methods. Each join method has a corresponding "sub" method which you can use when you need to use a derived table (i.e. leftJoinSub(), rightJoinSub(), etc).

    These functions differ slightly than the normal join methods, because the first two arguments specify:

    • The alias to use for the derived table (which is how you reference your query)

    • Either a QueryBuilder instances or closure defining the subquery

    //qb
    var getResults = query.from('blogs')
        .join('users', 'users.ID', '=', 'blogs.FK_usersID')
        .get();
    writeDump(getResults);
    
    //sql
    SELECT users.name,blogs.title,blogs.ID as blogID FROM `blogs` INNER JOIN `users` ON `users`.`ID` = `blogs`.`FK_usersID`
    //qb
    var getResults = query.from('blogs')
        .joinRaw('[users] AS u (nolock)', 'u.ID', '=', 'blogs.FK_usersID')
        .get();
    writeDump(getResults);
    
    //sql
    SELECT * FROM [blogs] INNER JOIN [users] AS u (nolock) ON [u].[ID] = [blogs].[FK_usersID]
    //qb
    var getResults = query.from( "blogs" )
        .join( "users", function( j ) {
            j.on( "users.ID", "=", "blogs.FK_usersID" )
                .on( "users.type", "=", "blogs.type" );
        } )
        .get();
    
    //sql
    SELECT users.name,blogs.title,blogs.ID as blogID FROM `blogs` INNER JOIN `users` ON `users`.`ID` = `blogs`.`FK_usersID` AND `users`.`type` = `blogs`.`type`
    //qb (leftJoin)
    var getResults = query.from('blogs')
        .leftJoin('users', 'users.ID', '=', 'blogs.FK_usersID')
        .get();
    writeDump(getResults);
    
    //qb (rightJoin)
    var getResults = query.from('blogs')
        .rightJoin('users', 'users.ID', '=', 'blogs.FK_usersID')
        .get();
    writeDump(getResults);
    
    //sql (leftJoin)
    SELECT * FROM `blogs` LEFT JOIN `users` ON `users`.`ID` = `blogs`.`FK_usersID`
    
    //sql (rightJoin)
    SELECT * FROM `blogs` RIGHT JOIN `users` ON `users`.`ID` = `blogs`.`FK_usersID`
    var getResults = query.from('users')
        .crossJoin('departments', 'departments.ID', '=', 'users.FK_departmentID')
        .get();
    writeDump(getResults);
    //qb
    var getResults = query
        .from('blogs')
        .joinSub('u', function (q){
            q
                .from('users')
                .where('disabled', 0)
            ;
        }, 'u.ID', '=', 'blogs.FK_usersID')
        .get();
    writeDump(getResults);
    
    //sql
    SELECT * FROM `blogs` INNER JOIN (SELECT * FROM `users` WHERE `disabled` = 0) AS `u` ON `u`.`ID` = `blogs`.`FK_usersID`

    Creating Table Constraints

    Sometimes you want to add constraints on a table level, rather than a column level. The following methods will let you accomplish that.

    hashtag
    index

    Create a generic index from one or more columns.

    Argument

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    foreignKey

    Create a foreign key constraint from one or more columns. Follow up this call with calls to the TableIndex's and methods.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    primaryKey

    Create a primary key constraint from one or more columns.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    unique

    Create a unique constraint from one or more columns.

    Example:

    SchemaBuilder

    SQL (MySQL)

    Type

    Required

    Default

    Description

    columns

    string or array

    true

    The column or array of columns that make up the index.

    name

    string

    false

    A generated name consisting of the table name and column name(s).

    The name of the index constraint.

    Argument

    Type

    Required

    Default

    Description

    columns

    string or array

    true

    The column or array of columns that references a key or keys on another table.

    name

    string

    false

    A generated name consisting of the table name and column name(s).

    Argument

    Type

    Required

    Default

    Description

    columns

    string or array

    true

    The column or array of columns that make up the primary key.

    name

    string

    false

    A generated name consisting of the table name and column name(s).

    Argument

    Type

    Required

    Default

    Description

    columns

    string or array

    true

    The column or array of columns that make up the unique constraint.

    name

    string

    false

    A generated name consisting of the table name and column name(s).

    references
    onTable

    The name of the foreign key constraint.

    The name of the primary key constraint.

    The name of the unique constraint.

    schema.create( "users", function( table ) {
        table.string( "first_name" );
        table.string( "last_name" );
        table.index( [ "first_name", "last_name" ], "idx_users_full_name" );
    } );
    CREATE TABLE `users` (
        `first_name` VARCHAR(255) NOT NULL,
        `last_name` VARCHAR(255) NOT NULL,
        INDEX `idx_users_full_name` (`first_name`, `last_name`)
    )
    schema.create( "users", function( table ) {
        table.unsignedInteger( "country_id" );
        table.foreignKey( "country_id" ).references( "id" ).onTable( "countries" );
    } );
    CREATE TABLE `users` (
        `country_id` INTEGER UNSIGNED NOT NULL,
        CONSTRAINT `fk_users_country_id` FOREIGN KEY (`country_id`) REFERENCES `countries` (`id`) ON UPDATE NO ACTION ON DELETE NO ACTION
    )
    schema.create( "posts_users", function( table ) {
        table.unsignedInteger( "post_id" ).references( "id" ).onTable( "posts" );
        table.unsignedInteger( "user_id" ).references( "id" ).onTable( "users" );
        table.primaryKey( [ "post_id", "user_id" ], "pk_posts_users" );
    } );
    CREATE TABLE `posts_users` (
        `post_id` VARCHAR(255) NOT NULL,
        `user_id` VARCHAR(255) NOT NULL,
        INDEX `idx_users_full_name` (`first_name`, `last_name`),
        CONSTRAINT `fk_posts_users_post_id` FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`) ON UPDATE NO ACTION ON DELETE NO ACTION,
        CONSTRAINT `fk_posts_users_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON UPDATE NO ACTION ON DELETE NO ACTION,
        CONSTRAINT ""pk_users_first_name_last_name"" PRIMARY KEY (""first_name"", ""last_name"")
    )
    schema.create( "users", function( table ) {
        table.increments( "id" );
        table.string( "username ");
        table.unique( "username" );
    } );
    CREATE TABLE `users` (
        `id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
        UNIQUE (`username`)
    )

    Drop

    Dropping tables straightforward in qb.

    For dropping columns or constraints, see Alter.

    hashtag
    drop

    Drop a table from the database.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    dropIfExists

    Drop a table from the database if it exists.

    Example:

    SchemaBuilder

    SQL (MySQL)

    execute

    boolean

    false

    true

    Run the query immediately after building it.

    execute

    boolean

    false

    true

    Run the query immediately after building it.

    Argument

    Type

    Required

    Default

    Description

    table

    string

    true

    The name of the table to drop.

    options

    struct

    false

    {}

    Argument

    Type

    Required

    Default

    Description

    table

    string

    true

    The name of the table to drop.

    options

    struct

    false

    {}

    Options to pass to queryExecute.

    Options to pass to queryExecute.

    schema.drop( "user_logins" );
    DROP TABLE `user_logins`
    schema.dropIfExists( "user_logins" );
    DROP TABLE IF EXISTS `user_logins`

    Columns

    The Blueprint object has many column types available to construct your table schema. Additionally, you can modify the columns created with an additional set of methods and indexes.

    Columns

    hashtag
    bigIncrements

    Create an auto-incrementing column using an unsigned BIGINT type. This column is also set as the primary key for the table.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    bigInteger

    Create a column using a BIGINT equivalent type for your database.

    Example (no precision):

    SchemaBuilder

    SQL (MySQL)

    Example (with precision):

    SchemaBuilder

    SQL (MySQL)

    hashtag
    bit

    Create a column using a BIT equivalent type for your database. The length can be specified as the second argument.

    Example (default length):

    SchemaBuilder

    SQL (MySQL)

    Example (custom length):

    SchemaBuilder

    SQL (MySQL)

    hashtag
    boolean

    Create a column using a BOOLEAN equivalent type for your database.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    char

    Create a column using a CHAR equivalent type for your database.

    Example (default length):

    SchemaBuilder

    SQL (MySQL)

    Example (custom length):

    SchemaBuilder

    SQL (MySQL)

    hashtag
    date

    Create a column using a DATE equivalent type for your database.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    datetime

    Create a column using a DATETIME equivalent type for your database.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    decimal

    Create a column using a DECIMAL equivalent type for your database. The length and precision can be specified as the second and third arguments.

    Example (with defaults):

    SchemaBuilder

    SQL (MySQL)

    Example (with length):

    SchemaBuilder

    SQL (MySQL)

    Example (with precision):

    SchemaBuilder

    SQL (MySQL)

    hashtag
    enum

    Create a column using a ENUM equivalent type for your database.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    float

    Create a column using a FLOAT equivalent type for your database. The length and precision can be specified as the second and third arguments.

    Example (with defaults):

    SchemaBuilder

    SQL (MySQL)

    Example (with length):

    SchemaBuilder

    SQL (MySQL)

    Example (with precision):

    SchemaBuilder

    SQL (MySQL)

    hashtag
    increments

    Create an auto-incrementing column using an unsigned INTEGER type. This column is also set as the primary key for the table.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    integer

    Create a column using a INTEGER equivalent type for your database.

    Example (no precision):

    SchemaBuilder

    SQL (MySQL)

    Example (with precision):

    SchemaBuilder

    SQL (MySQL)

    hashtag
    json

    Create a column using a JSON equivalent type for your database.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    longText

    Create a column using a LONGTEXT equivalent type for your database.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    mediumIncrements

    Create an auto-incrementing column using an unsigned MEDIUMINT type. This column is also set as the primary key for the table.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    mediumInteger

    Create a column using a MEDIUMINT equivalent type for your database.

    Example (no precision):

    SchemaBuilder

    SQL (MySQL)

    Example (with precision):

    SchemaBuilder

    SQL (MySQL)

    hashtag
    mediumText

    Create a column using a MEDIUMTEXT equivalent type for your database. For databases that distinguish between unicode and non-unicode fields, creates a non-unicode field.

    Example:

    SchemaBuilder

    SQL (MySQL)

    SQL (MSSQL)

    hashtag
    morphs

    Creates the necessary columns for a polymorphic relationship. It takes the name provided and creates an _id and an _type column.

    If you want different names for your polymorphic relationship columns, feel free to call other schema builder methods individually.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    nullableMorphs

    Creates the necessary columns for a polymorphic relationship. It takes the name provided and creates an _id and an _type column. The only difference between this method and morphs is that the columns created here are nullable.

    If you want different names for your polymorphic relationship columns, feel free to call other schema builder methods individually.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    raw

    An escape hatch to directly insert any sql in to the statement.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    smallIncrements

    Create an auto-incrementing column using an unsigned SMALLINT type. This column is also set as the primary key for the table.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    smallInteger

    Create a column using a SMALLINT equivalent type for your database.

    Example (no precision):

    SchemaBuilder

    SQL (MySQL)

    Example (with precision):

    SchemaBuilder

    SQL (MySQL)

    hashtag
    string

    Create a column using a VARCHAR equivalent type for your database. For databases that distinguish between unicode- and non-unicode string data types, this function will create a non-unicode string.

    Example (with defaults):

    SchemaBuilder

    SQL (MySQL)

    Example (with length):

    SchemaBuilder

    SQL (MySQL)

    hashtag
    text

    Create a column using a TEXT equivalent type for your database. For databases that distinguish between unicode- and non-unicode string data types, this function will create a non-unicode text field.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    time

    Create a column using a TIME equivalent type for your database.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    timestamp

    Create a column using a TIMESTAMP equivalent type for your database.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    tinyIncrements

    Create an auto-incrementing column using an unsigned TINYINT type. This column is also set as the primary key for the table.

    Example:

    SchemaBuilder

    SQL (MySQL)

    hashtag
    tinyInteger

    Create a column using a TINYINT equivalent type for your database.

    Example (no precision):

    SchemaBuilder

    SQL (MySQL)

    Example (with precision):

    SchemaBuilder

    SQL (MySQL)

    hashtag
    unicodeLongText

    Create a column using a LONGTEXT equivalent type for your database. For databases that distinguish between unicode- and non-unicode string data types, this function will create a unicode text field.

    Example:

    SchemaBuilder

    SQL (MySQL)

    SQL (MSSQL)

    hashtag
    unicodeMediumText

    Create a unicode-enabled column using a MEDIUMTEXT equivalent type for your database. For databases that distinguish between unicode- and non-unicode string data types, this function will create a unicode text field.

    Example:

    SchemaBuilder

    SQL (MySQL)

    SQL (MSSQL)

    hashtag
    unicodeString

    Create a column using a NVARCHAR equivalent type for your database. For databases that distinguish between unicode- and non-unicode string data types, this function will create a unicode string.

    Example (with defaults):

    SchemaBuilder

    SQL (MySQL)

    SQL (MSSQL)

    Example (with length):

    SchemaBuilder

    SQL (MySQL)

    SQL (MSSQL)

    hashtag
    unicodeText

    Create a column using a NTEXT equivalent type for your database.

    Example:

    SchemaBuilder

    SQL (MySQL)

    SQL (MSSQL)

    hashtag
    unsignedBigInteger

    Create a column using a UNSIGNED BIGINT equivalent type for your database.

    Example (no precision):

    SchemaBuilder

    SQL (MySQL)

    Example (with precision):

    SchemaBuilder

    SQL (MySQL)

    hashtag
    unsignedInteger

    Create a column using a UNSIGNED INTEGER equivalent type for your database.

    Example (no precision):

    SchemaBuilder

    SQL (MySQL)

    Example (with precision):

    SchemaBuilder

    SQL (MySQL)

    hashtag
    unsignedMediumInteger

    Create a column using a UNSIGNED MEDIUMINT equivalent type for your database.

    Example (no precision):

    SchemaBuilder

    SQL (MySQL)

    Example (with precision):

    SchemaBuilder

    SQL (MySQL)

    hashtag
    unsignedSmallInteger

    Create a column using a UNSIGNED SMALLINT equivalent type for your database.

    Example (no precision):

    SchemaBuilder

    SQL (MySQL)

    Example (with precision):

    SchemaBuilder

    SQL (MySQL)

    hashtag
    unsignedTinyInteger

    Create a column using a UNSIGNED TINYINT equivalent type for your database.

    Example (no precision):

    SchemaBuilder

    SQL (MySQL)

    Example (with precision):

    SchemaBuilder

    SQL (MySQL)

    hashtag
    uuid

    SQL Server: Create a column using a uniqueidentifier.

    MySQL and Others: Create a column using a CHAR equivalent type for your database and a length of 36. Used in conjunction with the CFML createUUID method.

    Example:

    SchemaBuilder

    MySQL (SQL Server)

    SQL (MySQL)

    precision

    numeric

    false

    0

    The precision of the column.

    precision

    numeric

    false

    0

    The precision of the column.

    char

    date

    datetime

    decimal

    enum

    float

    increments

    integer

    json

    longText

    mediumIncrements

    mediumInteger

    mediumText

    morphs

    nullableMorphs

    raw

    smallIncrements

    smallInteger

    string

    text

    time

    timestamp

    tinyIncrements

    tinyInteger

    unicodeLongText

    unicodeMediumText

    unicodeString

    unicodeText

    unsignedBigInteger

    unsignedInteger

    unsignedMediumInteger

    unsignedSmallInteger

    unsignedTinyInteger

    uuid

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    indexName

    string

    false

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    precision

    numeric

    false

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    length

    numeric

    false

    1

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    length

    numeric

    false

    1

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    length

    numeric

    false

    10

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    length

    numeric

    false

    10

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    indexName

    string

    false

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    precision

    numeric

    false

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    indexName

    string

    false

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    precision

    numeric

    false

    10

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The prefix for the polymorphic columns.

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The prefix for the polymorphic columns.

    Argument

    Type

    Required

    Default

    Description

    sql

    string

    true

    The sql to insert directly into the statement.

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    indexName

    string

    false

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    precision

    numeric

    false

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    length

    numeric

    false

    255

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    indexName

    string

    false

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    precision

    numeric

    false

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    length

    numeric

    false

    255

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    precision

    numeric

    false

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    precision

    numeric

    false

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    precision

    numeric

    false

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    precision

    numeric

    false

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    precision

    numeric

    false

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    The name for the column.

    bigIncrements
    bigInteger
    bit
    boolean

    The name for the primary key index. If no name is passed in, the name will be dynamically created based off of the table name and column name.

    The precision for the column.

    The length for the column.

    The length for the column.

    The length of the column.

    The length of the column.

    The name for the primary key index. If no name is passed in, the name will be dynamically created based off of the table name and column name.

    The precision for the column.

    The name for the primary key index. If no name is passed in, the name will be dynamically created based off of the table name and column name.

    The precision for the column.

    The name for the primary key index. If no name is passed in, the name will be dynamically created based off of the table name and column name.

    The precision for the column.

    The length of the column.

    The name for the primary key index. If no name is passed in, the name will be dynamically created based off of the table name and column name.

    The precision for the column.

    The length of the column.

    The precision for the column.

    The precision for the column.

    The precision for the column.

    The precision for the column.

    The precision for the column.

    schema.create( "users", function( table ) {
        table.bigIncrements( "id" );
    } );
    CREATE TABLE `users` (
        `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
        CONSTRAINT `pk_users_id` PRIMARY KEY (`id`)
    )
    schema.create( "users", function( table ) {
        table.bigInteger( "salary" );
    } );
    CREATE TABLE `users` (
        `salary` BIGINT NOT NULL
    )
    schema.create( "users", function( table ) {
        table.bigInteger( "salary", 5 );
    } );
    CREATE TABLE `users` (
        `salary` BIGINT(5) NOT NULL
    )
    schema.create( "users", function( table ) {
        table.bit( "is_active" );
    } );
    CREATE TABLE `users` (
        `is_active` BIT(1) NOT NULL
    )
    schema.create( "users", function( table ) {
        table.bit( "is_active", 2 );
    } );
    CREATE TABLE `users` (
        `is_active` BIT(2) NOT NULL
    )
    schema.create( "users", function( table ) {
        table.boolean( "is_subscribed" );
    } );
    CREATE TABLE `users` (
        `is_subscribed` TINYINT(1) NOT NULL
    )
    schema.create( "students", function( table ) {
        table.char( "grade" );
    } );
    CREATE TABLE `students` (
        `grade` CHAR(1) NOT NULL
    )
    schema.create( "users", function( table ) {
        table.char( "tshirt_size", 4 );
    } );
    CREATE TABLE `users` (
        `tshirt_size` CHAR(4) NOT NULL
    )
    schema.create( "users", function( table ) {
        table.date( "birthday" );
    } );
    CREATE TABLE `users` (
        `birthday` DATE NOT NULL
    )
    schema.create( "users", function( table ) {
        table.datetime( "hire_date" );
    } );
    CREATE TABLE `users` (
        `hire_date` DATETIME NOT NULL
    )
    schema.create( "weather", function( table ) {
        table.decimal( "temperature" );
    } );
    CREATE TABLE `weather` (
        `temperature` DECIMAL(10,0) NOT NULL
    )
    schema.create( "weather", function( table ) {
        table.decimal( "temperature", 4 );
    } );
    CREATE TABLE `weather` (
        `temperature` DECIMAL(4,0) NOT NULL
    )
    schema.create( "weather", function( table ) {
        table.decimal( name = "temperature", precision = 2 );
    } );
    CREATE TABLE `weather` (
        `temperature` DECIMAL(10,2) NOT NULL
    )
    schema.create( "users", function( table ) {
        table.enum( "tshirt_size", [ "S", "M", "L", "XL", "XXL" ] );
    } );
    CREATE TABLE `users` (
        `tshirt_size` ENUM(`S`, `M`, `L`, `XL`, `XXL`) NOT NULL
    )
    schema.create( "weather", function( table ) {
        table.float( "temperature" );
    } );
    CREATE TABLE `weather` (
        `temperature` FLOAT(10,0) NOT NULL
    )
    schema.create( "weather", function( table ) {
        table.float( "temperature", 4 );
    } );
    CREATE TABLE `weather` (
        `temperature` FLOAT(4,0) NOT NULL
    )
    schema.create( "weather", function( table ) {
        table.float( name = "temperature", precision = 2 );
    } );
    CREATE TABLE `weather` (
        `temperature` FLOAT(10,2) NOT NULL
    )
    schema.create( "users", function( table ) {
        table.increments( "id" );
    } );
    CREATE TABLE `users` (
        `id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
        CONSTRAINT `pk_users_id` PRIMARY KEY (`id`)
    )
    schema.create( "games", function( table ) {
        table.integer( "score" );
    } );
    CREATE TABLE `games` (
        `score` INTEGER NOT NULL
    )
    schema.create( "games", function( table ) {
        table.integer( "score", 3 );
    } );
    CREATE TABLE `games` (
        `score` INTEGER(3) NOT NULL
    )
    schema.create( "users", function( table ) {
        table.json( "options" ).nullable();
    } );
    CREATE TABLE `users` (
        `options` JSON
    )
    schema.create( "posts", function( table ) {
        table.longText( "body" );
    } );
    CREATE TABLE `posts` (
        `body` LONGTEXT NOT NULL
    )
    schema.create( "users", function( table ) {
        table.mediumIncrements( "id" );
    } );
    CREATE TABLE `users` (
        `id` MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT,
        CONSTRAINT `pk_users_id` PRIMARY KEY (`id`)
    )
    schema.create( "games", function( table ) {
        table.mediumInteger( "score" );
    } );
    CREATE TABLE `games` (
        `score` MEDIUMINT NOT NULL
    )
    schema.create( "games", function( table ) {
        table.mediumInteger( "score", 5 );
    } );
    CREATE TABLE `games` (
        `score` MEDIUMINT(5) NOT NULL
    )
    schema.create( "posts", function( table ) {
        table.mediumText( "body" );
    } );
    CREATE TABLE `posts` (
        `body` MEDIUMTEXT NOT NULL
    )
    CREATE TABLE `posts` (
        `body` VARCHAR(MAX) NOT NULL
    )
    schema.create( "tags", function( table ) {
        table.morphs( "taggable" );
    } );
    CREATE TABLE `tags` (
        `taggable_id` INTEGER UNSIGNED NOT NULL,
        `taggable_type` VARCHAR(255) NOT NULL,
        INDEX `taggable_index` (`taggable_id`, `taggable_type`)
    )
    schema.create( "tags", function( table ) {
        table.nullableMorphs( "taggable" );
    } );
    CREATE TABLE `tags` (
        `taggable_id` INTEGER UNSIGNED,
        `taggable_type` VARCHAR(255),
        INDEX `taggable_index` (`taggable_id`, `taggable_type`)
    )
    schema.create( "users", function( table ) {
        table.raw( "`profile_image` BLOB NOT NULL" );
    } );
    CREATE TABLE `users` (
        `profile_image` BLOB NOT NULL
    )
    schema.create( "users", function( table ) {
        table.smallIncrements( "id" );
    } );
    CREATE TABLE `users` (
        `id` SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
        CONSTRAINT `pk_users_id` PRIMARY KEY (`id`)
    )
    schema.create( "games", function( table ) {
        table.smallInteger( "score" );
    } );
    CREATE TABLE `games` (
        `score` SMALLINT NOT NULL
    )
    schema.create( "games", function( table ) {
        table.smallInteger( "score", 3 );
    } );
    CREATE TABLE `games` (
        `score` SMALLINT(3) NOT NULL
    )
    schema.create( "users", function( table ) {
        table.string( "username" );
    } );
    CREATE TABLE `users` (
        `username` VARCHAR(255) NOT NULL
    )
    schema.create( "users", function( table ) {
        table.string( "username", 50 );
    } );
    CREATE TABLE `users` (
        `username` VARCHAR(50) NOT NULL
    )
    schema.create( "posts", function( table ) {
        table.text( "body" );
    } );
    CREATE TABLE `posts` (
        `body` TEXT NOT NULL
    )
    schema.create( "races", function( table ) {
        table.time( "finish_time" );
    } );
    CREATE TABLE `races` (
        `finish_time` TIME NOT NULL
    )
    schema.create( "users", function( table ) {
        table.timestamp( "created_at" );
    } );
    CREATE TABLE `users` (
        `created_at` TIMESTAMP NOT NULL
    )
    schema.create( "users", function( table ) {
        table.tinyIncrements( "id" );
    } );
    CREATE TABLE `users` (
        `id` TINYINT UNSIGNED NOT NULL AUTO_INCREMENT,
        CONSTRAINT `pk_users_id` PRIMARY KEY (`id`)
    )
    schema.create( "games", function( table ) {
        table.tinyInteger( "score" );
    } );
    CREATE TABLE `games` (
        `score` TINYINT NOT NULL
    )
    schema.create( "games", function( table ) {
        table.tinyInteger( "score", 3 );
    } );
    CREATE TABLE `games` (
        `score` TINYINT(3) NOT NULL
    )
    schema.create( "posts", function( table ) {
        table.longText( "body" );
    } );
    CREATE TABLE `posts` (
        `body` LONGTEXT NOT NULL
    )
    CREATE TABLE [posts] (
        [body] NVARCHAR(MAX) NOT NULL
    )
    schema.create( "posts", function( table ) {
        table.unicodeMediumText( "body" );
    } );
    CREATE TABLE `posts` (
        `body` MEDIUMTEXT NOT NULL
    )
    CREATE TABLE [posts] (
        [body] NVARCHAR(MAX) NOT NULL
    )
    schema.create( "users", function( table ) {
        table.unicodeString( "username" );
    } );
    CREATE TABLE `users` (
        `username` VARCHAR(255) NOT NULL
    )
    CREATE TABLE [users] (
        [username] NVARCHAR(255) NOT NULL
    )
    schema.create( "users", function( table ) {
        table.unicodeString( "username", 50 );
    } );
    CREATE TABLE `users` (
        `username` VARCHAR(50) NOT NULL
    )
    CREATE TABLE [users] (
        [username] NVARCHAR(50) NOT NULL
    )
    schema.create( "posts", function( table ) {
        table.unicodeText( "body" );
    } );
    CREATE TABLE `posts` (
        `body` TEXT NOT NULL
    )
    CREATE TABLE [posts] (
        [body] NVARCHAR(MAX) NOT NULL
    )
    schema.create( "games", function( table ) {
        table.unsignedBigInteger( "score" );
    } );
    CREATE TABLE `games` (
        `score` BIGINT UNSIGNED NOT NULL
    )
    schema.create( "games", function( table ) {
        table.unsignedBigInteger( "score", 3 );
    } );
    CREATE TABLE `games` (
        `score` BIGINT(3) UNSIGNED NOT NULL
    )
    schema.create( "games", function( table ) {
        table.unsignedInteger( "score" );
    } );
    CREATE TABLE `games` (
        `score` INTEGER UNSIGNED NOT NULL
    )
    schema.create( "games", function( table ) {
        table.unsignedInteger( "score", 3 );
    } );
    CREATE TABLE `games` (
        `score` INTEGER(3) UNSIGNED NOT NULL
    )
    schema.create( "games", function( table ) {
        table.unsignedMediumInteger( "score" );
    } );
    CREATE TABLE `games` (
        `score` MEDIUMINT UNSIGNED NOT NULL
    )
    schema.create( "games", function( table ) {
        table.unsignedMediumInteger( "score", 3 );
    } );
    CREATE TABLE `games` (
        `score` MEDIUMINT(3) UNSIGNED NOT NULL
    )
    schema.create( "games", function( table ) {
        table.unsignedSmallInteger( "score" );
    } );
    CREATE TABLE `games` (
        `score` SMALLINT UNSIGNED NOT NULL
    )
    schema.create( "games", function( table ) {
        table.unsignedSmallInteger( "score", 3 );
    } );
    CREATE TABLE `games` (
        `score` SMALLINT(3) UNSIGNED NOT NULL
    )
    schema.create( "games", function( table ) {
        table.unsignedTinyInteger( "score" );
    } );
    CREATE TABLE `games` (
        `score` TINYINT UNSIGNED NOT NULL
    )
    schema.create( "games", function( table ) {
        table.unsignedTinyInteger( "score", 3 );
    } );
    CREATE TABLE `games` (
        `score` TINYINT(3) UNSIGNED NOT NULL
    )
    schema.create( "users", function( table ) {
        table.uuid( "id" ).primaryKey();
    } );
    CREATE TABLE `games` (
        `id` uniqueidentifier NOT NULL,
        CONSTRAINT `pk_games_id` PRIMARY KEY (`id`)
    )
    CREATE TABLE `games` (
        `id` VARCHAR(36) NOT NULL,
        CONSTRAINT `pk_games_id` PRIMARY KEY (`id`)
    )

    Create

    This method allows you to create a table object.

    Argument

    Type

    Required

    Default

    Description

    table

    string

    true

    The name of the table to create.

    The majority of the work comes from calling methods on the Blueprint object. A Blueprint defines the and for your tables.

    Example:

    This would convert to the following SQL in MySQL:

    Only one table can be created at a time. If you wanted to create multiple tables, you would call create multiple times.

    The callback argument is where you define the schema of your table. It is passed a Blueprint object. This is commonly aliased as table in the callback. Blueprint defines the field, index and constraint methods to build your table. You can find a comprehensive list of all available methods here for and here for .

    Contributors

    Thanks goes to these wonderful people (emoji keyarrow-up-right):

    This project follows the all-contributorsarrow-up-right specification. Contributions of any kind welcome!

    πŸ’»arrow-up-right
    πŸ“–arrow-up-right
    πŸ’¬
    πŸ’»arrow-up-right
    πŸ›arrow-up-right
    πŸ’»arrow-up-right
    πŸ’»arrow-up-right
    πŸ›arrow-up-right
    πŸ’»arrow-up-right
    πŸ“–arrow-up-right

    callback

    function

    true

    A callback function used to define the table body. It is passed a Blueprint as the only argument.

    options

    struct

    false

    {}

    Options to pass to queryExecute.

    execute

    boolean

    false

    true

    Run the query immediately after building it.

    columns
    indexes
    columnsarrow-up-right
    indexes and constraints
    schema.create( "users", function( table ) {
        table.increments( "id" );
        table.string( "email" );
        table.string( "password" );
        table.timestamp( "created_date" );
        table.timestamp( "modified_date" );
        table.timestamp( "last_logged_in" ).nullable();
    } );
    CREATE TABLE `users` (
        `id` INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
        `email` VARCHAR(255) NOT NULL,
        `password` VARCHAR(255) NOT NULL,
        `created_date` TIMESTAMP NOT NULL,
        `modified_date` TIMESTAMP NOT NULL,
        `last_logged_in` TIMESTAMP,
        CONSTRAINT `pk_users_id` PRIMARY KEY (`id`)
    )