diff --git a/knex/knex-test.ts b/knex/knex-test.ts
new file mode 100644
index 000000000..39b441d6b
--- /dev/null
+++ b/knex/knex-test.ts
@@ -0,0 +1,569 @@
+///
+///
+import Knex = require('knex');
+import _ = require('lodash');
+'use strict';
+// Initializing the Library
+var knex = Knex({
+ client: 'sqlite3',
+ connection: {
+ filename: "./mydb.sqlite"
+ }
+});
+
+var knex = Knex({
+ client: 'mysql',
+ connection: {
+ socketPath : '/path/to/socket.sock',
+ user : 'your_database_user',
+ password : 'your_database_password',
+ database : 'myapp_test'
+ }
+});
+
+// Pooling
+var knex = 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
+ }
+});
+
+// Migrations
+var knex = Knex({
+ client: 'mysql',
+ connection: {
+ host : '127.0.0.1',
+ user : 'your_database_user',
+ password : 'your_database_password',
+ database : 'myapp_test'
+ },
+ migrations: {
+ tableName: 'migrations'
+ }
+});
+
+// Knex Query Builder
+knex.select('title', 'author', 'year').from('books');
+knex.select().table('books');
+
+knex.avg('sum_column1').from(function() {
+ this.sum('column1 as sum_column1').from('t1').groupBy('column1').as('t1')
+}).as('ignored_alias');
+
+knex.column('title', 'author', 'year').select().from('books');
+knex.column(['title', 'author', 'year']).select().from('books');
+knex.select('*').from('users');
+
+knex('users').where({
+ first_name: 'Test',
+ last_name: 'User'
+}).select('id');
+
+knex('users').where('id', 1);
+
+knex('users').where(() => {
+ this.where('id', 1).orWhere('id', '>', 10)
+}).orWhere({name: 'Tester'});
+
+knex('users').where('votes', '>', 100);
+
+var subquery = knex('users').where('votes', '>', 100).andWhere('status', 'active').orWhere('name', 'John').select('id');
+knex('accounts').where('id', 'in', subquery);
+
+knex.select('name').from('users')
+ .whereIn('id', [1, 2, 3])
+ .orWhereIn('id', [4, 5, 6]);
+
+var subquery = knex.select('id').from('accounts');
+knex.select('name').from('users')
+ .whereIn('account_id', subquery);
+
+knex('users')
+ .where('name', '=', 'John')
+ .orWhere(function() {
+ this.where('votes', '>', 100).andWhere('title', '<>', 'Admin');
+ });
+
+knex('users').whereNotIn('id', [1, 2, 3]);
+
+knex('users').where('name', 'like', '%Test%').orWhereNotIn('id', [1, 2, 3]);
+
+knex('users').whereNull('updated_at');
+
+knex('users').whereNotNull('created_at');
+
+knex('users').whereExists(function() {
+ this.select('*').from('accounts').whereRaw('users.account_id = accounts.id');
+});
+
+knex('users').whereExists(knex.select('*').from('accounts').whereRaw('users.account_id = accounts.id'));
+
+knex('users').whereNotExists(function() {
+ this.select('*').from('accounts').whereRaw('users.account_id = accounts.id');
+});
+
+knex('users').whereBetween('votes', [1, 100]);
+
+knex('users').whereNotBetween('votes', [1, 100]);
+
+knex('users').whereRaw('id = ?', [1]);
+
+// Join methods
+knex('users')
+ .join('contacts', 'users.id', '=', 'contacts.user_id')
+ .select('users.id', 'contacts.phone');
+
+knex('users')
+ .join('contacts', 'users.id', 'contacts.user_id')
+ .select('users.id', 'contacts.phone');
+
+knex.select('*').from('users').join('accounts', function() {
+ this.on('accounts.id', '=', 'users.account_id').orOn('accounts.owner_id', '=', 'users.id')
+});
+
+knex.select('*').from('users').join('accounts', 'accounts.type', knex.raw('?', ['admin']));
+
+knex.from('users').innerJoin('accounts', 'users.id', 'accounts.user_id');
+
+knex.table('users').innerJoin('accounts', 'users.id', '=', 'accounts.user_id');
+
+knex('users').innerJoin('accounts', function() {
+ this.on('accounts.id', '=', 'users.account_id').orOn('accounts.owner_id', '=', 'users.id')
+});
+
+knex.select('*').from('users').leftJoin('accounts', 'users.id', 'accounts.user_id');
+
+knex.select('*').from('users').leftJoin('accounts', function() {
+ this.on('accounts.id', '=', 'users.account_id').orOn('accounts.owner_id', '=', 'users.id')
+});
+
+knex.select('*').from('users').leftOuterJoin('accounts', 'users.id', 'accounts.user_id');
+
+knex.select('*').from('users').leftOuterJoin('accounts', function() {
+ this.on('accounts.id', '=', 'users.account_id').orOn('accounts.owner_id', '=', 'users.id')
+});
+
+knex.select('*').from('users').rightJoin('accounts', 'users.id', 'accounts.user_id');
+
+knex.select('*').from('users').rightJoin('accounts', function() {
+ this.on('accounts.id', '=', 'users.account_id').orOn('accounts.owner_id', '=', 'users.id')
+});
+
+knex.select('*').from('users').rightOuterJoin('accounts', 'users.id', 'accounts.user_id');
+
+knex.select('*').from('users').rightOuterJoin('accounts', function() {
+ this.on('accounts.id', '=', 'users.account_id').orOn('accounts.owner_id', '=', 'users.id')
+});
+
+knex.select('*').from('users').outerJoin('accounts', 'users.id', 'accounts.user_id');
+
+knex.select('*').from('users').outerJoin('accounts', function() {
+ this.on('accounts.id', '=', 'users.account_id').orOn('accounts.owner_id', '=', 'users.id')
+});
+
+knex.select('*').from('users').fullOuterJoin('accounts', 'users.id', 'accounts.user_id');
+
+knex.select('*').from('users').fullOuterJoin('accounts', function() {
+ this.on('accounts.id', '=', 'users.account_id').orOn('accounts.owner_id', '=', 'users.id')
+});
+
+knex.select('*').from('users').crossJoin('accounts', 'users.id', 'accounts.user_id');
+
+knex.select('*').from('accounts').joinRaw('natural full join table1').where('id', 1);
+
+knex.select('*').from('accounts').join(knex.raw('natural full join table1')).where('id', 1);
+
+knex('customers')
+ .distinct('first_name', 'last_name')
+ .select();
+
+knex('users').groupBy('count');
+
+knex.select('year', knex.raw('SUM(profit)')).from('sales').groupByRaw('year WITH ROLLUP');
+
+knex('users').orderBy('name', 'desc');
+
+knex.select('*').from('table').orderByRaw('col NULLS LAST DESC');
+
+knex('books').insert({title: 'Slaughterhouse Five'});
+
+knex('coords').insert([{x: 20}, {y: 30}, {x: 10, y: 20}]);
+
+knex.insert([{title: 'Great Gatsby'}, {title: 'Fahrenheit 451'}], 'id').into('books');
+
+knex('books')
+ .returning('id')
+ .insert({title: 'Slaughterhouse Five'});
+
+knex('books')
+ .returning('id')
+ .insert([{title: 'Great Gatsby'}, {title: 'Fahrenheit 451'}]);
+
+knex('books')
+ .where('published_date', '<', 2000)
+ .update({
+ status: 'archived'
+ });
+
+knex('books').update('title', 'Slaughterhouse Five');
+
+knex('accounts')
+ .where('activated', false)
+ .del();
+
+var someExternalMethod: Function;
+
+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)
+ .catch(trx.rollback);
+
+}).then(function() {
+ console.log('Transaction complete.');
+}).catch(function(err) {
+ console.error(err);
+});
+
+knex.transaction(function(trx) {
+ knex('tableName')
+ .transacting(trx)
+ .forUpdate()
+ .select('*');
+
+ knex('tableName')
+ .transacting(trx)
+ .forShare()
+ .select('*')
+});
+
+knex('users').count('active');
+
+knex('users').min('age');
+
+knex('users').min('age as a');
+
+knex('users').max('age');
+
+knex('users').max('age as a');
+
+knex('users').sum('products');
+
+knex('users').sum('products as p');
+
+knex('users').avg('age');
+
+knex('users').avg('age as a');
+
+knex('accounts')
+ .where('userid', '=', 1)
+ .increment('balance', 10);
+
+knex('accounts').where('userid', '=', 1).decrement('balance', 5);
+
+knex('accounts').truncate();
+
+knex.table('users').pluck('id').then(function(ids) {
+ console.log(ids);
+});
+
+knex.table('users').first('id', 'name').then(function(row) {
+ console.log(row);
+});
+
+// Using trx as a query builder:
+knex.transaction(function(trx) {
+
+ var info: any;
+ var books: any[] = [
+ {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);
+});
+
+// Using trx as a transaction object:
+knex.transaction(function(trx) {
+
+ var info: any;
+ var books: any[] = [
+ {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)
+ .catch(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);
+});
+
+knex.schema.createTable('users', function (table) {
+ table.increments();
+ table.string('name');
+ table.timestamps();
+});
+
+knex.schema.renameTable('users', 'old_users');
+
+knex.schema.dropTable('users');
+
+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');
+ });
+ }
+});
+
+var tableName: string;
+var columnName: string;
+knex.schema.hasColumn(tableName, columnName);
+
+knex.schema.dropTableIfExists('users');
+
+knex.schema.table('users', function (table) {
+ table.dropColumn('name');
+ table.string('first_name');
+ table.string('last_name');
+});
+
+knex.schema.raw("SET sql_mode='TRADITIONAL'")
+.table('users', function (table) {
+ table.dropColumn('name');
+ table.string('first_name');
+ table.string('last_name');
+});
+
+knex('users')
+ .select(knex.raw('count(*) as user_count, status'))
+ .where(knex.raw(1))
+ .orWhere(knex.raw('status <> ?', [1]))
+ .groupBy('status');
+
+ knex.raw('select * from users where id = ?', [1]).then(function(resp) {
+ // ...
+ });
+
+(() => {
+ 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');
+})();
+
+(() => {
+ 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');
+})();
+
+var x: number;
+knex.select('name').from('users')
+ .where('id', '>', 20)
+ .andWhere('id', '<', 200)
+ .limit(10)
+ .offset(x)
+ .then(function(rows: any) {
+ return _.pluck(rows, 'name');
+ })
+ .then(function(names: any) {
+ return knex.select('id').from('nicknames').whereIn('nickname', names);
+ })
+ .then(function(rows) {
+ console.log(rows);
+ })
+ .catch(function(error) {
+ console.error(error)
+ });
+
+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);
+ });
+
+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);
+ });
+
+var query: any;
+query.then(function(x: any) {
+ // doSideEffectsHere(x);
+ return x;
+});
+
+knex.select('name').from('users').limit(10).map(function(row: any) {
+ return row.name;
+}).then(function(names) {
+ console.log(names);
+}).catch(function(e) {
+ console.error(e);
+});
+
+knex.select('name').from('users').limit(10).reduce(function(memo: any, row: any) {
+ memo.names.push(row.name);
+ memo.count++;
+ return memo;
+}, {count: 0, names: []}).then(function(obj) {
+ console.log(obj);
+}).catch(function(e) {
+ console.error(e);
+});
+
+knex.select('name').from('users')
+ .limit(10)
+ .bind(console)
+ .then(console.log)
+ .catch(console.error);
+
+var values: any[];
+// Without return:
+knex.insert(values).into('users')
+ .then(function() {
+ return {inserted: true};
+ });
+
+knex.insert(values).into('users').return({inserted: true});
+
+knex.select('name').from('users')
+ .where('id', '>', 20)
+ .andWhere('id', '<', 200)
+ .limit(10)
+ .offset(x)
+ .exec(function(err: any, rows: any[]) {
+ if (err) return console.error(err);
+ knex.select('id').from('nicknames').whereIn('nickname', _.pluck(rows, 'name'))
+ .exec(function(err: any, rows: any[]) {
+ if (err) return console.error(err);
+ console.log(rows);
+ });
+ });
+
+// Retrieve the stream:
+var stream = knex.select('*').from('users').stream();
+var writableStream: any;
+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: any) {
+ stream.pipe(writableStream);
+}).then(function() {
+ // ...
+}).catch(function(e: Error) {
+ console.error(e);
+});
+
+})();
+
+var stream = knex.select('*').from('users').pipe(writableStream);
+var app: any;
+
+knex.select('*')
+ .from('users')
+ .on('query', function(data: any) {
+ app.log(data);
+ })
+ .then(function() {
+ // ...
+ });
+
+ knex.select('*').from('users').where(knex.raw('id = ?', [1])).toString();
+
+ knex.select('*').from('users').where(knex.raw('id = ?', [1])).toSQL();
+
+//
+// Migrations
+//
+var config = { };
+knex.migrate.make(name, config);
+knex.migrate.make(name);
+
+knex.migrate.latest(config);
+knex.migrate.latest();
+
+knex.migrate.rollback(config);
+knex.migrate.rollback();
+
+knex.migrate.currentversion(config);
+knex.migrate.currentversion();
+
+knex.seed.make(name, config);
+knex.seed.make(name);
+
+knex.seed.run(config);
+knex.seed.run();
diff --git a/knex/knex.d.ts b/knex/knex.d.ts
new file mode 100644
index 000000000..d3216acf9
--- /dev/null
+++ b/knex/knex.d.ts
@@ -0,0 +1,457 @@
+// Type definitions for Knex.js
+// Project: https://github.com/tgriesser/knex
+// Definitions by: Qubo
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+///
+///
+
+declare module "knex" {
+ import Promise = require("bluebird");
+ import events = require("events");
+
+ type Callback = Function;
+ type Client = Function;
+ type Value = string|number|boolean|Date;
+ type ColumnName = string|Raw|QueryBuilder;
+
+ module KnexStatic {
+ interface ConfigStatic { }
+ }
+
+ interface KnexStatic {
+ (config: Config): Knex;
+ }
+
+ interface Knex extends QueryInterface { }
+
+ interface Knex {
+ (tableName?: string): QueryBuilder;
+ VERSION: string;
+ __knex__: string;
+
+ raw: RawBuilder;
+ transaction: (transactionScope: ((trx: Transaction) => void)) => Promise;
+ destroy(callback: Function): void;
+ destroy(): Promise;
+
+ client: any;
+ migrate: any;
+ seed: any;
+ fn: any;
+ }
+
+ //
+ // QueryInterface
+ //
+
+ interface QueryInterface {
+ select: Select;
+ as: As;
+ columns: Select;
+ column: Select;
+ from: Table;
+ into: Table;
+ table: Table;
+ distinct: Distinct;
+
+ // Joins
+ join: Join;
+ joinRaw: JoinRaw;
+ innerJoin: Join;
+ leftJoin: Join;
+ leftOuterJoin: Join;
+ rightJoin: Join;
+ rightOuterJoin: Join;
+ outerJoin: Join;
+ fullOuterJoin: Join;
+ crossJoin: Join;
+
+ // Wheres
+ where: Where;
+ andWhere: Where;
+ orWhere: Where;
+ whereRaw: WhereRaw;
+ whereWrapped: WhereWrapped;
+ havingWrapped: WhereWrapped;
+ orWhereRaw: WhereRaw;
+ whereExists: WhereExists;
+ orWhereExists: WhereExists;
+ whereNotExists: WhereExists;
+ orWhereNotExists: WhereExists;
+ whereIn: WhereIn;
+ orWhereIn: WhereIn;
+ whereNotIn: WhereIn;
+ orWhereNotIn: WhereIn;
+ whereNull: WhereNull;
+ orWhereNull: WhereNull;
+ whereNotNull: WhereNull;
+ orWhereNotNull: WhereNull;
+ whereBetween: WhereBetween;
+ whereNotBetween: WhereBetween;
+ orWhereBetween: WhereBetween;
+ orWhereNotBetween: WhereBetween;
+
+ // Group by
+ groupBy: GroupBy;
+ groupByRaw: RawQueryBuilder;
+
+ // Order by
+ orderBy: OrderBy;
+ orderByRaw: RawQueryBuilder;
+
+ // Union
+ union: Union;
+ unionAll(callback: Function): QueryBuilder;
+
+ // Having
+ having: Having;
+ havingRaw: RawQueryBuilder;
+ orHaving: Having;
+ orHavingRaw: RawQueryBuilder;
+
+ // Paging
+ offset(offset: number): QueryBuilder;
+ limit(limit: number): QueryBuilder;
+
+ // Aggregation
+ count(columnName?: string): QueryBuilder;
+ min(columnName: string): QueryBuilder;
+ max(columnName: string): QueryBuilder;
+ sum(columnName: string): QueryBuilder;
+ avg(columnName: string): QueryBuilder;
+ increment(columnName: string, amount?: number): QueryBuilder;
+ decrement(columnName: string, amount?: number): QueryBuilder;
+
+ // Others
+ first(...columns: string[]): QueryBuilder;
+
+ debug(enabled?: boolean): QueryBuilder;
+ pluck(column: string): QueryBuilder;
+
+ insert(data: any, returning?: string): QueryBuilder;
+ update(data: any, returning?: string): QueryBuilder;
+ update(columnName: string, value: Value, returning?: string): QueryBuilder;
+ returning(column: string): QueryBuilder;
+
+ del(returning?: string): QueryBuilder;
+ delete(returning?: string): QueryBuilder;
+ truncate(): QueryBuilder;
+
+ transacting(trx: Transaction): QueryBuilder;
+ connection(connection: any): QueryBuilder;
+ }
+
+ interface As {
+ (columnName: string): QueryBuilder;
+ }
+
+ interface Select extends ColumnNameQueryBuilder {
+ }
+
+ interface Table {
+ (tableName: string): QueryBuilder;
+ (callback: Function): QueryBuilder;
+ }
+
+ interface Distinct extends ColumnNameQueryBuilder {
+ }
+
+ interface Join {
+ (raw: Raw): QueryBuilder;
+ (tableName: string, callback: Function): QueryBuilder;
+ (tableName: string, column1: string, column2: string): QueryBuilder;
+ (tableName: string, column1: string, raw: Raw): QueryBuilder;
+ (tableName: string, column1: string, operator: string, column2: string): QueryBuilder;
+ }
+
+ interface JoinRaw {
+ (tableName: string, binding?: Value): QueryBuilder;
+ }
+
+ interface Where extends WhereRaw, WhereWrapped, WhereNull {
+ (object: Object): QueryBuilder;
+ (columnName: string, value: Value): QueryBuilder;
+ (columnName: string, operator: string, value: Value): QueryBuilder;
+ (columnName: string, operator: string, query: QueryBuilder): QueryBuilder;
+ }
+
+ interface WhereRaw extends RawQueryBuilder {
+ (condition: boolean): QueryBuilder;
+ }
+
+ interface WhereWrapped {
+ (callback: Function): QueryBuilder;
+ }
+
+ interface WhereNull {
+ (columnName: string): QueryBuilder;
+ }
+
+ interface WhereIn {
+ (columnName: string, values: Value[]): QueryBuilder;
+ (columnName: string, callback: Function): QueryBuilder;
+ (columnName: string, query: QueryBuilder): QueryBuilder;
+ }
+
+ interface WhereBetween {
+ (columnName: string, range: [Value, Value]): QueryBuilder;
+ }
+
+ interface WhereExists {
+ (callback: Function): QueryBuilder;
+ (query: QueryBuilder): QueryBuilder;
+ }
+
+ interface WhereNull {
+ (columnName: string): QueryBuilder;
+ }
+
+ interface WhereIn {
+ (columnName: string, values: Value[]): QueryBuilder;
+ }
+
+ interface GroupBy extends RawQueryBuilder, ColumnNameQueryBuilder {
+ }
+
+ interface OrderBy {
+ (columnName: string, direction?: string): QueryBuilder;
+ }
+
+ interface Union {
+ (callback: Function, wrap?: boolean): QueryBuilder;
+ (callbacks: Function[], wrap?: boolean): QueryBuilder;
+ (...callbacks: Function[]): QueryBuilder;
+ // (...callbacks: Function[], wrap?: boolean): QueryInterface;
+ }
+
+ interface Having extends RawQueryBuilder, WhereWrapped {
+ (tableName: string, column1: string, operator: string, column2: string): QueryBuilder;
+ }
+
+ // commons
+
+ interface ColumnNameQueryBuilder {
+ (...columnNames: ColumnName[]): QueryBuilder;
+ (columnNames: ColumnName[]): QueryBuilder;
+ }
+
+ interface RawQueryBuilder {
+ (sql: string, ...bindings: Value[]): QueryBuilder;
+ (sql: string, bindings: Value[]): QueryBuilder;
+ (raw: Raw): QueryBuilder;
+ }
+
+ // Raw
+
+ interface Raw extends events.EventEmitter, ChainableInterface {
+ wrap(before: string, after: string): Raw;
+ }
+
+ interface RawBuilder {
+ (value: Value): Raw;
+ (sql: string, ...bindings: Value[]): Raw;
+ (sql: string, bindings: Value[]): Raw;
+ }
+
+ //
+ // QueryBuilder
+ //
+
+ interface QueryBuilder extends QueryInterface, ChainableInterface {
+ or: QueryBuilder;
+ and: QueryBuilder;
+
+ //TODO: Promise?
+ columnInfo(column?: string): Promise;
+
+ forUpdate(): QueryBuilder;
+ forShare(): QueryBuilder;
+
+ toSQL(): Sql;
+
+ on(event: string, callback: Function): QueryBuilder;
+ }
+
+ interface Sql {
+ method: string;
+ options: any;
+ bindings: Value[];
+ sql: string;
+ }
+
+ //
+ // Chainable interface
+ //
+
+ interface ChainableInterface extends Promise {
+ toQuery(): string;
+ options(options: any): QueryBuilder;
+ stream(options?: any, callback?: (builder: QueryBuilder) => any): QueryBuilder;
+ stream(callback?: (builder: QueryBuilder) => any): QueryBuilder;
+ pipe(writable: any): QueryBuilder;
+ exec(callback: Function): QueryBuilder;
+ }
+
+ interface Transaction extends QueryBuilder {
+ commit: any;
+ rollback: any;
+ }
+
+ //
+ // Schema builder
+ //
+
+ interface Knex {
+ schema: SchemaBuilder;
+ }
+
+ interface SchemaBuilder {
+ createTable(tableName: string, callback: (tableBuilder: CreateTableBuilder) => any): void;
+ renameTable(oldTableName: string, newTableName: string): void;
+ dropTable(tableName: string): void;
+ hasTable(tableName: string): Promise;
+ hasColumn(tableName: string, columnName: string): Promise;
+ table(tableName: string, callback: (tableBuilder: AlterTableBuilder) => any): void;
+ dropTableIfExists(tableName: string): void;
+ raw(statement: string): SchemaBuilder;
+ }
+
+ interface TableBuilder {
+ increments(columnName?: string): ColumnBuilder;
+ dropColumn(columnName: string): TableBuilder;
+ dropColumns(...columnNames: string[]): TableBuilder;
+ renameColumn(from: string, to: string): ColumnBuilder;
+ integer(columnName: string): ColumnBuilder;
+ bigInteger(columnName: string): ColumnBuilder;
+ text(columnName: string, textType?: string): ColumnBuilder;
+ string(columnName: string, length?: number): ColumnBuilder;
+ float(columnName: string, precision?: number, scale?: number): ColumnBuilder;
+ decimal(columnName: string, precision?: number, scale?: number): ColumnBuilder;
+ boolean(columnName: string): ColumnBuilder;
+ date(columnName: string): ColumnBuilder;
+ dateTime(columnName: string): ColumnBuilder;
+ time(columnName: string): ColumnBuilder;
+ timestamp(columnName: string): ColumnBuilder;
+ timestamps(): ColumnBuilder;
+ binary(columnName: string): ColumnBuilder;
+ enum(columnName: string): ColumnBuilder;
+ enu(columnName: string): ColumnBuilder;
+ json(columnName: string): ColumnBuilder;
+ uuid(columnName: string): ColumnBuilder;
+ comment(val: string): TableBuilder;
+ specificType(columnName: string, type: string): ColumnBuilder;
+ }
+
+ interface CreateTableBuilder extends TableBuilder {
+ }
+
+ interface MySqlTableBuilder extends CreateTableBuilder {
+ engine(val: string): CreateTableBuilder;
+ charset(val: string): CreateTableBuilder;
+ collate(val: string): CreateTableBuilder;
+ }
+
+ interface AlterTableBuilder extends TableBuilder {
+ }
+
+ interface MySqlAlterTableBuilder extends AlterTableBuilder {
+ }
+
+ interface ColumnBuilder {
+ index(indexName?: string): ColumnBuilder;
+ primary(): ColumnBuilder;
+ unique(): ColumnBuilder;
+ references(columnName: string): ReferencingColumnBuilder;
+ onDelete(command: string): ColumnBuilder;
+ onUpdate(command: string): ColumnBuilder;
+ defaultTo(value: Value): ColumnBuilder;
+ unsigned(): ColumnBuilder;
+ notNullable(): ColumnBuilder;
+ nullable(): ColumnBuilder;
+ comment(value: string): ColumnBuilder;
+ }
+
+ interface PostgreSqlColumnBuilder extends ColumnBuilder {
+ index(indexName?: string, indexType?: string): ColumnBuilder;
+ }
+
+ interface ReferencingColumnBuilder {
+ inTable(tableName: string): ColumnBuilder;
+ }
+
+ interface AlterColumnBuilder extends ColumnBuilder {
+ }
+
+ interface MySqlAlterColumnBuilder extends AlterColumnBuilder {
+ first(): AlterColumnBuilder;
+ after(columnName: string): AlterColumnBuilder;
+ }
+
+ //
+ // Configurations
+ //
+
+ interface ColumnInfo {
+ defaultValue: Value;
+ type: string;
+ maxLength: number;
+ nullable: boolean;
+ }
+
+ interface Config {
+ client?: string;
+ dialect?: string;
+ connection: string|ConnectionConfig|
+ Sqlite3ConnectionConfig|SocketConnectionConfig;
+ pool?: PoolConfig;
+ migrations?: MigrationConfig;
+ }
+
+ interface ConnectionConfig {
+ host: string;
+ user: string;
+ password: string;
+ database: string;
+ debug?: boolean;
+ }
+
+ /** Used with SQLite3 adapter */
+ interface Sqlite3ConnectionConfig {
+ filename: string;
+ debug?: boolean;
+ }
+
+ interface SocketConnectionConfig {
+ socketPath: string;
+ user: string;
+ password: string;
+ database: string;
+ debug?: boolean;
+ }
+
+ interface PoolConfig {
+ name?: string;
+ create?: Function;
+ destroy?: Function;
+ min?: number;
+ max?: number;
+ refreshIdle?: boolean;
+ idleTimeoutMillis?: number;
+ reapIntervalMillis?: number;
+ returnToHead?: boolean;
+ priorityRange?: number;
+ validate?: Function;
+ log?: boolean;
+ }
+
+ interface MigrationConfig {
+ database?: string;
+ directory?: string;
+ extension?: string;
+ tableName?: string;
+ }
+
+ var _: KnexStatic;
+ export = _;
+}