In my previous post , i mentioned about configuring Team build along with XUnit without installing anything on the build machine. This is sometimes useful as the build machine is miles away and is shared among other projects  and you don’t want to mess things up installing your stuffs.

Now, inside the TeamBuildTypes folder you can add your referenced dlls which you can use in your MSBuild target file to do automated test, which is on the other hand is referenced in TFSBuild.Proj file.

Now, It’s fine, but let’s say i want to organize my folders a little bit and occasionally want to drop the docs along with current build  from the source or any other folder that is necessary. To do so, we can visually customize it from Builds –> My Build –> Edit Build Definition –> Workspaces.

 

BuildWorkspace

 

Here, MyRoot is the root in my TFS setup where MyFolder is the one under which i have CodeBase, Build, Help , etc. By default, as sources get into a temp folder before the build starts , all the files from solution directory will be get and is entered under workspace folders automatically as you select your project file.  But if you want to get a Help file or reference assembly , in this case  XUnit MsBuild dlls then you have to specify it in this wizard, if you don’t want to have them under TeamBuildTypes/MyDefinationName folder.

Finally, from the previous XUniBuild.Targets our reference path will change like:

   1:    <UsingTask  AssemblyFile="$(SolutionRoot)\MyFolder\Build\xunit.runner.msbuild.dll"
   2:     TaskName="Xunit.Runner.MSBuild.xunit"/>
 
Or copy docs from
 
   1:  <Copy SourceFiles="$(SolutionRoot)\MyFolder\Help\MyDoc.docx" DestinationFiles="$(OutDir)\Docs\MyDoc.docx" /> 

 

Here , $(SolutionRoot) is the temp folder where items to be get according to the  workspace setup, where you can add/ modify items as you want and you can also see how its going from BuildLog that is dropped after each build to the root of your drop folder.

 

If you missed the previous post , here it is again:

http://weblogs.asp.net/mehfuzh/archive/2009/08/25/configuring-team-build-using-xunit.aspx

 

Hope that helps

Shout it

Recently, while i was setting up TFS build [to enable CI] for a project at Telerik that i am currently working on, i came across configuring it up with XUnit for doing automated tests every time someone checks-in source code after the build process is complete using the Xunit MsBuild task and additionally it will print the build steps so that developer knows what’s the issue.

Now, to layout a little bit of background. When you setup a “New build Definition” from Team Explorer – > Builds . TFS actually drops a  TFSBuild.proj under  “$/ProjectName/TeamBuidTypes/BuildDefinationName/” folder . This is nothing but a regular MSBuild file that defines how and where your project should be built and dropped and how it will be tested.

image

TFS gives out of the box support for VSTests , but for other types you need to do a little bit of configuration.When you do a check-in[If build process is setup to fire for each check-in],first TFS does a GET operation from /TeamBuildTypes/BuildDefinationName/ and after that it starts executing as things are defined in TFSBuild.proj. In the pasted Team explorer snap you can see that i have added a target file named “XunitBuild.targets”. It is referenced in TFSBuild.proj  somewhere above the <itemGroup> like

   1: <Import Project="$(MSBuildProjectDirectory)\XUnitBuild.targets" />

To use xunit task we need to include the following two assemblies in same folder with TFSBuild.proj.

  • xunit.runner.msbuild.dll
  • xunit.runner.utiliy.dll

 

Inside XUnitBuild.targets, first of all we need to reference the task. Just to mention that assembly file path will be preceded by a folder path where TFSBuild.proj is stored though GET operation.

   1: <UsingTask  AssemblyFile="xunit.runner.msbuild.dll"
   2:    TaskName="Xunit.Runner.MSBuild.xunit"/>

Next, we need to hook the task under specific target that will be invoked by TFS automatically. TFS has some predefined targets that are fired at different steps of the build process, we can hook them to perform some custom tasks before, during or after each step is completed.

Some of the targets are :

  • AfterCompile
  • BeforeTest
  • CoreTest
  • AfterTest
  • AfterDropBuild

You can get the full list from MSDN but i would rather leave it up to you as it is not the main topic here. Moving forward, i have hooked CoreTest Target [ set Name=”CoreTest”]. Inside it, i created a build step that will print if tests are successful or failed depending on the result returned by xunit task.

   1: <BuildStep
   2:            TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
   3:            BuildUri="$(BuildUri)"
   4:            Message="Preparing to test...">
   5:       <Output TaskParameter="Id" PropertyName="StepId" />
   6:     </BuildStep>

On first run BuildStep task will produce an Id that will be stored in a property which will be used later to print test status. 

   1: <xunit ContinueOnError="true" Assembly="$(OutDir)\Sample.Tests.dll" Verbose="true">
   2:       <Output TaskParameter="ExitCode" PropertyName="Result" />
   3: </xunit>

Executing xunit task requires the assembly path for tests to perform on,  additionally you can specify it to be verbose and finally can store the return code in a property for further checks. Here, i have also specified “ContinueOnError=true” as for any failure, things will be handled manually.

   1: <BuildStep Condition="'$(Result)'=='0'" TeamFoundationServerUrl="$(TeamFoundationServerUrl)" 
   2:              BuildUri="$(BuildUri)" Id="$(StepId)" Status="Succeeded" Message="Test succeeded." />
   3:   <BuildStep Condition="'$(Result)'!='0'" TeamFoundationServerUrl="$(TeamFoundationServerUrl)" 
   4:              BuildUri="$(BuildUri)" Id="$(StepId)"  Status="Failed"  Message="Test Failed." />
   5:  
   6:   <Error Condition="'$(Result)'!='0'" Text="Test failed."/>

Above two BuildStep tasks  will print test status depending on the result set by xunit task for previously created step and followed by Error task will fail the build for same.  Finally, when we will be expanding the build explorer, list will contain the custom step where build status will be determined from the error condition.

image

That’s it and here goes the target file XUnitBuild.zip . I actually binged it out and covered all together in one place so that it saves a little time of yours so feel free to suggest anything that comes to your mind.

Enjoy !!!

Shout it
Now , it happens that you go to McDonalds website and order an item for you. It could happen that price of the menu changed or new one comes to the menu. Now, generally it can happen that admin can go though wizard and loads of textboxes or dropdowns to make the changes or he/she can just write as if he/she is writing in some text editor and everything else is taken care of on behalf. Textual DSL is a powerful tool that might become the future of how we communicate to computer systems. Well, things are not that easy to convert human language to machine readable forms completely but its not bad to dream for the best :-).
 
In this post, i will show how you can change items using  M and then bind it to a data grid using LINQ query. I will do it using sample data that shows price menu for Mc burgers.
 
Our first step is to define a constant that holds the M value format.
 
   1: const string MGraphCode = @"Burgers
   2: {   
   3:    { Code=""DCB001"",Name=""Double Cheese Burger"",Quantity=1,Price=5},
   4:    { Code=""Mc001"",Name=""Mc Chicken"",Quantity=1,Price=4}
   5: }"; 

Next, you need to load the grammar using the QueryContext :

   1: var mcContext = QueryContext.Instance.Load(MGraphCode);

And, finally need to bind it to a data grid,

   1: gridView1.DataSource = mcContext;  
   2: gridView1.DataBind();

Now, this for when you are just getting your data and binding it to the grid without any type of filters, to use filter let’s construct a class around the items, let’s call it McBurger, actually  internally it infers to the class that we have defined rather building a anonymous type.

   1: public class McBurger 
   2: {  
   3:   public string Code {get;set;}
   4:   public string Name { get; set; }   
   5:   public int Quantity { get; set; }  
   6:   public float Price { get;set;}
   7: }

Accordingly, you can use LINQ statement to do it like

   1: var mcContext= QueryContext.Instance.Load<McBurger>(MGraphCode);   
   2:  
   3: var query = from mcBurger in mcContext
   4:             where mcBurger.Code == "Mc001"
   5:             select mcBurger;
   6:  
   7: // rest of the databinding code remains the same.
   8:  

So, we took the context and queried for specific menu and data grid binding remains the same which brings an output like

image

Actually, Steve and I are pretty excited about this, the possibility of doing things with M is almost endless. Steve has made a more detail post on this and you can find it right at LINQ to M is available.  You can also download the library as well as the sample from Telerik labs and it points to here.

Finally, you can download the example that i have shown from  here.  You will be needing Oslo May CTP to run this sample.

Hope that helps

Shout it

In the last post i said about LinqtExtender implementing necessary property and injecting specific settings for entity objects. The issue i have is that it works fine under full / high trust settings but when running in medium trust it gives the following error:

image

Ouch.. it is only happening while i am using the extender from medium trust environment. As to add a little prologue, actually it creates a proxy around your original entity and if you look closely it is giving the error in .ctor(). Now lets dig in.

   1: ILGenerator ilGenerator = constructorBuilder.GetILGenerator();
   2:  
   3: ConstructorInfo baseConstructor = typeof(object).GetConstructors()[0];
   4:  
   5: ilGenerator.Emit(OpCodes.Ldarg_0);
   6: ilGenerator.Emit(OpCodes.Call, baseConstructor);
   7: ilGenerator.Emit(OpCodes.Ret);

The IL code is pretty simple actually , its the method body of the proxy class constructor that calls default constructor of the base class. Now, this will work fine in full/high trust as here i require the entity class to have a default constructor. But, as i switch the mode to medium trust it will throw me the above exception. The reason why, in medium trust the framework verifies the IL generated and though it may seem from my point of view that its a valid IL as it is expecting default constructor , to framework’s context its invalid as the base object might never have any default constructor (it should throw error in high trust). In that case the call is absolutely suspicious duh…

So the valid block for this scenario would be:

   1: ILGenerator ilGenerator = constructorBuilder.GetILGenerator();
   2:  
   3: ConstructorInfo baseConstructor = null;
   4: ConstructorInfo[] constructorInfos = parent.GetConstructors();
   5:  
   6: bool containsDefaultConstructor = false;
   7:  
   8: foreach (ConstructorInfo info in constructorInfos)
   9: {
  10:     if (info.GetParameters().Length == 0)
  11:     {
  12:         baseConstructor = info;
  13:         containsDefaultConstructor = true;
  14:         break;
  15:     }
  16: }
  17:  
  18: if (!containsDefaultConstructor)
  19:     throw new Exception(Properties.Messages.MustHaveADefaultConstructor);
  20:  
  21: ilGenerator.Emit(OpCodes.Ldarg_0);
  22: ilGenerator.Emit(OpCodes.Call, baseConstructor);
  23: ilGenerator.Emit(OpCodes.Ret);

The code is similar , just it checks for a default constructor , if not throws a valid exception and to medium trust everything looks fine.  I have added a patch for extender with this as well, do check it out.

Finally, while you are doing Reflection.Emit do check this and more like, you should not emit any unmanaged code and even not play around with private stuffs , etc to avoid pitfalls.

Hope that helps

Shout it
Posted Sunday, June 07, 2009 4:14 PM by mehfuzh | with no comments
Filed under: ,

While developing LinqExtender, i have come across various scenarios that people don’t want to extent any query class or even implement any interface. Also, it is almost absurd when they have to add new extender specific attributes to their entity class. It is though not very important for people creating new provider with small codebase but with large codebase it soon becomes a pain to modify each class.

The solution is to make Extender as a container , which is people will write their logic to act on their specific entity or list of entities, also define their settings via fluent interface. To wrap it around , there is a basic ORM that comes with the extender pack and i have a made LibraryContext on top of SqlQueryContext<T>. Inside, the constructor i wrote the following code to define the extender specific settings.

 

   1: Extender
   2:     .Settings
   3:         .For<Base>()
   4:         .Begin
   5:             .Property(x => x.Id).MarkAsUnique
   6:         .End
   7:         .For<Book>()
   8:         .MapToEntity("book")
   9:         .Begin
  10:             .Property(x => x.Id).MapToAttribute("Bk_Id")
  11:             .Property(x => x.ShelveId).MapToAttribute("Shelve_Id")
  12:             .Property(x => x.Title).MapToAttribute("Bk_Title")
  13:             .Property(x => x.BookInfo).MarkToIgnore()
  14:         .End
  15:         .For<Library>()
  16:         .MapToEntity("Bk_Library")
  17:     .InstantiateIn(this);    

Note that there is a base settings that will be applied to all the common properties under my project and is a local class inherited from LinqExtender.Configruation.All. During the instantiation it will be applied to the current container instance.

Now, as i have said extender should be used a container so that there should be no strings attached. In my entity class, i can implement IQueryObject to mark it as a query class, but if not then extender should be smarter enough to implement it internally when the entity is used in LINQ query via extender query class. Actually , under the hood it dynamically creates a proxy via Reflection.Emit that has the settings and ensures IQueryObject. I will in days time come out with a open source project where i have practiced all these reflection stuffs and which i will extensively blog about , so stay tuned.

To make it more clear i have re-implemented the LINQ to Twitter post using the new extender. So few things like implementing IQueryObject and defining unique identifier is no longer required. You can get the new copy at the end of the post. Also, before i forget, there is a tiny catch which is you can’t left the extender auto generate settings, if you are using it in medium-trust as Reflection.Emit does not work in such environment. In that case you will have to implement IQueryObject by hand and add the attributes manually to make it work so i am leaving LinqToTwitter post untouched [See bottom]. I know most of the good hosting providers these days support high trust and soon i think medium trust will become classic with dynamic proxy generation and cross domain request is becoming growing common (Just my two cents, don't want to get in war with these ;)).

In previous release you can access the Fluent implementation of Bucket just by Bucket.Instance, as it seems that i have somewhere statically stored the bucket object and the syntax bit more sexy but considering multiple threads , there is a possibility of data corruption. Therefore Bucket instance is passed to Query<T> overrides as IBucket and new syntax for Bucket.Instance follows

   1: FluentBucket fluentBucket = FluentBucket.As(bucket);
   2: // do your work.

Down to acknowledgement , Microsoft Germany has published two new tutorials around LinqExtender using LinqToFlickr and LinqToTwitter that also led me fix the VB method call issue and thanks Lars and Tim. In German way i would say, “Danke[Dang – ko]”. You can find the recordings in the following URLs

http://www.microsoft.com/germany/msdn/solve/codeclips/library.aspx?id=msdn_de_33389

http://www.microsoft.com/germany/msdn/solve/codeclips/library.aspx?id=msdn_de_33369

Finally, while we are preparing our new Sitefinity release and making some LINQ extensions, bob’s comments were helpful shaping the release as well and nonetheless all community reviews and feedbacks are great. Try the new release here.

Linq To Twitter Source : LinqToTwitter.zip

Enjoy !!!

June 7, 2009 => Correction ,Reflecton.Emit does not work in medium trust for unmanaged IL codes and  possible IL that might destabilize the runtime that it finds by verifying the assembly, will show more on it in upcoming post. Added a patch of extender, this will work in medium trust with auto implementaion and fluent configuration.

Shout it

In a post few month back , i showed how can i simulate a callback using JQuery and ASP.NET with my experimental FlickrXplorer project. More detail on this can be found at the following URL

http://weblogs.asp.net/mehfuzh/archive/2008/10/13/using-jquery-to-do-ajax-form-posts-in-asp-net-mvc.aspx

Now, what i have done here is basically, i did an AJAX call to the controller and rendered the view result in a div.  One thing about this way is that i am able to make the view strongly typed as i first rendered view using standard way with all the strongly type ViewData.Model. It is nice for rendering views with small amount of html in it (Like , tag lists), but slow for big outputs. The best practice for all these is to use the JSONResult. Here, i will show a small example of how i render the comment list in FlickrXplorer using JSON result and JQuery $.get in conjunction to make the AJAX request.

First, let’s see how the controller looks like. Assume that there is a controller named CommentController and we have an action named List

[AcceptVerbs(HttpVerbs.Get)]
public ActionResult List(string photoId, int ? index, int? page)
{
    int skip = index == null ? 0 : index.Value*page.Value;
    int take = page == null ? int.MaxValue : page.Value;

    PhotoCommentViewData comments = new PhotoCommentViewData();

    try
    {
        comments = model.GetComments(photoId, skip, take, false);
        return Json(comments);
    }
    catch (Exception ex)
    {
         /// do some exception tracking
    }
}

As it seems, it gets the list of comment from its underlying model and then pass it through JSON result. Optionally, i limited that the action should only be accepting GET calls as it is a list request.

Now, coming back to JavaScript we first need to do a GET request to this action and syntax for doing it in JQuery style:

$.get(url, { index: index, page: page }, function(result) {

   processComments(url, result, index, page, loaderTarget, contentTarget); [strike though is not covered in the post]

 }, "json");

The first argument is the comment list URL, this is constructed in server side using Url.Action and then passed in the JS that also ensures the routing setup, second is the JSON string for params, third is the callback for the result it fetches and final is the type of response it should contain.

Inside processComments , i basically do some DOM operations to build the necessary html block

$("#layout")
    .append($("<tr/>")
        .css({'vertical-align' : 'top'})
        .append($("<td/>")
        .attr("class", "said")
        .append($("<strong/>")
        .append($("<a/>")
                .attr("href", "/Photo/NsId/" + comment.Author)
                .css({ 'color': '#0063DC', 'text-decoration': 'none'})
                .append(comment.AuthorName))
            .append("&nbsp;says: "))
        .append($("<br/>"))
        .append(comment.Text)));

So, there is a “layout” panel in the comment container where i am to add the dynamic html. jQuery has this nice way of adding html in a chain and elements under it. For example i want to render a html link with some custom CSS and i want to point that to some URL as well.

Using jQuery , i would do

$("<a/>")
 .attr("href", "/Photo/NsId/" + comment.Author)
 .css({ 'color': '#0063DC', 'text-decoration': 'none' })
 .append(comment.AuthorName)

This will render a html tag something like

<a href=”/photo/NsId/x@y” style=”color:#0063DC, text-decoration:none”>Mehfuz </a>

The rule is that you start a element with $(…) in XHTML style then add necessary attributes, styles and text and it will automatically give you a well-formed html,  moreover you can nest it as you like with other elements.

The above block finally produces a look similar to

image

There are few other JS that  is responsible for generating the pager control which is not covered in this post, for this and more you can take a look at the latest bits of FlickrXplorer under www.codeplex.com/flickrXplorer .That’s so far and if you have some cool ideas to share on this,  let me know.

Hope that helps.

Shout it

In this post, i will show how you can generate SQL programmatically from M. Now, so far i have learnt that MGrammer is a contract that converts user’s input into MGraph. Now, Oslo by default comes with MSchema. Through MSchema you can define a type and extend it with MGraph to populate your repository. Here, i will use MSchema to define an entity object , then MGraph and finally run this through a custom SQL generator in C# to get my DDL statement similar to what you can generate by using intellipad that comes with Oslo SDK.

Let’s define a Contacts M

module Contacts {
    type Person {
        Id : Integer32;
        Name: Text;
        Age: Integer32;
    } where identity Id;
    
    People : Person*
    {    
        {Id = 1, Name="Steve",Age=36}, 
        {Id = 2, Name="Kazi",Age=30}
    };
    Employee : Person*
    {    
        {Id = 1, Name="Nike",Age=29} 
    };
}

So, “Person” is a type with ID,Name and Age respectively that is under “Contacts” module with two different MGraph which are “People” and “Employee” that will generate separate create table statements of “Person” type.

Internally , M is  represented somewhat like

image

Parsing the M all starts with Microsoft.M.Parser.SourceParser. In my sample M to SQL project, i used it like

SqlGenerator generator = SqlGenerator.Load(new StringReader(code));
string sql = generator.Generate();

Inside Load…

SourceParser parser = new SourceParser();
syntaxTerm = (CompilationUnit)parser.ParseTerm(reader, "buffer.m");
...
...

/// check if the parse was successful
if (!parser.LastParseSuccessful)
{
    /// do some error processing for invalid schema.
}

Now, once we have a valid grammar, our next step is to get the modules from ISytaxTerm implementation, for each module we have to process the MGraph for the specified type.

foreach (IModuleDeclaration declaration in syntaxTerm.Modules)
{
    builder.AppendSetExtactAbort();
    builder.AppendGo();

    builder.AppendBeginTransaction();
    builder.AppendGo();

    builder.AppendSetANSINulls();
    builder.AppendGo();

    builder.AppendCreateSchema(declaration.Name.Value);
    builder.AppendGo();
    builder.Append(ProcessMembers(declaration.Name.Value, declaration.Members));

    builder.AppendCommitTransaction();
    builder.AppendGo();
}

This shows the basic skeleton of how the output will look like. ProcessMembers is the actual place that generates the entity from type and associates Insert statements. Only, during the MGraph initialization type is realized. Therefore, the table name is equal to the extent name not to the type name.

Inside ProcessMembers …

/// There will be three declaration 
/// -TypeDeclaion
///- ExtentDeclaration
///- ExtnetDeclaration
foreach (IDeclaration declaration in declarations)
{
    if (declaration is TypeDeclaration)
    {
        typeDeclaration = (TypeDeclaration) declaration;
    }
 
    if (declaration is ExtentDeclaration)
    {
       /// use the type declaration from previous step.
        builder.Append(ProcessExtent(name, typeDeclaration, (ExtentDeclaration) declaration));
    }
}

TypeDeclaration is narrowed down to ParameteriedExpression , which has different operations for the declaring type, which is tracked by  DeclartionReference.Name (“$Operator$Where”, “$Operator$Identity” , etc). Therefore, to process constraint and data types separately, we need to switch them for operation type.  Now, the question is how the MGraph is referred from the type specified. The JSON like string  is basically translated to GraphExpression. Like for the “Person” type , we have three properties. GraphExpression.Successors.Count will be equal to numeric value 3 and each of those which are GraphExpression themselves will have only one successor which is a M.Literal. This will actually contain the property name, type and value for parent type ref.

GraphExpression graphExpression = (GraphExpression) extentDeclaration.InitialValue;

if (extentDeclaration.InitialValue != null)
{
foreach (GraphExpression successor in graphExpression.Successors)
{
    int index = 0;

    foreach (var expression in successor.Successors)
    {
        if (expression is GraphExpression)
        {
            GraphExpression node = (GraphExpression) expression;

            Literal literal = (Literal) (node).Successors[0];
           /// process fragment
        }

        index++;
    }
   /// process the final statement
}

That’s all to get started. All the code has been taken from a MSqlProvider that i created while learning M. The technology is itself in bleeding edge so things will change and i will share my updated knowledge forward. You can further enhance MSQLProvider to run the result in configured database along with the mx.exe that comes with Oslo SDK.

You can download the source here to play around and see it live.

Enjoy!!

kick it on DotNetKicks.com

Just released LinqExtender 2.0. Over previous release , it contains generally bugs fixes. Overall, I have focused on striping out complexity as much as possible to keep you focused on your business logic. You can see the full list of features in the documentation that comes with it.

Now, while creating the LinqToTwitter example, I have shown that creating custom providers with LinqExtender requires two steps, first you have to define a query object by implementing IQueryObject and then you have made a Query<T> successor and override few methods. In LinqExtender, object/ entity equivalent is Bucket. Starting from 2.0, there is a Fluent interface implementation of it that works as an internal DSL and gives you a single entry point for all query and update , inserts and delete, thus making things more declarative and one way.

In this post, I will show you how to generate SQL statement from LINQ query with nested where clause, using the fluent interface implementation. To start, let's consider the following query

var query = from book in bookContext
where ((book.Author == "Mehfuz" && book.ISBN == "2") || book.Id == books[2].Id) || 
(book.Author == "Paolo Pialorsi" && (book.ISBN == "100-11-777" || book.ISBN == "1"))
select book;

It's taken from the Entrypoint.cs test class that comes with LinqExtender project along with OpenLinqToSql sample ORM. Now, to do things in a very basic way. Let's first create a string builder and append the initial select.

StringBuilder builder = new StringBuilder("SELECT * FROM [" + Bucket.Instance.Entity.Name + "]");

To be precise, Bucket.Instance is the entry point for all query and object details. Moving to where statement , LinqExtender uses simplified expression tree that is exposed by Bucket.Instance.ExpressionTree. All we need to setup how the output will look like and the rest will be covered by the toolkit.

builder.Append("WHERE");
builder.Append("\r\n");
Bucket
.Instance
.ExpressionTree
.DescribeContainerAs(builder)
.Root((containter, operatorType) => containter.Append(" " + operatorType + " "))
.Begin(container => container.Append("("))
.EachLeaf((container, item) =>
 {
     string value = GetValue(item.Value);
     container.Append(item.Name + RelationalOperators[item.RelationType] + value);
 })
.End(container => container.Append(")"))
.Execute();

Here, let assume that GetValue(..) will return a formatted SQL string and ReleationalOperators is a dictionary that has mappings for item.RealtionType ( GreaterThan -> ">" , LessThan => "<", etc). Basically, as the implementation shows, we are defining the way output will be stored in the container (In this case, StringBuilder). All these code should be placed in Query<T>.Process(IModify<T> items) method and on execute it will just return the following SQL block

Select * from book 
 WHERE
(((Author='Mehfuz' AND ISBN='2') OR Bk_Id='1734') 
OR (Author='Paolo Pialorsi' AND (ISBN='100-11-777' OR ISBN='1'))) 

Extender basically knows how to get though this nested where clause. From basic computer science, it builds linked objects based on a Syntax Tree, with each parenthesis adding diversion to the tree like shown below

 image

So far, this is a very rudimentary example. With 2.0 it is also possible to build your own reusable format provider for building literals that saves repetitive code blocks for same kind of task (updating a database). This is actually just a schema builder that defines how the output will look like using the same Bucket.Instance calls. Out of the box, TSqlFormatProvider is provided.Depending under which Query<T> method it is used; it will generate insert, update, delete or select statement where all you have to call Bucket.Instance.Translate(...).

string sql = Bucket.Instance.Translate(new TSqlFormatProvider());

This enables you to build not only your own LINQ to Anything format providers but also share it with the community to reuse what is already out there. More information on how to get started can be found at the project documentation.

In a word, Bucket.Instance is all you need to go through and build your own LINQ provider. Optionally, you can override the following methods (under Query<T>) to give your provider various OTS (Object tracking service) support .

1. AddItem () - called during SubmitChanges() call for new object.
2. RemoveItem () - called during SubmitChanges() call for Delete.
3. UpdateItem () – called during SubmitChanges() call for update.

I have updated Creating LinqToTwitter using LinqExtender post with the latest release. You can get a copy of the latest 2.0 release from www.codeplex.com/linqextender,  and of course as usual all your feedbacks are really helping to shape the toolkit.

Hope that helps,

Update on 28th Feb 2009, with new patch for Bucket.Instance.ExpressionTree

kick it on DotNetKicks.com

In my last post, I showed how to turn on Amazon S3 support in Sitefinity. In this post, I will show how to create a simple video site using the video library support that is bundled with 3.6 release. It is often required that you want to add a streaming video content to your site, either it could be a product demonstration or a getting started tutorial. Using third party video provider is one way to get the job done but sometimes it requires a lot of manual work, thus headache for managing them as the library grows bigger. 3.6 release breaks you free from all these and provides an easy way for creating , uploading and managing video content.

Now, uploading video content and publishing them requires a few easy steps. You can either decide to store / stream it from your hosting server or from Amazon S3, typically which can be divided into following.

    1. Configure the data provider
    2. Create a video library
    3. Upload videos
    4. Create a page and add the video content control onto it.
    5. Publish it.

Sitefinity uses RadMediaPlayer (comes as part of Telerik Rad controls suit), a cool Silverlight media player made on top of the basic MediaPlayer with out of the box features that can get you on the groove right away. As I mentioned already, Sitefinity is a combination of content, modules and pages. Modules can have their own data providers, own handlers, whereas each page can control its content presentation by using the revolutionary control designer.

image

Coming back, to start creating our simple video site first we need to create a module (which is a video library). We can either choose to use the default data provider "Libraries" or we can define our own custom provider. To define one by ourselves we must ensure the following

  • Create an entry under <cmsEngine> that looks like "<add name=Libraries..."  or like the one described in Amazon S3 post.
  • Add related meta fields under <metaFields> that are same as the default ones with only prefix = name, you have given to the data provider
    <add key="Libraries.Description" valueType="ShortText" visible="True" searchable="True" sortable="True" defaultValue="" />

    This converters to the following where name = "MyLib". Similar goes for the rest.

    <add key="MyLib.Description" valueType="ShortText" visible="True" searchable="True" sortable="True" defaultValue="" />
  • Map it with "Libraries" module under libraries.genericContentproviders
     <libraries defaultGenericProvider="Libraries">
          <genericContentProviders>
            <add providerName="MyLib" publicationDateField="Publication_Date" />
      .........
      .........
  • Under cmsEngine.providers.add (where name="MyLib/Libraries") there is a key called applicatinName, which is set to "/Libraries" but we can set it to "/MyOwnApplciation" to ensure that it does not mess data up with the default one.

For multiple data providers you will see a dropdown in the library create wizard, to upload under the specific one, we just need to select and start uploading.

 MultipleLIbrary

So, once we have created a video library it will automatically take us to the upload view and once it is done, we can see the preview right away. Next,  we just need to drag and drop the video control onto the page. To further customize it, we can play around with designer that is tied with it (click on the "edit" link) we can set things like the max width for the thumbnail or video player and tweak labels and meta datas as we go.

VideoEdit 

We have already seen how to set up multiple data providers and select specific libraries from designer. Moreover, we can set custom provider from advance mode of the content control. This applies to all Sitefinity content controls like Events, Blogs, etc that implements the same generic content base class.

advanced

Finally, if all are set, we will see a video page like the one shown just below. While we are uploading video, each will have a thumbnail generated from the video itself that will be shown in the list view. Each items in list view is tied with a detail view (similar to video sites), where you can play the video, leave comments and bookmark it in your favorite social networking site.

Video 

We have already seen in my previous post that we can set the urlRewriteFormat in the data provider declaration. For local libraries , when urlRewriteFormat="~/{LibraryName}/[Name].sflb.ashx" the video detail permalink will be http://<hostname>/<applicationPath>/<pagename>/MyLib/ButterFly.aspx, that means the video content control (detail view) will have the same mirror URL terminating with "*.aspx". So, if you change the URL format in library data provider it will reflect in the content control as well.

So far, that's all for the simple video site. Let us know, how you like to shape it for you and what features you really want to add in it. You can grab a free community edition  and of course any feedback will really make us feel better.

Hope that helps

kick it on DotNetKicks.com

Here at Telerik, Sitefinity team is preparing for the 3.6 release next week. 3.6 comes with lot of core level enhancements and cool new features. Of which , I can't but mention one feature that will make most ISV vendors who want the power of CMS but want to let go their pain of managing large content. As, the title suggests its external storage support via Amazon S3. The data plan for hosting and transferring data to/from S3 server is pretty cheap these days in return to world class service with almost zero downtime that it offers which of course makes the most of your money. If you are not familiar with Sitefinity to add it is a product by Telerik  that comes with full content management features along with blogs, news, events, list and few other pre-made modules with easy setup and management via unique control designer.

In this post, I will show how to turn on S3 support in Sitefinity 3.6 that comes out of the box.In Sitefinity, files are kept in Library. Every file which can be audio, video, document or anything else is stored as Library entries, which are consumed by modules for example images in blog post. These library entries are dependant on data providers which can be extended from internal to cloud. S3 support is just a plugin to that extensibility.

Now, to configure S3 support let's start with a simple example. I want to create a personal blog and I want all the images and attachments go to Amazon S3 server. To do so , we need to ensure the following

  1. Turn on the S3 data provider in web.config (that comes with the installation)
  2. Add your S3 API and secret key to the specific place holder.
  3. Create your blog module
  4. Drag and drop your module over a page.
  5. Publish it
  6. Use Admin or Live writer to do your post with Images and attachments.

Steps 3- 6 are pretty basic and are beyond the scope of this post. I will deeply encourage you to grab a community version from the project's download page(link provided at the end) and see the step by step documentation that comes right with it.

To start setting up, first we need to navigate to the cmsEngine node. If amazon block is there then un-comment it and remove the default "Libraries" data provider or less add the following data provider.

<add name="Libraries" urlRewriteFormat="~/{LibraryName}/[Name].s3lb" 
    thumbnailExtension=".tmb"
    urlDateTimeFormat="yy-MM-dd" urlWhitespaceChar="_" visible="False" 
    defaultMetaField="Name" applicationName="/Libraries" allowVersioning="True" 
    allowLocalization="False"
    localizationProviderName="" allowWorkflow="False" 
    securityProviderName="" versioningProviderName=""
    connectionStringName="GenericContentConnection" 
    type="Telerik.Libraries.Data.AmazonProvider, Telerik.Libraries.Data"
    tagEditorTemplate="~/Sitefinity/Admin/ControlTemplates/Libraries/BatchTagsEditor.ascx"/>

Now, inside the data provider you can do plenty of tweaks like, modify the URL format , turn on/off localization, have multiple providers of same type (with different name) and map it from admin, etc. The most important thing for libraries or any other module is the urlRewriteFormat. You can set up any format and the detail (permalink) url will generate accordingly. Here, [Name] = name of the file but you can change it to any meta fields that the module supports or add any constants you want.

The amazon data provider is different in two ways from local one

  1. It has different content extension(.s3lb).
  2. Separate data provider dedicated to communicate with S3. Default type = Telerik.Libraries.Data.DefaultProvider

As, we are pretty much done with the first step. Next, we have to put the right API and secret access key that we have purchased from Amazon. All the transfers will be made against the key associated to a user's account. Under the telerik node we have a section called storageSetting which looks like

<storageSetting defaultProvider="Amazon">
      <providers>
        <add name="Amazon"           
          type="Telerik.Libraries.AmazonStorage.AmazonStorageProvider, Telerik.Libraries" 
          downloadUrlPrefix="http://s3.amazonaws.com" 
          accessKey="YOUR ACCESS KEY"
          secretAccessKey="YOUR SECRECT KEY"
          bucketName="Sitefinity" />
      </providers>
</storageSetting>

Just Fill in the gaps and you are through. In Sitefinity module is the heart of every content and a page can contain 1..N modules but each module can have its own specific settings like data provider, URL format, etc. As we have finished setting up the data provider and associated configuration to talk with S3 server. we can now play the way we like. We can create gallery with image library or setup  a download list for providing documents and pdfs. Even we can setup a video site(which I will cover in later post) easily. But for now , let's create a blog, write a post, add some images and text and publish it.

SiteFinity Admin page edit 

The above is the snap of edit mode of the blog page along with the post that I have done using Live Writer. Now, to be more sure (we haven't done any wrong) if you monitor using firebug Net tab your list will look like the pasted

Fiirbug stat 

Down in the bottom there are two request for images posted by Live Writer which are directly forwarded to S3 server (302->200). Thus, the whole load goes to Amazon and gives you peaceful night sleep.

This is basically shortly all for now, I will cover more things from Sitefinity like creating video site , working with Sitefinity designers to configure your site without touching any of the html code and more that is interesting in my future posts.

Till then, you can get a free copy from http://www.sitefinity.com/product/community-edition.aspx (you need to create an account if you haven't. You can use it for other Telerik products and to log any issues as well.

Hope that helps

kick it on DotNetKicks.com
More Posts Next page »