knex/clients/base.js

200 lines
5.4 KiB
JavaScript
Raw Normal View History

2013-08-06 11:29:46 -04:00
var whenfn = require('when/function');
2013-05-08 20:16:39 -04:00
var nodefn = require('when/node/function');
var _ = require('underscore');
// Setup is called with the context of the current client.
exports.setup = function(Client, name, options) {
if (!options.connection) {
throw new Error('The database connection properties must be specified.');
}
this.name = name;
this.debug = options.debug;
this.connectionSettings = options.connection;
this.grammar = Client.grammar;
this.schemaGrammar = Client.schemaGrammar;
// Extend the genericPool with the options
// passed into the init under the "pool" option.
var instance = this;
var poolInstance = this.pool = require('generic-pool').Pool(_.extend({
name: 'pool-' + name,
2013-05-03 00:20:51 -04:00
min: 2,
max: 10,
log: false,
idleTimeoutMillis: 30000,
create: function(callback) {
var pool = this;
instance.getRawConnection(function(err, conn) {
if (err) return callback(err);
conn.__cid = _.uniqueId('__cid');
if (pool.afterCreate) {
pool.afterCreate(conn, function(err) {
callback(err, conn);
});
} else {
callback(null, conn);
}
});
},
destroy: function(conn) {
if (this.beforeDestroy) {
this.beforeDestroy(conn, function() {
conn.end();
});
} else {
conn.end();
}
}
}, this.poolDefaults, options.pool));
// Default to draining on exit.
if (poolInstance.drainOnExit !== false && typeof process === 'object') {
process.on('exit', function() {
poolInstance.drain(function() {
poolInstance.destroyAllNow();
});
});
}
};
exports.skim = function(data) {
return _.map(data, function(obj) {
return _.pick(obj, _.keys(obj));
});
};
exports.debug = function(builder, conn) {
console.log({sql: builder.sql, bindings: builder.bindings, __cid: conn.__cid});
};
exports.protoProps = {
2013-05-03 00:20:51 -04:00
// Retrieves a connection from the connection pool,
// returning a promise.
getConnection: function() {
2013-05-08 20:16:39 -04:00
return nodefn.call(this.pool.acquire);
2013-05-03 00:20:51 -04:00
},
// Releases a connection from the connection pool,
// returning a promise.
releaseConnection: function(conn) {
2013-08-06 11:29:46 -04:00
return whenfn.call(this.pool.release, conn);
2013-05-03 00:20:51 -04:00
},
// Begins a transaction statement on the instance,
// resolving with the connection of the current transaction.
startTransaction: function() {
2013-05-03 00:20:51 -04:00
return this.getConnection().then(function(connection) {
2013-05-18 00:07:28 -04:00
return nodefn.call(connection.query.bind(connection), 'begin;', []).then(function() {
2013-05-03 00:20:51 -04:00
return connection;
});
});
},
finishTransaction: function(type, trans, dfd, msg) {
2013-05-18 00:07:28 -04:00
var ctx = this;
nodefn.call(trans.connection.query.bind(trans.connection), type + ';', []).then(function(resp) {
if (type === 'commit') dfd.resolve(msg || resp);
if (type === 'rollback') dfd.reject(msg || resp);
2013-05-08 20:16:39 -04:00
}).ensure(function() {
return ctx.releaseConnection(trans.connection).then(function() {
trans.connection = null;
});
});
}
2013-05-03 10:03:44 -04:00
};
exports.grammar = {};
2013-05-03 10:03:44 -04:00
exports.schemaGrammar = {
2013-05-22 13:10:42 -04:00
// Get the primary key command if it exists on the blueprint.
getCommandByName: function(blueprint, name) {
var commands = this.getCommandsByName(blueprint, name);
if (commands.length > 0) return commands[0];
},
// Get all of the commands with a given name.
getCommandsByName: function(blueprint, name) {
return _.filter(blueprint.commands, function(value) { return value.name == name; }) || [];
},
// Used to compile any database specific items.
compileAdditional: function() {},
// Compile a create table command.
2013-05-22 13:10:42 -04:00
compileCreateTable: function(blueprint) {
var columns = this.getColumns(blueprint).join(', ');
return 'create table ' + this.wrapTable(blueprint) + ' (' + columns + ')';
},
2013-05-03 10:03:44 -04:00
// Compile a drop table command.
2013-05-22 13:10:42 -04:00
compileDropTable: function(blueprint) {
2013-05-03 10:03:44 -04:00
return 'drop table ' + this.wrapTable(blueprint);
},
// Compile a drop table (if exists) command.
2013-05-22 13:10:42 -04:00
compileDropTableIfExists: function(blueprint) {
2013-05-03 10:03:44 -04:00
return 'drop table if exists ' + this.wrapTable(blueprint);
},
// Compile a drop index command.
compileDropIndex: function(blueprint, command) {
return 'drop index ' + command.index;
},
2013-07-17 10:26:24 -04:00
// Create the column definition for a string type.
typeString: function(column) {
return "varchar(" + column.length + ")";
},
// Create the column definition for a text type.
typeText: function() {
return 'text';
},
// Create the column definition for a tiny integer type.
typeTinyInteger: function() {
return 'tinyint';
},
// Create the column definition for a time type.
2013-05-22 13:10:42 -04:00
typeTime: function() {
return 'time';
},
// Create the column definition for a date type.
2013-05-22 13:10:42 -04:00
typeDate: function() {
return 'date';
},
// Create the column definition for a binary type.
2013-05-22 13:10:42 -04:00
typeBinary: function() {
return 'blob';
},
// Create the column definition for a json type.
typeJson: function() {
return 'text';
},
2013-07-17 10:26:24 -04:00
// Create the column definition for a uuid type.
typeUuid: function() {
return 'char(36)';
},
// Get the SQL for a nullable column modifier.
modifyNullable: function(blueprint, column) {
return column.isNullable ? ' null' : ' not null';
2013-05-22 12:37:29 -04:00
},
// Get the SQL for a default column modifier.
modifyDefault: function(blueprint, column) {
if (column.defaultValue != void 0) {
return " default '" + this.getDefaultValue(column.defaultValue) + "'";
}
2013-05-03 10:03:44 -04:00
}
};