mirror of
https://github.com/knex/knex.git
synced 2025-07-06 08:30:38 +00:00
2967 lines
106 KiB
HTML
2967 lines
106 KiB
HTML
<!DOCTYPE HTML>
|
||
<html>
|
||
<head>
|
||
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
|
||
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
|
||
<meta name="viewport" content="width=device-width">
|
||
<link rel="canonical" href="http://knexjs.org" />
|
||
<link rel="icon" href="docs/images/favicon.ico" />
|
||
<link rel="stylesheet" href="docs/assets/style.css" />
|
||
<link rel="stylesheet" href="docs/assets/highlight.min.css" />
|
||
<title>Knex.js - A SQL Query Builder for Javascript</title>
|
||
<!--
|
||
._____. ______
|
||
| | / /
|
||
| | / /
|
||
| | _____ ._____ ._____. ,_____________. ______ / /
|
||
| | / / | \ | | / \ \ \ / /
|
||
| | / / | \ | | / \ \ \ / /
|
||
| | / / | \ | | / ,______. \ \ \ / /
|
||
| | / / | \ | | / / \ \ \ \/ /
|
||
| |/ \ | \ | | | | ____\ | \ /
|
||
| |\ \ | \| | | | / | \ \
|
||
| | \ \ | |\ | | | /__________| / \
|
||
| | \ \ | | \ | \ \ / /\ \
|
||
| | \ \ | | \ | \ \__________/\ / / \ \
|
||
| | \ \ | | \ | \ \ / / \ \
|
||
|_____| \_____\ |_____| \______| \_______________/ /_____/ \_____\
|
||
-->
|
||
</head>
|
||
<body>
|
||
|
||
<div id="sidebar" class="interface">
|
||
|
||
<a class="toc_title" href="#">
|
||
Knex.js <span class="version">(0.7.2)</span>
|
||
</a>
|
||
<ul class="toc_section">
|
||
<li>» <a href="https://github.com/tgriesser/knex">GitHub Repository</a></li>
|
||
<li>» <a href="#support">Support</a></li>
|
||
<li>» <a href="#faq">FAQ</a></li>
|
||
<li>» <a href="#changelog">Change Log</a></li>
|
||
</ul>
|
||
|
||
<a class="toc_title" href="#Upgrading">
|
||
Upgrading
|
||
</a>
|
||
<ul class="toc_section">
|
||
<li>– <a href="#Upgrading-from0.5">0.5.x -> 0.6</a></li>
|
||
<li>– <a href="#Upgrading-from0.4">0.4.x -> 0.5</a></li>
|
||
</ul>
|
||
|
||
<a class="toc_title" href="#Installation">
|
||
Installation
|
||
</a>
|
||
<ul class="toc_section">
|
||
<li>– <a href="#Installation-node">Node.js</a></li>
|
||
<li>– <a href="#Installation-browser">Browser</a></li>
|
||
<li><b><a href="#Installation-client">Config Options:</a></b></li>
|
||
<li> – <a href="#Installation-client">client</a></li>
|
||
<li> – <a href="#Installation-debug">debug</a></li>
|
||
<li> – <a href="#Installation-pooling">pooling</a></li>
|
||
<li> – <a href="#Installation-migrations">migrations</a></li>
|
||
</ul>
|
||
|
||
<a class="toc_title" href="#Builder">
|
||
Query Builder
|
||
</a>
|
||
<ul class="toc_section">
|
||
<li>– <a href="#Builder-main"><b>constructor</b></a></li>
|
||
<li>– <a href="#Builder-select">select</a></li>
|
||
<li>– <a href="#Builder-as">as</a></li>
|
||
<li>– <a href="#Builder-column">column</a></li>
|
||
<li>– <a href="#Builder-from">from</a></li>
|
||
|
||
<li><b><a href="#Builder-wheres">Where Methods:</a></b></li>
|
||
<li> - <a href="#Builder-where">where</a></li>
|
||
<li> - <a href="#Builder-whereIn">whereIn</a></li>
|
||
<li> - <a href="#Builder-whereNotIn">whereNotIn</a></li>
|
||
<li> - <a href="#Builder-whereNull">whereNull</a></li>
|
||
<li> - <a href="#Builder-whereNotNull">whereNotNull</a></li>
|
||
<li> - <a href="#Builder-whereExists">whereExists</a></li>
|
||
<li> - <a href="#Builder-whereNotExists">whereNotExists</a></li>
|
||
<li> - <a href="#Builder-whereBetween">whereBetween</a></li>
|
||
<li> - <a href="#Builder-whereNotBetween">whereNotBetween</a></li>
|
||
<li> - <a href="#Builder-whereRaw">whereRaw</a></li>
|
||
|
||
<li><b><a href="#Builder-join">Join Methods:</a></b></li>
|
||
<li> – <a href="#Builder-innerJoin">innerJoin</a></li>
|
||
<li> – <a href="#Builder-leftJoin">leftJoin</a></li>
|
||
<li> – <a href="#Builder-leftOuterJoin">leftOuterJoin</a></li>
|
||
<li> – <a href="#Builder-rightJoin">rightJoin</a></li>
|
||
<li> – <a href="#Builder-rightOuterJoin">rightOuterJoin</a></li>
|
||
<li> – <a href="#Builder-outerJoin">outerJoin</a></li>
|
||
<li> – <a href="#Builder-fullOuterJoin">fullOuterJoin</a></li>
|
||
<li> – <a href="#Builder-crossJoin">crossJoin</a></li>
|
||
<li> – <a href="#Builder-joinRaw">joinRaw</a></li>
|
||
|
||
<li>– <a href="#Builder-distinct">distinct</a></li>
|
||
<li>– <a href="#Builder-groupBy">groupBy</a></li>
|
||
<li>– <a href="#Builder-groupByRaw">groupByRaw</a></li>
|
||
<li>– <a href="#Builder-orderBy">orderBy</a></li>
|
||
<li>– <a href="#Builder-orderByRaw">orderByRaw</a></li>
|
||
<li>– <a href="#Builder-having">having</a></li>
|
||
<li>– <a href="#Builder-offset">offset</a></li>
|
||
<li>– <a href="#Builder-limit">limit</a></li>
|
||
<li>– <a href="#Builder-union">union</a></li>
|
||
<li>– <a href="#Builder-unionAll">unionAll</a></li>
|
||
<li>– <a href="#Builder-insert">insert</a></li>
|
||
<li>– <a href="#Builder-returning">returning</a></li>
|
||
<li>– <a href="#Builder-update">update</a></li>
|
||
<li>– <a href="#Builder-del">del / delete</a></li>
|
||
<li>– <a href="#Builder-transacting">transacting</a></li>
|
||
<li> – <a href="#Builder-forUpdate">forUpdate</a></li>
|
||
<li> – <a href="#Builder-forShare">forShare</a></li>
|
||
<li>– <a href="#Builder-count">count</a></li>
|
||
<li>– <a href="#Builder-min">min</a></li>
|
||
<li>– <a href="#Builder-max">max</a></li>
|
||
<li>– <a href="#Builder-sum">sum</a></li>
|
||
<li>– <a href="#Builder-increment">increment</a></li>
|
||
<li>– <a href="#Builder-decrement">decrement</a></li>
|
||
<li>– <a href="#Builder-truncate">truncate</a></li>
|
||
<li>– <a href="#Builder-pluck">pluck</a></li>
|
||
<li>– <a href="#Builder-first">first</a></li>
|
||
<li>– <a href="#Builder-clone">clone</a></li>
|
||
<li>– <a href="#Builder-columnInfo">columnInfo</a></li>
|
||
<li>– <a href="#Builder-debug">debug</a></li>
|
||
<li>– <a href="#Builder-connection">connection</a></li>
|
||
<li>– <a href="#Builder-options">options</a></li>
|
||
</ul>
|
||
|
||
<a class="toc_title" href="#Transactions">
|
||
Transactions
|
||
</a>
|
||
<ul class="toc_section">
|
||
<li>– <a href="#Transactions"><b>overview</b></a></li>
|
||
</ul>
|
||
|
||
<a class="toc_title" href="#Schema">
|
||
Schema Builder
|
||
</a>
|
||
<ul class="toc_section">
|
||
<li>– <a href="#Schema-createTable">createTable</a></li>
|
||
<li>– <a href="#Schema-renameTable">renameTable</a></li>
|
||
<li>– <a href="#Schema-dropTable">dropTable</a></li>
|
||
<li>– <a href="#Schema-hasColumn">hasColumn</a></li>
|
||
<li>– <a href="#Schema-hasTable">hasTable</a></li>
|
||
<li>– <a href="#Schema-dropTableIfExists">dropTableIfExists</a></li>
|
||
<li>– <a href="#Schema-table">table</a></li>
|
||
<li>– <a href="#Schema-raw">raw</a></li>
|
||
<li><b><a href="#Schema-Building">Schema Building:</a></b></li>
|
||
<li>– <a href="#Schema-dropColumn">dropColumn</a></li>
|
||
<li>– <a href="#Schema-dropColumns">dropColumns</a></li>
|
||
<li>– <a href="#Schema-renameColumn">renameColumn</a></li>
|
||
<li>– <a href="#Schema-increments">increments</a></li>
|
||
<li>– <a href="#Schema-integer">integer</a></li>
|
||
<li>– <a href="#Schema-bigInteger">bigInteger</a></li>
|
||
<li>– <a href="#Schema-text">text</a></li>
|
||
<li>– <a href="#Schema-string">string</a></li>
|
||
<li>– <a href="#Schema-float">float</a></li>
|
||
<li>– <a href="#Schema-decimal">decimal</a></li>
|
||
<li>– <a href="#Schema-boolean">boolean</a></li>
|
||
<li>– <a href="#Schema-date">date</a></li>
|
||
<li>– <a href="#Schema-dateTime">dateTime</a></li>
|
||
<li>– <a href="#Schema-time">time</a></li>
|
||
<li>– <a href="#Schema-timestamp">timestamp</a></li>
|
||
<li>– <a href="#Schema-timestamps">timestamps</a></li>
|
||
<li>– <a href="#Schema-binary">binary</a></li>
|
||
<li>– <a href="#Schema-enum">enum / enu</a></li>
|
||
<li>– <a href="#Schema-json">json</a></li>
|
||
<li>– <a href="#Schema-uuid">uuid</a></li>
|
||
<li>– <a href="#Schema-comment">comment</a></li>
|
||
<li>– <a href="#Schema-engine">engine</a></li>
|
||
<li>– <a href="#Schema-charset">charset</a></li>
|
||
<li>– <a href="#Schema-collate">collate</a></li>
|
||
<li>– <a href="#Schema-specificType">specificType</a></li>
|
||
<li><a href="#Chainable"><b>Chainable:</b></li>
|
||
<li>– <a href="#Chainable-index">index</a></li>
|
||
<li>– <a href="#Chainable-primary">primary</a></li>
|
||
<li>– <a href="#Chainable-unique">unique</a></li>
|
||
<li>– <a href="#Chainable-references">references</a></li>
|
||
<li>– <a href="#Chainable-inTable">inTable</a></li>
|
||
<li>– <a href="#Chainable-onDelete">onDelete</a></li>
|
||
<li>– <a href="#Chainable-onUpdate">onUpdate</a></li>
|
||
<li>– <a href="#Chainable-defaultTo">defaultTo</a></li>
|
||
<li>– <a href="#Chainable-unsigned">unsigned</a></li>
|
||
<li>– <a href="#Chainable-notNullable">notNullable</a></li>
|
||
<li>– <a href="#Chainable-nullable">nullable</a></li>
|
||
<li>– <a href="#Chainable-first">first</a></li>
|
||
<li>– <a href="#Chainable-after">after</a></li>
|
||
<li>– <a href="#Chainable-comment">comment</a></li>
|
||
</ul>
|
||
|
||
<a class="toc_title" href="#Raw">
|
||
Raw
|
||
</a>
|
||
<ul class="toc_section">
|
||
<li>– <a href="#Raw-Expressions">Raw Expressions</a></li>
|
||
<li>– <a href="#Raw-Queries">Raw Queries</a></li>
|
||
<li>- <a href="#Raw-queries-wrapped">Wrapped Queries</a></li>
|
||
</ul>
|
||
|
||
<a class="toc_title" href="#Interfaces">
|
||
Interfaces
|
||
</a>
|
||
<ul class="toc_section">
|
||
<li><b><a href="#Interfaces-Promises">Promises</a></b></li>
|
||
<li> – <a href="#Promises-then">then</a></li>
|
||
<li> – <a href="#Promises-catch">catch</a></li>
|
||
<li> – <a href="#Promises-tap">tap</a></li>
|
||
<li> – <a href="#Promises-map">map</a></li>
|
||
<li> – <a href="#Promises-reduce">reduce</a></li>
|
||
<li> – <a href="#Promises-bind">bind</a></li>
|
||
<li> – <a href="#Promises-return">return</a></li>
|
||
<li><b><a href="#Interfaces-Callbacks">Callbacks</a></b></li>
|
||
<li> – <a href="#Interfaces-exec">exec</a></li>
|
||
<li><b><a href="#Interfaces-Streams">Streams</a></b></li>
|
||
<li> – <a href="#Streams-stream">stream</a></li>
|
||
<li> – <a href="#Streams-pipe">pipe</a></li>
|
||
<li><b><a href="#Interfaces-Events">Events</a></b></li>
|
||
<li> – <a href="#Events-query">query</a></li>
|
||
<li><b><a href="#Interfaces-Other">Other:</a></b></li>
|
||
<li> – <a href="#Other-toString">toString</a></li>
|
||
<li> – <a href="#Other-toSQL">toSQL</a></li>
|
||
</ul>
|
||
|
||
<a class="toc_title" href="#Migrations">
|
||
Migrations
|
||
</a>
|
||
|
||
<ul class="toc_section">
|
||
<li><a href="#Migrations-CLI"><b>CLI</b></li>
|
||
<li>– <a href="#Migrations-CLI">Migrations</a></li>
|
||
<li>– <a href="#Seeds-CLI">Seed files</a></li>
|
||
<li>– <a href="#knexfile">knexfile.js</a></li>
|
||
<li><a href="#Migrations-API"><b>Migration API</b></li>
|
||
<li>– <a href="#Migrations-make">make</a></li>
|
||
<li>– <a href="#Migrations-latest">latest</a></li>
|
||
<li>– <a href="#Migrations-rollback">rollback</a></li>
|
||
<li>– <a href="#Migrations-currentVersion">currentVersion</a></li>
|
||
<li><a href="#Seeds-API"><b>Seed API</b></li>
|
||
<li>– <a href="#Seeds-make">make</a></li>
|
||
<li>– <a href="#Seeds-run">run</a></li>
|
||
</ul>
|
||
|
||
<a class="toc_title" href="#support">
|
||
Support
|
||
</a>
|
||
|
||
<a class="toc_title" href="#faq">
|
||
F.A.Q.
|
||
</a>
|
||
|
||
<a class="toc_title" href="#changelog">
|
||
Change Log
|
||
</a>
|
||
|
||
</div>
|
||
|
||
<div class="language">
|
||
Show example query output as:<br />
|
||
<select class="js-query-output">
|
||
<option value="mysql">MySQL / MariaDB</option>
|
||
<option value="pg">PostgreSQL</option>
|
||
<option value="sqlite3">SQLite3</option>
|
||
<option value="oracle">Oracle (experimental)</option>
|
||
</select>
|
||
</div>
|
||
|
||
<a href="https://github.com/tgriesser/knex"><img style="position: fixed; top: 0; right: 0; border: 0;" src="docs/images/github.png" alt="Fork me on GitHub"></a>
|
||
|
||
<div class="container">
|
||
|
||
<p>
|
||
<img id="logo" src="docs/images/knex.png" alt="Knex.js">
|
||
</p>
|
||
|
||
<p>
|
||
<b>Knex.js</b> is a "batteries included" SQL query builder for <b>Postgres</b>, <b>MySQL</b>, <b>MariaDB</b> and <b>SQLite3</b>, designed to be flexible,
|
||
portable, and fun to use. It features both traditional node style <a href="#Interfaces-Callbacks">callbacks</a>
|
||
as well as a <a href="#Interfaces-Promises">promise</a> interface for cleaner async flow control, <a href="#Interfaces-Streams">a stream interface</a>, full featured <a href="#Builder">query</a> and <a href="#Schema">schema</a> builders, <a href="#Transaction-overview"><b>transaction support</b></a>, connection <a href="#Installation-pooling">pooling</a> and standardized responses between
|
||
different query clients and dialects.
|
||
</p>
|
||
|
||
<p>
|
||
The project is <a href="http://github.com/tgriesser/knex">hosted on GitHub</a>,
|
||
and has a comprehensive <a href="https://travis-ci.org/tgriesser/knex">test suite</a>.
|
||
</p>
|
||
|
||
<p>
|
||
Knex is available for use under the <a href="http://github.com/tgriesser/knex/blob/master/LICENSE">MIT software license</a>.
|
||
</p>
|
||
|
||
<p>
|
||
You can report bugs and discuss features on the
|
||
<a href="http://github.com/tgriesser/knex/issues">GitHub issues page</a>,
|
||
add pages to the <a href="https://github.com/tgriesser/knex/wiki">wiki</a>
|
||
or send tweets to <a href="http://twitter.com/tgriesser">@tgriesser</a>.
|
||
</p>
|
||
|
||
<p>
|
||
Thanks to all of the great <a href="https://github.com/tgriesser/knex/graphs/contributors">contributions</a> to the project.
|
||
</a>
|
||
|
||
<p class="warning">
|
||
Special thanks to <a href="https://twitter.com/taylorotwell">Taylor Otwell</a> and his work
|
||
on the <a href="http://laravel.com/docs/queries">Laravel Query Builder</a>,
|
||
from which much of the builder's code and syntax was originally derived.
|
||
</p>
|
||
|
||
|
||
<h2>Latest Release: 0.7.2 - <span class="small"><a href="#changelog">Change Log</a></span></h2>
|
||
|
||
<p>
|
||
Current Develop —
|
||
<a href="https://travis-ci.org/tgriesser/knex">
|
||
<img src="https://travis-ci.org/tgriesser/knex.png?branch=master" alt="Travis Badge">
|
||
</a>
|
||
</p>
|
||
|
||
<h2 id="Upgrading">Upgrading</h2>
|
||
|
||
<h3 id="Upgrading-from0.6">Upgrading 0.6 -> 0.7</h3>
|
||
|
||
<p>
|
||
Should be a painless upgrade, the only breaking change should be "collate nocase"
|
||
no longer used as the default <tt>order by</tt> in sqlite3
|
||
for <a href="https://github.com/tgriesser/knex/pull/396">performance reasons</a>.
|
||
If there are other issues, please <a href="https://github.com/tgriesser/knex/issues">open a ticket</a>.
|
||
</p>
|
||
|
||
|
||
<h3 id="Upgrading-from0.5">Upgrading 0.5 -> 0.6</h3>
|
||
|
||
<p>
|
||
Big and exciting improvements from the 0.5 release, the 0.6 release brings refactored internals, streams, the ability
|
||
to properly inject & bind knex.raw statements throughout any queries, the ability to re-use existing snippets.
|
||
If you were only using the publicly documented API, no major changes should be necessary. If you notice any issues,
|
||
please <a href="https://github.com/tgriesser/knex/issues">open a ticket</a>. For a full list of changes, see the entry in the <a href="#release-0.6.0">change log.</a>
|
||
</p>
|
||
|
||
<h2 id="Installation">
|
||
Installation
|
||
</h2>
|
||
|
||
<p>Knex can be used as an SQL query builder in both Node.JS and the browser, limited to WebSQL's constraints (like the inability to drop tables or read schemas). Composing SQL queries in the browser for execution on the server is highly discouraged, as this can be the cause of serious security vulnerabilities. The browser builds outside of WebSQL are primarily for learning purposes - for example, you can pop open the console and build queries on this page using the <a href="javascript:alert(pg)">pg</a>, <a href="javascript:alert(mysql)">mysql</a>, and <a href="javascript:alert(sqlite3)">sqlite3</a> objects.</p>
|
||
|
||
<h3 id="Installation-node">Node.js</h3>
|
||
|
||
<p>
|
||
The primary target environment for Knex is Node.js, you will need to install the <tt>knex</tt> library,
|
||
and then install the appropriate database library: <tt><a href="https://github.com/brianc/node-postgres">pg</a></tt> for PostgreSQL, <tt><a href="https://github.com/felixge/node-mysql">mysql</a></tt> for MySQL or MariaDB, or <a href="https://github.com/mapbox/node-sqlite3"><tt>sqlite3</tt></a> for SQLite3.
|
||
</p>
|
||
|
||
<pre>
|
||
$ npm install knex@0.6 --save
|
||
|
||
# Then add one of the following (adding a --save) flag:
|
||
$ npm install mysql
|
||
$ npm install mariasql
|
||
$ npm install pg
|
||
$ npm install sqlite3
|
||
</pre>
|
||
|
||
<h3 id="Installation-browser">Browser</h3>
|
||
|
||
<p>
|
||
The browser builds and pre-built dependencies can be found in the <a href="https://github.com/tgriesser/knex/tree/master/browser">browser directory</a>. View source on this page to see the browser builds in-action.
|
||
</p>
|
||
|
||
<h3 id="Installation-client">Initializing the Library</h3>
|
||
|
||
<p>
|
||
The <tt>knex</tt> module is its self a function which takes a configuration object for
|
||
Knex, accepting a few parameters. The <tt>client</tt> parameter is required
|
||
and determines which client adapter will be used with the library.
|
||
</p>
|
||
|
||
<pre>
|
||
<code class="js">var knex = require('knex')({
|
||
client: 'mysql',
|
||
connection: {
|
||
host : '127.0.0.1',
|
||
user : 'your_database_user',
|
||
password : 'your_database_password',
|
||
database : 'myapp_test'
|
||
}
|
||
});
|
||
</code>
|
||
</pre>
|
||
|
||
<p>
|
||
The connection options are passed directly to the appropriate database client to create the connection, and may be either an object, or a connection string:
|
||
</p>
|
||
|
||
<pre>
|
||
<code class="js">var pg = require('knex')({
|
||
client: 'pg',
|
||
connection: process.env.PG_CONNECTION_STRING
|
||
});
|
||
</code>
|
||
</pre>
|
||
|
||
<p class="warning">
|
||
Note: When you use the SQLite3 adapter, there is a filename required, not a network connection. For example:
|
||
</p>
|
||
|
||
<pre>
|
||
<code class="js">var knex = require('knex')({
|
||
client: 'sqlite3',
|
||
connection: {
|
||
filename: "./mydb.sqlite"
|
||
}
|
||
});
|
||
</code>
|
||
</pre>
|
||
|
||
<p class="warning">
|
||
Initializing the library should normally only ever happen once in your application, as it creates a connection pool
|
||
for the current database, you should use the instance returned from the initialize call throughout
|
||
your library.
|
||
</p>
|
||
|
||
<h3 id="Installation-debug">Debugging</h3>
|
||
|
||
<p>
|
||
Passing a <tt>debug: true</tt> flag on your initialization object will turn on <a href="#Builder-debug">debugging</a> for all queries.
|
||
</p>
|
||
|
||
<h3 id="Installation-pooling">Pooling</h3>
|
||
|
||
<p>
|
||
The client created by the configuration initializes a connection pool, using the <a href="https://github.com/bookshelf/generic-pool-redux">generic-pool-redux</a> library. This connection pool has a default setting of a <tt>min: 2, max: 10</tt> for the MySQL and PG libraries, and a single connection for sqlite3 (due to issues with utilizing multiple connections on a single file). To change the config settings for the pool, pass a <tt>pool</tt> option as one of the keys in the initialize block.
|
||
</p>
|
||
|
||
<pre>
|
||
<code class="js">var knex = require('knex')({
|
||
client: 'mysql',
|
||
connection: {
|
||
host : '127.0.0.1',
|
||
user : 'your_database_user',
|
||
password : 'your_database_password',
|
||
database : 'myapp_test'
|
||
},
|
||
pool: {
|
||
min: 0,
|
||
max: 7
|
||
}
|
||
});
|
||
</code>
|
||
</pre>
|
||
|
||
<p>
|
||
If you ever need to explicitly teardown the connection pool, you may use <tt>knex.destroy([callback])</tt>.
|
||
You may use <tt>knex.destroy</tt> by passing a callback, or by chaining as a promise, just not both.
|
||
</p>
|
||
|
||
<h3 id="Installation-migrations">Migrations</h3>
|
||
|
||
<p>
|
||
For convenience, the any migration configuration may be specified when initializing the library. Read the <a href="#Migrations">Migrations</a> section for more information and a full list of configuration options.
|
||
</p>
|
||
|
||
<pre>
|
||
<code class="js">var knex = require('knex')({
|
||
client: 'mysql',
|
||
connection: {
|
||
host : '127.0.0.1',
|
||
user : 'your_database_user',
|
||
password : 'your_database_password',
|
||
database : 'myapp_test'
|
||
},
|
||
migrations: {
|
||
tableName: 'migrations'
|
||
}
|
||
});
|
||
</code>
|
||
</pre>
|
||
|
||
<h2 id="Builder">Knex Query Builder</h2>
|
||
|
||
<p>
|
||
The heart of the library, the knex query builder is the interface used for building
|
||
and executing standard SQL queries, such as <tt>select</tt>, <tt>insert</tt>, <tt>update</tt>, <tt>delete</tt>.
|
||
</p>
|
||
|
||
<p id="Builder-main">
|
||
<b class="header">knex</b><code>knex(tableName) / knex.[methodName]</code>
|
||
<br />
|
||
The query builder starts off either by specifying a <b>tableName</b> you wish to query against,
|
||
or by calling any method directly on the knex object. This kicks off a jQuery-like chain, with which
|
||
you can call additional query builder methods as needed to construct the query, eventually calling any of the
|
||
<a href="#Interfaces">interface methods</a>, to either convert toString, or execute the
|
||
query with a <a href="#Interfaces-Promises">promise</a>, <a href="#Interfaces-Callbacks">callback</a>, or <a href="#Interfaces-Streams">stream</a>.
|
||
</p>
|
||
|
||
<p id="Builder-select">
|
||
<b class="header">select</b><code>.select([*columns])</code>
|
||
<br />
|
||
Creates a <tt>select</tt> query, taking an optional array of <b>columns</b> for the query, eventually
|
||
defaulting to <tt>*</tt> if none are specified when the query is built. The response of a select call will
|
||
resolve with an array of objects selected from the database.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.select('title', 'author', 'year').from('books')
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
knex.select().table('books')
|
||
</pre>
|
||
|
||
<p id="Builder-as">
|
||
<b class="header">as</b><code>.as(name)</code>
|
||
<br />
|
||
Allows for aliasing a subquery, taking the string you wish to <b>name</b> the current query.
|
||
If the query is not a sub-query, it will be ignored.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.avg('sum_column1').from(function() {
|
||
this.sum('column1 as sum_column1').from('t1').groupBy('column1').as('t1')
|
||
}).as('ignored_alias')
|
||
</pre>
|
||
|
||
<p id="Builder-column">
|
||
<b class="header">column</b><code>.column(columns)</code>
|
||
<br />
|
||
Specifically set the <b>columns</b> to be selected on a select query, taking an array or a list of of column names.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.column('title', 'author', 'year').select().from('books')
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
knex.column(['title', 'author', 'year']).select().from('books')
|
||
</pre>
|
||
|
||
<p id="Builder-from">
|
||
<b class="header">from</b><code>.from([tableName])</code> <span class="alias">Alias: <b>into</b>, <b>table</b></span>
|
||
<br />
|
||
Specifies the table used in the current query, replacing the current table name if
|
||
one has already been specified. This is typically used in the sub-queries performed
|
||
in the advanced <a href="#Builder-where">where</a> or <a href="#Builder-union">union</a> methods.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.select('*').from('users')
|
||
</pre>
|
||
|
||
<h3 id="Builder-wheres">Where Clauses</h3>
|
||
|
||
<p>
|
||
Several methods exist to assist in dynamic where clauses. In many places functions may be used in place of values,
|
||
constructing subqueries. In most places existing knex queries may be used to compose sub-queries, etc. Take a look at a few of the examples for each method for instruction on use:
|
||
</p>
|
||
|
||
<p id="Builder-where">
|
||
<b class="header">where</b><code>.where(~mixed~)</code>
|
||
</p>
|
||
|
||
<p class="title">Object Syntax:</p>
|
||
|
||
<pre class="display">
|
||
knex('users').where({
|
||
first_name: 'Test',
|
||
last_name: 'User'
|
||
}).select('id')
|
||
</pre>
|
||
|
||
<p class="title">Key, Value:</p>
|
||
|
||
<pre class="display">
|
||
knex('users').where('id', 1)
|
||
</pre>
|
||
|
||
<p class="title">Grouped Chain:</p>
|
||
|
||
<pre class="display">
|
||
knex('users').where(function() {
|
||
this.where('id', 1).orWhere('id', '>', 10)
|
||
}).orWhere({name: 'Tester'})
|
||
</pre>
|
||
|
||
<p class="title">Operator:</p>
|
||
|
||
<pre class="display">
|
||
knex('users').where('votes', '>', 100)
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
var subquery = knex('users').where('votes', '>', 100).andWhere('status', 'active').orWhere('name', 'John').select('id');
|
||
|
||
knex('accounts').where('id', 'in', subquery)
|
||
</pre>
|
||
|
||
<p id="Builder-whereIn">
|
||
<b class="header">whereIn</b><code>.whereIn(column, array|callback|builder) / .orWhereIn</code><br />
|
||
Shorthand for <tt>.where('id', 'in', obj)</tt>, the .whereIn and .orWhereIn methods add a "where in" clause
|
||
to the query. Click the "play" button below to see the queries.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.select('name').from('users')
|
||
.whereIn('id', [1, 2, 3])
|
||
.orWhereIn('id', [4, 5, 6])
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
knex.select('name').from('users')
|
||
.whereIn('account_id', function() {
|
||
this.select('id').from('accounts');
|
||
})
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
var subquery = knex.select('id').from('accounts');
|
||
|
||
knex.select('name').from('users')
|
||
.whereIn('account_id', subquery)
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
knex('users')
|
||
.where('name', '=', 'John')
|
||
.orWhere(function() {
|
||
this.where('votes', '>', 100).andWhere('title', '<>', 'Admin');
|
||
})
|
||
</pre>
|
||
|
||
<p id="Builder-whereNotIn">
|
||
<b class="header">whereNotIn</b><code>.whereNotIn(column, array|callback|builder) / .orWhereNotIn</code>
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('users').whereNotIn('id', [1, 2, 3])
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
knex('users').where('name', 'like', '%Test%').orWhereNotIn('id', [1, 2, 3])
|
||
</pre>
|
||
|
||
<p id="Builder-whereNull">
|
||
<b class="header">whereNull</b><code>.whereNull(column) / .orWhereNotNull</code>
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('users').whereNull('updated_at')
|
||
</pre>
|
||
|
||
<p id="Builder-whereNotNull">
|
||
<b class="header">whereNotNull</b><code>.whereNotNull(column) / .orWhereNotNull</code>
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('users').whereNotNull('created_at')
|
||
</pre>
|
||
|
||
<p id="Builder-whereExists">
|
||
<b class="header">whereExists</b><code>.whereExists(builder | callback) / .orWhereExists</code>
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('users').whereExists(function() {
|
||
this.select('*').from('accounts').whereRaw('users.account_id = accounts.id');
|
||
})
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
knex('users').whereExists(knex.select('*').from('accounts').whereRaw('users.account_id = accounts.id'))
|
||
</pre>
|
||
|
||
<p id="Builder-whereNotExists">
|
||
<b class="header">whereNotExists</b><code>.whereNotExists(builder | callback) / .orWhereNotExists</code>
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('users').whereNotExists(function() {
|
||
this.select('*').from('accounts').whereRaw('users.account_id = accounts.id');
|
||
})
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
knex('users').whereNotExists(knex.select('*').from('accounts').whereRaw('users.account_id = accounts.id'))
|
||
</pre>
|
||
|
||
<p id="Builder-whereBetween">
|
||
<b class="header">whereBetween</b><code>.whereBetween(column, range) / .orWhereBetween</code>
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('users').whereBetween('votes', [1, 100])
|
||
</pre>
|
||
|
||
<p id="Builder-whereNotBetween">
|
||
<b class="header">whereNotBetween</b><code>.whereNotBetween(column, range) / .orWhereNotBetween</code>
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('users').whereNotBetween('votes', [1, 100])
|
||
</pre>
|
||
|
||
<p id="Builder-whereRaw">
|
||
<b class="header">whereRaw</b><code>.whereRaw(query, [bindings])</code>
|
||
<br />
|
||
Convenience helper for <tt>.where(knex.raw(query))</tt>.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('users').whereRaw('id = ?', [1])
|
||
</pre>
|
||
|
||
<h3>Join Methods</h3>
|
||
|
||
<p>
|
||
Several methods are provided which assist in building
|
||
</p>
|
||
|
||
<p id="Builder-join">
|
||
<b class="header">join</b><code>.join(table, first, [operator], second)</code>
|
||
<br />
|
||
The <tt>join</tt> builder can be used to specify joins between tables,
|
||
with the first argument being the joining <b>table</b>, the next three arguments
|
||
being the <b>first</b> join column, the join <b>operator</b> and the <b>second</b>
|
||
join column, respectively.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('users')
|
||
.join('contacts', 'users.id', '=', 'contacts.user_id')
|
||
.select('users.id', 'contacts.phone')
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
knex('users')
|
||
.join('contacts', 'users.id', 'contacts.user_id')
|
||
.select('users.id', 'contacts.phone')
|
||
</pre>
|
||
|
||
|
||
<p>
|
||
For grouped joins, specify a function as the second argument for the
|
||
join query, and use <tt>on</tt> and <tt>orOn</tt> to create joins that are
|
||
grouped with parentheses.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.select('*').from('users').join('accounts', function() {
|
||
this.on('accounts.id', '=', 'users.account_id').orOn('accounts.owner_id', '=', 'users.id')
|
||
})
|
||
</pre>
|
||
|
||
<p id="Builder-innerJoin">
|
||
<b class="header">innerJoin</b><code>.innerJoin(column, ~mixed~)</code>
|
||
<br>
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.from('users').innerJoin('accounts', 'users.id', 'accounts.user_id')
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
knex.table('users').innerJoin('accounts', 'users.id', '=', 'accounts.user_id')
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
knex('users').innerJoin('accounts', function() {
|
||
this.on('accounts.id', '=', 'users.account_id').orOn('accounts.owner_id', '=', 'users.id')
|
||
})
|
||
</pre>
|
||
|
||
<p id="Builder-leftJoin">
|
||
<b class="header">leftJoin</b><code>.leftJoin(column, ~mixed~)</code>
|
||
<br>
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.select('*').from('users').leftJoin('accounts', 'users.id', 'accounts.user_id')
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
knex.select('*').from('users').leftJoin('accounts', function() {
|
||
this.on('accounts.id', '=', 'users.account_id').orOn('accounts.owner_id', '=', 'users.id')
|
||
})
|
||
</pre>
|
||
|
||
<p id="Builder-leftOuterJoin">
|
||
<b class="header">leftOuterJoin</b><code>.leftOuterJoin(column, ~mixed~)</code>
|
||
<br>
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.select('*').from('users').leftOuterJoin('accounts', 'users.id', 'accounts.user_id')
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
knex.select('*').from('users').leftOuterJoin('accounts', function() {
|
||
this.on('accounts.id', '=', 'users.account_id').orOn('accounts.owner_id', '=', 'users.id')
|
||
})
|
||
</pre>
|
||
|
||
<p id="Builder-rightJoin">
|
||
<b class="header">rightJoin</b><code>.rightJoin(column, ~mixed~)</code>
|
||
<br>
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.select('*').from('users').rightJoin('accounts', 'users.id', 'accounts.user_id')
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
knex.select('*').from('users').rightJoin('accounts', function() {
|
||
this.on('accounts.id', '=', 'users.account_id').orOn('accounts.owner_id', '=', 'users.id')
|
||
})
|
||
</pre>
|
||
|
||
<p id="Builder-rightOuterJoin">
|
||
<b class="header">rightOuterJoin</b><code>.rightOuterJoin(column, ~mixed~)</code>
|
||
<br>
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.select('*').from('users').rightOuterJoin('accounts', 'users.id', 'accounts.user_id')
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
knex.select('*').from('users').rightOuterJoin('accounts', function() {
|
||
this.on('accounts.id', '=', 'users.account_id').orOn('accounts.owner_id', '=', 'users.id')
|
||
})
|
||
</pre>
|
||
|
||
<p id="Builder-outerJoin">
|
||
<b class="header">outerJoin</b><code>.outerJoin(column, ~mixed~)</code>
|
||
<br>
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.select('*').from('users').outerJoin('accounts', 'users.id', 'accounts.user_id')
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
knex.select('*').from('users').outerJoin('accounts', function() {
|
||
this.on('accounts.id', '=', 'users.account_id').orOn('accounts.owner_id', '=', 'users.id')
|
||
})
|
||
</pre>
|
||
|
||
<p id="Builder-fullOuterJoin">
|
||
<b class="header">fullOuterJoin</b><code>.fullOuterJoin(column, ~mixed~)</code>
|
||
<br>
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.select('*').from('users').fullOuterJoin('accounts', 'users.id', 'accounts.user_id')
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
knex.select('*').from('users').fullOuterJoin('accounts', function() {
|
||
this.on('accounts.id', '=', 'users.account_id').orOn('accounts.owner_id', '=', 'users.id')
|
||
})
|
||
</pre>
|
||
|
||
<p id="Builder-crossJoin">
|
||
<b class="header">crossJoin</b><code>.crossJoin(column, ~mixed~)</code>
|
||
<br>
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.select('*').from('users').crossJoin('accounts', 'users.id', 'accounts.user_id')
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
knex.select('*').from('users').crossJoin('accounts', function() {
|
||
this.on('accounts.id', '=', 'users.account_id').orOn('accounts.owner_id', '=', 'users.id')
|
||
})
|
||
</pre>
|
||
|
||
|
||
<p id="Builder-joinRaw">
|
||
<b class="header">joinRaw</b><code>.joinRaw(sql, [bindings])</code>
|
||
<br>
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.select('*').from('accounts').joinRaw('natural full join table1').where('id', 1)
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
knex.select('*').from('accounts').join(knex.raw('natural full join table1')).where('id', 1)
|
||
</pre>
|
||
|
||
<p id="Builder-distinct">
|
||
<b class="header">distinct</b><code>.distinct()</code>
|
||
<br />
|
||
Sets a <tt>distinct</tt> clause on the query.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
// select distinct 'first_name' from customers
|
||
knex('customers')
|
||
.distinct('first_name', 'last_name')
|
||
.select()
|
||
</pre>
|
||
|
||
<p id="Builder-groupBy">
|
||
<b class="header">groupBy</b><code>.groupBy(*names)</code>
|
||
<br />
|
||
Adds a <tt>group by</tt> clause to the query.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('users').groupBy('count')
|
||
</pre>
|
||
|
||
<p id="Builder-groupByRaw">
|
||
<b class="header">groupByRaw</b><code>.groupBy(sql)</code>
|
||
<br />
|
||
Adds a raw <tt>group by</tt> clause to the query.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.select('year', knex.raw('SUM(profit)')).from('sales').groupByRaw('year WITH ROLLUP')
|
||
</pre>
|
||
|
||
<p id="Builder-orderBy">
|
||
<b class="header">orderBy</b><code>.orderBy(column, [direction])</code>
|
||
<br />
|
||
Adds an <tt>order by</tt> clause to the query.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('users').orderBy('name', 'desc')
|
||
</pre>
|
||
|
||
<p id="Builder-orderByRaw">
|
||
<b class="header">orderByRaw</b><code>.orderByRaw(sql)</code>
|
||
<br />
|
||
Adds an <tt>order by raw</tt> clause to the query.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.select('*').from('table').orderByRaw('col NULLS LAST DESC')
|
||
</pre>
|
||
|
||
<p id="Builder-having">
|
||
<b class="header">having</b><code>.having(column, operator, value)</code>
|
||
<br />
|
||
Adds a <tt>having</tt> clause to the query.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('users')
|
||
.groupBy('count')
|
||
.orderBy('name', 'desc')
|
||
.having('count', '>', 100)
|
||
</pre>
|
||
|
||
<p id="Builder-havingRaw">
|
||
<b class="header">havingRaw</b><code>.havingRaw(column, operator, value)</code>
|
||
<br />
|
||
Adds a <tt>havingRaw</tt> clause to the query.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('users')
|
||
.groupBy('count')
|
||
.orderBy('name', 'desc')
|
||
.havingRaw('count > ?', [100])
|
||
</pre>
|
||
|
||
|
||
<p id="Builder-offset">
|
||
<b class="header">offset</b><code>.offset(value)</code>
|
||
<br />
|
||
Adds an <tt>offset</tt> clause to the query.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.select('*').from('users').offset(10)
|
||
</pre>
|
||
|
||
<p id="Builder-limit">
|
||
<b class="header">limit</b><code>.limit(value)</code>
|
||
<br />
|
||
Adds a <tt>limit</tt> clause to the query.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.select('*').from('users').limit(10).offset(30)
|
||
</pre>
|
||
|
||
<p id="Builder-union">
|
||
<b class="header">union</b><code>.union(query)</code>
|
||
<br />
|
||
Creates a <tt>union</tt> query, taking a callback to build the union statement.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.select('*').from('users').whereNull('last_name').union(function() {
|
||
this.select('*').from('users').whereNull('first_name');
|
||
})
|
||
</pre>
|
||
|
||
<p id="Builder-unionAll">
|
||
<b class="header">unionAll</b><code>.unionAll(query)</code>
|
||
<br />
|
||
Creates a <tt>union all</tt> query, with the same method signature as
|
||
the <a href="#Builder-union">union</a> method.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.select('*').from('users').whereNull('last_name').unionAll(function() {
|
||
this.select('*').from('users').whereNull('first_name');
|
||
})
|
||
</pre>
|
||
|
||
<p id="Builder-insert">
|
||
<b class="header">insert</b><code>.insert(data, [returning])</code>
|
||
<br />
|
||
Creates an <tt>insert</tt> query, taking either a hash of properties to be inserted into the row, or
|
||
an array of inserts, to be executed as a single insert command. Resolves the promise / fulfills the callback
|
||
with an array containing the first insert id of the inserted model, or an array containing all inserted <tt>ids</tt>
|
||
for postgresql.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
// Returns [1] in "mysql", "sqlite"; [] in "postgresql" unless the 'returning' parameter is set.
|
||
knex('books').insert({title: 'Slaughterhouse Five'})
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
// Normalizes for empty keys on multi-row insert:
|
||
knex('coords').insert([{x: 20}, {y: 30}, {x: 10, y: 20}])
|
||
</pre>
|
||
|
||
|
||
<pre class="display">
|
||
// Returns [2] in "mysql", "sqlite"; [2, 3] in "postgresql"
|
||
knex.insert([{title: 'Great Gatsby'}, {title: 'Fahrenheit 451'}], 'id').into('books')
|
||
</pre>
|
||
|
||
<p id="Builder-returning">
|
||
<b class="header">returning</b><code>.returning(column)</code>
|
||
<br />
|
||
Only utilitzed by PostgreSQL databases, the returning method specifies which column should be returned
|
||
by the <a href="#Builder-insert">insert</a> method.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
// Returns [1]
|
||
knex('books')
|
||
.returning('id')
|
||
.insert({title: 'Slaughterhouse Five'})
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
// Returns [2] in "mysql", "sqlite"; [2, 3] in "postgresql"
|
||
knex('books')
|
||
.returning('id')
|
||
.insert([{title: 'Great Gatsby'}, {title: 'Fahrenheit 451'}])
|
||
</pre>
|
||
|
||
<p id="Builder-update">
|
||
<b class="header">update</b><code>.update(data, [returning]) / .update(key, value, [returning])</code>
|
||
<br />
|
||
Creates an <tt>update</tt> query, taking a hash of properties or a key/value pair
|
||
to be updated based on the other query constraints. Resolves the promise / fulfills the
|
||
callback with the number of affected rows for the query.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('books')
|
||
.where('published_date', '<', 2000)
|
||
.update({
|
||
status: 'archived'
|
||
})
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
// Returns [1] in "mysql", "sqlite"; [] in "postgresql" unless the 'returning' parameter is set.
|
||
knex('books').update('title', 'Slaughterhouse Five')
|
||
</pre>
|
||
|
||
<p id="Builder-del">
|
||
<b class="header">del / delete</b><code>.del()</code>
|
||
<br />
|
||
Aliased to <tt>del</tt> as <tt>delete</tt> is a reserved word in javascript, this method deletes
|
||
one or more rows, based on other conditions specified in the query. Resolves the promise / fulfills the
|
||
callback with the number of affected rows for the query.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('accounts')
|
||
.where('activated', false)
|
||
.del()
|
||
</pre>
|
||
|
||
<p id="Builder-transacting">
|
||
<b class="header">transacting</b><code>.transacting(transactionObj)</code>
|
||
<br />
|
||
Used by <a href="#Transactions">knex.transaction</a>, the transacting method may be chained to any
|
||
query and passed the object you wish to join the query as part of the transaction for.
|
||
</p>
|
||
|
||
<pre>
|
||
<code class="js">var Promise = require('bluebird');
|
||
|
||
knex.transaction(function(trx) {
|
||
|
||
knex('books').transacting(trx).insert({name: 'Old Books'})
|
||
.then(function(resp) {
|
||
var id = resp[0];
|
||
return someExternalMethod(id, trx);
|
||
})
|
||
.then(trx.commit)
|
||
.then(trx.rollback);
|
||
|
||
}).then(function(resp) {
|
||
console.log('Transaction complete.');
|
||
}).catch(function(err) {
|
||
console.error(err);
|
||
});
|
||
</code>
|
||
</pre>
|
||
|
||
<p id="Builder-forUpdate">
|
||
<b class="header">forUpdate</b><code>.transacting(t).forUpdate()</code>
|
||
<br />
|
||
Dynamically added after a <a href="#Builder-transacting">transaction</a> is specified,
|
||
the <tt>forUpdate</tt> adds a <tt>FOR UPDATE</tt> in PostgreSQL and MySQL during a select statement.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('tableName')
|
||
.transacting(trx)
|
||
.forUpdate()
|
||
.select('*')
|
||
</pre>
|
||
|
||
<p id="Builder-forShare">
|
||
<b class="header">forShare</b><code>.transacting(t).forShare()</code>
|
||
<br />
|
||
Dynamically added after a <a href="#Builder-transacting">transaction</a> is specified,
|
||
the <tt>forShare</tt> adds a <tt>FOR SHARE</tt> in PostgreSQL and a <tt>LOCK IN SHARE MODE</tt>
|
||
for MySQL during a select statement.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('tableName')
|
||
.transacting(trx)
|
||
.forShare()
|
||
.select('*')
|
||
</pre>
|
||
|
||
<p id="Builder-count">
|
||
<b class="header">count</b><code>.count(column)</code>
|
||
<br />
|
||
Performs a count on the specified <b>column</b>.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('users').count('active')
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
knex('users').count('active as a')
|
||
</pre>
|
||
|
||
<p id="Builder-min">
|
||
<b class="header">min</b><code>.min(column)</code>
|
||
<br />
|
||
Gets the minimum value for the specified <b>column</b>.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('users').min('age')
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
knex('users').min('age as a')
|
||
</pre>
|
||
|
||
|
||
<p id="Builder-max">
|
||
<b class="header">max</b><code>.max(column)</code>
|
||
<br />
|
||
Gets the maximum value for the specified <b>column</b>.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('users').max('age')
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
knex('users').max('age as a')
|
||
</pre>
|
||
|
||
<p id="Builder-sum">
|
||
<b class="header">sum</b><code>.sum(column)</code>
|
||
<br />
|
||
Retrieve the sum of the values of a given <b>column</b>.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('users').sum('products')
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
knex('users').sum('products as p')
|
||
</pre>
|
||
|
||
<p id="Builder-avg">
|
||
<b class="header">avg</b><code>.avg(column)</code>
|
||
<br />
|
||
Retrieve the average of the values of a given <b>column</b>.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('users').avg('age')
|
||
</pre>
|
||
|
||
<pre class="display">
|
||
knex('users').avg('age as a')
|
||
</pre>
|
||
|
||
<p id="Builder-increment">
|
||
<b class="header">increment</b><code>.increment(column, amount)</code>
|
||
<br />
|
||
Increments a <b>column</b> value by the specified <b>amount</b>.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('accounts')
|
||
.where('userid', '=', 1)
|
||
.increment('balance', 10)
|
||
</pre>
|
||
|
||
<p id="Builder-decrement">
|
||
<b class="header">decrement</b><code>.decrement(column, amount)</code>
|
||
<br />
|
||
Decrements a <b>column</b> value by the specified <b>amount</b>.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('accounts').where('userid', '=', 1).decrement('balance', 5)
|
||
</pre>
|
||
|
||
<p id="Builder-truncate">
|
||
<b class="header">truncate</b><code>.truncate()</code>
|
||
<br />
|
||
Truncates the current table.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('accounts').truncate()
|
||
</pre>
|
||
|
||
<p id="Builder-pluck">
|
||
<b class="header">pluck</b><code>.pluck(id)</code>
|
||
<br />
|
||
This will pluck the specified column from each row in your results, yielding a promise which resolves
|
||
to the array of values selected.
|
||
</p>
|
||
|
||
<pre>
|
||
<code class="js">knex.table('users').pluck('id').then(function(ids) {
|
||
console.log(ids);
|
||
});
|
||
</code>
|
||
</pre>
|
||
|
||
<p id="Builder-first">
|
||
<b class="header">first</b><code>.first([columns])</code>
|
||
<br />
|
||
Similar to select, but only retrieves & resolves with the first record from the query.
|
||
</p>
|
||
|
||
<pre>
|
||
<code class="js">knex.table('users').first('id', 'name').then(function(row) {
|
||
console.log(row);
|
||
});
|
||
</code>
|
||
</pre>
|
||
|
||
<p id="Builder-clone">
|
||
<b class="header">clone</b><code>.clone()</code>
|
||
<br />
|
||
Clones the current query chain, useful for re-using partial query snippets in other queries
|
||
without mutating the original.
|
||
</p>
|
||
|
||
|
||
<p id="Builder-columnInfo">
|
||
<b class="header">columnInfo</b><code>.columnInfo([columnName])</code>
|
||
<br />
|
||
Returns an object with the column info about the current table, or an individual column if one is passed, returning an object with the following keys:
|
||
|
||
<ul>
|
||
<li><b>defaultValue</b>: the default value for the column</li>
|
||
<li><b>type</b>: the column type</li>
|
||
<li><b>maxLength</b>: the max length set for the column</li>
|
||
<li><b>nullable</b>: whether the column may be null</li>
|
||
</ul>
|
||
|
||
</p>
|
||
|
||
<pre>
|
||
<code class="js">knex('users').columnInfo().then(function(info) {
|
||
// ...
|
||
});
|
||
</code>
|
||
</pre>
|
||
|
||
<p id="Builder-debug">
|
||
<b class="header">debug</b><code>.debug()</code>
|
||
<br />
|
||
Turns on debugging for the current query chain.
|
||
</p>
|
||
|
||
<p id="Builder-connection">
|
||
<b class="header">connection</b><code>.connection(dbConnection)</code>
|
||
<br />
|
||
Explicitly specify the connection for the query, allowing you to use the knex chain outside of
|
||
the built-in pooling capabilities.
|
||
</p>
|
||
|
||
<p id="Builder-options">
|
||
<b class="header">options</b><code>.options()</code>
|
||
<br />
|
||
Allows for mixing in additional options as defined by database client specific libraries:
|
||
</p>
|
||
|
||
<pre>
|
||
<code class="js">knex('accounts as a1')
|
||
.leftJoin('accounts as a2', function() {
|
||
this.on('a1.email', '<>', 'a2.email');
|
||
})
|
||
.select(['a1.email', 'a2.email'])
|
||
.where(knex.raw('a1.id = 1'))
|
||
.option({ nestTables: true, rowMode: 'array' })
|
||
.limit(2)
|
||
.then(...
|
||
</code>
|
||
</pre>
|
||
|
||
<h2 id="Transactions">Transactions</h2>
|
||
|
||
<p>
|
||
Transactions are an important feature of relational databases, as they allow correct recovery from failures and keep a database consistent even in cases of system failure. All queries within a transaction are executed on the same database connection, and run the entire set of queries as a single unit of work. Any failure will mean the database will rollback any queries executed on that connection to the pre-transaction state.
|
||
</p>
|
||
|
||
<p>
|
||
Transactions are handled by passing a handler function into <tt>knex.transaction</tt>.
|
||
The handler function accepts a single argument, the an object which may be used in two ways:
|
||
|
||
<ol>
|
||
<li>As the "promise aware" knex connection</li>
|
||
<li>As an object passed into a query with <a href="#Builder-transacting"></a> and eventually call commit or rollback.</li>
|
||
</ol>
|
||
|
||
Consider these two examples:
|
||
</p>
|
||
|
||
<pre>
|
||
<code class="js">var Promise = require('bluebird');
|
||
|
||
// Using trx as a query builder:
|
||
knex.transaction(function(trx) {
|
||
|
||
var books = [
|
||
{title: 'Canterbury Tales'},
|
||
{title: 'Moby Dick'},
|
||
{title: 'Hamlet'}
|
||
];
|
||
|
||
return trx
|
||
.insert({name: 'Old Books'}, 'id')
|
||
.into('catalogues')
|
||
.then(function(ids) {
|
||
return Promise.map(books, function(book) {
|
||
book.catalogue_id = ids[0];
|
||
|
||
// Some validation could take place here.
|
||
|
||
return trx.insert(info).into('books');
|
||
}));
|
||
});
|
||
|
||
})
|
||
.then(function(inserts) {
|
||
console.log(inserts.length + ' new books saved.');
|
||
})
|
||
.catch(function(error) {
|
||
// If we get here, that means that neither the 'Old Books' catalogues insert,
|
||
// nor any of the books inserts will have taken place.
|
||
console.error(error);
|
||
});
|
||
</code>
|
||
</pre>
|
||
|
||
<p>And then this example:</p>
|
||
|
||
<pre>
|
||
<code class="js">var Promise = require('bluebird');
|
||
|
||
// Using trx as a transaction object:
|
||
knex.transaction(function(trx) {
|
||
|
||
var books = [
|
||
{title: 'Canterbury Tales'},
|
||
{title: 'Moby Dick'},
|
||
{title: 'Hamlet'}
|
||
];
|
||
|
||
knex.insert({name: 'Old Books'}, 'id')
|
||
.into('catalogues')
|
||
.transacting(trx)
|
||
.then(function(ids) {
|
||
return Promise.map(books, function(book) {
|
||
book.catalogue_id = ids[0];
|
||
|
||
// Some validation could take place here.
|
||
|
||
return knex.insert(info).into('books').transacting(trx);
|
||
}));
|
||
})
|
||
.then(trx.commit)
|
||
.then(trx.rollback);
|
||
})
|
||
.then(function(inserts) {
|
||
console.log(inserts.length + ' new books saved.');
|
||
})
|
||
.catch(function(error) {
|
||
// If we get here, that means that neither the 'Old Books' catalogues insert,
|
||
// nor any of the books inserts will have taken place.
|
||
console.error(error);
|
||
});
|
||
</code>
|
||
</pre>
|
||
|
||
<p>
|
||
Notice that if a promise is not returned within the handler, it is up to you to ensure <tt>trx.commit</tt>, or
|
||
<tt>trx.rollback</tt> are called, otherwise the transaction connection will hang.
|
||
</p>
|
||
|
||
<h2 id="Schema">Schema Builder</h2>
|
||
These methods return <a href="http://knexjs.org/#Interfaces-Promises">promises</a>.
|
||
|
||
<p id="Schema-createTable">
|
||
<b class="header">createTable</b><code>knex.schema.createTable(tableName, callback)</code>
|
||
<br />
|
||
Creates a new table on the database, with a callback function to modify the table's
|
||
structure, using the <a href="#Schema-Building">schema-building</a> commands.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.schema.createTable('users', function (table) {
|
||
table.increments();
|
||
table.string('name');
|
||
table.timestamps();
|
||
})
|
||
</pre>
|
||
|
||
<p id="Schema-renameTable">
|
||
<b class="header">renameTable</b><code>knex.schema.renameTable(from, to)</code>
|
||
<br />
|
||
Renames a table <b>from</b> a current tableName <b>to</b> another.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.schema.renameTable('users', 'old_users')
|
||
</pre>
|
||
|
||
<p id="Schema-dropTable">
|
||
<b class="header">dropTable</b><code>knex.schema.dropTable(tableName)</code>
|
||
<br />
|
||
Drops a table, specified by <b>tableName</b>.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.schema.dropTable('users')
|
||
</pre>
|
||
|
||
<p id="Schema-hasTable">
|
||
<b class="header">hasTable</b><code>knex.schema.hasTable(tableName)</code>
|
||
<br />
|
||
Checks for a table's existence by <b>tableName</b>, resolving with a boolean to
|
||
signal if the table exists.
|
||
</p>
|
||
|
||
<pre>
|
||
<code class="js">knex.schema.hasTable('users').then(function(exists) {
|
||
if (!exists) {
|
||
return knex.schema.createTable('users', function(t) {
|
||
t.increments('id').primary();
|
||
t.string('first_name', 100);
|
||
t.string('last_name', 100);
|
||
t.text('bio');
|
||
});
|
||
}
|
||
});
|
||
</code>
|
||
</pre>
|
||
|
||
<p id="Schema-hasColumn">
|
||
<b class="header">hasColumn</b><code>knex.schema.hasColumn(tableName, columnName)</code>
|
||
<br />
|
||
Checks if a column exists in the current table, resolves the promise with a boolean, <tt>true</tt>
|
||
if the column exists, <tt>false</tt> otherwise.
|
||
</p>
|
||
|
||
<p id="Schema-dropTableIfExists">
|
||
<b class="header">dropTableIfExists</b><code>knex.schema.dropTableIfExists(tableName)</code>
|
||
<br />
|
||
Drops a table conditionally if the table exists, specified by <tt>tableName</tt>.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.schema.dropTableIfExists('users')
|
||
</pre>
|
||
|
||
<p id="Schema-table">
|
||
<b class="header">table</b><code>knex.schema.table(tableName, callback)</code>
|
||
<br />
|
||
Chooses a database table, and then modifies the table, using the <a href="#Schema-Building">Schema Building</a>
|
||
functions inside of the callback.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.schema.table('users', function (table) {
|
||
table.dropColumn('name');
|
||
table.string('first_name');
|
||
table.string('last_name');
|
||
})
|
||
</pre>
|
||
|
||
<p id="Schema-raw">
|
||
<b class="header">raw</b><code>knex.schema.raw(statement)</code>
|
||
<br />
|
||
Run an arbitrary sql query in the schema builder chain.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.schema.raw("SET sql_mode='TRADITIONAL'")
|
||
.table('users', function (table) {
|
||
table.dropColumn('name');
|
||
table.string('first_name');
|
||
table.string('last_name');
|
||
})
|
||
</pre>
|
||
|
||
<h3 id="Schema-Building">Schema Building:</h3>
|
||
|
||
<p id="Schema-dropColumn">
|
||
<b class="header">dropColumn</b><code>table.dropColumn(name)</code>
|
||
<br />
|
||
Drops a column, specified by the column's <b>name</b>
|
||
</p>
|
||
|
||
<p id="Schema-dropColumns">
|
||
<b class="header">dropColumns</b><code>table.dropColumns(*columns)</code>
|
||
<br />
|
||
Drops multiple <b>columns</b>, taking a variable number of column names.
|
||
</p>
|
||
|
||
<p id="Schema-renameColumn">
|
||
<b class="header">renameColumn</b><code>table.renameColumn(from, to)</code>
|
||
<br />
|
||
Renames a column <b>from</b> one name <b>to</b> another.
|
||
</p>
|
||
|
||
<p id="Schema-increments">
|
||
<b class="header">increments</b><code>table.increments(name)</code>
|
||
<br />
|
||
Adds an auto incrementing column, in PostgreSQL this is a <tt>serial</tt>. This will be used as the primary key for the column. Also available is a <tt>bigIncrements</tt> if you wish to add a bigint incrementing number (in PostgreSQL <tt>bigserial</tt>).
|
||
</p>
|
||
|
||
<p id="Schema-integer">
|
||
<b class="header">integer</b><code>table.integer(name)</code>
|
||
<br />
|
||
Adds an integer column.
|
||
</p>
|
||
|
||
<p id="Schema-bigInteger">
|
||
<b class="header">bigInteger</b><code>table.bigInteger(name)</code>
|
||
<br />
|
||
In MySQL or PostgreSQL, adds a <tt>bigint</tt> column,
|
||
otherwise adds a normal integer.
|
||
</p>
|
||
|
||
<p id="Schema-text">
|
||
<b class="header">text</b><code>table.text(name, [textType])</code>
|
||
<br />
|
||
Adds a text column, with optional textType for MySql text datatype preference.
|
||
<br />
|
||
textType may be <tt>mediumtext</tt> or <tt>longtext</tt>, otherwise defaults to text.
|
||
</p>
|
||
|
||
<p id="Schema-string">
|
||
<b class="header">string</b><code>table.string(name, [length])</code>
|
||
<br />
|
||
Adds a string column, with optional length defaulting to 255.
|
||
</p>
|
||
|
||
<p id="Schema-float">
|
||
<b class="header">float</b><code>table.float(column, [precision], [scale])</code>
|
||
<br />
|
||
Adds a float column, with optional precision and scale.
|
||
</p>
|
||
|
||
<p id="Schema-decimal">
|
||
<b class="header">decimal</b><code>table.decimal(column, [precision], [scale])</code>
|
||
<br />
|
||
Adds a decimal column, with optional precision and scale.
|
||
</p>
|
||
|
||
<p id="Schema-boolean">
|
||
<b class="header">boolean</b><code>table.boolean(name)</code>
|
||
<br />
|
||
Adds a boolean column.
|
||
</p>
|
||
|
||
<p id="Schema-date">
|
||
<b class="header">date</b><code>table.date(name)</code>
|
||
<br />
|
||
Adds a date column.
|
||
</p>
|
||
|
||
<p id="Schema-dateTime">
|
||
<b class="header">dateTime</b><code>table.dateTime(name)</code>
|
||
<br />
|
||
Adds a dateTime column.
|
||
</p>
|
||
|
||
<p id="Schema-time">
|
||
<b class="header">time</b><code>table.time(name)</code>
|
||
<br />
|
||
Adds a time column.
|
||
</p>
|
||
|
||
<p id="Schema-timestamp">
|
||
<b class="header">timestamp</b><code>table.timestamp(name, [standard])</code>
|
||
<br />
|
||
Adds a timestamp column, defaults to <tt>timestamptz</tt> in PostgreSQL, unless true
|
||
is passed as the second argument.
|
||
<br />
|
||
Note that the method for defaulting to the current datetime varies from one database to another.
|
||
For example: PostreSQL requires <tt>.defaultTo(knex.raw('now()'))</tt>,
|
||
but SQLite3 requires <tt>.defaultTo(knex.raw("date('now')"))</tt>.
|
||
</p>
|
||
|
||
<p id="Schema-timestamps">
|
||
<b class="header">timestamps</b><code>table.timestamps()</code>
|
||
<br />
|
||
Adds a <tt>created_at</tt> and <tt>updated_at</tt> column on the database,
|
||
setting these each to <a href="#Schema-dateTime">dateTime</a> types.
|
||
</p>
|
||
|
||
<p id="Schema-binary">
|
||
<b class="header">binary</b><code>table.binary(name)</code>
|
||
<br />
|
||
Adds a binary column.
|
||
</p>
|
||
|
||
<p id="Schema-enum">
|
||
<b class="header">enum / enu</b><code>table.enu(col, values)</code>
|
||
<br />
|
||
Adds a enum column, (aliased to <tt>enu</tt>, as enum is a reserved word in javascript).
|
||
</p>
|
||
|
||
<p id="Schema-json">
|
||
<b class="header">json</b><code>table.json(name, [jsonb])</code>
|
||
<br />
|
||
Adds a json column, using the built-in <tt>json</tt> type in postgresql, defaulting to a text column
|
||
in older versions of postgresql or in unsupported databases. <tt>jsonb</tt> can be used by passing
|
||
<tt>true</tt> as the second argument.
|
||
</p>
|
||
|
||
<p id="Schema-uuid">
|
||
<b class="header">uuid</b><code>table.uuid(name)</code>
|
||
<br />
|
||
Adds a uuid column - this uses the built-in uuid type in postgresql, and falling back to a
|
||
<tt>char(36)</tt> in other databases.
|
||
</p>
|
||
|
||
<p id="Schema-comment">
|
||
<b class="header">comment</b><code>table.comment(value)</code>
|
||
<br />
|
||
Sets the comment for a table.
|
||
</p>
|
||
|
||
<p id="Schema-engine">
|
||
<b class="header">engine</b><code>table.engine(val)</code>
|
||
<br />
|
||
Sets the engine for the database table, only available within a <tt>createTable</tt> call, and only
|
||
applicable to MySQL.
|
||
</p>
|
||
|
||
<p id="Schema-charset">
|
||
<b class="header">charset</b><code>table.charset(val)</code>
|
||
<br />
|
||
Sets the charset for the database table, only available within a <tt>createTable</tt> call, and only
|
||
applicable to MySQL.
|
||
</p>
|
||
|
||
<p id="Schema-collate">
|
||
<b class="header">collate</b><code>table.collate(val)</code>
|
||
<br />
|
||
Sets the collation for the database table, only available within a <tt>createTable</tt> call, and only
|
||
applicable to MySQL.
|
||
</p>
|
||
|
||
<p id="Schema-specificType">
|
||
<b class="header">specificType</b><code>table.specificType(column, value)</code>
|
||
<br />
|
||
Sets a specific type for the column creation, if you'd like to add a column type that isn't supported here.
|
||
</p>
|
||
|
||
<h3 id="Chainable">Chainable Methods:</h3>
|
||
|
||
<p>
|
||
The following three methods may be chained on the schema building methods, as modifiers to the column.
|
||
</p>
|
||
|
||
<p id="Chainable-index">
|
||
<b class="header">index</b><code>column.index()</code>
|
||
<br />
|
||
Specifies an field as an index. No-op if this is chained off of a field that cannot be indexed.
|
||
</p>
|
||
|
||
<p id="Chainable-primary">
|
||
<b class="header">primary</b><code>column.primary()</code>
|
||
<br />
|
||
Sets the field as the primary key for the table.
|
||
To create a compound primary key, pass an array of column names: <code>table.primary(['column1', 'column2'])</code>.
|
||
</p>
|
||
|
||
<p id="Chainable-unique">
|
||
<b class="header">unique</b><code>column.unique()</code>
|
||
<br />
|
||
Sets the column as unique.
|
||
</p>
|
||
|
||
<p id="Chainable-references">
|
||
<b class="header">references</b><code>column.references(column)</code>
|
||
<br />
|
||
Sets the "column" that the current column references as a foreign key.
|
||
</p>
|
||
|
||
<p id="Chainable-inTable">
|
||
<b class="header">inTable</b><code>column.inTable(table)</code>
|
||
<br />
|
||
Sets the "table" where the foreign key column is located.
|
||
</p>
|
||
|
||
<p id="Chainable-onDelete">
|
||
<b class="header">onDelete</b><code>column.onDelete(command)</code>
|
||
<br />
|
||
Sets the SQL command to be run "onDelete".
|
||
</p>
|
||
|
||
<p id="Chainable-onUpdate">
|
||
<b class="header">onUpdate</b><code>column.onUpdate(command)</code>
|
||
<br />
|
||
Sets the SQL command to be run "onUpdate".
|
||
</p>
|
||
|
||
<p id="Chainable-defaultTo">
|
||
<b class="header">defaultTo</b><code>column.defaultTo(value)</code>
|
||
<br />
|
||
Sets the default value for the column on an insert.
|
||
</p>
|
||
|
||
<p id="Chainable-unsigned">
|
||
<b class="header">unsigned</b><code>column.unsigned()</code>
|
||
<br />
|
||
Specifies an integer as unsigned. No-op if this is chained off of a non-integer field.
|
||
</p>
|
||
|
||
<p id="Chainable-notNullable">
|
||
<b class="header">notNullable</b><code>column.notNullable()</code>
|
||
<br />
|
||
Adds a <tt>not null</tt> on the current column being created.
|
||
</p>
|
||
|
||
<p id="Chainable-nullable">
|
||
<b class="header">nullable</b><code>column.nullable()</code>
|
||
<br />
|
||
Default on column creation, this explicitly sets a field to be nullable.
|
||
</p>
|
||
|
||
<p id="Chainable-first">
|
||
<b class="header">first</b><code>column.first()</code>
|
||
<br />
|
||
Sets the column to be inserted on the first position, only used in MySQL alter tables.
|
||
</p>
|
||
|
||
<p id="Chainable-after">
|
||
<b class="header">after</b><code>column.after(field)</code>
|
||
<br />
|
||
Sets the column to be inserted after another, only used in MySQL alter tables.
|
||
</p>
|
||
|
||
<p id="Chainable-comment">
|
||
<b class="header">comment</b><code>column.comment(value)</code>
|
||
<br />
|
||
Sets the comment for a column.
|
||
</p>
|
||
|
||
<pre>
|
||
knex.schema.createTable('accounts', function() {
|
||
t.increments().primary();
|
||
t.string('email').unique();
|
||
});
|
||
</pre>
|
||
|
||
<h2 id="Raw">Raw Queries</h2>
|
||
|
||
<p>
|
||
Sometimes you may need to use a raw expression in a query. Raw query object may be injected pretty much
|
||
anywhere you want, and using proper bindings can ensure your values are escaped properly, preventing SQL-injection attacks.
|
||
</p>
|
||
|
||
<h3 id="Raw-Expressions">Raw Expressions:</h3>
|
||
|
||
<p>
|
||
Raw expressions are created by using <tt>knex.raw(sql, [bindings])</tt> and passing this as a value for any value in the query chain.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex('users')
|
||
.select(knex.raw('count(*) as user_count, status'))
|
||
.where(knex.raw(1))
|
||
.orWhere(knex.raw('status <> ?', [1]))
|
||
.groupBy('status')
|
||
</pre>
|
||
|
||
<h3 id="Raw-Queries">Raw Queries:</h3>
|
||
|
||
<p>
|
||
The <tt>knex.raw</tt> may also be used to build a full query and execute it, as a
|
||
standard query builder query would be executed. The benefit of this is that it uses the connection
|
||
pool and provides a standard interface for the different client libraries.
|
||
</p>
|
||
|
||
<pre>
|
||
<code class="js">knex.raw('select * from users where id = ?', [1]).then(function(resp) {
|
||
...
|
||
});
|
||
</code>
|
||
</pre>
|
||
|
||
<p class="warning">
|
||
Note that the response will be whatever the underlying sql library would typically return on a
|
||
normal query, so you may need to look at the documentation for the base library the queries are
|
||
executing against to determine how to handle the response.
|
||
</p>
|
||
|
||
<h3 id="Raw-queries-wrapped">Wrapped Queries:</h3>
|
||
|
||
<p>
|
||
The raw query builder also comes with a <tt>wrap</tt> method, which allows wrapping the query in a value:
|
||
</p>
|
||
|
||
<pre class="display">var subcolumn = knex.raw('select avg(salary) from employee where dept_no = e.dept_no')
|
||
.wrap('(', ') avg_sal_dept');
|
||
|
||
knex.select('e.lastname', 'e.salary', subcolumn)
|
||
.from('employee as e')
|
||
.whereRaw('dept_no = e.dept_no')
|
||
</pre>
|
||
|
||
<p>
|
||
Note that the example above be achieved more easily using the <a href="#Builder-as">as</a> method.
|
||
</p>
|
||
|
||
<pre class="display">var subcolumn = knex.avg('salary')
|
||
.from('employee')
|
||
.whereRaw('dept_no = e.dept_no')
|
||
.as('avg_sal_dept');
|
||
|
||
knex.select('e.lastname', 'e.salary', subcolumn)
|
||
.from('employee as e')
|
||
.whereRaw('dept_no = e.dept_no')
|
||
</pre>
|
||
|
||
<h2 id="Interfaces">Interfaces</h2>
|
||
|
||
<p>
|
||
Knex.js provides several options to deal with query output. The following methods are present on the query builder, schema builder, and the raw builder:
|
||
</p>
|
||
|
||
<h3 id="Interfaces-Promises">Promises</h3>
|
||
|
||
<p>
|
||
<a href="https://github.com/petkaantonov/bluebird#what-are-promises-and-why-should-i-use-them">Promises</a> are the preferred way of dealing with queries in knex, as they allow you to return values from a fulfillment handler,
|
||
which in turn become the value of the promise. The main benefit of promises are the ability to catch thrown errors without
|
||
crashing the node app, making your code behave like a <b>.try / .catch / .finally</b> in synchronous code.
|
||
</p>
|
||
|
||
<pre>
|
||
<code class="js">knex.select('name').from('users')
|
||
.where('id', '>', 20)
|
||
.andWhere('id', '<', 200)
|
||
.limit(10)
|
||
.offset(x)
|
||
.then(function(rows) {
|
||
return _.pluck(rows, 'name');
|
||
})
|
||
.then(function(names) {
|
||
return knex.select('id').from('nicknames').whereIn('nickname', names);
|
||
})
|
||
.then(function(rows) {
|
||
console.log(rows);
|
||
})
|
||
.catch(function(error) {
|
||
console.error(error)
|
||
});
|
||
</code>
|
||
</pre>
|
||
|
||
<p id="Promises-then">
|
||
<b class="header">then</b><code>.then(onFulfilled)</code>
|
||
<br />
|
||
Coerces the current query builder chain into a promise state, accepting the resolve
|
||
and reject handlers as specified by the <a href="http://promises-aplus.github.com/promises-spec">Promises/A+ spec</a>.
|
||
As stated in the spec, more than one call to the <tt>then</tt> method for the current query chain will resolve
|
||
with the same value, in the order they were called; the query will not be executed multiple times.
|
||
</p>
|
||
|
||
<pre>
|
||
<code class="js">knex.select('*').from('users').where({name: 'Tim'})
|
||
.then(function(rows) {
|
||
return knex.insert({user_id: rows[0].id, name: 'Test'}, 'id').into('accounts');
|
||
}).then(function(id) {
|
||
console.log('Inserted Account ' + id);
|
||
}).catch(function(error) {
|
||
console.error(error);
|
||
});
|
||
</code>
|
||
</pre>
|
||
|
||
<p id="Promises-catch">
|
||
<b class="header">catch</b><code>.catch(onRejected)</code>
|
||
<br />
|
||
Coerces the current query builder into a promise state, catching any error thrown by the query, the same as calling <tt>.then(null, onRejected)</tt>.
|
||
</p>
|
||
|
||
<pre>
|
||
<code class="js">return knex.insert({id: 1, name: 'Test'}, 'id').into('accounts')
|
||
.catch(function(error) {
|
||
console.error(error);
|
||
}).then(function() {
|
||
return knex.select('*').from('accounts').where('id', 1);
|
||
}).then(function(rows) {
|
||
console.log(rows[0]);
|
||
}).catch(function(error) {
|
||
console.error(error);
|
||
});
|
||
</code>
|
||
</pre>
|
||
|
||
<p id="Promises-tap">
|
||
<b class="header">tap</b><code>.tap(sideEffectHandler)</code>
|
||
<br />
|
||
Executes side effects on the resolved response, ultimately returning a promise that fulfills with the original
|
||
value. A thrown error or rejected promise will cause the promise to transition into a rejected state.
|
||
</p>
|
||
|
||
<pre>
|
||
<code class="js">// Using only .then()
|
||
query.then(function(x) {
|
||
doSideEffectsHere(x);
|
||
return x;
|
||
});
|
||
|
||
// Using .tap()
|
||
promise.tap(doSideEffectsHere);
|
||
</code>
|
||
</pre>
|
||
|
||
<p id="Promises-map">
|
||
<b class="header">map</b><code>.map(mapper)</code>
|
||
<br />
|
||
A passthrough to <a href="https://github.com/petkaantonov/bluebird/blob/master/API.md#mapfunction-mapper---promise">Bluebird's map implementation</a> with the result set.
|
||
</p>
|
||
|
||
<pre>
|
||
<code class="js">knex.select('name').from('users').limit(10).map(function(row) {
|
||
return row.name;
|
||
}).then(function(names) {
|
||
console.log(names);
|
||
}).catch(function(e) {
|
||
console.error(e);
|
||
});
|
||
</code>
|
||
</pre>
|
||
|
||
<p id="Promises-reduce">
|
||
<b class="header">reduce</b><code>.reduce(reducer, [initialValue])</code>
|
||
<br />
|
||
A passthrough to <a href="https://github.com/petkaantonov/bluebird/blob/master/API.md#reducefunction-reducer--dynamic-initialvalue---promise">Bluebird's reduce implementation</a> with the result set.
|
||
</p>
|
||
|
||
<pre>
|
||
<code class="js">knex.select('name').from('users').limit(10).reduce(function(memo, row) {
|
||
memo.names.push(row.name);
|
||
memo.count++;
|
||
return memo;
|
||
}, {count: 0, names: []}).then(function(obj) {
|
||
console.log(obj);
|
||
}).catch(function(e) {
|
||
console.error(e);
|
||
});
|
||
</code>
|
||
</pre>
|
||
|
||
<p id="Promises-bind">
|
||
<b class="header">bind</b><code>.bind(context)</code>
|
||
<br />
|
||
A passthrough to <a href="https://github.com/petkaantonov/bluebird/blob/master/API.md#binddynamic-thisarg---promise">Bluebird's bind method</a> which sets the context value (this) for the returned promise.
|
||
</p>
|
||
|
||
<pre>
|
||
<code class="js">knex.select('name').from('users')
|
||
.limit(10)
|
||
.bind(console)
|
||
.then(console.log)
|
||
.catch(console.error)
|
||
</code>
|
||
</pre>
|
||
|
||
<p id="Promises-return">
|
||
<b class="header">return</b><code>.return(value)</code>
|
||
<br />
|
||
Shorthand for calling <tt>.then(function() { return value })</tt>.
|
||
</p>
|
||
|
||
|
||
<pre>
|
||
<code class="js">// Without return:
|
||
knex.insert(values).into('users')
|
||
.then(function() {
|
||
return {inserted: true};
|
||
});
|
||
|
||
knex.insert(values).into('users').return({inserted: true});
|
||
</code>
|
||
</pre>
|
||
|
||
<h3 id="Interfaces-Callbacks">Callbacks</h3>
|
||
|
||
<p id="Interfaces-exec">
|
||
<b class="header">exec</b><code>.exec(callback)</code>
|
||
<br />
|
||
If you'd prefer a callback interface over promises, the <b>exec</b> function
|
||
accepts a standard node style callback for executing the query chain. Note that as
|
||
with the <a href="#Promises-then">then</a> method, subsequent calls to the same
|
||
query chain will return the same result.
|
||
</p>
|
||
|
||
<pre>
|
||
<code class="js">knex.select('name').from('users')
|
||
.where('id', '>', 20)
|
||
.andWhere('id', '<', 200)
|
||
.limit(10)
|
||
.offset(x)
|
||
.exec(function(err, rows) {
|
||
if (err) return console.error(err);
|
||
knex.select('id').from('nicknames').whereIn('nickname', _.pluck(rows, 'name'))
|
||
.exec(function(err, rows) {
|
||
if (err) return console.error(err);
|
||
console.log(rows);
|
||
});
|
||
});
|
||
</code>
|
||
</pre>
|
||
|
||
<h3 id="Interfaces-Streams">Streams</h3>
|
||
|
||
<p>
|
||
Streams are a powerful way of piping data through as it comes in, rather than all at once.
|
||
You can read more about streams <a href="https://github.com/substack/stream-handbook">here at substack's stream handbook</a>.
|
||
See the following for example uses of stream & pipe. If you wish to use streams with PostgreSQL, you must also install the <a href="https://github.com/brianc/node-pg-query-stream">pg-query-stream</a> module.
|
||
</p>
|
||
|
||
<p id="Streams-stream">
|
||
<b class="header">stream</b><code>.stream([options], [callback])</code>
|
||
<br />
|
||
If called with a <b>callback</b>, the callback is passed the stream and a promise is returned. Otherwise,
|
||
the readable stream is returned.
|
||
</p>
|
||
|
||
<pre>
|
||
<code class="js">// Retrieve the stream:
|
||
var stream = knex.select('*').from('users').stream();
|
||
stream.pipe(writableStream);
|
||
|
||
// With options:
|
||
var stream = knex.select('*').from('users').stream({highWaterMark: 5});
|
||
stream.pipe(writableStream);
|
||
|
||
// Use as a promise:
|
||
var stream = knex.select('*').from('users').where(knex.raw('id = ?', [1])).stream(function(stream) {
|
||
stream.pipe(writableStream);
|
||
}).then(function() {
|
||
// ...
|
||
}).catch(function(e) {
|
||
console.error(e);
|
||
});
|
||
</code>
|
||
</pre>
|
||
|
||
<p id="Streams-pipe">
|
||
<b class="header">pipe</b><code>.pipe(writableStream)</code>
|
||
<br />
|
||
Pipe a stream for the current query to a writableStream.
|
||
</p>
|
||
|
||
<pre>
|
||
<code class="js">var stream = knex.select('*').from('users').pipe(writableStream);
|
||
</code>
|
||
</pre>
|
||
|
||
<h3 id="Interfaces-Events">Events</h3>
|
||
|
||
<p id="Events-query">
|
||
<b class="header">query</b>
|
||
<br />
|
||
A <b>query</b> event is fired just before a query takes place, providing data about the query, including the connection's <tt>__cid</tt> property and any other information about the query as described in <a href="#Other-toSQL">toSQL</a>. Useful for logging all
|
||
</p>
|
||
|
||
|
||
<pre>
|
||
<code class="js">knex.select('*')
|
||
.from('users')
|
||
.on('query', function(data) {
|
||
app.log(data);
|
||
})
|
||
.then(function() {
|
||
// ...
|
||
});
|
||
</code>
|
||
</pre>
|
||
|
||
<h3 id="Interfaces-Other">Other</h3>
|
||
|
||
<p id="Other-toString">
|
||
<b class="header">toString</b><code>.toString()</code>
|
||
<br />
|
||
Returns an array of query strings filled out with the
|
||
correct values based on bindings, etc. Useful for debugging.
|
||
</p>
|
||
|
||
<pre class="display">
|
||
knex.select('*').from('users').where(knex.raw('id = ?', [1])).toString()
|
||
</pre>
|
||
|
||
<p id="Other-toSQL">
|
||
<b class="header">toSQL</b><code>.toSQL()</code>
|
||
<br />
|
||
Returns an array of query strings filled out with the
|
||
correct values based on bindings, etc. Useful for debugging.
|
||
</p>
|
||
|
||
<pre>
|
||
<code class="js">knex.select('*').from('users').where(knex.raw('id = ?', [1])).toSQL()
|
||
|
||
// Ouputs:
|
||
{
|
||
bindings: [1],
|
||
method: 'select',
|
||
sql: 'select * from "users" where id = ?',
|
||
options: undefined,
|
||
}
|
||
</code>
|
||
</pre>
|
||
|
||
|
||
<h2 id="Migrations">Migrations</h2>
|
||
|
||
<p>
|
||
Migrations allow for you to define sets of schema changes so upgrading a database is a breeze.
|
||
</p>
|
||
|
||
<h3 id="Migrations-CLI">Migration CLI</h3>
|
||
|
||
<p>
|
||
The migration CLI is bundled with the knex install, and is driven by the <a href="https://github.com/tkellen/node-liftoff">node-liftoff</a> module. To install globally, run:
|
||
</p>
|
||
|
||
<pre>
|
||
$ npm install knex -g
|
||
</pre>
|
||
|
||
<p>
|
||
The 0.6 migrations use a <b>knexfile</b>, which specify various configuration settings for the module. To create a new
|
||
knexfile, run the following:
|
||
</p>
|
||
|
||
<pre>
|
||
$ knex init
|
||
|
||
# or for .coffee
|
||
|
||
$ knex init -x coffee
|
||
</pre>
|
||
|
||
<p>
|
||
will create a sample knexfile.js - the file which contains our various database configurations. Once you have a knexfile.js,
|
||
you can use the migration tool to create migration files to the specified directory (default migrations). Creating new migration
|
||
files can be achieved by running:
|
||
</p>
|
||
|
||
<pre>
|
||
$ knex migrate:make migration_name
|
||
</pre>
|
||
|
||
<p>
|
||
Once you have the migrations in place you wish to run, you can run:
|
||
</p>
|
||
|
||
<pre>
|
||
$ knex migrate:latest
|
||
</pre>
|
||
|
||
<p>
|
||
To update your database to the latest version.
|
||
</p>
|
||
|
||
<h2 id="Seeds">Seed files</h2>
|
||
|
||
<p>
|
||
Seed files allow you to populate your database with test or seed data independent of your migration files.
|
||
</p>
|
||
|
||
<h3 id="Seeds-CLI">Seed CLI</h3>
|
||
|
||
<p>
|
||
To create a seed file, run:
|
||
</p>
|
||
|
||
<pre>
|
||
$ knex seed:make seed_name
|
||
</pre>
|
||
|
||
<p>
|
||
Seed files are created in the directory specified in your knexfile.js for the current environment. A sample seed configuration looks like:
|
||
</p>
|
||
|
||
<pre>
|
||
development: {
|
||
client: ...,
|
||
connection: { ... },
|
||
<b>seeds: {
|
||
directory: './seeds/dev'
|
||
}</b>
|
||
}
|
||
</pre>
|
||
|
||
<p>
|
||
If no <tt>seeds.directory</tt> is defined, files are created in <tt>./seeds</tt>. Note that the seed directory needs to be a relative path. Absolute paths are not supported (nor is it good practice).
|
||
</p>
|
||
|
||
<p>
|
||
To run seed files, execute:
|
||
</p>
|
||
|
||
<pre>
|
||
$ knex seed:run
|
||
</pre>
|
||
|
||
<p>
|
||
Seed files are executed in alphabetical order.
|
||
</p>
|
||
|
||
<h3 id="knexfile">knexfile.js</h3>
|
||
|
||
<p>
|
||
A knexfile.js or knexfile.coffee generally contains all of the configuration for your database, for each environment you will be using. You may pass a <tt>--knexfile</tt> option to any of the command line statements to specify an alternate path to your knexfile.
|
||
</p>
|
||
|
||
|
||
<h3 id="Migrations-API">Migration API</h3>
|
||
|
||
<p>
|
||
<tt>knex.migrate</tt> is the class utilized by the knex migrations cli. Each method
|
||
takes an optional <tt>config</tt> object, which may specify specifies the <tt>database</tt>,
|
||
<tt>directory</tt>, <tt>extension</tt>, and <tt>tableName</tt> for the migrations.
|
||
</p>
|
||
|
||
<p id="Migrations-make">
|
||
<b class="header">make</b><code>knex.migrate.make(name, [config])</code>
|
||
<br />
|
||
Creates a new migration, with the <b>name</b> of the migration being added.
|
||
</p>
|
||
|
||
<p id="Migrations-latest">
|
||
<b class="header">latest</b><code>knex.migrate.latest([config])</code>
|
||
<br />
|
||
Runs all migrations that have not yet been run.
|
||
</p>
|
||
|
||
<p id="Migrations-rollback">
|
||
<b class="header">rollback</b><code>knex.migrate.rollback([config])</code>
|
||
<br />
|
||
Rolls back the latest migration group.
|
||
</p>
|
||
|
||
<p id="Migrations-currentVersion">
|
||
<b class="header">currentVersion</b><code>knex.migrate.currentVersion([config])</code>
|
||
<br />
|
||
Retrieves and returns the current migration version, as a promise.
|
||
If there aren't any migrations run yet, returns "none" as the value for the currentVersion.
|
||
</p>
|
||
|
||
<h3 id="Seeds-API">Seed API</h3>
|
||
|
||
<p>
|
||
<tt>knex.seed</tt> is the class utilized by the knex seed CLI. Each method
|
||
takes an optional <tt>config</tt> object, which may specify the relative
|
||
<tt>directory</tt> for the migrations.
|
||
</p>
|
||
|
||
<p id="Seeds-make">
|
||
<b class="header">make</b><code>knex.seed.make(name, [config])</code>
|
||
<br />
|
||
Creates a new seed file, with the <b>name</b> of the seed file being added.
|
||
</p>
|
||
|
||
<p id="Seeds-run">
|
||
<b class="header">run</b><code>knex.seed.run([config])</code>
|
||
<br />
|
||
Runs all seed files for the current environment.
|
||
</p>
|
||
|
||
<h2 id="support">Support</h2>
|
||
|
||
<p>
|
||
Have questions about the library? Come join us in the <a href="http://webchat.freenode.net/?channels=bookshelf">#bookshelf freenode IRC</a> channel for support on knex.js and <a href="http://bookshelfjs.org">bookshelf.js</a>, or post an issue on <a href="http://stackoverflow.com/questions/tagged/knex.js">Stack Overflow</a> or in the GitHub <a href="https://github.com/tgriesser/knex/issues">issue tracker</a>.
|
||
</p>
|
||
|
||
<h2 id="faq">F.A.Q.</h2>
|
||
|
||
<p id="faq-contribute">
|
||
<b class="header">How do I help contribute?</b><br />
|
||
Glad you ask! Pull requests, or feature requests, though not always implemented, are a great way
|
||
to help make Knex even better than it is now. If you're looking for something specific to help out with,
|
||
there's a number of unit tests that aren't implemented yet, the library could never have too many of those.
|
||
If you want to submit a fix or feature, take a look at the <a href="https://github.com/tgriesser/knex/blob/master/CONTRIBUTING.md">
|
||
Contributing</a> readme in the Github and go ahead and open a ticket.
|
||
</p>
|
||
|
||
<p id="faq-debug">
|
||
<b class="header">How do I debug?</b><br />
|
||
If you pass <tt>{debug: true}</tt> as one of the options in your initialize settings, you can see all of the query calls being made. Sometimes you need to dive a bit further into the various calls and see what all is going on behind the scenes. I'd recommend
|
||
<a href="https://github.com/dannycoates/node-inspector">node-inspector</a>, which allows you to debug code with <tt>debugger</tt> statements like you would in the browser.
|
||
</p>
|
||
|
||
<p>At the start of your application code will catch any errors not otherwise caught in the normal promise chain handlers, which is very helpful in debugging.
|
||
</p>
|
||
|
||
<p id="faq-tests">
|
||
<b class="header">How do I run the test suite?</b><br />
|
||
The test suite looks for an environment variable called <tt>KNEX_TEST</tt> for the path to the database
|
||
configuration. If you run the following command:
|
||
</p>
|
||
<pre>
|
||
$ export KNEX_TEST='/path/to/your/knex_config.js'
|
||
$ npm test
|
||
</pre>
|
||
|
||
<p>
|
||
replacing with the path to your config file, and the config file is valid, the test suite should run properly.
|
||
</p>
|
||
|
||
<p id="faq-nonode">
|
||
<b class="header">Can I use Knex outside of Node.js</b><br />
|
||
Yes. While the WebSQL spec is deprecated, there is still an adapter that provides support.
|
||
Checkout the <a href="https://github.com/tgriesser/knex/tree/master/browser">browser builds</a> for more details</a>.
|
||
</p>
|
||
|
||
<h2 id="changelog">Change Log</h2>
|
||
|
||
<p>
|
||
<b class="header">0.7.1 & 0.7.2</b> — <small><i>Oct 1, 2014</i></small><br />
|
||
</p>
|
||
|
||
<ul>
|
||
<li>Better disconnect handling & pool removal for MySQL clients, #452.</li>
|
||
<li>Fix for regression in migrations.</li>
|
||
</ul>
|
||
|
||
<p>
|
||
<b class="header">0.7.0</b> — <small><i>Oct 1, 2014</i></small><br />
|
||
|
||
<b>New Features:</b>
|
||
<ul>
|
||
<li>Oracle support, #419</li>
|
||
<li>Database seed file support, #391</li>
|
||
<li>Improved support for sub-raw queries within raw statements</li>
|
||
</ul>
|
||
|
||
<b>Breaking Changes:</b>
|
||
<ul>
|
||
<li>"collate nocase" no longer used by default in sqlite3 #396</li>
|
||
</ul>
|
||
|
||
<b>Other Changes:</b>
|
||
<ul>
|
||
<li>Bumping Bluebird to ^2.x</li>
|
||
<li>Transactions in websql are now a no-op (unsupported) #375</li>
|
||
<li>Improved test suite</li>
|
||
<li>knex.fn namespace as function helper (knex.fn.now), #372</li>
|
||
<li>Better handling of disconnect errors</li>
|
||
<li>Support for offset without limit, #446</li>
|
||
<li>Chainable first method for mysql schema, #406</li>
|
||
<li>Support for empty array in <tt>whereIn</tt></li>
|
||
<li>Create/drop schema for postgres, #511</li>
|
||
<li>Inserting multiple rows with default values, #468</li>
|
||
<li>Join columns are optional for cross-join, #508</li>
|
||
<li>Flag for creating jsonb columns in Postgresql, #500</li>
|
||
</ul>
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.6.22</b> — <small><i>July 10, 2014</i></small><br />
|
||
Bug fix for properly binding postgresql streaming queries, (#363).
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.6.21</b> — <small><i>July 9, 2014</i></small><br />
|
||
</p>
|
||
<ul>
|
||
<li>Bug fix for raw queries not being transaction context aware, (#351).</li>
|
||
<li>Properly forward stream errors in sqlite3 runner, (#359).</li>
|
||
</ul>
|
||
|
||
<p>
|
||
<b class="header">0.6.20</b> — <small><i>June 30, 2014</i></small><br />
|
||
Allow case insensitive operators in sql clauses, (#344).
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.6.19</b> — <small><i>June 27, 2014</i></small><br />
|
||
</p>
|
||
<ul>
|
||
<li>Add <tt>groupByRaw</tt> / <tt>orderByRaw</tt> methods, better support for raw statements in group / order (#282).</li>
|
||
<li>Support more config options for node-mysql2 dialect (#341).</li>
|
||
<li>CLI help text fix, (#342).</li>
|
||
</ul>
|
||
|
||
<p>
|
||
<b class="header">0.6.18</b> — <small><i>June 25, 2014</i></small><br />
|
||
Patch for the <a href="#Streams-stream">method</a>, calling without a handler should return the stream, not a promise (#337).
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.6.17</b> — <small><i>June 23, 2014</i></small><br />
|
||
Adding missing map / reduce proxies to bluebird's implementation.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.6.16</b> — <small><i>June 18, 2014</i></small><br />
|
||
</p>
|
||
<ul>
|
||
<li>Increment / decrement returns the number of affectedRows (#330).</li>
|
||
<li>Allow --cwd option flag to be passed to CLI tool (#326).</li>
|
||
</ul>
|
||
|
||
<p>
|
||
<b class="header">0.6.15</b> — <small><i>June 14, 2014</i></small><br />
|
||
Added the <a href="#Builder-as">as</a> method for aliasing subqueries.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.6.14</b> — <small><i>June 14, 2014</i></small><br />
|
||
<tt>whereExists</tt> / <tt>whereNotExists</tt> may now take a query builder instance as well as a callback.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.6.13</b> — <small><i>June 12, 2014</i></small><br />
|
||
</p>
|
||
<ul>
|
||
<li>Fix regression with onUpdate / onDelete in PostgreSQL, (#308).</li>
|
||
<li>Add missing <tt>Promise</tt> require to knex.js, unit test for knex.destroy (#314).</li>
|
||
</ul>
|
||
|
||
<p>
|
||
<b class="header">0.6.12</b> — <small><i>June 10, 2014</i></small><br />
|
||
Fix for regression with boolean default types in PostgreSQL.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.6.11</b> — <small><i>June 10, 2014</i></small><br />
|
||
Fix for regression with queries containing multiple <tt>order by</tt> statements in sqlite3.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.6.10</b> — <small><i>June 10, 2014</i></small><br />
|
||
Fix for big regression in memoization of column names from 0.5 -> 0.6.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.6.9</b> — <small><i>June 9, 2014</i></small><br />
|
||
Fix for regression in <tt>specificType</tt> method.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.6.8</b> — <small><i>June 9, 2014</i></small><br />
|
||
Package.json fix for CLI.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.6.7</b> — <small><i>June 9, 2014</i></small><br />
|
||
</p>
|
||
<ul>
|
||
<li>Adds support for <a href="https://github.com/sidorares/node-mysql2">node-mysql2</a> library.</li>
|
||
<li>Bundles CLI with the knex install, various related migrate CLI fixes.</li>
|
||
</ul>
|
||
|
||
<p>
|
||
<b class="header">0.6.6</b> — <small><i>June 9, 2014</i></small><br />
|
||
</p>
|
||
|
||
<ul>
|
||
<li>console.warn rather than throw when adding foreignKeys in SQLite3.</li>
|
||
<li>Add support for dropColumn in SQLite3.</li>
|
||
<li>Document <tt>raw.wrap</tt>.</li>
|
||
</ul>
|
||
|
||
<p>
|
||
<b class="header">0.6.5</b> — <small><i>June 9, 2014</i></small><br />
|
||
Add missing <tt>_</tt> require to WebSQL builds.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.6.4</b> — <small><i>June 9, 2014</i></small><br />
|
||
Fix & document <a href="#Schema-raw">schema.raw</a> method.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.6.3</b> — <small><i>June 6, 2014</i></small><br />
|
||
</p>
|
||
|
||
<ul>
|
||
<li>Schema methods on transaction object are now transaction aware (#301).</li>
|
||
<li>Fix for resolved value from transactions, (#298).</li>
|
||
<li>Undefined columns are not added to builder.</li>
|
||
</ul>
|
||
|
||
<p>
|
||
<b class="header">0.6.2</b> — <small><i>June 4, 2014</i></small><br />
|
||
</p>
|
||
|
||
<ul>
|
||
<li>Fix regression in raw query output, (#297).</li>
|
||
<li>Fix regression in "pluck" method (#296).</li>
|
||
<li>Document <a href="#Builder-first">first</a> method.</li>
|
||
</ul>
|
||
|
||
<p>
|
||
<b class="header">0.6.1</b> — <small><i>June 4, 2014</i></small><br />
|
||
Reverting to using .npmignore, the "files" syntax forgot the knex.js file
|
||
</p>
|
||
|
||
<p id="release-0.6.0">
|
||
<b class="header">0.6.0</b> — <small><i>June 4, 2014</i></small><br />
|
||
Major Library refactor. Notable changes & fixes include:
|
||
|
||
<ul>
|
||
<li>Major internal overhaul to clean up the various dialect code.</li>
|
||
<li>Improved unit test suite.</li>
|
||
<li>Support for the <a href="https://github.com/mscdex/node-mariasql">mariasql</a> driver.</li>
|
||
<li>More consistent use of raw query bindings throughout the library.</li>
|
||
<li>Queries are more composable, may be injected in various points throughout the builder.</li>
|
||
<li>Added <a href="#Interfaces-Streams">streaming</a> interface</li>
|
||
<li>Deprecated 5 argument <a href="#Builder-join">join</a> in favor of additional join methods.</li>
|
||
<li>The wrapValue function to allow for array column operations in PostgreSQL (#287).</li>
|
||
<li>An explicit connection can be passed for any query (#56).</li>
|
||
<li>Drop column support for sqlite3</li>
|
||
<li>All schema actions are run sequentially on the same connection if chained.</li>
|
||
<li>Schema actions can now be wrapped in a transaction</li>
|
||
<li><tt>.references(tableName.columnName)</tt> as shorthand for <tt>.references(columnName).inTable(tableName)</tt></li>
|
||
<li><tt>.join('table.column', 'otherTable.column')</tt> as shorthand for .join('table.column', '=', 'otherTable.column')</tt></li>
|
||
<li>Streams are supported for selects, passing through to the streaming capabilities of node-mysql and node-postgres</li>
|
||
</ul>
|
||
|
||
For More information, see this <a href="https://github.com/tgriesser/knex/pull/252">pull-request</a>.
|
||
</p>
|
||
|
||
<p><a href="#" class="js-change-log" style="text-align:center">Show Full Change log</a></p>
|
||
|
||
<div class="change-log" style="display:none;">
|
||
|
||
<p>
|
||
<b class="header">0.5.15</b> — <small><i>June 4, 2014</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.5.14...0.5.15">Diff</a><br />
|
||
Dropped indexes feature now functions correctly, (#278).
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.5.14</b> — <small><i>May 6, 2014</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.5.13...0.5.14">Diff</a><br />
|
||
Remove the charset encoding if it's utf8 for mysql, as it's the default but also
|
||
currently causes some issues in recent versions of node-mysql.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.5.13</b> — <small><i>April 2, 2014</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.5.12...0.5.13">Diff</a><br />
|
||
Fix regression in array bindings for postgresql (#228).
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.5.12</b> — <small><i>Mar 31, 2014</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.5.11...0.5.12">Diff</a><br />
|
||
Add more operators for where clauses, including <tt>&&</tt> (#226).
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.5.11</b> — <small><i>Mar 25, 2014</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.5.10...0.5.11">Diff</a><br />
|
||
<ul>
|
||
<li><tt>.where(col, 'is', null)</tt> or <tt>.where(col, 'is not', null)</tt> are not supported (#221).</li>
|
||
<li>Case insensitive <tt>where</tt> operators now allowed (#212).</li>
|
||
<li>Fix bug in increment/decrement truncating to an integer (#210).</li>
|
||
<li>Disconnected connections are now properly handled & removed from the pool (#206).</li>
|
||
<li>Internal tweaks to binding concatenations for performance (#207).</li>
|
||
</ul>
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.5.10</b> — <small><i>Mar 19, 2014</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.5.9...0.5.10">Diff</a><br />
|
||
Add the <tt>.exec</tt> method to the internal promise shim.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.5.9</b> — <small><i>Mar 18, 2014</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.5.8...0.5.9">Diff</a><br />
|
||
Remove error'ed connections from the connection pool (#206), added support for <a href="https://github.com/brianc/node-postgres-pure">node-postgres-pure (pg.js)</a> (#200).
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.5.8</b> — <small><i>Feb 27, 2014</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.5.7...0.5.8">Diff</a><br />
|
||
Fix for chaining on <tt>forUpdate</tt> / <tt>forShare</tt>, adding <a href="#Builder-map">map</a> & <a href="#Builder-reduce">reduce</a> from bluebird.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.5.7</b> — <small><i>Feb 18, 2014</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.5.6...0.5.7">Diff</a><br />
|
||
Fix for a <tt>null</tt> limit / offset breaking query chain (#182).
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.5.6</b> — <small><i>Feb 5, 2014</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.5.5...0.5.6">Diff</a><br />
|
||
Bump bluebird dependency to ~1.0.0, fixing regression in Bluebird 1.0.2 (#176).
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.5.5</b> — <small><i>Jan 28, 2014</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.5.4...0.5.5">Diff</a><br />
|
||
<ul>
|
||
<li>Fix for the exit code on the migrations cli (#151).</li>
|
||
<li>The <tt>init</tt> method in <tt>knex.migrate</tt> now uses <tt>this.config</tt> if one isn't passed in (#156).</li>
|
||
</ul>
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.5.4</b> — <small><i>Jan 7, 2014</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.5.3...0.5.4">Diff</a><br />
|
||
Fix for using raw statements in <tt>defaultTo</tt> schema builder methods (#146).
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.5.3</b> — <small><i>Jan 2, 2014</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.5.2...0.5.3">Diff</a><br />
|
||
Fix for incorrectly formed sql when aggregates are used with columns (#144).
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.5.2</b> — <small><i>Dec 18, 2013</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.5.1...0.5.2">Diff</a><br />
|
||
Adding passthrough "catch", "finally" to bluebird implementations, use
|
||
bluebird's "nodeify" internally for exec.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.5.1</b> — <small><i>Dec 12, 2013</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.5.0...0.5.1">Diff</a><br />
|
||
<ul>
|
||
<li>The <a href="#Builder-returning">returning</a> in PostgreSQL may now accept * or an array of columns to return. If either of these are passed, the response will be an array of objects rather than an array of values. Updates may also now use a <tt>returning</tt> value. (#132)</li>
|
||
<li>Added <tt>bigint</tt> and <tt>bigserial</tt> type to PostgreSQL. (#111)</li>
|
||
<li>Fix for the <a href="#Schema-specificType">specificType</a> schema call (#118)</li>
|
||
<li>Several fixes for migrations, including migration file path fixes, passing a
|
||
Promise constructor to the migration <tt>up</tt> and <tt>down</tt> methods, allowing
|
||
the "knex" module to be used globally, file ordering on migrations, and other small improvements. (#112-115, #125, #135)</li>
|
||
</ul>
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.5.0</b> — <small><i>Nov 25, 2013</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.4.13...0.5.0">Diff</a> — <a href="http://htmlpreview.github.com/?https://raw.github.com/tgriesser/knex/0.5.0/index.html">Docs</a><br />
|
||
<ul>
|
||
<li>Initial pass at a <a href="#Migrations">migration</a> api.</li>
|
||
<li>Aggregate methods are no longer aliased as "aggregate",
|
||
but may now be aliased and have more than one aggregate in a query (#108, #110).</li>
|
||
<li>Adding bigint and bigserial to PostgreSQL (#111).</li>
|
||
<li>Bugfix on increment/decrement values (#100).</li>
|
||
<li>Bugfix with having method (#107).</li>
|
||
<li>Switched from when.js to <a href="https://github.com/petkaantonov/bluebird">bluebird</a> for promise implementation, with shim for backward compatibility.</li>
|
||
<li>Switched from underscore to lodash, for semver reliability.</li>
|
||
</ul>
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.4.13</b> — <small><i>Oct 31, 2013</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.4.12...0.4.13">Diff</a><br />
|
||
Fix for aggregate methods on <tt>toString</tt> and <tt>clone</tt>, (#98).
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.4.12</b> — <small><i>Oct 29, 2013</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.4.11...0.4.12">Diff</a><br />
|
||
Fix incorrect values passed to <tt>float</tt> in MySQL and <tt>decimal</tt>
|
||
in PostgreSQL.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.4.11</b> — <small><i>Oct 15, 2013</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.4.10...0.4.11">Diff</a><br />
|
||
Fix potential sql injection vulnerability in <tt>orderBy</tt>, thanks to @sebgie.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.4.10</b> — <small><i>Oct 14, 2013</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.4.9...0.4.10">Diff</a><br />
|
||
<ul>
|
||
<li>Added <a href="#Builder-forUpdate">forUpdate</a> and <a href="#Builder-forShare">forShare</a> for select modes in transactions. (#84)</li>
|
||
<li>Fix bug where current query chain type is not copied on <a href="#Builder-clone">clone</a>. (#90)</li>
|
||
<li>Charset and collate are now added as methods on the schema builder. (#89)</li>
|
||
<li>Added <tt>into</tt> as an alias of <a href="#Builder-from">from</a>, for builder syntax of: <tt>insert(value).into(tableName)</tt></li>
|
||
<li>Internal pool fixes. (#90)</li>
|
||
</ul>
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.4.9</b> — <small><i>Oct 7, 2013</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.4.8...0.4.9">Diff</a><br />
|
||
<ul>
|
||
<li>Fix for documentation of <a href="#Schema-hasColumn">hasColumn</a>, ensure that <tt>hasColumn</tt> works with MySQL (#87).</li>
|
||
<li>More cleanup of error messages, showing the original error message concatenated with the sql and bindings.</li>
|
||
</ul>
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.4.8</b> — <small><i>Oct 2, 2013</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.4.7...0.4.8">Diff</a><br />
|
||
Connections are no longer pushed back into the pool if they never existed to begin with (#85).
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.4.7</b> — <small><i>Sep 27, 2013</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.4.6...0.4.7">Diff</a><br />
|
||
The <a href="#Builder-column">column</a> is now a documented method on the builder api, and takes either an individual column or an array of columns to select.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.4.6</b> — <small><i>Sep 25, 2013</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.4.5...0.4.6">Diff</a><br />
|
||
Standardizing handling of errors for easier debugging, as noted in (#39).
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.4.5</b> — <small><i>Sep 24, 2013</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.4.4...0.4.5">Diff</a><br />
|
||
Fix for <tt>hasTable</tt> always returning true in MySQL (#82), fix where sql queries were duplicated with multiple calls on <tt>toSql</tt> with the
|
||
schema builder.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.4.4</b> — <small><i>Sep 22, 2013</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.4.3...0.4.4">Diff</a><br />
|
||
Fix for <tt>debug</tt> method not properly debugging individual queries.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.4.3</b> — <small><i>Sep 18, 2013</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.4.2...0.4.3">Diff</a><br />
|
||
Fix for underscore not being defined in various grammar files.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.4.2</b> — <small><i>Sep 17, 2013</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.4.1...0.4.2">Diff</a><br />
|
||
Fix for an error being thrown when an initialized <tt>ClientBase</tt> instance was passed into <tt>Knex.initialize</tt>. <tt>pool.destroy</tt> now optionally accepts a callback to notify when it has completed draining and destroying all connections.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.4.1</b> — <small><i>Sep 16, 2013</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.4.0...0.4.1">Diff</a><br />
|
||
Cleanup from the 0.4.0 release, fix a potential exploit in "where" clauses pointed out by <a href="http://themoll.com">Andri Möll</a>, fix for clients
|
||
not being properly released from the pool #70, fix for <tt>where("foo", "<>", null)</tt> doing an "IS NULL" statement.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.4.0</b> — <small><i>Sep 13, 2013</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.2.6...0.4.0">Diff</a> — <a href="http://htmlpreview.github.com/?https://raw.github.com/tgriesser/knex/0.4.0/index.html">Docs</a><br />
|
||
<b>Breaking Changes:</b>
|
||
<ul>
|
||
<li>
|
||
Global state is no longer stored in the library, an instance is returned from <tt>Knex.initialize</tt>,
|
||
so you will need to call this once and then reference this <tt>knex</tt> client elsewhere in your application.
|
||
</li>
|
||
<li>
|
||
Lowercasing of <tt>knex.raw</tt>, <tt>knex.transaction</tt>, and <tt>knex.schema</tt>.
|
||
</li>
|
||
<li>
|
||
Created columns are now nullable by default, unless <tt>notNullable</tt> is chained as an option.
|
||
</li>
|
||
<li>
|
||
Keys created with <tt>increments</tt> are now assumed to be unsigned (MySQL) by default.
|
||
</li>
|
||
<li>
|
||
The <tt>destroyAllNow</tt> is no longer called by the library on <tt>process.exit</tt> event. If you need to call
|
||
it explicitly yourself, you may use <tt>knex.client.destroyPool</tt>
|
||
</li>
|
||
</ul>
|
||
Schema: Added <a href="#Schema-hasColumn">hasColumn</a>, <a href="#Schema-renameColumn">renameColumn</a>, <a href="#Schema-bigInteger">bigInteger</a>,
|
||
<a href="#Schema-specificType">specificType</a>.
|
||
General: Refactoring the library to support UMD and eventual use on the client. Added <a href="#Builder-options">options</a> method for adding additional
|
||
parameters specific to individual database libraries, #64.
|
||
Bugfixes: Case insensitive where operators (e.g.) <tt>LIKE, BETWEEN, NOT LIKE</tt> are now supported.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.2.6</b> — <small><i>Aug 29, 2013</i></small> — <a href="https://github.com/tgriesser/knex/compare/0.2.5...0.2.6">Diff</a> — <a href="http://htmlpreview.github.com/?https://raw.github.com/tgriesser/knex/0.2.5/index.html">Docs</a><br />
|
||
Reject the transaction promise if the transaction "commit" fails, (#50).
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.2.5</b> — <small><i>Aug 25, 2013</i></small><br />
|
||
Fix error if a callback isn't specified for <tt>exec</tt>, (#49).
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.2.4</b> — <small><i>Aug 22, 2013</i></small><br />
|
||
Fix SQLite3 delete not returning affected row count, (#45).
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.2.3</b> — <small><i>Aug 22, 2013</i></small><br />
|
||
Fix insert with default values in PostgreSQL and SQLite3, (#44).
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.2.2</b> — <small><i>Aug 20, 2013</i></small><br />
|
||
Allowing <tt>Raw</tt> queries to be passed as the primary table names.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.2.1</b> — <small><i>Aug 13, 2013</i></small><br />
|
||
Fix for an array passed to <tt>insert</tt> being mutated.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.2.0</b> — <small><i>Aug 7, 2013</i></small><br />
|
||
<b>Breaking changes:</b>
|
||
<ul>
|
||
<li>
|
||
<a href="#Schema-hasTable">hasTable</a> now returns a boolean rather than a failed promise.
|
||
</li>
|
||
<li>
|
||
Changed syntax for insert in postgresql, where the <tt>id</tt> is not assumed on inserts (#18).
|
||
The second parameter of <a href="#Builder-insert">insert</a> is now required to return an array of insert id's for the last insert.
|
||
</li>
|
||
<li>
|
||
The <a href="#Schema-timestamp">timestamp</a> method on the schema builder now uses a <tt>dateTime</tt> rather than a <tt>timestamp</tt>.
|
||
</li>
|
||
</ul>
|
||
Restored basic binding support on <tt>Raw</tt> queries (#19).
|
||
Added support for the JSON and UUID datatypes in postgres (#20).
|
||
Fix enabling enum in postgresql (#21).
|
||
Added foreign key support (#24).
|
||
Bugfix for column ordering on insert (#31).
|
||
Other minor bugfixes, documentation cleanup, & tweaks.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.1.8</b> — <small><i>July 7, 2013</i></small><br />
|
||
Somehow missing the <tt>!=</tt> operator. Using <tt>_.find</tt> rather than <tt>_.where</tt> in <tt>getCommandsByName</tt>(#22).
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.1.7</b> — <small><i>June 12, 2013</i></small><br />
|
||
Ensures unhandled errors in the <tt>exec</tt> callback interface are re-thrown.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.1.6</b> — <small><i>June 9, 2013</i></small><br />
|
||
Renaming <tt>beforeCreate</tt> to <tt>afterCreate</tt>. Better handling of errors in the connection pooling.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.1.5</b> — <small><i>June 9, 2013</i></small><br />
|
||
Added the ability to specify <tt>beforeCreate</tt> and <tt>beforeDestroy</tt> hooks on the initialize's <tt>options.pool</tt>
|
||
to perform any necessary database setup/teardown on connections before use (#14). <tt>where</tt> and <tt>having</tt>
|
||
may now accept <tt>Knex.Raw</tt> instances, for consistency (#15). Added an <tt>orHaving</tt> method to the builder.
|
||
The ability to specify bindings on Raw queries has been removed.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.1.4</b> — <small><i>May 22, 2013</i></small><br />
|
||
<tt>defaultTo</tt> now accepts <tt>"false"</tt> for boolean columns, allows for empty strings as default values.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.1.3</b> — <small><i>May 18, 2013</i></small><br />
|
||
Enabling table aliases (#11). Fix for issues with transactions not functioning (#12).
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.1.2</b> — <small><i>May 15, 2013</i></small><br />
|
||
Bug fixes for <tt>groupBy</tt> (#7). Mysql using collation, charset config settings in <tt>createTable</tt>.
|
||
Added engine on <tt>schemaBuilder</tt> specifier (#6). Other doc fixes, tests.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.1.1</b> — <small><i>May 14, 2013</i></small><br />
|
||
Bug fixes for sub-queries, minor changes to initializing "main" instance, adding "pg" as
|
||
a valid parameter for the client name in the connection settings.
|
||
</p>
|
||
|
||
<p>
|
||
<b class="header">0.1.0</b> — <small><i>May 13, 2013</i></small><br />
|
||
Initial Knex release.
|
||
</p>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
<script src="docs/assets/ga.js"></script>
|
||
<script src="docs/assets/lodash.js"></script>
|
||
<script src="docs/assets/jquery.min.js"></script>
|
||
<script src="docs/assets/jquery.cookie.js"></script>
|
||
<script src="docs/assets/highlight.min.js"></script>
|
||
<script src="/browser/knex.js"></script>
|
||
<script>
|
||
var trx = {}, dialects = {};
|
||
|
||
// Feel free to play with these in the console.
|
||
var knex = Knex({client: 'websql'});
|
||
var pg = dialects.pg = Knex({client: 'pg'});
|
||
var mysql = dialects.mysql = Knex({client: 'mysql'});
|
||
var sqlite3 = dialects.sqlite3 = Knex({client: 'sqlite3'});
|
||
var oracle = dialects.oracle = Knex({client: 'oracle'});
|
||
|
||
$(function() {
|
||
var setDialect = function(dialect) {
|
||
$.cookie('dialect', dialect, { expires: 7, path: '/' });
|
||
return dialect;
|
||
};
|
||
var displayDialect = function(dialect) {
|
||
$('.display').each(function() {
|
||
var code = $(this).data('code') || $(this).data('code', $(this).text()).data('code');
|
||
try {
|
||
var blocks = code.split('\n\n')
|
||
blocks[blocks.length - 1] = 'return (' + blocks[blocks.length - 1] + ').toString()';
|
||
$(this).html('<code class="js">' + code + '</code><br /><br />Outputs:<br /><code class="sql">' + new Function('knex', 'trx', blocks.join('\n\n'))(dialects[dialect], trx)) + '</code>';
|
||
} catch (e) {
|
||
console.error(e);
|
||
}
|
||
});
|
||
$('pre code').each(function(i, block) {
|
||
hljs.highlightBlock(block);
|
||
});
|
||
};
|
||
var currentDialect = $.cookie('dialect') || setDialect('mysql');
|
||
$('.js-query-output').on('change', function(e) {
|
||
displayDialect(setDialect(e.target.value));
|
||
});
|
||
$('.js-query-output').val(currentDialect);
|
||
displayDialect(currentDialect);
|
||
|
||
// Don't show the full change log.
|
||
$(".js-change-log").on('click', function(e) {
|
||
e.preventDefault();
|
||
$(this).remove();
|
||
$('.change-log').show();
|
||
});
|
||
});
|
||
</script>
|
||
</body>
|
||
</html>
|