Initial work on the server

This commit is contained in:
Abhishek Das
2013-03-25 06:08:51 +05:30
parent 93400554fd
commit 0485272d93
626 changed files with 121311 additions and 1 deletions
+41
View File
@@ -0,0 +1,41 @@
var Sequence = require('./Sequence');
var Util = require('util');
var Packets = require('../packets');
var Auth = require('../Auth');
module.exports = ChangeUser;
Util.inherits(ChangeUser, Sequence);
function ChangeUser(options, callback) {
Sequence.call(this, callback);
this._user = options.user;
this._password = options.password;
this._database = options.database;
this._charsetNumber = options.charsetNumber;
this._currentConfig = options.currentConfig;
}
ChangeUser.prototype.start = function(handshakeInitializationPacket) {
var scrambleBuff = handshakeInitializationPacket.scrambleBuff();
scrambleBuff = Auth.token(this._password, scrambleBuff);
var packet = new Packets.ComChangeUserPacket({
user : this._user,
scrambleBuff : scrambleBuff,
database : this._database,
charsetNumber : this._charsetNumber,
});
this._currentConfig.user = this._user;
this._currentConfig.password = this._password;
this._currentConfig.database = this._database;
this._currentConfig.charsetNumber = this._charsetNumber;
this.emit('packet', packet);
};
ChangeUser.prototype['ErrorPacket'] = function(packet) {
var err = this._packetToError(packet);
err.fatal = true;
this.end(err);
};
+65
View File
@@ -0,0 +1,65 @@
var Sequence = require('./Sequence');
var Util = require('util');
var Packets = require('../packets');
var Auth = require('../Auth');
module.exports = Handshake;
Util.inherits(Handshake, Sequence);
function Handshake(config, callback) {
Sequence.call(this, callback);
this._config = config;
this._handshakeInitializationPacket = null;
}
Handshake.prototype.determinePacket = function(firstByte) {
if (firstByte === 0xff) {
return Packets.ErrorPacket;
}
if (!this._handshakeInitializationPacket) {
return Packets.HandshakeInitializationPacket;
}
if (firstByte === 0xfe) {
return Packets.UseOldPasswordPacket;
}
};
Handshake.prototype['HandshakeInitializationPacket'] = function(packet) {
this._handshakeInitializationPacket = packet;
this.emit('packet', new Packets.ClientAuthenticationPacket({
clientFlags : this._config.clientFlags,
maxPacketSize : this._config.maxPacketSize,
charsetNumber : this._config.charsetNumber,
user : this._config.user,
scrambleBuff : Auth.token(this._config.password, packet.scrambleBuff()),
database : this._config.database,
}));
};
Handshake.prototype['UseOldPasswordPacket'] = function(packet) {
if (!this._config.insecureAuth) {
var err = new Error(
'MySQL server is requesting the old and insecure pre-4.1 auth mechanism.' +
'Upgrade the user password or use the {insecureAuth: true} option.'
);
err.code = 'HANDSHAKE_INSECURE_AUTH';
err.fatal = true;
this.end(err);
return;
}
this.emit('packet', new Packets.OldPasswordPacket({
scrambleBuff : Auth.scramble323(this._handshakeInitializationPacket.scrambleBuff(), this._config.password),
}));
};
Handshake.prototype['ErrorPacket'] = function(packet) {
var err = this._packetToError(packet, true);
err.fatal = true;
this.end(err);
};
+14
View File
@@ -0,0 +1,14 @@
var Sequence = require('./Sequence');
var Util = require('util');
var Packets = require('../packets');
module.exports = Ping;
Util.inherits(Ping, Sequence);
function Ping(callback) {
Sequence.call(this, callback);
}
Ping.prototype.start = function() {
this.emit('packet', new Packets.ComPingPacket);
};
+163
View File
@@ -0,0 +1,163 @@
var Sequence = require('./Sequence');
var Util = require('util');
var Packets = require('../packets');
var ResultSet = require('../ResultSet');
var ServerStatus = require('../constants/server_status');
var fs = require('fs');
module.exports = Query;
Util.inherits(Query, Sequence);
function Query(options, callback) {
Sequence.call(this, callback);
this.sql = options.sql;
this.values = options.values;
this.typeCast = (options.typeCast === undefined)
? true
: options.typeCast;
this.nestTables = options.nestTables || false;
this._resultSet = null;
this._results = [];
this._fields = [];
this._index = 0;
this._loadError = null;
}
Query.prototype.start = function() {
this.emit('packet', new Packets.ComQueryPacket(this.sql));
};
Query.prototype.determinePacket = function(firstByte, parser) {
if (firstByte === 0) {
// If we have a resultSet and got one eofPacket
if (this._resultSet && this._resultSet.eofPackets.length === 1) {
// Then this is a RowDataPacket with an empty string in the first column.
// See: https://github.com/felixge/node-mysql/issues/222
} else {
return;
}
}
if (firstByte === 255) {
return;
}
// EofPacket's are 5 bytes in mysql >= 4.1
// This is the only / best way to differentiate their firstByte from a 9
// byte length coded binary.
if (firstByte === 0xfe && parser.packetLength() < 9) {
return Packets.EofPacket;
}
if (!this._resultSet) {
return Packets.ResultSetHeaderPacket;
}
return (this._resultSet.eofPackets.length === 0)
? Packets.FieldPacket
: Packets.RowDataPacket;
};
Query.prototype['OkPacket'] = function(packet) {
// try...finally for exception safety
try {
if (!this._callback) {
this.emit('result', packet, this._index);
} else {
this._results.push(packet);
this._fields.push(undefined);
}
} finally {
this._index++;
this._handleFinalResultPacket(packet);
}
};
Query.prototype['ErrorPacket'] = function(packet) {
var err = this._packetToError(packet);
var results = (this._results.length > 0)
? this._results
: undefined;
var fields = (this._fields.length > 0)
? this._fields
: undefined;
err.index = this._index;
this.end(err, results, fields);
};
Query.prototype['ResultSetHeaderPacket'] = function(packet) {
this._resultSet = new ResultSet(packet);
// used by LOAD DATA LOCAL INFILE queries
if (packet.fieldCount === null) {
this._sendLocalDataFile(packet.extra);
}
};
Query.prototype['FieldPacket'] = function(packet) {
this._resultSet.fieldPackets.push(packet);
};
Query.prototype['EofPacket'] = function(packet) {
this._resultSet.eofPackets.push(packet);
if (this._resultSet.eofPackets.length === 1 && !this._callback) {
this.emit('fields', this._resultSet.fieldPackets, this._index);
}
if (this._resultSet.eofPackets.length !== 2) {
return;
}
if (this._callback) {
this._results.push(this._resultSet.rows);
this._fields.push(this._resultSet.fieldPackets);
}
this._index++;
this._resultSet = null;
this._handleFinalResultPacket(packet);
};
Query.prototype._handleFinalResultPacket = function(packet) {
if (packet.serverStatus & ServerStatus.SERVER_MORE_RESULTS_EXISTS) {
return;
}
var results = (this._results.length > 1)
? this._results
: this._results[0];
var fields = (this._fields.length > 1)
? this._fields
: this._fields[0];
this.end(this._loadError, results, fields);
};
Query.prototype['RowDataPacket'] = function(packet, parser, connection) {
packet.parse(parser, this._resultSet.fieldPackets, this.typeCast, this.nestTables, connection);
if (this._callback) {
this._resultSet.rows.push(packet);
} else {
this.emit('result', packet, this._index);
}
};
Query.prototype._sendLocalDataFile = function(path) {
var self = this;
fs.readFile(path, 'utf-8', function(err, data) {
if (err) {
self._loadError = err;
} else {
self.emit('packet', new Packets.LocalDataFilePacket(data));
}
self.emit('packet', new Packets.EmptyPacket());
});
};
+13
View File
@@ -0,0 +1,13 @@
var Sequence = require('./Sequence');
var Util = require('util');
var Packets = require('../packets');
module.exports = Quit;
Util.inherits(Quit, Sequence);
function Quit(callback) {
Sequence.call(this, callback);
}
Quit.prototype.start = function() {
this.emit('packet', new Packets.ComQuitPacket);
};
+83
View File
@@ -0,0 +1,83 @@
var Util = require('util');
var EventEmitter = require('events').EventEmitter;
var Packets = require('../packets');
var ErrorConstants = require('../constants/errors');
module.exports = Sequence;
Util.inherits(Sequence, EventEmitter);
function Sequence(callback) {
EventEmitter.call(this);
this._callback = callback;
this._ended = false;
// Experimental: Long stack trace support
this._callSite = (new Error).stack.replace(/.+\n/, '');
}
Sequence.determinePacket = function(byte) {
switch (byte) {
case 0x00: return Packets.OkPacket;
case 0xfe: return Packets.EofPacket;
case 0xff: return Packets.ErrorPacket;
}
};
Sequence.prototype.hasErrorHandler = function() {
return this._callback || this.listeners('error').length > 1;
};
Sequence.prototype._packetToError = function(packet) {
var code = ErrorConstants[packet.errno] || 'UNKNOWN_CODE_PLEASE_REPORT';
var err = new Error(code + ': ' + packet.message);
err.code = code;
return err;
};
Sequence.prototype._addLongStackTrace = function(err) {
var delimiter = '\n --------------------\n' ;
if (err.stack.indexOf(delimiter) > -1) {
return;
}
err.stack += delimiter + this._callSite;
};
Sequence.prototype.end = function(err) {
if (this._ended) {
return;
}
this._ended = true;
if (err) {
this._addLongStackTrace(err);
}
// try...finally for exception safety
try {
if (err) {
this.emit('error', err);
}
} finally {
try {
if (this._callback) {
this._callback.apply(this, arguments);
}
} finally {
this.emit('end');
}
}
};
Sequence.prototype['OkPacket'] = function(packet) {
this.end(null, packet);
};
Sequence.prototype['ErrorPacket'] = function(packet) {
this.end(this._packetToError(packet));
};
// Implemented by child classes
Sequence.prototype.start = function() {};
+23
View File
@@ -0,0 +1,23 @@
var Sequence = require('./Sequence');
var Util = require('util');
var Packets = require('../packets');
module.exports = Statistics;
Util.inherits(Statistics, Sequence);
function Statistics(callback) {
Sequence.call(this, callback);
}
Statistics.prototype.start = function() {
this.emit('packet', new Packets.ComStatisticsPacket);
};
Statistics.prototype['StatisticsPacket'] = function (packet) {
this.end(null, packet);
};
Statistics.prototype.determinePacket = function(firstByte, parser) {
if (firstByte === 0x55) {
return Packets.StatisticsPacket;
}
};
+4
View File
@@ -0,0 +1,4 @@
var Elements = module.exports = require('require-all')({
dirname : __dirname,
filter : /([A-Z].+)\.js$/,
});