Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Use iconv-lite instead of iconv.

The iconv package is not supported on Windows. This meant that it was included as an
optional dependency, and codepages were not properly supported on Windows.
The iconv package also caused confusion with Windows users, as the installation error
messages looked alarming despite npm recovering the installation.

Using iconv lite takes tedious back to being pure Javascript for itself and its
dependencies.
  • Loading branch information...
commit a2e2a885ff125721d337721dc6a8d9bd66d6b14a 1 parent b5f5b95
@pekim authored
View
4 package.json
@@ -24,11 +24,9 @@
"node": "0.6 || 0.7"
},
"dependencies": {
+ "iconv-lite": "0.2.0",
"sprintf": "0.1.1"
},
- "optionalDependencies": {
- "iconv": "1.1.3"
- },
"devDependencies": {
"coffee-script": "1.3.1",
"nodeunit": "0.7.4"
View
12 src/collation.coffee
@@ -1,8 +1,3 @@
-try
- Iconv = require('iconv').Iconv
-catch exception
- Iconv = undefined
-
exports.codepageByLcid =
1025: 'WINDOWS-1256'
1029: 'WINDOWS-1250'
@@ -35,10 +30,3 @@ exports.codepageByLcid =
66574: 'WINDOWS-1250'
66615: 'WINDOWS-1252'
133124: 'WINDOWS-936'
-
-exports.iconvByLcid = {}
-for lcid, codepage of exports.codepageByLcid
- if Iconv
- exports.iconvByLcid[lcid] = new Iconv(codepage, 'UTF-8')
- else
- exports.iconvByLcid[lcid] = undefined
View
4 src/metadata-parser.coffee
@@ -1,5 +1,4 @@
codepageByLcid = require('./collation').codepageByLcid
-iconvByLcid = require('./collation').iconvByLcid
TYPE = require('./data-type').TYPE
sprintf = require('sprintf').sprintf
@@ -48,9 +47,8 @@ parse = (buffer) ->
collation.lcid = (collationData[2] & 0x0F) << 16
collation.lcid |= collationData[1] << 8
collation.lcid |= collationData[0]
-
+
collation.codepage = codepageByLcid[collation.lcid]
- collation.iconv = iconvByLcid[collation.lcid]
# This may not be extracting the correct nibbles in the correct order.
collation.flags = collationData[3] >> 4
View
63 src/value-parser.coffee
@@ -1,3 +1,4 @@
+iconv = require('iconv-lite')
sprintf = require('sprintf').sprintf
require('./buffertools')
@@ -106,25 +107,17 @@ parse = (buffer, metaData) ->
value = null
when 1
value = !!buffer.readUInt8()
- when 'VarChar', 'Char', 'NVarChar', 'NChar'
- switch type.name
- when 'VarChar', 'Char'
- iconv = metaData.collation.iconv
- encoding = 'ascii'
- when 'NVarChar', 'NChar'
- iconv = undefined
- encoding = 'ucs2'
-
+ when 'VarChar', 'Char'
+ codepage = metaData.collation.codepage
if metaData.dataLength == MAX
- if iconv
- value = readMaxChars(buffer, iconv)
- else
- value = readMaxChars(buffer, encoding)
+ value = readMaxChars(buffer, codepage)
else
- if iconv
- value = readChars(buffer, dataLength, iconv)
- else
- value = readChars(buffer, dataLength, encoding)
+ value = readChars(buffer, dataLength, codepage)
+ when 'NVarChar', 'NChar'
+ if metaData.dataLength == MAX
+ value = readMaxNChars(buffer)
+ else
+ value = readNChars(buffer, dataLength)
when 'VarBinary', 'Binary'
if metaData.dataLength == MAX
value = readMaxBinary(buffer)
@@ -134,15 +127,12 @@ parse = (buffer, metaData) ->
if dataLength == 0
value = null
else
- if metaData.collation.iconv
- value = readChars(buffer, dataLength, metaData.collation.iconv)
- else
- value = readChars(buffer, dataLength, 'ascii')
+ value = readChars(buffer, dataLength, metaData.collation.codepage)
when 'NText'
if dataLength == 0
value = null
else
- value = readChars(buffer, dataLength, 'ucs2')
+ value = readNChars(buffer, dataLength)
when 'Image'
if dataLength == 0
value = null
@@ -201,30 +191,31 @@ readBinary = (buffer, dataLength) ->
else
buffer.readArray(dataLength)
-readChars = (buffer, dataLength, encodingOrIconv) ->
+readChars = (buffer, dataLength, codepage) ->
if dataLength == NULL
null
else
- if typeof encodingOrIconv == 'string'
- encoding = encodingOrIconv
- buffer.readString(dataLength, encoding)
- else
- iconv = encodingOrIconv
- iconv.convert(buffer.readBuffer(dataLength)).toString()
+ iconv.decode(buffer.readBuffer(dataLength), codepage)
+
+readNChars = (buffer, dataLength) ->
+ if dataLength == NULL
+ null
+ else
+ buffer.readString(dataLength, 'ucs2')
readMaxBinary = (buffer) ->
readMax(buffer, (valueBuffer) ->
Array.prototype.slice.call(valueBuffer)
)
-readMaxChars = (buffer, encodingOrIconv) ->
+readMaxChars = (buffer, codepage) ->
readMax(buffer, (valueBuffer) ->
- if typeof encodingOrIconv == 'string'
- encoding = encodingOrIconv
- valueBuffer.toString(encoding)
- else
- iconv = encodingOrIconv
- iconv.convert(valueBuffer).toString()
+ iconv.decode(valueBuffer, codepage)
+ )
+
+readMaxNChars = (buffer) ->
+ readMax(buffer, (valueBuffer) ->
+ valueBuffer.toString('ucs2')
)
readMax = (buffer, decodeFunction) ->
View
11 test/integration/datatypes-in-results-test.coffee
@@ -117,11 +117,20 @@ exports.moneyNull = (test) ->
execSql(test, "select cast(null as money)", null)
exports.varchar = (test) ->
- execSql(test, "select cast('abcdé' as varchar(10))", 'abcdé')
+ execSql(test, "select cast('abcde' as varchar(10))", 'abcde')
exports.varcharNull = (test) ->
execSql(test, "select cast(null as varchar(10))", null)
+exports.varcharCollation = (test) ->
+ # The codepage used is WINDOWS-1251.
+ sql = """
+ create table #tab1 (col1 nvarchar(10) collate Cyrillic_General_CS_AS);
+ insert into #tab1 values(N'abcdШ');
+ select cast(col1 as varchar(10)) from #tab1
+ """
+ execSql(test, sql, 'abcdШ')
+
exports.varcharMax = (test) ->
execSql(test, "select cast('abc' as varchar(max))", 'abc')
View
13 test/unit/token/row-token-parser-test.coffee
@@ -1,6 +1,5 @@
parser = require('../../../src/token/row-token-parser')
dataTypeByName = require('../../../src/data-type').typeByName
-Iconv = require('iconv').Iconv
ReadableTrackingBuffer = require('../../../src/tracking-buffer/tracking-buffer').ReadableTrackingBuffer
WritableTrackingBuffer = require('../../../src/tracking-buffer/tracking-buffer').WritableTrackingBuffer
@@ -120,7 +119,7 @@ module.exports.varCharWithoutCodepage = (test) ->
colMetaData = [
type: dataTypeByName.VarChar
collation:
- iconv: undefined
+ codepage: undefined
]
value = 'abcde'
@@ -141,7 +140,7 @@ module.exports.varCharWithCodepage = (test) ->
colMetaData = [
type: dataTypeByName.VarChar
collation:
- iconv: new Iconv('WINDOWS-1252', 'UTF-8')
+ codepage: 'WINDOWS-1252'
]
value = 'abcdé'
@@ -217,7 +216,7 @@ module.exports.varCharMaxNull = (test) ->
type: dataTypeByName.VarChar
dataLength: 65535
collation:
- iconv: undefined
+ codepage: undefined
]
buffer = new WritableTrackingBuffer(0, 'ascii')
@@ -238,7 +237,7 @@ module.exports.varCharMaxUnknownLength = (test) ->
type: dataTypeByName.VarChar
dataLength: 65535
collation:
- iconv: undefined
+ codepage: undefined
]
value = 'abcdef'
@@ -265,7 +264,7 @@ module.exports.varCharMaxKnownLength = (test) ->
type: dataTypeByName.VarChar
dataLength: 65535
collation:
- iconv: undefined
+ codepage: undefined
]
value = 'abcdef'
@@ -292,7 +291,7 @@ module.exports.varCharMaxWithCodepage = (test) ->
type: dataTypeByName.VarChar
dataLength: 65535
collation:
- iconv: new Iconv('WINDOWS-1252', 'UTF-8')
+ codepage: 'WINDOWS-1252'
]
value = 'abcdéf'
Please sign in to comment.
Something went wrong with that request. Please try again.