Only this pageAll pages
Powered 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?

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-contributors
// 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)" ];
}
README

Introduction

qb is a fluent query builder for CFML. It is heavily inspired by from .

Using qb, you can:

  • Quickly scaffold simple queries

Make complex, out-of-order queries possible

  • Abstract away differences between database engines

    • Adobe ColdFusion 11+

    • Lucee 4.5+

    qb supports four major database grammars:

    • MSSQL (MSSQLGrammar)

    • MySQL (MySQLGrammar)

    • Oracle (OracleGrammar)

    • Postgres (PostgresGrammar)

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

    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! https://gist.github.com/elpete/80d641b98025f16059f6476561d88202

    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:

    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.

    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

    String

    The sql string to execute

    bindings

    Struct

    Thanks goes to these wonderful people (emoji key):

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

    Introduction

    Eloquent
    Laravel
    All Contributors
    Master Branch Build Status
    Development Branch Build Status
    // 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 }
                );
            }
        }
    };

    Requirements

    Installation

    Code Samples

    Usage

    Return Format

    Interception Points

    Contributors

    Migration Guide

    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.

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

    options

    Struct

    Any options to pass along to queryExecute

    📖
    🐛
    💻
    📖
    ⚠️
    🐛
    💻
    📖
    🐛
    💻
    💻
    💻
    📝
    💬
    📝
    🎨
    💡
    👀
    📢
    💬

    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);

    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:

    //qb
    var deleteRecords = query.from( "users" )
        .whereID( 10 )
        .delete();
    writeDump(deleteRecords);
    
    //sql
    DELETE FROM `users` WHERE `ID` = 10;

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

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

    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"

    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.

    Conditionals

    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.

    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:

    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:

    You can also use Expressions inside an update statement:

    Null values can be inserted by using queryparam syntax:

    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

    Name

    Type

    Description

    moduleSettings = {
        qb = {
            returnFormat = function( q ) {
                return application.wirebox.getInstance(
                    name = "Collection",
                    initArguments = { collection = q }
                );
            }
        }
    };

    Default

    Description

    condition

    boolean

    true

    The condition to switch on.

    onTrue

    Closure

    true

    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.

    We can rewrite the above query like so:

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

    Name

    Type

    Basic if and else

    when

    Required

    if you are using Lucee with full null support the following (easier) syntax is also allowed:
    //qb
    var addRecords = query.from( "users" )
        .whereID( 10 )
        .update(  { "name" = "Roberto", "email" = "roberto@test.com", "age" = 55 });
    writeDump(addRecords);
    
    //sql
    UPDATE `users` SET `age` = 55, `email` = `roberto@test.com`, `name` = `Roberto` WHERE `ID` = 10
    query.from( "posts" )
        .whereID( 10 )
        .update( { "likes" = query.raw( "likes + 1" ) } );
        
    // SQL:      UPDATE `posts` SET `likes` = likes + 1 WHERE `ID` = ?
    // Bindings: [ 10 ]

    Updating Null values

    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();
    query.from("user")
    		.whereId( 10 )
    		.update( {
    			manager_FK = { value = "", null=true },
    		} )
    query.from("user")
    		.whereId( 10 )
    		.update( {
    			manager_FK = { value = null },
    		} )

    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

    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:

    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)

    Drop a column on an existing table.

    Example:

    SchemaBuilder

    SQL (MySQL)

    Modify an existing column on a table.

    Example:

    SchemaBuilder

    SQL (MySQL)

    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)

    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)

    Drop an existing table constraint.

    Example:

    SchemaBuilder

    SQL (MySQL)

    Rename an existing table constraint.

    Example:

    SchemaBuilder

    SQL (MySQL)

    Retrieving Results

    Usage## Retrieving Results

    Retrieving All Rows From A Table

    // 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" }
        );

    The get method returns an Array of Structs by default. Both columns and options are optional.

    public any function get( any columns, struct options = {} )

    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:

    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

    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" = "robert@test.com", "age" = 55 } );
    writeDump(addRecords);
    
    //sql
    INSERT INTO `users` (`age`, `email`, `name`) VALUES (55, `robert@test.com`, `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:

    //qb
    var addRecords = query.from( "users" )
    .insert( values = [
            { "name" = "Robert", "email" = "robert@test.com", "age" = 55 },
            { "name" = "Jessica", "email" = "jessica@test.com", "age" = 31 },
            { "name" = "Ross", "email" = "ross@test.com", "age" = 9 }
        ] );
    writeDump(addRecords);
    
    //sql
    INSERT INTO `users` (`age`, `email`, `name`)
    VALUES (55, `robert@test.com`, `Robert`),
            (31, `jessica@test.com`, `Jessica`),
            (9, `ross@test.com`, `Ross`)

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

    //qb
    var addRecords = query
            .from( "users" )
            .insert( values = { 
                    "name" = "Robert", 
                    "email" = "robert@test.com", 
                    "age" = { value : 55, cfsqltype : "integer" },
                    "createdDate" = { value : now(), cfsqltype : "timestamp" }
            } );
    writeDump(addRecords);

    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.

    Installation & Usage

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

    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

    Create

    This method allows you to create a table object.

    column

    Column

    true

    A column object to replace the named column.

    column

    Column

    true

    A column object with the new column name and definition.

    newName

    string OR TableIndex

    true

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

    Type

    Required

    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

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    constraint

    TableIndex

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string OR TableIndex

    true

    Argument

    Type

    Required

    Default

    Description

    oldName

    string OR TableIndex

    true

    addColumn

    dropColumn

    modifyColumn

    renameColumn

    addConstraint

    dropConstraint

    renameConstraint

    column methods
    column modifier methods

    A column object to add to the table.

    The name of the column to drop.

    The name of the column to modify.

    The current name of a column.

    The TableIndex instance to add to the table.

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

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

    index methods

    Options parameter: Retrieving results from alternative datasources

    // qb
    var addRecords = query.from( "users" )
        .returning( "id" )
        .insert( { "name" = "Robert", "email" = "robert@test.com", "age" = 55 } );
    writeDump(addRecords);
    
    // Postgres
    INSERT INTO "users" ("age", "email", "name")
    VALUES (55, "robert@test.com", "Robert")
    RETURNING "id"
    
    // MSSQL
    INSERT INTO [users] ([age], [email], [name])
    OUTPUT INSERTED.[id]
    VALUES (55, "robert@test.com", "Robert")
    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`
    //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" );
    // [ "john@example.com", "jane@example.com", "jim@example.com", ... ]
    public any function values( required string column, struct options = {} );
    query.from( "users" ).value( "email" );
    // "john@example.com"
    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') );
    object with the correct grammar:

    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.

    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.

    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().

    moduleSettings = {
        qb = {
            defaultGrammar = "MySQLGrammar"
        }
    };

    Installation

    Usage

    CommandBox
    ForgeBox
    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();

    Integrating With FW/1

    Wiring Up With DI/1

    Usage In Your FW/1 Application

    For further instructions on getting started with qb & FW/1, refer to .

    true

    The name of the table to create.

    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.

    The majority of the work comes from calling methods on the Blueprint object. A Blueprint defines the columns 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 columns and here for .

    Argument

    Type

    Required

    Default

    Description

    table

    string

    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`)
    )

    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.

    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:

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

    This would return all columns from the users table.

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

    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:

    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.

    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:

    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

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

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

    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.

    Joins

    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:

    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

    indexes
    indexes and constraints
    this blog post

    Declaring a table alias

    Defining the from clause using raw SQL

    Adding bindings to your raw from clause

    Derived tables

    Defining a derived table using a closure

    Defining a derived table using a QueryBuilder instance

    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.

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

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

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

    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.

    Your query can contain multiple union methods:

    Simple union using a callback

    Using a Query Builder instance

    union all

    Ordering union queries

    Multiple union statements

    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.

    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:

    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:

    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:

    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

    Inner Join Clause

    Joining using raw SQL

    Complex (multi-conditional) Join Clause

    Left/Right Join Clause

    Cross Join Clause

    Joining using Derived Tables

    //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`
    //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
    //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`

    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.

    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.

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

    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.

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

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

    A single query can reference multiple 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:

    Simple CTE using a closure

    Simple CTE using a QueryBuilder instance

    Multiple CTEs

    Recursive CTEs

    // 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]

    Required

    Default

    Description

    columns

    any

    true

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

    Example:

    SchemaBuilder

    SQL (MySQL)

    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

    Example:

    SchemaBuilder

    SQL (MySQL)

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

    Argument

    Type

    Required

    Default

    Description

    option

    string

    true

    Example:

    SchemaBuilder

    SQL (MySQL)

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

    Argument

    Type

    Required

    Default

    Description

    option

    string

    true

    Example:

    SchemaBuilder

    SQL (MySQL)

    Argument

    references

    Blueprint
    Column

    Type

    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
    )

    onTable

    onUpdate

    onDelete

    The referencing table name.

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

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

    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.

    // 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`.

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

    // 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.

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

    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.

    index

    Create a generic index from one or more columns.

    Argument

    Type

    Required

    Default

    Description

    Example:

    SchemaBuilder

    SQL (MySQL)

    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)

    Create a primary key constraint from one or more columns.

    Example:

    SchemaBuilder

    SQL (MySQL)

    Create a unique constraint from one or more columns.

    Example:

    SchemaBuilder

    SQL (MySQL)

    name

    string

    false

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

    The name of the foreign key constraint.

    name

    string

    false

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

    The name of the primary key constraint.

    name

    string

    false

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

    The name of the unique constraint.

    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

    Argument

    Type

    Required

    Default

    Description

    columns

    string or array

    true

    Argument

    Type

    Required

    Default

    Description

    columns

    string or array

    true

    foreignKey

    primaryKey

    unique

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

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

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

    references
    onTable
    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`)
    )

    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

    Attach a comment to the column.

    Example:

    SchemaBuilder

    SQL (MySQL)

    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)

    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)

    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)

    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)

    Sets the column as unsigned.

    Example:

    SchemaBuilder

    SQL (MySQL)

    Sets the column to have the UNIQUE constraint.

    Example:

    SchemaBuilder

    SQL (MySQL)

    Where Clauses

    Base

    AND

    OR

    where()

    andWhere()

    orWhere()

    whereBetween()

    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.

    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:

    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:

    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.

    Drop

    Dropping tables straightforward in qb.

    For dropping columns or constraints, see Alter.

    drop

    Drop a table from the database.

    Argument

    Type

    Example:

    SchemaBuilder

    SQL (MySQL)

    Drop a table from the database if it exists.

    Example:

    SchemaBuilder

    SQL (MySQL)

    default

    nullable

    primaryKey

    references

    unsigned

    unique

    Argument

    Type

    Required

    Default

    Description

    comment

    string

    true

    Argument

    Type

    Required

    Default

    Description

    value

    string

    true

    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.

    Argument

    Type

    Required

    Default

    Description

    value

    string

    true

    Argument

    Type

    Required

    Default

    Description

    No arguments

    Argument

    Type

    Required

    Default

    Description

    No arguments

    comment

    default

    nullable

    primaryKey

    references

    unsigned

    unique

    TableIndex instance.
    TableIndex instance.
    comment

    The comment text.

    The default value.

    The name to use for the primary key constraint.

    The default value.

    andWhereBetween()

    orWhereBetween()

    whereColumn()

    andWhereColumn()

    orWhereColumn()

    whereExists()

    andWhereExists()

    orWhereExists()

    whereIn()

    andWhereIn()

    orWhereIn()

    whereNotBetween()

    andWhereNotBetween()

    orWhereNotBetween()

    whereNotExists()

    andWhereNotExists()

    orWhereNotExists()

    whereNotIn()

    andWhereNotIn()

    orWhereNotIn()

    whereNotNull()

    andWhereNotNull()

    orWhereNotNull()

    whereNull()

    andWhereNull()

    orWhereNull()

    whereRaw()

    andWhereRaw()

    orWhereRaw()

    Parameters

    Simple Where Clauses

    Or Statements

    Additional Where Clauses

    options

    struct

    false

    {}

    Options to pass to queryExecute.

    execute

    boolean

    false

    true

    Run the query immediately after building it.

    Required

    Default

    Description

    table

    string

    true

    The name of the table to drop.

    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

    dropIfExists

    The name of the table to drop.

    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
    )
    //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.drop( "user_logins" );
    DROP TABLE `user_logins`
    schema.dropIfExists( "user_logins" );
    DROP TABLE IF EXISTS `user_logins`

    Contributors

    Thanks goes to these wonderful people (emoji key):

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

    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:

    Create a new table in the database.

    Argument

    Type

    Required

    Default

    Description

    table

    string

    true

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

    Example:

    SchemaBuilder

    SQL (MySQL)

    Alter an existing table in the database.

    Argument

    Type

    Required

    Default

    Description

    table

    string

    true

    In addition to using the columns and indexes 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)

    Drop a table from the database.

    Argument

    Type

    Required

    Default

    Description

    table

    string

    true

    Example:

    SchemaBuilder

    SQL (MySQL)

    Rename a table from an old name to a new name

    Argument

    Type

    Required

    Default

    Description

    from

    string

    true

    Example:

    SchemaBuilder

    SQL (MySQL)

    Check if a table exists in the database.

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Example:

    SchemaBuilder

    SQL (MySQL)

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

    Argument

    Type

    Required

    Default

    Description

    table

    string

    true

    Example:

    SchemaBuilder

    SQL (MySQL)

    // 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'

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

    rename

    hasTable

    hasColumn

    Selects

    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:

    var getResults = query.from('users')
        .get('name,email,age');
    writeDump(getResults);

    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.

    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);

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

    var getResults = query.from('users')
        .select('email')
        .distinct();
    writeDump(getResults);

    (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:

    The name of the table to create.

    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.

    The name of the table to alter.

    callback

    function

    true

    A callback function used to define the changes 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.

    The name of the table to drop.

    options

    struct

    false

    {}

    Options to pass to queryExecute.

    execute

    boolean

    false

    true

    Run the query immediately after building it.

    The old table name.

    to

    string

    true

    The new table name.

    options

    struct

    false

    {}

    Options to pass to queryExecute.

    execute

    boolean

    false

    true

    Run the query immediately after building it.

    The name of the table to check.

    options

    struct

    false

    {}

    Options to pass to queryExecute.

    execute

    boolean

    false

    true

    Run the query immediately after building it.

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

    column

    string

    true

    The column to check for in the table.

    options

    struct

    false

    {}

    Options to pass to queryExecute.

    execute

    boolean

    false

    true

    Run the query immediately after building it.

    create
    alter
    drop and dropIfExists
    var getResults = query.from('users')
        .where('age','>=','18');
    getResults = getResults.addSelect('name,email,age').get();
    writeDump(getResults);

    Ordering, Grouping & Limit

    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:

    //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

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

    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:

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

    Alternatively, you may use the limit method:

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

    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.

    take / limit

    offset

    forPage

    //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();

    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 .

    Columns

    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)

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

    Example (no precision):

    SchemaBuilder

    SQL (MySQL)

    Example (with precision):

    SchemaBuilder

    SQL (MySQL)

    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)

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

    Example:

    SchemaBuilder

    SQL (MySQL)

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

    Example (default length):

    SchemaBuilder

    SQL (MySQL)

    Example (custom length):

    SchemaBuilder

    SQL (MySQL)

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

    Example:

    SchemaBuilder

    SQL (MySQL)

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

    Example:

    SchemaBuilder

    SQL (MySQL)

    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)

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

    Example:

    SchemaBuilder

    SQL (MySQL)

    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)

    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)

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

    Example (no precision):

    SchemaBuilder

    SQL (MySQL)

    Example (with precision):

    SchemaBuilder

    SQL (MySQL)

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

    Example:

    SchemaBuilder

    SQL (MySQL)

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

    Example:

    SchemaBuilder

    SQL (MySQL)

    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)

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

    Example (no precision):

    SchemaBuilder

    SQL (MySQL)

    Example (with precision):

    SchemaBuilder

    SQL (MySQL)

    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)

    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)

    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)

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

    Example:

    SchemaBuilder

    SQL (MySQL)

    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)

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

    Example (no precision):

    SchemaBuilder

    SQL (MySQL)

    Example (with precision):

    SchemaBuilder

    SQL (MySQL)

    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)

    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)

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

    Example:

    SchemaBuilder

    SQL (MySQL)

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

    Example:

    SchemaBuilder

    SQL (MySQL)

    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)

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

    Example (no precision):

    SchemaBuilder

    SQL (MySQL)

    Example (with precision):

    SchemaBuilder

    SQL (MySQL)

    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)

    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)

    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)

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

    Example:

    SchemaBuilder

    SQL (MySQL)

    SQL (MSSQL)

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

    Example (no precision):

    SchemaBuilder

    SQL (MySQL)

    Example (with precision):

    SchemaBuilder

    SQL (MySQL)

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

    Example (no precision):

    SchemaBuilder

    SQL (MySQL)

    Example (with precision):

    SchemaBuilder

    SQL (MySQL)

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

    Example (no precision):

    SchemaBuilder

    SQL (MySQL)

    Example (with precision):

    SchemaBuilder

    SQL (MySQL)

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

    Example (no precision):

    SchemaBuilder

    SQL (MySQL)

    Example (with precision):

    SchemaBuilder

    SQL (MySQL)

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

    Example (no precision):

    SchemaBuilder

    SQL (MySQL)

    Example (with precision):

    SchemaBuilder

    SQL (MySQL)

    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)

    indexName

    string

    false

    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.

    precision

    numeric

    false

    The precision for the column.

    length

    numeric

    false

    1

    The length for the column.

    length

    numeric

    false

    1

    The length for the column.

    length

    numeric

    false

    10

    The length of the column.

    precision

    numeric

    false

    0

    The precision of the column.

    length

    numeric

    false

    10

    The length of the column.

    precision

    numeric

    false

    0

    The precision of the column.

    indexName

    string

    false

    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.

    precision

    numeric

    false

    The precision for the column.

    indexName

    string

    false

    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.

    precision

    numeric

    false

    10

    The precision for the column.

    indexName

    string

    false

    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.

    precision

    numeric

    false

    The precision for the column.

    length

    numeric

    false

    255

    The length of the column.

    indexName

    string

    false

    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.

    precision

    numeric

    false

    The precision for the column.

    length

    numeric

    false

    255

    The length of the column.

    precision

    numeric

    false

    The precision for the column.

    precision

    numeric

    false

    The precision for the column.

    precision

    numeric

    false

    The precision for the column.

    precision

    numeric

    false

    The precision for the column.

    precision

    numeric

    false

    The precision for the column.

    bigIncrements

    bigInteger

    bit

    boolean

    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

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    sql

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    Argument

    Type

    Required

    Default

    Description

    name

    string

    true

    bigIncrements

    bigInteger

    bit

    boolean

    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

    indexes

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The prefix for the polymorphic columns.

    The prefix for the polymorphic columns.

    The sql to insert directly into the statement.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name for the column.

    The name 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`)
    )