This commit is contained in:
Alexander Ivanov 2016-10-04 16:06:16 -07:00
Родитель 6ab27d8eaf
Коммит 12dee7c3f0
244 изменённых файлов: 2783 добавлений и 1086 удалений

3
.gitignore поставляемый
Просмотреть файл

@ -190,3 +190,6 @@ FakesAssemblies/
GeneratedArtifacts/
_Pvt_Extensions/
ModelManifest.xml
# Visual Studio data
.vs/

Просмотреть файл

@ -11,9 +11,9 @@
</packageRestore>
<packageSources>
<clear />
<add key="Nuget.Org" value="https://www.nuget.org/api/v2/" />
<add key="Nuget.Org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
<disabledPackageSources/>
<disabledPackageSources />
<activePackageSource>
<add key="All" value="(Aggregate source)" />
</activePackageSource>

Просмотреть файл

@ -36,37 +36,43 @@
<CodeAnalysisRuleSet>ManagedMinimumRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Data.Edm, Version=5.6.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.Data.Edm.5.6.2\lib\net40\Microsoft.Data.Edm.dll</HintPath>
<Reference Include="Castle.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Data.OData, Version=5.6.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.Data.OData.5.6.2\lib\net40\Microsoft.Data.OData.dll</HintPath>
<Reference Include="Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.KeyVault.Core.1.0.0\lib\net40\Microsoft.Azure.KeyVault.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Data.Services.Client, Version=5.6.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.Data.Services.Client.5.6.2\lib\net40\Microsoft.Data.Services.Client.dll</HintPath>
<Reference Include="Microsoft.Data.Edm, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Data.Edm.5.6.4\lib\net40\Microsoft.Data.Edm.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.WindowsAzure.ConfigurationManager.2.0.3\lib\net40\Microsoft.WindowsAzure.Configuration.dll</HintPath>
<Reference Include="Microsoft.Data.OData, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Data.OData.5.6.4\lib\net40\Microsoft.Data.OData.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Storage, Version=4.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\WindowsAzure.Storage.4.3.0\lib\net40\Microsoft.WindowsAzure.Storage.dll</HintPath>
<Reference Include="Microsoft.Data.Services.Client, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Data.Services.Client.5.6.4\lib\net40\Microsoft.Data.Services.Client.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Moq">
<HintPath>..\..\packages\Moq.4.2.1409.1722\lib\net40\Moq.dll</HintPath>
<Reference Include="Microsoft.WindowsAzure.Storage, Version=7.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\WindowsAzure.Storage.7.2.0\lib\net40\Microsoft.WindowsAzure.Storage.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Moq, Version=4.5.21.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<HintPath>..\..\packages\Moq.4.5.21\lib\net45\Moq.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Newtonsoft.Json.6.0.5\lib\net45\Newtonsoft.Json.dll</HintPath>
<HintPath>..\..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Spatial, Version=5.6.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\System.Spatial.5.6.2\lib\net40\System.Spatial.dll</HintPath>
<Reference Include="System.Spatial, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Spatial.5.6.4\lib\net40\System.Spatial.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<Choose>

Просмотреть файл

@ -1,11 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Data.Edm" version="5.6.2" targetFramework="net45" />
<package id="Microsoft.Data.OData" version="5.6.2" targetFramework="net45" />
<package id="Microsoft.Data.Services.Client" version="5.6.2" targetFramework="net45" />
<package id="Microsoft.WindowsAzure.ConfigurationManager" version="2.0.3" targetFramework="net45" />
<package id="Moq" version="4.2.1409.1722" targetFramework="net45" />
<package id="Newtonsoft.Json" version="6.0.5" targetFramework="net45" />
<package id="System.Spatial" version="5.6.2" targetFramework="net45" />
<package id="WindowsAzure.Storage" version="4.3.0" targetFramework="net45" />
<package id="Castle.Core" version="3.3.3" targetFramework="net451" />
<package id="Microsoft.Azure.KeyVault.Core" version="1.0.0" targetFramework="net451" />
<package id="Microsoft.Data.Edm" version="5.6.4" targetFramework="net451" />
<package id="Microsoft.Data.OData" version="5.6.4" targetFramework="net451" />
<package id="Microsoft.Data.Services.Client" version="5.6.4" targetFramework="net451" />
<package id="Moq" version="4.5.21" targetFramework="net451" />
<package id="Newtonsoft.Json" version="6.0.8" targetFramework="net451" />
<package id="System.Spatial" version="5.6.4" targetFramework="net451" />
<package id="WindowsAzure.Storage" version="7.2.0" targetFramework="net451" />
</packages>

Просмотреть файл

@ -60,6 +60,7 @@
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Shared\AzureStorageLocationModeValueConverter.cs" />
<Compile Include="Shared\AzureTableAdapterConfiguration.cs" />
<Compile Include="Shared\AzureTableAdapterConfigurationProvider.cs" />
<Compile Include="Shared\AzureTableAdapterConnectionConfigurationControl.xaml.cs">

Просмотреть файл

@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.18444
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@ -60,6 +60,42 @@ namespace Microsoft.DataTransfer.AzureTable.Wpf {
}
}
/// <summary>
/// Looks up a localized string similar to Primary only.
/// </summary>
internal static string AzureStorageLocationMode_PrimaryOnly {
get {
return ResourceManager.GetString("AzureStorageLocationMode_PrimaryOnly", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Primary, then secondary.
/// </summary>
internal static string AzureStorageLocationMode_PrimaryThenSecondary {
get {
return ResourceManager.GetString("AzureStorageLocationMode_PrimaryThenSecondary", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Secondary only.
/// </summary>
internal static string AzureStorageLocationMode_SecondaryOnly {
get {
return ResourceManager.GetString("AzureStorageLocationMode_SecondaryOnly", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Secondary, then primary.
/// </summary>
internal static string AzureStorageLocationMode_SecondaryThenPrimary {
get {
return ResourceManager.GetString("AzureStorageLocationMode_SecondaryThenPrimary", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Verify Connection.
/// </summary>

Просмотреть файл

@ -117,6 +117,18 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AzureStorageLocationMode_PrimaryOnly" xml:space="preserve">
<value>Primary only</value>
</data>
<data name="AzureStorageLocationMode_PrimaryThenSecondary" xml:space="preserve">
<value>Primary, then secondary</value>
</data>
<data name="AzureStorageLocationMode_SecondaryOnly" xml:space="preserve">
<value>Secondary only</value>
</data>
<data name="AzureStorageLocationMode_SecondaryThenPrimary" xml:space="preserve">
<value>Secondary, then primary</value>
</data>
<data name="TestConnectionResultTitle" xml:space="preserve">
<value>Verify Connection</value>
</data>

Просмотреть файл

@ -0,0 +1,21 @@
using Microsoft.DataTransfer.AzureTable.Shared;
using Microsoft.DataTransfer.WpfHost.Basics.ValueConverters;
using System.Collections.Generic;
namespace Microsoft.DataTransfer.AzureTable.Wpf.Shared
{
sealed class AzureStorageLocationModeValueConverter : EnumDisplayNameValueConverter.Base<AzureStorageLocationMode>
{
private static IDictionary<AzureStorageLocationMode, string> KnownValues =
new Dictionary<AzureStorageLocationMode, string>
{
{ AzureStorageLocationMode.PrimaryOnly, Resources.AzureStorageLocationMode_PrimaryOnly },
{ AzureStorageLocationMode.PrimaryThenSecondary, Resources.AzureStorageLocationMode_PrimaryThenSecondary },
{ AzureStorageLocationMode.SecondaryOnly, Resources.AzureStorageLocationMode_SecondaryOnly },
{ AzureStorageLocationMode.SecondaryThenPrimary, Resources.AzureStorageLocationMode_SecondaryThenPrimary }
};
public AzureStorageLocationModeValueConverter()
: base(KnownValues) { }
}
}

Просмотреть файл

@ -9,12 +9,27 @@ namespace Microsoft.DataTransfer.AzureTable.Wpf.Shared
public static readonly string ConnectionStringPropertyName =
ObjectExtensions.MemberName<IAzureTableAdapterConfiguration>(c => c.ConnectionString);
public static readonly string LocationModePropertyName =
ObjectExtensions.MemberName<IAzureTableAdapterConfiguration>(c => c.LocationMode);
private string connectionString;
private AzureStorageLocationMode? locationMode;
public string ConnectionString
{
get { return connectionString; }
set { SetProperty(ref connectionString, value, ValidateNonEmptyString); }
}
public AzureStorageLocationMode? LocationMode
{
get { return locationMode; }
set { SetProperty(ref locationMode, value); }
}
public AzureTableAdapterConfiguration()
{
LocationMode = Defaults.Current.LocationMode;
}
}
}

Просмотреть файл

@ -13,6 +13,11 @@ namespace Microsoft.DataTransfer.AzureTable.Wpf.Shared
Guard.NotNull("arguments", arguments);
arguments.Add(AzureTableAdapterConfiguration.ConnectionStringPropertyName, configuration.ConnectionString);
if (configuration.LocationMode.HasValue && configuration.LocationMode.Value != Defaults.Current.LocationMode)
arguments.Add(
AzureTableAdapterConfiguration.LocationModePropertyName,
configuration.LocationMode.Value.ToString());
}
}
}

Просмотреть файл

@ -4,15 +4,18 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:Microsoft.DataTransfer.AzureTable.Wpf.Shared"
mc:Ignorable="d" x:ClassModifier="internal"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="..\XamlResources.xaml"/>
<ResourceDictionary Source="..\XamlResources.xaml" />
</ResourceDictionary.MergedDictionaries>
<ObjectDataProvider x:Key="LocationModeValues" ObjectType="{x:Type local:AzureStorageLocationModeValueConverter}" MethodName="GetDisplayNames" />
<Style x:Key="ConnectionStringConfiguration" TargetType="Grid">
<Style.Resources>
<Style TargetType="Button">
@ -24,20 +27,32 @@
</ResourceDictionary>
</UserControl.Resources>
<StackPanel x:Name="LayoutRoot" Style="{StaticResource OptionElement}">
<Label Content="{DynamicResource ConnectionStringKey}" />
<AdornerDecorator>
<StackPanel x:Name="LayoutRoot">
<StackPanel Style="{StaticResource OptionElement}">
<Label Content="{DynamicResource ConnectionStringKey}" />
<Grid Style="{StaticResource ConnectionStringConfiguration}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid Style="{StaticResource ConnectionStringConfiguration}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="{Binding Configuration.ConnectionString, UpdateSourceTrigger=PropertyChanged, TargetNullValue={x:Static system:String.Empty}}" />
<Button Grid.Column="1" Validation.ErrorTemplate="{x:Null}"
Content="{DynamicResource TestConnectionKey}"
Command="{Binding TestConnection}" CommandParameter="{Binding Configuration.ConnectionString}" />
</Grid>
</StackPanel>
<TextBox Grid.Column="0" Text="{Binding Configuration.ConnectionString, UpdateSourceTrigger=PropertyChanged, TargetNullValue={x:Static system:String.Empty}}" />
<Button Grid.Column="1" Validation.ErrorTemplate="{x:Null}"
Content="{DynamicResource TestConnectionKey}"
Command="{Binding TestConnection}" CommandParameter="{Binding Configuration}" />
</Grid>
</StackPanel>
<StackPanel Style="{StaticResource OptionElement}">
<Label Content="{DynamicResource LocationModeKey}" />
<ComboBox
ItemsSource="{Binding Source={StaticResource LocationModeValues}}"
SelectedValue="{Binding Configuration.LocationMode}" SelectedValuePath="Key"
DisplayMemberPath="Value" />
</StackPanel>
</StackPanel>
</AdornerDecorator>
</UserControl>

Просмотреть файл

@ -1,4 +1,5 @@
using Microsoft.DataTransfer.AzureTable.Client;
using Microsoft.DataTransfer.AzureTable.Shared;
using Microsoft.DataTransfer.Basics;
using Microsoft.DataTransfer.WpfHost.Basics.Commands;
using System;
@ -18,7 +19,12 @@ namespace Microsoft.DataTransfer.AzureTable.Wpf.Shared
protected override async Task ExecuteAsync(object parameter)
{
await probeClient.TestConnection(parameter as string);
var configuration = parameter as IAzureTableAdapterConfiguration;
if (configuration == null)
return;
await probeClient.TestConnection(configuration.ConnectionString, configuration.LocationMode);
MessageBox.Show(
Resources.TestConnectionSuccessMessage,

Просмотреть файл

@ -3,14 +3,17 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:shared="clr-namespace:Microsoft.DataTransfer.AzureTable.Wpf.Shared"
mc:Ignorable="d" x:ClassModifier="internal"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="..\XamlResources.xaml"/>
<ResourceDictionary Source="..\XamlResources.xaml" />
</ResourceDictionary.MergedDictionaries>
<shared:AzureStorageLocationModeValueConverter x:Key="LocationModeConverter" />
</ResourceDictionary>
</UserControl.Resources>
@ -25,6 +28,7 @@
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="{DynamicResource ConnectionStringSummaryKey}" />
@ -32,23 +36,28 @@
<TextBlock Text="{Binding ConnectionString}" />
</Label>
<Label Grid.Row="1" Grid.Column="0" Content="{DynamicResource TableNameSummaryKey}" />
<Label Grid.Row="1" Grid.Column="0" Content="{DynamicResource LocationModeSummaryKey}" />
<Label Grid.Row="1" Grid.Column="1">
<TextBlock Text="{Binding LocationMode, Converter={StaticResource LocationModeConverter}}" />
</Label>
<Label Grid.Row="2" Grid.Column="0" Content="{DynamicResource TableNameSummaryKey}" />
<Label Grid.Row="2" Grid.Column="1">
<TextBlock Text="{Binding Table}" />
</Label>
<Label Grid.Row="2" Grid.Column="0" Content="{DynamicResource InternalFieldsSummaryKey}" />
<Label Grid.Row="2" Grid.Column="1">
<Label Grid.Row="3" Grid.Column="0" Content="{DynamicResource InternalFieldsSummaryKey}" />
<Label Grid.Row="3" Grid.Column="1">
<TextBlock Text="{Binding InternalFields}" />
</Label>
<Label Grid.Row="3" Grid.Column="0" Content="{DynamicResource FilterSummaryKey}" />
<Label Grid.Row="3" Grid.Column="1">
<Label Grid.Row="4" Grid.Column="0" Content="{DynamicResource FilterSummaryKey}" />
<Label Grid.Row="4" Grid.Column="1">
<TextBlock Text="{Binding Filter}" />
</Label>
<Label Grid.Row="4" Grid.Column="0" Content="{DynamicResource ProjectionSummaryKey}" />
<ItemsControl Grid.Row="4" Grid.Column="1" ItemsSource="{Binding Projection}" />
<Label Grid.Row="5" Grid.Column="0" Content="{DynamicResource ProjectionSummaryKey}" />
<ItemsControl Grid.Row="5" Grid.Column="1" ItemsSource="{Binding Projection}" />
</Grid>
</UserControl>

Просмотреть файл

@ -12,6 +12,9 @@
<system:String x:Key="ConnectionStringSummaryKey">Connection String:</system:String>
<system:String x:Key="TestConnectionKey">Verify</system:String>
<system:String x:Key="LocationModeKey">Location Mode</system:String>
<system:String x:Key="LocationModeSummaryKey">Location Mode:</system:String>
<system:String x:Key="TableNameKey">Table Name</system:String>
<system:String x:Key="TableNameSummaryKey">Table Name:</system:String>

Просмотреть файл

@ -0,0 +1,28 @@
using Microsoft.DataTransfer.AzureTable.Shared;
using Microsoft.WindowsAzure.Storage.RetryPolicies;
namespace Microsoft.DataTransfer.AzureTable.Client
{
static class AzureTableClientHelper
{
public static LocationMode? ToSdkLocationMode(AzureStorageLocationMode? locationMode)
{
if (!locationMode.HasValue)
locationMode = Defaults.Current.LocationMode;
switch (locationMode)
{
case AzureStorageLocationMode.PrimaryOnly:
return LocationMode.PrimaryOnly;
case AzureStorageLocationMode.PrimaryThenSecondary:
return LocationMode.PrimaryThenSecondary;
case AzureStorageLocationMode.SecondaryOnly:
return LocationMode.SecondaryOnly;
case AzureStorageLocationMode.SecondaryThenPrimary:
return LocationMode.SecondaryThenPrimary;
default:
return null;
}
}
}
}

Просмотреть файл

@ -1,4 +1,5 @@
using Microsoft.WindowsAzure.Storage;
using Microsoft.DataTransfer.AzureTable.Shared;
using Microsoft.WindowsAzure.Storage;
using System;
using System.Threading.Tasks;
@ -13,13 +14,17 @@ namespace Microsoft.DataTransfer.AzureTable.Client
/// Tests the Azure Table storage connection.
/// </summary>
/// <param name="connectionString">Azure Table storage connection string to use to connect to the account.</param>
/// <param name="locationMode">Location mode to use when connecting to Azure Table storage.</param>
/// <returns>Task that represents asynchronous connection operation.</returns>
public async Task TestConnection(string connectionString)
public async Task TestConnection(string connectionString, AzureStorageLocationMode? locationMode)
{
if (String.IsNullOrEmpty(connectionString))
throw Errors.ConnectionStringMissing();
var properties = await CloudStorageAccount.Parse(connectionString).CreateCloudTableClient().GetServicePropertiesAsync();
var client = CloudStorageAccount.Parse(connectionString).CreateCloudTableClient();
client.DefaultRequestOptions.LocationMode = AzureTableClientHelper.ToSdkLocationMode(locationMode);
var properties = await client.GetServicePropertiesAsync();
if (properties == null)
throw Errors.EmptyResponseReceived();
}

Просмотреть файл

@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.18444
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@ -69,6 +69,15 @@ namespace Microsoft.DataTransfer.AzureTable {
}
}
/// <summary>
/// Looks up a localized string similar to Optional, default is {0}. Specifies which location mode to use when connecting to Azure Table storage: {1}.
/// </summary>
public static string LocationModeFormat {
get {
return ResourceManager.GetString("LocationModeFormat", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Optional. Filter string to apply.
/// </summary>

Просмотреть файл

@ -120,6 +120,9 @@
<data name="ConnectionString" xml:space="preserve">
<value>Connection string for the Azure Table storage</value>
</data>
<data name="LocationModeFormat" xml:space="preserve">
<value>Optional, default is {0}. Specifies which location mode to use when connecting to Azure Table storage: {1}</value>
</data>
<data name="Source_Filter" xml:space="preserve">
<value>Optional. Filter string to apply</value>
</data>

Просмотреть файл

@ -1,4 +1,5 @@
using Microsoft.DataTransfer.AzureTable.Source;
using Microsoft.DataTransfer.AzureTable.Shared;
using Microsoft.DataTransfer.AzureTable.Source;
using Microsoft.DataTransfer.Basics;
using System;
@ -42,6 +43,7 @@ namespace Microsoft.DataTransfer.AzureTable
private sealed class LibraryDefaults : IDefaults
{
public AzureStorageLocationMode LocationMode { get { return AzureStorageLocationMode.PrimaryOnly; } }
public AzureTableInternalFields SourceInternalFields { get { return AzureTableInternalFields.All; } }
}
}

Просмотреть файл

@ -1,4 +1,5 @@
using Microsoft.DataTransfer.AzureTable.Source;
using Microsoft.DataTransfer.AzureTable.Shared;
using Microsoft.DataTransfer.AzureTable.Source;
using Microsoft.DataTransfer.Basics;
using System;
@ -9,6 +10,18 @@ namespace Microsoft.DataTransfer.AzureTable
/// </summary>
public sealed class DynamicConfigurationResources : DynamicResourcesBase
{
/// <summary>
/// Gets the description for location mode configuration property.
/// </summary>
public static string LocationMode
{
get
{
return Format(ConfigurationResources.LocationModeFormat, Defaults.Current.LocationMode,
String.Join(", ", Enum.GetNames(typeof(AzureStorageLocationMode))));
}
}
/// <summary>
/// Gets the description for source internal fields configuration property.
/// </summary>

Просмотреть файл

@ -1,4 +1,5 @@
using Microsoft.DataTransfer.AzureTable.Source;
using Microsoft.DataTransfer.AzureTable.Shared;
using Microsoft.DataTransfer.AzureTable.Source;
namespace Microsoft.DataTransfer.AzureTable
{
@ -7,6 +8,11 @@ namespace Microsoft.DataTransfer.AzureTable
/// </summary>
public interface IDefaults
{
/// <summary>
/// Gets the default value that indicates which location mode should be used when connecting to Azure Table storage.
/// </summary>
AzureStorageLocationMode LocationMode { get; }
/// <summary>
/// Gets the default value that indicates which internal Azure Table fields should be preserved in the source adapter output.
/// </summary>

Просмотреть файл

@ -31,35 +31,36 @@
</PropertyGroup>
<Import Project="..\..\Solution Items\CommonProperties.proj" />
<ItemGroup>
<Reference Include="Microsoft.Data.Edm, Version=5.6.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.Data.Edm.5.6.2\lib\net40\Microsoft.Data.Edm.dll</HintPath>
<Reference Include="Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.KeyVault.Core.1.0.0\lib\net40\Microsoft.Azure.KeyVault.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Data.OData, Version=5.6.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.Data.OData.5.6.2\lib\net40\Microsoft.Data.OData.dll</HintPath>
<Reference Include="Microsoft.Data.Edm, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Data.Edm.5.6.4\lib\net40\Microsoft.Data.Edm.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Data.Services.Client, Version=5.6.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.Data.Services.Client.5.6.2\lib\net40\Microsoft.Data.Services.Client.dll</HintPath>
<Reference Include="Microsoft.Data.OData, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Data.OData.5.6.4\lib\net40\Microsoft.Data.OData.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.WindowsAzure.ConfigurationManager.2.0.3\lib\net40\Microsoft.WindowsAzure.Configuration.dll</HintPath>
<Reference Include="Microsoft.Data.Services.Client, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Data.Services.Client.5.6.4\lib\net40\Microsoft.Data.Services.Client.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Storage, Version=4.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\WindowsAzure.Storage.4.3.0\lib\net40\Microsoft.WindowsAzure.Storage.dll</HintPath>
<Reference Include="Microsoft.WindowsAzure.Storage, Version=7.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\WindowsAzure.Storage.7.2.0\lib\net40\Microsoft.WindowsAzure.Storage.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Newtonsoft.Json.6.0.5\lib\net45\Newtonsoft.Json.dll</HintPath>
<HintPath>..\..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Core" />
<Reference Include="System.Spatial, Version=5.6.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\System.Spatial.5.6.2\lib\net40\System.Spatial.dll</HintPath>
<Reference Include="System.Spatial, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Spatial.5.6.4\lib\net40\System.Spatial.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
@ -71,6 +72,7 @@
<Compile Include="..\..\Solution Items\CommonAssemblyInfo.cs">
<Link>Properties\CommonAssemblyInfo.cs</Link>
</Compile>
<Compile Include="Client\AzureTableClientHelper.cs" />
<Compile Include="Client\AzureTableProbeClient.cs" />
<Compile Include="ConfigurationResources.Designer.cs">
<AutoGen>True</AutoGen>
@ -87,6 +89,7 @@
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Shared\AzureStorageLocationMode.cs" />
<Compile Include="Shared\IAzureTableAdapterConfiguration.cs" />
<Compile Include="Source\AzureTableInternalFields.cs" />
<Compile Include="Source\AzureTableSourceAdapter.cs" />

Просмотреть файл

@ -0,0 +1,28 @@
namespace Microsoft.DataTransfer.AzureTable.Shared
{
/// <summary>
/// Azure Storage location modes enumeration.
/// </summary>
public enum AzureStorageLocationMode
{
/// <summary>
/// Connect to the primary replica only.
/// </summary>
PrimaryOnly,
/// <summary>
/// Try connect to the primary replica and fallback to secondary.
/// </summary>
PrimaryThenSecondary,
/// <summary>
/// Connect to the secondary replica only.
/// </summary>
SecondaryOnly,
/// <summary>
/// Try connect to the secondary replica and fallback to primary.
/// </summary>
SecondaryThenPrimary
}
}

Просмотреть файл

@ -12,5 +12,11 @@ namespace Microsoft.DataTransfer.AzureTable.Shared
/// </summary>
[Display(ResourceType = typeof(ConfigurationResources), Description = "ConnectionString")]
string ConnectionString { get; }
/// <summary>
/// Gets the location mode to use when connecting to Azure Storage.
/// </summary>
[Display(ResourceType = typeof(DynamicConfigurationResources), Description = "LocationMode")]
AzureStorageLocationMode? LocationMode { get; }
}
}

Просмотреть файл

@ -1,4 +1,5 @@
using Microsoft.DataTransfer.Extensibility;
using Microsoft.DataTransfer.AzureTable.Client;
using Microsoft.DataTransfer.Extensibility;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Table;
using System.Collections.Generic;
@ -24,7 +25,12 @@ namespace Microsoft.DataTransfer.AzureTable.Source
{
this.configuration = configuration;
table = CloudStorageAccount.Parse(configuration.ConnectionString).CreateCloudTableClient().GetTableReference(configuration.Table);
var client = CloudStorageAccount.Parse(configuration.ConnectionString).CreateCloudTableClient();
client.DefaultRequestOptions.LocationMode =
AzureTableClientHelper.ToSdkLocationMode(configuration.LocationMode);
table = client.GetTableReference(configuration.Table);
query = new TableQuery
{
FilterString = configuration.Filter,

Просмотреть файл

@ -47,6 +47,7 @@ namespace Microsoft.DataTransfer.AzureTable.Source
return new AzureTableSourceAdapterInstanceConfiguration
{
ConnectionString = configuration.ConnectionString,
LocationMode = configuration.LocationMode,
Table = configuration.Table,
InternalFields = configuration.InternalFields ?? Defaults.Current.SourceInternalFields,
Filter = configuration.Filter,

Просмотреть файл

@ -1,10 +1,12 @@
using System.Collections.Generic;
using Microsoft.DataTransfer.AzureTable.Shared;
using System.Collections.Generic;
namespace Microsoft.DataTransfer.AzureTable.Source
{
sealed class AzureTableSourceAdapterInstanceConfiguration : IAzureTableSourceAdapterInstanceConfiguration
{
public string ConnectionString { get; set; }
public AzureStorageLocationMode? LocationMode { get; set; }
public string Table { get; set; }
public AzureTableInternalFields InternalFields { get; set; }
public string Filter { get; set; }

Просмотреть файл

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Data.Edm" version="5.6.2" targetFramework="net45" />
<package id="Microsoft.Data.OData" version="5.6.2" targetFramework="net45" />
<package id="Microsoft.Data.Services.Client" version="5.6.2" targetFramework="net45" />
<package id="Microsoft.WindowsAzure.ConfigurationManager" version="2.0.3" targetFramework="net45" />
<package id="Newtonsoft.Json" version="6.0.5" targetFramework="net45" />
<package id="System.Spatial" version="5.6.2" targetFramework="net45" />
<package id="WindowsAzure.Storage" version="4.3.0" targetFramework="net45" />
<package id="Microsoft.Azure.KeyVault.Core" version="1.0.0" targetFramework="net451" />
<package id="Microsoft.Data.Edm" version="5.6.4" targetFramework="net451" />
<package id="Microsoft.Data.OData" version="5.6.4" targetFramework="net451" />
<package id="Microsoft.Data.Services.Client" version="5.6.4" targetFramework="net451" />
<package id="Newtonsoft.Json" version="6.0.8" targetFramework="net451" />
<package id="System.Spatial" version="5.6.4" targetFramework="net451" />
<package id="WindowsAzure.Storage" version="7.2.0" targetFramework="net451" />
</packages>

Просмотреть файл

@ -8,7 +8,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Azure.Documents.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.6.0.0" newVersion="1.6.0.0" />
<bindingRedirect oldVersion="0.0.0.0-1.10.0.0" newVersion="1.10.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>

Просмотреть файл

@ -44,7 +44,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Azure.Documents.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.6.0.0" newVersion="1.6.0.0" />
<bindingRedirect oldVersion="0.0.0.0-1.10.0.0" newVersion="1.10.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.SqlServer.Types" publicKeyToken="89845dcd8080cc91" culture="neutral" />

Просмотреть файл

@ -33,7 +33,12 @@ namespace Microsoft.DataTransfer.ConsoleHost.App.Handlers
Console.WriteLine();
helpHandler.Print();
return 1;
return -1;
}
public int HandleSoftFailure()
{
return -10;
}
}
}

Просмотреть файл

@ -5,5 +5,6 @@ namespace Microsoft.DataTransfer.ConsoleHost.App.Handlers
interface IErrorHandler
{
int Handle(Exception error);
int HandleSoftFailure();
}
}

Просмотреть файл

@ -1,10 +1,9 @@
using Microsoft.DataTransfer.ServiceModel.Entities;
using System.Threading.Tasks;
using System.Threading.Tasks;
namespace Microsoft.DataTransfer.ConsoleHost.App.Handlers
{
interface ITransferHandler
{
Task RunAsync();
Task<TransferResult> RunAsync();
}
}

Просмотреть файл

@ -29,7 +29,7 @@ namespace Microsoft.DataTransfer.ConsoleHost.App.Handlers
this.configuration = configuration;
}
public async Task RunAsync()
public async Task<TransferResult> RunAsync()
{
ValidateConfiguration();
@ -64,8 +64,13 @@ namespace Microsoft.DataTransfer.ConsoleHost.App.Handlers
}
}
if (statistics != null)
statisticsHandler.PrintResult(statistics.GetSnapshot());
if (statistics == null)
return TransferResult.Empty;
var statisticsSnapshot = statistics.GetSnapshot();
statisticsHandler.PrintResult(statisticsSnapshot);
return new TransferResult(statisticsSnapshot.Transferred, statisticsSnapshot.Failed);
}
private TimeSpan GetProgressUpdateInterval()

Просмотреть файл

@ -0,0 +1,18 @@
namespace Microsoft.DataTransfer.ConsoleHost.App.Handlers
{
sealed class TransferResult
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes",
Justification = "Singleton instance to use where empty value is required")]
public static readonly TransferResult Empty = new TransferResult(0, 0);
public int Transferred { get; private set; }
public int Failed { get; private set; }
public TransferResult(int transferred, int failed)
{
this.Transferred = transferred;
this.Failed = failed;
}
}
}

Просмотреть файл

@ -18,8 +18,11 @@ namespace Microsoft.DataTransfer.ConsoleHost.App
{
try
{
transferHandler.RunAsync().Wait();
return 0;
var transferResult = transferHandler.RunAsync().Result;
return transferResult.Failed > 0
? errorHandler.HandleSoftFailure()
: 0;
}
catch (Exception ex)
{

Просмотреть файл

@ -57,6 +57,7 @@
<Compile Include="..\..\Solution Items\CommonAssemblyInfo.cs">
<Link>Properties\CommonAssemblyInfo.cs</Link>
</Compile>
<Compile Include="App\Handlers\TransferResult.cs" />
<Compile Include="Configuration\InfrastructureConfigurationFactory.cs" />
<Compile Include="Configuration\IInfrastructureConfiguration.cs" />
<Compile Include="Configuration\IInfrastructureConfigurationFactory.cs" />

Просмотреть файл

@ -40,8 +40,13 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Autofac.3.5.2\lib\net40\Autofac.dll</HintPath>
</Reference>
<Reference Include="Moq">
<HintPath>..\..\packages\Moq.4.2.1409.1722\lib\net40\Moq.dll</HintPath>
<Reference Include="Castle.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Moq, Version=4.5.21.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<HintPath>..\..\packages\Moq.4.5.21\lib\net45\Moq.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
</ItemGroup>

Просмотреть файл

@ -6,6 +6,10 @@
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Spatial" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.6.4.0" newVersion="5.6.4.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

Просмотреть файл

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Autofac" version="3.5.2" targetFramework="net45" />
<package id="Moq" version="4.2.1409.1722" targetFramework="net45" />
<package id="Castle.Core" version="3.3.3" targetFramework="net451" />
<package id="Moq" version="4.5.21" targetFramework="net451" />
</packages>

Просмотреть файл

@ -3,6 +3,7 @@ using Microsoft.DataTransfer.Basics.Files.Sink;
using Microsoft.DataTransfer.ServiceModel.Errors;
using Microsoft.DataTransfer.ServiceModel.Statistics;
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
@ -18,8 +19,9 @@ namespace Microsoft.DataTransfer.Core.Statistics
return String.IsNullOrEmpty(configuration.ErrorLog)
? (ITransferStatistics)new InMemoryTransferStatistics(errorDetailsProvider)
: new CsvErrorLogTransferStatistics(
await SinkStreamProvidersFactory.Create(
configuration.ErrorLog, configuration.OverwriteErrorLog).CreateWriter(cancellation),
new StreamWriter(
await SinkStreamProvidersFactory.Create(configuration.ErrorLog, false, configuration.OverwriteErrorLog)
.CreateStream(cancellation)),
errorDetailsProvider);
}
}

Просмотреть файл

@ -6,6 +6,10 @@
<assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.5.0.0" newVersion="3.5.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

Просмотреть файл

@ -5,6 +5,7 @@ using Microsoft.DataTransfer.TestsCommon.Mocks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@ -71,6 +72,63 @@ namespace Microsoft.DataTransfer.CsvFile.FunctionalTests
Assert.AreEqual(2, nestedDocument.GetFieldNames().Count(), TestResources.UnexpectedFieldsProcessed);
}
[TestMethod, Timeout(120000)]
[DeploymentItem(@"TestData\CustomCultureTest.csv", @"InputData")]
public async Task ReadFlatDocuments_CustomCulture_AllDataRead()
{
var customCulture = new CultureInfo(CultureInfo.InvariantCulture.Name);
customCulture.TextInfo.ListSeparator = ";";
CultureInfo.DefaultThreadCurrentCulture = customCulture;
var configuration = Mocks
.Of<ICsvFileSourceAdapterConfiguration>(c =>
c.Files == new[] { @"InputData\CustomCultureTest.csv" } &&
c.UseRegionalSettings == true)
.First();
var readResults = await ReadData(configuration);
Assert.AreEqual(3, readResults.Count, TestResources.UnexpectedRecordsProcessed);
Assert.AreEqual(6, readResults[0].GetFieldNames().Count(), TestResources.UnexpectedFieldsProcessed);
}
[TestMethod, Timeout(120000)]
[DeploymentItem(@"TestData\BasicTest.csv", @"InputData")]
public async Task ReadFlatDocuments_UseInvariantCultureWhenCustomCultureIsSet_AllDataRead()
{
var customCulture = new CultureInfo(CultureInfo.InvariantCulture.Name);
customCulture.TextInfo.ListSeparator = ";";
CultureInfo.DefaultThreadCurrentCulture = customCulture;
var configuration = Mocks
.Of<ICsvFileSourceAdapterConfiguration>(c =>
c.Files == new[] { @"InputData\BasicTest.csv" })
.First();
var readResults = await ReadData(configuration);
Assert.AreEqual(3, readResults.Count, TestResources.UnexpectedRecordsProcessed);
Assert.AreEqual(6, readResults[0].GetFieldNames().Count(), TestResources.UnexpectedFieldsProcessed);
}
[TestMethod, Timeout(120000)]
[DeploymentItem(@"TestData\BasicTest.gz", @"InputData")]
public async Task ReadFlatDocumentsFromCompressedFile_AllDataRead()
{
var configuration = Mocks
.Of<ICsvFileSourceAdapterConfiguration>(c =>
c.Files == new[] { @"InputData\BasicTest.gz" } &&
c.Decompress == true)
.First();
var readResults = await ReadData(configuration);
Assert.AreEqual(3, readResults.Count, TestResources.UnexpectedRecordsProcessed);
Assert.AreEqual(6, readResults[0].GetFieldNames().Count(), TestResources.UnexpectedFieldsProcessed);
}
private async Task<List<IDataItem>> ReadData(ICsvFileSourceAdapterConfiguration configuration)
{
using (var adapter = await new CsvFileSourceAdapterFactory()

Просмотреть файл

@ -36,8 +36,13 @@
<CodeAnalysisRuleSet>ManagedMinimumRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Moq">
<HintPath>..\..\packages\Moq.4.2.1409.1722\lib\net40\Moq.dll</HintPath>
<Reference Include="Castle.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Moq, Version=4.5.21.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<HintPath>..\..\packages\Moq.4.5.21\lib\net45\Moq.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
</ItemGroup>
@ -86,6 +91,12 @@
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
<None Include="TestData\BasicTest.gz">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="TestData\CustomCultureTest.csv">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="TestData\BasicTest.csv">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,5 @@
FirstName;LastName;Title;ReportsTo.Email;Birthdate;Description
Tom;Jones;Senior Director;buyer@salesforcesample.com;1940-06-07Z;"Self-described as ""the top"" branding guru on the West Coast"
Ian;Dury;Chief Imagineer;cto@salesforcesample.com;;"World-renowned expert in fuzzy logic design.
Influential in technology purchases."
Bruce;Anakonda;Assassin;ba@snake.com;N/A;"Good, Record"
1 FirstName LastName Title ReportsTo.Email Birthdate Description
2 Tom Jones Senior Director buyer@salesforcesample.com 1940-06-07Z Self-described as "the top" branding guru on the West Coast
3 Ian Dury Chief Imagineer cto@salesforcesample.com World-renowned expert in fuzzy logic design. Influential in technology purchases.
4 Bruce Anakonda Assassin ba@snake.com N/A Good, Record

Просмотреть файл

@ -6,6 +6,10 @@
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Spatial" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.6.4.0" newVersion="5.6.4.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

Просмотреть файл

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Moq" version="4.2.1409.1722" targetFramework="net45" />
<package id="Castle.Core" version="3.3.3" targetFramework="net451" />
<package id="Moq" version="4.5.21" targetFramework="net451" />
</packages>

Просмотреть файл

@ -2,6 +2,7 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
@ -14,7 +15,12 @@ namespace Microsoft.DataTransfer.CsvFile.UnitTests
[DeploymentItem(@"TestData\SimpleQuotedValues.csv")]
public void Read_SimpleQuotedValues_AllValuesRead()
{
ReadAndVerify("SimpleQuotedValues.csv", new CsvReaderConfiguration(),
ReadAndVerify(
"SimpleQuotedValues.csv",
new CsvReaderConfiguration
{
ParserCulture = CultureInfo.InvariantCulture
},
new[]
{
new object[] { "Tom", "Jones", "Senior Director", "buyer@salesforcesample.com" },
@ -26,7 +32,12 @@ namespace Microsoft.DataTransfer.CsvFile.UnitTests
[DeploymentItem(@"TestData\ComplexQuotedValues.csv")]
public void Read_ComplexQuotedValues_AllValuesRead()
{
ReadAndVerify("ComplexQuotedValues.csv", new CsvReaderConfiguration(),
ReadAndVerify(
"ComplexQuotedValues.csv",
new CsvReaderConfiguration
{
ParserCulture = CultureInfo.InvariantCulture
},
new[]
{
new object[] { "Tom", "Jones", "Senior\" Director", "buyer@salesforcesample.com" },
@ -38,7 +49,12 @@ namespace Microsoft.DataTransfer.CsvFile.UnitTests
[DeploymentItem(@"TestData\IntegerValues.csv")]
public void Read_IntegerValues_AllValuesRead()
{
ReadAndVerify("IntegerValues.csv", new CsvReaderConfiguration(),
ReadAndVerify(
"IntegerValues.csv",
new CsvReaderConfiguration
{
ParserCulture = CultureInfo.InvariantCulture
},
new[]
{
new object[] { "Tom", "Jones", (long)10, "buyer@salesforcesample.com" },
@ -50,7 +66,12 @@ namespace Microsoft.DataTransfer.CsvFile.UnitTests
[DeploymentItem(@"TestData\FloatingPointValues.csv")]
public void Read_FloatingPointValues_AllValuesRead()
{
ReadAndVerify("FloatingPointValues.csv", new CsvReaderConfiguration(),
ReadAndVerify(
"FloatingPointValues.csv",
new CsvReaderConfiguration
{
ParserCulture = CultureInfo.InvariantCulture
},
new[]
{
new object[] { "Tom", "Jones", (double)10.1, "buyer@salesforcesample.com" },
@ -62,7 +83,12 @@ namespace Microsoft.DataTransfer.CsvFile.UnitTests
[DeploymentItem(@"TestData\BooleanValues.csv")]
public void Read_BooleanValues_AllValuesRead()
{
ReadAndVerify("BooleanValues.csv", new CsvReaderConfiguration(),
ReadAndVerify(
"BooleanValues.csv",
new CsvReaderConfiguration
{
ParserCulture = CultureInfo.InvariantCulture
},
new[]
{
new object[] { "Tom", "Jones", true, "buyer@salesforcesample.com" },
@ -74,7 +100,12 @@ namespace Microsoft.DataTransfer.CsvFile.UnitTests
[DeploymentItem(@"TestData\DateTimeValues.csv")]
public void Read_DateTimeValues_AllValuesRead()
{
ReadAndVerify("DateTimeValues.csv", new CsvReaderConfiguration(),
ReadAndVerify(
"DateTimeValues.csv",
new CsvReaderConfiguration
{
ParserCulture = CultureInfo.InvariantCulture
},
new[]
{
new object[] { "Tom", "Jones", new DateTime(2015, 4, 15, 20, 0, 15, DateTimeKind.Utc), "buyer@salesforcesample.com" },
@ -86,7 +117,12 @@ namespace Microsoft.DataTransfer.CsvFile.UnitTests
[DeploymentItem(@"TestData\UnquotedNulls.csv")]
public void Read_UnquotedNulls_NullsReadAsNullsByDefault()
{
ReadAndVerify("UnquotedNulls.csv", new CsvReaderConfiguration(),
ReadAndVerify(
"UnquotedNulls.csv",
new CsvReaderConfiguration
{
ParserCulture = CultureInfo.InvariantCulture
},
new[]
{
new object[] { "Tom", null, "Senior Director", "buyer@salesforcesample.com" },
@ -98,7 +134,13 @@ namespace Microsoft.DataTransfer.CsvFile.UnitTests
[DeploymentItem(@"TestData\UnquotedNulls.csv")]
public void Read_UnquotedNulls_NullsReadAsStrings()
{
ReadAndVerify("UnquotedNulls.csv", new CsvReaderConfiguration { IgnoreUnquotedNulls = true },
ReadAndVerify(
"UnquotedNulls.csv",
new CsvReaderConfiguration
{
IgnoreUnquotedNulls = true,
ParserCulture = CultureInfo.InvariantCulture
},
new[]
{
new object[] { "Tom", "NULL", "Senior Director", "buyer@salesforcesample.com" },
@ -110,7 +152,12 @@ namespace Microsoft.DataTransfer.CsvFile.UnitTests
[DeploymentItem(@"TestData\EmptyLines.csv")]
public void Read_EmptyLines_TreatedAsSingleNullValues()
{
ReadAndVerify("EmptyLines.csv", new CsvReaderConfiguration(),
ReadAndVerify(
"EmptyLines.csv",
new CsvReaderConfiguration
{
ParserCulture = CultureInfo.InvariantCulture
},
new[]
{
new object[] { null },
@ -122,7 +169,12 @@ namespace Microsoft.DataTransfer.CsvFile.UnitTests
[DeploymentItem(@"TestData\EmptySpaceQuotedValues.csv")]
public void Read_EmptySpaceInQuotes_EmptySpaceIsNotTrimmedByDefault()
{
ReadAndVerify("EmptySpaceQuotedValues.csv", new CsvReaderConfiguration(),
ReadAndVerify(
"EmptySpaceQuotedValues.csv",
new CsvReaderConfiguration
{
ParserCulture = CultureInfo.InvariantCulture
},
new[]
{
new object[] { "Tom", " Jones ", "Senior Director", "buyer@salesforcesample.com" },
@ -134,7 +186,13 @@ namespace Microsoft.DataTransfer.CsvFile.UnitTests
[DeploymentItem(@"TestData\EmptySpaceQuotedValues.csv")]
public void Read_EmptySpaceInQuotes_EmptySpaceIsTrimmed()
{
ReadAndVerify("EmptySpaceQuotedValues.csv", new CsvReaderConfiguration { TrimQuoted = true },
ReadAndVerify(
"EmptySpaceQuotedValues.csv",
new CsvReaderConfiguration
{
TrimQuoted = true,
ParserCulture = CultureInfo.InvariantCulture
},
new[]
{
new object[] { "Tom", "Jones", "Senior Director", "buyer@salesforcesample.com" },
@ -146,7 +204,12 @@ namespace Microsoft.DataTransfer.CsvFile.UnitTests
[DeploymentItem(@"TestData\EmptySpaceUnquotedValues.csv")]
public void Read_EmptySpaceInUnquotedValues_EmptySpaceIsTrimmed()
{
ReadAndVerify("EmptySpaceUnquotedValues.csv", new CsvReaderConfiguration(),
ReadAndVerify(
"EmptySpaceUnquotedValues.csv",
new CsvReaderConfiguration
{
ParserCulture = CultureInfo.InvariantCulture
},
new[]
{
new object[] { "Tom", "Jones", "Senior Director", "buyer@salesforcesample.com" },
@ -154,6 +217,29 @@ namespace Microsoft.DataTransfer.CsvFile.UnitTests
});
}
[TestMethod]
[DeploymentItem(@"TestData\CustomCulture.csv")]
public void Read_CustomCulture_AllValuesRead()
{
var customCulture = new CultureInfo(CultureInfo.InvariantCulture.Name);
customCulture.TextInfo.ListSeparator = "|";
customCulture.NumberFormat.NumberDecimalSeparator = ",";
customCulture.NumberFormat.NumberGroupSeparator = " ";
ReadAndVerify(
"CustomCulture.csv",
new CsvReaderConfiguration
{
ParserCulture = customCulture
},
new[]
{
new object[] { "Jessica", "Simpson", (double)10.2, "jess@sample.com" },
new object[] { "Mark", "Doe", false, "mark@sample.com" },
new object[] { "Chris", "Johnson", (double)1050.10, "chris@sample.com" },
});
}
private static void ReadAndVerify(string inputFileName, CsvReaderConfiguration configuration, object[][] expectedRows)
{
using (var csvReader = new CsvReader(new StreamReader(inputFileName), configuration))

Просмотреть файл

@ -69,6 +69,9 @@
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="TestData\CustomCulture.csv">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="TestData\EmptySpaceUnquotedValues.csv">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>

Просмотреть файл

@ -0,0 +1,3 @@
"Jessica"|"Simpson"|10,2|"jess@sample.com"
"Mark"|"Doe"|false|"mark@sample.com"
"Chris"|"Johnson"|1 050,10|"chris@sample.com"
1 Jessica Simpson 10,2 jess@sample.com
2 Mark Doe false mark@sample.com
3 Chris Johnson 1 050,10 chris@sample.com

Просмотреть файл

@ -24,10 +24,18 @@ namespace Microsoft.DataTransfer.CsvFile.Wpf.Source
public static readonly string NoUnquotedNullsPropertyName =
ObjectExtensions.MemberName<ICsvFileSourceAdapterConfiguration>(c => c.NoUnquotedNulls);
public static readonly string UseRegionalSettingsPropertyName =
ObjectExtensions.MemberName<ICsvFileSourceAdapterConfiguration>(c => c.UseRegionalSettings);
public static readonly string DecompressPropertyName =
ObjectExtensions.MemberName<ICsvFileSourceAdapterConfiguration>(c => c.Decompress);
private ObservableCollection<string> files;
private string nestingSeparator;
private bool trimQuoted;
private bool noUnquotedNulls;
private bool useRegionalSettings;
private bool decompress;
public IEnumerable<string> Files
{
@ -58,6 +66,18 @@ namespace Microsoft.DataTransfer.CsvFile.Wpf.Source
set { SetProperty(ref noUnquotedNulls, value); }
}
public bool UseRegionalSettings
{
get { return useRegionalSettings; }
set { SetProperty(ref useRegionalSettings, value); }
}
public bool Decompress
{
get { return decompress; }
set { SetProperty(ref decompress, value); }
}
public CsvFileSourceAdapterConfiguration()
{
EditableFiles = new ObservableCollection<string>();

Просмотреть файл

@ -11,7 +11,7 @@
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="..\XamlResources.xaml"/>
<ResourceDictionary Source="..\XamlResources.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
@ -23,14 +23,14 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<DockPanel Grid.Row="0" Style="{StaticResource OptionElement}">
<bc:FilesPickerControl DockPanel.Dock="Bottom"
Files="{Binding EditableFiles}"
Filter="{DynamicResource OpenFilesFilterKey}"
DefaultExtension="{DynamicResource OpenFilesDefaultExtensionKey}" />
</DockPanel>
<bc:FilesPickerControl Grid.Row="0" Style="{StaticResource OptionElement}"
Files="{Binding EditableFiles}"
Filter="{DynamicResource OpenFilesFilterKey}"
DefaultExtension="{DynamicResource OpenFilesDefaultExtensionKey}" />
<StackPanel Grid.Row="1" Style="{StaticResource OptionElement}">
<bc:ToolTipDecorator ToolTip="{DynamicResource NestingSeparatorDescriptionKey}">
@ -44,6 +44,16 @@
<CheckBox Grid.Row="3" Style="{StaticResource SingleLineOptionElement}"
Content="{DynamicResource NoUnquotedNullsKey}" IsChecked="{Binding NoUnquotedNulls}" />
<bc:ToolTipDecorator Grid.Row="4" Style="{StaticResource SingleLineOptionElement}"
ToolTip="{DynamicResource UseRegionalSettingsDescriptionKey}">
<CheckBox Content="{DynamicResource UseRegionalSettingsKey}" IsChecked="{Binding UseRegionalSettings}" />
</bc:ToolTipDecorator>
<bc:ToolTipDecorator Grid.Row="5" Style="{StaticResource SingleLineOptionElement}"
ToolTip="{DynamicResource DecompressDescriptionKey}">
<CheckBox Content="{DynamicResource DecompressKey}" IsChecked="{Binding Decompress}" />
</bc:ToolTipDecorator>
</Grid>
</AdornerDecorator>

Просмотреть файл

@ -10,7 +10,7 @@
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="..\XamlResources.xaml"/>
<ResourceDictionary Source="..\XamlResources.xaml" />
</ResourceDictionary.MergedDictionaries>
<converters:BooleanToStringValueConverter x:Key="YesNoConverter" />
@ -27,6 +27,8 @@
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="{DynamicResource FilesSummaryKey}" />
@ -46,6 +48,16 @@
<Label Grid.Row="3" Grid.Column="1">
<TextBlock Text="{Binding NoUnquotedNulls, Converter={StaticResource YesNoConverter}}" />
</Label>
<Label Grid.Row="4" Grid.Column="0" Content="{DynamicResource UseRegionalSettingsSummaryKey}" />
<Label Grid.Row="4" Grid.Column="1">
<TextBlock Text="{Binding UseRegionalSettings, Converter={StaticResource YesNoConverter}}" />
</Label>
<Label Grid.Row="5" Grid.Column="0" Content="{DynamicResource DecompressSummaryKey}" />
<Label Grid.Row="5" Grid.Column="1">
<TextBlock Text="{Binding Decompress, Converter={StaticResource YesNoConverter}}" />
</Label>
</Grid>
</UserControl>

Просмотреть файл

@ -38,6 +38,12 @@ namespace Microsoft.DataTransfer.CsvFile.Wpf.Source
if (configuration.NoUnquotedNulls)
arguments.Add(CsvFileSourceAdapterConfiguration.NoUnquotedNullsPropertyName, null);
if (configuration.UseRegionalSettings)
arguments.Add(CsvFileSourceAdapterConfiguration.UseRegionalSettingsPropertyName, null);
if (configuration.Decompress)
arguments.Add(CsvFileSourceAdapterConfiguration.DecompressPropertyName, null);
}
}
}

Просмотреть файл

@ -9,7 +9,7 @@
<!-- String resources -->
<system:String x:Key="FilesSummaryKey">Files:</system:String>
<system:String x:Key="OpenFilesFilterKey">CSV Files|*.csv|All Files|*.*</system:String>
<system:String x:Key="OpenFilesFilterKey">CSV Files|*.csv|GZip Files|*.gz|All Files|*.*</system:String>
<system:String x:Key="OpenFilesDefaultExtensionKey">*.csv</system:String>
<system:String x:Key="NestingSeparatorKey">Nesting Separator</system:String>
@ -22,4 +22,16 @@
<system:String x:Key="NoUnquotedNullsKey">Treat unquoted NULL as string</system:String>
<system:String x:Key="NoUnquotedNullsSummaryKey">Unquoted NULL is string:</system:String>
<system:String x:Key="UseRegionalSettingsKey">Use regional format settings</system:String>
<system:String x:Key="UseRegionalSettingsDescriptionKey">
Some applications may export CSV files using current regional format settings. This includes such settings as list separator, number, date and time format.
By default, all CSV files are assumed to be comma-separated and use "." as a decimal separator. Select this option, if input file was exported with current
regional format settings
</system:String>
<system:String x:Key="UseRegionalSettingsSummaryKey">Use regional format settings:</system:String>
<system:String x:Key="DecompressKey">Decompress data</system:String>
<system:String x:Key="DecompressDescriptionKey">Data from the source files will be decompressed with GZip</system:String>
<system:String x:Key="DecompressSummaryKey">Decompress data:</system:String>
</ResourceDictionary>

Просмотреть файл

@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.18444
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@ -60,6 +60,15 @@ namespace Microsoft.DataTransfer.CsvFile {
}
}
/// <summary>
/// Looks up a localized string similar to Optional. If source files should be decompressed with GZip.
/// </summary>
public static string Source_Decompress {
get {
return ResourceManager.GetString("Source_Decompress", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to One or more file search patterns to read CSV from.
/// </summary>
@ -95,5 +104,14 @@ namespace Microsoft.DataTransfer.CsvFile {
return ResourceManager.GetString("Source_TrimQuoted", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Optional. If system regional settings should be used to parse the files. This includes such settings as list separator, number, date and time format.
/// </summary>
public static string Source_UseRegionalSettings {
get {
return ResourceManager.GetString("Source_UseRegionalSettings", resourceCulture);
}
}
}
}

Просмотреть файл

@ -117,6 +117,9 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Source_Decompress" xml:space="preserve">
<value>Optional. If source files should be decompressed with GZip</value>
</data>
<data name="Source_Files" xml:space="preserve">
<value>One or more file search patterns to read CSV from</value>
</data>
@ -129,4 +132,7 @@
<data name="Source_TrimQuoted" xml:space="preserve">
<value>Optional. If empty space at the start and end of the quoted value should be removed</value>
</data>
<data name="Source_UseRegionalSettings" xml:space="preserve">
<value>Optional. If system regional settings should be used to parse the files. This includes such settings as list separator, number, date and time format</value>
</data>
</root>

Просмотреть файл

@ -40,42 +40,53 @@ namespace Microsoft.DataTransfer.CsvFile.Reader
char character;
while (ReadNext(out character))
{
switch (character)
if (character == '\r')
{
case '\r':
break;
case '\n':
if (readingValue)
result.Add(ConvertUnquotedValue(value.ToString()));
continue;
}
else if (character == '\n')
{
if (readingValue)
result.Add(ConvertUnquotedValue(value.ToString()));
if (!result.Any())
// Skip empty row and continue
break;
if (!result.Any())
// Skip empty row and continue
continue;
return result;
case ',':
if (readingValue)
result.Add(ConvertUnquotedValue(value.ToString()));
value.Clear();
readingValue = true;
break;
case '"':
if (value.Length > 0 || !readingValue)
throw UnexpectedCharacter(character);
result.Add(ReadQuotedValue());
readingValue = false;
break;
case ' ':
case '\t':
// Trim spaces and tabs at the beginning of unquoted values
if (value.Length > 0)
value.Append(character);
break;
default:
if (!readingValue)
throw UnexpectedCharacter(character);
return result;
}
// Currently there seem to be no standard cultures that use multiple characters as a list separator.
// Lets not complicate the parsing logic for now.
else if (character == configuration.ParserCulture.TextInfo.ListSeparator[0])
{
if (readingValue)
result.Add(ConvertUnquotedValue(value.ToString()));
value.Clear();
readingValue = true;
continue;
}
else if (character == '"')
{
if (value.Length > 0 || !readingValue)
throw UnexpectedCharacter(character);
result.Add(ReadQuotedValue());
readingValue = false;
continue;
}
else if (character == ' ' || character == '\t')
{
// Trim spaces and tabs at the beginning of unquoted values
if (value.Length > 0)
value.Append(character);
break;
continue;
}
else
{
if (!readingValue)
throw UnexpectedCharacter(character);
value.Append(character);
}
}
@ -125,16 +136,18 @@ namespace Microsoft.DataTransfer.CsvFile.Reader
if (String.IsNullOrEmpty(value))
return null;
var numberFormat = NumberFormatInfo.GetInstance(configuration.ParserCulture);
long number;
if (long.TryParse(value, out number))
if (long.TryParse(value, NumberStyles.Integer, numberFormat, out number))
return number;
double doubleNumber;
if (double.TryParse(value, out doubleNumber))
if (double.TryParse(value, NumberStyles.Float | NumberStyles.AllowThousands, numberFormat, out doubleNumber))
return doubleNumber;
DateTime dateTime;
if (DateTime.TryParse(value, CultureInfo.InvariantCulture,
if (DateTime.TryParse(value, DateTimeFormatInfo.GetInstance(configuration.ParserCulture),
DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal, out dateTime))
return dateTime;

Просмотреть файл

@ -1,9 +1,11 @@

using System.Globalization;
namespace Microsoft.DataTransfer.CsvFile.Reader
{
sealed class CsvReaderConfiguration
{
public bool TrimQuoted { get; set; }
public bool IgnoreUnquotedNulls { get; set; }
public CultureInfo ParserCulture { get; set; }
}
}

Просмотреть файл

@ -6,6 +6,7 @@ using Microsoft.DataTransfer.Extensibility.Basics.Source;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@ -36,11 +37,12 @@ namespace Microsoft.DataTransfer.CsvFile.Source
if (reader == null)
{
reader = new CsvReader(
await sourceStreamProvider.CreateReader(cancellation),
new StreamReader(await sourceStreamProvider.CreateStream(cancellation)),
new CsvReaderConfiguration
{
TrimQuoted = configuration.TrimQuoted,
IgnoreUnquotedNulls = configuration.NoUnquotedNulls
IgnoreUnquotedNulls = configuration.NoUnquotedNulls,
ParserCulture = configuration.UseRegionalSettings ? CultureInfo.CurrentCulture : CultureInfo.InvariantCulture
});
header = ReadHeaderRow();
}

Просмотреть файл

@ -43,7 +43,7 @@ namespace Microsoft.DataTransfer.CsvFile.Source
return new AggregateDataSourceAdapter(
configuration.Files
.SelectMany(f => SourceStreamProvidersFactory
.Create(f)
.Create(f, configuration.Decompress)
.Select(p => new CsvFileSourceAdapter(p, instanceConfiguration))));
}
@ -53,7 +53,8 @@ namespace Microsoft.DataTransfer.CsvFile.Source
{
NestingSeparator = configuration.NestingSeparator,
TrimQuoted = configuration.TrimQuoted,
NoUnquotedNulls = configuration.NoUnquotedNulls
NoUnquotedNulls = configuration.NoUnquotedNulls,
UseRegionalSettings = configuration.UseRegionalSettings
};
}
}

Просмотреть файл

@ -6,5 +6,6 @@ namespace Microsoft.DataTransfer.CsvFile.Source
public string NestingSeparator { get; set; }
public bool TrimQuoted { get; set; }
public bool NoUnquotedNulls { get; set; }
public bool UseRegionalSettings { get; set; }
}
}

Просмотреть файл

@ -31,5 +31,17 @@ namespace Microsoft.DataTransfer.CsvFile.Source
/// </summary>
[Display(ResourceType = typeof(ConfigurationResources), Description = "Source_NoUnquotedNulls")]
bool NoUnquotedNulls { get; }
/// <summary>
/// Gets the value that indicates whether regional format settings should be used to parse the input files.
/// </summary>
[Display(ResourceType = typeof(ConfigurationResources), Description = "Source_UseRegionalSettings")]
bool UseRegionalSettings { get; }
/// <summary>
/// Gets the value that indicates whether input files should be decompressed.
/// </summary>
[Display(ResourceType = typeof(ConfigurationResources), Description = "Source_Decompress")]
bool Decompress { get; }
}
}

Просмотреть файл

@ -6,5 +6,6 @@ namespace Microsoft.DataTransfer.CsvFile.Source
string NestingSeparator { get; }
bool TrimQuoted { get; }
bool NoUnquotedNulls { get; }
bool UseRegionalSettings { get; }
}
}

Просмотреть файл

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.DataTransfer.Core", "Core\Microsoft.DataTransfer.Core\Microsoft.DataTransfer.Core.csproj", "{01631F6D-813C-47D7-9CA7-3A6E493356F5}"
EndProject
@ -148,6 +148,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.DataTransfer.HBas
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.DataTransfer.Basics.Files", "Shared\Microsoft.DataTransfer.Basics.Files\Microsoft.DataTransfer.Basics.Files.csproj", "{DA182D5C-79F4-4AF6-BF15-6E4496353A6A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.DataTransfer.MongoDb.UnitTests", "MongoDb\Microsoft.DataTransfer.MongoDb.UnitTests\Microsoft.DataTransfer.MongoDb.UnitTests.csproj", "{2AC0E216-9ED4-4D1D-A264-73905A37F6AA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -335,6 +337,9 @@ Global
{DA182D5C-79F4-4AF6-BF15-6E4496353A6A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DA182D5C-79F4-4AF6-BF15-6E4496353A6A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DA182D5C-79F4-4AF6-BF15-6E4496353A6A}.Release|Any CPU.Build.0 = Release|Any CPU
{2AC0E216-9ED4-4D1D-A264-73905A37F6AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2AC0E216-9ED4-4D1D-A264-73905A37F6AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2AC0E216-9ED4-4D1D-A264-73905A37F6AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -389,6 +394,7 @@ Global
{98706C69-8F15-4D97-9DD9-D7FD6F5A038F} = {1BD0D669-8E45-4E7C-A20F-707A1887E8ED}
{6544F78F-4EE3-489E-87B7-5FCA9C4D50BD} = {1BD0D669-8E45-4E7C-A20F-707A1887E8ED}
{DA182D5C-79F4-4AF6-BF15-6E4496353A6A} = {F9CAC1F5-436E-4406-BACC-FC18C8FE36C5}
{2AC0E216-9ED4-4D1D-A264-73905A37F6AA} = {7F83D352-1039-4B8F-B63C-56231421056A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EnterpriseLibraryConfigurationToolBinariesPathV6 = packages\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\lib\portable-net45+win+wp8;packages\EnterpriseLibrary.TransientFaultHandling.Data.6.0.1304.1\lib\NET45

Просмотреть файл

@ -1,4 +1,5 @@
using Microsoft.DataTransfer.DocumentDb.Exceptions;
using Microsoft.Azure.Documents;
using Microsoft.DataTransfer.DocumentDb.Exceptions;
using Microsoft.DataTransfer.DocumentDb.Sink.Bulk;
using Microsoft.DataTransfer.Extensibility.Basics.Source;
using Microsoft.DataTransfer.TestsCommon.Mocks;
@ -216,5 +217,32 @@ namespace Microsoft.DataTransfer.DocumentDb.FunctionalTests
VerifyData(GetExpectedDuplicateDataItems(), DocumentDbHelper.ReadDocuments(ConnectionString, CollectionName));
}
[TestMethod, Timeout(300000)]
[DeploymentItem("BulkInsert.js")]
[ExpectedException(typeof(DocumentClientException))]
public async Task BulkWriteSampleData_PartitionedCollection_ThrowsException()
{
const string CollectionName = "Data";
const int NumberOfItems = 42;
var configuration =
Mocks
.Of<IDocumentDbBulkSinkAdapterConfiguration>(m =>
m.ConnectionString == ConnectionString &&
m.Collection == new[] { CollectionName } &&
m.CollectionThroughput == 10100 && // 10000 RUs is the current threshold for single partition collections
m.BatchSize == 10 &&
m.MaxScriptSize == 1024)
.First();
var sampleData = SampleData.GetSimpleDataItems(NumberOfItems);
using (var adapter = await new DocumentDbBulkSinkAdapterFactory()
.CreateAsync(configuration, DataTransferContextMock.Instance, CancellationToken.None))
{
await WriteDataAsync(adapter, sampleData);
}
}
}
}

Просмотреть файл

@ -10,6 +10,8 @@ using System.Threading.Tasks;
namespace Microsoft.DataTransfer.DocumentDb.FunctionalTests
{
[TestClass]
[DeploymentItem("DocumentDB.Spatial.Sql.dll")]
[DeploymentItem("Microsoft.Azure.Documents.ServiceInterop.dll")]
public class DocumentDbParallelSinkAdapterTests : DocumentDbSinkAdapterTestBase
{
[TestMethod, Timeout(300000)]

Просмотреть файл

@ -16,7 +16,8 @@
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
<IsCodedUITest>False</IsCodedUITest>
<TestProjectType>UnitTest</TestProjectType>
<NuGetPackageImportStamp>84adfeb4</NuGetPackageImportStamp>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -37,20 +38,25 @@
<CodeAnalysisRuleSet>ManagedMinimumRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Azure.Documents.Client, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.DocumentDB.1.6.1\lib\net45\Microsoft.Azure.Documents.Client.dll</HintPath>
<Reference Include="Castle.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Azure.Documents.Client.TransientFaultHandling, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.DocumentDB.TransientFaultHandling.1.2.0\lib\net45\Microsoft.Azure.Documents.Client.TransientFaultHandling.dll</HintPath>
<Reference Include="Microsoft.Azure.Documents.Client, Version=1.10.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.DocumentDB.1.10.0\lib\net45\Microsoft.Azure.Documents.Client.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Azure.Documents.Client.TransientFaultHandling, Version=1.4.0.0, Culture=neutral, PublicKeyToken=69c3241e6f0468ca, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.DocumentDB.TransientFaultHandling.1.4.0\lib\net45\Microsoft.Azure.Documents.Client.TransientFaultHandling.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\lib\portable-net45+win+wp8\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.dll</HintPath>
</Reference>
<Reference Include="Moq">
<HintPath>..\..\packages\Moq.4.2.1409.1722\lib\net40\Moq.dll</HintPath>
<Reference Include="Moq, Version=4.5.21.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<HintPath>..\..\packages\Moq.4.5.21\lib\net45\Moq.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
@ -58,8 +64,8 @@
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Spatial, Version=5.6.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Spatial.5.6.2\lib\net40\System.Spatial.dll</HintPath>
<Reference Include="System.Spatial, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Spatial.5.6.4\lib\net40\System.Spatial.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
@ -144,12 +150,12 @@
</Choose>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\packages\Microsoft.Azure.DocumentDB.1.6.1\build\Microsoft.Azure.DocumentDB.targets" Condition="Exists('..\..\packages\Microsoft.Azure.DocumentDB.1.6.1\build\Microsoft.Azure.DocumentDB.targets')" />
<Import Project="..\..\packages\Microsoft.Azure.DocumentDB.1.10.0\build\Microsoft.Azure.DocumentDB.targets" Condition="Exists('..\..\packages\Microsoft.Azure.DocumentDB.1.10.0\build\Microsoft.Azure.DocumentDB.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\Microsoft.Azure.DocumentDB.1.6.1\build\Microsoft.Azure.DocumentDB.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Azure.DocumentDB.1.6.1\build\Microsoft.Azure.DocumentDB.targets'))" />
<Error Condition="!Exists('..\..\packages\Microsoft.Azure.DocumentDB.1.10.0\build\Microsoft.Azure.DocumentDB.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Azure.DocumentDB.1.10.0\build\Microsoft.Azure.DocumentDB.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

Просмотреть файл

@ -8,7 +8,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Azure.Documents.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.6.0.0" newVersion="1.6.0.0" />
<bindingRedirect oldVersion="0.0.0.0-1.10.0.0" newVersion="1.10.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>

Просмотреть файл

@ -1,9 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Castle.Core" version="3.3.3" targetFramework="net451" />
<package id="EnterpriseLibrary.TransientFaultHandling" version="6.0.1304.0" targetFramework="net45" />
<package id="Microsoft.Azure.DocumentDB" version="1.6.1" targetFramework="net451" />
<package id="Microsoft.Azure.DocumentDB.TransientFaultHandling" version="1.2.0" targetFramework="net45" />
<package id="Moq" version="4.2.1409.1722" targetFramework="net45" />
<package id="Microsoft.Azure.DocumentDB" version="1.10.0" targetFramework="net451" />
<package id="Microsoft.Azure.DocumentDB.TransientFaultHandling" version="1.4.0" targetFramework="net451" />
<package id="Moq" version="4.5.21" targetFramework="net451" />
<package id="Newtonsoft.Json" version="6.0.8" targetFramework="net451" />
<package id="System.Spatial" version="5.6.2" targetFramework="net45" />
<package id="System.Spatial" version="5.6.4" targetFramework="net451" />
</packages>

Просмотреть файл

@ -16,7 +16,8 @@
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
<IsCodedUITest>False</IsCodedUITest>
<TestProjectType>UnitTest</TestProjectType>
<NuGetPackageImportStamp>dd2064cf</NuGetPackageImportStamp>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -37,12 +38,17 @@
<CodeAnalysisRuleSet>ManagedMinimumRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Azure.Documents.Client, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.DocumentDB.1.6.1\lib\net45\Microsoft.Azure.Documents.Client.dll</HintPath>
<Reference Include="Castle.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Moq">
<HintPath>..\..\packages\Moq.4.2.1409.1722\lib\net40\Moq.dll</HintPath>
<Reference Include="Microsoft.Azure.Documents.Client, Version=1.10.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.DocumentDB.1.10.0\lib\net45\Microsoft.Azure.Documents.Client.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Moq, Version=4.5.21.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<HintPath>..\..\packages\Moq.4.5.21\lib\net45\Moq.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
@ -139,12 +145,12 @@
</Choose>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\packages\Microsoft.Azure.DocumentDB.1.6.1\build\Microsoft.Azure.DocumentDB.targets" Condition="Exists('..\..\packages\Microsoft.Azure.DocumentDB.1.6.1\build\Microsoft.Azure.DocumentDB.targets')" />
<Import Project="..\..\packages\Microsoft.Azure.DocumentDB.1.10.0\build\Microsoft.Azure.DocumentDB.targets" Condition="Exists('..\..\packages\Microsoft.Azure.DocumentDB.1.10.0\build\Microsoft.Azure.DocumentDB.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\Microsoft.Azure.DocumentDB.1.6.1\build\Microsoft.Azure.DocumentDB.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Azure.DocumentDB.1.6.1\build\Microsoft.Azure.DocumentDB.targets'))" />
<Error Condition="!Exists('..\..\packages\Microsoft.Azure.DocumentDB.1.10.0\build\Microsoft.Azure.DocumentDB.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Azure.DocumentDB.1.10.0\build\Microsoft.Azure.DocumentDB.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

Просмотреть файл

@ -26,7 +26,7 @@ namespace Microsoft.DataTransfer.DocumentDb.UnitTests.Sink
using (var adapter = new DocumentDbBulkSinkAdapter(clientMock, PassThroughTransformation.Instance, configurationMock))
{
await adapter.InitializeAsync();
await adapter.InitializeAsync(CancellationToken.None);
await adapter.CompleteAsync(CancellationToken.None);
}

Просмотреть файл

@ -4,6 +4,7 @@ using Microsoft.DataTransfer.TestsCommon;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.DataTransfer.DocumentDb.UnitTests.Sink
@ -28,7 +29,7 @@ namespace Microsoft.DataTransfer.DocumentDb.UnitTests.Sink
using (var adapter = new DocumentDbParallelSinkAdapter(clientMock, PassThroughTransformation.Instance, configuration))
{
await adapter.InitializeAsync();
await adapter.InitializeAsync(CancellationToken.None);
await WriteDataAsync(adapter, SampleData.GetSimpleDataItems(NumberOfItems));
}
@ -56,7 +57,7 @@ namespace Microsoft.DataTransfer.DocumentDb.UnitTests.Sink
using (var adapter = new DocumentDbParallelSinkAdapter(clientMock, PassThroughTransformation.Instance, configuration))
{
await adapter.InitializeAsync();
await adapter.InitializeAsync(CancellationToken.None);
await WriteDataAsync(adapter, SampleData.GetSimpleDataItems(NumberOfItems));
}

Просмотреть файл

@ -1,7 +1,6 @@
using Microsoft.Azure.Documents;
using Microsoft.DataTransfer.Basics.Threading;
using Microsoft.DataTransfer.DocumentDb.Client;
using Microsoft.DataTransfer.DocumentDb.Sink;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
@ -35,15 +34,8 @@ namespace Microsoft.DataTransfer.DocumentDb.UnitTests.Sink
deletedStoredProcedures = new HashSet<string>();
}
public Task<string> GetOrCreateCollectionAsync(string collectionName, CollectionPricingTier collectionTier, IndexingPolicy indexingPolicy)
{
Assert.IsFalse(String.IsNullOrEmpty(collectionName), TestResources.MissingCollectionNameInGetOrCreateCollection);
createdCollections.Add(collectionName);
return Task.FromResult(collectionName);
}
public Task<string> GetOrCreateElasticCollectionAsync(string collectionName, string partitionKey, int desiredThroughput, IndexingPolicy indexingPolicy)
public Task<string> GetOrCreateCollectionAsync(
string collectionName, string partitionKey, int desiredThroughput, IndexingPolicy indexingPolicy, CancellationToken cancellation)
{
Assert.IsFalse(String.IsNullOrEmpty(collectionName), TestResources.MissingCollectionNameInGetOrCreateCollection);

Просмотреть файл

@ -8,7 +8,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Azure.Documents.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.6.0.0" newVersion="1.6.0.0" />
<bindingRedirect oldVersion="0.0.0.0-1.10.0.0" newVersion="1.10.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>

Просмотреть файл

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Azure.DocumentDB" version="1.6.1" targetFramework="net451" />
<package id="Moq" version="4.2.1409.1722" targetFramework="net45" />
<package id="Castle.Core" version="3.3.3" targetFramework="net451" />
<package id="Microsoft.Azure.DocumentDB" version="1.10.0" targetFramework="net451" />
<package id="Moq" version="4.5.21" targetFramework="net451" />
<package id="Newtonsoft.Json" version="6.0.8" targetFramework="net451" />
</packages>

Просмотреть файл

@ -78,7 +78,6 @@
<Compile Include="Sink\Bulk\DocumentDbBulkSinkAdapterConfigurationSummaryPage.xaml.cs">
<DependentUpon>DocumentDbBulkSinkAdapterConfigurationSummaryPage.xaml</DependentUpon>
</Compile>
<Compile Include="Sink\Bulk\CollectionPricingTierValueConverter.cs" />
<Compile Include="Sink\DocumentDbSinkAdapterAdvancedConfigurationControl.xaml.cs">
<DependentUpon>DocumentDbSinkAdapterAdvancedConfigurationControl.xaml</DependentUpon>
</Compile>
@ -115,6 +114,7 @@
<EmbeddedResource Include="Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<AppDesigner Include="Properties\" />
</ItemGroup>

Просмотреть файл

@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.34209
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@ -60,42 +60,6 @@ namespace Microsoft.DataTransfer.DocumentDb.Wpf {
}
}
/// <summary>
/// Looks up a localized string similar to Standard: S1.
/// </summary>
internal static string CollectionPricingTier_S1 {
get {
return ResourceManager.GetString("CollectionPricingTier_S1", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Standard: S2.
/// </summary>
internal static string CollectionPricingTier_S2 {
get {
return ResourceManager.GetString("CollectionPricingTier_S2", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Standard: S3.
/// </summary>
internal static string CollectionPricingTier_S3 {
get {
return ResourceManager.GetString("CollectionPricingTier_S3", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Non-negative number of retries should be provided.
/// </summary>
internal static string InvalidNumberOfRetries {
get {
return ResourceManager.GetString("InvalidNumberOfRetries", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Non-negative retry interval should be provided.
/// </summary>

Просмотреть файл

@ -117,18 +117,6 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="CollectionPricingTier_S1" xml:space="preserve">
<value>Standard: S1</value>
</data>
<data name="CollectionPricingTier_S2" xml:space="preserve">
<value>Standard: S2</value>
</data>
<data name="CollectionPricingTier_S3" xml:space="preserve">
<value>Standard: S3</value>
</data>
<data name="InvalidNumberOfRetries" xml:space="preserve">
<value>Non-negative number of retries should be provided</value>
</data>
<data name="InvalidRetryInterval" xml:space="preserve">
<value>Non-negative retry interval should be provided</value>
</data>

Просмотреть файл

@ -23,23 +23,25 @@
</ResourceDictionary>
</UserControl.Resources>
<StackPanel>
<StackPanel Style="{StaticResource OptionElement}">
<Label Content="{DynamicResource RetriesKey}" />
<TextBox Text="{Binding Retries, UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
<AdornerDecorator>
<StackPanel>
<StackPanel Style="{StaticResource OptionElement}">
<Label Content="{DynamicResource RetriesKey}" />
<TextBox Text="{Binding Retries, UpdateSourceTrigger=PropertyChanged, TargetNullValue={x:Static system:String.Empty}}" />
</StackPanel>
<StackPanel Style="{StaticResource OptionElement}">
<Label Content="{DynamicResource RetryIntervalKey}" />
<TextBox Text="{Binding RetryInterval, UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
<StackPanel Style="{StaticResource OptionElement}">
<Label Content="{DynamicResource RetryIntervalKey}" />
<TextBox Text="{Binding RetryInterval, UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
<StackPanel Style="{StaticResource OptionElement}">
<bc:ToolTipDecorator ToolTip="{DynamicResource ConnectionModeDescriptionKey}">
<Label Content="{DynamicResource ConnectionModeKey}" />
</bc:ToolTipDecorator>
<ComboBox ItemsSource="{Binding Source={StaticResource ConnectionModeValues}}" SelectedValue="{Binding ConnectionMode}" />
<StackPanel Style="{StaticResource OptionElement}">
<bc:ToolTipDecorator ToolTip="{DynamicResource ConnectionModeDescriptionKey}">
<Label Content="{DynamicResource ConnectionModeKey}" />
</bc:ToolTipDecorator>
<ComboBox ItemsSource="{Binding Source={StaticResource ConnectionModeValues}}" SelectedValue="{Binding ConnectionMode}" />
</StackPanel>
</StackPanel>
</StackPanel>
</AdornerDecorator>
</UserControl>

Просмотреть файл

@ -25,23 +25,25 @@
</ResourceDictionary>
</UserControl.Resources>
<StackPanel x:Name="LayoutRoot" Style="{StaticResource OptionElement}">
<bc:ToolTipDecorator ToolTip="{DynamicResource ConnectionStringDescriptionKey}">
<Label Content="{DynamicResource ConnectionStringKey}" />
</bc:ToolTipDecorator>
<AdornerDecorator>
<StackPanel x:Name="LayoutRoot" Style="{StaticResource OptionElement}">
<bc:ToolTipDecorator ToolTip="{DynamicResource ConnectionStringDescriptionKey}">
<Label Content="{DynamicResource ConnectionStringKey}" />
</bc:ToolTipDecorator>
<Grid Style="{StaticResource ConnectionStringConfiguration}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid Style="{StaticResource ConnectionStringConfiguration}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="{Binding Configuration.ConnectionString, UpdateSourceTrigger=PropertyChanged, TargetNullValue={x:Static system:String.Empty}}" />
<Button Grid.Column="1"
Validation.ErrorTemplate="{x:Null}"
Content="{DynamicResource TestConnectionKey}"
Command="{Binding TestConnection}" CommandParameter="{Binding Configuration}" />
</Grid>
</StackPanel>
<TextBox Grid.Column="0" Text="{Binding Configuration.ConnectionString, UpdateSourceTrigger=PropertyChanged, TargetNullValue={x:Static system:String.Empty}}" />
<Button Grid.Column="1"
Validation.ErrorTemplate="{x:Null}"
Content="{DynamicResource TestConnectionKey}"
Command="{Binding TestConnection}" CommandParameter="{Binding Configuration}" />
</Grid>
</StackPanel>
</AdornerDecorator>
</UserControl>

Просмотреть файл

@ -2,7 +2,6 @@
using Microsoft.DataTransfer.WpfHost.Basics;
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace Microsoft.DataTransfer.DocumentDb.Wpf.Shared
{
@ -29,7 +28,7 @@ namespace Microsoft.DataTransfer.DocumentDb.Wpf.Shared
public int? Retries
{
get { return retries; }
set { SetProperty(ref retries, value, ValidateRetries); }
set { SetProperty(ref retries, value, ValidateNonNegativeInteger); }
}
public TimeSpan? RetryInterval
@ -45,11 +44,6 @@ namespace Microsoft.DataTransfer.DocumentDb.Wpf.Shared
RetryInterval = Defaults.Current.RetryInterval;
}
private static IReadOnlyCollection<string> ValidateRetries(int? value)
{
return value >= 0 ? null : new[] { Resources.InvalidNumberOfRetries };
}
private static IReadOnlyCollection<string> ValidateRetryInterval(TimeSpan? value)
{
return value >= TimeSpan.Zero ? null : new[] { Resources.InvalidRetryInterval };

Просмотреть файл

@ -1,20 +0,0 @@
using Microsoft.DataTransfer.DocumentDb.Sink;
using Microsoft.DataTransfer.WpfHost.Basics.ValueConverters;
using System.Collections.Generic;
namespace Microsoft.DataTransfer.DocumentDb.Wpf.Sink.Bulk
{
sealed class CollectionPricingTierValueConverter : EnumDisplayNameValueConverter.Base<CollectionPricingTier>
{
private static IDictionary<CollectionPricingTier, string> KnownValues =
new Dictionary<CollectionPricingTier, string>
{
{ CollectionPricingTier.S1, Resources.CollectionPricingTier_S1 },
{ CollectionPricingTier.S2, Resources.CollectionPricingTier_S2 },
{ CollectionPricingTier.S3, Resources.CollectionPricingTier_S3 }
};
public CollectionPricingTierValueConverter()
: base(KnownValues) { }
}
}

Просмотреть файл

@ -18,9 +18,6 @@ namespace Microsoft.DataTransfer.DocumentDb.Wpf.Sink.Bulk
public static readonly string PartitionKeyPropertyName =
ObjectExtensions.MemberName<IDocumentDbBulkSinkAdapterConfiguration>(c => c.PartitionKey);
public static readonly string CollectionTierPropertyName =
ObjectExtensions.MemberName<IDocumentDbBulkSinkAdapterConfiguration>(c => c.CollectionTier);
public static readonly string StoredProcFilePropertyName =
ObjectExtensions.MemberName<IDocumentDbBulkSinkAdapterConfiguration>(c => c.StoredProcFile);
@ -32,7 +29,6 @@ namespace Microsoft.DataTransfer.DocumentDb.Wpf.Sink.Bulk
private ObservableCollection<string> collections;
private string partitionKey;
private CollectionPricingTier? collectionTier;
private string storedProcFile;
private int? batchSize;
@ -64,12 +60,6 @@ namespace Microsoft.DataTransfer.DocumentDb.Wpf.Sink.Bulk
set { SetProperty(ref partitionKey, value); }
}
public CollectionPricingTier? CollectionTier
{
get { return collectionTier; }
set { SetProperty(ref collectionTier, value); }
}
public string StoredProcFile
{
get { return storedProcFile; }
@ -92,7 +82,6 @@ namespace Microsoft.DataTransfer.DocumentDb.Wpf.Sink.Bulk
: base(sharedConfiguration)
{
EditableCollections = new ObservableCollection<string>();
CollectionTier = Defaults.Current.BulkSinkCollectionTier;
BatchSize = Defaults.Current.BulkSinkBatchSize;
MaxScriptSize = Defaults.Current.BulkSinkMaxScriptSize;
}

Просмотреть файл

@ -7,7 +7,6 @@
xmlns:bc="clr-namespace:Microsoft.DataTransfer.WpfHost.Basics.Controls;assembly=Microsoft.DataTransfer.WpfHost.Basics"
xmlns:shared="clr-namespace:Microsoft.DataTransfer.DocumentDb.Wpf.Shared"
xmlns:sink="clr-namespace:Microsoft.DataTransfer.DocumentDb.Wpf.Sink"
xmlns:local="clr-namespace:Microsoft.DataTransfer.DocumentDb.Wpf.Sink.Bulk"
mc:Ignorable="d" x:ClassModifier="internal"
d:DesignHeight="300" d:DesignWidth="300">
@ -20,8 +19,6 @@
<Style x:Key="CollectionsList" TargetType="bc:EditableStringsListControl">
<Setter Property="Height" Value="75" />
</Style>
<ObjectDataProvider x:Key="CollectionTierValues" ObjectType="{x:Type local:CollectionPricingTierValueConverter}" MethodName="GetDisplayNames" />
</ResourceDictionary>
</UserControl.Resources>
@ -44,16 +41,6 @@
<TextBox Text="{Binding PartitionKey, UpdateSourceTrigger=PropertyChanged, TargetNullValue={x:Static system:String.Empty}}" />
</StackPanel>
<StackPanel Style="{StaticResource OptionElement}">
<bc:ToolTipDecorator ToolTip="{DynamicResource CollectionTierDescriptionKey}">
<Label Content="{DynamicResource CollectionTierKey}" />
</bc:ToolTipDecorator>
<ComboBox
ItemsSource="{Binding Source={StaticResource CollectionTierValues}}"
SelectedValue="{Binding CollectionTier}" SelectedValuePath="Key"
DisplayMemberPath="Value" />
</StackPanel>
<sink:DocumentDbSinkAdapterCommonConfigurationControl DataContext="{Binding}" />
<Expander Style="{DynamicResource OptionElement}" Header="{DynamicResource AdvancedConfigurationTitleKey}">
@ -71,12 +58,12 @@
<StackPanel Style="{StaticResource OptionElement}">
<Label Content="{DynamicResource BatchSizeKey}" />
<TextBox Text="{Binding BatchSize, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Text="{Binding BatchSize, UpdateSourceTrigger=PropertyChanged, TargetNullValue={x:Static system:String.Empty}}" />
</StackPanel>
<StackPanel Style="{StaticResource OptionElement}">
<Label Content="{DynamicResource MaxScriptSizeKey}" />
<TextBox Text="{Binding MaxScriptSize, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Text="{Binding MaxScriptSize, UpdateSourceTrigger=PropertyChanged, TargetNullValue={x:Static system:String.Empty}}" />
</StackPanel>
<sink:DocumentDbSinkAdapterAdvancedConfigurationControl DataContext="{Binding}" />

Просмотреть файл

@ -3,7 +3,6 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Microsoft.DataTransfer.DocumentDb.Wpf.Sink.Bulk"
xmlns:converters="clr-namespace:Microsoft.DataTransfer.WpfHost.Basics.ValueConverters;assembly=Microsoft.DataTransfer.WpfHost.Basics"
mc:Ignorable="d" x:ClassModifier="internal"
d:DesignHeight="360" d:DesignWidth="300">
@ -14,8 +13,6 @@
<ResourceDictionary Source="..\..\XamlResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
<local:CollectionPricingTierValueConverter x:Key="CollectionTierConverter" />
<converters:BooleanToVisibilityValueConverter x:Key="IsVisible" />
<converters:BooleanToVisibilityValueConverter x:Key="IsInvisible" True="Collapsed" False="Visible" />
<converters:BooleanToStringValueConverter x:Key="YesNoConverter" />
@ -58,9 +55,9 @@
<TextBlock Text="{Binding PartitionKey}" />
</Label>
<Label Grid.Row="3" Grid.Column="0" Content="{DynamicResource CollectionTierSummaryKey}" />
<Label Grid.Row="3" Grid.Column="0" Content="{DynamicResource CollectionThroughputSummaryKey}" />
<Label Grid.Row="3" Grid.Column="1">
<TextBlock Text="{Binding CollectionTier, Converter={StaticResource CollectionTierConverter}}" />
<TextBlock Text="{Binding CollectionThroughput}" />
</Label>
<Label Grid.Row="4" Grid.Column="0" Content="{DynamicResource IdFieldSummaryKey}" />

Просмотреть файл

@ -39,9 +39,6 @@ namespace Microsoft.DataTransfer.DocumentDb.Wpf.Sink.Bulk
if (!String.IsNullOrEmpty(configuration.PartitionKey))
arguments.Add(DocumentDbBulkSinkAdapterConfiguration.PartitionKeyPropertyName, configuration.PartitionKey);
if (configuration.CollectionTier.HasValue && configuration.CollectionTier.Value != Defaults.Current.BulkSinkCollectionTier)
arguments.Add(DocumentDbBulkSinkAdapterConfiguration.CollectionTierPropertyName, configuration.CollectionTier.Value.ToString());
if (!String.IsNullOrEmpty(configuration.StoredProcFile))
arguments.Add(DocumentDbBulkSinkAdapterConfiguration.StoredProcFilePropertyName, configuration.StoredProcFile);

Просмотреть файл

@ -32,40 +32,42 @@
</ResourceDictionary>
</UserControl.Resources>
<StackPanel>
<bc:ToolTipDecorator Style="{StaticResource SingleLineOptionElement}" ToolTip="{DynamicResource DisableIdGenerationDescriptionKey}">
<CheckBox Content="{DynamicResource DisableIdGenerationKey}" IsChecked="{Binding DisableIdGeneration}" />
</bc:ToolTipDecorator>
<AdornerDecorator>
<StackPanel>
<bc:ToolTipDecorator Style="{StaticResource SingleLineOptionElement}" ToolTip="{DynamicResource DisableIdGenerationDescriptionKey}">
<CheckBox Content="{DynamicResource DisableIdGenerationKey}" IsChecked="{Binding DisableIdGeneration}" />
</bc:ToolTipDecorator>
<bc:ToolTipDecorator Style="{StaticResource SingleLineOptionElement}" ToolTip="{DynamicResource UpdateExistingDescriptionKey}">
<CheckBox Content="{DynamicResource UpdateExistingKey}" IsChecked="{Binding UpdateExisting}" />
</bc:ToolTipDecorator>
<bc:ToolTipDecorator Style="{StaticResource SingleLineOptionElement}" ToolTip="{DynamicResource UpdateExistingDescriptionKey}">
<CheckBox Content="{DynamicResource UpdateExistingKey}" IsChecked="{Binding UpdateExisting}" />
</bc:ToolTipDecorator>
<StackPanel Style="{StaticResource OptionElement}">
<Label Content="{DynamicResource DatesHandlingKey}" />
<ComboBox ItemsSource="{Binding Source={StaticResource DateTimeHandlingValues}}" SelectedValue="{Binding Dates}" />
<StackPanel Style="{StaticResource OptionElement}">
<Label Content="{DynamicResource DatesHandlingKey}" />
<ComboBox ItemsSource="{Binding Source={StaticResource DateTimeHandlingValues}}" SelectedValue="{Binding Dates}" />
</StackPanel>
<bc:StringOrFileConfigurationControl Style="{StaticResource IndexingPolicyEditor}"
UseFile="{Binding UseIndexingPolicyFile}"
StringValueLabel="{DynamicResource EnterIndexingPolicySelectionKey}" StringValue="{Binding IndexingPolicy}"
FileNameLabel="{DynamicResource IndexingPolicyFileSelectionKey}" FileName="{Binding IndexingPolicyFile}"
FileFilter="{DynamicResource IndexingPolicyFileFilterKey}" FileDefaultExtension="{DynamicResource IndexingPolicyFileDefaultExtensionKey}">
<bc:StringOrFileConfigurationControl.StringEditorContextMenu>
<ContextMenu>
<MenuItem Header="{DynamicResource IndexingPolicyDefaultTemplateMenuHeader}"
Command="{Binding Source={StaticResource PasteToFocusedTextBox}}" CommandParameter="{DynamicResource IndexingPolicyDefaultTemplate}" />
<MenuItem Header="{DynamicResource IndexingPolicyAllRangeTemplateMenuHeader}"
Command="{Binding Source={StaticResource PasteToFocusedTextBox}}" CommandParameter="{DynamicResource IndexingPolicyAllRangeTemplate}" />
<Separator />
<MenuItem Command="ApplicationCommands.Copy" />
<MenuItem Command="ApplicationCommands.Cut" />
<MenuItem Command="ApplicationCommands.Paste" />
</ContextMenu>
</bc:StringOrFileConfigurationControl.StringEditorContextMenu>
</bc:StringOrFileConfigurationControl>
<shared:DocumentDbAdapterAdvancedConfigurationControl DataContext="{Binding}" />
</StackPanel>
<bc:StringOrFileConfigurationControl Style="{StaticResource IndexingPolicyEditor}"
UseFile="{Binding UseIndexingPolicyFile}"
StringValueLabel="{DynamicResource EnterIndexingPolicySelectionKey}" StringValue="{Binding IndexingPolicy}"
FileNameLabel="{DynamicResource IndexingPolicyFileSelectionKey}" FileName="{Binding IndexingPolicyFile}"
FileFilter="{DynamicResource IndexingPolicyFileFilterKey}" FileDefaultExtension="{DynamicResource IndexingPolicyFileDefaultExtensionKey}">
<bc:StringOrFileConfigurationControl.StringEditorContextMenu>
<ContextMenu>
<MenuItem Header="{DynamicResource IndexingPolicyDefaultTemplateMenuHeader}"
Command="{Binding Source={StaticResource PasteToFocusedTextBox}}" CommandParameter="{DynamicResource IndexingPolicyDefaultTemplate}" />
<MenuItem Header="{DynamicResource IndexingPolicyAllRangeTemplateMenuHeader}"
Command="{Binding Source={StaticResource PasteToFocusedTextBox}}" CommandParameter="{DynamicResource IndexingPolicyAllRangeTemplate}" />
<Separator />
<MenuItem Command="ApplicationCommands.Copy" />
<MenuItem Command="ApplicationCommands.Cut" />
<MenuItem Command="ApplicationCommands.Paste" />
</ContextMenu>
</bc:StringOrFileConfigurationControl.StringEditorContextMenu>
</bc:StringOrFileConfigurationControl>
<shared:DocumentDbAdapterAdvancedConfigurationControl DataContext="{Binding}" />
</StackPanel>
</AdornerDecorator>
</UserControl>

Просмотреть файл

@ -4,6 +4,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:bc="clr-namespace:Microsoft.DataTransfer.WpfHost.Basics.Controls;assembly=Microsoft.DataTransfer.WpfHost.Basics"
mc:Ignorable="d" x:ClassModifier="internal"
d:DesignHeight="300" d:DesignWidth="300">
@ -15,11 +16,20 @@
</ResourceDictionary>
</UserControl.Resources>
<StackPanel>
<StackPanel Style="{StaticResource OptionElement}">
<Label Content="{DynamicResource IdFieldKey}" />
<TextBox Text="{Binding IdField, UpdateSourceTrigger=PropertyChanged, TargetNullValue={x:Static system:String.Empty}}" />
<AdornerDecorator>
<StackPanel>
<StackPanel Style="{StaticResource OptionElement}">
<bc:ToolTipDecorator ToolTip="{DynamicResource CollectionThroughputDescriptionKey}">
<Label Content="{DynamicResource CollectionThroughputKey}" />
</bc:ToolTipDecorator>
<TextBox Text="{Binding CollectionThroughput, UpdateSourceTrigger=PropertyChanged, TargetNullValue={x:Static system:String.Empty}}" />
</StackPanel>
<StackPanel Style="{StaticResource OptionElement}">
<Label Content="{DynamicResource IdFieldKey}" />
<TextBox Text="{Binding IdField, UpdateSourceTrigger=PropertyChanged, TargetNullValue={x:Static system:String.Empty}}" />
</StackPanel>
</StackPanel>
</StackPanel>
</AdornerDecorator>
</UserControl>

Просмотреть файл

@ -9,6 +9,9 @@ namespace Microsoft.DataTransfer.DocumentDb.Wpf.Sink
{
abstract class DocumentDbSinkAdapterConfiguration : DocumentDbAdapterConfiguration<ISharedDocumentDbSinkAdapterConfiguration>, IDocumentDbSinkAdapterConfiguration
{
public static readonly string CollectionThroughputPropertyName =
ObjectExtensions.MemberName<IDocumentDbSinkAdapterConfiguration>(c => c.CollectionThroughput);
public static readonly string IndexingPolicyPropertyName =
ObjectExtensions.MemberName<IDocumentDbSinkAdapterConfiguration>(c => c.IndexingPolicy);
@ -30,6 +33,12 @@ namespace Microsoft.DataTransfer.DocumentDb.Wpf.Sink
private static readonly string UseIndexingPolicyFilePropertyName =
ObjectExtensions.MemberName<DocumentDbSinkAdapterConfiguration>(c => c.UseIndexingPolicyFile);
public int? CollectionThroughput
{
get { return SharedConfiguration.CollectionThroughput; }
set { SharedConfiguration.CollectionThroughput = value; }
}
public bool UseIndexingPolicyFile
{
get { return SharedConfiguration.UseIndexingPolicyFile; }
@ -78,6 +87,7 @@ namespace Microsoft.DataTransfer.DocumentDb.Wpf.Sink
protected override Map<string, string> GetSharedPropertiesMapping()
{
var mapping = base.GetSharedPropertiesMapping();
mapping.Add(SharedDocumentDbSinkAdapterConfigurationProperties.CollectionThroughput, CollectionThroughputPropertyName);
mapping.Add(SharedDocumentDbSinkAdapterConfigurationProperties.UseIndexingPolicyFile, UseIndexingPolicyFilePropertyName);
mapping.Add(SharedDocumentDbSinkAdapterConfigurationProperties.IndexingPolicy, IndexingPolicyPropertyName);
mapping.Add(SharedDocumentDbSinkAdapterConfigurationProperties.IndexingPolicyFile, IndexingPolicyFilePropertyName);

Просмотреть файл

@ -3,6 +3,7 @@ using Microsoft.DataTransfer.DocumentDb.Wpf.Shared;
using Microsoft.DataTransfer.WpfHost.Extensibility;
using System;
using System.Collections.Generic;
using System.Globalization;
namespace Microsoft.DataTransfer.DocumentDb.Wpf.Sink
{
@ -24,6 +25,11 @@ namespace Microsoft.DataTransfer.DocumentDb.Wpf.Sink
Guard.NotNull("configuration", configuration);
Guard.NotNull("arguments", arguments);
if (configuration.CollectionThroughput.HasValue && configuration.CollectionThroughput.Value != Defaults.Current.SinkCollectionThroughput)
arguments.Add(
DocumentDbSinkAdapterConfiguration.CollectionThroughputPropertyName,
configuration.CollectionThroughput.Value.ToString(CultureInfo.InvariantCulture));
if (configuration.UseIndexingPolicyFile)
{
if (!String.IsNullOrEmpty(configuration.IndexingPolicyFile))

Просмотреть файл

@ -5,6 +5,7 @@ namespace Microsoft.DataTransfer.DocumentDb.Wpf.Sink
{
interface ISharedDocumentDbSinkAdapterConfiguration : ISharedDocumentDbAdapterConfiguration
{
int? CollectionThroughput { get; set; }
bool UseIndexingPolicyFile { get; set; }
string IndexingPolicy { get; set; }
string IndexingPolicyFile { get; set; }

Просмотреть файл

@ -11,15 +11,11 @@ namespace Microsoft.DataTransfer.DocumentDb.Wpf.Sink.Parallel
public static readonly string PartitionKeyPropertyName =
ObjectExtensions.MemberName<IDocumentDbParallelSinkAdapterConfiguration>(c => c.PartitionKey);
public static readonly string CollectionThroughputPropertyName =
ObjectExtensions.MemberName<IDocumentDbParallelSinkAdapterConfiguration>(c => c.CollectionThroughput);
public static readonly string ParallelRequestsPropertyName =
ObjectExtensions.MemberName<IDocumentDbParallelSinkAdapterConfiguration>(c => c.ParallelRequests);
private string collection;
private string partitionKey;
private int? collectionThroughput;
private int? parallelRequests;
@ -35,12 +31,6 @@ namespace Microsoft.DataTransfer.DocumentDb.Wpf.Sink.Parallel
set { SetProperty(ref partitionKey, value); }
}
public int? CollectionThroughput
{
get { return collectionThroughput; }
set { SetProperty(ref collectionThroughput, value, ValidatePositiveInteger); }
}
public int? ParallelRequests
{
get { return parallelRequests; }
@ -50,7 +40,6 @@ namespace Microsoft.DataTransfer.DocumentDb.Wpf.Sink.Parallel
public DocumentDbParallelSinkAdapterConfiguration(ISharedDocumentDbSinkAdapterConfiguration sharedConfiguration)
: base(sharedConfiguration)
{
CollectionThroughput = Defaults.Current.ParallelSinkCollectionThroughput;
ParallelRequests = Defaults.Current.ParallelSinkNumberOfParallelRequests;
}
}

Просмотреть файл

@ -35,20 +35,13 @@
<TextBox Text="{Binding PartitionKey, UpdateSourceTrigger=PropertyChanged, TargetNullValue={x:Static system:String.Empty}}" />
</StackPanel>
<StackPanel Style="{StaticResource OptionElement}">
<bc:ToolTipDecorator ToolTip="{DynamicResource CollectionThroughputDescriptionKey}">
<Label Content="{DynamicResource CollectionThroughputKey}" />
</bc:ToolTipDecorator>
<TextBox Text="{Binding CollectionThroughput, UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
<sink:DocumentDbSinkAdapterCommonConfigurationControl DataContext="{Binding}" />
<Expander Style="{DynamicResource OptionElement}" Header="{DynamicResource AdvancedConfigurationTitleKey}">
<StackPanel>
<StackPanel Style="{StaticResource OptionElement}">
<Label Content="{DynamicResource ParallelRequestsKey}" />
<TextBox Text="{Binding ParallelRequests, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Text="{Binding ParallelRequests, UpdateSourceTrigger=PropertyChanged, TargetNullValue={x:Static system:String.Empty}}" />
</StackPanel>
<sink:DocumentDbSinkAdapterAdvancedConfigurationControl DataContext="{Binding}" />

Просмотреть файл

@ -39,11 +39,6 @@ namespace Microsoft.DataTransfer.DocumentDb.Wpf.Sink.Parallel
if (!String.IsNullOrEmpty(configuration.PartitionKey))
arguments.Add(DocumentDbParallelSinkAdapterConfiguration.PartitionKeyPropertyName, configuration.PartitionKey);
if (configuration.CollectionThroughput.HasValue && configuration.CollectionThroughput.Value != Defaults.Current.ParallelSinkCollectionThroughput)
arguments.Add(
DocumentDbParallelSinkAdapterConfiguration.CollectionThroughputPropertyName,
configuration.CollectionThroughput.Value.ToString(CultureInfo.InvariantCulture));
if (configuration.ParallelRequests.HasValue && configuration.ParallelRequests.Value != Defaults.Current.ParallelSinkNumberOfParallelRequests)
arguments.Add(
DocumentDbParallelSinkAdapterConfiguration.ParallelRequestsPropertyName,

Просмотреть файл

@ -1,13 +1,12 @@
using Microsoft.DataTransfer.DocumentDb.Sink;
using Microsoft.DataTransfer.DocumentDb.Wpf.Shared;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
namespace Microsoft.DataTransfer.DocumentDb.Wpf.Sink
{
sealed class SharedDocumentDbSinkAdapterConfiguration : SharedDocumentDbAdapterConfiguration, ISharedDocumentDbSinkAdapterConfiguration
{
private int? collectionThroughput;
private bool useIndexingPolicyFile;
private string indexingPolicy;
private string indexingPolicyFile;
@ -18,6 +17,12 @@ namespace Microsoft.DataTransfer.DocumentDb.Wpf.Sink
private DateTimeHandling? dates;
public int? CollectionThroughput
{
get { return collectionThroughput; }
set { SetProperty(ref collectionThroughput, value, ValidateNonNegativeInteger); }
}
public bool UseIndexingPolicyFile
{
get { return useIndexingPolicyFile; }
@ -62,6 +67,7 @@ namespace Microsoft.DataTransfer.DocumentDb.Wpf.Sink
public SharedDocumentDbSinkAdapterConfiguration()
{
CollectionThroughput = Defaults.Current.SinkCollectionThroughput;
Dates = Defaults.Current.SinkDateTimeHandling;
}
}

Просмотреть файл

@ -4,6 +4,9 @@ namespace Microsoft.DataTransfer.DocumentDb.Wpf.Sink
{
static class SharedDocumentDbSinkAdapterConfigurationProperties
{
public static readonly string CollectionThroughput =
ObjectExtensions.MemberName<ISharedDocumentDbSinkAdapterConfiguration>(c => c.CollectionThroughput);
public static readonly string UseIndexingPolicyFile =
ObjectExtensions.MemberName<ISharedDocumentDbSinkAdapterConfiguration>(c => c.UseIndexingPolicyFile);

Просмотреть файл

@ -34,10 +34,6 @@
</system:String>
<system:String x:Key="PartitionKeySummaryKey">Partition Key:</system:String>
<system:String x:Key="CollectionTierKey">Collection Pricing Tier</system:String>
<system:String x:Key="CollectionTierDescriptionKey">Specify the pricing / performance tier of the collection. Note that this only applies to collection creation, existing collections will not have their pricing tier modified</system:String>
<system:String x:Key="CollectionTierSummaryKey">Collection Pricing Tier:</system:String>
<system:String x:Key="CollectionThroughputKey">Collection Throughput</system:String>
<system:String x:Key="CollectionThroughputDescriptionKey">Specify the desired throughput for the collection in RUs (request units). Note that this only applies to collection creation, existing collections will not have their throughput modified</system:String>
<system:String x:Key="CollectionThroughputSummaryKey">Collection Throughput:</system:String>

Просмотреть файл

@ -8,7 +8,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Azure.Documents.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.6.0.0" newVersion="1.6.0.0" />
<bindingRedirect oldVersion="0.0.0.0-1.10.0.0" newVersion="1.10.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше