This repository has been archived by the owner on May 5, 2023. It is now read-only.
Adding connection string parser. #376
Merged
Merged
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
a4611eb
Starting to add node CLI tests.
803e19b
Adding connection string parser.
30caaf2
Handling quotes.
70694cf
Adding comments.
a29a7cc
Implementing service bus connection strings.
5333cb6
Fixing undeclared variable.
c2facd9
Simplifying condition.
e9eaa4a
Add support for acs namespace.
dc0068c
Implementing storage connection strings.
da0a165
Adding tableservice tests for connection strings.
04c35e1
Adding more UT.
8c801bc
Updating connection string parser.
c43a810
Updating parser.
5fe2085
Applying code review.
0926b81
Adding more UT.
32cf01f
Merge pull request #3 from andrerod/connect
aa3923a
Improving error message testing.
cc96782
Merge branch 'connectionStrings' of https://github.com/andrerod/azure…
f4a5d70
Merge branch 'dev' into storageconnect
fa460df
Merge branch 'connectionStrings' into storageconnect
d36aa97
Removing CLI tests.
2fc4404
Updating error messages.
0967bcc
Starting service management connection strings.
07a61c3
Adding protocol check.
1ecbcf5
Applying review comments.
2fba11f
Merge pull request #5 from andrerod/storageconnect
8b2ae41
Uncomment UT.
File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,217 @@ | |||
/** | |||
* Copyright (c) Microsoft. All rights reserved. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
* you may not use this file except in compliance with the License. | |||
* You may obtain a copy of the License at | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
*/ | |||
|
|||
var util = require('../../util/util'); | |||
|
|||
// Expose 'ConnectionStringParser'. | |||
exports = module.exports; | |||
|
|||
/** | |||
* Creates a new 'ConnectionString' instance. | |||
* | |||
* @constructor | |||
* @param {string} connectionString The connection string to be parsed. | |||
*/ | |||
function ConnectionStringParser(connectionString) { | |||
this._value = connectionString; | |||
this._pos = 0; | |||
this._state = 'ExpectKey'; | |||
} | |||
|
|||
/** | |||
* Parses a connection string into an object. | |||
* | |||
* @return {object} The query string object. | |||
*/ | |||
ConnectionStringParser.prototype._parse = function () { | |||
var key = null; | |||
var value = null; | |||
var parsedConnectionString = { }; | |||
|
|||
for (; ;) { | |||
this._skipWhitespaces(); | |||
|
|||
if (this._pos === this._value.length && this._state !== 'ExpectValue') | |||
{ | |||
// Not stopping after the end has been reached and a value is expected | |||
// results in creating an empty value, which we expect. | |||
break; | |||
} | |||
|
|||
switch (this._state) { | |||
case 'ExpectKey': | |||
key = this._extractKey(); | |||
this._state = 'ExpectAssignment'; | |||
break; | |||
|
|||
case 'ExpectAssignment': | |||
this._skipOperator('='); | |||
this._state = 'ExpectValue'; | |||
break; | |||
|
|||
case 'ExpectValue': | |||
value = this._extractValue(); | |||
this._state = 'ExpectSeparator'; | |||
parsedConnectionString[key.toLowerCase()] = value; | |||
key = null; | |||
value = null; | |||
break; | |||
|
|||
default: | |||
this._skipOperator(';'); | |||
this._state = 'ExpectKey'; | |||
break; | |||
} | |||
} | |||
|
|||
if (this._state === 'ExpectAssignment') { | |||
// Must end parsing in the valid state (expected key or separator) | |||
throw new Error('Missing character "="'); | |||
} | |||
|
|||
return parsedConnectionString; | |||
}; | |||
|
|||
|
|||
/** | |||
* Skips whitespaces at the current position. | |||
*/ | |||
ConnectionStringParser.prototype._skipWhitespaces = function () { | |||
while (this._pos < this._value.length && this._value[this._pos] === ' ') | |||
{ | |||
this._pos++; | |||
} | |||
}; | |||
|
|||
/** | |||
* Extracts key at the current position. | |||
* | |||
* @return {string} Key. | |||
*/ | |||
ConnectionStringParser.prototype._extractKey = function () { | |||
var key = null; | |||
var firstPos = this._pos; | |||
var ch = this._value[this._pos++]; | |||
|
|||
if (ch === '"' || ch === '\'') { | |||
key = this._extractString(ch); | |||
} else if (ch === ';' || ch === '=') { | |||
// Key name was expected. | |||
throw new Error('Missing key'); | |||
} else { | |||
while (this._pos < this._value.length) { | |||
ch = this._value[this._pos]; | |||
if (ch === '=') { | |||
break; | |||
} | |||
this._pos++; | |||
} | |||
|
|||
key = this._value.substring(firstPos, this._pos); | |||
} | |||
|
|||
if (key.length === 0) { | |||
// Empty key name. | |||
throw new Error('Empty key name'); | |||
} | |||
|
|||
return key; | |||
}; | |||
|
|||
/** | |||
* Extracts the string until the given quotation mark. | |||
* | |||
* @param {string} quote Quotation mark terminating the string. | |||
* @return {string} string. | |||
*/ | |||
ConnectionStringParser.prototype._extractString = function (quote) { | |||
var firstPos = this._pos; | |||
while (this._pos < this._value.length && this._value[this._pos] !== quote) | |||
{ | |||
this._pos++; | |||
} | |||
|
|||
if (this._pos === this._value.length) { | |||
// Runaway string. | |||
throw new Error('Unterminated string starting at position ' + firstPos); | |||
} | |||
|
|||
return this._value.substring(firstPos, this._pos++); | |||
}; | |||
|
|||
/** | |||
* Skips specified operator. | |||
* | |||
* @param {string} operatorChar The oeprator to skip. | |||
*/ | |||
ConnectionStringParser.prototype._skipOperator = function (operatorChar) { | |||
if (this._value[this._pos] != operatorChar) { | |||
// Character was expected. | |||
throw new Error('expecting ' + operatorChar + ' but instead got ' + currentChar + ' at position ' + this._pos); | |||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's no currentChar variable - you should probably define one, or replace with the full expression. |
|||
} | |||
|
|||
this._pos++; | |||
}; | |||
|
|||
/** | |||
* Extracts key's value. | |||
* | |||
* @return {string} The key value. | |||
*/ | |||
ConnectionStringParser.prototype._extractValue = function () { | |||
var value = ''; | |||
|
|||
if (this._pos < this._value.length) { | |||
var ch = this._value[this._pos]; | |||
|
|||
if (ch === '\'' || ch === '"') { | |||
this._pos++; | |||
value = this._extractString(ch); | |||
} else { | |||
var firstPos = this._pos; | |||
var isFound = false; | |||
|
|||
while (this._pos < this._value.length && !isFound) { | |||
ch = this._value[this._pos]; | |||
|
|||
switch (ch) { | |||
case ';': | |||
isFound = true; | |||
break; | |||
|
|||
|
|||
default: | |||
this._pos++; | |||
break; | |||
} | |||
} | |||
|
|||
value = this._value.substring(firstPos, this._pos); | |||
} | |||
} | |||
|
|||
return value; | |||
}; | |||
|
|||
/** | |||
* Parses a connection string. | |||
* | |||
* @param {number} connectionString The connection string to be parsed. | |||
* @return {object} The query string object. | |||
*/ | |||
exports.parse = function (connectionString) { | |||
var connectionStringParser = new ConnectionStringParser(connectionString); | |||
return connectionStringParser._parse(); | |||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a way to escape quotes within a quoted string? If so then this needs to be a little more complex to handle that case. If not, you're good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
http://www.connectionstrings.com/articles/show/important-rules-for-connection-strings
"No escape sequences are supported"