Skip to content
This repository
  • 9 commits
  • 12 files changed
  • 3 comments
  • 2 contributors
Sep 17, 2010
Felix Geisendörfer Don't execute slow tests by default
Create a new system/slow folder. Tests in there will only be run on
`make test-all`. Also made the slow test itself a little faster.
465b9b0
Sep 26, 2010
Felix Geisendörfer Renamed constructor argument to `properties`
Much clearer than `config`.
5b87b59
Felix Geisendörfer Initial support for type casting 9f53326
Felix Geisendörfer Update todo c14b4d2
Sep 27, 2010
C Corrigan Code cleanups
- add missing ';'
- remove surplus ','

Signed-off-by: Charles Corrigan <charles@runegate.org>
84b6216
Felix Geisendörfer Added new sponsor 2df74a1
Sep 28, 2010
Felix Geisendörfer Add charset constants and make utf8 default
MySql defaults on latin1, but this is the 21st century - utf8
should IMHO be pre-configured in a good MySql client.
31e43ec
Felix Geisendörfer Update readme 750332b
Felix Geisendörfer Bump version 7704155
4  Makefile
... ...
@@ -1,4 +1,6 @@
1 1
 test:
2 2
 	@find test/{simple,system}/test-*.js | xargs -n 1 -t node
  3
+test-all: test
  4
+	@find test/system/slow/test-*.js | xargs -n 1 -t node
3 5
 
4  
-.PHONY: test
  6
+.PHONY: test
10  Readme.md
Source Rendered
@@ -15,6 +15,7 @@ A node.js module implementing the
15 15
 ## Sponsors
16 16
 
17 17
 * [Joyent](http://www.joyent.com/)
  18
+* [pinkbike.com](http://pinkbike.com/)
18 19
 
19 20
 I'm working on this driver because I need it for my own startup
20 21
 ([transloadit.com][transloadit]), but it's a big project (~100-200 hours) with
@@ -192,10 +193,13 @@ parameter is provided which contains the information from the mysql OK packet.
192 193
 
193 194
 At this point the module is ready to be tried out, but a lot of things are yet to be done:
194 195
 
195  
-* Auto-cast mysql types into JS types
  196
+* Handle timeouts / reconnect
  197
+* Remaining mysql commands
196 198
 * Prepared Statements
197  
-* Charsets handling
198  
-* ...
  199
+* Packet's > 16 MB
  200
+* Compression
  201
+* Performance profiling
  202
+* ?
199 203
 
200 204
 ## License
201 205
 
16  lib/mysql/auth.js
@@ -73,7 +73,7 @@ exports.randomInit = function(seed1, seed2) {
73 73
     max_value: 0x3FFFFFFF,
74 74
     max_value_dbl: 0x3FFFFFFF,
75 75
     seed1: seed1 % 0x3FFFFFFF,
76  
-    seed2: seed2 % 0x3FFFFFFF,
  76
+    seed2: seed2 % 0x3FFFFFFF
77 77
   };
78 78
 };
79 79
 
@@ -115,18 +115,18 @@ exports.fmt32 = function(x){
115 115
   if (b.length == 2) b = '00'+b;
116 116
   if (b.length == 3) b = '0'+b;
117 117
   return '' + a + '/' + b;
118  
-}
  118
+};
119 119
 
120 120
 exports.xor32 = function(a,b){
121 121
   return [a[0] ^ b[0], a[1] ^ b[1]];
122  
-}
  122
+};
123 123
 
124 124
 exports.add32 = function(a,b){
125 125
   var w1 = a[1] + b[1],
126 126
       w2 = a[0] + b[0] + ((w1 & 0xFFFF0000) >> 16);
127 127
 
128 128
   return [w2 & 0xFFFF, w1 & 0xFFFF];
129  
-}
  129
+};
130 130
 
131 131
 exports.mul32 = function(a,b){
132 132
   // based on this example of multiplying 32b ints using 16b
@@ -135,11 +135,11 @@ exports.mul32 = function(a,b){
135 135
       w2 = (((a[1] * b[1]) >> 16) & 0xFFFF) + ((a[0] * b[1]) & 0xFFFF) + (a[1] * b[0] & 0xFFFF);
136 136
 
137 137
   return [w2 & 0xFFFF, w1 & 0xFFFF];
138  
-}
  138
+};
139 139
 
140 140
 exports.and32 = function(a,b){
141  
-  return [a[0] & b[0], a[1] & b[1]]
142  
-}
  141
+  return [a[0] & b[0], a[1] & b[1]];
  142
+};
143 143
 
144 144
 exports.shl32 = function(a,b){
145 145
   // assume b is 16 or less
@@ -147,7 +147,7 @@ exports.shl32 = function(a,b){
147 147
       w2 = (a[0] << b) | ((w1 & 0xFFFF0000) >> 16);
148 148
 
149 149
   return [w2 & 0xFFFF, w1 & 0xFFFF];
150  
-}
  150
+};
151 151
 
152 152
 exports.int31Write = function(buffer, number, offset) {
153 153
   buffer[offset] = (number[0] >> 8) & 0x7F;
147  lib/mysql/client.js
@@ -8,9 +8,9 @@ var sys = require('sys'),
8 8
     Query = require('./query'),
9 9
     EventEmitter = require('events').EventEmitter;
10 10
 
11  
-function Client(config) {
  11
+function Client(properties) {
12 12
   if (!(this instanceof Client)) {
13  
-    return new Client(config);
  13
+    return new Client(properties);
14 14
   }
15 15
 
16 16
   EventEmitter.call(this);
@@ -21,9 +21,10 @@ function Client(config) {
21 21
   this.password = null;
22 22
   this.database = '';
23 23
 
  24
+  this.typeCast = true;
24 25
   this.flags = Client.defaultFlags;
25 26
   this.maxPacketSize = 0x01000000;
26  
-  this.charsetNumber = 8;
  27
+  this.charsetNumber = Client.UTF8_UNICODE_CI;
27 28
   this.debug = false;
28 29
 
29 30
   this._greeting = null;
@@ -31,10 +32,10 @@ function Client(config) {
31 32
   this._connection = null;
32 33
   this._parser = null;
33 34
 
34  
-  for (var key in config) {
35  
-    this[key] = config[key];
  35
+  for (var key in properties) {
  36
+    this[key] = properties[key];
36 37
   }
37  
-}
  38
+};
38 39
 sys.inherits(Client, EventEmitter);
39 40
 module.exports = Client;
40 41
 
@@ -69,7 +70,8 @@ Client.prototype.query = function(sql, params, cb) {
69 70
     cb = arguments[1];
70 71
   }
71 72
 
72  
-  var query = new Query();
  73
+  var query = new Query({typeCast: this.typeCast});
  74
+
73 75
   if (cb) {
74 76
     var rows = [], fields = {};
75 77
     query
@@ -319,7 +321,7 @@ Client.CONNECT_WITH_DB   = 8;
319 321
 Client.NO_SCHEMA         = 16;
320 322
 Client.COMPRESS          = 32;
321 323
 Client.ODBC              = 64;
322  
-Client.LOCAL_FILES       = 128
  324
+Client.LOCAL_FILES       = 128;
323 325
 Client.IGNORE_SPACE      = 256;
324 326
 Client.PROTOCOL_41       = 512;
325 327
 Client.INTERACTIVE       = 1024;
@@ -379,6 +381,135 @@ Client.COM_STMT_RESET          = 0x1a;
379 381
 Client.COM_SET_OPTION          = 0x1b;
380 382
 Client.COM_STMT_FETCH          = 0x1c;
381 383
 
  384
+// Collations / Charsets
  385
+Client.BIG5_CHINESE_CI      = 1;
  386
+Client.LATIN2_CZECH_CS      = 2;
  387
+Client.DEC8_SWEDISH_CI      = 3;
  388
+Client.CP850_GENERAL_CI     = 4;
  389
+Client.LATIN1_GERMAN1_CI    = 5;
  390
+Client.HP8_ENGLISH_CI       = 6;
  391
+Client.KOI8R_GENERAL_CI     = 7;
  392
+Client.LATIN1_SWEDISH_CI    = 8;
  393
+Client.LATIN2_GENERAL_CI    = 9;
  394
+Client.SWE7_SWEDISH_CI      = 10;
  395
+Client.ASCII_GENERAL_CI     = 11;
  396
+Client.UJIS_JAPANESE_CI     = 12;
  397
+Client.SJIS_JAPANESE_CI     = 13;
  398
+Client.CP1251_BULGARIAN_CI  = 14;
  399
+Client.LATIN1_DANISH_CI     = 15;
  400
+Client.HEBREW_GENERAL_CI    = 16;
  401
+Client.TIS620_THAI_CI       = 18;
  402
+Client.EUCKR_KOREAN_CI      = 19;
  403
+Client.LATIN7_ESTONIAN_CS   = 20;
  404
+Client.LATIN2_HUNGARIAN_CI  = 21;
  405
+Client.KOI8U_GENERAL_CI     = 22;
  406
+Client.CP1251_UKRAINIAN_CI  = 23;
  407
+Client.GB2312_CHINESE_CI    = 24;
  408
+Client.GREEK_GENERAL_CI     = 25;
  409
+Client.CP1250_GENERAL_CI    = 26;
  410
+Client.LATIN2_CROATIAN_CI   = 27;
  411
+Client.GBK_CHINESE_CI       = 28;
  412
+Client.CP1257_LITHUANIAN_CI = 29;
  413
+Client.LATIN5_TURKISH_CI    = 30;
  414
+Client.LATIN1_GERMAN2_CI    = 31;
  415
+Client.ARMSCII8_GENERAL_CI  = 32;
  416
+Client.UTF8_GENERAL_CI      = 33;
  417
+Client.CP1250_CZECH_CS      = 34;
  418
+Client.UCS2_GENERAL_CI      = 35;
  419
+Client.CP866_GENERAL_CI     = 36;
  420
+Client.KEYBCS2_GENERAL_CI   = 37;
  421
+Client.MACCE_GENERAL_CI     = 38;
  422
+Client.MACROMAN_GENERAL_CI  = 39;
  423
+Client.CP852_GENERAL_CI     = 40;
  424
+Client.LATIN7_GENERAL_CI    = 41;
  425
+Client.LATIN7_GENERAL_CS    = 42;
  426
+Client.MACCE_BIN            = 43;
  427
+Client.CP1250_CROATIAN_CI   = 44;
  428
+Client.LATIN1_BIN           = 47;
  429
+Client.LATIN1_GENERAL_CI    = 48;
  430
+Client.LATIN1_GENERAL_CS    = 49;
  431
+Client.CP1251_BIN           = 50;
  432
+Client.CP1251_GENERAL_CI    = 51;
  433
+Client.CP1251_GENERAL_CS    = 52;
  434
+Client.MACROMAN_BIN         = 53;
  435
+Client.CP1256_GENERAL_CI    = 57;
  436
+Client.CP1257_BIN           = 58;
  437
+Client.CP1257_GENERAL_CI    = 59;
  438
+Client.BINARY               = 63;
  439
+Client.ARMSCII8_BIN         = 64;
  440
+Client.ASCII_BIN            = 65;
  441
+Client.CP1250_BIN           = 66;
  442
+Client.CP1256_BIN           = 67;
  443
+Client.CP866_BIN            = 68;
  444
+Client.DEC8_BIN             = 69;
  445
+Client.GREEK_BIN            = 70;
  446
+Client.HEBREW_BIN           = 71;
  447
+Client.HP8_BIN              = 72;
  448
+Client.KEYBCS2_BIN          = 73;
  449
+Client.KOI8R_BIN            = 74;
  450
+Client.KOI8U_BIN            = 75;
  451
+Client.LATIN2_BIN           = 77;
  452
+Client.LATIN5_BIN           = 78;
  453
+Client.LATIN7_BIN           = 79;
  454
+Client.CP850_BIN            = 80;
  455
+Client.CP852_BIN            = 81;
  456
+Client.SWE7_BIN             = 82;
  457
+Client.UTF8_BIN             = 83;
  458
+Client.BIG5_BIN             = 84;
  459
+Client.EUCKR_BIN            = 85;
  460
+Client.GB2312_BIN           = 86;
  461
+Client.GBK_BIN              = 87;
  462
+Client.SJIS_BIN             = 88;
  463
+Client.TIS620_BIN           = 89;
  464
+Client.UCS2_BIN             = 90;
  465
+Client.UJIS_BIN             = 91;
  466
+Client.GEOSTD8_GENERAL_CI   = 92;
  467
+Client.GEOSTD8_BIN          = 93;
  468
+Client.LATIN1_SPANISH_CI    = 94;
  469
+Client.CP932_JAPANESE_CI    = 95;
  470
+Client.CP932_BIN            = 96;
  471
+Client.EUCJPMS_JAPANESE_CI  = 97;
  472
+Client.EUCJPMS_BIN          = 98;
  473
+Client.CP1250_POLISH_CI     = 99;
  474
+Client.UCS2_UNICODE_CI      = 128;
  475
+Client.UCS2_ICELANDIC_CI    = 129;
  476
+Client.UCS2_LATVIAN_CI      = 130;
  477
+Client.UCS2_ROMANIAN_CI     = 131;
  478
+Client.UCS2_SLOVENIAN_CI    = 132;
  479
+Client.UCS2_POLISH_CI       = 133;
  480
+Client.UCS2_ESTONIAN_CI     = 134;
  481
+Client.UCS2_SPANISH_CI      = 135;
  482
+Client.UCS2_SWEDISH_CI      = 136;
  483
+Client.UCS2_TURKISH_CI      = 137;
  484
+Client.UCS2_CZECH_CI        = 138;
  485
+Client.UCS2_DANISH_CI       = 139;
  486
+Client.UCS2_LITHUANIAN_CI   = 140;
  487
+Client.UCS2_SLOVAK_CI       = 141;
  488
+Client.UCS2_SPANISH2_CI     = 142;
  489
+Client.UCS2_ROMAN_CI        = 143;
  490
+Client.UCS2_PERSIAN_CI      = 144;
  491
+Client.UCS2_ESPERANTO_CI    = 145;
  492
+Client.UCS2_HUNGARIAN_CI    = 146;
  493
+Client.UTF8_UNICODE_CI      = 192;
  494
+Client.UTF8_ICELANDIC_CI    = 193;
  495
+Client.UTF8_LATVIAN_CI      = 194;
  496
+Client.UTF8_ROMANIAN_CI     = 195;
  497
+Client.UTF8_SLOVENIAN_CI    = 196;
  498
+Client.UTF8_POLISH_CI       = 197;
  499
+Client.UTF8_ESTONIAN_CI     = 198;
  500
+Client.UTF8_SPANISH_CI      = 199;
  501
+Client.UTF8_SWEDISH_CI      = 200;
  502
+Client.UTF8_TURKISH_CI      = 201;
  503
+Client.UTF8_CZECH_CI        = 202;
  504
+Client.UTF8_DANISH_CI       = 203;
  505
+Client.UTF8_LITHUANIAN_CI   = 204;
  506
+Client.UTF8_SLOVAK_CI       = 205;
  507
+Client.UTF8_SPANISH2_CI     = 206;
  508
+Client.UTF8_ROMAN_CI        = 207;
  509
+Client.UTF8_PERSIAN_CI      = 208;
  510
+Client.UTF8_ESPERANTO_CI    = 209;
  511
+Client.UTF8_HUNGARIAN_CI    = 210;
  512
+
382 513
 // Error numbers
383 514
 // from: http://dev.mysql.com/doc/refman/5.0/en/error-messages-server.html
384 515
 Client.ERROR_HASHCHK                                 = 1000;
2  lib/mysql/outgoing_packet.js
@@ -7,7 +7,7 @@ function OutgoingPacket(size, num) {
7 7
   this.index = 0;
8 8
   this.writeNumber(3, size);
9 9
   this.writeNumber(1, num || 0);
10  
-}
  10
+};
11 11
 module.exports = OutgoingPacket;
12 12
 
13 13
 OutgoingPacket.prototype.writeNumber = function(bytes, number) {
8  lib/mysql/parser.js
@@ -18,7 +18,7 @@ function Parser() {
18 18
 
19 19
   this._lengthCodedLength = null;
20 20
   this._lengthCodedStringLength = null;
21  
-}
  21
+};
22 22
 sys.inherits(Parser, EventEmitter);
23 23
 module.exports = Parser;
24 24
 
@@ -161,7 +161,7 @@ Parser.prototype.write = function(buffer) {
161 161
         break;
162 162
       case Parser.GREETING_FILLER_1:
163 163
         // 1 byte - 0x00
164  
-        advance()
  164
+        advance();
165 165
         break;
166 166
       case Parser.GREETING_SERVER_CAPABILITIES:
167 167
         if (packet.index == 0) {
@@ -208,7 +208,7 @@ Parser.prototype.write = function(buffer) {
208 208
         if (packet.index == 0) {
209 209
           if (c === 0xff) {
210 210
             packet.type = Parser.ERROR_PACKET;
211  
-            advance(Parser.ERROR_NUMBER)
  211
+            advance(Parser.ERROR_NUMBER);
212 212
             break;
213 213
           }
214 214
 
@@ -221,7 +221,7 @@ Parser.prototype.write = function(buffer) {
221 221
             // after the first OK PACKET, we are authenticated
222 222
             this.authenticated = true;
223 223
             packet.type = Parser.OK_PACKET;
224  
-            advance(Parser.AFFECTED_ROWS)
  224
+            advance(Parser.AFFECTED_ROWS);
225 225
             break;
226 226
           }
227 227
         }
73  lib/mysql/query.js
@@ -5,9 +5,15 @@ var sys = require('sys'),
5 5
     Parser = require('./parser'),
6 6
     Client;
7 7
 
8  
-function Query() {
  8
+function Query(properties) {
9 9
   EventEmitter.call(this);
10  
-}
  10
+
  11
+  this.typeCast = true;
  12
+
  13
+  for (var key in properties) {
  14
+    this[key] = properties[key];
  15
+  }
  16
+};
11 17
 sys.inherits(Query, EventEmitter);
12 18
 module.exports = Query;
13 19
 
@@ -31,7 +37,7 @@ Query.prototype._handlePacket = function(packet) {
31 37
         this._fields = [];
32 38
       }
33 39
 
34  
-      this._fields.push(packet.name);
  40
+      this._fields.push(packet);
35 41
       this.emit('field', packet);
36 42
       break;
37 43
     case Parser.EOF_PACKET:
@@ -50,17 +56,42 @@ Query.prototype._handlePacket = function(packet) {
50 56
           field = this._fields[0];
51 57
 
52 58
       this._rowIndex = 0;
53  
-      row[field] = '';
  59
+      row[field.name] = '';
54 60
 
55 61
       packet.on('data', function(buffer, remaining) {
56 62
         if (buffer) {
57  
-          row[field] += buffer;
  63
+          row[field.name] += buffer;
58 64
         } else {
59  
-          row[field] = null;
  65
+          row[field.name] = null;
60 66
         }
61 67
 
62 68
         if (remaining == 0) {
63 69
           self._rowIndex++;
  70
+          if (self.typeCast) {
  71
+            switch (field.fieldType) {
  72
+              case Query.FIELD_TYPE_TIMESTAMP:
  73
+              case Query.FIELD_TYPE_DATE:
  74
+              case Query.FIELD_TYPE_DATETIME:
  75
+              case Query.FIELD_TYPE_NEWDATE:
  76
+                row[field.name] = new Date(row[field.name]+'Z');
  77
+                break;
  78
+              case Query.FIELD_TYPE_TINY:
  79
+              case Query.FIELD_TYPE_SHORT:
  80
+              case Query.FIELD_TYPE_LONG:
  81
+              case Query.FIELD_TYPE_LONGLONG:
  82
+              case Query.FIELD_TYPE_INT24:
  83
+              case Query.FIELD_TYPE_YEAR:
  84
+                row[field.name] = parseInt(row[field.name], 10);
  85
+                break;
  86
+              case Query.FIELD_TYPE_DECIMAL:
  87
+              case Query.FIELD_TYPE_FLOAT:
  88
+              case Query.FIELD_TYPE_DOUBLE:
  89
+              case Query.FIELD_TYPE_NEWDECIMAL:
  90
+                row[field.name] = parseFloat(row[field.name]);
  91
+                break;
  92
+            }
  93
+          }
  94
+
64 95
           if (self._rowIndex == self._fields.length) {
65 96
              delete self._row;
66 97
              delete self._rowIndex;
@@ -69,9 +100,37 @@ Query.prototype._handlePacket = function(packet) {
69 100
           }
70 101
 
71 102
           field = self._fields[self._rowIndex];
72  
-          row[field] = '';
  103
+          row[field.name] = '';
73 104
         }
74 105
       });
75 106
       break;
76 107
   }
77 108
 };
  109
+
  110
+Query.FIELD_TYPE_DECIMAL     = 0x00;
  111
+Query.FIELD_TYPE_TINY        = 0x01;
  112
+Query.FIELD_TYPE_SHORT       = 0x02;
  113
+Query.FIELD_TYPE_LONG        = 0x03;
  114
+Query.FIELD_TYPE_FLOAT       = 0x04;
  115
+Query.FIELD_TYPE_DOUBLE      = 0x05;
  116
+Query.FIELD_TYPE_NULL        = 0x06;
  117
+Query.FIELD_TYPE_TIMESTAMP   = 0x07;
  118
+Query.FIELD_TYPE_LONGLONG    = 0x08;
  119
+Query.FIELD_TYPE_INT24       = 0x09;
  120
+Query.FIELD_TYPE_DATE        = 0x0a;
  121
+Query.FIELD_TYPE_TIME        = 0x0b;
  122
+Query.FIELD_TYPE_DATETIME    = 0x0c;
  123
+Query.FIELD_TYPE_YEAR        = 0x0d;
  124
+Query.FIELD_TYPE_NEWDATE     = 0x0e;
  125
+Query.FIELD_TYPE_VARCHAR     = 0x0f;
  126
+Query.FIELD_TYPE_BIT         = 0x10;
  127
+Query.FIELD_TYPE_NEWDECIMAL  = 0xf6;
  128
+Query.FIELD_TYPE_ENUM        = 0xf7;
  129
+Query.FIELD_TYPE_SET         = 0xf8;
  130
+Query.FIELD_TYPE_TINY_BLOB   = 0xf9;
  131
+Query.FIELD_TYPE_MEDIUM_BLOB = 0xfa;
  132
+Query.FIELD_TYPE_LONG_BLOB   = 0xfb;
  133
+Query.FIELD_TYPE_BLOB        = 0xfc;
  134
+Query.FIELD_TYPE_VAR_STRING  = 0xfd;
  135
+Query.FIELD_TYPE_STRING      = 0xfe;
  136
+Query.FIELD_TYPE_GEOMETRY    = 0xff;
2  package.json
... ...
@@ -1,5 +1,5 @@
1 1
 { "name" : "mysql"
2  
-, "version": "0.5.0"
  2
+, "version": "0.6.0"
3 3
 , "dependencies": {"gently": ">=0.8.0"}
4 4
 , "main" : "./lib/mysql"
5 5
 }
15  test/simple/test-client.js
@@ -7,7 +7,7 @@ var StreamStub = GENTLY.stub('net', 'Stream'),
7 7
 
8 8
 for (var k in Parser) {
9 9
   ParserStub[k] = Parser[k];
10  
-}
  10
+};
11 11
 
12 12
 var Client = require('mysql/client');
13 13
 
@@ -16,7 +16,7 @@ function test(test) {
16 16
   gently = new Gently();
17 17
   test();
18 18
   gently.verify(test.name);
19  
-}
  19
+};
20 20
 
21 21
 test(function constructor() {
22 22
   (function testDefaultProperties() {
@@ -28,11 +28,12 @@ test(function constructor() {
28 28
       assert.strictEqual(client.password, null);
29 29
       assert.strictEqual(client.database, '');
30 30
 
  31
+      assert.strictEqual(client.typeCast, true);
31 32
       assert.strictEqual(client.debug, false);
32 33
 
33 34
       assert.strictEqual(client.flags, Client.defaultFlags);
34 35
       assert.strictEqual(client.maxPacketSize, 0x01000000);
35  
-      assert.strictEqual(client.charsetNumber, 8);
  36
+      assert.strictEqual(client.charsetNumber, Client.UTF8_UNICODE_CI);
36 37
 
37 38
       assert.strictEqual(client._greeting, null);
38 39
       assert.deepEqual(client._queue, []);
@@ -139,6 +140,8 @@ test(function query() {
139 140
       QUERY,
140 141
       queryEmit = {};
141 142
 
  143
+  client.typeCast = 'super';
  144
+
142 145
   (function testRegular() {
143 146
     gently.expect(client, 'format', function(sql, params) {
144 147
       assert.strictEqual(sql, SQL);
@@ -146,9 +149,11 @@ test(function query() {
146 149
       return FORMATED_SQL;
147 150
     });
148 151
 
149  
-    gently.expect(QueryStub, 'new', function() {
  152
+    gently.expect(QueryStub, 'new', function(properties) {
150 153
       QUERY = this;
151 154
 
  155
+      assert.equal(properties.typeCast, client.typeCast);
  156
+
152 157
       var events = ['error', 'field', 'row', 'end'];
153 158
       gently.expect(QUERY, 'on', events.length, function (event, fn) {
154 159
         assert.equal(event, events.shift());
@@ -524,7 +529,7 @@ test(function _packetToUserObject() {
524 529
       length: 65,
525 530
       received: 65,
526 531
       number: 92,
527  
-      foo: 'bar',
  532
+      foo: 'bar'
528 533
     };
529 534
 
530 535
     var ok = Client._packetToUserObject(PACKET);
46  test/simple/test-query.js
@@ -15,6 +15,8 @@ function test(test) {
15 15
 
16 16
 test(function constructor() {
17 17
   assert.ok(query instanceof EventEmitter);
  18
+  assert.strictEqual(query.typeCast, true);
  19
+  assert.equal(new Query({foo: 'bar'}).foo, 'bar');
18 20
 });
19 21
 
20 22
 test(function _handlePacket() {
@@ -60,7 +62,7 @@ test(function _handlePacket() {
60 62
 
61 63
     query._handlePacket(PACKET);
62 64
 
63  
-    assert.deepEqual(query._fields, [PACKET.name]);
  65
+    assert.strictEqual(query._fields[0], PACKET);
64 66
   })();
65 67
 
66 68
   (function testEofPacket() {
@@ -78,7 +80,7 @@ test(function _handlePacket() {
78 80
   })();
79 81
 
80 82
   (function testRowPacket() {
81  
-    query._fields = ['a', 'b'];
  83
+    query._fields = [{name: 'a', fieldType: -1}, {name: 'b', fieldType: -1}];
82 84
 
83 85
     var PACKET = new EventEmitter();
84 86
     PACKET.type = Parser.ROW_DATA_PACKET;
@@ -100,4 +102,44 @@ test(function _handlePacket() {
100 102
 
101 103
     query._handlePacket(PACKET);
102 104
   })();
  105
+
  106
+  function typeCast(type, strValue) {
  107
+    query._fields = [{name: 'my_field', fieldType: type}];
  108
+
  109
+    var PACKET = new EventEmitter(), r;
  110
+    PACKET.type = Parser.ROW_DATA_PACKET;
  111
+
  112
+    gently.expect(PACKET, 'on', function (event, fn) {
  113
+      assert.equal(event, 'data');
  114
+
  115
+      gently.expect(query, 'emit', function (event, row) {
  116
+        assert.equal(event, 'row');
  117
+        r = row.my_field;
  118
+      });
  119
+
  120
+      fn(new Buffer(strValue), 0);
  121
+    });
  122
+
  123
+    query._handlePacket(PACKET);
  124
+    return r;
  125
+  }
  126
+
  127
+  assert.deepEqual(typeCast(Query.FIELD_TYPE_TIMESTAMP, '2010-10-05 06:23:42'), new Date('2010-10-05 06:23:42Z'));
  128
+
  129
+  assert.deepEqual(typeCast(Query.FIELD_TYPE_TIMESTAMP, '2010-10-05'), new Date('2010-10-05Z'));
  130
+  assert.deepEqual(typeCast(Query.FIELD_TYPE_DATE, '2010-10-05'), new Date('2010-10-05Z'));
  131
+  assert.deepEqual(typeCast(Query.FIELD_TYPE_DATETIME, '2010-10-05'), new Date('2010-10-05Z'));
  132
+  assert.deepEqual(typeCast(Query.FIELD_TYPE_NEWDATE, '2010-10-05'), new Date('2010-10-05Z'));
  133
+
  134
+  assert.strictEqual(typeCast(Query.FIELD_TYPE_TINY, '08'), 8);
  135
+  assert.strictEqual(typeCast(Query.FIELD_TYPE_SHORT, '08'), 8);
  136
+  assert.strictEqual(typeCast(Query.FIELD_TYPE_LONG, '08'), 8);
  137
+  assert.strictEqual(typeCast(Query.FIELD_TYPE_LONGLONG, '08'), 8);
  138
+  assert.strictEqual(typeCast(Query.FIELD_TYPE_INT24, '08'), 8);
  139
+  assert.strictEqual(typeCast(Query.FIELD_TYPE_YEAR, '08'), 8);
  140
+
  141
+  assert.strictEqual(typeCast(Query.FIELD_TYPE_DECIMAL, '2.8'), 2.8);
  142
+  assert.strictEqual(typeCast(Query.FIELD_TYPE_FLOAT, '2.8'), 2.8);
  143
+  assert.strictEqual(typeCast(Query.FIELD_TYPE_DOUBLE, '2.8'), 2.8);
  144
+  assert.strictEqual(typeCast(Query.FIELD_TYPE_NEWDECIMAL, '2.8'), 2.8);
103 145
 });
4  test/system/test-client-query-column-order.js → test/system/slow/test-client-query-column-order.js
... ...
@@ -1,5 +1,5 @@
1  
-require('../common');
2  
-var REPEATS = 1000,
  1
+require('../../common');
  2
+var REPEATS = 500,
3 3
     Client = require('mysql').Client,
4 4
     client = Client(TEST_CONFIG),
5 5
     fs = require('fs'),
2  test/system/test-client-query.js
@@ -62,6 +62,8 @@ var query = client.query(
62 62
 
63 63
     assert.equal(results.length, 2);
64 64
     assert.equal(results[1].title, 'another entry');
  65
+    assert.ok(typeof results[1].id == 'number');
  66
+    assert.ok(results[1].created instanceof Date);
65 67
     client.end();
66 68
   })
67 69
 );

Showing you all comments on commits in this comparison.

Bert Belder

Is there a specific reason why BLOB's aren't cast into buffers?

Brian White

My original patch contained support for casting blobs to buffers. Maybe there is a plan for implementing it differently? I dunno.

Felix Geisendörfer
Owner

Yeah, I didn't do that part yet because it is hard to do efficiently. I need to talk to ryan to see if we can do better than that, but otherwise yes - this is coming back in. If any of you guys needs it right now, ping me and I'll put the naive implementation back in.

Something went wrong with that request. Please try again.