azure-storage
Version:
Microsoft Azure Storage Client Library for Node.js
438 lines (391 loc) • 23.5 kB
HTML
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Azure Storage JavaScript Client Library Sample for Table Operations</title>
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<div class="mt-1">
<h1>Azure Storage JavaScript Client Library Sample for Table Operations</h1>
</div>
<p class="lead">In this sample, we will demonstrate common scenarios for Azure Table Storage that includes creating, listing and deleting tables and entities.</p>
<hr/>
<p>Azure Storage table is a service that stores structured NoSQL data in the cloud. Table storage is a key/attribute store with a schemaless design. Because Table storage is schemaless, it's easy to adapt your data as the needs of your application evolve. Access to data is fast and cost-effective for all kinds of applications. Table storage is typically significantly lower in cost than traditional SQL for similar volumes of data.
</p>
<div class="panel panel-danger">
<div class="panel-body">
<b>Note</b>: You may need set up a HTTP server to host this sample for IE11 and latest Chrome.
</div>
</div>
<h2>Contents:</h2>
<ul>
<li><a href="#step1">Step 1: Preparing an Azure Storage account with CORS rules set</a></li>
<li><a href="#step2">Step 2: Importing Azure Storage JavaScript Client Library</a></li>
<li><a href="#step3">Step 3: Creating an Azure Storage Table Service Object</a></li>
<li><a href="#step4">Step 4: Table Operations</a></li>
<li><a href="#step5">Step 5: Table Entities Operations</a></li>
<li><a href="#step6">Step 6: Creating your JavaScript Application based on Azure Storage JavaScript Client Library</a></li>
</ul>
<h2 id="step1">Step 1: Preparing an Azure Storage account with CORS rules set</h2>
<p>Cross-origin resource sharing, or CORS, must be configured on the Azure Storage account to be accessed directly from JavaScript in the browser.
You are able to set the CORS rules for specific Azure Storage account on the <a href="https://portal.azure.com">Azure Portal</a>.
The "Allowed origins" could be set to "*" to allow all the origins in this sample.
For more information about CORS, see <a href="https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/cross-origin-resource-sharing--cors--support-for-the-azure-storage-services">Cross-Origin Resource Sharing (CORS)</a>.</p>
<img src="cors.PNG"/>
<h2 id="step2">Step 2: Importing Azure Storage JavaScript Client Library</h2>
<p>
Importing <code>azure-storage.table.js</code> in your HTML file for table operations.
<p>
<pre>
<script src="azure-storage.table.js"></script>
</pre>
<h2 id="step3">Step 3: Creating an Azure Storage Table Service Object</h2>
<p>
The <code>TableService</code> object lets you work with table and entities.
Following code creates a <code>TableService</code> object with storage account and SAS Token.
</p>
<pre>
var tableUri = 'https://' + 'STORAGE_ACCOUNT' + '.table.core.windows.net';
var tableService = AzureStorage.Table.createTableServiceWithSas(tableUri, 'SAS_TOKEN');
</pre>
<p>
You can load Azure Storage JavaScript Client Library in a CommonJS or AMD environment by JavaScript module loaders. If no module system is found, global variable <code>AzureStorage.Table</code> will be set, which is the start point where we can create service objects for table and access to the storage utilities.
</p>
<div class="panel panel-primary">
<div class="panel-body">
<b>How to get full detailed API definitions? </b> Currently, the JavaScript Client Library shares almost the same API definitions with Node.js SDK, besides Node.js runtime specific APIs.
Please check API details on <a href="http://azure.github.io/azure-storage-node/">Azure Storage API reference documents</a>. The JavaScript global variable <code>AzureStorage.Table</code> is just like the object <code>require('azure-storage')</code> returns in Node.js, but limits to Table related interfaces.
Go to <a href="https://azure.github.io/azure-storage-node/TableService.html">TableService</a> to view possible methods provided by <code>TableService</code> class.
</div>
</div>
<div class="panel panel-danger">
<div class="panel-body">
<b>Warning</b>: Azure Storage JavaScript Client Library also supports creating <code>TableService</code> based on Storage Account Key for authentication besides SAS Token.
However, for security concerns, we recommend use of a limited time SAS Token, generated by a backend web server using a <a href="https://docs.microsoft.com/en-us/azure/storage/storage-dotnet-shared-access-signature-part-1">Stored Access Policy</a>.
</div>
</div>
<h2 id="step4">Step 4: Table Operations</h2>
<p>
<b>Table</b>: A table is a collection of entities. Tables don't enforce a schema on entities, which means a single table can contain entities that have different sets of properties. The number of tables that a storage account can contain is limited only by the storage account capacity limit.
</p>
<h3>List Tables</h3>
<p><code>TableService</code> provides <code>listTablesSegmented</code> and <code>listTablesSegmentedWithPrefix</code> for retrieving the table list under your storage account.</p>
<pre>
tableService.listTablesSegmented(null, {maxResults : 200}, function (error, results) {
if (error) {
// List tables error
} else {
for (var i = 0, table; table = results.entries[i]; i++) {
// Deal with table object
}
}
});
</pre>
<h3>Create Table</h3>
<p><code>TableService</code> provides <code>createTable</code> and <code>createTableIfNotExists</code> for creating a table under a storage account.</p>
<pre>
tableService.createTableIfNotExists('mytable', function(error, result) {
if (error) {
// Create table error
} else {
// Create table successfully
}
});
</pre>
<h3>Delete Table</h3>
<p><code>TableService</code> provides <code>deleteTable</code> and <code>deleteTableIfExists</code> for deleting a table under a storage account.</p>
<pre>
tableService.deleteTableIfExists('mytable', function(error, result) {
if (error) {
// Delete table error
} else {
// Delete table successfully
}
});
</pre>
<h3> Executable Example </h3>
<p>The sample will try to create an Azure Storage table service object based on SAS Token authorization. Enter your Azure Storage account name and SAS Token here. Make sure you have set the CORS rules for the Azure Storage table service, and the SAS Token is in valid period.</p>
<label><b>Storage account:</b> </label> <input type="text" id="account"/>
<label><b>SAS Token:</b> </label> <input type="text" id="sas"/>
<p> Azure Storage table service provides plenty of interfaces for table operations. In following example, you can try to list all the tables under your storage account, and try to create or delete one table from your account.</p>
<ul>
<li><p> Click <button class="btn btn-xs btn-primary" onclick="refreshTableList()">ListTables</button> button to view the table list under your Azure Storage account</p></li>
<li><p> Click <button class="btn btn-xs btn-primary" onclick="createTable()">CreateTable</button> button to create a table under your Azure Storage account</p>
<p><label><b>New Table Name:</b> </label> <input type="text" value="mytable" id="newtable"/> </p>
</li>
<li><p> Click "<b>Delete</b>" button to delete the table under your Azure Storage account</p></li>
<li><p> Click "<b>Select</b>" button to operate with the table entities in next step</p></li>
</ul>
<div id="tables"></div>
<h2 id="step5">Step 5: Table Entities Operations</h2>
<p><b>Entity</b>: An entity is a set of properties, similar to a database row. An entity can be up to 1MB in size.</p>
<p><b>Properties</b>: A property is a name-value pair. Each entity can include up to 252 properties to store data. Each entity also has 3 system properties that specify a partition key, a row key, and a timestamp. Entities with the same partition key can be queried more quickly, and inserted/updated in atomic operations. An entity's row key is its unique identifier within a partition.</p>
<h3>Query Entities</h3>
<p><code>TableService</code> provides <code>queryEntities</code> for querying a table under a storage account.</p>
<pre>
var tableQuery = new AzureStorage.Table.TableQuery().top(200);
tableService.queryEntities('mytable', tableQuery, null, function(error, result) {
if (error) {
// Query entities error
} else {
for (var i = 0, entity; entity = results.entries[i]; i++) {
// Deal with entity object
}
}
});
</pre>
<h3>Insert or Replace Entity</h3>
<p><code>TableService</code> provides <code>insertEntity</code>, <code>insertOrReplaceEntity</code> and <code>insertOrMergeEntity</code> for adding a table entity under a storage account.</p>
<pre>
var insertEntity = {
PartitionKey: {'_': 'partitionKey'},
RowKey: {'_': 'rowKey'}
};
tableService.insertOrReplaceEntity('mytable', insertEntity, function(error, result, response) {
if(error) {
// Insert table entity error
} else {
// Insert table entity successfully
}
});
</pre>
<h3>Delete Entity</h3>
<p><code>TableService</code> provides <code>deleteEntity</code> for deleting a table entity under a storage account.</p>
<pre>
var deleteEntity = {
PartitionKey: {'_': 'partitionKey'},
RowKey: {'_': 'rowKey'}
};
tableService.deleteEntity('mytable', deleteEntity, function(error, result, response) {
if(error) {
// Delete table entity error
} else {
// Delete table entity successfully
}
});
</pre>
<h3> Executable Example </h3>
<p>After clicked the "<b>Select</b>" button on the table list, you are able to operate with the table entities under the selected table.<p>
<ul>
<li><p> Click <button class="btn btn-xs btn-primary" onclick="refreshEntityList()">QueryEntities</button> button to refresh the entity list in your selected table</p></li>
<li><p> Click <button class="btn btn-xs btn-primary" onclick="addEntity()">AddOrUpdateEntity</button> button to create an entity in your selected table. If existing entity with the sampe PartitionKey and RowKey, old entity will be merged.</p>
<p>
<label><b>PK</b> </label> <input type="text" value="PartitionKey" id="pk"/>
<label><b>RK</b> </label> <input type="text" value="RowKey" id="rk"/>
<label><b>CustomProperty1</b> </label> <input type="text" value="Custom Property 1" id="cp1"/>
<label><b>CustomProperty2</b> </label> <input type="text" value="Custom Property 2" id="cp2"/>
</p>
</li>
<li><p> Click "<b>Delete</b>" button to delete the selected table entity in your selected table</p></li>
</ul>
<div id="result"></div>
<h3 id="step6">Step 6: Creating your JavaScript Application based on Azure Storage JavaScript Client Library</h3>
<ol>
<li>Setting CORS rules for your selected Azure-Storage account table service.</li>
<li>Including functional file(s) needed, such as "azure-storage.table.js" for table operation.</li>
<li>Using keyword "AzureStorage.Table" to access to Azure storage JavaScript APIs for tables.</li>
<li>Referring to <a href="http://azure.github.io/azure-storage-node/">API documents</a> for detailed API definitions.</li>
</ol>
<p> You can view the source code of this sample for detailed reference. </p>
</div>
<script src="../bundle/azure-storage.table.js"></script>
<script>
var account = document.getElementById('account').value;
var sas = document.getElementById('sas').value;
var table = '';
var tableUri = '';
function checkParameters() {
account = document.getElementById('account').value;
sas = document.getElementById('sas').value;
if (account == null || account.length < 1)
{
alert('Please enter a valid storage account name!');
return false;
}
if (sas == null || sas.length < 1)
{
alert('Please enter a valid SAS Token!');
return false;
}
return true;
}
function getTableService() {
if (!checkParameters())
return null;
tableUri = 'https://' + account + '.table.core.windows.net';
var tableService = AzureStorage.Table.createTableServiceWithSas(tableUri, sas).withFilter(new AzureStorage.Table.ExponentialRetryPolicyFilter());
return tableService;
}
function refreshTableList()
{
var tableService = getTableService();
if (!tableService)
return;
document.getElementById('tables').innerHTML = 'Loading table list...';
tableService.listTablesSegmented(null, {maxResults : 200}, function(error, results) {
if (error) {
alert('List table list error, please open browser console to view detailed error');
console.log(error);
} else {
var output = [];
output.push('<tr>',
'<th>TableName</th>',
'<th>Operations</th>',
'</tr>');
if (results.entries.length < 1) {
output.push('<tr><td>Empty results...</td></tr>');
}
for (var i = 0, table; table = results.entries[i]; i++) {
output.push('<tr>',
'<td>', table, '</td>',
'<td>', '<button class="btn btn-xs btn-danger" onclick="deleteTable(\'', table ,'\')">Delete</button> ',
'<button class="btn btn-xs btn-success" onclick="viewTable(\'', table ,'\')">Select</button>', '</td>',
'</tr>');
}
document.getElementById('tables').innerHTML = '<table class="table table-condensed table-bordered">' + output.join('') + '</table>';
}
});
}
function createTable() {
var tableService = getTableService();
if (!tableService)
return;
var table = document.getElementById('newtable').value;
if (!AzureStorage.Table.Validate.tableNameIsValid(table, function(err, res){})) {
alert('Invalid table name!');
return;
}
tableService.createTableIfNotExists(table.toLowerCase(), function(error, result) {
if (error) {
alert('Create table failed, open browser console for more detailed info.');
console.log(error);
} else {
alert('Create ' + table + ' successfully!');
refreshTableList();
}
});
}
function deleteTable(table) {
var tableService = getTableService();
if (!tableService)
return;
tableService.deleteTableIfExists(table, function(error, result) {
if (error) {
alert('Delete table failed, open browser console for more detailed info.');
console.log(error);
} else {
alert('Delete ' + table + ' successfully!');
refreshTableList();
}
});
}
function viewTable(selectedTable) {
table = selectedTable;
alert('Selected ' + table + ' !');
refreshEntityList();
}
function refreshEntityList() {
var tableService = getTableService();
if (!tableService)
return;
if (table == null || table.length < 1) {
alert('Please select a table from table list!')
return;
}
document.getElementById('result').innerHTML = 'Loading table entities...';
var tableQuery = new AzureStorage.Table.TableQuery().top(200);
tableService.queryEntities(table, tableQuery, null, function(error, results) {
if (error) {
alert('List table entities error, please open browser console to view detailed error');
console.log(error);
} else {
var output = [];
output.push('<tr>',
'<th>PartitionKey</th>',
'<th>RowKey</th>',
'<th>Custom Property 1</th>',
'<th>Custom Property 2</th>',
'<th>Timestamp</th>',
'<th>Operations</th>',
'</tr>');
if (results.entries.length < 1) {
output.push('<tr><td>Empty results...</td></tr>');
}
for (var i = 0, entity; entity = results.entries[i]; i++) {
var cp1 = '';
var cp2 = '';
if (typeof entity.CustomProperty1 !== 'undefined') {
cp1 = entity.CustomProperty1._;
}
if (typeof entity.CustomProperty2 !== 'undefined') {
cp2 = entity.CustomProperty2._;
}
output.push('<tr>',
'<td>', entity.PartitionKey._, '</td>',
'<td>', entity.RowKey._, '</td>',
'<td>', cp1, '</td>',
'<td>', cp2, '</td>',
'<td>', entity.Timestamp._, '</td>',
'<td>', '<button class="btn btn-xs btn-danger" onclick="deleteEntity(\'', entity.PartitionKey._ ,'\'', ',', '\'', entity.RowKey._ ,'\'',')">Delete</button>', '</td>',
'</tr>');
}
document.getElementById('result').innerHTML = '<table class="table table-condensed table-bordered">' + output.join('') + '</table>';
}
});
}
function addEntity() {
var tableService = getTableService();
if (!tableService)
return;
if (table == null || table.length < 1) {
alert('Invalid table name!')
return;
}
var partitionKey = document.getElementById('pk').value;
var rowKey = document.getElementById('rk').value;
var customProperty1 = document.getElementById('cp1').value;
var customProperty2 = document.getElementById('cp2').value;
var insertEntity = {
PartitionKey: {'_': partitionKey},
RowKey: {'_': rowKey},
CustomProperty1: {'_': customProperty1},
CustomProperty2: {'_': customProperty2}
};
tableService.insertOrMergeEntity(table, insertEntity, function(error, result, response) {
if(error) {
alert('Insert table entity error, please open browser console to view detailed error');
console.log(error);
} else {
alert('Insert table entity successfully!');
refreshEntityList();
}
});
}
function deleteEntity(partitionKey, rowKey) {
var tableService = getTableService();
if (!tableService)
return;
if (table == null || table.length < 1) {
alert('Invalid table name!')
return;
}
var deleteEntity = {
PartitionKey: {'_': partitionKey},
RowKey: {'_': rowKey}
};
tableService.deleteEntity(table, deleteEntity, function(error, result, response) {
if(error) {
alert('Delete table entity error, please open browser console to view detailed error');
console.log(error);
} else {
alert('Delete table entity successfully!');
refreshEntityList();
}
});
}
</script>
</body>
</html>