Permalink
Browse files

#76 #126 - Results (rows and column metadata) are now simple arrays

Optionaly key-value collections (useColumnNames)
  • Loading branch information...
1 parent e864ec7 commit 5e51de9ae115e13aaa4591917c960edb2454003b @patriksimek patriksimek committed Mar 31, 2014
View
@@ -24,7 +24,8 @@ Current version: 0.1.5
- Added option to choose whether to pass/receive times in UTC or local time (`useUTC`)
- Binary, VarBinary and Image are now supported as input parameters
- Binary, VarBinary and Image types are now returned as Buffer (was Array)
-- Connection errors are now correctly propagated to `connect` event.
+- Connection errors are now correctly propagated to `connect` event
+- Better support for numeric column names and columns with same name
- Errors are now instanceof Error / ConnectionError / RequestError (was plain text)
- Transaction isolationLevel default is now `READ_COMMITED` (was `READ_UNCOMMITED`)
- Fixed issue when zero value was casted as null when using BigInt as input parameter
@@ -38,6 +39,7 @@ Current version: 0.1.5
- There was a change in default transaction isolationLevel from `READ_UNCOMMITED` to `READ_COMMITED`. You can disable this by `options.isolationLevel = require('tedious').ISOLATION_LEVEL.READ_UNCOMMITTED`.
- Binary values are now returned in Buffers.
- All error values are no longer strings, but instances of Error.
+- Results (rows and column metadata) are now simple arrays. You can change this to key-value collections by `options.useColumnNames = true`.
<a name="documentation" />
## Documentation
View
@@ -201,6 +201,7 @@ class Connection extends EventEmitter
@config.options.encrypt ||= false
@config.options.cryptoCredentialsDetails ||= {}
@config.options.useUTC ?= true
+ @config.options.useColumnNames ?= false
if !@config.options.port && !@config.options.instanceName
@config.options.port = DEFAULT_PORT
@@ -269,7 +270,13 @@ class Connection extends EventEmitter
)
@tokenStreamParser.on('columnMetadata', (token) =>
if @request
- @request.emit('columnMetadata', token.columns)
+ if @config.options.useColumnNames
+ columns = {}
+ columns[col.colName] = col for col in token.columns when not columns[col.colName]?
+ else
+ columns = token.columns
+
+ @request.emit('columnMetadata', columns)
else
@emit 'error', new Error "Received 'columnMetadata' when no sqlRequest is in progress"
@close()
@@ -2,8 +2,6 @@
metadataParse = require('../metadata-parser')
-DIGITS_REGEX = /^\d+$/
-
parser = (buffer, colMetadata, options) ->
columnCount = buffer.readUInt16LE()
@@ -37,9 +35,6 @@ parser = (buffer, colMetadata, options) ->
columns.push(column)
- if !(DIGITS_REGEX.test(column.colName))
- columns[column.colName] = column
-
# Return token
name: 'COLMETADATA'
event: 'columnMetadata'
@@ -3,8 +3,6 @@
valueParse = require('../value-parser')
sprintf = require('sprintf').sprintf
-DIGITS_REGEX = /^\d+$/
-
parser = (buffer, columnsMetaData, options) ->
length = Math.ceil columnsMetaData.length / 8
bytes = buffer.readBuffer length
@@ -14,7 +12,7 @@ parser = (buffer, columnsMetaData, options) ->
for i in [0..7]
bitmap.push if byte & (1 << i) then true else false
- columns = []
+ columns = if options.useColumnNames then {} else []
for columnMetaData, index in columnsMetaData
#console.log sprintf('Token @ 0x%02X', buffer.position)
@@ -27,23 +25,15 @@ parser = (buffer, columnsMetaData, options) ->
value: value
metadata: columnMetaData
- columns.push(column)
-
- if !(DIGITS_REGEX.test(columnMetaData.colName))
- saveColumn(columnMetaData.colName, columns, column)
+ if options.useColumnNames
+ unless columns[columnMetaData.colName]?
+ columns[columnMetaData.colName] = column
+ else
+ columns.push(column)
# Return token
name: 'NBCROW'
event: 'row'
columns: columns
-saveColumn = (columnName, columns, value) ->
- entry = columns[columnName]
- if !entry
- columns[columnName] = value;
- else if Array.isArray(entry)
- entry.push(value)
- else
- columns[columnName] = [entry, value]
-
module.exports = parser
@@ -3,10 +3,8 @@
valueParse = require('../value-parser')
sprintf = require('sprintf').sprintf
-DIGITS_REGEX = /^\d+$/
-
parser = (buffer, columnsMetaData, options) ->
- columns = []
+ columns = if options.useColumnNames then {} else []
for columnMetaData in columnsMetaData
#console.log sprintf('Token @ 0x%02X', buffer.position)
@@ -15,24 +13,16 @@ parser = (buffer, columnsMetaData, options) ->
column =
value: value
metadata: columnMetaData
-
- columns.push(column)
-
- if !(DIGITS_REGEX.test(columnMetaData.colName))
- saveColumn(columnMetaData.colName, columns, column)
+
+ if options.useColumnNames
+ unless columns[columnMetaData.colName]?
+ columns[columnMetaData.colName] = column
+ else
+ columns.push(column)
# Return token
name: 'ROW'
event: 'row'
columns: columns
-saveColumn = (columnName, columns, value) ->
- entry = columns[columnName]
- if !entry
- columns[columnName] = value;
- else if Array.isArray(entry)
- entry.push(value)
- else
- columns[columnName] = [entry, value]
-
module.exports = parser
@@ -184,7 +184,7 @@ exports.encrypt = (test) ->
)
exports.execSql = (test) ->
- test.expect(8)
+ test.expect(7)
config = getConfig()
@@ -207,7 +207,6 @@ exports.execSql = (test) ->
request.on('row', (columns) ->
test.strictEqual(columns.length, 1)
test.strictEqual(columns[0].value, 8)
- test.strictEqual(columns.C1.value, 8)
)
connection = new Connection(config)
@@ -232,6 +231,7 @@ exports.numericColumnName = (test) ->
test.expect(5)
config = getConfig()
+ config.options.useColumnNames = true
request = new Request('select 8 as [123]', (err, rowCount) ->
test.ok(!err)
@@ -241,12 +241,12 @@ exports.numericColumnName = (test) ->
)
request.on('columnMetadata', (columnsMetadata) ->
- test.strictEqual(columnsMetadata.length, 1)
+ test.strictEqual(Object.keys(columnsMetadata).length, 1)
)
request.on('row', (columns) ->
- test.strictEqual(columns.length, 1)
- test.strictEqual(columns[0].value, 8)
+ test.strictEqual(Object.keys(columns).length, 1)
+ test.strictEqual(columns[123].value, 8)
)
connection = new Connection(config)
@@ -268,30 +268,26 @@ exports.numericColumnName = (test) ->
)
exports.duplicateColumnNames = (test) ->
- test.expect(10)
+ test.expect(6)
config = getConfig()
+ config.options.useColumnNames = true
- request = new Request('select 1 as abc, 2 as xyz, 3 as abc', (err, rowCount) ->
+ request = new Request('select 1 as abc, 2 as xyz, \'3\' as abc', (err, rowCount) ->
test.ok(!err)
test.strictEqual(rowCount, 1)
connection.close()
)
request.on('columnMetadata', (columnsMetadata) ->
- test.strictEqual(columnsMetadata.length, 3)
+ test.strictEqual(Object.keys(columnsMetadata).length, 2)
)
request.on('row', (columns) ->
- test.strictEqual(columns.length, 3)
+ test.strictEqual(Object.keys(columns).length, 2)
- test.strictEqual(columns[0].value, 1)
- test.strictEqual(columns[1].value, 2)
- test.strictEqual(columns[2].value, 3)
-
- test.strictEqual(columns.abc[0].value, 1)
- test.strictEqual(columns.abc[1].value, 3)
+ test.strictEqual(columns.abc.value, 1)
test.strictEqual(columns.xyz.value, 2)
)
@@ -317,7 +313,7 @@ exports.execSqlMultipleTimes = (test) ->
timesToExec = 5
sqlExecCount = 0
- test.expect(timesToExec * 8)
+ test.expect(timesToExec * 7)
config = getConfig()
@@ -346,7 +342,6 @@ exports.execSqlMultipleTimes = (test) ->
request.on('row', (columns) ->
test.strictEqual(columns.length, 1)
test.strictEqual(columns[0].value, 8)
- test.strictEqual(columns.C1.value, 8)
)
connection.execSql(request)
@@ -800,7 +795,7 @@ exports.cancelRequest = (test) ->
request.on('row', (columns) ->
test.strictEqual(columns.length, 1)
- test.strictEqual(columns.C1.value, 1)
+ test.strictEqual(columns[0].value, 1)
)
connection = new Connection(config)
@@ -27,7 +27,6 @@ module.exports.int = (test) ->
test.strictEqual(token.columns[0].flags, 3)
test.strictEqual(token.columns[0].type.name, 'Int')
test.strictEqual(token.columns[0].colName, 'name')
- test.strictEqual(token.columns.name.colName, 'name')
test.done()
@@ -64,7 +63,6 @@ module.exports.varchar = (test) ->
test.strictEqual(token.columns[0].collation.version, 0x8)
test.strictEqual(token.columns[0].collation.sortId, 0x9a)
test.strictEqual(token.columns[0].colName, 'name')
- test.strictEqual(token.columns.name.colName, 'name')
test.strictEqual(token.columns[0].dataLength, length)
test.done()

0 comments on commit 5e51de9

Please sign in to comment.