Archives for December, 2011

29
Dec

PowerShell script to tabify text (i.e. in code files)

Few weeks ago I needed to tabify (change spaces to tabs) in a C# files in a solution. I tested some plug-ins to Visual Studio, but none of them did what I wanted. I left the idea, as it was not that important to have consistent tabs/spaces. But a day or two ago I had some time and yen for to create simple PowerShell script to fix that for me. It simply replaces x spaces taken from input parameter with tab(s). Text goes to stdin and result to stdout.

param([int]$spaces)

$pattern = '';
for ($i = 0; $i -lt $spaces; $i++) {
	$pattern = $pattern + ' ';
}
$pattern = '^((' + $pattern + ')*)' + $pattern;
$replace = '$1' + "`t";

$input | foreach {
	$text = $_;
	do {
		$prev = $text;
		$text = $text -replace $pattern, $replace;
	} while ($prev -ne $text)
	Write-Output $text;
}

The script, as you can see, is not interpreting the code in any way, hence some spaces i.e. in comments at the beginning might become tabs even if that’s actually wrong. But hey, you can take Roslyn and plug it in, as an exercise. :)

To, for instance, tabify all .cs files in some path, you can call this script (saved as tabify.ps1) using something like:

Get-ChildItem -Recurse ".\src" | Where-Object {$_.Extension -eq ".cs"} | foreach { Get-Content $_.FullName | .\tabify.ps1 -Spaces 2 | Set-Content -Encoding UTF8 ($_.FullName + ".tabs") }
24
Dec

Composing functions the LINQ way

Few days ago I was writing a class, that was simply wrapped for a collection of other classes (with same interface), aggregate class. The class also had few methods, where the logic was simple. Let’s say one method M. Other classes having same method as well. This method was simple transformation of data with same output as input. The aggregate class was simply calling M method of first, second, … of other classes.

I started with something like this:

function T M<T>(T data)
{
	T tmp = data;
	foreach (var c in classes)
	{
		tmp = c.M(tmp);
	}
	return tmp;
}

But then I had some weird wave in my brain and started thinking. I could create collection of functions, like IEnumerable<Func<T, T>> and call methods from this collection. Wait a minute… I can create from this collection of function one aggregate function and call just this one. Crazy? ;) Probably. But it’s a nice way to keep my brain running.

It turned out, it’s pretty easy with LINQ:

public static Func<T, T> Compose<T>(this IEnumerable<Func<T, T>> source)
{
	return source.Aggregate((agg, fn) => (d => fn(agg(d))));
}

I don’t think it’s any more (less) useful than the foreach with direct method calls, but it’s more succinct, more functional and more fun. 8-)

21
Dec

log4net (back) alive on NuGet

It turned out, that the previous maintainer of log4net NuGet package @dotnetjunky was assigned mistakenly. So nobody was actually maintaining that package. After few messages with him, we decided, I’ll take over the ownership and maintain it.

I still use NLog in my projects, as I like it a little bit more. But I know, there’s big community around log4net, with my coworker Ales included. :)

Today I uploaded package with new version 1.2.11 [1], and I’ll try my best to keep the package up-to-date. Enjoy.

[1] I used the binaries signed with new key so any new dependencies will follow this recommended usage.

20
Dec

Mapping self references in Code First

From time to time I see people having problems to map self references in Code First in Entity Framework. It might be confusing what to do with HasMany/WithMany and HasOptional/WithOptional.

So let’s jump in. Define a pretty simple table:

create table SelfRefs (
  ID int primary key,
  FooBar varchar(20) not null,
  ID_Parent int
);

alter table SelfRefs add foreign key (ID_Parent) references SelfRefs(ID);

The corresponding class could be:

class SelfRef
{
	public int ID { get; set; }
	public string FooBar { get; set; }
	public SelfRef ParentItem { get; set; }
	public int? ParentItemID { get; set; }
	public ICollection<SelfRef> ChildItems { get; set; }
}

Now the mapping. The “trick” here is to realize, that we have not only child->parent association, but also parent->children. The other one is implied from the first one. Hence every child item has optional parent. If the child item has no parent, it is actually a 1st level child, aka child of (invisible) “root” (NULL parent). That also means you can map it from both directions and result will be the same. Here’s the example (it’s explicit a little more) with both mappings (you can use both declarations together without any problem):

class SelfRefConfiguration : EntityTypeConfiguration<SelfRef>
{
	public SelfRefConfiguration()
	{
		this.HasKey(x => x.ID);
		this.Property(x => x.ParentItemID).HasColumnName("ID_Parent");
		// starting from child with parent
		//this.HasOptional(x => x.ParentItem).WithMany(x => x.ChildItems).HasForeignKey(x => x.ParentItemID).WillCascadeOnDelete(false);
		// starting from parent with children
		this.HasMany(x => x.ChildItems).WithOptional(x => x.ParentItem).HasForeignKey(x => x.ParentItemID).WillCascadeOnDelete(false);

		this.Map(map =>
			{
				map.Properties(x => new { x.ID, x.FooBar, x.ParentItemID });
				map.ToTable("SelfRefs", "dbo");
			});
	}
}

Hope I made it a little bit more clear. If not, feel free to ask in comments.

19
Dec

Improved command logging in ADO.NET provider for Firebird – part 2

Previous version of ADO.NET provider for Firebird brought us a support for command tracing. Although it was good, it could be done better. Few interesting scenarios came back to as a valuable feedback and with the old implementation it was hard to do it.

The new one builds on top of TraceSource class allowing you to handle different sources from trace messages easily and independently. The what’s logged is same, but now every message is traced through FirebirdSql.Data.FirebirdClient source, hence you can easily i.e. turn it of (and just these messages, without affecting other messages) or send it to i.e. console window. Just a few lines in app.config and you’re done.

<system.diagnostics>
	<sources>
		<source name="FirebirdSql.Data.FirebirdClient">
			<listeners>
				<clear />
				<add name="console" type="System.Diagnostics.ConsoleTraceListener"/>
			</listeners>
		</source>
	</sources>
</system.diagnostics>

The code above sends all messages (commands) from provider to (only) console window. You can use your own listener, of course or turn it off completely, using just the <clear />.

19
Dec

ADO.NET provider for Firebird 2.7 released

I’m happy to bring you early Christmas gift packed as ADO.NET provider for Firebird version 2.7. This version brings important bug fixes (tracker.firebirdsql.org) and logging improvements.

This release wouldn’t be possible without support of people/companies using provider actively. Big thanks to them.

You can download it at www.firebirdsql.org or use NuGet package.

Enjoy!

11
Dec

Custom logic in every Entity Framework’s query

Few days ago there was a question on Twitter in #efhelp about adding custom logic to every query in Entity Framework. It’s pretty easy and you can do it absolutely transparently so nobody using your code needs to know.

First you need to focus you Entity Set (not Entity Type) in Model Browser window.

Here set the access modifier to i.e. private or (internal/protected) and rename it to something else, so it’ll not interfere with original name of property we’re going to create. I often use X prefix (especially for properties on entities).

Now it’s pretty easy to create some logic. Here I simply added filtering to always only fetch entities younger than 10 days from now.

partial class Model1Container
{
	public IQueryable<FooBarEntity> FooBarEntitySet
	{
		get
		{
			DateTime d = DateTime.UtcNow.AddDays(-10);
			return XFooBarEntitySet.Where(fb => fb.Created > d);
		}
	}
}

And that’s it. Not a difficult task. But also note that through Entity SQL (or i.e. reflection) somebody might be still able to access original entity set and get access to the data. So it’s not rock hard security solution.

9
Dec

Sorting using blob column on Firebird

Imagine you have a blob column and you want to add sorting clause to your query based on that column. Crazy? Might be. On the other hand, why not?

Firebird allows you to use blob column for sorting. No problem. But the behavior might surprise you. I’m not going to deeply describe how the blobs are stored in Firebird database. Simply speaking, it’s stored in separate data pages and inside row only blob id is stored. If you use blob column for sorting, Firebird isn’t fetching the complete blob (though looks straightforward, it would be very slow), but rather uses blob id for sorting. You probably see the problem already – the blob id has nothing to do with content. Hence the sorting will be very likely broken.

But there’s a solution. I’m assuming that you want to mainly sort on text blobs (though you can use it on binary blobs too). Simply cast the blob to i.e. varchar(20) (choose length that fits your needs) and sort using this. Yes, it’s going to be slow, but if you need to do it often, you can precompute this column (using trigger etc.).