├── .gitignore ├── Documentation ├── Branching Guidance.md ├── Contribution Guidance.md ├── Contribution Workflow.md └── Issue Guidance.md ├── ElasticDatabaseTools.sln ├── LICENSE ├── README.md ├── SECURITY.md ├── Samples ├── CodeAnalysis.Samples.ruleset ├── Dapper │ ├── Blog.cs │ ├── ElasticDapper.csproj │ ├── LICENSE │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── Sharding.cs ├── EFCodeFirst │ ├── DataClasses.cs │ ├── ElasticScaleContext.cs │ ├── ElasticScaleDbConfiguration.cs │ ├── EntityFrameworkCodeFirst.csproj │ ├── LICENSE │ ├── Migrations │ │ ├── 201405280437372_InitialCreate.Designer.cs │ │ ├── 201405280437372_InitialCreate.cs │ │ ├── 201405280437372_InitialCreate.resx │ │ ├── 201405280633219_AddUrl.Designer.cs │ │ ├── 201405280633219_AddUrl.cs │ │ ├── 201405280633219_AddUrl.resx │ │ ├── 201405280638095_AddUser.Designer.cs │ │ ├── 201405280638095_AddUser.cs │ │ ├── 201405280638095_AddUser.resx │ │ ├── 201405280640127_ChangeDisplayName.Designer.cs │ │ ├── 201405280640127_ChangeDisplayName.cs │ │ ├── 201405280640127_ChangeDisplayName.resx │ │ └── Configuration.cs │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Sharding.cs │ ├── SqlDatabaseUtils.cs │ └── appsettings.json ├── EFMultiTenant │ ├── ApplySqlToShards.ps1 │ ├── DataClasses.cs │ ├── ElasticScaleContext.cs │ ├── ElasticScaleDbConfiguration.cs │ ├── EnableRLS.sql │ ├── EntityFrameworkMultiTenant.csproj │ ├── LICENSE │ ├── Migrations │ │ ├── 201405280437372_InitialCreate.Designer.cs │ │ ├── 201405280437372_InitialCreate.cs │ │ ├── 201405280437372_InitialCreate.resx │ │ ├── 201405280633219_AddUrl.Designer.cs │ │ ├── 201405280633219_AddUrl.cs │ │ ├── 201405280633219_AddUrl.resx │ │ ├── 201405280638095_AddUser.Designer.cs │ │ ├── 201405280638095_AddUser.cs │ │ ├── 201405280638095_AddUser.resx │ │ ├── 201405280640127_ChangeDisplayName.Designer.cs │ │ ├── 201405280640127_ChangeDisplayName.cs │ │ ├── 201405280640127_ChangeDisplayName.resx │ │ ├── 201504020051125_AddTenantId.Designer.cs │ │ ├── 201504020051125_AddTenantId.cs │ │ ├── 201504020051125_AddTenantId.resx │ │ └── Configuration.cs │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── RemoveRLS.sql │ ├── Sharding.cs │ ├── SqlDatabaseUtils.cs │ └── appsettings.json ├── ElasticScaleStarterKit │ ├── App.config │ ├── Configuration.cs │ ├── ConsoleUtils.cs │ ├── CreateShardSample.cs │ ├── DataDependentRoutingSample.cs │ ├── ElasticScaleStarterKit.csproj │ ├── InitializeShard.sql │ ├── LICENSE │ ├── MultiShardQuerySample.cs │ ├── Program.cs │ ├── README.txt │ ├── ShardManagementUtils.cs │ ├── SqlDatabaseUtils.cs │ └── TableFormatter.cs ├── PowerShell │ ├── ExecuteSampleSplitMerge.ps1 │ ├── GetMappings.ps1 │ ├── GetShards.ps1 │ ├── GetSplitMergeHistory.ps1 │ ├── SetupSampleSplitMergeEnvironment.ps1 │ ├── ShardManagement │ │ ├── CreatePerformanceCounterCategory.ps1 │ │ └── ShardManagement.psm1 │ ├── SplitMerge │ │ └── SplitMerge.psm1 │ ├── SqlDatabaseHelpers │ │ └── SqlDatabaseHelpers.psm1 │ └── Upgrade.ps1 └── ShardSqlCmd │ ├── LICENSE │ ├── Program.cs │ ├── ShardSqlCmd.csproj │ └── TableFormatter.cs ├── Src └── ElasticScale.Client │ ├── ElasticScale.Common │ ├── ElasticScale.Common.csproj.vspscc │ ├── ExceptionHandling │ │ └── ExceptionExtensionMethods.cs │ ├── GlobalSuppressions.cs │ ├── InternalHelpers │ │ ├── ApplicationNameHelper.cs │ │ └── SerializationHelper.cs │ ├── Logging │ │ ├── ILogConfigWatcher.cs │ │ ├── ILogger.cs │ │ ├── LoggerFactory.cs │ │ └── TraceSource │ │ │ ├── ActivityIdScope.cs │ │ │ ├── TraceSourceFactory.cs │ │ │ └── TraceSourceWrapper.cs │ ├── Patterns │ │ └── ConditionalDisposable.cs │ ├── Properties │ │ ├── Resources.Designer.cs │ │ └── Resources.resx │ └── TransientFaultHandling │ │ ├── Implementation │ │ ├── AsyncExecution.cs │ │ ├── ExponentialBackoff.cs │ │ ├── FixedInterval.cs │ │ ├── Guard.cs │ │ ├── ITransientErrorDetectionStrategy.cs │ │ ├── Incremental.cs │ │ ├── RetryLimitExceededException.cs │ │ ├── RetryManager.cs │ │ ├── RetryPolicy.Generic.cs │ │ ├── RetryPolicy.cs │ │ ├── RetryStrategy.cs │ │ ├── RetryingEventArgs.cs │ │ ├── SqlDatabaseTransientErrorDetectionStrategy.cs │ │ └── ThrottlingCondition.cs │ │ ├── RetryBehavior.cs │ │ ├── RetryPolicy.cs │ │ └── RetryingEventArgs.cs │ ├── GlobalSuppressions.cs │ ├── Microsoft.Azure.SqlDatabase.ElasticScale.Client.csproj │ ├── Properties │ ├── AssemblyInfo.cs │ └── Icon.png │ ├── Query │ ├── DbCommandExtensions.cs │ ├── Exceptions │ │ ├── MultiShardAggregateException.cs │ │ ├── MultiShardDataReaderClosedException.cs │ │ ├── MultiShardDataReaderInternalException.cs │ │ ├── MultiShardException.cs │ │ ├── MultiShardPartialReadException.cs │ │ └── MultiShardSchemaMismatchException.cs │ ├── GlobalConstants.cs │ ├── LabeledDbDataReader.cs │ ├── Logging │ │ └── TraceHelper.cs │ ├── MultiShardCommand.cs │ ├── MultiShardConnection.cs │ ├── MultiShardDataReader.cs │ ├── MultiShardExecutionOptions.cs │ ├── MultiShardExecutionPolicy.cs │ ├── MultiShardQueryTransientErrorDetectionStrategy.cs │ ├── MultiShardUtils.cs │ ├── ResultSetAggregator.csproj.vspscc │ └── ShardExecutionEventArgs.cs │ └── ShardManagement │ ├── Cache │ ├── CacheListMapper.cs │ ├── CacheMapper.cs │ ├── CacheMapping.cs │ ├── CacheMappingExtensions.cs │ ├── CacheObject.cs │ ├── CacheRangeMapper.cs │ ├── CacheRoot.cs │ ├── CacheShardMap.cs │ ├── CacheStore.cs │ ├── ICacheStore.cs │ ├── ICacheStoreMapping.cs │ ├── PerfCounterInstance.cs │ ├── PerformanceCounterWrapper.cs │ ├── ReadLockScope.cs │ └── WriteLockScope.cs │ ├── Errors.Designer.cs │ ├── Errors.resx │ ├── Logging │ ├── TraceHelper.cs │ └── TraceSourceConstants.cs │ ├── PerformanceCounters.Designer.cs │ ├── PerformanceCounters.resx │ ├── Recovery │ ├── MappingComparisonResult.cs │ ├── MappingComparisonUtils.cs │ ├── MappingDifference.cs │ ├── MappingDifferenceResolution.cs │ ├── MappingDifferenceType.cs │ ├── MappingLocation.cs │ ├── RecoveryManager.cs │ └── RecoveryToken.cs │ ├── SchemaInformation │ ├── ReferenceTableInfo.cs │ ├── SchemaInfo.cs │ ├── SchemaInfoCollection.cs │ ├── SchemaInfoErrorCode.cs │ ├── SchemaInfoException.cs │ ├── ShardedTableInfo.cs │ └── TableInfo.cs │ ├── Scripts │ ├── CheckShardMapManagerGlobal.cs │ ├── CheckShardMapManagerLocal.cs │ ├── CreateShardMapManagerGlobal.cs │ ├── CreateShardMapManagerLocal.cs │ ├── DropShardMapManagerGlobal.cs │ ├── DropShardMapManagerLocal.cs │ ├── UpgradeScripts.cs │ ├── UpgradeShardMapManagerGlobalFrom0.0To1.0.cs │ ├── UpgradeShardMapManagerGlobalFrom1.0To1.1.cs │ ├── UpgradeShardMapManagerGlobalFrom1.1To1.2.cs │ ├── UpgradeShardMapManagerGlobalFrom1000.0To1000.1.cs │ ├── UpgradeShardMapManagerLocalFrom0.0To1.0.cs │ ├── UpgradeShardMapManagerLocalFrom1.0To1.1.cs │ ├── UpgradeShardMapManagerLocalFrom1.1To1.2.cs │ └── UpgradeShardMapManagerLocalFrom1000.0To1000.1.cs │ ├── Shard │ ├── BaseMappingUpdate.cs │ ├── IMappingInfoProvider.cs │ ├── IMappingUpdate.cs │ ├── IShardProvider.cs │ ├── LookupOptions.cs │ ├── MappingLockToken.cs │ ├── MappingStatus.cs │ ├── PointMapping.cs │ ├── PointMappingUpdate.cs │ ├── Range.cs │ ├── RangeMapping.cs │ ├── RangeMappingUpdate.cs │ ├── Shard.cs │ ├── ShardKey.cs │ ├── ShardKeyType.cs │ ├── ShardLocation.cs │ ├── ShardRange.cs │ ├── ShardStatus.cs │ ├── ShardUpdate.cs │ └── ValidationUtils.cs │ ├── ShardMap │ ├── ListShardMap.cs │ ├── RangeShardMap.cs │ ├── ShardMap.cs │ ├── ShardMapExtensions.cs │ ├── ShardMapType.cs │ └── ShardMapUtils.cs │ ├── ShardMapManager.csproj.vspscc │ ├── ShardMapManager │ ├── ShardManagementException.cs │ ├── ShardManagementTransientErrorDetectionStrategy.cs │ ├── ShardMapManager.cs │ └── ShardMapManagerFactory.cs │ ├── ShardMapper │ ├── BaseShardMapper.cs │ ├── DefaultShardMapper.cs │ ├── HashShardMapper.cs │ ├── IShardMapper.cs │ ├── ListShardMapper.cs │ └── RangeShardMapper.cs │ ├── SqlStore │ ├── SqlConnectionInfo.cs │ ├── SqlLocation.cs │ ├── SqlLogEntry.cs │ ├── SqlMapping.cs │ ├── SqlResults.cs │ ├── SqlSchemaInfo.cs │ ├── SqlShard.cs │ ├── SqlShardMap.cs │ ├── SqlShardMapManagerCredentials.cs │ ├── SqlStoreConnection.cs │ ├── SqlStoreConnectionFactory.cs │ ├── SqlStoreTransactionScope.cs │ └── SqlUserStoreConnection.cs │ ├── Store │ ├── DefaultStoreMapping.cs │ ├── DefaultStoreSchemaInfo.cs │ ├── DefaultStoreShard.cs │ ├── DefaultStoreShardMap.cs │ ├── IStoreConnection.cs │ ├── IStoreConnectionFactory.cs │ ├── IStoreLocation.cs │ ├── IStoreLogEntry.cs │ ├── IStoreMapping.cs │ ├── IStoreResults.cs │ ├── IStoreSchemaInfo.cs │ ├── IStoreShard.cs │ ├── IStoreShardMap.cs │ ├── IStoreTransactionScope.cs │ ├── IStoreVersion.cs │ ├── IUserStoreConnection.cs │ ├── SqlVersion.cs │ └── StoreException.cs │ ├── StoreOperations │ ├── Base │ │ ├── IStoreOperation.cs │ │ ├── IStoreOperationFactory.cs │ │ ├── IStoreOperationGlobal.cs │ │ ├── IStoreOperationLocal.cs │ │ ├── StoreConnectionInfo.cs │ │ ├── StoreObjectFormatterXml.cs │ │ ├── StoreOperation.cs │ │ ├── StoreOperationCode.cs │ │ ├── StoreOperationErrorHandler.cs │ │ ├── StoreOperationFactory.cs │ │ ├── StoreOperationGlobal.cs │ │ ├── StoreOperationLocal.cs │ │ ├── StoreOperationRequestBuilder.cs │ │ ├── StoreOperationState.cs │ │ └── StoreOperationTransactionScopeKind.cs │ ├── Recovery │ │ ├── AttachShardOperation.cs │ │ ├── CheckShardLocalOperation.cs │ │ ├── DetachShardGlobalOperation.cs │ │ ├── GetMappingsByRangeLocalOperation.cs │ │ ├── GetShardsLocalOperation.cs │ │ ├── ReplaceMappingsGlobalOperation.cs │ │ └── ReplaceMappingsLocalOperation.cs │ ├── SchemaInformation │ │ ├── AddShardingSchemaInfoGlobalOperation.cs │ │ ├── FindShardingSchemaInfoGlobalOperation.cs │ │ ├── GetShardingSchemaInfosGlobalOperation.cs │ │ ├── RemoveShardingSchemaInfoGlobalOperation.cs │ │ └── UpdateShardingSchemaInfoGlobalOperation.cs │ ├── ShardMap │ │ ├── AddShardOperation.cs │ │ ├── FindShardByLocationGlobalOperation.cs │ │ ├── GetShardsGlobalOperation.cs │ │ ├── RemoveShardOperation.cs │ │ └── UpdateShardOperation.cs │ ├── ShardMapManager │ │ ├── AddShardMapGlobalOperation.cs │ │ ├── FindShardMapByNameGlobalOperation.cs │ │ ├── GetDistinctShardLocationsGlobalOperation.cs │ │ ├── GetShardMapsGlobalOperation.cs │ │ ├── LoadShardMapManagerGlobalOperation.cs │ │ └── RemoveShardMapGlobalOperation.cs │ ├── ShardMapManagerFactory │ │ ├── CreateShardMapManagerGlobalOperation.cs │ │ └── GetShardMapManagerGlobalOperation.cs │ ├── ShardMapper │ │ ├── AddMappingOperation.cs │ │ ├── FindMappingByIdGlobalOperation.cs │ │ ├── FindMappingByKeyGlobalOperation.cs │ │ ├── GetMappingsByRangeGlobalOperation.cs │ │ ├── LockOrUnLockMappingsGlobalOperation.cs │ │ ├── RemoveMappingOperation.cs │ │ ├── ReplaceMappingsOperation.cs │ │ └── UpdateMappingOperation.cs │ └── Upgrade │ │ ├── UpgradeStoreGlobalOperation.cs │ │ └── UpgradeStoreLocalOperation.cs │ └── Utils │ ├── ExceptionUtils.cs │ ├── GlobalConstants.cs │ ├── ICloneable.cs │ ├── ReflectionUtils.cs │ ├── SqlUtils.cs │ ├── StringUtils.cs │ ├── TimerUtils.cs │ └── ValueLock.cs ├── Test ├── ElasticScale.ClientTestCommon │ ├── AssertExtensions.cs │ ├── CommonTestUtils.cs │ ├── Microsoft.Azure.SqlDatabase.ElasticScale.ClientTestCommon.csproj │ ├── Properties │ │ └── AssemblyInfo.cs │ └── SqlAuthenticationLogin.cs ├── ElasticScale.Query.UnitTests │ ├── DataSetExtensions.cs │ ├── EnumerableHelpers.cs │ ├── Microsoft.Azure.SqlDatabase.ElasticScale.Query.UnitTests.csproj │ ├── Microsoft.Azure.SqlDatabase.ElasticScale.Query.UnitTests.csproj.user │ ├── MockSqlCommand.cs │ ├── MockSqlConnection.cs │ ├── MockSqlDataReader.cs │ ├── MultiShardConnectionTests.cs │ ├── MultiShardDataReaderTests.cs │ ├── MultiShardQueryE2ETests.cs │ ├── MultiShardTestCaseColumn.cs │ ├── MultiShardTestUtils.cs │ ├── MultiShardUnitTests.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── ProxyServer.cs ├── ElasticScale.ShardManagement.LoadTests │ ├── ElasticScale.ShardManagement.LoadTests.csproj │ ├── Microsoft.VisualStudio.QualityTools.Common.xml │ ├── Properties │ │ └── AssemblyInfo.cs │ └── SmmLoadTest.loadtest └── ElasticScale.ShardManagement.UnitTests │ ├── DateTimeShardMapperTests.cs │ ├── Decorators │ ├── CacheStoreDecorator.cs │ ├── CountingCacheStore.cs │ └── StoreOperationDecorator.cs │ ├── Globals.cs │ ├── Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.UnitTests.csproj │ ├── Properties │ └── AssemblyInfo.cs │ ├── RecoveryManagerTests.cs │ ├── ScenarioTests.cs │ ├── SchemaInfoCollectionTests.cs │ ├── ShardKeyInfo.cs │ ├── ShardKeyTests.cs │ ├── ShardKeyTypeInfo.cs │ ├── ShardMapFaultHandlingTests.cs │ ├── ShardMapManagerConcurrencyTests.cs │ ├── ShardMapManagerFactoryTests.cs │ ├── ShardMapManagerLoadTests.cs │ ├── ShardMapManagerTests.cs │ ├── ShardMapManagerUnitTests.csproj.vspscc │ ├── ShardMapManagerUpgradeTests.cs │ ├── ShardMapTests.cs │ ├── ShardMapperTests.cs │ ├── ShardRangeTests.cs │ ├── Stubs │ ├── IStubBehavior.cs │ ├── StubAddMappingOperation.cs │ ├── StubAddShardOperation.cs │ ├── StubBehaviors.cs │ ├── StubCacheStore.cs │ ├── StubFindMappingByKeyGlobalOperation.cs │ ├── StubICacheStoreMapping.cs │ ├── StubRemoveMappingOperation.cs │ ├── StubRemoveShardOperation.cs │ ├── StubReplaceMappingsOperation.cs │ ├── StubSqlStoreConnectionFactory.cs │ ├── StubStoreOperationFactory.cs │ ├── StubUpdateMappingOperation.cs │ └── StubUpdateShardOperation.cs │ ├── TestShardMap.cs │ └── TestShardMapVerifier.cs ├── azure-pipelines.yml ├── build.props ├── elastic-db-tools.publickey ├── elastic-db-tools.snk └── strongname.props /.gitignore: -------------------------------------------------------------------------------- 1 | # Nuget restore 2 | packages 3 | project.lock.json 4 | 5 | # Build folders 6 | bin 7 | FakesAssemblies 8 | obj 9 | 10 | # Other misc build output 11 | msbuild.log 12 | Src/Microsoft.Azure.SqlDatabase.ElasticScale.Client.xml 13 | 14 | # Test output 15 | TestResults 16 | 17 | # Tools files 18 | *.sln.DotSettings.user 19 | 20 | # Temporary tools files 21 | *.GhostDoc.xml 22 | *.suo 23 | *.pd_ 24 | 25 | # Visual studio 26 | .vs/ 27 | .vscode/ 28 | 29 | # Build output 30 | *.dll 31 | *.exe 32 | -------------------------------------------------------------------------------- /Documentation/Branching Guidance.md: -------------------------------------------------------------------------------- 1 | Branching Guide 2 | =============== 3 | 4 | We will have the following branches in the repository: 5 | 6 | * **master** 7 | * Where most development happens 8 | * Submit all your PRs here 9 | 10 | * **release/[name]** 11 | * Release branches snapped from master. 12 | * Do not submit pull requests to these branches 13 | * Fixes here do not flow to follow-up releases 14 | * Generally, fixes after a snap needing to make it in to a release will go in to master and get cherry-picked to the release branch. 15 | 16 | * **dev/[name]** 17 | * Features (aka topics) under active development by more than one developer. 18 | * Submit PRs here only if you've made prior arrangements to work on something in one of these branches. 19 | * It is up to the developers creating these branches to decide what level of review is required 20 | * These features will only ship if they are successfully pulled to master or future via the standard PR and API review process. 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Microsoft 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Elastic database tools for Azure SQL Database 2 | Elastic database tools client library allows ADO.NET developers to create applications that implement and use the pattern known as database sharding in Azure SQL Database. Learn more at http://azure.microsoft.com/en-us/documentation/learning-paths/sql-database-elastic-scale/ . 3 | 4 | To get started on contributing, take a look at [issues that are up-for-grabs](https://github.com/Azure/elastic-db-tools/labels/Up%20For%20Grabs). 5 | 6 | - [Issue Guidance](https://github.com/Microsoft/Elastic-database-client-library-for-Azure-SQL-Database/blob/master/Documentation/Issue%20Guidance.md) 7 | - [Branching Guidance](https://github.com/Microsoft/Elastic-database-client-library-for-Azure-SQL-Database/blob/master/Documentation/Branching%20Guidance.md) 8 | - [Contribution Guidance](https://github.com/Microsoft/Elastic-database-client-library-for-Azure-SQL-Database/blob/master/Documentation/Contribution%20Guidance.md) 9 | 10 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 11 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /Samples/CodeAnalysis.Samples.ruleset: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Samples/Dapper/Blog.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace ElasticDapper 5 | { 6 | // Let's use the standard blogging class 7 | public class Blog 8 | { 9 | public long BlogId { get; set; } 10 | 11 | public string Name { get; set; } 12 | 13 | public string Url { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Samples/Dapper/ElasticDapper.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0;net8.0 4 | Exe 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Samples/Dapper/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Microsoft 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Samples/Dapper/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Runtime.InteropServices; 5 | 6 | // Setting ComVisible to false makes the types in this assembly not visible 7 | // to COM components. If you need to access a type in this assembly from 8 | // COM, set the ComVisible attribute to true on that type. 9 | [assembly: ComVisible(false)] 10 | 11 | // The following GUID is for the ID of the typelib if this project is exposed to COM 12 | [assembly: Guid("1e1f1152-0ac3-4631-b801-33bd9ec84fa9")] 13 | -------------------------------------------------------------------------------- /Samples/Dapper/Sharding.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement; 5 | using Microsoft.Data.SqlClient; 6 | 7 | namespace ElasticDapper 8 | { 9 | internal class Sharding 10 | { 11 | public ShardMapManager ShardMapManager { get; private set; } 12 | 13 | public ListShardMap ShardMap { get; private set; } 14 | 15 | // Bootstrap Elastic Scale by creating a new shard map manager and a shard map on 16 | // the shard map manager database if necessary. 17 | public Sharding(string smmserver, string smmdatabase, string smmconnstr) 18 | { 19 | // Connection string with administrative credentials for the root database 20 | SqlConnectionStringBuilder connStrBldr = new SqlConnectionStringBuilder(smmconnstr); 21 | connStrBldr.DataSource = smmserver; 22 | connStrBldr.InitialCatalog = smmdatabase; 23 | 24 | // Deploy shard map manager. 25 | ShardMapManager smm; 26 | if (!ShardMapManagerFactory.TryGetSqlShardMapManager(connStrBldr.ConnectionString, ShardMapManagerLoadPolicy.Lazy, out smm)) 27 | { 28 | ShardMapManager = ShardMapManagerFactory.CreateSqlShardMapManager(connStrBldr.ConnectionString); 29 | } 30 | else 31 | { 32 | ShardMapManager = smm; 33 | } 34 | 35 | ListShardMap sm; 36 | if (!ShardMapManager.TryGetListShardMap("ElasticScaleWithDapper", out sm)) 37 | { 38 | ShardMap = ShardMapManager.CreateListShardMap("ElasticScaleWithDapper"); 39 | } 40 | else 41 | { 42 | ShardMap = sm; 43 | } 44 | } 45 | 46 | // Enter a new shard - i.e. an empty database - to the shard map, allocate a first tenant to it 47 | public void RegisterNewShard(string server, string database, int key) 48 | { 49 | Shard shard; 50 | ShardLocation shardLocation = new ShardLocation(server, database); 51 | 52 | if (!ShardMap.TryGetShard(shardLocation, out shard)) 53 | { 54 | shard = ShardMap.CreateShard(shardLocation); 55 | } 56 | 57 | // Register the mapping of the tenant to the shard in the shard map. 58 | // After this step, DDR on the shard map can be used 59 | PointMapping mapping; 60 | if (!ShardMap.TryGetMappingForKey(key, out mapping)) 61 | { 62 | ShardMap.CreatePointMapping(key, shard); 63 | } 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Samples/EFCodeFirst/DataClasses.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | 7 | namespace EFCodeFirstElasticScale 8 | { 9 | // Let's use the standard blogging classes from the EF tutorial 10 | public class Blog 11 | { 12 | public int BlogId { get; set; } 13 | 14 | public string Name { get; set; } 15 | 16 | public string Url { get; set; } 17 | 18 | public virtual List Posts { get; set; } 19 | } 20 | 21 | public class Post 22 | { 23 | public int PostId { get; set; } 24 | 25 | public string Title { get; set; } 26 | 27 | public string Content { get; set; } 28 | 29 | public int BlogId { get; set; } 30 | 31 | public virtual Blog Blog { get; set; } 32 | } 33 | 34 | public class User 35 | { 36 | [Key] 37 | public string UserName { get; set; } 38 | 39 | public string DisplayName { get; set; } 40 | } 41 | } -------------------------------------------------------------------------------- /Samples/EFCodeFirst/ElasticScaleDbConfiguration.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Configuration; 5 | using System.Data.Entity; 6 | using System.Data.Entity.Infrastructure; 7 | 8 | namespace EFCodeFirstElasticScale 9 | { 10 | public class ElasticScaleDbConfiguration : DbConfiguration 11 | { 12 | public ElasticScaleDbConfiguration() 13 | { 14 | // This sets the execution strategy so that transient faults are handled 15 | // by the Transient Fault Handling Block. We are not using the default 16 | // execution strategy for SQL Server here as its exceptions encourage to use 17 | // the SqlAzureExecutionStrategy which would lead to wrong retry behavior 18 | // since it would not use the OpenConnectionForKey call. 19 | // For more details, see http://msdn.microsoft.com/en-us/data/dn456835.aspx. 20 | this.SetExecutionStrategy("System.Data.SqlClient", () => new DefaultExecutionStrategy()); 21 | 22 | // There are legitimate cases, typically for migrations during development 23 | // using Add-Migration and Update-Datase, where a connection to a 24 | // development database is needed. 25 | // 26 | // Usually, that would go through the DbContext default c'tor. However, 27 | // we limited calls to DbContext to just data dependent routing. This DbConfig 28 | // gives EF the opportunity to still bootstrap connections for those cases. 29 | // EF then finds and invokes the following c'tor when needed. 30 | // For more information on DbConfiguration, see http://msdn.microsoft.com/en-us/data/jj680699.aspx. 31 | this.SetContextFactory>(() => 32 | { 33 | string connStr = ConfigurationManager.ConnectionStrings["DevelopmentDatabase"].ConnectionString; 34 | return new ElasticScaleContext(connStr); 35 | }); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /Samples/EFCodeFirst/EntityFrameworkCodeFirst.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net6.0;net8.0 4 | Exe 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Samples/EFCodeFirst/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Microsoft 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Samples/EFCodeFirst/Migrations/201405280437372_InitialCreate.Designer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | // 5 | 6 | namespace EFCodeFirstElasticScale.Migrations 7 | { 8 | using System.CodeDom.Compiler; 9 | using System.Data.Entity.Migrations; 10 | using System.Data.Entity.Migrations.Infrastructure; 11 | using System.Resources; 12 | 13 | [GeneratedCode("EntityFramework.Migrations", "6.1.0-30225")] 14 | public sealed partial class InitialCreate : IMigrationMetadata 15 | { 16 | private readonly ResourceManager Resources = new ResourceManager(typeof(InitialCreate)); 17 | 18 | string IMigrationMetadata.Id 19 | { 20 | get { return "201405280437372_InitialCreate"; } 21 | } 22 | 23 | string IMigrationMetadata.Source 24 | { 25 | get { return null; } 26 | } 27 | 28 | string IMigrationMetadata.Target 29 | { 30 | get { return Resources.GetString("Target"); } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Samples/EFCodeFirst/Migrations/201405280437372_InitialCreate.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | // 5 | 6 | namespace EFCodeFirstElasticScale.Migrations 7 | { 8 | using System; 9 | using System.Data.Entity.Migrations; 10 | 11 | public partial class InitialCreate : DbMigration 12 | { 13 | public override void Up() 14 | { 15 | CreateTable( 16 | "dbo.Blogs", 17 | c => new 18 | { 19 | BlogId = c.Int(nullable: false, identity: true), 20 | Name = c.String(), 21 | }) 22 | .PrimaryKey(t => t.BlogId); 23 | 24 | CreateTable( 25 | "dbo.Posts", 26 | c => new 27 | { 28 | PostId = c.Int(nullable: false, identity: true), 29 | Title = c.String(), 30 | Content = c.String(), 31 | BlogId = c.Int(nullable: false), 32 | }) 33 | .PrimaryKey(t => t.PostId) 34 | .ForeignKey("dbo.Blogs", t => t.BlogId, cascadeDelete: true) 35 | .Index(t => t.BlogId); 36 | } 37 | 38 | public override void Down() 39 | { 40 | DropForeignKey("dbo.Posts", "BlogId", "dbo.Blogs"); 41 | DropIndex("dbo.Posts", new[] { "BlogId" }); 42 | DropTable("dbo.Posts"); 43 | DropTable("dbo.Blogs"); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Samples/EFCodeFirst/Migrations/201405280633219_AddUrl.Designer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | // 5 | 6 | namespace EFCodeFirstElasticScale.Migrations 7 | { 8 | using System.CodeDom.Compiler; 9 | using System.Data.Entity.Migrations; 10 | using System.Data.Entity.Migrations.Infrastructure; 11 | using System.Resources; 12 | 13 | [GeneratedCode("EntityFramework.Migrations", "6.1.0-30225")] 14 | public sealed partial class AddUrl : IMigrationMetadata 15 | { 16 | private readonly ResourceManager Resources = new ResourceManager(typeof(AddUrl)); 17 | 18 | string IMigrationMetadata.Id 19 | { 20 | get { return "201405280633219_AddUrl"; } 21 | } 22 | 23 | string IMigrationMetadata.Source 24 | { 25 | get { return null; } 26 | } 27 | 28 | string IMigrationMetadata.Target 29 | { 30 | get { return Resources.GetString("Target"); } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Samples/EFCodeFirst/Migrations/201405280633219_AddUrl.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | // 5 | 6 | namespace EFCodeFirstElasticScale.Migrations 7 | { 8 | using System; 9 | using System.Data.Entity.Migrations; 10 | 11 | public partial class AddUrl : DbMigration 12 | { 13 | public override void Up() 14 | { 15 | AddColumn("dbo.Blogs", "Url", c => c.String()); 16 | } 17 | 18 | public override void Down() 19 | { 20 | DropColumn("dbo.Blogs", "Url"); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Samples/EFCodeFirst/Migrations/201405280638095_AddUser.Designer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | // 5 | 6 | namespace EFCodeFirstElasticScale.Migrations 7 | { 8 | using System.CodeDom.Compiler; 9 | using System.Data.Entity.Migrations; 10 | using System.Data.Entity.Migrations.Infrastructure; 11 | using System.Resources; 12 | 13 | [GeneratedCode("EntityFramework.Migrations", "6.1.0-30225")] 14 | public sealed partial class AddUser : IMigrationMetadata 15 | { 16 | private readonly ResourceManager Resources = new ResourceManager(typeof(AddUser)); 17 | 18 | string IMigrationMetadata.Id 19 | { 20 | get { return "201405280638095_AddUser"; } 21 | } 22 | 23 | string IMigrationMetadata.Source 24 | { 25 | get { return null; } 26 | } 27 | 28 | string IMigrationMetadata.Target 29 | { 30 | get { return Resources.GetString("Target"); } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Samples/EFCodeFirst/Migrations/201405280638095_AddUser.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | // 5 | 6 | namespace EFCodeFirstElasticScale.Migrations 7 | { 8 | using System; 9 | using System.Data.Entity.Migrations; 10 | 11 | public partial class AddUser : DbMigration 12 | { 13 | public override void Up() 14 | { 15 | CreateTable( 16 | "dbo.Users", 17 | c => new 18 | { 19 | UserName = c.String(nullable: false, maxLength: 128), 20 | DisplayName = c.String(), 21 | }) 22 | .PrimaryKey(t => t.UserName); 23 | } 24 | 25 | public override void Down() 26 | { 27 | DropTable("dbo.Users"); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Samples/EFCodeFirst/Migrations/201405280640127_ChangeDisplayName.Designer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | // 5 | 6 | namespace EFCodeFirstElasticScale.Migrations 7 | { 8 | using System.CodeDom.Compiler; 9 | using System.Data.Entity.Migrations; 10 | using System.Data.Entity.Migrations.Infrastructure; 11 | using System.Resources; 12 | 13 | [GeneratedCode("EntityFramework.Migrations", "6.1.0-30225")] 14 | public sealed partial class ChangeDisplayName : IMigrationMetadata 15 | { 16 | private readonly ResourceManager Resources = new ResourceManager(typeof(ChangeDisplayName)); 17 | 18 | string IMigrationMetadata.Id 19 | { 20 | get { return "201405280640127_ChangeDisplayName"; } 21 | } 22 | 23 | string IMigrationMetadata.Source 24 | { 25 | get { return null; } 26 | } 27 | 28 | string IMigrationMetadata.Target 29 | { 30 | get { return Resources.GetString("Target"); } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Samples/EFCodeFirst/Migrations/201405280640127_ChangeDisplayName.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | // 5 | 6 | namespace EFCodeFirstElasticScale.Migrations 7 | { 8 | using System; 9 | using System.Data.Entity.Migrations; 10 | 11 | public partial class ChangeDisplayName : DbMigration 12 | { 13 | public override void Up() 14 | { 15 | RenameColumn(table: "dbo.Users", name: "DisplayName", newName: "display_name"); 16 | } 17 | 18 | public override void Down() 19 | { 20 | RenameColumn(table: "dbo.Users", name: "display_name", newName: "DisplayName"); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Samples/EFCodeFirst/Migrations/Configuration.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Data.Entity.Migrations; 5 | 6 | namespace EFCodeFirstElasticScale.Migrations 7 | { 8 | internal sealed class Configuration : DbMigrationsConfiguration> 9 | { 10 | public Configuration() 11 | { 12 | this.AutomaticMigrationsEnabled = false; 13 | this.ContextKey = "CodeFirstNewDatabaseSample.BloggingContext"; 14 | } 15 | 16 | protected override void Seed(EFCodeFirstElasticScale.ElasticScaleContext context) 17 | { 18 | // This method will be called after migrating to the latest version. 19 | 20 | // You can use the DbSet.AddOrUpdate() helper extension method 21 | // to avoid creating duplicate seed data. E.g. 22 | // 23 | // context.People.AddOrUpdate( 24 | // p => p.FullName, 25 | // new Person { FullName = "Andrew Peters" }, 26 | // new Person { FullName = "Brice Lambson" }, 27 | // new Person { FullName = "Rowan Miller" } 28 | // ); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Samples/EFCodeFirst/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Runtime.InteropServices; 5 | 6 | // Setting ComVisible to false makes the types in this assembly not visible 7 | // to COM components. If you need to access a type in this assembly from 8 | // COM, set the ComVisible attribute to true on that type. 9 | [assembly: ComVisible(false)] 10 | 11 | // The following GUID is for the ID of the typelib if this project is exposed to COM 12 | [assembly: Guid("1e1f1152-0ac3-4631-b801-33bd9ec84fa9")] 13 | -------------------------------------------------------------------------------- /Samples/EFCodeFirst/SqlDatabaseUtils.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling; 6 | 7 | namespace EFCodeFirstElasticScale 8 | { 9 | /// 10 | /// Helper methods for interacting with SQL Databases. 11 | /// 12 | internal static class SqlDatabaseUtils 13 | { 14 | /// 15 | /// Gets the retry policy to use for connections to SQL Server. 16 | /// 17 | public static RetryPolicy SqlRetryPolicy 18 | { 19 | get { return new RetryPolicy(10, TimeSpan.FromSeconds(5)); } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Samples/EFCodeFirst/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "DevelopmentDatabase": "Data Source=(localdb)\\v11.0;Initial Catalog=elasticscaledev;Integrated Security=True" 4 | } 5 | } -------------------------------------------------------------------------------- /Samples/EFMultiTenant/ApplySqlToShards.ps1: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft. All rights reserved. 2 | # Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | # Params you must supply 5 | $server = '[YourSQLServerName]' 6 | $shardmapmgr = '[YourShardMapManagerDatabaseName]' 7 | $username = '[YourUserName]' 8 | $password = '[YourPassword]' 9 | $sqlfile = 'EnableRLS.sql' 10 | 11 | # Get shards and execute sqlfile 12 | $sqldir = Split-Path -Parent $MyInvocation.MyCommand.Path 13 | $sqlpath = Join-Path -Path $sqldir -ChildPath $sqlfile 14 | $query = "SELECT ServerName, DatabaseName FROM __ShardManagement.ShardsGlobal;" 15 | 16 | $shards = Invoke-Sqlcmd -Query $query -ServerInstance $server -Database $shardmapmgr -Username $username -Password $password 17 | 18 | foreach ($shard in $shards) { 19 | # Assume all shards have same username/password as shard map manager 20 | "Executing... " + $shard["DatabaseName"] 21 | Invoke-Sqlcmd -InputFile $sqlpath -ServerInstance $shard["ServerName"] -Database $shard["DatabaseName"] -Username $username -Password $password 22 | } -------------------------------------------------------------------------------- /Samples/EFMultiTenant/DataClasses.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | 7 | namespace EFMultiTenantElasticScale 8 | { 9 | // Let's use the standard blogging classes from the EF tutorial 10 | public class Blog 11 | { 12 | public int BlogId { get; set; } 13 | 14 | public string Name { get; set; } 15 | 16 | public string Url { get; set; } 17 | 18 | public virtual List Posts { get; set; } 19 | 20 | // All tables must have a TenantId to indicate which tenant owns each row. 21 | // Note: you should REMOVE TenantId from the EF data model (but not the underlying database tables) 22 | // if you plan to use default constraints, otherwise EF will automatically supply a default value 23 | public int TenantId { get; set; } 24 | } 25 | 26 | public class Post 27 | { 28 | public int PostId { get; set; } 29 | 30 | public string Title { get; set; } 31 | 32 | public string Content { get; set; } 33 | 34 | public int BlogId { get; set; } 35 | 36 | public virtual Blog Blog { get; set; } 37 | 38 | public int TenantId { get; set; } // same as TenantId in Blogs 39 | } 40 | 41 | public class User 42 | { 43 | [Key] 44 | public string UserName { get; set; } 45 | 46 | public string DisplayName { get; set; } 47 | } 48 | } -------------------------------------------------------------------------------- /Samples/EFMultiTenant/ElasticScaleDbConfiguration.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Configuration; 5 | using System.Data.Entity; 6 | using System.Data.Entity.Infrastructure; 7 | 8 | namespace EFMultiTenantElasticScale 9 | { 10 | public class ElasticScaleDbConfiguration : DbConfiguration 11 | { 12 | public ElasticScaleDbConfiguration() 13 | { 14 | // This sets the execution strategy so that transient faults are handled 15 | // by the Transient Fault Handling Block. We are not using the default 16 | // execution strategy for SQL Server here as its exceptions encourage to use 17 | // the SqlAzureExecutionStrategy which would lead to wrong retry behavior 18 | // since it would not use the OpenConnectionForKey call. 19 | // For more details, see http://msdn.microsoft.com/en-us/data/dn456835.aspx. 20 | this.SetExecutionStrategy("System.Data.SqlClient", () => new DefaultExecutionStrategy()); 21 | 22 | // There are legitimate cases, typically for migrations during development 23 | // using Add-Migration and Update-Datase, where a connection to a 24 | // development database is needed. 25 | // 26 | // Usually, that would go through the DbContext default c'tor. However, 27 | // we limited calls to DbContext to just data dependent routing. This DbConfig 28 | // gives EF the opportunity to still bootstrap connections for those cases. 29 | // EF then finds and invokes the following c'tor when needed. 30 | // For more information on DbConfiguration, see http://msdn.microsoft.com/en-us/data/jj680699.aspx. 31 | this.SetContextFactory>(() => 32 | { 33 | string connStr = ConfigurationManager.ConnectionStrings["DevelopmentDatabase"].ConnectionString; 34 | return new ElasticScaleContext(connStr); 35 | }); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /Samples/EFMultiTenant/EnableRLS.sql: -------------------------------------------------------------------------------- 1 | -- Copyright (c) Microsoft. All rights reserved. 2 | -- Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | -- Enable RLS 5 | CREATE SCHEMA rls -- separate schema to organize RLS objects 6 | GO 7 | 8 | CREATE FUNCTION rls.fn_tenantAccessPredicate(@TenantId int) 9 | RETURNS TABLE 10 | WITH SCHEMABINDING 11 | AS 12 | RETURN SELECT 1 AS fn_accessResult 13 | WHERE DATABASE_PRINCIPAL_ID() = DATABASE_PRINCIPAL_ID('dbo') -- the user in your application’s connection string (dbo is only for demo purposes!) 14 | AND CAST(SESSION_CONTEXT(N'TenantId') AS int) = @TenantId 15 | GO 16 | 17 | CREATE SECURITY POLICY rls.tenantAccessPolicy 18 | ADD FILTER PREDICATE rls.fn_tenantAccessPredicate(TenantId) ON dbo.Blogs, 19 | ADD BLOCK PREDICATE rls.fn_tenantAccessPredicate(TenantId) ON dbo.Blogs, 20 | ADD FILTER PREDICATE rls.fn_tenantAccessPredicate(TenantId) ON dbo.Posts, 21 | ADD BLOCK PREDICATE rls.fn_tenantAccessPredicate(TenantId) ON dbo.Posts 22 | GO 23 | 24 | -- Default constraint example 25 | -- Note: You should remove TenantId from the Entity Framework data model (DataClasses.cs) 26 | -- before creating default constraints to prevent EF from automatically supplying default values 27 | --ALTER TABLE Blogs 28 | -- ADD CONSTRAINT df_TenantId_Blogs 29 | -- DEFAULT CAST(SESSION_CONTEXT(N'TenantId') AS int) FOR TenantId 30 | --GO 31 | --ALTER TABLE Posts 32 | -- ADD CONSTRAINT df_TenantId_Posts 33 | -- DEFAULT CAST(SESSION_CONTEXT(N'TenantId') AS int) FOR TenantId 34 | --GO 35 | 36 | -- Example of altering the security policy to allow a "superuser" to access all rows 37 | -- Note: You should create a new function with the new logic, and then "swap" it out with 38 | -- the existing predicates on the Blogs and Posts tables 39 | --CREATE FUNCTION rls.fn_tenantAccessPredicateWithSuperUser(@TenantId int) 40 | -- RETURNS TABLE 41 | -- WITH SCHEMABINDING 42 | --AS 43 | -- RETURN SELECT 1 AS fn_accessResult 44 | -- WHERE 45 | -- ( 46 | -- DATABASE_PRINCIPAL_ID() = DATABASE_PRINCIPAL_ID('dbo') -- note, should not be dbo! 47 | -- AND CAST(SESSION_CONTEXT(N'TenantId') AS int) = @TenantId 48 | -- ) 49 | -- OR 50 | -- ( 51 | -- DATABASE_PRINCIPAL_ID() = DATABASE_PRINCIPAL_ID('superuser') 52 | -- ) 53 | --GO 54 | 55 | --ALTER SECURITY POLICY rls.tenantAccessPolicy 56 | -- ALTER FILTER PREDICATE rls.fn_tenantAccessPredicateWithSuperUser(TenantId) ON dbo.Blogs, 57 | -- ALTER BLOCK PREDICATE rls.fn_tenantAccessPredicateWithSuperUser(TenantId) ON dbo.Blogs, 58 | -- ALTER FILTER PREDICATE rls.fn_tenantAccessPredicateWithSuperUser(TenantId) ON dbo.Posts, 59 | -- ALTER BLOCK PREDICATE rls.fn_tenantAccessPredicateWithSuperUser(TenantId) ON dbo.Posts 60 | --GO -------------------------------------------------------------------------------- /Samples/EFMultiTenant/EntityFrameworkMultiTenant.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net6.0;net8.0 4 | Exe 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Samples/EFMultiTenant/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Microsoft 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Samples/EFMultiTenant/Migrations/201405280437372_InitialCreate.Designer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | // 5 | 6 | namespace EFMultiTenantElasticScale.Migrations 7 | { 8 | using System.CodeDom.Compiler; 9 | using System.Data.Entity.Migrations; 10 | using System.Data.Entity.Migrations.Infrastructure; 11 | using System.Resources; 12 | 13 | [GeneratedCode("EntityFramework.Migrations", "6.1.0-30225")] 14 | public sealed partial class InitialCreate : IMigrationMetadata 15 | { 16 | private readonly ResourceManager Resources = new ResourceManager(typeof(InitialCreate)); 17 | 18 | string IMigrationMetadata.Id 19 | { 20 | get { return "201405280437372_InitialCreate"; } 21 | } 22 | 23 | string IMigrationMetadata.Source 24 | { 25 | get { return null; } 26 | } 27 | 28 | string IMigrationMetadata.Target 29 | { 30 | get { return Resources.GetString("Target"); } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Samples/EFMultiTenant/Migrations/201405280437372_InitialCreate.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | // 5 | 6 | namespace EFMultiTenantElasticScale.Migrations 7 | { 8 | using System; 9 | using System.Data.Entity.Migrations; 10 | 11 | public partial class InitialCreate : DbMigration 12 | { 13 | public override void Up() 14 | { 15 | CreateTable( 16 | "dbo.Blogs", 17 | c => new 18 | { 19 | BlogId = c.Int(nullable: false, identity: true), 20 | Name = c.String(), 21 | }) 22 | .PrimaryKey(t => t.BlogId); 23 | 24 | CreateTable( 25 | "dbo.Posts", 26 | c => new 27 | { 28 | PostId = c.Int(nullable: false, identity: true), 29 | Title = c.String(), 30 | Content = c.String(), 31 | BlogId = c.Int(nullable: false), 32 | }) 33 | .PrimaryKey(t => t.PostId) 34 | .ForeignKey("dbo.Blogs", t => t.BlogId, cascadeDelete: true) 35 | .Index(t => t.BlogId); 36 | } 37 | 38 | public override void Down() 39 | { 40 | DropForeignKey("dbo.Posts", "BlogId", "dbo.Blogs"); 41 | DropIndex("dbo.Posts", new[] { "BlogId" }); 42 | DropTable("dbo.Posts"); 43 | DropTable("dbo.Blogs"); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Samples/EFMultiTenant/Migrations/201405280633219_AddUrl.Designer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | // 5 | 6 | namespace EFMultiTenantElasticScale.Migrations 7 | { 8 | using System.CodeDom.Compiler; 9 | using System.Data.Entity.Migrations; 10 | using System.Data.Entity.Migrations.Infrastructure; 11 | using System.Resources; 12 | 13 | [GeneratedCode("EntityFramework.Migrations", "6.1.0-30225")] 14 | public sealed partial class AddUrl : IMigrationMetadata 15 | { 16 | private readonly ResourceManager Resources = new ResourceManager(typeof(AddUrl)); 17 | 18 | string IMigrationMetadata.Id 19 | { 20 | get { return "201405280633219_AddUrl"; } 21 | } 22 | 23 | string IMigrationMetadata.Source 24 | { 25 | get { return null; } 26 | } 27 | 28 | string IMigrationMetadata.Target 29 | { 30 | get { return Resources.GetString("Target"); } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Samples/EFMultiTenant/Migrations/201405280633219_AddUrl.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | // 5 | 6 | namespace EFMultiTenantElasticScale.Migrations 7 | { 8 | using System; 9 | using System.Data.Entity.Migrations; 10 | 11 | public partial class AddUrl : DbMigration 12 | { 13 | public override void Up() 14 | { 15 | AddColumn("dbo.Blogs", "Url", c => c.String()); 16 | } 17 | 18 | public override void Down() 19 | { 20 | DropColumn("dbo.Blogs", "Url"); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Samples/EFMultiTenant/Migrations/201405280638095_AddUser.Designer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | // 5 | 6 | namespace EFMultiTenantElasticScale.Migrations 7 | { 8 | using System.CodeDom.Compiler; 9 | using System.Data.Entity.Migrations; 10 | using System.Data.Entity.Migrations.Infrastructure; 11 | using System.Resources; 12 | 13 | [GeneratedCode("EntityFramework.Migrations", "6.1.0-30225")] 14 | public sealed partial class AddUser : IMigrationMetadata 15 | { 16 | private readonly ResourceManager Resources = new ResourceManager(typeof(AddUser)); 17 | 18 | string IMigrationMetadata.Id 19 | { 20 | get { return "201405280638095_AddUser"; } 21 | } 22 | 23 | string IMigrationMetadata.Source 24 | { 25 | get { return null; } 26 | } 27 | 28 | string IMigrationMetadata.Target 29 | { 30 | get { return Resources.GetString("Target"); } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Samples/EFMultiTenant/Migrations/201405280638095_AddUser.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | // 5 | 6 | namespace EFMultiTenantElasticScale.Migrations 7 | { 8 | using System; 9 | using System.Data.Entity.Migrations; 10 | 11 | public partial class AddUser : DbMigration 12 | { 13 | public override void Up() 14 | { 15 | CreateTable( 16 | "dbo.Users", 17 | c => new 18 | { 19 | UserName = c.String(nullable: false, maxLength: 128), 20 | DisplayName = c.String(), 21 | }) 22 | .PrimaryKey(t => t.UserName); 23 | } 24 | 25 | public override void Down() 26 | { 27 | DropTable("dbo.Users"); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Samples/EFMultiTenant/Migrations/201405280640127_ChangeDisplayName.Designer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | // 5 | 6 | namespace EFMultiTenantElasticScale.Migrations 7 | { 8 | using System.CodeDom.Compiler; 9 | using System.Data.Entity.Migrations; 10 | using System.Data.Entity.Migrations.Infrastructure; 11 | using System.Resources; 12 | 13 | [GeneratedCode("EntityFramework.Migrations", "6.1.0-30225")] 14 | public sealed partial class ChangeDisplayName : IMigrationMetadata 15 | { 16 | private readonly ResourceManager Resources = new ResourceManager(typeof(ChangeDisplayName)); 17 | 18 | string IMigrationMetadata.Id 19 | { 20 | get { return "201405280640127_ChangeDisplayName"; } 21 | } 22 | 23 | string IMigrationMetadata.Source 24 | { 25 | get { return null; } 26 | } 27 | 28 | string IMigrationMetadata.Target 29 | { 30 | get { return Resources.GetString("Target"); } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Samples/EFMultiTenant/Migrations/201405280640127_ChangeDisplayName.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | // 5 | 6 | namespace EFMultiTenantElasticScale.Migrations 7 | { 8 | using System; 9 | using System.Data.Entity.Migrations; 10 | 11 | public partial class ChangeDisplayName : DbMigration 12 | { 13 | public override void Up() 14 | { 15 | RenameColumn(table: "dbo.Users", name: "DisplayName", newName: "display_name"); 16 | } 17 | 18 | public override void Down() 19 | { 20 | RenameColumn(table: "dbo.Users", name: "display_name", newName: "DisplayName"); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Samples/EFMultiTenant/Migrations/201504020051125_AddTenantId.Designer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | // 5 | 6 | namespace EFMultiTenantElasticScale.Migrations 7 | { 8 | using System.CodeDom.Compiler; 9 | using System.Data.Entity.Migrations; 10 | using System.Data.Entity.Migrations.Infrastructure; 11 | using System.Resources; 12 | 13 | [GeneratedCode("EntityFramework.Migrations", "6.1.0-30225")] 14 | public sealed partial class AddTenantId : IMigrationMetadata 15 | { 16 | private readonly ResourceManager Resources = new ResourceManager(typeof(AddTenantId)); 17 | 18 | string IMigrationMetadata.Id 19 | { 20 | get { return "201504020051125_AddTenantId"; } 21 | } 22 | 23 | string IMigrationMetadata.Source 24 | { 25 | get { return null; } 26 | } 27 | 28 | string IMigrationMetadata.Target 29 | { 30 | get { return Resources.GetString("Target"); } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Samples/EFMultiTenant/Migrations/201504020051125_AddTenantId.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | // 5 | 6 | namespace EFMultiTenantElasticScale.Migrations 7 | { 8 | using System; 9 | using System.Data.Entity.Migrations; 10 | 11 | public partial class AddTenantId : DbMigration 12 | { 13 | public override void Up() 14 | { 15 | AddColumn("dbo.Blogs", "TenantId", c => c.Int(nullable: false)); 16 | AddColumn("dbo.Posts", "TenantId", c => c.Int(nullable: false)); 17 | } 18 | 19 | public override void Down() 20 | { 21 | DropColumn("dbo.Posts", "TenantId"); 22 | DropColumn("dbo.Blogs", "TenantId"); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Samples/EFMultiTenant/Migrations/Configuration.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | // 5 | 6 | using System.Data.Entity.Migrations; 7 | 8 | namespace EFMultiTenantElasticScale.Migrations 9 | { 10 | internal sealed class Configuration : DbMigrationsConfiguration> 11 | { 12 | public Configuration() 13 | { 14 | this.AutomaticMigrationsEnabled = false; 15 | this.ContextKey = "CodeFirstNewDatabaseSample.BloggingContext"; 16 | } 17 | 18 | protected override void Seed(ElasticScaleContext context) 19 | { 20 | // This method will be called after migrating to the latest version. 21 | 22 | // You can use the DbSet.AddOrUpdate() helper extension method 23 | // to avoid creating duplicate seed data. E.g. 24 | // 25 | // context.People.AddOrUpdate( 26 | // p => p.FullName, 27 | // new Person { FullName = "Andrew Peters" }, 28 | // new Person { FullName = "Brice Lambson" }, 29 | // new Person { FullName = "Rowan Miller" } 30 | // ); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Samples/EFMultiTenant/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Runtime.InteropServices; 5 | 6 | // Setting ComVisible to false makes the types in this assembly not visible 7 | // to COM components. If you need to access a type in this assembly from 8 | // COM, set the ComVisible attribute to true on that type. 9 | [assembly: ComVisible(false)] 10 | 11 | // The following GUID is for the ID of the typelib if this project is exposed to COM 12 | [assembly: Guid("1e1f1152-0ac3-4631-b801-33bd9ec84fa9")] 13 | -------------------------------------------------------------------------------- /Samples/EFMultiTenant/RemoveRLS.sql: -------------------------------------------------------------------------------- 1 | -- Copyright (c) Microsoft. All rights reserved. 2 | -- Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | -- Remove RLS policies and functions 5 | IF ( EXISTS(SELECT * FROM sys.security_policies WHERE name = 'tenantAccessPolicy') ) 6 | DROP SECURITY POLICY rls.tenantAccessPolicy 7 | go 8 | 9 | IF ( EXISTS(SELECT * FROM sys.objects WHERE name = 'fn_tenantAccessPredicate') ) 10 | DROP FUNCTION rls.fn_tenantAccessPredicate 11 | go 12 | 13 | IF ( EXISTS(SELECT * FROM sys.objects WHERE name = 'fn_tenantAccessPredicateWithSuperUser') ) 14 | DROP FUNCTION rls.fn_tenantAccessPredicateWithSuperUser 15 | go 16 | 17 | IF ( EXISTS(SELECT * FROM sys.schemas WHERE name = 'rls') ) 18 | DROP SCHEMA rls 19 | go 20 | -------------------------------------------------------------------------------- /Samples/EFMultiTenant/SqlDatabaseUtils.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling; 6 | 7 | namespace EFMultiTenantElasticScale 8 | { 9 | /// 10 | /// Helper methods for interacting with SQL Databases. 11 | /// 12 | internal static class SqlDatabaseUtils 13 | { 14 | /// 15 | /// Gets the retry policy to use for connections to SQL Server. 16 | /// 17 | public static RetryPolicy SqlRetryPolicy 18 | { 19 | get { return new RetryPolicy(10, TimeSpan.FromSeconds(5)); } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Samples/EFMultiTenant/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "DevelopmentDatabase": "Data Source=(localdb)\\v11.0;Initial Catalog=elasticscaledev;Integrated Security=True" 4 | } 5 | } -------------------------------------------------------------------------------- /Samples/ElasticScaleStarterKit/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 38 | 39 | 40 | 46 | 47 | 48 | 49 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /Samples/ElasticScaleStarterKit/ElasticScaleStarterKit.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0;net8.0 4 | Exe 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | PreserveNewest 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Always 23 | 24 | 25 | -------------------------------------------------------------------------------- /Samples/ElasticScaleStarterKit/InitializeShard.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/elastic-db-tools/b31d748a577d5920508cb19afb626a85df2408ca/Samples/ElasticScaleStarterKit/InitializeShard.sql -------------------------------------------------------------------------------- /Samples/ElasticScaleStarterKit/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Microsoft 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Samples/ElasticScaleStarterKit/README.txt: -------------------------------------------------------------------------------- 1 | Prerequisites 2 | ------------- 3 | - .Net 6.0 or later 4 | - Visual Studio 2022 5 | - Microsoft Azure SQL Database or Microsoft SQL Server instance on local machine 6 | 7 | Getting Started 8 | --------------- 9 | Before running this project, please fill in the values in App.config. 10 | 11 | For detailed instructions and background information, please refer to Getting Started web page 12 | for Azure SQL Database Elastic Scale: http://go.microsoft.com/fwlink/?LinkID=510913 13 | 14 | Authentication Info 15 | ------------------- 16 | https://learn.microsoft.com/en-us/sql/connect/ado-net/sql/azure-active-directory-authentication?view=sql-server-ver16#setting-microsoft-entra-authentication 17 | https://learn.microsoft.com/en-us/azure/azure-sql/database/authentication-aad-overview?view=azuresql#connect-by-using-microsoft-entra-identities -------------------------------------------------------------------------------- /Samples/PowerShell/GetMappings.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | /******************************************************** 3 | * * 4 | * © Microsoft. All rights reserved. * 5 | * * 6 | *********************************************************/ 7 | 8 | .SYNOPSIS 9 | For a given Sharding setup, this script outputs the Mapping 10 | of the shards. 11 | 12 | .NOTES 13 | Author: Microsoft SQL Elastic Scale team 14 | Last Updated: 7/30/2015 15 | 16 | .EXAMPLES 17 | .\GetMappings.ps1 ` 18 | -UserName 'mysqluser' ` 19 | -Password 'MySqlPassw0rd' ` 20 | -ShardMapManagerServerName 'abcdefghij.database.windows.net' ` 21 | -ShardMapManagerDatabaseName 'MyShardMapManagerDB' 22 | -ShardMapName 'CustomerIdShardMap' 23 | 24 | #> 25 | 26 | param ( 27 | [parameter(Mandatory=$true)][string]$UserName, 28 | [parameter(Mandatory=$true)][string]$Password, 29 | [parameter(Mandatory=$true)][string]$ShardMapManagerServerName, 30 | [parameter(Mandatory=$true)][string]$ShardMapManagerDatabaseName, 31 | [parameter(Mandatory=$true)][string]$ShardMapName 32 | ) 33 | 34 | Set-StrictMode -Version Latest 35 | $ErrorActionPreference = "Stop" 36 | 37 | # Import modules 38 | $ScriptDir = Split-Path -parent $MyInvocation.MyCommand.Path 39 | Import-Module $ScriptDir\ShardManagement -Force 40 | 41 | # Create new (or replace existing) shard map manager 42 | $ShardMapManager = Get-ShardMapManager -UserName $UserName -Password $Password -SqlServerName $ShardMapManagerServerName -SqlDatabaseName $ShardMapManagerDatabaseName 43 | 44 | $ShardMap = $ShardMapManager.GetShardMap($ShardMapName); 45 | 46 | # Get shard map 47 | If ($ShardMap.MapType.Equals([Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.ShardMapType]::List)) 48 | { 49 | $ShardMap = Get-ListShardMap -KeyType $ShardMap.KeyType.ToString() -ShardMapManager $ShardMapManager -ListShardMapName $ShardMapName 50 | } 51 | ElseIf ($ShardMap.MapType.Equals([Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.ShardMapType]::Range)) 52 | { 53 | $ShardMap = Get-RangeShardMap -KeyType $ShardMap.KeyType.ToString() -ShardMapManager $ShardMapManager -RangeShardMapName $ShardMapName 54 | } 55 | Else 56 | { 57 | Write-Error "Invalid Shard Map Type" 58 | } 59 | 60 | # Get mappings 61 | return Get-Mappings -ShardMap $ShardMap | Format-List 62 | 63 | -------------------------------------------------------------------------------- /Samples/PowerShell/GetShards.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | /******************************************************** 3 | * * 4 | * © Microsoft. All rights reserved. * 5 | * * 6 | *********************************************************/ 7 | 8 | .SYNOPSIS 9 | For a given Sharding setup, this script outputs the list of Shards. 10 | 11 | .NOTES 12 | Author: Microsoft SQL Elastic Scale team 13 | Last Updated: 8/13/2015 14 | 15 | .EXAMPLES 16 | .\GetShards.ps1 ` 17 | -UserName 'mysqluser' ` 18 | -Password 'MySqlPassw0rd' ` 19 | -ShardMapManagerServerName 'abcdefghij.database.windows.net' ` 20 | -ShardMapManagerDatabaseName 'MyShardMapManagerDB' 21 | -ShardMapName 'CustomerIdShardMap' 22 | 23 | #> 24 | 25 | param ( 26 | [parameter(Mandatory=$true)][string]$UserName, 27 | [parameter(Mandatory=$true)][string]$Password, 28 | [parameter(Mandatory=$true)][string]$ShardMapManagerServerName, 29 | [parameter(Mandatory=$true)][string]$ShardMapManagerDatabaseName, 30 | [parameter(Mandatory=$true)][string]$ShardMapName 31 | ) 32 | 33 | Set-StrictMode -Version Latest 34 | $ErrorActionPreference = "Stop" 35 | 36 | # Import modules 37 | $ScriptDir = Split-Path -parent $MyInvocation.MyCommand.Path 38 | Import-Module $ScriptDir\ShardManagement -Force 39 | 40 | # Create new (or replace existing) shard map manager 41 | $ShardMapManager = Get-ShardMapManager -UserName $UserName -Password $Password -SqlServerName $ShardMapManagerServerName -SqlDatabaseName $ShardMapManagerDatabaseName 42 | 43 | $ShardMap = $ShardMapManager.GetShardMap($ShardMapName) 44 | 45 | # Get mappings 46 | return Get-Shards -ShardMap $ShardMap | Format-List 47 | 48 | -------------------------------------------------------------------------------- /Samples/PowerShell/ShardManagement/CreatePerformanceCounterCategory.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | /******************************************************** 3 | * * 4 | * © Microsoft. All rights reserved. * 5 | * * 6 | *********************************************************/ 7 | 8 | .SYNOPSIS 9 | This script creates performance counter catagory and adds 10 | specified user to 'Performance Monitor Users' local group. 11 | 12 | .NOTES 13 | Author: Microsoft SQL Elastic Scale team 14 | Last Updated: 5/6/2016 15 | 16 | .EXAMPLES 17 | .\CreatePerformanceCounterCategory.ps1 ` 18 | -UserName 'domain\username' 19 | #> 20 | 21 | param( 22 | [Parameter(Mandatory = $true)] 23 | [string] 24 | $UserName="" 25 | ) 26 | Set-StrictMode -Version Latest 27 | $ErrorActionPreference = "Stop" 28 | 29 | # Import modules 30 | $ScriptDir = Split-Path -parent $MyInvocation.MyCommand.Path 31 | Import-Module $ScriptDir\ShardManagement -Force 32 | 33 | if (([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { 34 | Write-Host "Creating performance counter category 'Elastic Database: Shard Management' ..." 35 | [Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.ShardMapManagerFactory]::CreatePerformanceCategoryAndCounters() 36 | Write-Host "Performance counter category 'Elastic Database: Shard Management' created successfully." 37 | Write-Host "Adding specified user to 'Performance Monitor Users' group ..." 38 | net localgroup "Performance Monitor Users" $UserName /ADD 39 | if($?) { 40 | Write-Host "User $UserName is now part of 'Performance Monitor Users' group. 'Performance Monitor Users' group membership is required for accessing performance counters." 41 | } else { 42 | Write-Host "Failed to add User $UserName to 'Performance Monitor Users' group, please add $UserName to this group to enable performance counters access." 43 | } 44 | } else { 45 | Write-Host "Performance counter category creation needs Administrator privileges, please rerun script as Administrator." 46 | } 47 | -------------------------------------------------------------------------------- /Samples/PowerShell/SqlDatabaseHelpers/SqlDatabaseHelpers.psm1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/elastic-db-tools/b31d748a577d5920508cb19afb626a85df2408ca/Samples/PowerShell/SqlDatabaseHelpers/SqlDatabaseHelpers.psm1 -------------------------------------------------------------------------------- /Samples/PowerShell/Upgrade.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | /********************************************************* 3 | * * 4 | * © Microsoft. All rights reserved. * 5 | * * 6 | *********************************************************/ 7 | 8 | .SYNOPSIS 9 | Upgrades a Shard Map Manager and all its shards to the current version. 10 | 11 | .NOTES 12 | Author: Microsoft SQL Elastic Scale team 13 | Last Updated: 9/5/2014 14 | #> 15 | param( 16 | [Parameter(Mandatory = $true)] 17 | [string] 18 | $ShardMapManagerServerName="", 19 | [Parameter(Mandatory = $true)] 20 | [string] 21 | $ShardMapManagerDatabaseName="", 22 | [Parameter(Mandatory = $true)] 23 | [string] 24 | $UserName="", 25 | [Parameter(Mandatory = $true)] 26 | [string] 27 | $Password="" 28 | ) 29 | 30 | Set-StrictMode -Version Latest 31 | $ErrorActionPreference = "Stop" 32 | 33 | # Import modules 34 | $ScriptDir = Split-Path -parent $MyInvocation.MyCommand.Path 35 | Import-Module $ScriptDir\ShardManagement -Force 36 | 37 | # Get Shard Map Manager 38 | 39 | $SmmConnectionString = New-Object System.Data.SqlClient.SqlConnectionStringBuilder("Server=$ShardMapManagerServerName; Initial Catalog=$ShardMapManagerDatabaseName; User ID=$UserName; Password=$Password;") 40 | $LoadPolicy = [Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.ShardMapManagerLoadPolicy]::Lazy 41 | 42 | $smm = [Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.ShardMapManagerFactory]::GetSqlShardMapManager($SmmConnectionString, $LoadPolicy) 43 | 44 | # Upgrade GSM 45 | Write-Host "Upgrading GSM" 46 | $smm.UpgradeGlobalStore(); 47 | 48 | # Get distinct locations in this shard map manager 49 | $Locations = $smm.GetDistinctShardLocations(); 50 | 51 | # Upgrade all shards 52 | foreach ($Location in $Locations) 53 | { 54 | Write-Host "Upgrading " $Location.ToString() 55 | $smm.UpgradeLocalStore($Location); 56 | } 57 | -------------------------------------------------------------------------------- /Samples/ShardSqlCmd/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2024 Microsoft 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Samples/ShardSqlCmd/ShardSqlCmd.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net6.0;net8.0 4 | Exe 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ElasticScale.Common/ElasticScale.Common.csproj.vspscc: -------------------------------------------------------------------------------- 1 | "" 2 | { 3 | "FILE_VERSION" = "9237" 4 | "ENLISTMENT_CHOICE" = "NEVER" 5 | "PROJECT_FILE_RELATIVE_PATH" = "" 6 | "NUMBER_OF_EXCLUDED_FILES" = "0" 7 | "ORIGINAL_PROJECT_FILE_PATH" = "" 8 | "NUMBER_OF_NESTED_PROJECTS" = "0" 9 | "SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" 10 | } 11 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ElasticScale.Common/ExceptionHandling/ExceptionExtensionMethods.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Linq; 6 | 7 | namespace Microsoft.Azure.SqlDatabase.ElasticScale 8 | { 9 | /// 10 | /// Extension methods for System.Exception. 11 | /// 12 | internal static class ExceptionExtensionMethods 13 | { 14 | /// 15 | /// Checks if this exception's type is the same, or a sub-class, of any of the specified types. 16 | /// 17 | /// This instance. 18 | /// Types to be matched against. 19 | /// Whether or not this exception matched any of the specified types. 20 | public static bool IsAnyOf(this Exception ex, Type[] types) 21 | { 22 | if (ex == null) 23 | { 24 | throw new ArgumentNullException("ex"); 25 | } 26 | if (types == null) 27 | { 28 | throw new ArgumentNullException("types"); 29 | } 30 | 31 | Type exceptionType = ex.GetType(); 32 | return types.Any(type => type.IsAssignableFrom(exceptionType)); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ElasticScale.Common/GlobalSuppressions.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/elastic-db-tools/b31d748a577d5920508cb19afb626a85df2408ca/Src/ElasticScale.Client/ElasticScale.Common/GlobalSuppressions.cs -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ElasticScale.Common/Logging/ILogConfigWatcher.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | #region "Usings" 5 | 6 | using System; 7 | #endregion 8 | 9 | namespace Microsoft.Azure.SqlDatabase.ElasticScale 10 | { 11 | /// 12 | /// Interface for exposing a logging configuration change 13 | /// 14 | internal interface ILogConfigWatcher 15 | { 16 | event EventHandler OnConfigChange; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ElasticScale.Common/Logging/ILogger.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | #region "Usings" 5 | 6 | using System; 7 | #endregion 8 | 9 | namespace Microsoft.Azure.SqlDatabase.ElasticScale 10 | { 11 | /// 12 | /// Definition of a generic logging interface to abstract 13 | /// implementation details. Includes api trace methods. 14 | /// 15 | internal interface ILogger 16 | { 17 | void Info(string message); 18 | void Info(string format, params object[] vars); 19 | 20 | void Verbose(string message); 21 | void Verbose(string format, params object[] vars); 22 | 23 | void Warning(string message); 24 | void Warning(Exception exception, string message); 25 | void Warning(string format, params object[] vars); 26 | void Warning(Exception exception, string format, params object[] vars); 27 | 28 | void Error(string message); 29 | void Error(Exception exception, string message); 30 | void Error(string format, params object[] vars); 31 | void Error(Exception exception, string format, params object[] vars); 32 | 33 | void Critical(string message); 34 | void Critical(Exception exception, string message); 35 | void Critical(string format, params object[] vars); 36 | void Critical(Exception exception, string format, params object[] vars); 37 | 38 | void TraceIn(string method, Guid activityId); 39 | void TraceOut(string method, Guid activityId); 40 | 41 | void TraceIn(string method, Guid activityId, string format, params object[] vars); 42 | void TraceOut(string method, Guid activityId, string format, params object[] vars); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ElasticScale.Common/Logging/LoggerFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | // 4 | // Purpose: Generic pluggable logger factory for retrieving configured 5 | // logging objects 6 | 7 | namespace Microsoft.Azure.SqlDatabase.ElasticScale 8 | { 9 | /// 10 | /// Generic pluggable logger factory for retrieving configured 11 | /// logging objects 12 | /// 13 | internal static class LoggerFactory 14 | { 15 | #region "Singleton Implementation" 16 | 17 | private static TraceSourceFactory s_loggerFactory = null; 18 | 19 | private static object s_lockObj = new object(); 20 | 21 | private static ILogFactory _factory 22 | { 23 | get 24 | { 25 | if (s_loggerFactory == null) 26 | { 27 | lock (s_lockObj) 28 | { 29 | if (s_loggerFactory == null) 30 | { 31 | s_loggerFactory = new TraceSourceFactory(); 32 | } 33 | } 34 | } 35 | 36 | return s_loggerFactory; 37 | } 38 | } 39 | 40 | #endregion 41 | 42 | public static ILogger GetLogger() 43 | { 44 | return _factory.Create(typeof(T).Name); 45 | } 46 | 47 | public static ILogger GetLogger() 48 | { 49 | return _factory.Create(); 50 | } 51 | 52 | public static ILogger GetLogger(string logName) 53 | { 54 | return _factory.Create(logName); 55 | } 56 | } 57 | 58 | /// 59 | /// ILogFactory interface to be implemented for 60 | /// each logger 61 | /// 62 | internal interface ILogFactory 63 | { 64 | ILogger Create(); 65 | ILogger Create(string name); 66 | } 67 | } -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ElasticScale.Common/Logging/TraceSource/ActivityIdScope.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | // 4 | // Purpose: Utility class to set and restore the System.Diagnostics CorrelationManager 5 | // ActivityId via the using pattern 6 | 7 | using System; 8 | 9 | namespace Microsoft.Azure.SqlDatabase.ElasticScale 10 | { 11 | /// 12 | /// Utility class to set and restore the System.Diagnostics CorrelationManager 13 | /// ActivityId via the using pattern 14 | /// 15 | internal sealed class ActivityIdScope : IDisposable 16 | { 17 | /// 18 | /// The previous activity id that was in scope 19 | /// 20 | private readonly Guid _previousActivityId; 21 | 22 | /// 23 | /// Creates an instance of the class 24 | /// 25 | /// 26 | public ActivityIdScope(Guid activityId) 27 | { 28 | _previousActivityId = CorrelationManager.ActivityId; 29 | CorrelationManager.ActivityId = activityId; 30 | } 31 | 32 | /// 33 | /// Restores the previous activity id when this instance is disposed 34 | /// 35 | public void Dispose() 36 | { 37 | CorrelationManager.ActivityId = _previousActivityId; 38 | } 39 | } 40 | 41 | internal static class CorrelationManager 42 | { 43 | [ThreadStatic] 44 | private static Guid _activityId; 45 | 46 | public static Guid ActivityId 47 | { 48 | get 49 | { 50 | return _activityId; 51 | } 52 | set 53 | { 54 | _activityId = value; 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ElasticScale.Common/Patterns/ConditionalDisposable.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale 7 | { 8 | /// 9 | /// A disposable object which opts-out of disposing the inner disposable 10 | /// only when instructed by the caller. 11 | /// 12 | /// 13 | internal sealed class ConditionalDisposable : IDisposable where T : IDisposable 14 | { 15 | /// 16 | /// Inner disposable object. 17 | /// 18 | private T _innerDispoable; 19 | 20 | /// 21 | /// Constructor which takes an inner disposable object. 22 | /// 23 | /// 24 | public ConditionalDisposable(T innerDisposable) 25 | { 26 | _innerDispoable = innerDisposable; 27 | } 28 | 29 | /// 30 | /// Used for notifying about disposable decision on inner object. 31 | /// 32 | internal bool DoNotDispose 33 | { 34 | get; 35 | set; 36 | } 37 | 38 | /// 39 | /// Disposes the inner object if DoNotDispose is set to false. 40 | /// 41 | public void Dispose() 42 | { 43 | if (!this.DoNotDispose) 44 | { 45 | _innerDispoable.Dispose(); 46 | } 47 | } 48 | 49 | /// 50 | /// Gets the inner disposable object. 51 | /// 52 | public T Value 53 | { 54 | get 55 | { 56 | return this._innerDispoable; 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ElasticScale.Common/TransientFaultHandling/Implementation/ITransientErrorDetectionStrategy.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale 5 | { 6 | using System; 7 | 8 | internal partial class TransientFaultHandling 9 | { 10 | /// 11 | /// Defines an interface that must be implemented by custom components responsible for detecting specific transient conditions. 12 | /// 13 | internal interface ITransientErrorDetectionStrategy 14 | { 15 | /// 16 | /// Determines whether the specified exception represents a transient failure that can be compensated by a retry. 17 | /// 18 | /// The exception object to be verified. 19 | /// true if the specified exception is considered as transient; otherwise, false. 20 | bool IsTransient(Exception ex); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ElasticScale.Common/TransientFaultHandling/Implementation/RetryingEventArgs.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale 5 | { 6 | using System; 7 | 8 | internal partial class TransientFaultHandling 9 | { 10 | /// 11 | /// Contains information that is required for the event. 12 | /// 13 | internal class RetryingEventArgs : EventArgs 14 | { 15 | /// 16 | /// Initializes a new instance of the class. 17 | /// 18 | /// The current retry attempt count. 19 | /// The delay that indicates how long the current thread will be suspended before the next iteration is invoked. 20 | /// The exception that caused the retry conditions to occur. 21 | public RetryingEventArgs(int currentRetryCount, TimeSpan delay, Exception lastException) 22 | { 23 | Guard.ArgumentNotNull(lastException, "lastException"); 24 | 25 | this.CurrentRetryCount = currentRetryCount; 26 | this.Delay = delay; 27 | this.LastException = lastException; 28 | } 29 | 30 | /// 31 | /// Gets the current retry count. 32 | /// 33 | public int CurrentRetryCount { get; private set; } 34 | 35 | /// 36 | /// Gets the delay that indicates how long the current thread will be suspended before the next iteration is invoked. 37 | /// 38 | public TimeSpan Delay { get; private set; } 39 | 40 | /// 41 | /// Gets the exception that caused the retry conditions to occur. 42 | /// 43 | public Exception LastException { get; private set; } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ElasticScale.Common/TransientFaultHandling/RetryBehavior.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale 7 | { 8 | /// 9 | /// Defines the retry behavior to use for detecting transient errors. 10 | /// 11 | public sealed class RetryBehavior 12 | { 13 | /// 14 | /// Retry policy that tries upto 5 times with a 1 second backoff before giving up 15 | /// 16 | private static readonly Lazy s_defaultRetryBehavior = 17 | new Lazy(() => 18 | new RetryBehavior((e) => false)); 19 | 20 | /// 21 | /// Initializes an instance of the class 22 | /// 23 | ///Function that detects transient errors given an exception. 24 | /// The function needs to return true for an exception that should be treated as transient. 25 | /// 26 | public RetryBehavior(Func transientErrorDetector) 27 | { 28 | if (transientErrorDetector == null) 29 | { 30 | throw new ArgumentNullException("transientErrorDetector"); 31 | } 32 | 33 | this.TransientErrorDetector = transientErrorDetector; 34 | } 35 | 36 | /// 37 | /// Gets the default retry behavior. 38 | /// 39 | /// 40 | /// The default retry behavior has a built-in set of exceptions that are considered transient. 41 | /// You may create and use a custom object in order 42 | /// to treat additional exceptions as transient. 43 | /// 44 | public static RetryBehavior DefaultRetryBehavior 45 | { 46 | get 47 | { 48 | return s_defaultRetryBehavior.Value; 49 | } 50 | } 51 | 52 | /// 53 | /// Transient error detector predicate which decides whether a given exception is transient or not. 54 | /// 55 | internal Func TransientErrorDetector 56 | { 57 | get; 58 | private set; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ElasticScale.Common/TransientFaultHandling/RetryingEventArgs.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale 7 | { 8 | /// 9 | /// Shard management retrying event arguments 10 | /// 11 | internal sealed class RetryingEventArgs : EventArgs 12 | { 13 | /// 14 | /// Initializes new instance of class. 15 | /// 16 | /// RetryingEventArgs from RetryPolicy.Retrying event. 17 | internal RetryingEventArgs(TransientFaultHandling.RetryingEventArgs arg) 18 | { 19 | this.CurrentRetryCount = arg.CurrentRetryCount; 20 | this.Delay = arg.Delay; 21 | this.LastException = arg.LastException; 22 | } 23 | 24 | /// 25 | /// Gets the current retry count. 26 | /// 27 | public int CurrentRetryCount { get; private set; } 28 | 29 | /// 30 | /// Gets the delay that indicates how long the current thread will be suspended before the next iteration is invoked. 31 | /// 32 | public TimeSpan Delay { get; private set; } 33 | 34 | /// 35 | /// Gets the exception that caused the retry conditions to occur. 36 | /// 37 | public Exception LastException { get; private set; } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/GlobalSuppressions.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/elastic-db-tools/b31d748a577d5920508cb19afb626a85df2408ca/Src/ElasticScale.Client/GlobalSuppressions.cs -------------------------------------------------------------------------------- /Src/ElasticScale.Client/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Runtime.CompilerServices; 6 | using System.Runtime.InteropServices; 7 | 8 | // Setting ComVisible to false makes the types in this assembly not visible 9 | // to COM components. If you need to access a type in this assembly from 10 | // COM, set the ComVisible attribute to true on that type. 11 | [assembly: ComVisible(false)] 12 | 13 | // This assembly is strong name signed, so friend declaration must also have strong name public key 14 | [assembly: InternalsVisibleTo("Microsoft.Azure.SqlDatabase.ElasticScale.Query.UnitTests, PublicKey=00240000048000009400000006020000002400005253413100040000010001007d813b35eaf89b7ae4be8a49086058380e083b58752b0a3a8323157e68b4b0f9fd78d2fe75e9ec253d8bb2225637d4c2393234e0f877bfddd7907eda8293083b7f4dbc664f09f6b62ce74266a4e79002783252559f5b23cfc682eb79b51a5f5d16dca2364413ae563b3ab6db2fc9da3ced11f9eef50421b982dfc3a08cb635a8")] 15 | [assembly: InternalsVisibleTo("Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.UnitTests, PublicKey=00240000048000009400000006020000002400005253413100040000010001007d813b35eaf89b7ae4be8a49086058380e083b58752b0a3a8323157e68b4b0f9fd78d2fe75e9ec253d8bb2225637d4c2393234e0f877bfddd7907eda8293083b7f4dbc664f09f6b62ce74266a4e79002783252559f5b23cfc682eb79b51a5f5d16dca2364413ae563b3ab6db2fc9da3ced11f9eef50421b982dfc3a08cb635a8")] 16 | 17 | //[assembly: CLSCompliant(true)] 18 | 19 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1824:MarkAssembliesWithNeutralResourcesLanguage", Justification = "Too many dubious spelling errors.")] 20 | 21 | internal static class ElasticScaleVersionInfo 22 | { 23 | public const string ProductVersion = "2.0.0"; 24 | } 25 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/Properties/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/elastic-db-tools/b31d748a577d5920508cb19afb626a85df2408ca/Src/ElasticScale.Client/Properties/Icon.png -------------------------------------------------------------------------------- /Src/ElasticScale.Client/Query/DbCommandExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.Common; 3 | using System.Linq; 4 | using Microsoft.Data.SqlClient; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.Query 7 | { 8 | public static class DbCommandExtensions { 9 | 10 | /// 11 | /// Make best attempt to clone DbCommand 12 | /// 13 | /// 14 | /// 15 | public static DbCommand BestAttemptClone(this DbCommand from) { 16 | if(from is ICloneable) { 17 | return (DbCommand)(from as ICloneable).Clone(); 18 | } 19 | 20 | DbCommand newcmd = null; 21 | 22 | if(from is SqlCommand) { 23 | // do some special magic for SqlCommand 24 | newcmd = new SqlCommand(from.CommandText, (from as SqlCommand).Connection, (from as SqlCommand).Transaction); 25 | } else { 26 | var mi = from.GetType().GetMethod("Clone"); 27 | if(mi != null && mi.ReturnType != null && typeof(DbCommand).IsAssignableFrom(mi.ReturnType) && (mi.GetParameters()?.Count() ?? 0) == 0) { 28 | return (DbCommand)mi.Invoke(from, null); 29 | } else { 30 | newcmd = (DbCommand)Activator.CreateInstance(from.GetType()); 31 | newcmd.CommandText = from.CommandText; 32 | } 33 | } 34 | newcmd.CommandTimeout = from.CommandTimeout; 35 | newcmd.CommandType = from.CommandType; 36 | newcmd.DesignTimeVisible = from.DesignTimeVisible; 37 | newcmd.UpdatedRowSource = from.UpdatedRowSource; 38 | if(from.Parameters.Count > 0) { 39 | DbParameter[] p = new DbParameter[from.Parameters.Count]; 40 | from.Parameters.CopyTo(p, 0); 41 | foreach(object current in p) { 42 | newcmd.Parameters.Add(current); 43 | } 44 | } 45 | return newcmd; 46 | } 47 | 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/Query/GlobalConstants.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.Query 5 | { 6 | internal class GlobalConstants 7 | { 8 | /// 9 | /// Version information for Microsoft.Azure.SqlDatabase.ElasticScale.Query code. 10 | /// 11 | internal static string MultiShardQueryVersionInfo = ElasticScaleVersionInfo.ProductVersion; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/Query/Logging/TraceHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | // 4 | // Purpose: 5 | // Trace helper for CrossShardQuery 6 | 7 | using System; 8 | 9 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.Query 10 | { 11 | /// 12 | /// Trace helper for CrossShardQuery 13 | /// 14 | internal static class TraceHelper 15 | { 16 | /// 17 | /// The trace source name for cross shard query 18 | /// 19 | private const string MultiShardQueryTraceSourceName = "MultiShardQueryTraceSource"; 20 | 21 | // Suppression rationale: prefixing a static member on a static class with m_ is fine. 22 | // 23 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1504:ReviewMisleadingFieldNames")] 24 | private static readonly Lazy s_logger = new 25 | Lazy(() => LoggerFactory.GetLogger(MultiShardQueryTraceSourceName)); 26 | 27 | /// 28 | /// The tracer 29 | /// 30 | internal static ILogger Tracer 31 | { 32 | get 33 | { 34 | return s_logger.Value; 35 | } 36 | } 37 | 38 | internal static void TraceInfo(this ILogger logger, 39 | string methodName, 40 | string message, 41 | params object[] vars) 42 | { 43 | string fmtMessage = string.Format(message, vars); 44 | logger.Info("Method: {0}; {1}; ActivityId: {2};", methodName, fmtMessage, CorrelationManager.ActivityId); 45 | } 46 | 47 | internal static void TraceWarning(this ILogger logger, 48 | string methodName, 49 | string message, 50 | params object[] vars) 51 | { 52 | string fmtMessage = string.Format(message, vars); 53 | logger.Warning("Method: {0}; {1}; ActivityId: {2};", methodName, fmtMessage, 54 | CorrelationManager.ActivityId); 55 | } 56 | 57 | internal static void TraceError(this ILogger logger, 58 | string methodName, 59 | Exception ex, 60 | string message, 61 | params object[] vars) 62 | { 63 | string fmtMessage = string.Format(message, vars); 64 | logger.Error("Method: {0}; {1}; Exception: {2}; ActivityId: {3};", methodName, fmtMessage, ex.ToString(), 65 | CorrelationManager.ActivityId); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/Query/MultiShardExecutionOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.Query 7 | { 8 | /// 9 | /// Defines the available options when 10 | /// executing commands against multiple shards 11 | /// 12 | /// This enumeration has a flags attribute 13 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Multi"), FlagsAttribute] 14 | public enum MultiShardExecutionOptions 15 | { 16 | /// , 17 | /// Execute without any options enabled 18 | /// 19 | None, 20 | 21 | /// 22 | /// Whether the $ShardName pseudo column should be included 23 | /// in the result-sets. 24 | /// 25 | IncludeShardNameColumn 26 | }; 27 | } -------------------------------------------------------------------------------- /Src/ElasticScale.Client/Query/MultiShardExecutionPolicy.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | // 4 | // Purpose: 5 | // Defines the possible query execution policies 6 | 7 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.Query 8 | { 9 | // Suppression rationale: "Multi" is the spelling we want here. 10 | // 11 | /// 12 | /// Defines the possible query execution policies 13 | /// 14 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Multi")] 15 | public enum MultiShardExecutionPolicy 16 | { 17 | /// 18 | /// With the complete results execution policy an unsuccessful 19 | /// execution against any shard leads to all results being discarded 20 | /// and an exception being thrown either by the ExecuteReader method 21 | /// on the command or the Read method on the reader. 22 | /// 23 | CompleteResults, 24 | 25 | /// 26 | /// A best-effort execution policy that, unlike CompleteResults, tolerates unsuccessful command execution 27 | /// on some (but not all) shards and returns the results of the successful commands. 28 | /// Any errors encountered are returned to the user along with the partial results. 29 | /// The caller can inspect exceptions encountered during execution through 30 | /// the property of . 31 | /// 32 | PartialResults 33 | }; 34 | } -------------------------------------------------------------------------------- /Src/ElasticScale.Client/Query/MultiShardQueryTransientErrorDetectionStrategy.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.Query 7 | { 8 | /// 9 | /// Provides the transient error detection logic for transient faults that are specific to cross shard query. 10 | /// 11 | internal sealed class MultiShardQueryTransientErrorDetectionStrategy : TransientFaultHandling.ITransientErrorDetectionStrategy 12 | { 13 | /// 14 | /// Delegate used for detecting transient faults. 15 | /// 16 | private Func _transientFaultDetector; 17 | 18 | /// 19 | /// Standard transient error detection strategy. 20 | /// 21 | private TransientFaultHandling.SqlDatabaseTransientErrorDetectionStrategy _standardDetectionStrategy; 22 | 23 | /// 24 | /// Creates a new instance of transient error detection strategy for Shard map manager. 25 | /// 26 | /// Behavior for detecting transient errors. 27 | internal MultiShardQueryTransientErrorDetectionStrategy(RetryBehavior retryBehavior) 28 | { 29 | _standardDetectionStrategy = new TransientFaultHandling.SqlDatabaseTransientErrorDetectionStrategy(); 30 | _transientFaultDetector = retryBehavior.TransientErrorDetector; 31 | } 32 | 33 | /// 34 | /// Determines whether the specified exception represents a transient failure that can be compensated by a retry. 35 | /// 36 | /// The exception object to be verified. 37 | /// true if the specified exception is considered as transient; otherwise, false. 38 | public bool IsTransient(Exception ex) 39 | { 40 | return _standardDetectionStrategy.IsTransient(ex) || _transientFaultDetector(ex); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/Query/ResultSetAggregator.csproj.vspscc: -------------------------------------------------------------------------------- 1 | "" 2 | { 3 | "FILE_VERSION" = "9237" 4 | "ENLISTMENT_CHOICE" = "NEVER" 5 | "PROJECT_FILE_RELATIVE_PATH" = "" 6 | "NUMBER_OF_EXCLUDED_FILES" = "0" 7 | "ORIGINAL_PROJECT_FILE_PATH" = "" 8 | "NUMBER_OF_NESTED_PROJECTS" = "0" 9 | "SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" 10 | } 11 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/Query/ShardExecutionEventArgs.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement; 6 | 7 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.Query 8 | { 9 | /// 10 | /// Input to be passed to per-shard event handlers. 11 | /// 12 | public class ShardExecutionEventArgs : EventArgs 13 | { 14 | /// 15 | /// The exception to process, if applicable. Null if no exception was thrown. 16 | /// 17 | public Exception Exception 18 | { 19 | get; 20 | internal set; 21 | } 22 | 23 | /// 24 | /// The location of the shard on which the MultiShardCommand is currently executing. 25 | /// 26 | public ShardLocation ShardLocation 27 | { 28 | get; 29 | internal set; 30 | } 31 | 32 | /// 33 | /// FOR INTERNAL USE ONLY: 34 | /// The returned input reader. 35 | /// 36 | internal LabeledDbDataReader Reader 37 | { 38 | get; 39 | set; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Cache/CacheMappingExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 5 | { 6 | /// 7 | /// Encapsulates extension methods for CacheMappings 8 | /// 9 | public static class CacheMappingExtensions 10 | { 11 | /// 12 | /// Resets the mapping entry expiration time to 0 if necessary 13 | /// 14 | /// 15 | internal static void ResetTimeToLiveIfNecessary(this ICacheStoreMapping csm) 16 | { 17 | // Reset TTL on successful connection. 18 | if (csm != null && csm.TimeToLiveMilliseconds > 0) 19 | { 20 | csm.ResetTimeToLive(); 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Cache/CacheObject.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Diagnostics; 6 | using System.Threading; 7 | 8 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 9 | { 10 | /// 11 | /// Base class for all objects in the cache, providing locking facilities. 12 | /// 13 | internal abstract class CacheObject : IDisposable 14 | { 15 | /// 16 | /// Lock object. 17 | /// 18 | private ReaderWriterLockSlim _lock; 19 | 20 | /// 21 | /// Whether this object has already been disposed 22 | /// 23 | private bool _disposed = false; 24 | 25 | /// 26 | /// Instantiates the underlying lock object. 27 | /// 28 | protected CacheObject() 29 | { 30 | _lock = new ReaderWriterLockSlim(); 31 | } 32 | 33 | /// 34 | /// Obtains a read locking scope on the object. 35 | /// 36 | /// Whether the read lock should be upgradable. 37 | /// Read locking scope. 38 | internal ReadLockScope GetReadLockScope(bool upgradable) 39 | { 40 | return new ReadLockScope(_lock, upgradable); 41 | } 42 | 43 | /// 44 | /// Obtains a write locking scope on the object. 45 | /// 46 | /// Write locking scope. 47 | internal WriteLockScope GetWriteLockScope() 48 | { 49 | Debug.Assert(!_lock.IsUpgradeableReadLockHeld); 50 | 51 | return new WriteLockScope(_lock); 52 | } 53 | 54 | #region IDisposable 55 | 56 | /// 57 | /// Public dispose method. 58 | /// 59 | public void Dispose() 60 | { 61 | Dispose(true); 62 | GC.SuppressFinalize(this); 63 | } 64 | 65 | /// 66 | /// Protected vitual member of the dispose pattern. 67 | /// 68 | /// Call came from Dispose. 69 | protected virtual void Dispose(bool disposing) 70 | { 71 | if (!_disposed) 72 | { 73 | if (disposing) 74 | { 75 | _lock.Dispose(); 76 | } 77 | 78 | _disposed = true; 79 | } 80 | } 81 | 82 | #endregion IDisposable 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Cache/ICacheStoreMapping.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 5 | { 6 | /// 7 | /// Represents a cache entry for a mapping. 8 | /// 9 | internal interface ICacheStoreMapping 10 | { 11 | /// 12 | /// Store representation of mapping. 13 | /// 14 | IStoreMapping Mapping 15 | { 16 | get; 17 | } 18 | 19 | /// 20 | /// Mapping entry creation time. 21 | /// 22 | long CreationTime 23 | { 24 | get; 25 | } 26 | 27 | /// 28 | /// Mapping entry expiration time. 29 | /// 30 | long TimeToLiveMilliseconds 31 | { 32 | get; 33 | } 34 | 35 | /// 36 | /// Resets the mapping entry expiration time to 0. 37 | /// 38 | void ResetTimeToLive(); 39 | 40 | /// 41 | /// Whether TimeToLiveMilliseconds have elapsed 42 | /// since CreationTime 43 | /// 44 | /// 45 | bool HasTimeToLiveExpired(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Cache/PerfCounterInstance.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 7 | { 8 | /// 9 | /// Shard management performance counter names. 10 | /// 11 | internal enum PerformanceCounterName 12 | { 13 | // counters to track cached mappings 14 | MappingsCount, 15 | MappingsAddOrUpdatePerSec, 16 | MappingsRemovePerSec, 17 | MappingsLookupSucceededPerSec, 18 | MappingsLookupFailedPerSec, 19 | // counters to track ShardManagement operations 20 | DdrOperationsPerSec, 21 | }; 22 | 23 | /// 24 | /// Structure holding performance counter creation information 25 | /// 26 | internal struct PerfCounterCreationData 27 | { 28 | } 29 | 30 | /// 31 | /// Class represenging single instance of a all performance counters in shard management catagory 32 | /// 33 | internal class PerfCounterInstance : IDisposable 34 | { 35 | /// 36 | /// Initialize perf counter instance based on shard map name 37 | /// 38 | /// 39 | public PerfCounterInstance(string shardMapName) 40 | { 41 | } 42 | 43 | /// 44 | /// Try to increment specified performance counter by 1 for current instance. 45 | /// 46 | /// Counter to increment. 47 | internal void IncrementCounter(PerformanceCounterName counterName) 48 | { 49 | } 50 | 51 | /// 52 | /// Try to update performance counter with speficied value. 53 | /// 54 | /// Counter to update. 55 | /// New value. 56 | internal void SetCounter(PerformanceCounterName counterName, long value) 57 | { 58 | } 59 | 60 | /// 61 | /// Static method to recreate Shard Management performance counter catagory with given counter list. 62 | /// 63 | internal static void CreatePerformanceCategoryAndCounters() 64 | { 65 | } 66 | 67 | /// 68 | /// Dispose performance counter instance 69 | /// 70 | public void Dispose() 71 | { 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Cache/ReadLockScope.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Threading; 6 | 7 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 8 | { 9 | /// 10 | /// Scope for a read lock. 11 | /// 12 | internal class ReadLockScope : IDisposable 13 | { 14 | /// 15 | /// The lock object on which read lock is held. 16 | /// 17 | private ReaderWriterLockSlim _lock; 18 | 19 | /// 20 | /// Whether upgrade of read lock is possible. 21 | /// 22 | private bool _upgradable; 23 | 24 | /// 25 | /// Acquires the read lock. 26 | /// 27 | /// Lock to be acquired. 28 | /// Whether the lock is upgradable. 29 | internal ReadLockScope(ReaderWriterLockSlim _lock, bool upgradable) 30 | { 31 | this._lock = _lock; 32 | 33 | _upgradable = upgradable; 34 | 35 | if (_upgradable) 36 | { 37 | this._lock.EnterUpgradeableReadLock(); 38 | } 39 | else 40 | { 41 | this._lock.EnterReadLock(); 42 | } 43 | } 44 | 45 | /// 46 | /// Upgrade the read lock to a write lock. 47 | /// 48 | /// 49 | internal WriteLockScope Upgrade() 50 | { 51 | return new WriteLockScope(_lock); 52 | } 53 | 54 | /// 55 | /// Exits the locking scope. 56 | /// 57 | public void Dispose() 58 | { 59 | if (_upgradable) 60 | { 61 | _lock.ExitUpgradeableReadLock(); 62 | } 63 | else 64 | { 65 | _lock.ExitReadLock(); 66 | } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Cache/WriteLockScope.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Threading; 6 | 7 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 8 | { 9 | /// 10 | /// Scope for a write lock. 11 | /// 12 | internal class WriteLockScope : IDisposable 13 | { 14 | /// 15 | /// The lock object on which read lock is held. 16 | /// 17 | private ReaderWriterLockSlim _lock; 18 | 19 | /// 20 | /// Acquires the write lock. 21 | /// 22 | /// Lock to be acquired. 23 | internal WriteLockScope(ReaderWriterLockSlim _lock) 24 | { 25 | this._lock = _lock; 26 | 27 | this._lock.EnterWriteLock(); 28 | } 29 | 30 | /// 31 | /// Exits the locking scope. 32 | /// 33 | public void Dispose() 34 | { 35 | _lock.ExitWriteLock(); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Recovery/MappingComparisonResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.Recovery 5 | { 6 | /// 7 | /// Result of comparison b/w the given range mappings. 8 | /// 9 | internal class MappingComparisonResult 10 | { 11 | /// 12 | /// Instantiates a new instance of range mapping comparison result. 13 | /// 14 | /// Store representation of shard map. 15 | /// Range being considered. 16 | /// Location of mapping. 17 | /// Storage representation of GSM mapping. 18 | /// Storange representation of LSM mapping. 19 | internal MappingComparisonResult( 20 | IStoreShardMap ssm, 21 | ShardRange range, 22 | MappingLocation mappingLocation, 23 | IStoreMapping gsmMapping, 24 | IStoreMapping lsmMapping) 25 | { 26 | this.ShardMap = ssm; 27 | this.Range = range; 28 | this.MappingLocation = mappingLocation; 29 | this.ShardMapManagerMapping = gsmMapping; 30 | this.ShardMapping = lsmMapping; 31 | } 32 | 33 | /// 34 | /// Shard map to which mappings belong. 35 | /// 36 | internal IStoreShardMap ShardMap 37 | { 38 | get; 39 | private set; 40 | } 41 | 42 | /// 43 | /// Current range. 44 | /// 45 | internal ShardRange Range 46 | { 47 | get; 48 | private set; 49 | } 50 | 51 | /// 52 | /// Location of the mapping. 53 | /// 54 | internal MappingLocation MappingLocation 55 | { 56 | get; 57 | private set; 58 | } 59 | 60 | /// 61 | /// Mappings corresponding to current range in GSM. 62 | /// 63 | internal IStoreMapping ShardMapManagerMapping 64 | { 65 | get; 66 | private set; 67 | } 68 | 69 | /// 70 | /// Mapping corresponding to current range in LSM. 71 | /// 72 | internal IStoreMapping ShardMapping 73 | { 74 | get; 75 | private set; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Recovery/MappingDifference.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.Recovery 5 | { 6 | /// 7 | /// Class for mapping differences. 8 | /// 9 | internal class MappingDifference 10 | { 11 | internal MappingDifference( 12 | MappingDifferenceType type, 13 | MappingLocation location, 14 | IStoreShardMap shardMap, 15 | IStoreMapping mappingForShardMap, 16 | IStoreMapping mappingForShard 17 | ) 18 | { 19 | this.Type = type; 20 | this.Location = location; 21 | this.ShardMap = shardMap; 22 | this.MappingForShardMap = mappingForShardMap; 23 | this.MappingForShard = mappingForShard; 24 | } 25 | 26 | /// 27 | /// Type of mapping difference. Either List or Range. 28 | /// 29 | public MappingDifferenceType Type 30 | { 31 | get; 32 | private set; 33 | } 34 | 35 | /// 36 | /// Location where the mappings that differ exist. 37 | /// 38 | public MappingLocation Location 39 | { 40 | get; 41 | private set; 42 | } 43 | 44 | /// 45 | /// ShardMap which has the consistency violation. 46 | /// 47 | public IStoreShardMap ShardMap 48 | { 49 | get; 50 | private set; 51 | } 52 | 53 | /// 54 | /// Mapping found in shard map. 55 | /// 56 | public IStoreMapping MappingForShardMap 57 | { 58 | get; 59 | private set; 60 | } 61 | 62 | /// 63 | /// Mapping found in shard. 64 | /// 65 | public IStoreMapping MappingForShard 66 | { 67 | get; 68 | private set; 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Recovery/MappingDifferenceResolution.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.Recovery 5 | { 6 | /// 7 | /// Resolution strategy for resolving mapping differences. 8 | /// 9 | public enum MappingDifferenceResolution 10 | { 11 | /// 12 | /// Ignore the difference for now. 13 | /// 14 | Ignore, 15 | 16 | /// 17 | /// Use the mapping present in shard map. 18 | /// 19 | KeepShardMapMapping, 20 | 21 | /// 22 | /// Use the mapping in the shard. 23 | /// 24 | KeepShardMapping 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Recovery/MappingDifferenceType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.Recovery 5 | { 6 | /// 7 | /// Type of mapping difference. Useful for downcasting. 8 | /// 9 | public enum MappingDifferenceType 10 | { 11 | /// 12 | /// Violation associated with ListShardMap. 13 | /// 14 | List, 15 | 16 | /// 17 | /// Violation associated with RangeShardMap. 18 | /// 19 | Range 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Recovery/MappingLocation.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.Recovery 5 | { 6 | /// 7 | /// Location where the different mappings exist. 8 | /// 9 | public enum MappingLocation 10 | { 11 | /// 12 | /// Mapping is present in global store, but absent on the shard. 13 | /// 14 | MappingInShardMapOnly, 15 | 16 | /// 17 | /// Mapping is absent in global store, but present on the shard. 18 | /// 19 | MappingInShardOnly, 20 | 21 | /// 22 | /// Mapping present at both global store and shard. 23 | /// 24 | MappingInShardMapAndShard 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Recovery/RecoveryToken.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.Recovery 7 | { 8 | /// 9 | /// Recovery token generated and used by methods of the 10 | /// to perform conflict detection and resolution for shard maps. 11 | /// 12 | public sealed class RecoveryToken : IEquatable 13 | { 14 | /// 15 | /// Parameterless constructor to generate a new unique token for shard map conflict detection and resolution. 16 | /// 17 | internal RecoveryToken() 18 | { 19 | this.Id = Guid.NewGuid(); 20 | } 21 | 22 | /// 23 | /// Internal Guid for this token. 24 | /// 25 | private Guid Id 26 | { 27 | get; 28 | set; 29 | } 30 | 31 | /// 32 | /// Converts the object to its string representation. 33 | /// 34 | /// String representation of the object. 35 | public override string ToString() 36 | { 37 | return this.Id.ToString(); 38 | } 39 | 40 | /// 41 | /// Calculates the hash code for this instance. 42 | /// 43 | /// Hash code for the object. 44 | public override int GetHashCode() 45 | { 46 | return this.Id.GetHashCode(); 47 | } 48 | 49 | /// 50 | /// Determines whether the specified Object is equal to the current Object. 51 | /// 52 | /// The object to compare with the current object. 53 | /// True if the specified object is equal to the current object; otherwise, false. 54 | public override bool Equals(object obj) 55 | { 56 | RecoveryToken other = obj as RecoveryToken; 57 | 58 | if (other == null) 59 | { 60 | return false; 61 | } 62 | 63 | return this.Equals(other); 64 | } 65 | 66 | /// 67 | /// Performs equality comparison with another given RecoveryToken. 68 | /// 69 | /// RecoveryToken to compare with. 70 | /// True if same locations, false otherwise. 71 | public bool Equals(RecoveryToken other) 72 | { 73 | if (other == null) 74 | { 75 | return false; 76 | } 77 | 78 | return this.Id.Equals(other.Id); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/SchemaInformation/SchemaInfoErrorCode.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.Schema 5 | { 6 | /// 7 | /// Possible errors encountered by SchemaInfoCollection. 8 | /// 9 | public enum SchemaInfoErrorCode 10 | { 11 | /// 12 | /// No exists with the given name. 13 | /// 14 | SchemaInfoNameDoesNotExist, 15 | 16 | /// 17 | /// A entry with the given name already exists. 18 | /// 19 | SchemaInfoNameConflict, 20 | 21 | /// 22 | /// An entry for the given table already exists in the object. 23 | /// 24 | TableInfoAlreadyPresent 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/SchemaInformation/TableInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Runtime.Serialization; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.Schema 7 | { 8 | /// 9 | /// Repesents a table in a database. 10 | /// 11 | [DataContract(Name = "TableInfo", Namespace = "")] 12 | public abstract class TableInfo 13 | { 14 | /// 15 | /// Table's schema name. 16 | /// 17 | [DataMember()] 18 | public string SchemaName { get; protected set; } 19 | 20 | /// 21 | /// Table name. 22 | /// 23 | [DataMember()] 24 | public string TableName { get; protected set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Scripts/CheckShardMapManagerGlobal.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 5 | { 6 | /// 7 | /// Utility properties and methods used for managing scripts and errors. 8 | /// 9 | internal static partial class ReadOnlyScripts 10 | { 11 | internal const string CheckShardMapManagerGlobal = @" 12 | -- Copyright (c) Microsoft. All rights reserved. 13 | -- Licensed under the MIT license. See LICENSE file in the project root for full license information. 14 | 15 | --------------------------------------------------------------------------------------------------- 16 | -- Reads from shard map manager version information table if it exists. 17 | --------------------------------------------------------------------------------------------------- 18 | 19 | declare @stmt varchar(128) 20 | if object_id(N'__ShardManagement.ShardMapManagerGlobal', N'U') is not null 21 | begin 22 | if exists(select Name from sys.columns where Name = N'StoreVersion' and object_id = object_id(N'__ShardManagement.ShardMapManagerGlobal')) 23 | begin 24 | set @stmt = 'select 5, StoreVersion from __ShardManagement.ShardMapManagerGlobal' 25 | end 26 | else 27 | begin 28 | set @stmt = 'select 5, StoreVersionMajor, StoreVersionMinor from __ShardManagement.ShardMapManagerGlobal' 29 | end 30 | exec(@stmt) 31 | end 32 | go 33 | "; 34 | } 35 | } -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Scripts/CheckShardMapManagerLocal.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 5 | { 6 | /// 7 | /// Utility properties and methods used for managing scripts and errors. 8 | /// 9 | internal static partial class ReadOnlyScripts 10 | { 11 | internal const string CheckShardMapManagerLocal = @" 12 | -- Copyright (c) Microsoft. All rights reserved. 13 | -- Licensed under the MIT license. See LICENSE file in the project root for full license information. 14 | 15 | --------------------------------------------------------------------------------------------------- 16 | -- Reads from shard map manager version information table if it exists. 17 | --------------------------------------------------------------------------------------------------- 18 | 19 | declare @stmt varchar(128) 20 | if object_id(N'__ShardManagement.ShardMapManagerLocal', N'U') is not null 21 | begin 22 | if exists(select Name from sys.columns where Name = N'StoreVersion' and object_id = object_id(N'__ShardManagement.ShardMapManagerLocal')) 23 | begin 24 | set @stmt = 'select 5, StoreVersion from __ShardManagement.ShardMapManagerLocal' 25 | end 26 | else 27 | begin 28 | set @stmt = 'select 5, StoreVersionMajor, StoreVersionMinor from __ShardManagement.ShardMapManagerLocal' 29 | end 30 | exec(@stmt) 31 | end 32 | go 33 | "; 34 | } 35 | } -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Scripts/UpgradeShardMapManagerGlobalFrom0.0To1.0.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 5 | { 6 | /// 7 | /// Utility properties and methods used for managing scripts and errors. 8 | /// 9 | internal static partial class Scripts 10 | { 11 | internal static readonly UpgradeScript UpgradeShardMapManagerGlobalFrom0_0To1_0 = new UpgradeScript(0, 0, @" 12 | -- Copyright (c) Microsoft. All rights reserved. 13 | -- Licensed under the MIT license. See LICENSE file in the project root for full license information. 14 | 15 | --------------------------------------------------------------------------------------------------- 16 | -- Script to upgrade Global Shard Map from version 0.0 to 1.0 17 | --------------------------------------------------------------------------------------------------- 18 | 19 | -- add a column to ShardMapManagerGlobal table to hold SCH-M lock during upgrade 20 | alter table __ShardManagement.ShardMapManagerGlobal add UpgradeLock int null 21 | go 22 | "); 23 | } 24 | } -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Scripts/UpgradeShardMapManagerGlobalFrom1000.0To1000.1.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 5 | { 6 | /// 7 | /// Utility properties and methods used for managing scripts and errors. 8 | /// 9 | internal static partial class Scripts 10 | { 11 | internal static readonly UpgradeScript UpgradeShardMapManagerGlobalFrom1000_0To1000_1 = new UpgradeScript(1000, 0, @" 12 | -- Copyright (c) Microsoft. All rights reserved. 13 | -- Licensed under the MIT license. See LICENSE file in the project root for full license information. 14 | 15 | --------------------------------------------------------------------------------------------------- 16 | -- Script to upgrade Global Shard Map from version 1000.0 to 1000.1 17 | --------------------------------------------------------------------------------------------------- 18 | 19 | -- drop extra column from ShardMapManagerGlobal table which was added as first step to hold SCH-M lock during upgrade 20 | if exists(select * from sys.columns where Name = N'UpgradeLock' and object_id = object_id(N'__ShardManagement.ShardMapManagerGlobal')) 21 | begin 22 | alter table __ShardManagement.ShardMapManagerGlobal drop column UpgradeLock 23 | end 24 | go 25 | "); 26 | } 27 | } -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Scripts/UpgradeShardMapManagerLocalFrom0.0To1.0.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 5 | { 6 | /// 7 | /// Utility properties and methods used for managing scripts and errors. 8 | /// 9 | internal static partial class Scripts 10 | { 11 | internal static readonly UpgradeScript UpgradeShardMapManagerLocalFrom0_0To1_0 = new UpgradeScript(0, 0, @" 12 | -- Copyright (c) Microsoft. All rights reserved. 13 | -- Licensed under the MIT license. See LICENSE file in the project root for full license information. 14 | 15 | --------------------------------------------------------------------------------------------------- 16 | -- Script to upgrade Local Shard Map from version 0.0 to 1.0 17 | --------------------------------------------------------------------------------------------------- 18 | 19 | -- add a column to ShardMapManagerLocal table to hold SCH-M lock during upgrade 20 | alter table __ShardManagement.ShardMapManagerLocal add UpgradeLock int null 21 | go 22 | "); 23 | } 24 | } -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Scripts/UpgradeShardMapManagerLocalFrom1000.0To1000.1.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 5 | { 6 | /// 7 | /// Utility properties and methods used for managing scripts and errors. 8 | /// 9 | internal static partial class Scripts 10 | { 11 | internal static readonly UpgradeScript UpgradeShardMapManagerLocalFrom1000_0To1000_1 = new UpgradeScript(1000, 0, @" 12 | -- Copyright (c) Microsoft. All rights reserved. 13 | -- Licensed under the MIT license. See LICENSE file in the project root for full license information. 14 | 15 | --------------------------------------------------------------------------------------------------- 16 | -- Script to upgrade Local Shard Map from version 1000.0 to 1000.1 17 | --------------------------------------------------------------------------------------------------- 18 | 19 | -- drop extra column from ShardMapManagerLocal table which was added as first step to hold SCH-M lock during upgrade 20 | if exists(select * from sys.columns where Name = N'UpgradeLock' and object_id = object_id(N'__ShardManagement.ShardMapManagerLocal')) 21 | begin 22 | alter table __ShardManagement.ShardMapManagerLocal drop column UpgradeLock 23 | end 24 | go 25 | "); 26 | } 27 | } -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Shard/IMappingInfoProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 7 | { 8 | /// 9 | /// Types of supported mappings. 10 | /// 11 | internal enum MappingKind 12 | { 13 | PointMapping, 14 | RangeMapping 15 | } 16 | 17 | /// 18 | /// Interface that represents capability to provide information 19 | /// relavant to Add/Remove/Update operations for a mapping object. 20 | /// 21 | internal interface IMappingInfoProvider 22 | { 23 | /// 24 | /// ShardMapManager for the object. 25 | /// 26 | ShardMapManager Manager 27 | { 28 | get; 29 | } 30 | 31 | /// 32 | /// Shard map associated with the mapping. 33 | /// 34 | Guid ShardMapId 35 | { 36 | get; 37 | } 38 | 39 | /// 40 | /// Storage representation of the mapping. 41 | /// 42 | IStoreMapping StoreMapping 43 | { 44 | get; 45 | } 46 | 47 | /// 48 | /// Type of the mapping. 49 | /// 50 | MappingKind Kind 51 | { 52 | get; 53 | } 54 | 55 | /// 56 | /// Mapping type, useful for diagnostics. 57 | /// 58 | string TypeName 59 | { 60 | get; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Shard/IMappingUpdate.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 7 | { 8 | /// 9 | /// Records the updated properties for a mapping update object. 10 | /// 11 | [Flags] 12 | internal enum MappingUpdatedProperties : int 13 | { 14 | Status = 1, 15 | // Only applicable for point and range update. 16 | Shard = 2, 17 | All = Status | Shard 18 | } 19 | 20 | /// 21 | /// Common interface for point/range mapping updates. 22 | /// 23 | /// Status type. 24 | internal interface IMappingUpdate 25 | { 26 | /// 27 | /// Status property. 28 | /// 29 | TStatus Status 30 | { 31 | get; 32 | } 33 | 34 | /// 35 | /// Shard property. 36 | /// 37 | Shard Shard 38 | { 39 | get; 40 | } 41 | 42 | /// 43 | /// Checks if any property is set in the given bitmap. 44 | /// 45 | /// Properties bitmap. 46 | /// True if any of the properties is set, false otherwise. 47 | bool IsAnyPropertySet(MappingUpdatedProperties properties); 48 | 49 | /// 50 | /// Checks if the mapping is being taken offline. 51 | /// 52 | /// Original status. 53 | /// True of the update will take the mapping offline. 54 | bool IsMappingBeingTakenOffline(TStatus originalStatus); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Shard/IShardProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Threading.Tasks; 5 | using Microsoft.Data.SqlClient; 6 | 7 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 8 | { 9 | /// 10 | /// Represents capabilities to provide a Shard. 11 | /// 12 | internal interface IShardProvider 13 | { 14 | /// 15 | /// Shard for the ShardProvider object. 16 | /// 17 | Shard ShardInfo 18 | { 19 | get; 20 | } 21 | 22 | /// 23 | /// Performs validation that the local representation is as 24 | /// up-to-date as the representation on the backing 25 | /// data store. 26 | /// 27 | /// Shard map to which the shard provider belongs. 28 | /// Connection used for validation. 29 | void Validate(IStoreShardMap shardMap, SqlConnection conn); 30 | 31 | /// 32 | /// Asynchronously performs validation that the local representation is as 33 | /// up-to-date as the representation on the backing 34 | /// data store. 35 | /// 36 | /// Shard map to which the shard provider belongs. 37 | /// Connection used for validation. 38 | /// A task to await validation completion 39 | Task ValidateAsync(IStoreShardMap shardMap, SqlConnection conn); 40 | } 41 | 42 | /// 43 | /// Represents capabilities to provide a Shard along with an associated value. 44 | /// 45 | /// Value type. Examples are primitive types, ranges or shards themselves. 46 | internal interface IShardProvider : IShardProvider 47 | { 48 | /// 49 | /// Value corresponding to the Shard. Represents traits of the Shard 50 | /// object provided by the ShardInfo property. 51 | /// 52 | TValue Value 53 | { 54 | get; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Shard/LookupOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 7 | { 8 | /// 9 | /// Specifies where mapping lookup operations will search for mappings. 10 | /// 11 | [Flags] 12 | public enum LookupOptions : int 13 | { 14 | /// 15 | /// Default invalid kind of lookup options. 16 | /// 17 | None = 0, 18 | 19 | /// 20 | /// Attempt to lookup in the local cache. 21 | /// 22 | /// 23 | /// If LookupInCache and LookupInStore are both specified, the cache will be searched first, then the store. 24 | /// 25 | LookupInCache = 1 << 0, 26 | 27 | /// 28 | /// Attempt to lookup in the global shard map store. 29 | /// 30 | /// 31 | /// If LookupInCache and LookupInStore are both specified, the cache will be searched first, then the store. 32 | /// 33 | LookupInStore = 1 << 1, 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Shard/MappingStatus.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 5 | { 6 | /// 7 | /// Status of a mapping. 8 | /// 9 | public enum MappingStatus : int 10 | { 11 | /// 12 | /// Mapping is Offline. 13 | /// 14 | Offline = 0, 15 | 16 | /// 17 | /// Mapping is Online. 18 | /// 19 | Online = 1, 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Shard/PointMappingUpdate.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 5 | { 6 | /// 7 | /// Represents updates to a mapping between the singleton key value of a shardlet (a point) and the shard that holds its data. 8 | /// Also see . 9 | /// 10 | public sealed class PointMappingUpdate : BaseMappingUpdate 11 | { 12 | /// 13 | /// Instantiates a new point mapping update object. 14 | /// 15 | public PointMappingUpdate() 16 | : base() 17 | { 18 | } 19 | 20 | /// 21 | /// Detects if the current mapping is being taken offline. 22 | /// 23 | /// Original status. 24 | /// Updated status. 25 | /// Detects in the derived types if the mapping is being taken offline. 26 | protected override bool IsBeingTakenOffline(MappingStatus originalStatus, MappingStatus updatedStatus) 27 | { 28 | return originalStatus == MappingStatus.Online && updatedStatus == MappingStatus.Offline; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Shard/RangeMappingUpdate.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 5 | { 6 | /// 7 | /// Represents updates to a mapping between a of values and the that stores its data. 8 | /// Also see . 9 | /// 10 | public sealed class RangeMappingUpdate : BaseMappingUpdate 11 | { 12 | /// 13 | /// Instantiates a new range mapping update object. 14 | /// 15 | public RangeMappingUpdate() 16 | : base() 17 | { 18 | } 19 | 20 | /// 21 | /// Detects if the current mapping is being taken offline. 22 | /// 23 | /// Original status. 24 | /// Updated status. 25 | /// Detects in the derived types if the mapping is being taken offline. 26 | protected override bool IsBeingTakenOffline(MappingStatus originalStatus, MappingStatus updatedStatus) 27 | { 28 | return originalStatus == MappingStatus.Online && updatedStatus == MappingStatus.Offline; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Shard/ShardKeyType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 5 | { 6 | /// 7 | /// Type of shard key. Currently, only Int32, Int64, Guid and byte[] are the data types supported as shard keys. 8 | /// 9 | public enum ShardKeyType : int 10 | { 11 | /// 12 | /// No type specified. 13 | /// 14 | None, 15 | 16 | /// 17 | /// 32-bit integral value. 18 | /// 19 | Int32, 20 | 21 | /// 22 | /// 64-bit integral value. 23 | /// 24 | Int64, 25 | 26 | /// 27 | /// UniqueIdentifier value. 28 | /// 29 | Guid, 30 | 31 | /// 32 | /// Array of bytes value. 33 | /// 34 | Binary, 35 | 36 | /// 37 | /// Date and time value. 38 | /// 39 | DateTime, 40 | 41 | /// 42 | /// Time value. 43 | /// 44 | TimeSpan, 45 | 46 | /// 47 | /// Date and time value with offset. 48 | /// 49 | DateTimeOffset, 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Shard/ShardStatus.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 5 | { 6 | /// 7 | /// Status of a shard. 8 | /// 9 | internal enum ShardStatus : int 10 | { 11 | /// 12 | /// Shard is Offline. 13 | /// 14 | Offline = 0, 15 | 16 | /// 17 | /// Shard is Online. 18 | /// 19 | Online = 1, 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Shard/ShardUpdate.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 7 | { 8 | /// 9 | /// Records the updated properties on the shard. 10 | /// 11 | [Flags] 12 | internal enum ShardUpdatedProperties 13 | { 14 | Status = 1, 15 | All = Status 16 | } 17 | 18 | /// 19 | /// Represents updates to a Shard. 20 | /// 21 | internal sealed class ShardUpdate 22 | { 23 | /// 24 | /// Records the modified properties for update. 25 | /// 26 | private ShardUpdatedProperties _updatedProperties; 27 | 28 | /// 29 | /// Holder for update to status property. 30 | /// 31 | private ShardStatus _status; 32 | 33 | /// 34 | /// Instantiates the shard update object with no property set. 35 | /// 36 | public ShardUpdate() 37 | { 38 | } 39 | 40 | /// 41 | /// Status property. 42 | /// 43 | public ShardStatus Status 44 | { 45 | get 46 | { 47 | return _status; 48 | } 49 | set 50 | { 51 | _status = value; 52 | _updatedProperties |= ShardUpdatedProperties.Status; 53 | } 54 | } 55 | 56 | /// 57 | /// Checks if any of the properties specified in the given bitmap have 58 | /// been set by the user. 59 | /// 60 | /// Bitmap of properties. 61 | /// True if any property is set, false otherwise. 62 | internal bool IsAnyPropertySet(ShardUpdatedProperties p) 63 | { 64 | return (_updatedProperties & p) != 0; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/ShardMap/ShardMapType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 5 | { 6 | /// Type of shard map. 7 | public enum ShardMapType : int 8 | { 9 | /// 10 | /// Invalid kind of shard map. Only used for serialization/deserialization. 11 | /// 12 | None = 0, 13 | 14 | /// 15 | /// Shard map with list based mappings. 16 | /// 17 | List = 1, 18 | 19 | /// 20 | /// Shard map with range based mappings. 21 | /// 22 | Range = 2, 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/ShardMapManager.csproj.vspscc: -------------------------------------------------------------------------------- 1 | "" 2 | { 3 | "FILE_VERSION" = "9237" 4 | "ENLISTMENT_CHOICE" = "NEVER" 5 | "PROJECT_FILE_RELATIVE_PATH" = "" 6 | "NUMBER_OF_EXCLUDED_FILES" = "0" 7 | "ORIGINAL_PROJECT_FILE_PATH" = "" 8 | "NUMBER_OF_NESTED_PROJECTS" = "0" 9 | "SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" 10 | } 11 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/ShardMapManager/ShardManagementTransientErrorDetectionStrategy.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 7 | { 8 | /// 9 | /// Provides the transient error detection logic for transient faults that are specific to Shard map manager. 10 | /// 11 | internal sealed class ShardManagementTransientErrorDetectionStrategy : TransientFaultHandling.ITransientErrorDetectionStrategy 12 | { 13 | /// 14 | /// Delegate used for detecting transient faults. 15 | /// 16 | private Func _transientFaultDetector; 17 | 18 | /// 19 | /// Creates a new instance of transient error detection strategy for Shard map manager. 20 | /// 21 | /// User specified retry behavior. 22 | internal ShardManagementTransientErrorDetectionStrategy(RetryBehavior retryBehavior) 23 | { 24 | _transientFaultDetector = retryBehavior.TransientErrorDetector; 25 | } 26 | 27 | /// 28 | /// Determines whether the specified exception represents a transient failure that can be compensated by a retry. 29 | /// 30 | /// The exception object to be verified. 31 | /// true if the specified exception is considered as transient; otherwise, false. 32 | public bool IsTransient(Exception ex) 33 | { 34 | return SqlUtils.TransientErrorDetector(ex) || _transientFaultDetector(ex); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/ShardMapper/HashShardMapper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 5 | { 6 | #if FUTUREWORK 7 | /// 8 | /// Mapper that maps ranges of hashed key values to shards. 9 | /// 10 | /// Key type. 11 | /// Hashed key type. 12 | internal sealed class HashShardMapper : RangeShardMapper 13 | { 14 | /// 15 | /// Hash shard mapper, which managers hashed ranges. 16 | /// 17 | /// Reference to ShardMapManager. 18 | /// Containing shard map. 19 | internal HashShardMapper(ShardMapManager manager, ShardMap sm) 20 | : base(manager, sm) 21 | { 22 | } 23 | 24 | /// 25 | /// Hash function. 26 | /// 27 | internal Func HashFunction 28 | { 29 | get; 30 | set; 31 | } 32 | 33 | /// 34 | /// Function used to perform conversion of key type T to range type U. 35 | /// 36 | /// Input key. 37 | /// Mapped value of key. 38 | protected override U MapKeyTypeToRangeType(T key) 39 | { 40 | Debug.Assert(this.HashFunction != null); 41 | return this.HashFunction(key); 42 | } 43 | } 44 | #endif 45 | } 46 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/SqlStore/SqlLocation.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using Microsoft.Data.SqlClient; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 7 | { 8 | /// 9 | /// SQL backed storage representation of a location. 10 | /// 11 | internal sealed class SqlLocation : IStoreLocation 12 | { 13 | /// 14 | /// Constructs an instance of IStoreLocation using parts of a row from SqlDataReader. 15 | /// Used for creating the shard location instance. 16 | /// 17 | /// SqlDataReader whose row has shard information. 18 | /// Reader offset for column that begins shard information. 19 | internal SqlLocation(SqlDataReader reader, int offset) 20 | { 21 | this.Location = new ShardLocation( 22 | reader.GetString(offset + 1), 23 | reader.GetString(offset + 3), 24 | (SqlProtocol)reader.GetInt32(offset), 25 | reader.GetInt32(offset + 2)); 26 | } 27 | 28 | /// 29 | /// Data source location. 30 | /// 31 | public ShardLocation Location 32 | { 33 | get; 34 | private set; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/SqlStore/SqlSchemaInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Data.SqlTypes; 5 | using Microsoft.Data.SqlClient; 6 | 7 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 8 | { 9 | /// 10 | /// SQL backed storage representation of a schema info object. 11 | /// 12 | internal sealed class SqlSchemaInfo : IStoreSchemaInfo 13 | { 14 | /// 15 | /// Constructs an instance of IStoreSchemaInfo using parts of a row from SqlDataReader. 16 | /// 17 | /// SqlDataReader whose row has shard information. 18 | /// Reader offset for column that begins shard information. 19 | internal SqlSchemaInfo(SqlDataReader reader, int offset) 20 | { 21 | this.Name = reader.GetString(offset); 22 | this.ShardingSchemaInfo = reader.GetSqlXml(offset + 1); 23 | } 24 | 25 | /// 26 | /// Schema info name. 27 | /// 28 | public string Name 29 | { 30 | get; 31 | private set; 32 | } 33 | 34 | /// 35 | /// Schema info represented in XML. 36 | /// 37 | public SqlXml ShardingSchemaInfo 38 | { 39 | get; 40 | private set; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/SqlStore/SqlShard.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using Microsoft.Data.SqlClient; 6 | 7 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 8 | { 9 | /// 10 | /// SQL backed storage representation of a shard. 11 | /// 12 | internal sealed class SqlShard : IStoreShard 13 | { 14 | /// 15 | /// Constructs an instance of IStoreShard using parts of a row from SqlDataReader. 16 | /// Used for creating the shard instance for a mapping. 17 | /// 18 | /// SqlDataReader whose row has shard information. 19 | /// Reader offset for column that begins shard information. 20 | internal SqlShard(SqlDataReader reader, int offset) 21 | { 22 | this.Id = reader.GetGuid(offset); 23 | this.Version = reader.GetGuid(offset + 1); 24 | this.ShardMapId = reader.GetGuid(offset + 2); 25 | this.Location = new SqlLocation(reader, offset + 3).Location; 26 | this.Status = reader.GetInt32(offset + 7); 27 | } 28 | 29 | /// 30 | /// Shard Id. 31 | /// 32 | public Guid Id 33 | { 34 | get; 35 | private set; 36 | } 37 | 38 | /// 39 | /// Shard version. 40 | /// 41 | public Guid Version 42 | { 43 | get; 44 | private set; 45 | } 46 | 47 | /// 48 | /// Containing shard map's Id. 49 | /// 50 | public Guid ShardMapId 51 | { 52 | get; 53 | private set; 54 | } 55 | 56 | /// 57 | /// Data source location. 58 | /// 59 | public ShardLocation Location 60 | { 61 | get; 62 | private set; 63 | } 64 | 65 | /// 66 | /// Shard status. 67 | /// 68 | public int Status 69 | { 70 | get; 71 | private set; 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/SqlStore/SqlShardMap.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using Microsoft.Data.SqlClient; 6 | 7 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 8 | { 9 | /// 10 | /// SQL based storage representation of a shard map. 11 | /// 12 | internal class SqlShardMap : IStoreShardMap 13 | { 14 | /// 15 | /// Constructs an instance of IStoreShardMap using a row from SqlDataReader starting at specified offset. 16 | /// 17 | /// SqlDataReader whose row has shard map information. 18 | /// Reader offset for column that begins shard map information.. 19 | internal SqlShardMap(SqlDataReader reader, int offset) 20 | { 21 | this.Id = reader.GetGuid(offset); 22 | this.Name = reader.GetString(offset + 1); 23 | this.MapType = (ShardMapType)reader.GetInt32(offset + 2); 24 | this.KeyType = (ShardKeyType)reader.GetInt32(offset + 3); 25 | } 26 | 27 | /// 28 | /// Shard map's identity. 29 | /// 30 | public Guid Id 31 | { 32 | get; 33 | private set; 34 | } 35 | 36 | /// 37 | /// Shard map name. 38 | /// 39 | public string Name 40 | { 41 | get; 42 | private set; 43 | } 44 | 45 | /// 46 | /// Kind of shard map. 47 | /// 48 | public ShardMapType MapType 49 | { 50 | get; 51 | private set; 52 | } 53 | 54 | /// 55 | /// Key type. 56 | /// 57 | public ShardKeyType KeyType 58 | { 59 | get; 60 | private set; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/SqlStore/SqlStoreConnectionFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 5 | { 6 | /// 7 | /// Constructs instance of Sql Store Connection. 8 | /// 9 | internal class SqlStoreConnectionFactory : IStoreConnectionFactory 10 | { 11 | /// 12 | /// Constructs an instance of the factory. 13 | /// 14 | protected internal SqlStoreConnectionFactory() 15 | { 16 | } 17 | 18 | /// 19 | /// Constructs a new instance of store connection. 20 | /// 21 | /// Type of store connection. 22 | /// Connection info. 23 | /// An unopened instance of the store connection. 24 | public virtual IStoreConnection GetConnection( 25 | StoreConnectionKind kind, 26 | SqlConnectionInfo connectionInfo) 27 | { 28 | return new SqlStoreConnection(kind, connectionInfo); 29 | } 30 | 31 | /// 32 | /// Constructs a new instance of user connection. 33 | /// 34 | /// Connection info. 35 | /// An unopened instance of the user connection. 36 | public virtual IUserStoreConnection GetUserConnection(SqlConnectionInfo connectionInfo) 37 | { 38 | return new SqlUserStoreConnection(connectionInfo); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/SqlStore/SqlUserStoreConnection.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Threading.Tasks; 6 | using Microsoft.Data.SqlClient; 7 | 8 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 9 | { 10 | /// 11 | /// Instance of a User Sql Store Connection. 12 | /// 13 | internal class SqlUserStoreConnection : IUserStoreConnection 14 | { 15 | /// 16 | /// Underlying connection. 17 | /// 18 | private SqlConnection _conn; 19 | 20 | /// 21 | /// Creates a new instance of user store connection. 22 | /// 23 | /// Connection info. 24 | internal SqlUserStoreConnection(SqlConnectionInfo connectionInfo) 25 | { 26 | _conn = connectionInfo.CreateConnection(); 27 | } 28 | 29 | /// 30 | /// Underlying SQL server connection. 31 | /// 32 | public SqlConnection Connection 33 | { 34 | get 35 | { 36 | return _conn; 37 | } 38 | } 39 | 40 | /// 41 | /// Opens the connection. 42 | /// 43 | public void Open() 44 | { 45 | _conn.Open(); 46 | } 47 | 48 | /// 49 | /// Asynchronously opens the connection. 50 | /// 51 | /// Task to await completion of the Open 52 | public Task OpenAsync() 53 | { 54 | return _conn.OpenAsync(); 55 | } 56 | 57 | #region IDisposable 58 | 59 | /// 60 | /// Disposes the object. 61 | /// 62 | public void Dispose() 63 | { 64 | this.Dispose(true); 65 | GC.SuppressFinalize(this); 66 | } 67 | 68 | /// 69 | /// Performs actual Dispose of resources. 70 | /// 71 | /// Whether the invocation was from IDisposable.Dipose method. 72 | protected virtual void Dispose(bool disposing) 73 | { 74 | if (disposing) 75 | { 76 | _conn.Dispose(); 77 | _conn = null; 78 | } 79 | } 80 | 81 | #endregion IDisposable 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Store/DefaultStoreSchemaInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Data.SqlTypes; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 7 | { 8 | /// 9 | /// Used for generating storage representation from client side mapping objects. 10 | /// 11 | internal sealed class DefaultStoreSchemaInfo : IStoreSchemaInfo 12 | { 13 | /// 14 | /// Constructs the storage representation from client side objects. 15 | /// 16 | /// Schema info name. 17 | /// Schema info represented in XML. 18 | internal DefaultStoreSchemaInfo( 19 | string name, 20 | SqlXml shardingSchemaInfo) 21 | { 22 | this.Name = name; 23 | this.ShardingSchemaInfo = shardingSchemaInfo; 24 | } 25 | 26 | /// 27 | /// Schema info name. 28 | /// 29 | public string Name 30 | { 31 | get; 32 | private set; 33 | } 34 | 35 | /// 36 | /// Schema info represented in XML. 37 | /// 38 | public SqlXml ShardingSchemaInfo 39 | { 40 | get; 41 | private set; 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Store/DefaultStoreShard.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 7 | { 8 | /// 9 | /// Used for generating storage representation from client side shard objects. 10 | /// 11 | internal sealed class DefaultStoreShard : IStoreShard 12 | { 13 | /// 14 | /// Constructs the storage representation from client side objects. 15 | /// 16 | /// Shard Id. 17 | /// Shard version. 18 | /// Identify of shard map. 19 | /// Data source location. 20 | /// Status of the shard. 21 | internal DefaultStoreShard( 22 | Guid id, 23 | Guid version, 24 | Guid shardMapId, 25 | ShardLocation location, 26 | int status) 27 | { 28 | this.Id = id; 29 | this.Version = version; 30 | this.ShardMapId = shardMapId; 31 | this.Location = location; 32 | this.Status = status; 33 | } 34 | 35 | /// 36 | /// Shard Id. 37 | /// 38 | public Guid Id 39 | { 40 | get; 41 | private set; 42 | } 43 | 44 | /// 45 | /// Shard version. 46 | /// 47 | public Guid Version 48 | { 49 | get; 50 | private set; 51 | } 52 | 53 | /// 54 | /// Containing shard map's Id. 55 | /// 56 | public Guid ShardMapId 57 | { 58 | get; 59 | private set; 60 | } 61 | 62 | /// 63 | /// Data source location. 64 | /// 65 | public ShardLocation Location 66 | { 67 | get; 68 | private set; 69 | } 70 | 71 | /// 72 | /// Shard status. 73 | /// 74 | public int Status 75 | { 76 | get; 77 | private set; 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Store/DefaultStoreShardMap.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 7 | { 8 | /// 9 | /// Storage representation of a shard map. 10 | /// 11 | internal sealed class DefaultStoreShardMap : IStoreShardMap 12 | { 13 | /// 14 | /// Constructs an instance of DefaultStoreShardMap used for creating new shard maps. 15 | /// 16 | /// Shard map Id. 17 | /// Shard map name. 18 | /// Shard map kind. 19 | /// Shard map key type. 20 | /// Optional argument for shardId if this instance is for a local shardmap. 21 | internal DefaultStoreShardMap( 22 | Guid id, 23 | string name, 24 | ShardMapType mapType, 25 | ShardKeyType keyType, 26 | Guid? shardId = null) 27 | { 28 | this.Id = id; 29 | this.Name = name; 30 | this.MapType = mapType; 31 | this.KeyType = keyType; 32 | this.ShardId = shardId; 33 | } 34 | 35 | /// 36 | /// Shard map's identity. 37 | /// 38 | public Guid Id 39 | { 40 | get; 41 | private set; 42 | } 43 | 44 | /// 45 | /// Shard map name. 46 | /// 47 | public string Name 48 | { 49 | get; 50 | private set; 51 | } 52 | 53 | /// 54 | /// Type of shard map. 55 | /// 56 | public ShardMapType MapType 57 | { 58 | get; 59 | private set; 60 | } 61 | 62 | /// 63 | /// Key type. 64 | /// 65 | public ShardKeyType KeyType 66 | { 67 | get; 68 | private set; 69 | } 70 | 71 | /// 72 | /// The id of the local shardmap. Null if a global shardmap. 73 | /// 74 | public Guid? ShardId 75 | { 76 | get; 77 | private set; 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Store/IStoreConnection.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Threading.Tasks; 6 | 7 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 8 | { 9 | /// 10 | /// Types of store connections. 11 | /// 12 | internal enum StoreConnectionKind 13 | { 14 | /// 15 | /// Connection to GSM. 16 | /// 17 | Global, 18 | 19 | /// 20 | /// Connection to LSM Source Shard. 21 | /// 22 | LocalSource, 23 | 24 | /// 25 | /// Connection to LSM Target Shard (useful for Update Location operation only). 26 | /// 27 | LocalTarget 28 | } 29 | 30 | /// 31 | /// Instance of a store connection. 32 | /// 33 | internal interface IStoreConnection : IDisposable 34 | { 35 | /// 36 | /// Type of store connection. 37 | /// 38 | StoreConnectionKind Kind 39 | { 40 | get; 41 | } 42 | 43 | /// 44 | /// Open the store connection. 45 | /// 46 | void Open(); 47 | 48 | /// 49 | /// Asynchronously opens the store connection. 50 | /// 51 | /// Task to await completion of the Open 52 | Task OpenAsync(); 53 | 54 | /// 55 | /// Open the store connection, and acquire a lock on the store. 56 | /// 57 | /// Lock Id. 58 | void OpenWithLock(Guid lockId); 59 | 60 | /// 61 | /// Closes the store connection. 62 | /// 63 | void Close(); 64 | 65 | /// 66 | /// Closes the store connection after releasing lock. 67 | /// 68 | /// Lock Id. 69 | void CloseWithUnlock(Guid lockId); 70 | 71 | /// 72 | /// Acquires a transactional scope on the connection. 73 | /// 74 | /// Type of transaction scope. 75 | /// Transaction scope on the store connection. 76 | IStoreTransactionScope GetTransactionScope(StoreTransactionScopeKind kind); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Store/IStoreConnectionFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 5 | { 6 | /// 7 | /// Factory for store connections. 8 | /// 9 | internal interface IStoreConnectionFactory 10 | { 11 | /// 12 | /// Constructs a new instance of store connection. 13 | /// 14 | /// Type of store connection. 15 | /// Connection info. 16 | /// An unopened instance of the store connection. 17 | IStoreConnection GetConnection( 18 | StoreConnectionKind kind, 19 | SqlConnectionInfo connectionInfo); 20 | 21 | /// 22 | /// Constructs a new instance of user connection. 23 | /// 24 | /// Connection info. 25 | /// An unopened instance of the user connection. 26 | IUserStoreConnection GetUserConnection( 27 | SqlConnectionInfo connectionInfo); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Store/IStoreLocation.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 5 | { 6 | /// 7 | /// Storage representation of a single location. 8 | /// 9 | internal interface IStoreLocation 10 | { 11 | /// 12 | /// Data source location. 13 | /// 14 | ShardLocation Location 15 | { 16 | get; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Store/IStoreLogEntry.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Data.SqlTypes; 6 | 7 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 8 | { 9 | /// 10 | /// Represents a store operation. 11 | /// 12 | internal interface IStoreLogEntry 13 | { 14 | /// 15 | /// Identity of operation. 16 | /// 17 | Guid Id 18 | { 19 | get; 20 | } 21 | 22 | /// 23 | /// Operation code. Helps in deserialization during factory method. 24 | /// 25 | StoreOperationCode OpCode 26 | { 27 | get; 28 | } 29 | 30 | /// 31 | /// Serialized representation of the operation. 32 | /// 33 | SqlXml Data 34 | { 35 | get; 36 | } 37 | 38 | /// 39 | /// State from which Undo will start. 40 | /// 41 | StoreOperationState UndoStartState 42 | { 43 | get; 44 | } 45 | 46 | /// 47 | /// Original shard version for remove steps. 48 | /// 49 | Guid OriginalShardVersionRemoves 50 | { 51 | get; 52 | } 53 | 54 | /// 55 | /// Original shard version for add steps. 56 | /// 57 | Guid OriginalShardVersionAdds 58 | { 59 | get; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Store/IStoreMapping.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 7 | { 8 | /// 9 | /// Storage representation of a mapping b/w key ranges and shards. 10 | /// 11 | internal interface IStoreMapping 12 | { 13 | /// 14 | /// Mapping Id. 15 | /// 16 | Guid Id 17 | { 18 | get; 19 | } 20 | 21 | /// 22 | /// Shard map Id. 23 | /// 24 | Guid ShardMapId 25 | { 26 | get; 27 | } 28 | 29 | /// 30 | /// Min value. 31 | /// 32 | byte[] MinValue 33 | { 34 | get; 35 | } 36 | 37 | /// 38 | /// Max value. 39 | /// 40 | byte[] MaxValue 41 | { 42 | get; 43 | } 44 | 45 | /// 46 | /// Mapping status. 47 | /// 48 | int Status 49 | { 50 | get; 51 | } 52 | 53 | /// 54 | /// Lock owner id of this mapping 55 | /// 56 | Guid LockOwnerId 57 | { 58 | get; 59 | } 60 | 61 | /// 62 | /// Shard referenced by mapping. 63 | /// 64 | IStoreShard StoreShard 65 | { 66 | get; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Store/IStoreSchemaInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Data.SqlTypes; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 7 | { 8 | /// 9 | /// Storage representation of a shard schema info. 10 | /// 11 | internal interface IStoreSchemaInfo 12 | { 13 | /// 14 | /// Schema info name. 15 | /// 16 | string Name 17 | { 18 | get; 19 | } 20 | 21 | /// 22 | /// Schema info represented in XML. 23 | /// 24 | SqlXml ShardingSchemaInfo 25 | { 26 | get; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Store/IStoreShard.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 7 | { 8 | /// 9 | /// Storage representation of a single shard. 10 | /// 11 | internal interface IStoreShard 12 | { 13 | /// 14 | /// Shard Id. 15 | /// 16 | Guid Id 17 | { 18 | get; 19 | } 20 | 21 | /// 22 | /// Shard version. 23 | /// 24 | Guid Version 25 | { 26 | get; 27 | } 28 | 29 | /// 30 | /// Containing shard map's Id. 31 | /// 32 | Guid ShardMapId 33 | { 34 | get; 35 | } 36 | 37 | /// 38 | /// Data source location. 39 | /// 40 | ShardLocation Location 41 | { 42 | get; 43 | } 44 | 45 | /// 46 | /// Shard status. 47 | /// 48 | int Status 49 | { 50 | get; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Store/IStoreShardMap.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 7 | { 8 | /// 9 | /// Store representation of a shard map. 10 | /// 11 | internal interface IStoreShardMap 12 | { 13 | /// 14 | /// Shard map's identity. 15 | /// 16 | Guid Id 17 | { 18 | get; 19 | } 20 | 21 | /// 22 | /// Shard map name. 23 | /// 24 | string Name 25 | { 26 | get; 27 | } 28 | 29 | /// 30 | /// Type of shard map. 31 | /// 32 | ShardMapType MapType 33 | { 34 | get; 35 | } 36 | 37 | /// 38 | /// Key type. 39 | /// 40 | ShardKeyType KeyType 41 | { 42 | get; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Store/IStoreVersion.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 7 | { 8 | /// 9 | /// Storage representation of shard map manager version 10 | /// 11 | internal interface IStoreVersion 12 | { 13 | /// 14 | /// Store version information. 15 | /// 16 | Version Version 17 | { 18 | get; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Store/IUserStoreConnection.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Threading.Tasks; 6 | using Microsoft.Data.SqlClient; 7 | 8 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 9 | { 10 | /// 11 | /// Instance of a user connection to store. 12 | /// 13 | internal interface IUserStoreConnection : IDisposable 14 | { 15 | /// 16 | /// Underlying SQL server connection. 17 | /// 18 | SqlConnection Connection 19 | { 20 | get; 21 | } 22 | 23 | /// 24 | /// Opens the connection. 25 | /// 26 | void Open(); 27 | 28 | /// 29 | /// Asynchronously opens the connection. 30 | /// 31 | /// Task to await completion of the Open 32 | Task OpenAsync(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Store/SqlVersion.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using Microsoft.Data.SqlClient; 6 | 7 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 8 | { 9 | /// 10 | /// SQL backed storage representation of shard map manager store version. 11 | /// 12 | internal class SqlVersion : IStoreVersion 13 | { 14 | /// 15 | /// Constructs an instance of IStoreVersion using parts of a row from SqlDataReader. 16 | /// 17 | /// SqlDataReader whose row has shard information. 18 | /// Reader offset for column that begins shard information. 19 | internal SqlVersion(SqlDataReader reader, int offset) 20 | { 21 | int Major = reader.GetInt32(offset); 22 | int Minor = (reader.FieldCount > offset + 1) ? reader.GetInt32(offset + 1) : 0; 23 | this.Version = new Version(Major, Minor); 24 | } 25 | 26 | /// 27 | /// Store version. 28 | /// 29 | public Version Version 30 | { 31 | get; 32 | private set; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/StoreOperations/Base/IStoreOperationLocal.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 7 | { 8 | /// 9 | /// Represents an LSM only store operation. 10 | /// 11 | internal interface IStoreOperationLocal : IDisposable 12 | { 13 | /// 14 | /// Whether this is a read-only operation. 15 | /// 16 | bool ReadOnly 17 | { 18 | get; 19 | } 20 | 21 | /// 22 | /// Performs the store operation. 23 | /// 24 | /// Results of the operation. 25 | IStoreResults Do(); 26 | 27 | /// 28 | /// Execute the operation against LSM in the current transaction scope. 29 | /// 30 | /// Transaction scope. 31 | /// 32 | /// Results of the operation. 33 | /// 34 | IStoreResults DoLocalExecute(IStoreTransactionScope ts); 35 | 36 | /// 37 | /// Handles errors from the LSM operation. 38 | /// 39 | /// Operation result. 40 | void HandleDoLocalExecuteError(IStoreResults result); 41 | 42 | /// 43 | /// Returns the ShardManagementException to be thrown corresponding to a StoreException. 44 | /// 45 | /// Store exception that has been raised. 46 | /// ShardManagementException to be thrown. 47 | ShardManagementException OnStoreException(StoreException se); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/StoreOperations/Base/StoreConnectionInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 5 | { 6 | /// 7 | /// Provides information regarding LSM connections. 8 | /// 9 | internal class StoreConnectionInfo 10 | { 11 | /// 12 | /// Optional source shard location. 13 | /// 14 | internal ShardLocation SourceLocation 15 | { 16 | get; 17 | set; 18 | } 19 | 20 | /// 21 | /// Optional target shard location. 22 | /// 23 | internal ShardLocation TargetLocation 24 | { 25 | get; 26 | set; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/StoreOperations/Base/StoreOperationCode.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 5 | { 6 | /// 7 | /// Operation codes identifying various store operations. 8 | /// 9 | internal enum StoreOperationCode 10 | { 11 | AddShard = 1, 12 | RemoveShard = 2, 13 | UpdateShard = 3, 14 | 15 | AddPointMapping = 4, 16 | RemovePointMapping = 5, 17 | UpdatePointMapping = 6, 18 | UpdatePointMappingWithOffline = 7, 19 | 20 | AddRangeMapping = 8, 21 | RemoveRangeMapping = 9, 22 | UpdateRangeMapping = 10, 23 | UpdateRangeMappingWithOffline = 11, 24 | 25 | SplitMapping = 14, 26 | MergeMappings = 15, 27 | 28 | AttachShard = 16 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/StoreOperations/Base/StoreOperationTransactionScopeKind.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 5 | { 6 | /// 7 | /// Types of transaction scopes used during store operations. 8 | /// 9 | internal enum StoreOperationTransactionScopeKind 10 | { 11 | /// 12 | /// Scope of GSM. 13 | /// 14 | Global, 15 | 16 | /// 17 | /// Scope of source LSM. 18 | /// 19 | LocalSource, 20 | 21 | /// 22 | /// Scope of target LSM. 23 | /// 24 | LocalTarget 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Utils/ICloneable.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 5 | { 6 | /// 7 | /// Represents objects that can clone themselves. 8 | /// 9 | /// Type of object 10 | internal interface ICloneable where T : ICloneable 11 | { 12 | /// 13 | /// Clones the instance which implements the interface. 14 | /// 15 | /// Clone of the instance. 16 | T Clone(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Utils/ReflectionUtils.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Reflection; 6 | 7 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.Utils 8 | { 9 | internal static class ReflectionUtils 10 | { 11 | public static Assembly GetAssembly(this Type type) 12 | { 13 | return type.GetTypeInfo().Assembly; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Src/ElasticScale.Client/ShardManagement/Utils/TimerUtils.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Diagnostics; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement 7 | { 8 | /// 9 | /// Utility class for high precision time keeping. 10 | /// 11 | internal class TimerUtils 12 | { 13 | /// 14 | /// Ticks per millisecond = 10,000 15 | /// 16 | private const long TicksPerMilliSecond = 10000L; 17 | 18 | /// 19 | /// Ticks per second = 10,000,000 20 | /// 21 | private const double TicksPerSecond = 10000000.0; 22 | 23 | /// 24 | /// Frequency per tick of timer. 25 | /// 26 | private static double s_tickFrequency; 27 | 28 | /// 29 | /// Finds the appropriate tick frequency based on the timer we are using. 30 | /// 31 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline")] 32 | static TimerUtils() 33 | { 34 | if (Stopwatch.IsHighResolution) 35 | { 36 | s_tickFrequency = TicksPerSecond / ((double)Stopwatch.Frequency); 37 | } 38 | else 39 | { 40 | s_tickFrequency = 1.0; 41 | } 42 | } 43 | 44 | /// 45 | /// Obtains the current timestamp. 46 | /// 47 | /// Current timestamp. 48 | internal static long GetTimestamp() 49 | { 50 | return Stopwatch.GetTimestamp(); 51 | } 52 | 53 | /// 54 | /// Finds the time that has elapsed since the given . 55 | /// 56 | /// Original start timestamp. 57 | /// Milliseconds interval b/w original and current time. 58 | internal static long ElapsedMillisecondsSince(long startTimestamp) 59 | { 60 | long elapsedTime = Stopwatch.GetTimestamp() - startTimestamp; 61 | 62 | if (Stopwatch.IsHighResolution) 63 | { 64 | return ((long)(((double)elapsedTime) * s_tickFrequency)) / TicksPerMilliSecond; 65 | } 66 | else 67 | { 68 | return elapsedTime / TicksPerMilliSecond; 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Test/ElasticScale.ClientTestCommon/CommonTestUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Runtime.Serialization.Formatters.Binary; 4 | 5 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.Test.Common 6 | { 7 | public static class CommonTestUtils 8 | { 9 | public static T SerializeDeserialize(T originalException) where T : Exception 10 | { 11 | using (MemoryStream memStream = new MemoryStream()) 12 | { 13 | BinaryFormatter formatter = new BinaryFormatter(); 14 | 15 | formatter.Serialize(memStream, originalException); 16 | memStream.Seek(0, SeekOrigin.Begin); 17 | 18 | return (T)formatter.Deserialize(memStream); 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Test/ElasticScale.ClientTestCommon/Microsoft.Azure.SqlDatabase.ElasticScale.ClientTestCommon.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | netstandard2.0 4 | $(NoWarn);SYSLIB0011; 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Test/ElasticScale.ClientTestCommon/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Resources; 3 | using System.Runtime.InteropServices; 4 | 5 | // Setting ComVisible to false makes the types in this assembly not visible 6 | // to COM components. If you need to access a type in this assembly from 7 | // COM, set the ComVisible attribute to true on that type. 8 | [assembly: ComVisible(false)] 9 | [assembly: CLSCompliant(true)] 10 | [assembly: NeutralResourcesLanguage("en-US")] 11 | -------------------------------------------------------------------------------- /Test/ElasticScale.Query.UnitTests/DataSetExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Data; 2 | 3 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.Query.UnitTests 4 | { 5 | #if !NET451 6 | static class DataSetExtensions 7 | { 8 | public static T Field(this DataRow dataSet, int index) 9 | { 10 | return (T)dataSet[index]; 11 | } 12 | } 13 | #endif 14 | } 15 | -------------------------------------------------------------------------------- /Test/ElasticScale.Query.UnitTests/EnumerableHelpers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Threading; 5 | 6 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.Query.UnitTests 7 | { 8 | public static class EnumerableHelpers 9 | { 10 | public static IEnumerable ToConsumable(this IEnumerable source) 11 | { 12 | return new ConsumingEnumerable(source); 13 | } 14 | 15 | /// 16 | /// IEnumerable wrapper that can only be enumerated once. 17 | /// 18 | /// 19 | public class ConsumingEnumerable : IEnumerable 20 | { 21 | private IEnumerable _source; 22 | private int _consumed; 23 | 24 | public ConsumingEnumerable(IEnumerable source) 25 | { 26 | _source = source; 27 | _consumed = 0; 28 | } 29 | 30 | public IEnumerator GetEnumerator() 31 | { 32 | int wasConsumed = Interlocked.Exchange(ref _consumed, 1); 33 | if (wasConsumed == 0) 34 | { 35 | return _source.GetEnumerator(); 36 | } 37 | else 38 | { 39 | throw new InvalidOperationException("GetEnumerator() has already been called. Cannot enumerate more than once"); 40 | } 41 | } 42 | 43 | IEnumerator IEnumerable.GetEnumerator() 44 | { 45 | return GetEnumerator(); 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Test/ElasticScale.Query.UnitTests/Microsoft.Azure.SqlDatabase.ElasticScale.Query.UnitTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net6.0;net8.0;net481 4 | true 5 | false 6 | $(NoWarn);CS8073; 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Test/ElasticScale.Query.UnitTests/Microsoft.Azure.SqlDatabase.ElasticScale.Query.UnitTests.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Component 7 | 8 | 9 | Component 10 | 11 | 12 | -------------------------------------------------------------------------------- /Test/ElasticScale.Query.UnitTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Runtime.InteropServices; 5 | 6 | // Setting ComVisible to false makes the types in this assembly not visible 7 | // to COM components. If you need to access a type in this assembly from 8 | // COM, set the ComVisible attribute to true on that type. 9 | [assembly: ComVisible(false)] 10 | 11 | // The following GUID is for the ID of the typelib if this project is exposed to COM 12 | [assembly: Guid("712279df-5976-45b4-97ce-cec4a76553bc")] 13 | -------------------------------------------------------------------------------- /Test/ElasticScale.ShardManagement.LoadTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ShardMapManagerLoadTests")] 9 | [assembly: AssemblyDescription("")] 10 | 11 | // Setting ComVisible to false makes the types in this assembly not visible 12 | // to COM components. If you need to access a type in this assembly from 13 | // COM, set the ComVisible attribute to true on that type. 14 | [assembly: ComVisible(false)] 15 | 16 | // The following GUID is for the ID of the typelib if this project is exposed to COM 17 | [assembly: Guid("96c42e15-4ea2-4ca1-b4eb-8041f10a5d0b")] 18 | 19 | -------------------------------------------------------------------------------- /Test/ElasticScale.ShardManagement.UnitTests/Decorators/CacheStoreDecorator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.UnitTests 5 | { 6 | internal class CacheStoreDecorator : ICacheStore 7 | { 8 | protected readonly ICacheStore inner; 9 | 10 | internal CacheStoreDecorator(ICacheStore inner) 11 | { 12 | this.inner = inner; 13 | } 14 | 15 | public virtual void AddOrUpdateShardMap(IStoreShardMap shardMap) 16 | { 17 | this.inner.AddOrUpdateShardMap(shardMap); 18 | } 19 | 20 | public virtual void DeleteShardMap(IStoreShardMap shardMap) 21 | { 22 | this.inner.DeleteShardMap(shardMap); 23 | } 24 | 25 | public virtual IStoreShardMap LookupShardMapByName(string shardMapName) 26 | { 27 | return this.inner.LookupShardMapByName(shardMapName); 28 | } 29 | 30 | public virtual void AddOrUpdateMapping(IStoreMapping mapping, CacheStoreMappingUpdatePolicy policy) 31 | { 32 | this.inner.AddOrUpdateMapping(mapping, policy); 33 | } 34 | 35 | public virtual void DeleteMapping(IStoreMapping mapping) 36 | { 37 | this.inner.DeleteMapping(mapping); 38 | } 39 | 40 | public virtual ICacheStoreMapping LookupMappingByKey(IStoreShardMap shardMap, ShardKey key) 41 | { 42 | return this.inner.LookupMappingByKey(shardMap, key); 43 | } 44 | 45 | public virtual void IncrementPerformanceCounter(IStoreShardMap shardMap, PerformanceCounterName name) 46 | { 47 | this.inner.IncrementPerformanceCounter(shardMap, name); 48 | } 49 | 50 | public virtual void Clear() 51 | { 52 | this.inner.Clear(); 53 | } 54 | 55 | public virtual void Dispose() 56 | { 57 | this.inner.Dispose(); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Test/ElasticScale.ShardManagement.UnitTests/Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.UnitTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net6.0;net8.0;net481 4 | true 5 | false 6 | 0649;$(NoWarn) 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Test/ElasticScale.ShardManagement.UnitTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Runtime.InteropServices; 5 | 6 | // Setting ComVisible to false makes the types in this assembly not visible 7 | // to COM components. If you need to access a type in this assembly from 8 | // COM, set the ComVisible attribute to true on that type. 9 | [assembly: ComVisible(false)] 10 | 11 | // The following GUID is for the ID of the typelib if this project is exposed to COM 12 | [assembly: Guid("d4d94cc8-1452-4523-8bc4-b26cd51d6cf5")] 13 | 14 | -------------------------------------------------------------------------------- /Test/ElasticScale.ShardManagement.UnitTests/ShardMapManagerUnitTests.csproj.vspscc: -------------------------------------------------------------------------------- 1 | "" 2 | { 3 | "FILE_VERSION" = "9237" 4 | "ENLISTMENT_CHOICE" = "NEVER" 5 | "PROJECT_FILE_RELATIVE_PATH" = "" 6 | "NUMBER_OF_EXCLUDED_FILES" = "0" 7 | "ORIGINAL_PROJECT_FILE_PATH" = "" 8 | "NUMBER_OF_NESTED_PROJECTS" = "0" 9 | "SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" 10 | } 11 | -------------------------------------------------------------------------------- /Test/ElasticScale.ShardManagement.UnitTests/Stubs/IStubBehavior.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.UnitTests.Stubs 4 | { 5 | class IStubBehavior 6 | { 7 | public TReturn Result(T obj, string name) 8 | { 9 | throw new NotImplementedException(); 10 | } 11 | 12 | public void VoidResult(T obj, string name) 13 | { 14 | throw new NotImplementedException(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Test/ElasticScale.ShardManagement.UnitTests/Stubs/StubBehaviors.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.UnitTests.Stubs 4 | { 5 | static class StubBehaviors 6 | { 7 | public static IStubBehavior GetValueOrCurrent(IStubBehavior stubBehavior) 8 | { 9 | throw new NotImplementedException(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | true 4 | 5 | -------------------------------------------------------------------------------- /elastic-db-tools.publickey: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/elastic-db-tools/b31d748a577d5920508cb19afb626a85df2408ca/elastic-db-tools.publickey -------------------------------------------------------------------------------- /elastic-db-tools.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/elastic-db-tools/b31d748a577d5920508cb19afb626a85df2408ca/elastic-db-tools.snk -------------------------------------------------------------------------------- /strongname.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | $(MSBuildThisFileDirectory)\elastic-db-tools.snk 6 | true 7 | true 8 | 9 | --------------------------------------------------------------------------------