A while back I posted about selecting and implementing a source control system for Project Greenfield. I outlined how I came to the decision to use Mercurial (Hg) and so far I have been very pleased with my decision.
One of the key factors in my decision was Bitbucket, an online repository service that I am using as a central source control server. The original free service came with a single private repository, not exactly ideal for an ISV, so I purchased an account that gave me a handful of private repositories and more storage space. At a few dollars a month the price was more than reasonable.
The most important change is this: small accounts like mine are now free.
Bitbucket’s pricing scheme was based on the number of private repositories and storage space, but under Atlassian the pricing is all about users. An entry level account is for 5 users and includes unlimited public and private repositories with unlimited storage space.
According to the website, a user is defined as “Someone with read or write access to one of your private repositories.” This means that most small development shops won’t have to pay anything. I think that is just awesome.
What if I’m not so small?
Another great bit (pun intended) of news is that the price for pay accounts is very small. A 10 user account is only $10/month, 25 users is $20/month, 50 users is $40/month, and for $80/month you can have unlimited users. Again, this includes unlimited private repositories and unlimited storage space. In my mind those prices are great regardless of your team size. They also have an introductory offer: if you sign up for a 10user account before Oct. 3rd your first year will be free.
How does this affect Open Source projects?
Since users are only counted for private repositories, you can have unlimited users on public repositories. This means you should be able to manage any open source project on the standard free 5 users account.
What about Github?
This change got me thinking about Github. When I was selecting a DVCS I almost chose Git because of Github even though everything else had me leaning towards Mercurial. In my research it seemed people were more fanatical about Github than Git itself and I really wanted hosted repositories. In the end it was finding Bitbucket that finalized my choice.
The only reason I even bring this up is I wonder if this will be a game changer for Github. When I signed up, Bitbucket and Github prices were practically identical. Will people researching DVCS begin choosing Hg over Git because Bitbucket is now free? Github pricing is still based on the number of private repositories, will it change its pricing model?
Github already has unlimited free public repositories and “collaborators”, so I don’t see this affecting the open source crowd. And I certainly don’t think people will be switching from Git to Hg because of this: it’s the new adopters I’m curious about. It just seems to me that Github will have to do something to respond to this: I’ll be curious to see how it plays out.
Tweeted by @Pete_Brown recently:
Attention WPF (and SL4) Devs: Get back to blogging. You’re getting lost in the amazing amount of #wp7dev content :)
Well, when Pete says “Jump!”… I’ve actually been meaning to post this for a few months, so thanks to Pete for giving me a push :-)
A friend of mine is learning Silverlight and in prototyping a simple app he wanted to just use a TextBlock for his header. When the application has a fixed size, it works fine, but when the size is flexible he ran into one of the issues with TextBlock: it doesn’t resize or scale. When you set the properties for a TextBlock, you set the size of the font and it never changes.
Here is the default layout we are discussing:
And here it is expanded to full screen on a large resolution:
The text stays centered, but the size stays static. It makes the header seem small and out of proportion. And similarly when the window is much smaller the text seems too large and out of proportion. If you get extreme you can even see some weird results:
One way to solve this would be to listen to the UserControl’s SizeChanged event and do some math to calculate the new FontSize, but that just feels so WinForm. I’d much rather find a way to do this without code behind.
You could try to bind the FontSize of the TextBlock to a property in the ViewModel, but you still have to find a way to trigger the action. If you bound the UserControl width and height to the ViewModel you could have its Set method raise the PropertyChanged event for the FontSize property. And of course, you’d still have to write all the code to calculate it, which I’m sure would include measuring the text, calculating buffer zones and margins, etc.
These are just ideas, I haven’t tried either approach. You may find a situation where you need to do one of these things or come up with something different, but honestly, these ideas just somehow feel wrong in a XAML world. In this particular case, where the Text is static, I have a better solution.
Convert Text To A Path
The solution starts with taking advantage of the vector graphic nature of XAML. While Text may not expand and contract as desired, a Path certainly will, so the first step is to convert the Text to a Path.
In Blend, select the TextBlock item and right click, select Path –> Convert to Path (or go to Object –> Path –> Convert to Path). This will convert the text into a Path object (outlined in Red in the screen shot below). You’ll also notice the Horizontal and Vertical alignments have both been changed to Stretch and the Margins have been set (outlined in Yellow).
If you reset the Margins to 0, you will see the Text take up the entire space. If you change both the alignments to Center it will look OK in Blend, but when you execute the application you’ll see we actually get the same behavior as the Stretch. This is because of Width and Height are set to Auto, which is what we want: if we set these to fixed sizes we are right back where we started.
The good news is that if you resize the window now, either bigger or smaller, you’ll see the header resize itself, so we must be on the right track!
Margins and Proportions
At least in this case, we don’t want the text bumping up against the edges of its Border: it’s distracting and not very clean. Instead, we’d like a little space surrounding it on all sides.
You might be thinking “No big deal, I’ll just add a Margin” and you wouldn’t be totally wrong. The problem is that hard coding the Margin, like hard coding the Text’s FontSize, means it can never change. So a Margin that looks good when the window is small doesn’t necessarily look good when the window is large.
What we want is the effect of a Margin, but we want that Margin to be proportional to the available space. We really can’t solve this with the Margin property, at least not without a lot of work and calculation, which I’m just too lazy to figure out. So the real solution is not Margins, or even in the Text (now Path) itself: the real solution is in Layout.
Solving the Problem Using Layout
One of the things I see developers new to XAML struggling with is the power of layout. I’ve started labeling my approach “Container Driven Design” which really relies on the containers to manage the size and spacing of it’s child elements. It frequently involves nested containers, which is what we are going to use to solve this problem.
What we really want is for our Margins to float and resize in proportion to their parent container. Fortunately we have a container type built in that is perfect for this: the Grid. With a Grid, we can specify percentage based sized rows and columns. (NOTE: Yes, I know they are not *really* percentage based, but an explanation of the Star system is beyond the scope of this article.)
So to solve this problem using layout we are going to wrap our header in a 9-celled Grid: three rows and three columns, with the center cell holding our header. Right click the Path and select Group Into –> Grid. If you look at your Objects and Timelines panel you will see the Path is now the child of a Grid:
With Grid selected, you can use the blue bars along the top and left to position the rows and columns:
While I avoid editing XAML, there are a few times that it is simply faster and easier: editing Grid row and column sizes is one of those times. In the screen shot below, you’ll see that I’ve effectively created floating margins by defining star sizes for the top and bottom rows and right and left columns. The center row and center column have no size definition, so they will take up the remaining available space.
Execute this and you’ll find that as you resize the window the margins will resize themselves proportionally, the text will remain nicely centered and will also resize itself proportionally.
Wrapping it Up
So there are a couple of lessons I would want you to take away from this exercise. First, the problem we were having was with static text, so we solved that by turning that text into something else. We found a graphical solution to our graphical problem!
Second, we had a problem with Margins, so we used grid rows and columns instead of the Margin property. We solved that issue by relying on a Layout Container instead of a single property.
In both cases, we found simple and elegant solutions by thinking outside the box. I’ll grant that this example is not overly complex, but it does illustrate the power of XAML to solve design problems. And of course, a chance to play around in Blend is always welcome!
While Expression Blend remains my favorite tool and Visual Studio my most productive tool (with a little R# love), Sql Server Integration Services (SSIS) has moved solidly into the #3 slot.
I frequently have tasks that require me to move data from one location to another, perform conversions and transformations, create new tables with the resulting columns, etc. In the past, this meant a lot of ADO.NET and a lot of coding. These processes can be exceedingly slow and time consuming to produce and the performance is frequently less than desirable. With what I’ve learned about SSIS, most of that work will be a thing of the past. I can now do conversion work in a fraction of the time it took before and the resulting product, a Package in SSIS lingo, can execute in far less time.
It seems that SSIS is thought of as a DBA’s tool, but I believe that as Blend is not just for Designers, SSIS is not just for DBAs. This post is not going to be a how to or any kind of definitive work: what I want to accomplish is to introduce my fellow developers to the glory of SSIS and highlight some of the reasons I think you should be learning this technology.
Project Greenfield and SSIS
For Project Greenfield, one of the primary tasks is to convert data from the legacy IBM *insert nom du jour here* midrange server database to the new Sql Server database.
This is far more than pushing data from once place to another: the structure is completely different. Relationships are defined now that previously were unenforced and large tables are broken into dozens of smaller, more normalized tables, often in different schemas. Fields that were previously fixed length and Numeric types are now varchars and ints. In some cases single fields have been broken into multiple fields, and in some cases multiple fields have been combined. In all cases, data coming out is Unicode but is being stored as ANSI.
Obviously, this conversion represents a significant body of work in its own right. One of my recent tasks was to provide enough of a conversion that I could start prototyping (fake data just wasn’t what we wanted.) The amount of work I was able to do in a week would have easily taken over a month to write using ADO.NET. And best of all, now that I have a solid framework in place making changes is very easy.
Getting Started with SSIS
In order to start with SSIS, you will have to have it installed. More accurately, you will need the SQL Server Business Intelligence Development Studio installed, also known as BIDS. This is found as an option when installing SQL Server and I’m pretty sure it is not available below SQL Server Standard.
The current version of BIDS runs in Visual Studio 2008. If you already have VS2008 installed you will find a new Project Type category called Business Intelligence Projects added to your existing install. If you do not have VS2008 BIDS will install a Visual Studio 2008 Shell, even if you have VS2010 installed.
To start a new project, select the Business Intelligence Projects category and Integration Services Project in the create new project dialog. Once it is created, opening it and working with it is basically the same as any other solution.
Work Flow in SSIS
BIDS itself is the first application I’ve seen that serves as a compelling example of a Workflow driven application. The Package Designer workspace is organized in tabs, the only two of which I’ve needed so far are Control Flow and Data Flow.
All tasks are defined as compartmentalized units of work. The visual blocks for those are all shown in the Control Flow tab. These tasks may or may not be grouped into containers such as Sequence Container or Foreach Loop Container. You may define as many containers as necessary to organize the Package. So far I have preferred Sequence Containers as they allow me to organize tasks procedurally. Except for the simplest Package, I would not define tasks outside of containers.
There are many different task types available, but I have only needed three so far: Data Flow Task, Execute SQL Task, and Script Task. And now that I have better knowledge of what I am doing, I could get by without the Execute SQL Task.
Data Flow Task
At the heart of SSIS is the Data Flow Task. The basic formula is this: read data from a data source, manipulate/transform that data, then write the transformed data to the target destination. Data sources can be ADO.NET or OLE DB database connections but can also be Excel, Flat, or XML Files. There are even more options for Target Destinations.
In between the source and the target are the Data Flow Transformations which really represent the power of SSIS. Here is a brief list of the transformations I have so far found most useful.
Conditional Split – Evaluates the data in the current columns and creates logical subsets which can then be handled differently. Each subset effectively becomes it’s own data source at that point.
Derived Column – In my mind, the most important transformation of the bunch: derived columns are the new (or replacement) columns built by converting or transforming the source data. SSIS includes a highly evolved “Expression Language” that is used to convert the data at runtime. String manipulation, type conversion, mathematical operations, and much more are all supported.
Lookup – Second in importance only to Derived Column, this transformation allows you to perform lookup actions against other tables. This is essential for preventing invalid foreign key insertion. It also is great for performing Incremental Loads: basically, this means only inserting records into the database if they don’t already exist. This becomes important for several reasons, the least of which not being that I want to be able to execute the Package as often as possible, especially during development.
Multicast – Multicast creates multiple copies of the current data set, so you can perform multiple writes to multiple destinations.
The Script Task
The Script task allows you to write code to do things. Primarily I have used this to work with package variables, a whole topic in its own right, and for making OLE DB connections dynamic. I see substantial potential in the Script Task though as it really opens up the entire .NET Framework to the process.
Obviously, this barely scratches the surface of SSIS. BIDS is primarily a graphic tool, but there are distinct functions that developers could really leverage. The other place where developers could shine in SSIS is in process flow: once I understood things like Sequence Container and Conditional Split I really felt like I could make SSIS sing. This kind of flow is exactly what we code day in and day out, so I think developers can pick up SSIS quickly.
I may write some more about SSIS going forward, but if you are interested and looking for info now I recommend you check out Andy Leonard’s blog.