Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #22 from andrerod/sql

SQL Server Database
  • Loading branch information...
commit cce47743d99179ff158c4764a6ac3ecb2a471368 2 parents 799cf06 + 2ced2e8
@andrerod andrerod authored
View
33 lib/azure.js
@@ -98,6 +98,27 @@ exports.createServiceBusService = function (namespaceOrConnectionString, accessK
};
/**
+* SqlService client exports.
+*/
+
+var SqlService = require('./services/sqlAzure/sqlservice');
+exports.SqlService = SqlService;
+
+/**
+* Creates a new SqlManagementService object.
+*
+* @param {string} serverName The SQL server name.
+* @param {string} administratorLogin The SQL Server administrator login.
+* @param {string} administratorLoginPassword The SQL Server administrator login password.
+* @param {string} [host] The host for the service.
+* @param {string} [acsHost] The acs host.
+* @param {object} [authenticationProvider] The authentication provider.
+*/
+exports.createSqlService = function(serverName, administratorLogin, administratorLoginPassword, host, acsHost, authenticationProvider) {
+ return new SqlService(serverName, administratorLogin, administratorLoginPassword, host, acsHost, authenticationProvider);
+};
+
+/**
* ServiceManagement client exports.
*/
@@ -127,14 +148,14 @@ exports.createServiceManagementService = function(subscriptionId, authentication
};
/**
-* SqlDatabaseService client exports.
+* SqlManagementService client exports.
*/
-var SqlDatabaseService = require('./services/serviceManagement/sqldatabaseservice');
-exports.SqlDatabaseService = SqlDatabaseService;
+var SqlManagementService = require('./services/serviceManagement/sqlmanagementservice');
+exports.SqlManagementService = SqlManagementService;
/**
-* Creates a new SqlDatabaseService object.
+* Creates a new SqlManagementService object.
*
* @param {string} subscriptionId The subscription ID for the account.
* @param {string} authentication The authentication object for the client.
@@ -151,8 +172,8 @@ exports.SqlDatabaseService = SqlDatabaseService;
* serializetype: 'XML'
* }
*/
-exports.createSqlDatabaseService = function(subscriptionId, authentication, hostOptions) {
- return new SqlDatabaseService(subscriptionId, authentication, hostOptions);
+exports.createSqlManagementService = function(subscriptionId, authentication, hostOptions) {
+ return new SqlManagementService(subscriptionId, authentication, hostOptions);
};
/**
View
1  lib/services/core/serviceclient.js
@@ -72,6 +72,7 @@ ServiceClient.CLOUD_TABLE_HOST = 'table.core.windows.net';
ServiceClient.CLOUD_SERVICEBUS_HOST = 'servicebus.windows.net';
ServiceClient.CLOUD_ACCESS_CONTROL_HOST = 'accesscontrol.windows.net';
ServiceClient.CLOUD_SERVICE_MANAGEMENT_HOST = 'management.core.windows.net';
+ServiceClient.CLOUD_DATABASE_HOST = 'database.windows.net';
/**
* The default service bus issuer.
View
2  lib/services/core/servicemanagementclient.js
@@ -41,7 +41,7 @@ ServiceManagementClient.DefaultAPIVersion = '2012-03-01';
ServiceManagementClient.DefaultSerializeType = 'JSON';
/**
-* Creates a new ServiceClient object.
+* Creates a new ServiceManagementClient object.
*
* @constructor
* @param {string} hostOptions The host options to override defaults.
View
125 lib/services/core/sqlserviceclient.js
@@ -0,0 +1,125 @@
+/**
+* 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.
+*/
+
+// Module dependencies.
+var util = require('util');
+var url = require('url');
+
+var azureutil = require('../../util/util');
+
+var ServiceClient = require('./serviceclient');
+var SqlServerAcs = require('../sqlAzure/sqlserveracs');
+var Constants = require('../../util/constants');
+var HeaderConstants = Constants.HeaderConstants;
+var QueryStringConstants = Constants.QueryStringConstants;
+var HttpConstants = Constants.HttpConstants;
+
+// Expose 'SqlServiceClient'.
+exports = module.exports = SqlServiceClient;
+
+/**
+* Creates a new SqlServiceClient object.
+*
+* @constructor
+* @param {string} serverName The SQL server name.
+* @param {string} administratorLogin The SQL Server administrator login.
+* @param {string} administratorLoginPassword The SQL Server administrator login password.
+* @param {string} host The host for the service.
+* @param {string} acsHost The acs host. Usually the same as the sb namespace with "-sb" suffix.
+* @param {object} [authenticationProvider] The authentication provider.
+*/
+function SqlServiceClient(serverName, administratorLogin, administratorLoginPassword, host, acsHost, authenticationProvider) {
+ SqlServiceClient.super_.call(this, host, authenticationProvider);
+
+ this.authenticationProvider = authenticationProvider;
+ if (!this.authenticationProvider) {
+ this.authenticationProvider = new SqlServerAcs(acsHost, serverName, administratorLogin, administratorLoginPassword);
+ }
+}
+
+util.inherits(SqlServiceClient, ServiceClient);
+
+/**
+* Builds the request options to be passed to the http.request method.
+*
+* @param {WebResource} webResource The webresource where to build the options from.
+* @param {object} options The request options.
+* @param {function(error, requestOptions)} callback The callback function.
+*/
+SqlServiceClient.prototype._buildRequestOptions = function (webResource, options, callback) {
+ var self = this;
+
+ if (!webResource.headers || !webResource.headers[HeaderConstants.CONTENT_TYPE]) {
+ webResource.addOptionalHeader(HeaderConstants.CONTENT_TYPE, '');
+ }
+
+ if (!webResource.headers || !webResource.headers[HeaderConstants.CONTENT_LENGTH]) {
+ webResource.addOptionalHeader(HeaderConstants.CONTENT_LENGTH, 0);
+ }
+
+ webResource.addOptionalHeader(HeaderConstants.ACCEPT_CHARSET_HEADER, 'UTF-8');
+ webResource.addOptionalHeader(HeaderConstants.HOST_HEADER, this.host + ':' + this.port);
+
+ // Sets the request url in the web resource.
+ this._setRequestUrl(webResource);
+
+ // If wrap is used, make sure proxy settings are in sync
+ if (this.useProxy &&
+ this.authenticationProvider &&
+ this.authenticationProvider.wrapTokenManager &&
+ this.authenticationProvider.wrapTokenManager.wrapService) {
+ this.authenticationProvider.wrapTokenManager.wrapService.setProxy(this.proxyUrl, this.proxyPort);
+ }
+
+ // Now that the web request is finalized, sign it
+ this.authenticationProvider.signRequest(webResource, function (error) {
+ var requestOptions = null;
+
+ if (!error) {
+ requestOptions = {
+ url: url.format({
+ protocol: self._isHttps() ? 'https:' : 'http:',
+ hostname: self.host,
+ port: self.port,
+ pathname: webResource.path + webResource.getQueryString(true)
+ }),
+ method: webResource.httpVerb,
+ headers: webResource.headers
+ };
+
+ self._setRequestOptionsProxy(requestOptions);
+ }
+
+ callback(error, requestOptions);
+ });
+};
+
+/**
+* Retrieves the normalized path to be used in a request.
+* It adds a leading "/" to the path in case
+* it's not there before.
+*
+* @param {string} path The path to be normalized.
+* @return {string} The normalized path.
+*/
+SqlServiceClient.prototype._getPath = function (path) {
+ if (path === null || path === undefined) {
+ path = '/';
+ } else if (path.indexOf('/') !== 0) {
+ path = '/' + path;
+ }
+
+ return path;
+};
View
26 lib/services/serviceBus/models/queueresult.js
@@ -37,19 +37,6 @@ QueueResult.serialize = function (path, queue) {
}
};
- var atomQueue = {
- 'title': '',
- 'updated': ISO8061Date.format(new Date()),
- 'author': {
- name: ''
- },
- 'id': '',
- 'content': {
- '$': { type: 'application/xml' },
- QueueDescription: queueDescription
- }
- };
-
if (queue) {
if (queue[ServiceBusConstants.LOCK_DURATION]) {
queueDescription[ServiceBusConstants.LOCK_DURATION] = queue[ServiceBusConstants.LOCK_DURATION];
@@ -96,6 +83,19 @@ QueueResult.serialize = function (path, queue) {
}
}
+ var atomQueue = {
+ 'title': '',
+ 'updated': ISO8061Date.format(new Date()),
+ 'author': {
+ name: ''
+ },
+ 'id': '',
+ 'content': {
+ '$': { type: 'application/xml' },
+ QueueDescription: queueDescription
+ }
+ };
+
var atomHandler = new AtomHandler(null, null);
var xml = atomHandler.serialize(atomQueue);
View
30 lib/services/serviceBus/models/ruleresult.js
@@ -34,21 +34,6 @@ RuleResult.serialize = function (name, path, rule) {
}
};
- var atomRule = {
- 'title': {
- '$': {
- 'type': 'text'
- },
- '_': name
- },
- 'updated': ISO8061Date.format(new Date()),
- 'id': '',
- 'content': {
- '$': { type: 'application/xml' },
- RuleDescription: ruleDescription
- }
- };
-
if (rule) {
var filters = [];
if (rule.sqlExpressionFilter) {
@@ -122,6 +107,21 @@ RuleResult.serialize = function (name, path, rule) {
}
}
+ var atomRule = {
+ 'title': {
+ '$': {
+ 'type': 'text'
+ },
+ '_': name
+ },
+ 'updated': ISO8061Date.format(new Date()),
+ 'id': '',
+ 'content': {
+ '$': { type: 'application/xml' },
+ RuleDescription: ruleDescription
+ }
+ };
+
var atomHandler = new AtomHandler(null, null);
var xml = atomHandler.serialize(atomRule);
return xml;
View
26 lib/services/serviceBus/models/subscriptionresult.js
@@ -35,19 +35,6 @@ SubscriptionResult.serialize = function (path, subscription) {
}
};
- var atomQueue = {
- 'title': '',
- 'updated': ISO8061Date.format(new Date()),
- 'author': {
- name: ''
- },
- 'id': '',
- 'content': {
- '$': { type: 'application/xml' },
- SubscriptionDescription: subscriptionDescription
- }
- };
-
if (subscription) {
if (subscription[ServiceBusConstants.LOCK_DURATION]) {
subscriptionDescription[ServiceBusConstants.LOCK_DURATION] = subscription[ServiceBusConstants.LOCK_DURATION];
@@ -86,6 +73,19 @@ SubscriptionResult.serialize = function (path, subscription) {
}
}
+ var atomQueue = {
+ 'title': '',
+ 'updated': ISO8061Date.format(new Date()),
+ 'author': {
+ name: ''
+ },
+ 'id': '',
+ 'content': {
+ '$': { type: 'application/xml' },
+ SubscriptionDescription: subscriptionDescription
+ }
+ };
+
var atomHandler = new AtomHandler(null, null);
var xml = atomHandler.serialize(atomQueue);
View
26 lib/services/serviceBus/models/topicresult.js
@@ -35,19 +35,6 @@ TopicResult.serialize = function (path, topic) {
}
};
- var atomQueue = {
- 'title': '',
- 'updated': ISO8061Date.format(new Date()),
- 'author': {
- name: ''
- },
- 'id': '',
- 'content': {
- '$': { type: 'application/xml' },
- TopicDescription: topicDescription
- }
- };
-
if (topic) {
if (topic[ServiceBusConstants.DEFAULT_MESSAGE_TIME_TO_LIVE]) {
topicDescription[ServiceBusConstants.DEFAULT_MESSAGE_TIME_TO_LIVE] = topic[ServiceBusConstants.DEFAULT_MESSAGE_TIME_TO_LIVE];
@@ -74,6 +61,19 @@ TopicResult.serialize = function (path, topic) {
}
}
+ var atomQueue = {
+ 'title': '',
+ 'updated': ISO8061Date.format(new Date()),
+ 'author': {
+ name: ''
+ },
+ 'id': '',
+ 'content': {
+ '$': { type: 'application/xml' },
+ TopicDescription: topicDescription
+ }
+ };
+
var atomHandler = new AtomHandler(null, null);
var xml = atomHandler.serialize(atomQueue);
return xml;
View
28 lib/services/serviceManagement/sqldatabaseservice.js → ...ervices/serviceManagement/sqlmanagementservice.js
@@ -25,12 +25,12 @@ var parseserverresponse = require('./models/parseserverresponse');
var Constants = require('../../util/constants');
var HttpConstants = Constants.HttpConstants;
-// Expose 'SqlDatabaseService'.
-exports = module.exports = SqlDatabaseService;
+// Expose 'SqlManagementService'.
+exports = module.exports = SqlManagementService;
/**
*
-* Creates a new SqlDatabaseService object
+* Creates a new SqlManagementService object
*
* @constructor
* @param {string} subscriptionId Subscription ID for the account or the connection string
@@ -49,7 +49,7 @@ exports = module.exports = SqlDatabaseService;
* }
*/
-function SqlDatabaseService(subscriptionId, authentication, hostOptions) {
+function SqlManagementService(subscriptionId, authentication, hostOptions) {
if (typeof subscriptionId != 'string' || subscriptionId.length === 0) {
throw new Error('A subscriptionId or a connection string is required');
}
@@ -59,19 +59,19 @@ function SqlDatabaseService(subscriptionId, authentication, hostOptions) {
}
hostOptions.serializetype = 'XML';
- SqlDatabaseService.super_.call(this, authentication, hostOptions);
+ SqlManagementService.super_.call(this, authentication, hostOptions);
this.subscriptionId = subscriptionId;
}
-util.inherits(SqlDatabaseService, ServiceManagementClient);
+util.inherits(SqlManagementService, ServiceManagementClient);
/**
* Lists the available SQL Servers.
*
* @param {function} callback function (err, results, response) The callback function called on completion. Required.
*/
-SqlDatabaseService.prototype.listServers = function (callback) {
+SqlManagementService.prototype.listServers = function (callback) {
var path = this._makePath('servers');
var webResource = WebResource.get(path);
webResource.withOkCode(HttpConstants.HttpResponseCodes.OK_CODE, true);
@@ -98,7 +98,7 @@ SqlDatabaseService.prototype.listServers = function (callback) {
* @param {string} name The SQL Server name.
* @param {function} callback function (err, response) The callback function called on completion. Required.
*/
-SqlDatabaseService.prototype.deleteServer = function (name, callback) {
+SqlManagementService.prototype.deleteServer = function (name, callback) {
var path = this._makePath('servers') + '/' + name;
var webResource = WebResource.del(path);
@@ -119,7 +119,7 @@ SqlDatabaseService.prototype.deleteServer = function (name, callback) {
* @param {string} location The server's location.
* @param {function} callback function (err, server, response) The callback function called on completion. Required.
*/
-SqlDatabaseService.prototype.createServer = function (administratorLogin, administratorLoginPassword, location, callback) {
+SqlManagementService.prototype.createServer = function (administratorLogin, administratorLoginPassword, location, callback) {
var path = this._makePath('servers');
var webResource = WebResource.post(path);
@@ -159,7 +159,7 @@ SqlDatabaseService.prototype.createServer = function (administratorLogin, admini
* @param {string} serverName The server name.
* @param {function} callback function (err, results, response) The callback function called on completion. Required.
*/
-SqlDatabaseService.prototype.listServerFirewallRules = function (serverName, callback) {
+SqlManagementService.prototype.listServerFirewallRules = function (serverName, callback) {
var path = this._makePath('servers') + '/' + serverName + '/firewallrules';
var webResource = WebResource.get(path);
webResource.withOkCode(HttpConstants.HttpResponseCodes.OK_CODE, true);
@@ -188,7 +188,7 @@ SqlDatabaseService.prototype.listServerFirewallRules = function (serverName, cal
* @param {string} ruleName The rule name.
* @param {function} callback function (err, response) The callback function called on completion. Required.
*/
-SqlDatabaseService.prototype.deleteServerFirewallRule = function (serverName, ruleName, callback) {
+SqlManagementService.prototype.deleteServerFirewallRule = function (serverName, ruleName, callback) {
var path = this._makePath('servers') + '/' + serverName + '/firewallrules/' + ruleName;
var webResource = WebResource.del(path);
@@ -210,7 +210,7 @@ SqlDatabaseService.prototype.deleteServerFirewallRule = function (serverName, ru
* @param {string} endIPAddress The ending IP address for the rule.
* @param {function} callback function (err, rule, response) The callback function called on completion. Required.
*/
-SqlDatabaseService.prototype.createServerFirewallRule = function (serverName, ruleName, startIPAddress, endIPAddress, callback) {
+SqlManagementService.prototype.createServerFirewallRule = function (serverName, ruleName, startIPAddress, endIPAddress, callback) {
var path = this._makePath('servers') + '/' + serverName + '/firewallrules';
var webResource = WebResource.post(path);
@@ -254,7 +254,7 @@ SqlDatabaseService.prototype.createServerFirewallRule = function (serverName, ru
* @param {string} endIPAddress The ending IP address for the rule.
* @param {function} callback function (err, rule, response) The callback function called on completion. Required.
*/
-SqlDatabaseService.prototype.updateServerFirewallRule = function (serverName, ruleName, startIPAddress, endIPAddress, callback) {
+SqlManagementService.prototype.updateServerFirewallRule = function (serverName, ruleName, startIPAddress, endIPAddress, callback) {
var path = this._makePath('servers') + '/' + serverName + '/firewallrules/' + ruleName;
var webResource = WebResource.put(path);
webResource.withOkCode(HttpConstants.HttpResponseCodes.OK_CODE, true);
@@ -290,6 +290,6 @@ SqlDatabaseService.prototype.updateServerFirewallRule = function (serverName, ru
});
};
-SqlDatabaseService.prototype._makePath = function (operationName) {
+SqlManagementService.prototype._makePath = function (operationName) {
return '/' + this.subscriptionId + '/services/sqlservers/' + operationName;
};
View
81 lib/services/sqlAzure/models/databaseresult.js
@@ -0,0 +1,81 @@
+/**
+* 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.
+*/
+
+// Module dependencies.
+var AtomHandler = require('../../../util/atomhandler');
+var ISO8061Date = require('../../../util/iso8061date');
+var Constants = require('../../../util/constants');
+var ServiceBusConstants = Constants.ServiceBusConstants;
+var HeaderConstants = Constants.HeaderConstants;
+
+// Expose 'DatabaseResult'.
+exports = module.exports = DatabaseResult;
+
+function DatabaseResult() { }
+
+DatabaseResult.serialize = function (databaseName, collation, edition, maxSizeInGB) {
+ var databaseDescription = { };
+
+ if (collation) {
+ databaseDescription['d:CollationName'] = collation;
+ } else {
+ databaseDescription['d:CollationName'] = { '$': { 'm:null': 'true' } };
+ }
+
+ databaseDescription['d:CreationDate'] = { '$': { 'm:type': 'Edm.DateTime' }, '_': '0001-01-01T00:00:00' };
+
+ if (edition) {
+ databaseDescription['d:Edition'] = edition;
+ } else {
+ databaseDescription['d:Edition'] = { '$': { 'm:null': 'true' } };
+ }
+
+ databaseDescription['d:Id'] = { '$': { 'm:type': 'Edm.Int32' }, '_': '0' };
+ databaseDescription['d:IsFederationRoot'] = { '$': { 'm:type': 'Edm.Boolean', 'm:null': 'true' } };
+ databaseDescription['d:IsReadonly'] = { '$': { 'm:type': 'Edm.Boolean' }, '_': 'false' };
+ databaseDescription['d:IsRecursiveTriggersOn'] = { '$': { 'm:type': 'Edm.Boolean', 'm:null': 'true' } };
+ databaseDescription['d:IsSystemObject'] = { '$': { 'm:type': 'Edm.Boolean' }, '_': 'false' };
+
+ if (maxSizeInGB) {
+ databaseDescription['d:MaxSizeGB'] = { '$': { 'm:type': 'Edm.Int32' }, '_': maxSizeInGB };
+ } else {
+ databaseDescription['d:MaxSizeGB'] = { '$': { 'm:type': 'Edm.Int32', 'm:null': 'true' } };
+ }
+
+ if (databaseName) {
+ databaseDescription['d:Name'] = databaseName;
+ }
+
+ databaseDescription['d:SizeMB'] = { '$': { 'm:type': 'Edm.Decimal' }, '_': '0' };
+ databaseDescription['d:Status'] = { '$': { 'm:type': 'Edm.Int32' }, '_': '0' };
+
+ var atom = {
+ 'title': '',
+ 'updated': ISO8061Date.format(new Date(), false, 7),
+ 'author': {
+ name: ''
+ },
+ 'id': '',
+ 'content': {
+ '$': { type: 'application/xml' },
+ 'm:properties': databaseDescription
+ }
+ };
+
+ var atomHandler = new AtomHandler();
+ var xml = atomHandler.serialize(atom);
+
+ return xml;
+};
View
135 lib/services/sqlAzure/sqlserveracs.js
@@ -0,0 +1,135 @@
+/**
+* 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.
+*/
+
+// Module dependencies.
+var util = require('util');
+var url = require('url');
+var _ = require('underscore');
+
+var azureutil = require('../../util/util');
+
+var ServiceClient = require('../core/serviceclient');
+
+var WebResource = require('../../http/webresource');
+var Constants = require('../../util/constants');
+var QueryStringConstants = Constants.QueryStringConstants;
+var HttpConstants = Constants.HttpConstants;
+var HeaderConstants = Constants.HeaderConstants;
+var SqlAzureConstants = Constants.SqlAzureConstants;
+
+// Expose 'SqlServerAcs'.
+exports = module.exports = SqlServerAcs;
+
+/**
+* Creates a new SqlServerAcs object.
+*
+* @param {string} acsHost The access control host.
+* @param {string} serverName The SQL server name.
+* @param {string} administratorLogin The administrator login.
+* @param {string} administratorLoginPassword The administrator login password.
+*/
+function SqlServerAcs(acsHost, serverName, administratorLogin, administratorLoginPassword) {
+ this.acsHost = acsHost;
+ this.serverName = serverName;
+ this.administratorLogin = administratorLogin;
+ this.administratorLoginPassword = administratorLoginPassword;
+
+ SqlServerAcs.super_.call(this, acsHost);
+}
+
+util.inherits(SqlServerAcs, ServiceClient);
+
+/**
+* Signs a request with the Authentication header.
+*
+* @param {WebResource} The webresource to be signed.
+* @return {undefined}
+*/
+SqlServerAcs.prototype.signRequest = function (webResourceToSign, callback) {
+ var escapedLogin = escapeConnectionCredentials(this.administratorLogin);
+ var escapedLoginPassword = escapeConnectionCredentials(this.administratorLoginPassword);
+
+ var escapedCredentials = escapedLogin + ':' + escapedLoginPassword;
+
+ var encodedCredentials = 'Basic ' + (new Buffer(escapedCredentials).toString('base64'));
+
+ var webResource = WebResource.get('/v1/ManagementService.svc/GetAccessToken');
+
+ webResource.addOptionalHeader('sqlauthorization', encodedCredentials);
+
+ var processResponseCallback = function (responseObject, next) {
+ if (!responseObject.error) {
+ if (responseObject.response.headers['set-cookie']) {
+ _.each(responseObject.response.headers['set-cookie'], function (cookie) {
+ if (_.startsWith(cookie, SqlAzureConstants.SQL_SERVER_MANAGEMENT_COOKIE)) {
+ webResourceToSign.addOptionalHeader('Cookie', cookie.split(';')[0]);
+ }
+ })
+ }
+
+ webResourceToSign.addOptionalHeader('AccessToken', responseObject.response.body.string[Constants.XML_VALUE_MARKER]);
+ }
+
+ var finalCallback = function (returnObject) {
+ callback(returnObject.error);
+ };
+
+ next(responseObject, finalCallback);
+ };
+
+ this.performRequest(webResource, null, null, processResponseCallback);
+};
+
+SqlServerAcs.prototype._buildRequestOptions = function (webResource, options, callback) {
+ var self = this;
+
+ // Sets the request url in the web resource.
+ this._setRequestUrl(webResource);
+
+ var requestOptions = {
+ url: url.format({
+ protocol: self._isHttps() ? 'https:' : 'http:',
+ hostname: self.host,
+ port: self.port,
+ pathname: webResource.path + webResource.getQueryString(true)
+ }),
+ method: webResource.httpVerb,
+ headers: webResource.headers
+ };
+
+ callback(null, requestOptions);
+};
+
+/**
+* Retrieves the normalized path to be used in a request.
+* It adds a leading "/" to the path in case
+* it's not there before.
+*
+* @param {string} path The path to be normalized.
+* @return {string} The normalized path.
+*/
+SqlServerAcs.prototype._getPath = function (path) {
+ if (path === null || path === undefined) {
+ path = '/';
+ } else if (path.indexOf('/') !== 0) {
+ path = '/' + path;
+ }
+
+ return path;
+};
+
+function escapeConnectionCredentials(value) {
+ return value.replace(/\\/g, /\\\\/g).replace(/:/g, /\\:/g);
+}
View
192 lib/services/sqlAzure/sqlservice.js
@@ -0,0 +1,192 @@
+/**
+* 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.
+*/
+
+// Module dependencies.
+var util = require('util');
+var xml2js = require('xml2js');
+var url = require('url');
+var _ = require('underscore');
+
+var SqlServiceClient = require('../core/sqlserviceclient');
+var WebResource = require('../../http/webresource');
+var ServiceClient = require('../core/serviceclient');
+
+var AtomHandler = require('../../util/atomhandler');
+var DatabaseResult = require('./models/databaseresult');
+
+var Constants = require('../../util/constants');
+var HttpConstants = Constants.HttpConstants;
+var HeaderConstants = Constants.HeaderConstants;
+
+// Expose 'SqlService'.
+exports = module.exports = SqlService;
+
+/**
+*
+* Creates a new SqlService object
+*
+* @constructor
+* @param {string} serverName The SQL server name.
+* @param {string} administratorLogin The SQL Server administrator login.
+* @param {string} administratorLoginPassword The SQL Server administrator login password.
+* @param {string} [host] The host for the service.
+* @param {string} [acsHost] The acs host.
+* @param {object} [authenticationProvider] The authentication provider.
+*/
+
+function SqlService(serverName, administratorLogin, administratorLoginPassword, host, acsHost, authenticationProvider) {
+ this.serverName = serverName;
+
+ var endpoint = url.format({ protocol: 'https:', port: 443, hostname: serverName + '.' + ServiceClient.CLOUD_DATABASE_HOST });
+ var acsEndpoint = url.format({ protocol: 'https:', port: 443, hostname: serverName + '.' + ServiceClient.CLOUD_DATABASE_HOST });
+
+ SqlService.super_.call(this,
+ serverName,
+ administratorLogin,
+ administratorLoginPassword,
+ endpoint,
+ acsEndpoint,
+ authenticationProvider);
+}
+
+util.inherits(SqlService, SqlServiceClient);
+
+/**
+* Creates a SQL Server database.
+*
+* @param {string} databaseName The database name.
+* @param {object|function} [optionsOrCallback] The get options or callback function.
+* @param {string} [optionsOrCallback.collation] The database collation to be used.
+* @param {string} [optionsOrCallback.edition] The database edition to be used.
+* @param {string} [optionsOrCallback.maxSizeInGB] The database maximum size in gigabytes.
+* @param {function} callback function (err, response) The callback function called on completion. Required.
+*/
+SqlService.prototype.createServerDatabase = function (databaseName, optionsOrCallback, callback) {
+ var options = null;
+ if (typeof optionsOrCallback === 'function' && !callback) {
+ callback = optionsOrCallback;
+ options = { };
+ } else {
+ options = optionsOrCallback;
+ }
+
+ validateCallback(callback);
+
+ var databaseXml = DatabaseResult.serialize(databaseName, options.collation, options.edition, options.maxSizeInGB);
+
+ var webResource = WebResource.post(SqlAzureConstants.MANAGEMENT_SERVICE_URI + 'Server2(\'' + this.serverName + '\')/Databases');
+
+ webResource.addOptionalHeader(HeaderConstants.CONTENT_TYPE, 'application/atom+xml;charset="utf-8"');
+ webResource.addOptionalHeader(HeaderConstants.CONTENT_LENGTH, Buffer.byteLength(databaseXml, 'utf8'));
+ webResource.addOptionalHeader('Expect', '100-continue');
+
+ var processResponseCallback = function (responseObject, next) {
+ if (!responseObject.error && responseObject.response.body.entry) {
+ var atomHandler = new AtomHandler();
+ responseObject.database = atomHandler.parse(responseObject.response.body.entry)
+ }
+
+ var finalCallback = function (returnObject) {
+ callback(returnObject.error, returnObject.database, returnObject.response);
+ };
+
+ next(responseObject, finalCallback);
+ };
+
+ this._performRequestExtended(webResource, databaseXml, null, processResponseCallback);
+};
+
+/**
+* Deletes a SQL Server database.
+*
+* @param {string} databaseId The database identifier.
+* @param {function} callback function (err, response) The callback function called on completion. Required.
+*/
+SqlService.prototype.deleteServerDatabase = function (databaseId, callback) {
+ validateCallback(callback);
+
+ var webResource = WebResource.del(SqlAzureConstants.MANAGEMENT_SERVICE_URI + 'Server2(\'' + this.serverName + '\')/Databases(' + databaseId + ')');
+
+ var processResponseCallback = function (responseObject, next) {
+ var finalCallback = function (returnObject) {
+ callback(returnObject.error, returnObject.response);
+ };
+
+ next(responseObject, finalCallback);
+ };
+
+ this._performRequestExtended(webResource, null, null, processResponseCallback);
+};
+
+/**
+* Lists the SQL Server databases.
+*
+* @param {function} callback function (err, results, response) The callback function called on completion. Required.
+*/
+SqlService.prototype.listServerDatabases = function (callback) {
+ validateCallback(callback);
+
+ var webResource = WebResource.get(SqlAzureConstants.MANAGEMENT_SERVICE_URI + 'Server2(\'' + this.serverName + '\')/Databases');
+
+ var processResponseCallback = function (responseObject, next) {
+ if (!responseObject.error) {
+ responseObject.databases = [];
+
+ var entries = [];
+ if (responseObject.response.body.feed && responseObject.response.body.feed.entry) {
+ entries = responseObject.response.body.feed.entry;
+ } else if (responseObject.response.body.entry) {
+ entries = [responseObject.response.body.entry];
+ }
+
+ var atomHandler = new AtomHandler();
+ _.each(entries, function (entry) {
+ responseObject.databases.push(atomHandler.parse(entry));
+ });
+ }
+
+ var finalCallback = function (returnObject) {
+ callback(returnObject.error, returnObject.databases, returnObject.response);
+ };
+
+ next(responseObject, finalCallback);
+ };
+
+ this._performRequestExtended(webResource, null, null, processResponseCallback);
+};
+
+SqlService.prototype._performRequestExtended = function (webResource, rawData, options, callback) {
+ if (!webResource.headers || !webResource.headers[HeaderConstants.DATA_SERVICE_VERSION]) {
+ webResource.addOptionalHeader(HeaderConstants.DATA_SERVICE_VERSION, '1.0;NetFx');
+ }
+
+ if (!webResource.headers || !webResource.headers[HeaderConstants.MAX_DATA_SERVICE_VERSION]) {
+ webResource.addOptionalHeader(HeaderConstants.MAX_DATA_SERVICE_VERSION, '2.0;NetFx');
+ }
+
+ this.performRequest(webResource, rawData, options, callback);
+};
+
+/**
+* Validates a callback function.
+*
+* @param {string} callback The callback function.
+* @return {undefined}
+*/
+function validateCallback(callback) {
+ if (!callback) {
+ throw new Error(TableService.incorrectCallbackErr);
+ }
+}
View
1  lib/services/table/tableservice.js
@@ -24,7 +24,6 @@ var StorageServiceClient = require('../core/storageserviceclient');
var BatchServiceClient = require('./batchserviceclient');
var SharedKeyTable = require('./sharedkeytable');
var TableQuery = require('./tablequery');
-var AtomHandler = require('../../util/atomhandler');
var ServiceClient = require('../core/serviceclient');
var WebResource = require('../../http/webresource');
var Constants = require('../../util/constants');
View
5 lib/util/constants.js
@@ -2511,6 +2511,11 @@ var Constants = {
}
},
+ SqlAzureConstants: {
+ SQL_SERVER_MANAGEMENT_COOKIE: '.SQLSERVERMANAGEMENT',
+ MANAGEMENT_SERVICE_URI: '/v1/ManagementService.svc/'
+ },
+
BlobErrorCodeStrings: {
INVALID_BLOCK_ID: 'InvalidBlockId',
BLOB_NOT_FOUND: 'BlobNotFound',
View
2  ...ces/serviceManagement/sqldatabaseservice-tests.js → ...s/serviceManagement/sqlmanagementservice-tests.js
@@ -32,7 +32,7 @@ describe('SQL Server Management', function () {
before(function () {
var subscriptionId = process.env['AZURE_SUBSCRIPTION_ID'];
var auth = { keyvalue: testutil.getCertificateKey(), certvalue: testutil.getCertificate() };
- service = azure.createSqlDatabaseService(
+ service = azure.createSqlManagementService(
subscriptionId, auth,
{ serializetype: 'XML'});
});
View
190 test/services/sqlAzure/sqlservice-tests.js
@@ -0,0 +1,190 @@
+/**
+* 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 should = require('should');
+var mocha = require('mocha');
+var uuid = require('node-uuid');
+
+var testutil = require('../../util/util');
+
+var azure = testutil.libRequire('azure');
+
+var SERVER_ADMIN_USERNAME = 'azuresdk';
+var SERVER_ADMIN_PASSWORD = 'PassWord!1';
+var SERVER_LOCATION = 'West US';
+
+var DATABASE_NAME = 'mydatabase';
+
+describe('SQL Azure Database', function () {
+ var serverName;
+
+ var service;
+ var serviceManagement;
+
+ before(function (done) {
+ var subscriptionId = process.env['AZURE_SUBSCRIPTION_ID'];
+ var auth = { keyvalue: testutil.getCertificateKey(), certvalue: testutil.getCertificate() };
+ serviceManagement = azure.createSqlManagementService(
+ subscriptionId, auth,
+ { serializetype: 'XML'});
+
+ serviceManagement.createServer(SERVER_ADMIN_USERNAME, SERVER_ADMIN_PASSWORD, SERVER_LOCATION, function (err, name) {
+ should.not.exist(err);
+
+ serverName = name;
+
+ // Create the SQL Azure service to test
+ service = azure.createSqlService(serverName, SERVER_ADMIN_USERNAME, SERVER_ADMIN_PASSWORD);
+
+ // add firewall rule for all the ip range
+ serviceManagement.createServerFirewallRule(serverName, 'rule1', '0.0.0.0', '255.255.255.255', function () {
+
+ // Wait for the firewall rule to be added (test different operations needed as it seems they dont go valid at the same time)
+ var checkIfRuleAdded = function () {
+ setTimeout(function () {
+ var databaseId;
+
+ service.createServerDatabase(DATABASE_NAME, function (err, db) {
+ if (err) {
+ checkIfRuleAdded();
+ } else {
+ databaseId = db.Id;
+
+ var checkIfRuleDeleted = function () {
+ setTimeout(function () {
+ service.deleteServerDatabase(databaseId, function (err) {
+ if (err) {
+ checkIfRuleDeleted();
+ } else {
+ var checkIfRuleLists = function () {
+ setTimeout(function () {
+ service.listServerDatabases(function (err) {
+ if (err) {
+ checkIfRuleLists();
+ } else {
+ done();
+ }
+ })
+ }, 2000);
+ };
+
+ checkIfRuleLists();
+ }
+ });
+ }, 2000);
+ };
+
+ checkIfRuleDeleted();
+ }
+ });
+ }, 2000);
+ };
+
+ checkIfRuleAdded();
+ });
+ });
+ });
+
+ after(function (done) {
+ serviceManagement.deleteServer(serverName, done);
+ });
+
+ describe('list SQL databases', function () {
+ describe('when only master database is defined', function () {
+ it('should return it', function (done) {
+ service.listServerDatabases(function (err, databases) {
+ should.not.exist(err);
+ should.exist(databases);
+ databases.should.have.length(1);
+ databases[0].Name.should.equal('master');
+ done(err);
+ });
+ });
+ });
+
+ describe('when multiple databases are defined', function () {
+ var databaseId;
+
+ before(function (done) {
+ service.createServerDatabase(DATABASE_NAME, function (err, database) {
+ should.not.exist(err);
+ databaseId = database.Id;
+
+ done(err);
+ });
+ });
+
+ after(function (done) {
+ service.deleteServerDatabase(databaseId, function (err) {
+ done(err);
+ });
+ });
+
+ it('should return it', function (done) {
+ service.listServerDatabases(function (err, databases) {
+ should.not.exist(err);
+ should.exist(databases);
+ databases.should.have.length(2);
+ should.exist(databases.filter(function (database) {
+ return database.Name === DATABASE_NAME;
+ })[0]);
+
+ done(err);
+ });
+ });
+ });
+ });
+
+ describe('Delete SQL databases', function () {
+ var databaseId;
+
+ before(function (done) {
+ service.createServerDatabase(DATABASE_NAME, function (err, database) {
+ should.not.exist(err);
+ databaseId = database.Id;
+
+ done(err);
+ });
+ });
+
+ it('should delete existing database', function (done) {
+ service.deleteServerDatabase(databaseId, function (err, databases) {
+ should.not.exist(err);
+
+ service.listServerDatabases(function (err, databases) {
+ should.exist(databases);
+ should.not.exist(databases.filter(function (database) {
+ return database.Name === DATABASE_NAME;
+ })[0]);
+
+ done(err);
+ });
+ });
+ });
+ });
+
+ function deleteSqlDatabases(databases, callback) {
+ if (databases.length === 0) { return callback(); }
+ var numDeleted = 0;
+ databases.forEach(function (databaseId) {
+ service.deleteServerDatabase(databaseId, function (err) {
+ ++numDeleted;
+ if (numDeleted === databases.length) {
+ callback();
+ }
+ });
+ });
+ }
+});
View
3  test/testlist.txt
@@ -23,11 +23,12 @@ services/serviceBus/servicebusservice-tests.js
services/serviceBus/wrapservice-tests.js
services/serviceBus/wraptokenmanager-tests.js
services/serviceManagement/servicemanagementservice-tests.js
-services/serviceManagement/sqldatabaseservice-tests.js
+services/serviceManagement/sqlmanagementservice-tests.js
services/table/tablequery-tests.js
services/table/tableservice-batch-tests.js
services/table/tableservice-tablequery-tests.js
services/table/tableservice-tests.js
+services/sqlAzure/sqlservice-tests.js
util/atomhandler-tests.js
util/iso8061date-tests.js
util/util-tests.js
View
2  test/util/util.js
@@ -80,4 +80,4 @@ exports.getCertificate = function () {
}
return null;
-};
+};
Please sign in to comment.
Something went wrong with that request. Please try again.