Skip to content

Commit

Permalink
First working version of schemas and creation of assembly
Browse files Browse the repository at this point in the history
  • Loading branch information
madd0 committed Jan 6, 2012
1 parent e460fdb commit 1eb6be2
Show file tree
Hide file tree
Showing 6 changed files with 226 additions and 8 deletions.
40 changes: 40 additions & 0 deletions Madd0.AzureStorageDriver/AzureDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,53 @@ public override bool AreRepositoriesEquivalent(IConnectionInfo connection1, ICon
return account1.Equals(account2);
}

public override IEnumerable<string> GetAssembliesToAdd()
{
return new string[]
{
"System.Data.Services.Client.dll",
"Microsoft.WindowsAzure.StorageClient.dll"
};
}

public override IEnumerable<string> GetNamespacesToAdd()
{
return new string[]
{
"System.Data.Services.Client",
"Microsoft.WindowsAzure",
"Microsoft.WindowsAzure.StorageClient"
};
}

public override List<ExplorerItem> GetSchemaAndBuildAssembly(IConnectionInfo connectionInfo, System.Reflection.AssemblyName assemblyToBuild, ref string nameSpace, ref string typeName)
{
return SchemaBuilder.GetSchemaAndBuildAssembly(
new StorageAccountProperties(connectionInfo),
this.GetDriverFolder(),
assemblyToBuild,
ref nameSpace,
ref typeName);
}

public override object[] GetContextConstructorArguments(IConnectionInfo connectionInfo)
{
var properties = new StorageAccountProperties(connectionInfo);

return new object[]
{
properties.GetStorageAccount().TableEndpoint.ToString(),
properties.GetStorageAccount().Credentials
};
}

public override ParameterDescriptor[] GetContextConstructorParameters(IConnectionInfo connectionInfo)
{
return new[]
{
new ParameterDescriptor("baseAddress", "System.String"),
new ParameterDescriptor("credentials", "Microsoft.WindowsAzure.StorageCredentials")
};
}
}
}
1 change: 1 addition & 0 deletions Madd0.AzureStorageDriver/DevDeploy.bat
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ rem

xcopy /i/y Madd0.AzureStorageDriver.dll "%AllUsersProfile%\LINQPad\Drivers\DataContext\4.0\Madd0.AzureStorageDriver (47842961fb3025d7)\"
xcopy /i/y Madd0.AzureStorageDriver.pdb "%AllUsersProfile%\LINQPad\Drivers\DataContext\4.0\Madd0.AzureStorageDriver (47842961fb3025d7)\"
xcopy /i/y Microsoft.WindowsAzure.StorageClient.dll "%AllUsersProfile%\LINQPad\Drivers\DataContext\4.0\Madd0.AzureStorageDriver (47842961fb3025d7)\"
47 changes: 47 additions & 0 deletions Madd0.AzureStorageDriver/GenericEntity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//-----------------------------------------------------------------------
// <copyright file="GenericEntry.cs" company="">
// Copyright (c) madd0, . All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
namespace Madd0.AzureStorageDriver
{
using System;
using System.Linq;
using Microsoft.WindowsAzure.StorageClient;
using System.Data.Services.Common;
using System.Collections.Generic;

[DataServiceKey("PartitionKey", "RowKey")]
public class GenericEntity : TableServiceEntity
{
Dictionary<string, string> properties = new Dictionary<string, string>();

/// <summary>
/// Gets or sets the table name.
/// </summary>
/// <value>The table name.</value>
public string TableName
{
get;
set;
}

public Dictionary<string, string> Properties
{
get { return this.properties; }
}

internal string this[string key]
{
get
{
return this.properties[key];
}

set
{
this.properties[key] = value;
}
}
}
}
3 changes: 3 additions & 0 deletions Madd0.AzureStorageDriver/Madd0.AzureStorageDriver.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data.Services.Client" />
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
Expand All @@ -55,9 +56,11 @@
</ItemGroup>
<ItemGroup>
<Compile Include="AzureDriver.cs" />
<Compile Include="Class1.cs" />
<Compile Include="ConnectionDialog.xaml.cs">
<DependentUpon>ConnectionDialog.xaml</DependentUpon>
</Compile>
<Compile Include="GenericEntity.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
Expand Down
116 changes: 108 additions & 8 deletions Madd0.AzureStorageDriver/SchemaBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,22 @@ namespace Madd0.AzureStorageDriver
using LINQPad.Extensibility.DataContext;
using System.Reflection;
using System.Xml.Linq;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
using System.Data.Services.Client;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.IO;

/// <summary>
/// TODO: Provide summary section in the documentation header.
/// </summary>
internal static class SchemaBuilder
{
public static List<ExplorerItem> GetSchemaAndBuildAssembly(StorageAccountProperties properties, AssemblyName name, ref string nameSpace, ref string typeName)

public static List<ExplorerItem> GetSchemaAndBuildAssembly(StorageAccountProperties properties, string driverFolder, AssemblyName name, ref string nameSpace, ref string typeName)
{

// Read the EDM schema into an XDocument:
//XDocument data;
//using (XmlReader reader = GetSchemaReader(props))
Expand All @@ -32,23 +40,115 @@ public static List<ExplorerItem> GetSchemaAndBuildAssembly(StorageAccountPropert
// code = GenerateCode(reader, nameSpace);

// Compile the code into the assembly, using the assembly name provided:
//BuildAssembly(code, name);
BuildAssembly(name, driverFolder, typeName, nameSpace);

// Use the schema to populate the Schema Explorer:
//List<ExplorerItem> schema = GetSchema(data, out typeName);
List<ExplorerItem> schema = GetSchema(null, out typeName);
List<ExplorerItem> schema = GetSchema(properties);

return schema;
}

private static List<ExplorerItem> GetSchema(XDocument data, out string typeName)
private static void BuildAssembly(AssemblyName name, string driverFolder, string typeName, string nameSpace)
{
var code = @"namespace " + nameSpace + @"
{
public class " + typeName + @" : Microsoft.WindowsAzure.StorageClient.TableServiceContext
{
public " + typeName + @"(string baseAddress, Microsoft.WindowsAzure.StorageCredentials credentials)
: base(baseAddress, credentials)
{
typeName = "TypeName";
return new List<ExplorerItem>()
}
}
}";
CompilerResults results;
using (var codeProvider = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v4.0" } }))
{
new ExplorerItem("TestItem", ExplorerItemKind.Category, ExplorerIcon.Table)
};
var options = new CompilerParameters(
new [] { "System.dll", "System.Core.dll", "System.Xml.dll", "System.Data.Services.Client.dll", Path.Combine(driverFolder, "Microsoft.WindowsAzure.StorageClient.dll") },
name.CodeBase,
true);
results = codeProvider.CompileAssemblyFromSource(options, code);
}
if (results.Errors.Count > 0)
throw new Exception
("Cannot compile typed context: " + results.Errors[0].ErrorText + " (line " + results.Errors[0].Line + ")");
}

private static List<ExplorerItem> GetSchema(StorageAccountProperties properties)
{
var tableClient = properties.GetStorageAccount().CreateCloudTableClient();
var dataContext = tableClient.GetDataServiceContext();
dataContext.ReadingEntity += OnReadingEntity;

return (from tableName in tableClient.ListTables()
select new ExplorerItem(tableName, ExplorerItemKind.QueryableObject, ExplorerIcon.Table)
{
Children = (from columnName in dataContext.CreateQuery<GenericEntity>(tableName).Take(1).First().Properties
select new ExplorerItem(columnName.Key + " (" + columnName.Value + ")", ExplorerItemKind.Property, ExplorerIcon.Column)).ToList()
}).ToList();
}

static void OnReadingEntity(object sender, ReadingWritingEntityEventArgs e)
{
// TODO: Make these statics
XNamespace AtomNamespace = "http://www.w3.org/2005/Atom";
XNamespace AstoriaDataNamespace = "http://schemas.microsoft.com/ado/2007/08/dataservices";
XNamespace AstoriaMetadataNamespace = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";

GenericEntity entity = e.Entity as GenericEntity;

if (entity == null)
{
return;
}

entity.TableName = e.Data.Element(AtomNamespace + "link").Attribute("title").Value;

// read each property, type and value in the payload
//var properties = e.Entity.GetType().GetProperties();
//where properties.All(pp => pp.Name != p.Name.LocalName)
var q = from p in e.Data.Element(AtomNamespace + "content")
.Element(AstoriaMetadataNamespace + "properties")
.Elements()
select new
{
Name = p.Name.LocalName,
IsNull = string.Equals("true", p.Attribute(AstoriaMetadataNamespace + "null") == null ? null : p.Attribute(AstoriaMetadataNamespace + "null").Value, StringComparison.OrdinalIgnoreCase),
TypeName = p.Attribute(AstoriaMetadataNamespace + "type") == null ? "Edm.String" : p.Attribute(AstoriaMetadataNamespace + "type").Value,
p.Value
};

foreach (var dp in q)
{
entity[dp.Name] = dp.TypeName;
}
}

private static Type GetType(string type)
{
if (type == null)
return typeof(string);

switch (type)
{
case "Edm.String": return typeof(string);
case "Edm.Byte": return typeof(byte);
case "Edm.SByte": return typeof(sbyte);
case "Edm.Int16": return typeof(short);
case "Edm.Int32": return typeof(int);
case "Edm.Int64": return typeof(long);
case "Edm.Double": return typeof(double);
case "Edm.Single": return typeof(float);
case "Edm.Boolean": return typeof(bool);
case "Edm.Decimal": return typeof(decimal);
case "Edm.DateTime": return typeof(DateTime);
case "Edm.Binary": return typeof(byte[]);
case "Edm.Guid": return typeof(Guid);

default: throw new NotSupportedException("Not supported type " + type);
}
}
}
}
27 changes: 27 additions & 0 deletions Madd0.AzureStorageDriver/StorageAccountProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace Madd0.AzureStorageDriver
using LINQPad.Extensibility.DataContext;
using System.Xml.Linq;
using Madd0.AzureStorageDriver.Properties;
using Microsoft.WindowsAzure;

/// <summary>
/// Wrapper to expose typed properties over ConnectionInfo.DriverData.
Expand Down Expand Up @@ -68,6 +69,20 @@ public bool UseLocalStorage
}
}

public bool UseHttps
{
get
{
var currentValue = (string)this._driverData.Element("UseHttps") ?? string.Empty;
return Convert.ToBoolean(currentValue);
}

set
{
this._driverData.SetElementValue("UseHttps", value);
}
}

public string AccountName
{
get { return (string)this._driverData.Element("AccountName") ?? string.Empty; }
Expand Down Expand Up @@ -104,5 +119,17 @@ private void ClearAccountNameAndKey()
accountKey.Remove();
}
}

public CloudStorageAccount GetStorageAccount()
{
if (this.UseLocalStorage)
{
return CloudStorageAccount.DevelopmentStorageAccount;
}
else
{
return new CloudStorageAccount(new StorageCredentialsAccountAndKey(this.AccountName, this.AccountKey), this.UseHttps);
}
}
}
}

0 comments on commit 1eb6be2

Please sign in to comment.