mysql2 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.travis.yml CHANGED
@@ -2,8 +2,8 @@ language: node_js
2
2
  before_script:
3
3
  - mysql -e 'create database if not exists test;'
4
4
  node_js:
5
- - "0.4"
6
5
  - "0.6"
7
6
  - "0.8"
7
+ - "0.9"
8
8
  - "0.10"
9
9
  - "0.11"
@@ -0,0 +1,80 @@
1
+ var common = require('../test/common');
2
+ var connection = common.createConnection();
3
+ var assert = require('assert');
4
+
5
+ var table = 'insert_test';
6
+ //var text = "本日は晴天なり";
7
+ var text = "test abc xyz";
8
+ connection.query('drop table ' + table).on('error', function() {});
9
+ connection.query([
10
+ 'CREATE TABLE `' + table + '` (',
11
+ '`id` int(11) unsigned NOT NULL AUTO_INCREMENT,',
12
+ '`title` varchar(255) NOT NULL,',
13
+ 'PRIMARY KEY (`id`)',
14
+ ') ENGINE=InnoDB DEFAULT CHARSET=utf8'
15
+ ].join('\n'));
16
+
17
+ function benchmarkInsert(numLeft, callback) {
18
+ connection.query('INSERT INTO ' + table + ' SET title="' + text + '"', function(err, result) {
19
+ if (err) throw err;
20
+ if (numLeft > 1)
21
+ benchmarkInsert(numLeft-1, callback);
22
+ else
23
+ callback();
24
+ });
25
+ }
26
+
27
+ function benchmarkInserts(n, cb) {
28
+ var numInsert = 50000;
29
+ var start = process.hrtime();
30
+ benchmarkInsert(numInsert, function() {
31
+ var end = process.hrtime();
32
+ var diff = common.hrdiff(start, end);
33
+ console.log(numInsert*1e9/diff + ' inserts/sec');
34
+ if (n > 1)
35
+ benchmarkInserts(n - 1, cb);
36
+ else
37
+ cb();
38
+ });
39
+ }
40
+
41
+ function benchmarkParallelSelects(n, size, cb) {
42
+ var start = process.hrtime();
43
+ var numRunning = 0;
44
+
45
+ function commandDone() {
46
+ console.log(numRunning);
47
+ numRunning--;
48
+ if (numRunning > 0)
49
+ return;
50
+ var end = process.hrtime();
51
+ var diff = common.hrdiff(start, end);
52
+ console.log(size + ' rows: ' + n*1e9/diff + ' results/sec, ' + size*n*1e9/diff + ' rows/sec');
53
+ cb();
54
+ }
55
+
56
+ var connections = new Array(n);
57
+ for (var i=0; i < n; ++i)
58
+ {
59
+ numRunning++;
60
+ connections[i] = common.createConnection();
61
+ var cmd = connections[i].execute('select * from ' + table + ' limit ' + size, []);
62
+ cmd.on('end', commandDone);
63
+ }
64
+ }
65
+
66
+ module.exports = function(done) {
67
+ var testStart = process.hrtime();
68
+ benchmarkInserts(1, function() {
69
+ benchmarkParallelSelects(8, 50000, function() {
70
+ var testEnd = process.hrtime();
71
+ console.log('total time: ', common.hrdiff(testStart, testEnd)/1e9 );
72
+ if (done)
73
+ done();
74
+ });
75
+ });
76
+ };
77
+
78
+ if (require.main === module) {
79
+ module.exports();
80
+ }
@@ -8,13 +8,15 @@ var text = "test abc xyz";
8
8
  connection.query([
9
9
  'CREATE TEMPORARY TABLE `' + table + '` (',
10
10
  '`id` int(11) unsigned NOT NULL AUTO_INCREMENT,',
11
- '`title` varchar(255),',
11
+ '`id1` tinyint NOT NULL,',
12
+ // '`title` varchar(255),',
12
13
  'PRIMARY KEY (`id`)',
13
14
  ') ENGINE=InnoDB DEFAULT CHARSET=utf8'
14
15
  ].join('\n'));
15
16
 
16
17
  function benchmarkInsert(numLeft, callback) {
17
- connection.execute('INSERT INTO ' + table + ' SET title="' + text + '"', [], function(err, result) {
18
+ //connection.execute('INSERT INTO ' + table + ' SET title="' + text + '"', [], function(err, result) {
19
+ connection.execute('INSERT INTO ' + table + ' SET id1=123', [], function(err, result) {
18
20
  if (err) throw err;
19
21
  if (numLeft > 1)
20
22
  benchmarkInsert(numLeft-1, callback);
@@ -24,7 +26,7 @@ function benchmarkInsert(numLeft, callback) {
24
26
  }
25
27
 
26
28
  function benchmarkInserts(n, cb) {
27
- var numInsert = 10000;
29
+ var numInsert = 500000;
28
30
  var start = process.hrtime();
29
31
  benchmarkInsert(numInsert, function() {
30
32
  var end = process.hrtime();
@@ -64,9 +66,9 @@ function benchmarkSelects(n, size, cb) {
64
66
  module.exports = function(done) {
65
67
  var testStart = process.hrtime();
66
68
  benchmarkInserts(1, function() {
67
- benchmarkSelects(5, 100, function() {
68
- benchmarkSelects(10, 1000, function() {
69
- benchmarkSelects(2, 50000, function() {
69
+ benchmarkSelects(50, 100, function() {
70
+ benchmarkSelects(100, 1000, function() {
71
+ benchmarkSelects(20, 500000, function() {
70
72
  var testEnd = process.hrtime();
71
73
  console.log('total time: ', common.hrdiff(testStart, testEnd)/1e9 );
72
74
  connection.end();
@@ -7,13 +7,13 @@ var text = "本日は晴天なり";
7
7
  connection.query([
8
8
  'CREATE TEMPORARY TABLE `' + table + '` (',
9
9
  '`id` int(11) unsigned NOT NULL AUTO_INCREMENT,',
10
- '`title` varchar(255),',
10
+ '`ttt` int(11) unsigned NOT NULL,',
11
11
  'PRIMARY KEY (`id`)',
12
12
  ') ENGINE=InnoDB DEFAULT CHARSET=utf8'
13
13
  ].join('\n'));
14
14
 
15
15
  function benchmarkInsert(numLeft, callback) {
16
- connection.query('INSERT INTO ' + table + ' SET title="' + text + '"', function(err, result) {
16
+ connection.query('INSERT INTO ' + table + ' SET ttt=123', function(err, result) {
17
17
  if (err) throw err;
18
18
  if (numLeft > 1)
19
19
  benchmarkInsert(numLeft-1, callback);
@@ -0,0 +1,228 @@
1
+ Statistical profiling result from node, (156381 ticks, 1858 unaccounted, 0 excluded).
2
+
3
+ [Unknown]:
4
+ ticks total nonlib name
5
+ 1858 1.2%
6
+
7
+ [Shared libraries]:
8
+ ticks total nonlib name
9
+ 53890 34.5% 0.0% /usr/lib/system/libsystem_c.dylib
10
+ 50720 32.4% 0.0% /usr/lib/system/libsystem_kernel.dylib
11
+ 47085 30.1% 0.0% /usr/local/bin/node
12
+ 31 0.0% 0.0% /usr/lib/libstdc++.6.dylib
13
+ 15 0.0% 0.0% /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/CarbonCore
14
+ 3 0.0% 0.0% /usr/lib/system/libsystem_m.dylib
15
+
16
+ [JavaScript]:
17
+ ticks total nonlib name
18
+ 1474 0.9% 31.8% Script: ~native mirror.js
19
+ 1038 0.7% 22.4% Script: ~native debug.js
20
+ 447 0.3% 9.6% LazyCompile: *Socket._write net.js:515
21
+ 345 0.2% 7.4% Stub: CEntryStub
22
+ 217 0.1% 4.7% LazyCompile: *Query.row /private/tmp/node-mysql2/lib/commands/query.js:68
23
+ 167 0.1% 3.6% Builtin: A builtin from the snapshot {4}
24
+ 61 0.0% 1.3% Function: Command.execute /private/tmp/node-mysql2/lib/commands/command.js:10
25
+ 43 0.0% 0.9% Stub: FastNewClosureStub
26
+ 39 0.0% 0.8% LazyCompile: *Buffer buffer.js:205
27
+ 32 0.0% 0.7% Builtin: A builtin from the snapshot {1}
28
+ 31 0.0% 0.7% Stub: JSEntryStub
29
+ 28 0.0% 0.6% LazyCompile: ~<anonymous> native liveedit.js:45
30
+ 27 0.0% 0.6% Builtin: A builtin from the snapshot {3}
31
+ 25 0.0% 0.5% LazyCompile: *PacketParser.execute /private/tmp/node-mysql2/lib/packet_parser.js:23
32
+ 25 0.0% 0.5% CallMegamorphic: args_count: 2 {1}
33
+ 23 0.0% 0.5% Stub: CallConstructStub_Recording
34
+ 23 0.0% 0.5% LazyCompile: ~inherits native mirror.js:137
35
+ 20 0.0% 0.4% LazyCompile: *Connection.handlePacket /private/tmp/node-mysql2/lib/connection.js:67
36
+ 19 0.0% 0.4% Stub: CallConstructStub
37
+ 19 0.0% 0.4% Script: ~native liveedit.js
38
+ 18 0.0% 0.4% LazyCompile: ~DoConstructRegExp native regexp.js:35
39
+ 17 0.0% 0.4% LazyCompile: *Query.resultsetHeader /private/tmp/node-mysql2/lib/commands/query.js:25
40
+ 16 0.0% 0.3% LazyCompile: *writeUInt16 buffer.js:887
41
+ 15 0.0% 0.3% Stub: ToBooleanStub_NullSpecObject
42
+ 15 0.0% 0.3% LazyCompile: *exports.active timers.js:151
43
+ 14 0.0% 0.3% Stub: InstanceofStub
44
+ 14 0.0% 0.3% LazyCompile: ~ClearMirrorCache native mirror.js:39
45
+ 13 0.0% 0.3% LazyCompile: *onread net.js:377
46
+ 13 0.0% 0.3% LazyCompile: *benchmarkInsert /private/tmp/node-mysql2/benchmarks/bench-insert-select-parallel.js:17
47
+ 13 0.0% 0.3% LazyCompile: *Socket.write net.js:465
48
+ 13 0.0% 0.3% LazyCompile: *Connection.query /private/tmp/node-mysql2/lib/connection.js:85
49
+ 12 0.0% 0.3% LazyCompile: *Query /private/tmp/node-mysql2/lib/commands/query.js:6
50
+ 11 0.0% 0.2% LazyCompile: *Query.start /private/tmp/node-mysql2/lib/commands/query.js:19
51
+ 11 0.0% 0.2% LazyCompile: *EventEmitter events.js:25
52
+ 10 0.0% 0.2% Stub: ConstructStub
53
+ 10 0.0% 0.2% LazyCompile: *Buffer.write buffer.js:329
54
+ 10 0.0% 0.2% Function: b native v8natives.js:1582
55
+ 9 0.0% 0.2% Stub: FastCloneShallowObjectStub {2}
56
+ 9 0.0% 0.2% LazyCompile: ToString native runtime.js:550
57
+ 9 0.0% 0.2% LazyCompile: RegExpConstructor native regexp.js:86
58
+ 9 0.0% 0.2% LazyCompile: *ok assert.js:121
59
+ 9 0.0% 0.2% LazyCompile: *Packet.readLengthCodedString /private/tmp/node-mysql2/lib/packets/packet.js:143
60
+ 9 0.0% 0.2% Function: ~<anonymous> /private/tmp/node-mysql2/benchmarks/bench-insert-select-parallel.js:18
61
+ 8 0.0% 0.2% LazyCompile: *Query.toPacket /private/tmp/node-mysql2/lib/packets/query.js:9
62
+ 8 0.0% 0.2% LazyCompile: *Packet.readInt8 /private/tmp/node-mysql2/lib/packets/packet.js:38
63
+ 8 0.0% 0.2% LazyCompile: *EventEmitter.emit events.js:54
64
+ 8 0.0% 0.2% Builtin: A builtin from the snapshot {2}
65
+ 8 0.0% 0.2% Builtin: A builtin from the snapshot
66
+ 7 0.0% 0.2% Stub: CompareICStub
67
+ 7 0.0% 0.2% LazyCompile: *Connection.writePacket /private/tmp/node-mysql2/lib/connection.js:62
68
+ 7 0.0% 0.2% LazyCompile: *Command /private/tmp/node-mysql2/lib/commands/command.js:4
69
+ 7 0.0% 0.2% CallMegamorphic: args_count: 2
70
+ 6 0.0% 0.1% Stub: ArgumentsAccessStub_NewStrict
71
+ 6 0.0% 0.1% LazyCompile: ~c native mirror.js:138
72
+ 6 0.0% 0.1% LazyCompile: INSTANCE_OF native runtime.js:367
73
+ 6 0.0% 0.1% LazyCompile: *stream.ondata /private/tmp/node-mysql2/lib/connection.js:56
74
+ 6 0.0% 0.1% LazyCompile: *Packet.readLengthCodedNumber /private/tmp/node-mysql2/lib/packets/packet.js:59
75
+ 5 0.0% 0.1% LazyCompile: TextRow evalmachine.<anonymous>:1
76
+ 5 0.0% 0.1% LazyCompile: *Packet.writeHeader /private/tmp/node-mysql2/lib/packets/packet.js:329
77
+ 5 0.0% 0.1% LazyCompile: *Packet.isError /private/tmp/node-mysql2/lib/packets/packet.js:241
78
+ 5 0.0% 0.1% Function: ~PacketParser.execute /private/tmp/node-mysql2/lib/packet_parser.js:23
79
+ 4 0.0% 0.1% Stub: KeyedLoadElementStub {1}
80
+ 4 0.0% 0.1% Stub: KeyedLoadElementStub
81
+ 4 0.0% 0.1% Stub: FastCloneShallowObjectStub {3}
82
+ 4 0.0% 0.1% LazyCompile: *isBuffer buffer.js:293
83
+ 4 0.0% 0.1% LazyCompile: *isArray native array.js:1463
84
+ 4 0.0% 0.1% LazyCompile: *ResultSetHeader /private/tmp/node-mysql2/lib/packets/resultset_header.js:4
85
+ 4 0.0% 0.1% Function: ~stream.ondata /private/tmp/node-mysql2/lib/connection.js:56
86
+ 4 0.0% 0.1% Function: ~Socket._write net.js:515
87
+ 4 0.0% 0.1% Function: ~Packet.readInt8 /private/tmp/node-mysql2/lib/packets/packet.js:38
88
+ 3 0.0% 0.1% Stub: StringAddStub
89
+ 3 0.0% 0.1% Stub: JSEntryStub {1}
90
+ 3 0.0% 0.1% Stub: FastNewContextStub {1}
91
+ 3 0.0% 0.1% Stub: FastCloneShallowObjectStub {5}
92
+ 3 0.0% 0.1% Stub: FastCloneShallowObjectStub
93
+ 3 0.0% 0.1% Stub: CompareICStub {2}
94
+ 3 0.0% 0.1% Stub: BinaryOpStub_MUL_Alloc_SMI
95
+ 3 0.0% 0.1% LazyCompile: *toLowerCase native string.js:739
96
+ 3 0.0% 0.1% LazyCompile: *isFinite native v8natives.js:103
97
+ 2 0.0% 0.0% Stub: ToBooleanStub_UndefinedNullSpecObject
98
+ 2 0.0% 0.0% Stub: FastNewContextStub
99
+ 2 0.0% 0.0% Stub: ConstructStub {1}
100
+ 2 0.0% 0.0% Stub: CompareICStub {1}
101
+ 2 0.0% 0.0% LazyCompile: <anonymous> native string.js:36
102
+ 2 0.0% 0.0% LazyCompile: *Packet.writeString /private/tmp/node-mysql2/lib/packets/packet.js:302
103
+ 2 0.0% 0.0% LazyCompile: *Packet.parseInt /private/tmp/node-mysql2/lib/packets/packet.js:170
104
+ 2 0.0% 0.0% LazyCompile: *Packet.isEOF /private/tmp/node-mysql2/lib/packets/packet.js:55
105
+ 2 0.0% 0.0% LazyCompile: *Packet.haveMoreData /private/tmp/node-mysql2/lib/packets/packet.js:28
106
+ 2 0.0% 0.0% KeyedLoadIC: args_count: 0
107
+ 2 0.0% 0.0% KeyedLoadIC: A keyed load IC from the snapshot
108
+ 2 0.0% 0.0% Function: ~Packet.readLengthCodedNumber /private/tmp/node-mysql2/lib/packets/packet.js:59
109
+ 2 0.0% 0.0% Function: ~EventEmitter.emit events.js:54
110
+ 2 0.0% 0.0% Builtin: A builtin from the snapshot {5}
111
+ 1 0.0% 0.0% Stub: ToBooleanStub_UndefinedSmi
112
+ 1 0.0% 0.0% Stub: ToBooleanStub
113
+ 1 0.0% 0.0% Stub: InterruptStub
114
+ 1 0.0% 0.0% Stub: FastCloneShallowObjectStub {4}
115
+ 1 0.0% 0.0% Stub: FastCloneShallowObjectStub {1}
116
+ 1 0.0% 0.0% Stub: FastCloneShallowArrayStub
117
+ 1 0.0% 0.0% Stub: CompareStub
118
+ 1 0.0% 0.0% Stub: CompareICStub {3}
119
+ 1 0.0% 0.0% Stub: CallFunctionStub_Args2_Recording
120
+ 1 0.0% 0.0% Stub: ArgumentsAccessStub
121
+ 1 0.0% 0.0% LazyCompile: captureStackTrace native messages.js:1100
122
+ 1 0.0% 0.0% LazyCompile: *Packet.writeInt8 /private/tmp/node-mysql2/lib/packets/packet.js:285
123
+ 1 0.0% 0.0% LazyCompile: *Packet.parseLengthCodedInt /private/tmp/node-mysql2/lib/packets/packet.js:233
124
+ 1 0.0% 0.0% KeyedLoadIC: args_count: 0 {2}
125
+ 1 0.0% 0.0% KeyedLoadIC: args_count: 0 {1}
126
+ 1 0.0% 0.0% Function: ~fs.statSync fs.js:523
127
+ 1 0.0% 0.0% Function: ~Query.row /private/tmp/node-mysql2/lib/commands/query.js:68
128
+ 1 0.0% 0.0% Function: ~Packet.isError /private/tmp/node-mysql2/lib/packets/packet.js:241
129
+ 1 0.0% 0.0% Function: ~Buffer.write buffer.js:329
130
+ 1 0.0% 0.0% CallMiss: args_count: 3
131
+
132
+ [C++]:
133
+ ticks total nonlib name
134
+
135
+ [GC]:
136
+ ticks total nonlib name
137
+ 2727 1.7%
138
+
139
+ [Bottom up (heavy) profile]:
140
+ Note: percentage shows a share of a particular caller in the total
141
+ amount of its parent calls.
142
+ Callers occupying less than 2.0% are not shown.
143
+
144
+ ticks parent name
145
+ 53890 34.5% /usr/lib/system/libsystem_c.dylib
146
+ 29167 54.1% Script: ~native mirror.js
147
+ 28321 97.1% LazyCompile: *Query.row /private/tmp/node-mysql2/lib/commands/query.js:68
148
+ 28321 100.0% Function: Command.execute /private/tmp/node-mysql2/lib/commands/command.js:10
149
+ 28321 100.0% LazyCompile: *Connection.handlePacket /private/tmp/node-mysql2/lib/connection.js:67
150
+ 28321 100.0% Function: b native v8natives.js:1582
151
+ 846 2.9% LazyCompile: TextRow evalmachine.<anonymous>:1
152
+ 706 83.5% LazyCompile: *Query.row /private/tmp/node-mysql2/lib/commands/query.js:68
153
+ 706 100.0% Function: Command.execute /private/tmp/node-mysql2/lib/commands/command.js:10
154
+ 706 100.0% LazyCompile: *Connection.handlePacket /private/tmp/node-mysql2/lib/connection.js:67
155
+ 140 16.5% Function: ~Query.row /private/tmp/node-mysql2/lib/commands/query.js:68
156
+ 140 100.0% Function: Command.execute /private/tmp/node-mysql2/lib/commands/command.js:10
157
+ 140 100.0% LazyCompile: *Connection.handlePacket /private/tmp/node-mysql2/lib/connection.js:67
158
+ 23246 43.1% Script: ~native debug.js
159
+ 22584 97.2% LazyCompile: *Query.row /private/tmp/node-mysql2/lib/commands/query.js:68
160
+ 22584 100.0% Function: Command.execute /private/tmp/node-mysql2/lib/commands/command.js:10
161
+ 22584 100.0% LazyCompile: *Connection.handlePacket /private/tmp/node-mysql2/lib/connection.js:67
162
+ 22584 100.0% Function: b native v8natives.js:1582
163
+ 662 2.8% LazyCompile: TextRow evalmachine.<anonymous>:1
164
+ 543 82.0% LazyCompile: *Query.row /private/tmp/node-mysql2/lib/commands/query.js:68
165
+ 543 100.0% Function: Command.execute /private/tmp/node-mysql2/lib/commands/command.js:10
166
+ 543 100.0% LazyCompile: *Connection.handlePacket /private/tmp/node-mysql2/lib/connection.js:67
167
+ 119 18.0% Function: ~Query.row /private/tmp/node-mysql2/lib/commands/query.js:68
168
+ 119 100.0% Function: Command.execute /private/tmp/node-mysql2/lib/commands/command.js:10
169
+ 119 100.0% LazyCompile: *Connection.handlePacket /private/tmp/node-mysql2/lib/connection.js:67
170
+
171
+ 50720 32.4% /usr/lib/system/libsystem_kernel.dylib
172
+ 22714 44.8% Script: ~native mirror.js
173
+ 22047 97.1% LazyCompile: *Query.row /private/tmp/node-mysql2/lib/commands/query.js:68
174
+ 22047 100.0% Function: Command.execute /private/tmp/node-mysql2/lib/commands/command.js:10
175
+ 22047 100.0% LazyCompile: *Connection.handlePacket /private/tmp/node-mysql2/lib/connection.js:67
176
+ 22047 100.0% Function: b native v8natives.js:1582
177
+ 667 2.9% LazyCompile: TextRow evalmachine.<anonymous>:1
178
+ 547 82.0% LazyCompile: *Query.row /private/tmp/node-mysql2/lib/commands/query.js:68
179
+ 547 100.0% Function: Command.execute /private/tmp/node-mysql2/lib/commands/command.js:10
180
+ 547 100.0% LazyCompile: *Connection.handlePacket /private/tmp/node-mysql2/lib/connection.js:67
181
+ 120 18.0% Function: ~Query.row /private/tmp/node-mysql2/lib/commands/query.js:68
182
+ 120 100.0% Function: Command.execute /private/tmp/node-mysql2/lib/commands/command.js:10
183
+ 120 100.0% LazyCompile: *Connection.handlePacket /private/tmp/node-mysql2/lib/connection.js:67
184
+ 17884 35.3% Script: ~native debug.js
185
+ 17380 97.2% LazyCompile: *Query.row /private/tmp/node-mysql2/lib/commands/query.js:68
186
+ 17380 100.0% Function: Command.execute /private/tmp/node-mysql2/lib/commands/command.js:10
187
+ 17380 100.0% LazyCompile: *Connection.handlePacket /private/tmp/node-mysql2/lib/connection.js:67
188
+ 17380 100.0% Function: b native v8natives.js:1582
189
+ 504 2.8% LazyCompile: TextRow evalmachine.<anonymous>:1
190
+ 414 82.1% LazyCompile: *Query.row /private/tmp/node-mysql2/lib/commands/query.js:68
191
+ 414 100.0% Function: Command.execute /private/tmp/node-mysql2/lib/commands/command.js:10
192
+ 414 100.0% LazyCompile: *Connection.handlePacket /private/tmp/node-mysql2/lib/connection.js:67
193
+ 90 17.9% Function: ~Query.row /private/tmp/node-mysql2/lib/commands/query.js:68
194
+ 90 100.0% Function: Command.execute /private/tmp/node-mysql2/lib/commands/command.js:10
195
+ 90 100.0% LazyCompile: *Connection.handlePacket /private/tmp/node-mysql2/lib/connection.js:67
196
+
197
+ 47085 30.1% /usr/local/bin/node
198
+ 20688 43.9% Script: ~native mirror.js
199
+ 20090 97.1% LazyCompile: *Query.row /private/tmp/node-mysql2/lib/commands/query.js:68
200
+ 20090 100.0% Function: Command.execute /private/tmp/node-mysql2/lib/commands/command.js:10
201
+ 20090 100.0% LazyCompile: *Connection.handlePacket /private/tmp/node-mysql2/lib/connection.js:67
202
+ 20090 100.0% Function: b native v8natives.js:1582
203
+ 570 2.8% LazyCompile: TextRow evalmachine.<anonymous>:1
204
+ 470 82.5% LazyCompile: *Query.row /private/tmp/node-mysql2/lib/commands/query.js:68
205
+ 470 100.0% Function: Command.execute /private/tmp/node-mysql2/lib/commands/command.js:10
206
+ 470 100.0% LazyCompile: *Connection.handlePacket /private/tmp/node-mysql2/lib/connection.js:67
207
+ 100 17.5% Function: ~Query.row /private/tmp/node-mysql2/lib/commands/query.js:68
208
+ 100 100.0% Function: Command.execute /private/tmp/node-mysql2/lib/commands/command.js:10
209
+ 100 100.0% LazyCompile: *Connection.handlePacket /private/tmp/node-mysql2/lib/connection.js:67
210
+ 16503 35.0% Script: ~native debug.js
211
+ 15958 96.7% LazyCompile: *Query.row /private/tmp/node-mysql2/lib/commands/query.js:68
212
+ 15958 100.0% Function: Command.execute /private/tmp/node-mysql2/lib/commands/command.js:10
213
+ 15958 100.0% LazyCompile: *Connection.handlePacket /private/tmp/node-mysql2/lib/connection.js:67
214
+ 15958 100.0% Function: b native v8natives.js:1582
215
+ 514 3.1% LazyCompile: TextRow evalmachine.<anonymous>:1
216
+ 420 81.7% LazyCompile: *Query.row /private/tmp/node-mysql2/lib/commands/query.js:68
217
+ 420 100.0% Function: Command.execute /private/tmp/node-mysql2/lib/commands/command.js:10
218
+ 420 100.0% LazyCompile: *Connection.handlePacket /private/tmp/node-mysql2/lib/connection.js:67
219
+ 94 18.3% Function: ~Query.row /private/tmp/node-mysql2/lib/commands/query.js:68
220
+ 94 100.0% Function: Command.execute /private/tmp/node-mysql2/lib/commands/command.js:10
221
+ 94 100.0% LazyCompile: *Connection.handlePacket /private/tmp/node-mysql2/lib/connection.js:67
222
+ 4108 8.7% LazyCompile: *Query.row /private/tmp/node-mysql2/lib/commands/query.js:68
223
+ 4108 100.0% Function: Command.execute /private/tmp/node-mysql2/lib/commands/command.js:10
224
+ 4108 100.0% LazyCompile: *Connection.handlePacket /private/tmp/node-mysql2/lib/connection.js:67
225
+ 4108 100.0% Function: b native v8natives.js:1582
226
+ 3479 84.7% LazyCompile: *PacketParser.execute /private/tmp/node-mysql2/lib/packet_parser.js:23
227
+ 321 7.8% Function: ~PacketParser.execute /private/tmp/node-mysql2/lib/packet_parser.js:23
228
+ 308 7.5% Function: ~stream.ondata /private/tmp/node-mysql2/lib/connection.js:56
@@ -0,0 +1,5 @@
1
+ var mysql = require('../test/common').createConnection();
2
+ mysql.query(process.argv[2], function(err, rows, fields) {
3
+ // Work in progress
4
+ console.log(err, rows, fields);
5
+ });
package/index.js CHANGED
@@ -2,3 +2,5 @@ var Connection = require('./lib/connection');
2
2
  module.exports.createConnection = function(opts) {
3
3
  return new Connection(opts);
4
4
  };
5
+
6
+ module.exports.Connection = Connection;
@@ -1,6 +1,7 @@
1
1
  var Command = require('./command');
2
2
  var Packets = require('../packets/index.js');
3
3
  var util = require('util');
4
+ var compileParser = require('../compile_binary_parser');
4
5
 
5
6
  function Execute(sql, parameters, callback)
6
7
  {
@@ -19,6 +20,7 @@ function Execute(sql, parameters, callback)
19
20
  this.parameters = parameters;
20
21
  this.rows = [];
21
22
  this.id = 0;
23
+ this.rowParser = null;
22
24
  }
23
25
  util.inherits(Execute, Command);
24
26
 
@@ -58,10 +60,34 @@ Execute.prototype.readParameter = function(packet) {
58
60
  return this.doExecute();
59
61
  };
60
62
 
61
- Execute.prototype.readField = function(packet) {
63
+ // TODO: move to connection.js?
64
+ function getFieldsKey(fields) {
65
+ var res = '';
66
+ for (var i=0; i < fields.length; ++i)
67
+ res += '/' + fields[i].name + ':' + fields[i].columnType + ':' + fields[i].flags;
68
+ return res;
69
+ }
70
+
71
+ Execute.prototype.readField = function(packet, connection) {
62
72
  var def = new Packets.ColumnDefinition(packet);
63
73
  this.fields.push(def);
74
+
75
+ // TODO: api to allow to flag "I'm not going to chnge schema for this statement"
76
+ // this way we can ignore column definitions in binary response and use
77
+ // definition from prepare phase. Note that it's what happens currently
78
+ // e.i if you do execute("select * from foo") and later add/remove/rename rows to foo
79
+ // (without reconnecting) you are in trouble
80
+
64
81
  if (this.fields.length == this.fieldCount) {
82
+ // compile row parser
83
+ var parserKey = getFieldsKey(this.fields);
84
+ // try cached first
85
+ this.rowParser = connection.textProtocolParsers[parserKey];
86
+ if (!this.rowParser) {
87
+ this.rowParser = compileParser(this.fields);
88
+ console.log(this.rowParser.toString());
89
+ connection.textProtocolParsers[parserKey] = this.rowParser;
90
+ }
65
91
  return Execute.prototype.fieldsEOF;
66
92
  }
67
93
  return Execute.prototype.readField;
@@ -104,8 +130,13 @@ Execute.prototype.resultesetHeader = function(packet) {
104
130
  };
105
131
 
106
132
  Execute.prototype.readResultField = function(packet) {
107
- var def = new Packets.ColumnDefinition(packet);
108
- this.resultFields.push(def);
133
+ var def;
134
+ if (this.rowParser) // ignore result fields definition, we are reusing fields from prepare response
135
+ this.resultFields.push(null);
136
+ else {
137
+ def = new Packets.ColumnDefinition(packet);
138
+ this.resultFields.push(def);
139
+ }
109
140
  if (this.resultFields.length == this.resultFieldCount) {
110
141
  return Execute.prototype.resultFieldsEOF;
111
142
  }
@@ -127,9 +158,20 @@ Execute.prototype.row = function(packet)
127
158
  this.onResult(null, this.rows, this.fields);
128
159
  return null;
129
160
  }
161
+
162
+ if (this.rowParser)
163
+ {
164
+ var r = new this.rowParser(packet);
165
+ if (this.onResult)
166
+ this.rows.push(r);
167
+ else
168
+ this.emit('result', r);
169
+ return Execute.prototype.row;
170
+ }
171
+
130
172
  var row = Packets.BinaryRow.fromPacket(this.fields, packet);
131
173
  // TODO: here we'll have dynamically pre-compiled and cached row parser
132
- if (true) // TODO: think of API to store raw copulns array (most probably connection options flags)
174
+ if (true) // TODO: think of API to store raw columns array (most probably connection options flags)
133
175
  {
134
176
  var r = {};
135
177
  for (var i = 0; i < row.columns.length; ++i)
@@ -34,10 +34,11 @@ Query.prototype.resultsetHeader = function(packet) {
34
34
  return Query.prototype.readField;
35
35
  };
36
36
 
37
+ // TODO: move to connection.js ?
37
38
  function getFieldsKey(fields) {
38
39
  var res = '';
39
40
  for (var i=0; i < fields.length; ++i)
40
- res += '/' + fields[i].name + ':' + fields[i].columnType;
41
+ res += '/' + fields[i].name + ':' + fields[i].columnType + ':' + fields[i].flags;
41
42
  return res;
42
43
  }
43
44
 
@@ -0,0 +1,66 @@
1
+ var constants = require('./constants');
2
+ var vm = require('vm');
3
+
4
+ function compile(fields) {
5
+ var result = [];
6
+ var i=0;
7
+ var j=0;
8
+ var nullBitmapLength = Math.floor((fields.length + 7 + 2) / 8);
9
+ result.push('function BinaryRow(packet) {');
10
+ result.push(' var statusByte = packet.readInt8();');
11
+ for (j=0; j < nullBitmapLength; ++j)
12
+ result.push(' var nullBitmaskByte' + j + ' = packet.readInt8();');
13
+
14
+ var currentFieldNullBit = 4;
15
+ var nullByteIndex = 0;
16
+ for (i = 0; i < fields.length; i++) {
17
+ //result.push(' // type = ' + fields[i].columnType + ' flags = ' + fields[i].flags);
18
+ if (fields[i].flags & constants.FIELD_NOT_NULL) { // don't need to check null bitmap if field can't be null.
19
+ result.push(' this[\'' + fields[i].name + '\'] = ' + readCodeFor(fields[i].columnType, fields[i].flags));
20
+ } else if (fields[i].columnType == constants.MYSQL_TYPE_NULL) {
21
+ result.push(' this[\'' + fields[i].name + '\'] = null;');
22
+ } else {
23
+ result.push(' if (nullBitmaskByte' + nullByteIndex + ' & ' + currentFieldNullBit + ')');
24
+ result.push(' this[\'' + fields[i].name + '\'] = null;');
25
+ result.push(' else');
26
+ result.push(' this[\'' + fields[i].name + '\'] = ' + readCodeFor(fields[i].columnType, fields[i].flags));
27
+ }
28
+ currentFieldNullBit *= 2;
29
+ if (currentFieldNullBit == 0x100)
30
+ {
31
+ currentFieldNullBit = 1;
32
+ nullByteIndex++;
33
+ }
34
+ }
35
+ result.push('} BinaryRow;');
36
+ var src = result.join('\n');
37
+ return vm.runInNewContext(src);
38
+ }
39
+
40
+ function readCodeFor(type, flags) {
41
+ switch(type) {
42
+ case constants.MYSQL_TYPE_TINY:
43
+ return "packet.readInt8();";
44
+ case constants.MYSQL_TYPE_SHORT:
45
+ return "packet.readInt16();";
46
+ case constants.MYSQL_TYPE_LONG:
47
+ case constants.MYSQL_TYPE_INT24: // in binary protocol int24 is encoded in 4 bytes int32
48
+ return "packet.readInt32();";
49
+ case constants.MYSQL_TYPE_YEAR:
50
+ return "\'not implemented\';";
51
+ case constants.MYSQL_TYPE_FLOAT:
52
+ return "packet.readFloat();";
53
+ case constants.MYSQL_TYPE_DOUBLE:
54
+ return "packet.readDouble();";
55
+ case constants.MYSQL_TYPE_NULL:
56
+ return "null;";
57
+ case constants.MYSQL_TYPE_DATETIME:
58
+ return "packet.readDateTime();";
59
+ case constants.MYSQL_TYPE_LONGLONG: // TODO: 8 bytes. Implement as 4 bytes read for now
60
+ return "packet.readInt32() + 0xffffffff*packet.readInt32();";
61
+ default:
62
+ return "packet.readLengthCodedString();";
63
+ }
64
+ }
65
+
66
+ module.exports = compile;
@@ -1,3 +1,4 @@
1
+ var constants = require('./constants');
1
2
  var vm = require('vm');
2
3
 
3
4
  function compile(fields) {
@@ -14,19 +15,17 @@ function compile(fields) {
14
15
 
15
16
  function readCodeFor(type) {
16
17
  switch(type) {
17
- case 1:
18
- case 2:
19
- case 3:
20
- case 9:
21
- case 13:
18
+ case constants.MYSQL_TYPE_TINY:
19
+ case constants.MYSQL_TYPE_SHORT:
20
+ case constants.MYSQL_TYPE_LONG:
21
+ case constants.MYSQL_TYPE_INT24:
22
+ case constants.MYSQL_TYPE_YEAR:
22
23
  return "packet.parseLengthCodedInt();";
23
- // TODO: implement parseFloat
24
- //case 4:
25
- //case 5:
26
- // return "packet.parseFloat();";
27
- case 6:
28
- return "null;";
29
-
24
+ case constants.MYSQL_TYPE_FLOAT:
25
+ case constants.MYSQL_TYPE_DOUBLE:
26
+ return "packet.parseLengthCodedFloat();";
27
+ case constants.MYSQL_TYPE_NULL:
28
+ return "null; packet.skip(1);";
30
29
  default:
31
30
  return "packet.readLengthCodedString(); //" + type;
32
31
  }
package/lib/connection.js CHANGED
@@ -21,7 +21,8 @@ function Connection(opts)
21
21
  opts.flags = params.query.flags.split(',');
22
22
  _.extend(opts, _.pick(params.query, 'socketPath', 'charset', 'timesone', 'insecureAuth', 'typeCast', 'supportBigNumbers', 'debug'));
23
23
  }
24
- // fill defaults
24
+
25
+ // TODO: fill defaults
25
26
  // if no params, connect to /var/lib/mysql/mysql.sock ( /tmp/mysql.sock on OSX )
26
27
  // if host is given, connect to host:3306
27
28
 
@@ -36,14 +37,19 @@ function Connection(opts)
36
37
  this.opts = opts;
37
38
  this.commands = [];
38
39
  this.statements = {};
40
+
39
41
  // TODO: make it lru cache
40
42
  // https://github.com/mercadolibre/node-simple-lru-cache
41
43
  // or https://github.com/rsms/js-lru
42
44
  // or https://github.com/monsur/jscache
43
45
  //
44
- // key is field.name + ':' + field.columnType + '/'
46
+ // key is field.name + ':' + field.columnType + ':' field.flags + '/'
45
47
  this.textProtocolParsers = {};
46
48
 
49
+ // TODO: not sure if cache should be separate (same key as with textProtocolParsers)
50
+ // or part of prepared statements cache (key is sql query)
51
+ this.binaryProtocolParsers = {};
52
+
47
53
  var connection = this;
48
54
  this.packetParser = new PacketParser(this.handlePacket.bind(this));
49
55
  // TODO: check stream instanceof net.Stream, fallback if not
@@ -64,7 +70,7 @@ Connection.prototype.handlePacket = function(packet) {
64
70
  if (done) {
65
71
  commands.shift();
66
72
  if (commands.length !== 0)
67
- this.handlePacket(); // TODO: process.nextTick ?
73
+ this.handlePacket(); // TODO: process.nextTick to avoid recursion?
68
74
  }
69
75
  };
70
76
 
@@ -1,4 +1,4 @@
1
- //var constants = require('../constants');
1
+ var constants = require('../constants');
2
2
  var Packet = require('../packets/packet');
3
3
 
4
4
  function BinaryRow(columns)
@@ -6,22 +6,25 @@ function BinaryRow(columns)
6
6
  this.columns = columns || [];
7
7
  }
8
8
 
9
- var binaryReader = new Array(256);
10
- binaryReader[0] = Packet.prototype.readLengthCodedString; // MYSQL_TYPE_DECIMAL
11
- binaryReader[1] = Packet.prototype.readInt8; // tiny
12
- binaryReader[2] = Packet.prototype.readInt16; // short
13
- binaryReader[3] = Packet.prototype.readInt32; // long
14
- binaryReader[4] = Packet.prototype.readFloat; // float
15
- binaryReader[5] = Packet.prototype.readDouble; // double
16
- binaryReader[6] = Packet.prototype.assertInvalid; // null, should be skipped vie null bitmap
17
- binaryReader[7] = Packet.prototype.readTimestamp; // timestamp, http://dev.mysql.com/doc/internals/en/prepared-statements.html#packet-ProtocolBinary::MYSQL_TYPE_TIMESTAMP
18
- binaryReader[8] = Packet.prototype.readInt64; // long long
19
- binaryReader[9] = Packet.prototype.readInt32; // int24
20
- binaryReader[10] = Packet.prototype.readTimestamp; // date
21
- binaryReader[11] = Packet.prototype.readTime; // time, http://dev.mysql.com/doc/internals/en/prepared-statements.html#packet-ProtocolBinary::MYSQL_TYPE_TIME
22
- binaryReader[12] = Packet.prototype.readDateTime; // datetime, http://dev.mysql.com/doc/internals/en/prepared-statements.html#packet-ProtocolBinary::MYSQL_TYPE_DATETIME
23
- binaryReader[13] = Packet.prototype.readInt16; // year
24
- // TODO: complete list of types...
9
+ var binaryReader = new Array(256);
10
+
11
+ // TODO: replace with constants.MYSQL_TYPE_*
12
+ binaryReader[0] = Packet.prototype.readLengthCodedString; // MYSQL_TYPE_DECIMAL
13
+ binaryReader[1] = Packet.prototype.readInt8; // tiny
14
+ binaryReader[2] = Packet.prototype.readInt16; // short
15
+ binaryReader[3] = Packet.prototype.readInt32; // long
16
+ binaryReader[4] = Packet.prototype.readFloat; // float
17
+ binaryReader[5] = Packet.prototype.readDouble; // double
18
+ binaryReader[6] = Packet.prototype.assertInvalid; // null, should be skipped vie null bitmap
19
+ binaryReader[7] = Packet.prototype.readTimestamp; // timestamp, http://dev.mysql.com/doc/internals/en/prepared-statements.html#packet-ProtocolBinary::MYSQL_TYPE_TIMESTAMP
20
+ binaryReader[8] = Packet.prototype.readInt64; // long long
21
+ binaryReader[9] = Packet.prototype.readInt32; // int24
22
+ binaryReader[10] = Packet.prototype.readTimestamp; // date
23
+ binaryReader[11] = Packet.prototype.readTime; // time, http://dev.mysql.com/doc/internals/en/prepared-statements.html#packet-ProtocolBinary::MYSQL_TYPE_TIME
24
+ binaryReader[12] = Packet.prototype.readDateTime; // datetime, http://dev.mysql.com/doc/internals/en/prepared-statements.html#packet-ProtocolBinary::MYSQL_TYPE_DATETIME
25
+ binaryReader[13] = Packet.prototype.readInt16; // year
26
+ binaryReader[constants.MYSQL_TYPE_VAR_STRING] = Packet.prototype.readLengthCodedString; // var string
27
+ // TODO: complete list of types...
25
28
 
26
29
  BinaryRow.fromPacket = function(fields, packet) {
27
30
  var columns = new Array(fields.length);
@@ -30,7 +33,7 @@ BinaryRow.fromPacket = function(fields, packet) {
30
33
  // TODO: read and interpret null bitmap
31
34
  packet.skip(nullBitmapLength);
32
35
  for (var i = 0; i < columns.length; ++i)
33
- columns[i] = binaryReader[fields[i].type].apply(packet);
36
+ columns[i] = binaryReader[fields[i].columnType].apply(packet);
34
37
  return new BinaryRow(columns);
35
38
  };
36
39
 
@@ -75,11 +75,71 @@ Packet.prototype.readLengthCodedNumber = function() {
75
75
  throw "Should not reach here: " + byte1;
76
76
  };
77
77
 
78
+ Packet.prototype.readFloat = function() {
79
+ var res = this.buffer.readFloatLE(this.offset);
80
+ this.offset += 4;
81
+ return res;
82
+ };
83
+
84
+ Packet.prototype.readDouble = function() {
85
+ var res = this.buffer.readDoubleLE(this.offset);
86
+ this.offset += 8;
87
+ return res;
88
+ };
89
+
78
90
  Packet.prototype.readBuffer = function(len) {
79
91
  this.offset += len;
80
92
  return this.buffer.slice(this.offset - len, this.offset);
81
93
  };
82
94
 
95
+ // DATE, DATETIME and TIMESTAMP
96
+ Packet.prototype.readDateTime = function(convertTtoMs) {
97
+ var length = this.readInt8();
98
+ var y = 0;
99
+ var m = 0;
100
+ var d = 0;
101
+ var H = 0;
102
+ var M = 0;
103
+ var S = 0;
104
+ var ms = 0;
105
+ if (length > 3) {
106
+ y = this.readInt16();
107
+ m = this.readInt8();
108
+ d = this.readInt8();
109
+ }
110
+ if (length > 6) {
111
+ H = this.readInt8();
112
+ M = this.readInt8();
113
+ }
114
+ if (length > 11)
115
+ ms = this.readInt32();
116
+ return new Date(y, m, d, H, M, S, ms);
117
+ };
118
+
119
+ // TIME - value in microseconds. Can be negative
120
+ Packet.prototype.readTime = function(convertTtoMs) {
121
+ var length = this.readInt8();
122
+ if (length === 0)
123
+ return 0;
124
+
125
+ var result = 0;
126
+ var sign = this.readInt8() ? -1 : 1; // 'isNegative' flag byte
127
+ var d = 0;
128
+ var H = 0;
129
+ var M = 0;
130
+ var S = 0;
131
+ var ms = 0;
132
+ if (length > 7) {
133
+ d = this.readInt32();
134
+ H = this.readInt8();
135
+ M = this.readInt8();
136
+ S = this.readInt8();
137
+ }
138
+ if (length > 11)
139
+ ms = this.readInt32();
140
+ return d*86400000 + H*3600000 + M*60000 + S*1000 + ms;
141
+ };
142
+
83
143
  Packet.prototype.readLengthCodedString = function() {
84
144
  var len = this.readLengthCodedNumber();
85
145
  // TODO: check manually first byte here to avoid polymorphic return type?
@@ -104,28 +164,88 @@ Packet.prototype.readString = function(len) {
104
164
  return this.buffer.utf8Slice(this.offset - len, this.offset);
105
165
  };
106
166
 
167
+ var minus = '-'.charCodeAt(0);
168
+ var plus = '+'.charCodeAt(0);
107
169
  // TODO: base? sign? parseFloat?
108
170
  Packet.prototype.parseInt = function(len) {
109
171
  var result = 0;
110
172
  var end = this.offset + len;
173
+ var sign = 1;
174
+ if (len === 0)
175
+ return 0; // TODO: assert? exception?
176
+ if (this.buffer[this.offset] == minus) {
177
+ this.offset++;
178
+ sign = -1;
179
+ }
180
+ if (this.buffer[this.offset] == plus) {
181
+ this.offset++; // just ignore
182
+ }
111
183
  while(this.offset < end) {
112
184
  result *= 10;
113
185
  result += this.buffer[this.offset] - 48;
114
186
  this.offset++;
115
187
  }
116
- return result;
188
+ return result*sign;
189
+ };
190
+
191
+
192
+ // TODO: handle E notation
193
+ var dot = '.'.charCodeAt(0);
194
+ var exponent = 'e'.charCodeAt(0);
195
+ var exponentCapital = 'E'.charCodeAt(0);
196
+ Packet.prototype.parseFloat = function(len) {
197
+ var result = 0;
198
+ var end = this.offset + len;
199
+ var factor = 1;
200
+ var pastDot = false;
201
+ var charCode = 0;
202
+ if (len === 0)
203
+ return 0; // TODO: assert? exception?
204
+
205
+ if (this.buffer[this.offset] == minus) {
206
+ this.offset++;
207
+ factor = -1;
208
+ }
209
+ if (this.buffer[this.offset] == plus) {
210
+ this.offset++; // just ignore
211
+ }
212
+ while(this.offset < end) {
213
+ charCode = this.buffer[this.offset];
214
+ if (charCode == dot)
215
+ {
216
+ pastDot = true;
217
+ this.offset++;
218
+ } else if (charCode == exponent || charCode == exponentCapital) {
219
+ this.offset++;
220
+ var exponentValue = this.parseInt(end - this.offset);
221
+ return (result/factor)*Math.pow(10, exponentValue);
222
+ } else {
223
+ result *= 10;
224
+ result += this.buffer[this.offset] - 48;
225
+ this.offset++;
226
+ if (pastDot)
227
+ factor = factor*10;
228
+ }
229
+ }
230
+ return result/factor;
117
231
  };
118
232
 
119
233
  Packet.prototype.parseLengthCodedInt = function() {
120
234
  return this.parseInt(this.readLengthCodedNumber());
121
235
  };
122
236
 
237
+ Packet.prototype.parseLengthCodedFloat = function() {
238
+ return this.parseFloat(this.readLengthCodedNumber());
239
+ };
240
+
123
241
  Packet.prototype.isError = function() {
124
242
  return this.buffer[this.offset] == 0xff;
125
243
  };
126
244
 
127
245
  Packet.prototype.asError = function() {
128
- this.offset = 1;
246
+ this.reset();
247
+ this.skip(1);
248
+
129
249
  var code = this.readInt8();
130
250
  var sqlState = this.readBuffer(7);
131
251
  var message = this.buffer.slice(this.offset);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mysql2",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "fast mysql driver",
5
5
  "main": "index.js",
6
6
  "directories": {