Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: mysqljs/mysql
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.3.0
Choose a base ref
...
head repository: mysqljs/mysql
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.4.0
Choose a head ref

Commits on Aug 31, 2010

  1. Simplify tests

    felixge committed Aug 31, 2010
    Copy the full SHA
    c61d471 View commit details
  2. Ignore vim 7.3 undo files

    felixge committed Aug 31, 2010
    Copy the full SHA
    4a0fb91 View commit details
  3. Simple insert benchmark

    felixge committed Aug 31, 2010
    Copy the full SHA
    a5013dd View commit details

Commits on Sep 2, 2010

  1. Copy the full SHA
    5887e9d View commit details
  2. Copy the full SHA
    aef575b View commit details
  3. Copy the full SHA
    59dc842 View commit details
  4. Copy the full SHA
    ff65786 View commit details
  5. let's see which one is failing

    iamcal authored and felixge committed Sep 2, 2010
    Copy the full SHA
    4cc30d3 View commit details
  6. Copy the full SHA
    7c06248 View commit details
  7. cleanup

    iamcal authored and felixge committed Sep 2, 2010
    Copy the full SHA
    45a240a View commit details
  8. these functions will be next

    iamcal authored and felixge committed Sep 2, 2010
    Copy the full SHA
    8ab6841 View commit details
  9. fixtures and test for randomInit

    iamcal authored and felixge committed Sep 2, 2010
    Copy the full SHA
    274280b View commit details
  10. Copy the full SHA
    0ee929b View commit details
  11. Copy the full SHA
    f920b2b View commit details
  12. cleanup and more tests

    iamcal authored and felixge committed Sep 2, 2010
    Copy the full SHA
    7bc90da View commit details
  13. Remove old hashPassword test

    felixge committed Sep 2, 2010
    Copy the full SHA
    fff1c0a View commit details
  14. Copy the full SHA
    246d1f1 View commit details
  15. Wire up _sendOldAuth

    felixge committed Sep 2, 2010
    Copy the full SHA
    d4c6970 View commit details
  16. Add some comments

    felixge committed Sep 2, 2010
    Copy the full SHA
    c54e50a View commit details
  17. Tabs to spaces

    felixge committed Sep 2, 2010
    Copy the full SHA
    41b0091 View commit details
  18. Reorganize old auth tests

    Moved them into the test-auth.js test and reformated things a little bit to
    be in sync with the projects overall style.
    felixge committed Sep 2, 2010
    Copy the full SHA
    a303d9b View commit details
  19. A few more style changes

    felixge committed Sep 2, 2010
    Copy the full SHA
    ee8ce2e View commit details
  20. Bump version

    felixge committed Sep 2, 2010
    Copy the full SHA
    5eca50c View commit details
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
*.swo
*.un~
42 changes: 42 additions & 0 deletions benchmark/insert.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
require('../test/common');
var Client = require('mysql/client'),
client = Client(TEST_CONFIG);

client.connect();

client.query('CREATE DATABASE '+TEST_DB, function(err) {
if (err && err.number != Client.ERROR_DB_CREATE_EXISTS) {
throw err;
}
});
client.query('USE '+TEST_DB);
client.query(
'CREATE TEMPORARY TABLE '+TEST_TABLE+' ('+
'id INT(11) AUTO_INCREMENT, '+
'title VARCHAR(255), '+
'text TEXT, '+
'created DATETIME, '+
'PRIMARY KEY (id));',
function(err) {
if (err) throw err;

var start = +new Date, inserts = 0, total = 10000;
console.log('performing %d inserts ...\n', total);

function insertOne() {
client.query('INSERT INTO '+TEST_TABLE+' SET title = ?', ['super'], function() {
inserts++;
if (inserts < total) {
insertOne();
} else {
var duration = (+new Date - start) / 1000,
insertsPerSecond = inserts / duration;

console.log('%d inserts / second', insertsPerSecond.toFixed(2));
client.end();
}
});
}
insertOne();
}
);
132 changes: 132 additions & 0 deletions lib/mysql/auth.js
Original file line number Diff line number Diff line change
@@ -30,3 +30,135 @@ exports.token = function(password, scramble) {
var stage3 = sha1(scramble.toString('binary') + stage2);
return xor(stage3, stage1);
};

// This is a port of sql/password.c:hash_password which needs to be used for
// pre-4.1 passwords.
exports.hashPassword = function(password) {
var nr = [0x5030, 0x5735],
add = 7,
nr2 = [0x1234, 0x5671],
result = new Buffer(8);

if (typeof password == 'string'){
password = new Buffer(password);
}

for (var i = 0; i < password.length; i++) {
var c = password[i];
if (c == 32 || c == 9) {
// skip space in password
continue;
}

// nr^= (((nr & 63)+add)*c)+ (nr << 8);
// nr = xor(nr, add(mul(add(and(nr, 63), add), c), shl(nr, 8)))
nr = this.xor32(nr, this.add32(this.mul32(this.add32(this.and32(nr, [0,63]), [0,add]), [0,c]), this.shl32(nr, 8)));

// nr2+=(nr2 << 8) ^ nr;
// nr2 = add(nr2, xor(shl(nr2, 8), nr))
nr2 = this.add32(nr2, this.xor32(this.shl32(nr2, 8), nr));

// add+=tmp;
add += c;
}

this.int31Write(result, nr, 0);
this.int31Write(result, nr2, 4);

return result;
};

exports.randomInit = function(seed1, seed2) {
return {
max_value: 0x3FFFFFFF,
max_value_dbl: 0x3FFFFFFF,
seed1: seed1 % 0x3FFFFFFF,
seed2: seed2 % 0x3FFFFFFF,
};
};

exports.myRnd = function(r){
r.seed1 = (r.seed1 * 3 + r.seed2) % r.max_value;
r.seed2 = (r.seed1 + r.seed2 + 33) % r.max_value;

return r.seed1 / r.max_value_dbl;
};

exports.scramble323 = function(message, password) {
var to = new Buffer(8),
hashPass = this.hashPassword(password),
hashMessage = this.hashPassword(message.slice(0, 8)),
seed1 = this.int32Read(hashPass, 0) ^ this.int32Read(hashMessage, 0),
seed2 = this.int32Read(hashPass, 4) ^ this.int32Read(hashMessage, 4),
r = this.randomInit(seed1, seed2);

for (var i = 0; i < 8; i++){
to[i] = Math.floor(this.myRnd(r) * 31) + 64;
}
var extra = (Math.floor(this.myRnd(r) * 31));

for (var i = 0; i < 8; i++){
to[i] ^= extra;
}

return to;
};

exports.fmt32 = function(x){
var a = x[0].toString(16),
b = x[1].toString(16);

if (a.length == 1) a = '000'+a;
if (a.length == 2) a = '00'+a;
if (a.length == 3) a = '0'+a;
if (b.length == 1) b = '000'+b;
if (b.length == 2) b = '00'+b;
if (b.length == 3) b = '0'+b;
return '' + a + '/' + b;
}

exports.xor32 = function(a,b){
return [a[0] ^ b[0], a[1] ^ b[1]];
}

exports.add32 = function(a,b){
var w1 = a[1] + b[1],
w2 = a[0] + b[0] + ((w1 & 0xFFFF0000) >> 16);

return [w2 & 0xFFFF, w1 & 0xFFFF];
}

exports.mul32 = function(a,b){
// based on this example of multiplying 32b ints using 16b
// http://www.dsprelated.com/showmessage/89790/1.php
var w1 = a[1] * b[1],
w2 = (((a[1] * b[1]) >> 16) & 0xFFFF) + ((a[0] * b[1]) & 0xFFFF) + (a[1] * b[0] & 0xFFFF);

return [w2 & 0xFFFF, w1 & 0xFFFF];
}

exports.and32 = function(a,b){
return [a[0] & b[0], a[1] & b[1]]
}

exports.shl32 = function(a,b){
// assume b is 16 or less
var w1 = a[1] << b,
w2 = (a[0] << b) | ((w1 & 0xFFFF0000) >> 16);

return [w2 & 0xFFFF, w1 & 0xFFFF];
}

exports.int31Write = function(buffer, number, offset) {
buffer[offset] = (number[0] >> 8) & 0x7F;
buffer[offset + 1] = (number[0]) & 0xFF;
buffer[offset + 2] = (number[1] >> 8) & 0xFF;
buffer[offset + 3] = (number[1]) & 0xFF;
};

exports.int32Read = function(buffer, offset){
return (buffer[offset] << 24)
+ (buffer[offset+1] << 16)
+ (buffer[offset+2] << 8)
+ (buffer[offset+3]);
};
29 changes: 28 additions & 1 deletion lib/mysql/client.js
Original file line number Diff line number Diff line change
@@ -19,13 +19,14 @@ function Client(config) {
this.port = 3306;
this.user = null;
this.password = null;
this.database = null;
this.database = '';

this.flags = Client.defaultFlags;
this.maxPacketSize = 0x01000000;
this.charsetNumber = 8;
this.debug = false;

this._greeting = null;
this._queue = [];
this._connection = null;
this._parser = null;
@@ -194,6 +195,11 @@ Client.prototype._handlePacket = function(packet) {
return;
}

if (packet.type == Parser.USE_OLD_PASSWORD_PROTOCOL_PACKET) {
this._sendOldAuth(this._greeting);
return;
}

var type = packet.type,
task = this._queue[0],
delegate = (task)
@@ -239,6 +245,11 @@ Client.prototype._sendAuth = function(greeting) {
packet.writeNullTerminated(this.database);

this.write(packet);

// Keep a reference to the greeting packet. We might receive a
// USE_OLD_PASSWORD_PROTOCOL_PACKET as a response, in which case we will need
// the greeting packet again. See _sendOldAuth()
this._greeting = greeting;
};

Client._packetToUserObject = function(packet) {
@@ -284,6 +295,22 @@ Client.prototype._debugPacket = function(packet) {
console.log('<- %s: %j', packetName, packet);
};

Client.prototype._sendOldAuth = function(greeting) {
var token = auth.scramble323(greeting.scrambleBuffer, this.password),
packetSize = (
token.length + 1
),
packet = new OutgoingPacket(packetSize, greeting.number+3);

// I could not find any official documentation for this, but from sniffing
// the mysql command line client, I think this is the right way to send the
// scrambled token after receiving the USE_OLD_PASSWORD_PROTOCOL_PACKET.
packet.write(token);
packet.writeFiller(1);

this.write(packet);
};

// Client Flags
Client.LONG_PASSWORD = 1;
Client.FOUND_ROWS = 2;
9 changes: 9 additions & 0 deletions lib/mysql/parser.js
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@ function Parser() {
this.state = Parser.PACKET_LENGTH;
this.packet = null;
this.greeted = false;
this.authenticated = false;
this.receivingFieldPackets = false;
this.receivingRowPackets = false;

@@ -211,7 +212,14 @@ Parser.prototype.write = function(buffer) {
break;
}

if (c == 0xfe && !this.authenticated) {
packet.type = Parser.USE_OLD_PASSWORD_PROTOCOL_PACKET;
break;
}

if (c === 0x00) {
// after the first OK PACKET, we are authenticated
this.authenticated = true;
packet.type = Parser.OK_PACKET;
advance(Parser.AFFECTED_ROWS)
break;
@@ -606,3 +614,4 @@ Parser.ROW_DATA_PACKET = p++;
Parser.ROW_DATA_BINARY_PACKET = p++;
Parser.OK_FOR_PREPARED_STATEMENT_PACKET = p++;
Parser.PARAMETER_PACKET = p++;
Parser.USE_OLD_PASSWORD_PROTOCOL_PACKET = p++;
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{ "name" : "mysql"
, "version": "0.3.0"
, "version": "0.4.0"
, "dependencies": {"gently": ">=0.8.0"}
, "main" : "./lib/mysql"
}
4 changes: 2 additions & 2 deletions test/common.js
Original file line number Diff line number Diff line change
@@ -3,12 +3,12 @@ var path = require('path')

require.paths.unshift(path.dirname(__dirname)+'/lib');

global.TEST_DB = 'node_mysql_test';
global.TEST_CONFIG = {
host: 'localhost',
port: 3306,
user: 'root',
password: 'root',
database: 'node_mysql_test',
password: 'root'
};

global.TEST_TABLE = 'posts';
Loading