mirror of
https://github.com/knex/knex.git
synced 2025-12-27 23:18:41 +00:00
final commit for 0.1.0
This commit is contained in:
parent
e5fd8df44a
commit
0b3433b7b2
9
CONTRIBUTING.md
Normal file
9
CONTRIBUTING.md
Normal file
@ -0,0 +1,9 @@
|
||||
## How to contribute to Knex.js
|
||||
|
||||
* Before sending a pull request for a feature or bug fix, be sure to have
|
||||
[tests](https://github.com/tgriesser/knex/tree/master/test).
|
||||
|
||||
* Use the same coding style as the rest of the
|
||||
[codebase](https://github.com/tgriesser/knex/blob/master/knex.js).
|
||||
|
||||
* All pull requests should be made to the `master` branch.
|
||||
22
LICENSE
Normal file
22
LICENSE
Normal file
@ -0,0 +1,22 @@
|
||||
Copyright (c) 2013 Tim Griesser
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
@ -18,4 +18,6 @@
|
||||
|
||||
Knex.js is a multi-dialect query builder for Node.js.
|
||||
|
||||
[http://knexjs.org](knexjs.org)
|
||||
For Docs, License, Tests, FAQ, and other information, see: http://knexjs.org
|
||||
|
||||
To suggest a feature, report a bug, or general discussion: http://github.com/tgriesser/knex/issues/
|
||||
794
docs/knex.html
794
docs/knex.html
File diff suppressed because it is too large
Load Diff
379
index.html
379
index.html
@ -66,6 +66,9 @@
|
||||
width: 550px;
|
||||
margin: 40px 0 50px 260px;
|
||||
}
|
||||
div.container ul.small {
|
||||
font-size: 12px;
|
||||
}
|
||||
img#logo {
|
||||
width: 450px;
|
||||
}
|
||||
@ -192,6 +195,9 @@
|
||||
<a class="toc_title" href="#Initialize">
|
||||
Initialize
|
||||
</a>
|
||||
<ul class="toc_section">
|
||||
<li>– <a href="#Init-multi-instance">multi-instance</a></li>
|
||||
</ul>
|
||||
|
||||
<a class="toc_title" href="#Builder">
|
||||
Builder
|
||||
@ -200,7 +206,7 @@
|
||||
<li>– <a href="#Builder-main"><b>constructor</b></a></li>
|
||||
<li>– <a href="#Builder-select">select</a></li>
|
||||
<li>– <a href="#Builder-from">from</a></li>
|
||||
<li>– <a href="#Builder-where">where <b>16 methods</b></a></li>
|
||||
<li>– <a href="#Builder-where">where <b>+18 methods</b></a></li>
|
||||
<li>– <a href="#Builder-distinct">distinct</a></li>
|
||||
<li>– <a href="#Builder-join">join</a></li>
|
||||
<li>– <a href="#Builder-groupBy">groupBy</a></li>
|
||||
@ -208,20 +214,23 @@
|
||||
<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-insert">insert *</a></li>
|
||||
<li>– <a href="#Builder-update">update *</a></li>
|
||||
<li>– <a href="#Builder-del">del / delete *</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-update">update</a></li>
|
||||
<li>– <a href="#Builder-del">del / delete</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-truncate">truncate</a></li>
|
||||
<li>– <a href="#Builder-debug">debug</a></li>
|
||||
<li><b><a href="#Schema-Building">Interface:</a></b></li>
|
||||
<li><b><a href="#Builder-Interface">Interface:</a></b></li>
|
||||
<li>– <a href="#Builder-then">then</a></li>
|
||||
<li>– <a href="#Builder-exec">exec</a></li>
|
||||
<li>– <a href="#Builder-then">toString</a></li>
|
||||
</ul>
|
||||
|
||||
<a class="toc_title" href="#Transaction">
|
||||
@ -255,11 +264,17 @@
|
||||
<li>– <a href="#Schema-binary">binary</a></li>
|
||||
<li>– <a href="#Schema-enum">enum / enu</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-defaultTo">defaultTo</a></li>
|
||||
<li>– <a href="#Chainable-unsigned">unsigned</a></li>
|
||||
<li>– <a href="#Chainable-nullable">nullable</a></li>
|
||||
</ul>
|
||||
|
||||
<a class="toc_title" href="#Raw">
|
||||
Raw
|
||||
</a>
|
||||
|
||||
<a class="toc_title" href="#faq">
|
||||
F.A.Q.
|
||||
@ -278,11 +293,11 @@
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Knex.js</b> is a multi-dialect sql builder, designed to be flexible, portable, and fun to use.
|
||||
It features both traditional node style <a href="#Builder-exec">callbacks</a> as well
|
||||
as a <a href="#Builder-then">promise</a> interface for cleaner async flow control, full featured
|
||||
Knex.js is a query builder for <b>Postgres</b>, <b>MySql</b> and <b>SQLite3</b>, designed to be flexible,
|
||||
portable, and fun to use. It features both traditional node style <a href="#Builder-exec">callbacks</a>
|
||||
as well as a <a href="#Builder-then">promise</a> interface for cleaner async flow control, full featured
|
||||
query and schema builders, transaction support, connection pooling and node.js adapters for
|
||||
postgres, mysql, and sqlite3 - standardizing the responses between the three.
|
||||
postgres, mysql, and sqlite3 - standardizing responses between the three.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@ -291,10 +306,6 @@
|
||||
and has a comprehensive <a href="https://travis-ci.org/tgriesser/knex">test suite</a>.
|
||||
</p>
|
||||
|
||||
<a href="https://travis-ci.org/tgriesser/knex">
|
||||
<img src="https://travis-ci.org/tgriesser/knex.png?branch=master" alt="Travis Badge">
|
||||
</a>
|
||||
|
||||
<p>
|
||||
Knex is available for use under the <a href="http://github.com/tgriesser/knex/blob/master/LICENSE">MIT software license</a>.
|
||||
</p>
|
||||
@ -302,10 +313,21 @@
|
||||
<p>
|
||||
You can report bugs and discuss features on the
|
||||
<a href="http://github.com/tgriesser/knex/issues">GitHub issues page</a>,
|
||||
post questions to the <a href="https://groups.google.com/forum/?fromgroups#!forum/bookshelfjs">Google Group</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>
|
||||
|
||||
<h2>Latest Release: 0.1.0</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>
|
||||
|
||||
|
||||
<p>
|
||||
Special thanks to <a href="https://twitter.com/taylorotwell">Taylor Otwell</a> and his work
|
||||
on the <a href="http://four.laravel.com/docs/queries">Laravel Query Builder</a>,
|
||||
@ -324,7 +346,7 @@
|
||||
adapter and specify it in <a href="#Initialize">Knex.Initialize</a>.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
<pre>
|
||||
$ npm install knex
|
||||
|
||||
# Then add one of the following:
|
||||
@ -354,7 +376,7 @@ Knex.Initialize({
|
||||
});
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
<p id="Init-multi-instance">
|
||||
It is also possible to use Knex with multiple database connection instances if you'd like,
|
||||
by creating named instances. To do this, pass the name of the connection as the first
|
||||
parameter into <tt>Knex.Initialize</tt> and it will return that instance, which may
|
||||
@ -431,46 +453,87 @@ SqliteDB('users')
|
||||
<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 ______ methods.
|
||||
in the advanced <a href="#Builder-where">where</a> or <a href="#Builder-union">union</a> methods.
|
||||
</p>
|
||||
|
||||
<p id="Builder-where">
|
||||
<b class="header">where</b><code>.where(~dynamic~)</code>
|
||||
<br />
|
||||
One of the most flexible and imporant pieces of Knex, is the <tt>where</tt> clause generation.
|
||||
<br />
|
||||
There are several different types of arguments where may take, and several helper methods to simplify
|
||||
or, and, whereIn, etc.
|
||||
</p>
|
||||
There are several helpers for creating dynamic <tt>where</tt> clauses on queries.
|
||||
|
||||
<pre>
|
||||
// Basic Uses:
|
||||
|
||||
.where('id', '=', 1).where('used_count', '>', 10);
|
||||
Knex('users').where('votes', '>', 100).exec(function(err, resp) { ... });
|
||||
|
||||
.where('title', 'like', 'test').orWhere('title', 'like', 'fail');
|
||||
Knex('users').where('votes', '>', 100)
|
||||
.orWhere('name', 'John')
|
||||
.then(function(resp) { ... })
|
||||
|
||||
.where({email: 'test@example.com'}).and('other_key', 2)
|
||||
Knex('users').whereBetween('votes', [1, 100]).exec(...
|
||||
|
||||
Knex('users').whereIn('id', [1, 2, 3]).then(...
|
||||
|
||||
Knex('users').whereNotIn('id', [1, 2, 3]).then(...
|
||||
|
||||
Knex('users').whereNull('updated_at').exec(...
|
||||
|
||||
</pre>
|
||||
|
||||
<h3>Additional Where Methods:</h3>
|
||||
<p>
|
||||
<b>Grouped Where Clauses:</b>
|
||||
</p>
|
||||
|
||||
<ul class="small">
|
||||
<li><b>andWhere(column, operator, value)</b> — alias to standard "where" clause.</li>
|
||||
<li><b>orWhere(column, operator, value)</b> — adds an <tt>or where</tt> clause.</li>
|
||||
<li><b>whereExists(callback)</b> — </li>
|
||||
<li><b>whereNotExists(callback)</b> — </li>
|
||||
</ul>
|
||||
<pre>
|
||||
// select * from users where name = 'John' or (votes > 100 and title <> 'Admin')
|
||||
Knex('users')
|
||||
.where('name', '=', 'John')
|
||||
.orWhere(function() {
|
||||
this.where('votes', '>', 100).andWhere('title', '<>', 'Admin');
|
||||
})
|
||||
.then(function() {...
|
||||
</pre>
|
||||
|
||||
<h3>Advanced Where Methods:</h3>
|
||||
<p>
|
||||
<b>Exists Statements:</b>
|
||||
</p>
|
||||
|
||||
<ul class="small">
|
||||
<li><b>andWhere(column, operator, value)</b> — Alias to default where.</li>
|
||||
<li><b>orWhere(column, operator, value)</b> — adds an <tt>or where</tt> clause.</li>
|
||||
<li><b>whereExists(callback)</b> — </li>
|
||||
<li><b>whereNotExists(callback)</b> — </li>
|
||||
</ul>
|
||||
<pre>
|
||||
Knex('users')
|
||||
.whereExists(function() {
|
||||
this.select(Knex.raw(1))
|
||||
.from('orders')
|
||||
.whereRaw('orders.user_id = users.id');
|
||||
})
|
||||
.then(...
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
These different where clauses may be joined together in any number of ways to make valid SQL statements.
|
||||
</p>
|
||||
|
||||
<ul class="small">
|
||||
<li><a href="docs/knex.html#section-57">where</a></li>
|
||||
<li><a href="docs/knex.html#section-58">andWhere</a></li>
|
||||
<li><a href="docs/knex.html#section-59">orWhere</a></li>
|
||||
<li><a href="docs/knex.html#section-60">whereRaw</a></li>
|
||||
<li><a href="docs/knex.html#section-61">orWhereRaw</a></li>
|
||||
<li><a href="docs/knex.html#section-62">whereExists</a></li>
|
||||
<li><a href="docs/knex.html#section-63">orWhereExists</a></li>
|
||||
<li><a href="docs/knex.html#section-64">whereNotExists</a></li>
|
||||
<li><a href="docs/knex.html#section-65">orWhereNotExists</a></li>
|
||||
<li><a href="docs/knex.html#section-66">whereIn</a></li>
|
||||
<li><a href="docs/knex.html#section-67">orWhereIn</a></li>
|
||||
<li><a href="docs/knex.html#section-68">whereNotIn</a></li>
|
||||
<li><a href="docs/knex.html#section-69">orWhereNotIn</a></li>
|
||||
<li><a href="docs/knex.html#section-70">whereNull</a></li>
|
||||
<li><a href="docs/knex.html#section-71">orWhereNull</a></li>
|
||||
<li><a href="docs/knex.html#section-72">whereNotNull</a></li>
|
||||
<li><a href="docs/knex.html#section-73">orWhereNotNull</a></li>
|
||||
<li><a href="docs/knex.html#section-74">whereBetween</a></li>
|
||||
<li><a href="docs/knex.html#section-75">orWhereBetween</a></li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p id="Builder-distinct">
|
||||
<b class="header">distinct</b><code>.distinct()</code>
|
||||
@ -486,25 +549,35 @@ Knex('customers')
|
||||
</pre>
|
||||
|
||||
<p id="Builder-join">
|
||||
<b class="header">join</b><code>.join(~mixed~)</code>
|
||||
<b class="header">join</b><code>.join(table, first, operator, second, [type])</code>
|
||||
<br />
|
||||
The <tt>join</tt> builder can be used several different ways
|
||||
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. The last argument is optional and spefies the type of join.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
// select distinct 'name' FROM customers WHERE `order_date` > NOW()
|
||||
Knex('customers')
|
||||
.where('order_date', '>', Knex.raw('NOW()'))
|
||||
.distinct()
|
||||
.select('id', 'name')
|
||||
Knex('users')
|
||||
.join('contacts', 'users.id', '=', 'contacts.user_id')
|
||||
.join('orders', 'users.id', '=', 'orders.user_id', 'outer')
|
||||
.select('users.id', 'contacts.phone', 'orders.price')
|
||||
.then(function() { ... });
|
||||
</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>
|
||||
// select distinct 'name' FROM customers WHERE `order_date` > NOW()
|
||||
Knex('customers')
|
||||
.where('order_date', '>', Knex.raw('NOW()'))
|
||||
.distinct()
|
||||
.select('id', 'name')
|
||||
</pre>
|
||||
Knex('users')
|
||||
.join('contacts', function() {
|
||||
this.on('users.id', '=', 'contacts.user_id').orOn(...);
|
||||
})
|
||||
.exec(function(err, resp) { ... });
|
||||
</pre>
|
||||
|
||||
</p>
|
||||
|
||||
@ -554,44 +627,69 @@ Knex('users')
|
||||
.select()
|
||||
</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>
|
||||
|
||||
<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>
|
||||
Knex('users').whereNull('last_name').union(function() {
|
||||
|
||||
this.select('*').from('users').whereNull('first_name');
|
||||
|
||||
}).select().then(function() { ... });
|
||||
</pre>
|
||||
|
||||
<p id="Builder-insert">
|
||||
<b class="header">insert</b><code>.insert(data)</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.
|
||||
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>
|
||||
// generates: "insert into `books`
|
||||
// Returns [1]
|
||||
Knex('books').insert({title: 'Slaughterhouse Five'})
|
||||
|
||||
// generates "select * from `books`;"
|
||||
// Returns [2] in "mysql", "sqlite"; [2, 3] in "postgresql"
|
||||
Knex('books')
|
||||
.insert([{title: 'Great Gatsby'}, {title: ''}])
|
||||
|
||||
.insert([{title: 'Great Gatsby'}, {title: 'Fahrenheit 451'}])
|
||||
</pre>
|
||||
|
||||
|
||||
<p id="Builder-update">
|
||||
<b class="header">update</b><code>.update(data)</code>
|
||||
<br />
|
||||
Creates an <tt>update</tt> query, taking either a hash of properties to be updated into the row, or
|
||||
an array of updates, to be executed as a single update command.
|
||||
Creates an <tt>update</tt> query, taking a hash of properties 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>
|
||||
Knex('books').update({
|
||||
title: '',
|
||||
author: '',
|
||||
year: 2014
|
||||
})
|
||||
Knex('books')
|
||||
.where('published_date', '<', 2000)
|
||||
.update({
|
||||
status: 'archived'
|
||||
})
|
||||
.then(...
|
||||
</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.
|
||||
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>
|
||||
@ -603,43 +701,37 @@ Knex('accounts')
|
||||
<p id="Builder-count">
|
||||
<b class="header">count</b><code>.count(column)</code>
|
||||
<br />
|
||||
Performs a count on the specified column.
|
||||
Performs a count on the specified <b>column</b>.
|
||||
</p>
|
||||
|
||||
<p id="Builder-min">
|
||||
<b class="header">min</b><code>.min(column)</code>
|
||||
<br />
|
||||
Gets the minimum value for the specified column.
|
||||
Gets the minimum value for the specified <b>column</b>.
|
||||
</p>
|
||||
|
||||
<p id="Builder-max">
|
||||
<b class="header">max</b><code>.max(column)</code>
|
||||
<br />
|
||||
Gets the maximum value for the specified column.
|
||||
Gets the maximum value for the specified <b>column</b>.
|
||||
</p>
|
||||
|
||||
<p id="Builder-sum">
|
||||
<b class="header">sum</b><code>.sum(column)</code>
|
||||
<br />
|
||||
Retrieve the sum of the values of a given column.
|
||||
Retrieve the sum of the values of a given <b>column</b>.
|
||||
</p>
|
||||
|
||||
<p id="Builder-increment">
|
||||
<b class="header">increment</b><code>.increment(column, value)</code>
|
||||
<b class="header">increment</b><code>.increment(column, amount)</code>
|
||||
<br />
|
||||
Increments a column's value by the specified amount.
|
||||
Increments a <b>column</b> value by the specified <b>amount</b>.
|
||||
</p>
|
||||
|
||||
<p id="Builder-decrement">
|
||||
<b class="header">decrement</b><code>.decrement(column, value)</code>
|
||||
<b class="header">decrement</b><code>.decrement(column, amount)</code>
|
||||
<br />
|
||||
Decrements a column's value by the specified amount.
|
||||
</p>
|
||||
|
||||
<p id="Builder-increment">
|
||||
<b class="header">increment</b><code>.increment(column, value)</code>
|
||||
<br />
|
||||
Increments a column's value by the specified amount.
|
||||
Decrements a <b>column</b> value by the specified <b>amount</b>.
|
||||
</p>
|
||||
|
||||
<p id="Builder-truncate">
|
||||
@ -654,6 +746,33 @@ Knex('accounts')
|
||||
Turns on debugging for the current query chain.
|
||||
</p>
|
||||
|
||||
<h3 id="Builder-Interface">Builder Interface Methods:</h3>
|
||||
|
||||
<p id="Builder-then">
|
||||
<b class="header">then</b><code>.then(onFulfilled, onRejected)</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>
|
||||
|
||||
<p id="Builder-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="#Builder-then">then</a> method, subsequent calls to the same
|
||||
query chain will return the same result.
|
||||
</p>
|
||||
|
||||
<p id="Builder-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>
|
||||
|
||||
<h2 id="Transaction">Knex.Transaction</h2>
|
||||
|
||||
<p>
|
||||
@ -671,7 +790,7 @@ Knex.Transaction(function(t) {
|
||||
.insert({name: 'Old Books'})
|
||||
.then(function(row) {
|
||||
|
||||
return Q.all(_.map([
|
||||
return When.all(_.map([
|
||||
{title: 'Canterbury Tales'},
|
||||
{title: 'Moby Dick'},
|
||||
{title: 'Hamlet'}
|
||||
@ -683,7 +802,6 @@ Knex.Transaction(function(t) {
|
||||
return Knex('book').transacting(t).insert(info);
|
||||
|
||||
}));
|
||||
|
||||
})
|
||||
.then(t.commit, t.rollback);
|
||||
|
||||
@ -712,12 +830,36 @@ Knex.Schema.create('users', function (table) {
|
||||
});
|
||||
</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>
|
||||
|
||||
<p id="Schema-dropTable">
|
||||
<b class="header">dropTable</b><code>Knex.Schema.dropTable(tableName)</code>
|
||||
<br />
|
||||
Drops a table, specified by <tt>tableName</tt>.
|
||||
Drops a table, specified by <b>tableName</b>.
|
||||
</p>
|
||||
|
||||
<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>, with an error or failed promise if
|
||||
the requested table does not exist.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
Knex.Schema.hasTable('users').then(null, function() {
|
||||
return Knex.Schema.createTable('users', function(t) {
|
||||
t.increments('id').primary();
|
||||
t.string('first_name', 100);
|
||||
t.string('last_name', 100);
|
||||
t.text('bio');
|
||||
});
|
||||
});
|
||||
</pre>
|
||||
|
||||
<p id="Schema-dropTableIfExists">
|
||||
<b class="header">dropTableIfExists</b><code>Knex.Schema.dropTableIfExists(tableName)</code>
|
||||
<br />
|
||||
@ -741,24 +883,19 @@ Knex.Schema.table('users', function (table) {
|
||||
});
|
||||
</pre>
|
||||
|
||||
<p id="Schema-connection">
|
||||
<b class="header">connection</b><code>Knex.Schema.connection()</code>
|
||||
<br />
|
||||
Optional method to explicitly specifiy the
|
||||
</p>
|
||||
|
||||
<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.
|
||||
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 />
|
||||
Takes a variable number of column names, and drops them.
|
||||
Drops multiple columns, taking a variable number of column names.
|
||||
</p>
|
||||
|
||||
<p id="Schema-increments">
|
||||
@ -845,32 +982,38 @@ Knex.Schema.table('users', function (table) {
|
||||
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 integer as index. No-op if this is chained off of a non-integer field.
|
||||
</p>
|
||||
|
||||
<p id="Chainable-defaultTo">
|
||||
<b class="header">defaultTo</b><code>.defaultTo(value)</code>
|
||||
<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>.unsigned()</code>
|
||||
<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-nullable">
|
||||
<b class="header">nullable</b><code>.nullable()</code>
|
||||
<b class="header">nullable</b><code>column.nullable()</code>
|
||||
<br />
|
||||
Allows a field to be nullable. No-op if chained off of a non-nullable field.
|
||||
</p>
|
||||
|
||||
<p id="Chainable-nullable">
|
||||
<b class="header">nullable</b><code>.nullable()</code>
|
||||
<b class="header">nullable</b><code>column.nullable()</code>
|
||||
<br />
|
||||
Allows a field to be nullable. No-op if chained off of a non-nullable field.
|
||||
</p>
|
||||
|
||||
<p id="Chainable-primary">
|
||||
<b class="header">primary</b><code>.primary()</code>
|
||||
<b class="header">primary</b><code>column.primary()</code>
|
||||
<br />
|
||||
Sets the field as the primary key for the table.
|
||||
</p>
|
||||
@ -882,7 +1025,39 @@ Knex.createTable('accounts', function() {
|
||||
});
|
||||
</pre>
|
||||
|
||||
<h2 id="Knex-client">Knex.client</h2>
|
||||
<h2 id="Raw">Knex.Raw</h2>
|
||||
|
||||
<h3 id="Raw-Expression">Raw Expressions:</h3>
|
||||
|
||||
<p>
|
||||
Sometimes you may need to use a raw expression in a query. These expressions will be injected
|
||||
into the query as strings, so be careful not to create any SQL injection points!
|
||||
To create a raw expression, you may use the <tt>Knex.Raw</tt> function.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
Knex('users')
|
||||
.select(Knex.Raw('count(*) as user_count, status'))
|
||||
.where('status', '<>', 1)
|
||||
.groupBy('status')
|
||||
.get();
|
||||
</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.
|
||||
Note that the response will be whatever the underlying sql library would typically return on a
|
||||
normal query, so you may need to
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
Knex.Raw('select * from users where id = 1').then(function(resp) {
|
||||
...
|
||||
});
|
||||
</pre>
|
||||
|
||||
<h2 id="faq">F.A.Q.</h2>
|
||||
|
||||
@ -897,11 +1072,12 @@ Knex.createTable('accounts', function() {
|
||||
|
||||
<p id="faq-tests">
|
||||
<b class="header">How do I run the test suite?</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.
|
||||
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:
|
||||
<tt>$ export KNEX_TEST='/path/to/your/knex_config.js'</tt>, replacing with the path to your config file,
|
||||
and the config file is valid, the test suite should run with <tt>npm test</tt>. If you're going to
|
||||
add a test, you may want to follow similar patterns, used in the test suite,
|
||||
setting <tt>$ export KNEX_DEV=1</tt> to save the outputs data from the tests into the <tt>shared/output.js</tt> file.
|
||||
</p>
|
||||
|
||||
<p id="faq-nonode">
|
||||
@ -911,11 +1087,10 @@ Knex.createTable('accounts', function() {
|
||||
database, by providing a custom <a href="http://knexjs.org/#Adapters">Knex adapter</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<h2 id="changelog">Change Log</h2>
|
||||
|
||||
<p>
|
||||
<b class="header">0.1.0</b> — <small><i>TBD</i></small><br />
|
||||
<b class="header">0.1.0</b> — <small><i>May 13, 2013</i></small><br />
|
||||
Initial Knex release.
|
||||
</p>
|
||||
|
||||
|
||||
56
knex.js
56
knex.js
@ -56,12 +56,10 @@
|
||||
return this._promise.then(onFulfilled, onRejected);
|
||||
},
|
||||
|
||||
// Specifies to resolve the statement with the `data` rather
|
||||
// than a promise... useful in testing/debugging.
|
||||
// Returns an array of query strings filled out with the
|
||||
// correct values based on bindings, etc. Useful for debugging.
|
||||
toString: function() {
|
||||
if (!this.type) {
|
||||
throw new Error('Cannot be converted to string');
|
||||
}
|
||||
this.type || (this.type = 'select');
|
||||
var data = this.toSql();
|
||||
var builder = this;
|
||||
if (!_.isArray(data)) data = [data];
|
||||
@ -73,7 +71,7 @@
|
||||
}).join('; ');
|
||||
},
|
||||
|
||||
// Sets the connection
|
||||
// Explicitly sets the connection.
|
||||
connection: function(connection) {
|
||||
this._connection = connection;
|
||||
return this;
|
||||
@ -461,7 +459,8 @@
|
||||
return this;
|
||||
},
|
||||
|
||||
// Select a `column` rather than
|
||||
// Adds a column to the list of "columns" being selected
|
||||
// on the query.
|
||||
column: function(value) {
|
||||
this.columns.push(value);
|
||||
return this;
|
||||
@ -474,7 +473,9 @@
|
||||
return this;
|
||||
},
|
||||
|
||||
// Compiles the current query builder.
|
||||
toSql: function() {
|
||||
this.type || (this.type = 'select');
|
||||
return this.grammar['compile' + capitalize(this.type)](this);
|
||||
},
|
||||
|
||||
@ -561,27 +562,28 @@
|
||||
return this.where.apply(this, arguments);
|
||||
},
|
||||
|
||||
whereRaw: function(sql, bindings, bool) {
|
||||
bindings || (bindings = []);
|
||||
bool || (bool = 'and');
|
||||
this.wheres.push({type:'raw', sql:sql, bool:bool});
|
||||
push.apply(this.bindings, bindings);
|
||||
return this;
|
||||
},
|
||||
|
||||
orWhereRaw: function(sql, bindings) {
|
||||
return this.whereRaw(sql, bindings, 'or');
|
||||
},
|
||||
|
||||
// Adds an `or where` clause to the query.
|
||||
orWhere: function(column, operator, value) {
|
||||
return this.where(column, operator, value, 'or');
|
||||
},
|
||||
|
||||
// Adds a raw `where` clause to the query.
|
||||
whereRaw: function(sql, bindings, bool) {
|
||||
bindings || (bindings = []);
|
||||
bool || (bool = 'and');
|
||||
this.wheres.push({type: 'Raw', sql:sql, bool:bool});
|
||||
push.apply(this.bindings, bindings);
|
||||
return this;
|
||||
},
|
||||
|
||||
// Adds a raw `or where` clause to the query.
|
||||
orWhereRaw: function(sql, bindings) {
|
||||
return this.whereRaw(sql, bindings, 'or');
|
||||
},
|
||||
|
||||
// Adds a `where exists` clause to the query.
|
||||
whereExists: function(callback, bool, type) {
|
||||
var query = new Builder(this);
|
||||
query.isSubQuery = true;
|
||||
callback.call(query, query);
|
||||
this.wheres.push({
|
||||
type: (type || 'Exists'),
|
||||
@ -707,13 +709,13 @@
|
||||
},
|
||||
|
||||
havingRaw: function(sql, bindings) {
|
||||
this.havings.push({type: 'raw', sql: sql, bool: 'and'});
|
||||
this.havings.push({type: 'Raw', sql: sql, bool: 'and'});
|
||||
this.bindings.push(bindings);
|
||||
return this;
|
||||
},
|
||||
|
||||
orHavingRaw: function(sql, bindings) {
|
||||
this.havings.push({type: 'raw', sql: sql, bool: 'or'});
|
||||
this.havings.push({type: 'Raw', sql: sql, bool: 'or'});
|
||||
this.bindings.push(bindings);
|
||||
return this;
|
||||
},
|
||||
@ -829,19 +831,19 @@
|
||||
return values;
|
||||
},
|
||||
|
||||
// Helper for compiling any advanced `where in` queries.
|
||||
_whereInSub: function(column, callback, bool, condition) {
|
||||
var type = condition ? 'NotInSub' : 'InSub';
|
||||
var query = new Builder(this);
|
||||
query.isSubQuery = true;
|
||||
callback.call(query, query);
|
||||
this.wheres.push({type: type, column: column, query: query, bool: bool});
|
||||
push.apply(this.bindings, query.bindings);
|
||||
return this;
|
||||
},
|
||||
|
||||
// Helper for compiling any advanced `where` queries.
|
||||
_whereNested: function(callback, bool) {
|
||||
var query = new Builder(this);
|
||||
query.isSubQuery = true;
|
||||
query.table = this.table;
|
||||
callback.call(query, query);
|
||||
this.wheres.push({type: 'Nested', query: query, bool: bool});
|
||||
@ -849,9 +851,9 @@
|
||||
return this;
|
||||
},
|
||||
|
||||
// Helper for compiling any of the `where` advanced queries.
|
||||
_whereSub: function(column, operator, callback, bool) {
|
||||
var query = new Builder(this);
|
||||
query.isSubQuery = true;
|
||||
callback.call(query, query);
|
||||
this.wheres.push({
|
||||
type: 'Sub',
|
||||
@ -864,21 +866,23 @@
|
||||
return this;
|
||||
},
|
||||
|
||||
// Helper for compiling any aggregate queries.
|
||||
_aggregate: function(type, columns) {
|
||||
if (!_.isArray(columns)) columns = [columns];
|
||||
this.aggregate = {type: type, columns: columns};
|
||||
return this._setType('select');
|
||||
},
|
||||
|
||||
// Helper for the incrementing/decrementing queries.
|
||||
_counter: function(column, amount, symbol) {
|
||||
var sql = {};
|
||||
sql[column] = new Raw('' + this.grammar.wrap(column) + ' ' + (symbol || '+') + ' ' + amount);
|
||||
return this.update(sql);
|
||||
},
|
||||
|
||||
// Helper for compiling any `union` queries.
|
||||
_union: function(callback, bool) {
|
||||
var query = new Builder(this);
|
||||
query.isSubQuery = true;
|
||||
callback.call(query, query);
|
||||
this.unions.push({query: query, all: bool});
|
||||
push.apply(this.bindings, query.bindings);
|
||||
|
||||
11
package.json
11
package.json
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "knex",
|
||||
"version": "0.0.5",
|
||||
"description": "a fun sql query builder",
|
||||
"version": "0.1.0",
|
||||
"description": "A fun, multi-dialect SQL query builder.",
|
||||
"main": "knex.js",
|
||||
"directories": {
|
||||
"test": "test"
|
||||
@ -25,7 +25,12 @@
|
||||
"keywords": [
|
||||
"sql",
|
||||
"query",
|
||||
"builder"
|
||||
"builder",
|
||||
"postgresql",
|
||||
"postgres",
|
||||
"mysql",
|
||||
"sqlite3",
|
||||
"sqlite"
|
||||
],
|
||||
"author": "Tim Griesser",
|
||||
"license": "MIT"
|
||||
|
||||
@ -90,6 +90,17 @@ module.exports = function(Knex, dbName, resolver) {
|
||||
.then(resolver(ok), ok);
|
||||
});
|
||||
|
||||
it('does whereRaw', function(ok) {
|
||||
Knex('accounts')
|
||||
.whereExists(function() {
|
||||
this.select(Knex.Raw(1))
|
||||
.from('test_table_two')
|
||||
.whereRaw('test_table_two.account_id = accounts.id');
|
||||
})
|
||||
.select()
|
||||
.then(resolver(ok), ok);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
@ -448,6 +448,20 @@ module.exports = {
|
||||
bindings: [1,100,200,300]
|
||||
}
|
||||
},
|
||||
'selects.19': {
|
||||
mysql: {
|
||||
sql: ['select * from `accounts` where exists (select 1 from `test_table_two` where test_table_two.account_id = accounts.id)'],
|
||||
bindings: []
|
||||
},
|
||||
postgres: {
|
||||
sql: ['select * from "accounts" where exists (select 1 from "test_table_two" where test_table_two.account_id = accounts.id)'],
|
||||
bindings: []
|
||||
},
|
||||
sqlite3: {
|
||||
sql: ['select * from "accounts" where exists (select 1 from "test_table_two" where test_table_two.account_id = accounts.id)'],
|
||||
bindings: []
|
||||
}
|
||||
},
|
||||
'aggregate.1': {
|
||||
mysql: {
|
||||
sql: ['select sum(`logins`) as aggregate from `accounts`'],
|
||||
@ -1758,6 +1772,35 @@ module.exports = {
|
||||
phone: null
|
||||
}]
|
||||
},
|
||||
'selects.19': {
|
||||
mysql: [{
|
||||
id: 1,
|
||||
first_name: 'User',
|
||||
last_name: 'Test',
|
||||
email: 'test100@example.com',
|
||||
logins: 1,
|
||||
about: 'Lorem ipsum Dolore labore incididunt enim.',
|
||||
phone: null
|
||||
}],
|
||||
postgres: [{
|
||||
id: 1,
|
||||
first_name: 'User',
|
||||
last_name: 'Test',
|
||||
email: 'test100@example.com',
|
||||
logins: 1,
|
||||
about: 'Lorem ipsum Dolore labore incididunt enim.',
|
||||
phone: null
|
||||
}],
|
||||
sqlite3: [{
|
||||
id: 1,
|
||||
first_name: 'User',
|
||||
last_name: 'Test',
|
||||
email: 'test100@example.com',
|
||||
logins: 1,
|
||||
about: 'Lorem ipsum Dolore labore incididunt enim.',
|
||||
phone: null
|
||||
}]
|
||||
},
|
||||
'aggregate.1': {
|
||||
mysql: [{
|
||||
aggregate: 10
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user