<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ivan Krivyakov&#039;s Blog</title>
	<atom:link href="http://www.ikriv.com/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.ikriv.com/blog</link>
	<description>Premature optimization is the root of all evil</description>
	<lastBuildDate>Mon, 13 May 2013 03:42:00 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.1</generator>
		<item>
		<title>NuGet: How to Install a Package in 19 Easy Steps</title>
		<link>http://www.ikriv.com/blog/?p=1288</link>
		<comments>http://www.ikriv.com/blog/?p=1288#comments</comments>
		<pubDate>Mon, 13 May 2013 03:36:48 +0000</pubDate>
		<dc:creator>Ivan</dc:creator>
				<category><![CDATA[.NET]]></category>

		<guid isPermaLink="false">http://www.ikriv.com/blog/?p=1288</guid>
		<description><![CDATA[If they tell you the machines will outsmart us very soon, don&#8217;t believe it. Here&#8217;s why. Tonight I was trying to add &#8220;Unity&#8221; dependency injection framework to my .NET 4 project under Visual Studio 2010 via NuGet. Yes, I know, stone axes are no longer supported, but whatever. Here are the list of steps, just [...]]]></description>
			<content:encoded><![CDATA[<p>If they tell you the machines will outsmart us very soon, don&#8217;t believe it. Here&#8217;s why.</p>
<p>Tonight I was trying to add &#8220;Unity&#8221; dependency injection framework to my .NET 4 project under Visual Studio 2010 via NuGet. Yes, I know, <a href="http://www.ikriv.com/blog/?p=158">stone axes are no longer supported</a>, but whatever.</p>
<p>Here are the list of steps, just for my record, and perhaps for someone&#8217;s sadistic geeky amusement, if they are into that kind of stuff. So,</p>
<p>1. Opened Tools->Library Package Manager->Manage NuGet Packages for Solution. Typed &#8220;Unity&#8221; in the search box. It came out first.</p>
<p>2. Clicked on &#8220;Install&#8221;. Was told that this version of Unity requires .NET 4.5 which none of my projects supports (duh!). </p>
<p>3. Searched for a button or menu to list older versions &#8211; did not find any.</p>
<p>4. Googled how to install older version with NuGet &#8211; did not find any encouraging results. But found NuGet PowerShell reference instead.</p>
<p>5. Did <code>Get-Package -ListAvailable -Filter Unity</code> in Powershell. Got 40 results, in alphabetical order, none of them is Unity. Tried <code>-First</code> and <code>-Skip</code> options: no can do, a subset of the same 40 results.</p>
<p>6. Googled it. Found something about a bug in NuGet that is fixed in the new version. </p>
<p>7. Went to update NuGet to version 2.5 via Visual Studio Extension Manager. Installation failed, complaining something about the signature of my current NuGet not matching what they expect. Well, it did not complain per se, it just stated the failure, and gave the link to an installation log. The message with the actual root cause was in the middle of a very long line towards the end of file, around column 200, so some serious horizontal scrolling was required.</p>
<p>8. Went to uninstall current NuGet in the Extension Manager. Install button is disabled.</p>
<p>9. Googled it. Re-ran Visual Studio as administrator. Uninstalled current Nu-Get.</p>
<p>10. Installed NuGet 2.5. First small victory!</p>
<p>11. Did <code>Get-Package -ListAvailable -Filter Unity</code>  in Powershell. It returned over a hundred packages, Unity came 96th. But this displays only the latest version, and I wanted the previous one.</p>
<p>12. Tried to find the way to limit the search, so it would return just <code>Unity</code>. No cigar. According to the documentation <code>-Filter</code> searches in &#8220;package Id, the description and tags&#8221;. Trying to specify &#8220;The Unity Application Block&#8221; as a filter does not do any good: even more packages are returned. But <code>-Skip 96 - First 1</code> gives me only Unity. OK so far.</p>
<p>13. Trying <code>Get-Package -ListAvailable -Filter Unity -AllVersions -Skip 96 -First 1</code>. It waits a while (10 seconds or so), and then gives me <code>Cavity.ServiceLocation.Unit... 1.1.0.787</code>. Well, apparently it skips lines, not packages. Argh.</p>
<p>14. Googled it. No cigar. Found a reference to another command line, the <code>nuget.exe</code> tool.</p>
<p>15. Downloaded <code>nuget.exe</code>. It refused to run, requesting that I set some environment variable. Well, I did. It ran.</p>
<p>16. Did <code>nuget list unity</code>. Get a hundred packages again.</p>
<p>17. Did <code>nuget list Unity -allversions</code> and redirected output to a file. It took several minutes to create the file, and it came out with 1525 lines of text.</p>
<p>18. Found that the previous version of Unity is (ta-da) 2.1.505.2. It&#8217;s right there, in front of your eyes, proudly sitting on line 1353.</p>
<p>19. Back to Powershell, <code>Install-Package Unity -Version 2.1.505.2</code>.</p>
<p>Victory at last!</p>
<p>Some points to raise with the NuGet team(s):</p>
<p>- a search by Package Id only would be nice; an exact search by Id would be even nicer</p>
<p>- why is it that when I search for Unity in Gallery it comes up first, and not 96th? do they have a different API? if yes, why isn&#8217;t it available via Powershell or command line?</p>
<p>- installing previous version of a package should not require a degree in forensic science; having a menu listing all versions would save me 1.5 hours of work and lots of nerve cells</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ikriv.com/blog/?feed=rss2&#038;p=1288</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Random Notes on MDX Filtering</title>
		<link>http://www.ikriv.com/blog/?p=1277</link>
		<comments>http://www.ikriv.com/blog/?p=1277#comments</comments>
		<pubDate>Thu, 09 May 2013 15:26:50 +0000</pubDate>
		<dc:creator>Ivan</dc:creator>
				<category><![CDATA[.NET]]></category>

		<guid isPermaLink="false">http://www.ikriv.com/blog/?p=1277</guid>
		<description><![CDATA[1. Filter() and IIF work funny in the columns hierarchy. Consider this: SELECT FILTER([MarketValue], [MarketValue] >1000) ON COLUMNS, [Region].[Region].[Region] ON ROWS FROM [MyCube] In this case the MarketValue in red actually means the global number for MarketValue, not the per region one. I.e., if the global MarketValue is 1024, then all regions will be returned. [...]]]></description>
			<content:encoded><![CDATA[<p><b>1. Filter() and IIF work funny in the columns hierarchy.</b><br />
Consider this:</p>
<p><code>SELECT<br />
FILTER([MarketValue], <font color="red"><b>[MarketValue]</b></font> >1000) ON COLUMNS,<br />
[Region].[Region].[Region] ON ROWS<br />
FROM [MyCube]</code></p>
<p>In this case the <font color="red"><b><code>MarketValue</code></b></font> in red actually means the <b>global</b> number for MarketValue, not the per region one. I.e., if the global <code>MarketValue</code> is 1024, then <i>all</i> regions will be returned. If global market value is 999, none of the regions will be returned. <code>IIF</code> works in a similar way, and so does <code>IsEmpty</code>. Thus,</p>
<p><code>SELECT NON EMPTY [MarketValue]</code></p>
<p>will return regions where market value is not empty, whereas</p>
<p><code>SELECT FILTER([MarketValue], NOT IsEmpty([MarketValue]))</code></p>
<p>will return market value for all regions, empty or not, provided that the global market value is not empty. </p>
<p>To avoid this shenanigans one should filter on ROWS. E.g.</p>
<p><code>SELECT<br />
[MarketValue] ON COLUMNS,<br />
FILTER( [Region].[Region].[Region], [MarketValue] > 1000) ON ROWS<br />
FROM [MyCube]</code></p>
<p><b>2. Performance of FILTER on even medium sized sets is not so good.</b><br />
Even when the filter is trivial, something like 1=1, the query still takes several times longer than without the filter. If you filter on multiple fields, it makes situation even worse.</p>
<p>If you rewrite the query above like this</p>
<p><code>WTIH MEMBER [BigMarketValue] AS IIF([MarketValue]>1000, [MarketValue], NULL)<br />
SELECT NON EMPTY [BigMarketValue] ON COLUMNS,<br />
[Region].[Region].[Region] ON ROWS<br />
FROM [MyCube]</code></p>
<p>you might get much better performance.<a style="display:none" href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=1181663" rel="tag">CodeProject</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ikriv.com/blog/?feed=rss2&#038;p=1277</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SSRS Production Deployment, Part 3</title>
		<link>http://www.ikriv.com/blog/?p=1261</link>
		<comments>http://www.ikriv.com/blog/?p=1261#comments</comments>
		<pubDate>Fri, 03 May 2013 18:52:27 +0000</pubDate>
		<dc:creator>Ivan</dc:creator>
				<category><![CDATA[.NET]]></category>

		<guid isPermaLink="false">http://www.ikriv.com/blog/?p=1261</guid>
		<description><![CDATA[Deploying Reports Download code. In Part 2 we talked about deploying SSRS data sources. Now we are ready reports. Reports are deployed using rs.CreateReport() method. It accepts array of bytes instead of .rdl file name. This is relatively minor, since reading contents of a file is not that hard. Here&#8217;s the code: Dim len As [...]]]></description>
			<content:encoded><![CDATA[<p><b>Deploying Reports</b></p>
<p><a href="http://www.ikriv.com/dev/misc/ssrs/Deploy.vb">Download code</a>.</p>
<p>In <a href="http://www.ikriv.com/blog/?p=1248">Part 2</a> we talked about deploying SSRS data sources. Now we are ready reports. </p>
<p>Reports are deployed using <a href="http://msdn.microsoft.com/en-us/library/reportservice2005.reportingservice2005.createreport.aspx">rs.CreateReport()</a> method. It accepts array of bytes instead of <code>.rdl</code> file name. This is relatively minor, since reading contents of a file is not that hard. Here&#8217;s the code:</p>
<p><code>
<pre>Dim len As Integer
Dim fileBytes As Byte()
Using stream As FileStream = File.OpenRead(path)
    len = stream.Length
    fileBytes = New [Byte](len - 1) {}
    stream.Read(fileBytes, 0, len)
End Using

rs.CreateReport("MyReport", "Reports Folder", overwrite, fileBytes, Nothing)</pre>
<p></code></p>
<p>It would be even easier if Microsoft did not mess up the VB example at the above link: they don&#8217;t read the last byte of the stream and the result is invalid XML. Interestingly, in the <a href="http://msdn.microsoft.com/en-us/library/aa225813%28v=sql.80%29.aspx">SQL 2000 example</a> they messed up the array initialization instead, so they send an extra byte to the SSRS server instead. The result is the server complaining about illegal 0&#215;00 character in the end of the report.</p>
<p>It seems difficult to comprehend, even for Microsoft people, that in VB.NET the number of elements in your array is different from the number you specify in <code>Dim</code>.</p>
<p><b>Updating Data Source References</b></p>
<p>Another hurdle is that report definitions, as stored by BIDS, contain invalid data source references. When you upload a report like outlined above, you will get a warning similar to this:</p>
<p><code>The dataset `DataSet1' refers to the shared data source `MyDataSource', which is not published on the report server.</code></p>
<p>HTTP traffic sniffing shows that when BIDS deploys a report, it gets the same warning. The solution is to update the data source references after the report has been uploaded, changing them to existing data sources in the <code>"/Data Sources"</code> folder.</p>
<p>This requires several steps. First, we need to load the report file as XML and locate all data source references. </p>
<p><code>
<pre>Dim doc As System.Xml.XmlDocument = New System.Xml.XmlDocument()
doc.Load(rdlPath)

Dim nsManager As XmlNamespaceManager = New XmlNamespaceManager(doc.NameTable)
nsManager.AddNamespace("r", "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")
Dim nodes As XmlNodeList = doc.SelectNodes("/r:Report/r:DataSources/r:DataSource/r:DataSourceReference", nsManager)</pre>
<p></code></p>
<p>Then we need to convert those nodes to <code>DataSource</code> objects recognized by SSRS:</p>
<p><code>
<pre>Dim dataSources As DataSource() = New DataSource(nodes.Count - 1) {}

For i As Integer = 0 To nodes.Count - 1
    dataSources(i) = CreateDataSourceObj(nodes.Item(i))
Next

Private Function CreateDataSourceObj(ByVal refNode As XmlNode) As DataSource

    Dim reference As DataSourceReference = New DataSourceReference
    reference.Reference = "/Data Sources/" + refNode.InnerText

    Dim result As DataSource = New DataSource
    result.Name = CType(refNode.ParentNode, XmlElement).GetAttribute("Name")
    result.Item = reference

    Return result
End Function</pre>
<p></code></p>
<p>And finally, we need to call <a href="http://msdn.microsoft.com/en-us/library/reportservice2005.reportingservice2005.setitemdatasources.aspx">rs.SetItemDataSources</a> method:</p>
<p><code>rs.SetItemDataSources(serverReportPath, dataSources)</code></p>
<p>Complete code for creating a report is <a href="http://www.ikriv.com/dev/misc/ssrs/DeployReport.vb">here</a>.<br />
Combined file for creating a data source and a report is <a href="http://www.ikriv.com/dev/misc/ssrs/Deploy.vb">here</a>.</p>
<p>It was fun, isn&#8217;t it? I am not sure why Microsoft did not make it simpler: SSRS reports are typically needed in an enterprise environment, and production deployment is an important part of development for the enterprise. It would also help if the code sample for <code>CreateReport</code>  were right: I spent quite some time trying to figure out why I am getting weird exceptions from SSRS before I noticed the size error. </p>
<p>I hope this text will save others hours of boilerplate coding and frustration. <a style="display:none" href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=1181663" rel="tag">CodeProject</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ikriv.com/blog/?feed=rss2&#038;p=1261</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SSRS Production Deployment, Part 2</title>
		<link>http://www.ikriv.com/blog/?p=1248</link>
		<comments>http://www.ikriv.com/blog/?p=1248#comments</comments>
		<pubDate>Fri, 03 May 2013 16:02:12 +0000</pubDate>
		<dc:creator>Ivan</dc:creator>
				<category><![CDATA[.NET]]></category>

		<guid isPermaLink="false">http://www.ikriv.com/blog/?p=1248</guid>
		<description><![CDATA[In Part 1 we discussed that in development environemnt we deploy reports by simply clicking &#8220;Deploy&#8221; in BIDS, but this won&#8217;t work in production. To deploy reports in production we need to write an SSRS script, which is actually a piece of VB.NET code executing against SSRS web service. A typical report consists of the [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://www.ikriv.com/blog/?p=1237">Part 1</a> we discussed that in development environemnt we deploy reports by simply clicking &#8220;Deploy&#8221; in BIDS, but this won&#8217;t work in production. To deploy reports in production we need to write an SSRS script, which is actually a piece of VB.NET code executing against <a href="http://msdn.microsoft.com/en-us/library/ms155071.aspx">SSRS web service</a>.</p>
<p>A typical report consists of the report definition (the <code>.rdl</code> file) that references one or more <i>data sources</i>. And this is where things get tricky.</p>
<p><b>Deploying Data Sources</b></p>
<p><a href="http://www.ikriv.com/dev/misc/ssrs/DeployRds.vb">Code to deploy a data source</a>.<br />
<a href="http://www.ikriv.com/dev/misc/ssrs/Deploy.vb">Code to deploy data source and report</a>.</p>
<p>You create a data source using a call to <a href="http://msdn.microsoft.com/en-us/library/reportservice2010.reportingservice2010.createdatasource.aspx">rs.CreateDataSource()</a> method. Unfortunately, this method does not accept <code>.rds</code> files that BIDS uses to store data source information. Instead it wants a <a href="http://msdn.microsoft.com/en-us/library/reportservice2010.datasourcedefinition.aspx">DataSourceDefinition</a> object. This means that one must parse the <code>.rds</code> file and convert it to a <code>DataSourceDefinition</code> instance. Here&#8217;s a piece of code that does that. It is geared for datasources with integrated credentials, if you use other kind of credentials, you&#8217;ll need to make relevant modifications. </p>
<p><code>
<pre>Dim doc As System.Xml.XmlDocument = New System.Xml.XmlDocument
doc.Load(rdsPath)

Dim dataSource As DataSourceDefinition = New DataSourceDefinition
dataSource.ConnectString = doc.SelectSingleNode("/RptDataSource/ConnectionProperties/ConnectString/text()").Value
dataSource.Extension = doc.SelectSingleNode("/RptDataSource/ConnectionProperties/Extension/text()").Value
dataSource.CredentialRetrieval = CredentialRetrievalEnum.Integrated
dataSource.Enabled = True
dataSource.EnabledSpecified = True

Dim name As String
name = doc.SelectSingleNode("/RptDataSource/Name/text()").Value

Dim overwrite As Boolean = false

rs.CreateDataSource(name, "/Data Sources", overwrite, dataSource, Nothing)</pre>
<p></code></p>
<p>This was easy, wasn&#8217;t it? Full version of the code with logging and error handling can be found <a href="http://www.ikriv.com/dev/misc/ssrs/DeployRds.vb">here</a>.</p>
<p>But data sources are only one half of the story. In <a href="http://www.ikriv.com/blog/?p=1261">Part 3</a> we will discuss how to deploy reports.</p>
<p><a style="display:none" href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=1181663" rel="tag">CodeProject</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ikriv.com/blog/?feed=rss2&#038;p=1248</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>SSRS Production Deployment, Part 1</title>
		<link>http://www.ikriv.com/blog/?p=1237</link>
		<comments>http://www.ikriv.com/blog/?p=1237#comments</comments>
		<pubDate>Thu, 02 May 2013 15:33:33 +0000</pubDate>
		<dc:creator>Ivan</dc:creator>
				<category><![CDATA[.NET]]></category>

		<guid isPermaLink="false">http://www.ikriv.com/blog/?p=1237</guid>
		<description><![CDATA[So, you built your shiny and flashy SSRS report, and you hit &#8220;Deploy&#8221; in BIDS, or &#8220;SQL Server Data Tools&#8221; in newer versions. Your UAT is a breeze, and everything looks great. The million dollar question now becomes How do you deploy your reports to production? Download code. In most &#8220;enterprise&#8221; environments &#8220;production&#8221; means &#8220;no [...]]]></description>
			<content:encoded><![CDATA[<p>So, you built your shiny and flashy SSRS report, and you hit &#8220;Deploy&#8221; in BIDS, or &#8220;SQL Server Data Tools&#8221; in newer versions. Your UAT is a breeze, and everything looks great. The million dollar question now becomes</p>
<p><b>How do you deploy your reports to production?</b></p>
<p><a href="http://www.ikriv.com/dev/misc/ssrs/Deploy.vb">Download code</a>.</p>
<p>In most &#8220;enterprise&#8221; environments &#8220;production&#8221; means &#8220;no direct access for developers&#8221;. Any changes to production must be carefully documented and performed by dedicated people: release managers, system administrators, DBAs, etc. These dedicated people typically do not have BIDS on their desktops, nor do they want to. Thus, simply telling them to open the project, right click and hit &#8220;Deploy&#8221; won&#8217;t work. Whatever BIDS does when you hit &#8220;Deploy&#8221;, you&#8217;ll need to duplicate it in some way that works without BIDS. This is easier said than done, because, as it turns out, &#8220;Deploy&#8221; does quite a few things under the covers.</p>
<p><b>Scripting SSRS</b></p>
<p>But first off, how do you script SSRS in the first place? It comes with the <b>rs.exe</b> utility which on my machine is located at <code>"C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\rs.exe"</code> (your location may vary), and is described <a href="http://msdn.microsoft.com/en-us/library/ms162839.aspx">on this MSDN page</a>.</p>
<p>The &#8220;script&#8221; file that rs.exe accepts is regular VB.NET code that can call methods on a global <b>rs</b> object, which is actually a proxy to <a href="http://msdn.microsoft.com/en-us/library/ms155071.aspx">SSRS web service</a>. You can put any valid VB.NET statements in your script, including reading files, opening sockets, and the like.</p>
<p>WSDL definition for the SSRS web service is located at<br />
<code>http://reportServerName/ReportServer/ReportService2005.asmx?wsdl</code> for 2005 version of the protocol, or at<br />
<code>http://reportServerName/ReportServer/ReportService2010.asmx?wsdl</code> for 2010 version.</p>
<p>In fact, all rs.exe does is:</p>
<ul>
<li>Download WSDL from reporting server</li>
<li>Create a proxy class (perhaps using svcutil)</li>
<li>Read your script</li>
<li>Surround it with some extra code that defines the <b>rs</b> variable</li>
<li>Compile and run</li>
</ul>
<p>These steps are executed on every invocation of a script, and may take quite some time. Another limitation is that you must use VB.NET, C# is not supported. Also, you can&#8217;t have any <code>Imports</code> directives in your code, because it gets surrounded by the code generated by rs, and <code>Imports</code> in the middle of a class are not allowed. So, if you use classes like <code>System.Xml.XmlDocument</code>, they must be fully qualified.</p>
<p>If any of the above is an issue, you may want to bypass <code>rs.exe</code> and generate the proxy on your own. Simply create a console application and add a web reference to <code>ReportServiceXXXX.asmx?wsdl</code>. Your &#8220;script&#8221; will now be an executable file. The downside is that you lose dynamic compilation: quickly modifying the script &#8220;on the fly&#8221; is no longer an option.</p>
<p>But what exactly do you put in the script? This is going to be the topic of <a href="http://www.ikriv.com/blog/?p=1248">Part 2</a>.<a style="display:none" href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=1181663" rel="tag">CodeProject</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ikriv.com/blog/?feed=rss2&#038;p=1237</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Downloading Oracle Driver for .NET&#8230;</title>
		<link>http://www.ikriv.com/blog/?p=1232</link>
		<comments>http://www.ikriv.com/blog/?p=1232#comments</comments>
		<pubDate>Fri, 19 Apr 2013 18:42:28 +0000</pubDate>
		<dc:creator>Ivan</dc:creator>
				<category><![CDATA[.NET]]></category>

		<guid isPermaLink="false">http://www.ikriv.com/blog/?p=1232</guid>
		<description><![CDATA[feels like I am trying to download a semi-legal DVD-copying software. It starts simple enough: just go to this page. Shows a list of things to download, it does not get easier than that. But when you click on the first link, it - shows you another list - then says you must accept the [...]]]></description>
			<content:encoded><![CDATA[<p>feels like I am trying to download a semi-legal DVD-copying software. </p>
<p>It starts simple enough: just go to <a href="http://www.oracle.com/technetwork/database/windows/downloads/index-101290.html">this page</a>. Shows a list of things to download, it does not get easier than that. But when you click on the first link, it<br />
- shows you another list<br />
- then says you must accept the license agreement<br />
- then says you must create an account<br />
- this gives you a 3rd degree questionnaire with e-mail, company, your title, etc.<br />
- then sends you an e-mail with a link you must click to verify your account<br />
- the verification link (naturally) brings you to Oracle&#8217;s login page<br />
- login page brings you to start page<br />
- go back to downloads<br />
- click link<br />
- see another list, accept license agreement<br />
- click on link, get something else (what gives?)<br />
- click &#8220;back&#8221;, accept license agreement, click link</p>
<p>F-f-f-f-ew&#8230; You finally got it, dude!<br />
Ivan, a proud janitor from Screaming Toys, inc.,  42 Avenida de Las Juegas, Thimphu, Bhutan</p>
<p>P.S. Oracle actually knows the telephone code for Bhutan and won&#8217;t let you enter anything else for the phone number. How thoughtful of them.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ikriv.com/blog/?feed=rss2&#038;p=1232</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scripting on Windows</title>
		<link>http://www.ikriv.com/blog/?p=1228</link>
		<comments>http://www.ikriv.com/blog/?p=1228#comments</comments>
		<pubDate>Fri, 19 Apr 2013 17:36:34 +0000</pubDate>
		<dc:creator>Ivan</dc:creator>
				<category><![CDATA[.NET]]></category>

		<guid isPermaLink="false">http://www.ikriv.com/blog/?p=1228</guid>
		<description><![CDATA[I needed to create a script of medium complexity that goes along these lines: 1. Take a list of databases. 2. Each database has an SVN folder, list of files to execute (with possible wildcards), and list of files to skip. 3. For each database, perform &#8220;get&#8221; on the SVN folder, ignore the excluded files [...]]]></description>
			<content:encoded><![CDATA[<p>I needed to create a script of medium complexity that goes along these lines:</p>
<p>1. Take a list of databases.<br />
2. Each database has an SVN folder, list of files to execute (with possible wildcards), and list of files to skip.<br />
3. For each database, perform &#8220;get&#8221; on the SVN folder, ignore the excluded files and run files from the &#8220;execute&#8221; list in the order specified, respecting the wildcards.</p>
<p>What do they use to write such scripts these days? My first attempt was in</p>
<p><b><a href="http://en.wikipedia.org/wiki/NAnt">NAnt</a></b>. We already use NAnt for continuous integration and it seems to work reasonably well with files and external programs. The problem I had with NAnt is that it lacks adequate control structures and data types. All properties are strings, and I needed structured data. The only type of <code>for</code> loop is iteration over a delimited string (or files in a directory). There are no parameterized function calls, although they can be simulated (poorly) with setting global properties and calling a target. </p>
<p>Then I briefly thought about writing it in<br />
<b>C#</b>, but rejected the idea, since I wanted the script to be easily modifiable, and the compilation step gets in the way of that. Also, in compiled languages like C# script parameters are traditionally passed either via command line or via config file that must be parsed. My parameters were too big for the command line, and writing a parser was not in my plans. It is possible to do dynamic compilation in C#, but it is quite cumbersome. You don&#8217;t want your config file to start with something like <code>using System; class Config { ConfigItem[] Data = ... </code>, do you?</p>
<p>My next thought was<br />
<b>Powershell</b>, but this one is shipped only with the newest version of Windows Server, and we are not there yet. On older versions it requires installation with admin rights. It may be easier to get an audience with the Pope of Rome than to install an app with admin rights on a production box in a huge financial corporation.</p>
<p>I then settled on<br />
<b>Javascript</b> (WSH), and it worked, but I was plagued by various issues. First off, WSH does not seem to have a built-in way to execute an external command that sends output to current console window and wait for the result. You get either asynchronous execution without wait in current window (<code>Exec</code>), or optionally synchronous execution in external window (<code>Run</code>). I ended up writing a piece of code that uses <code>Exec</code> and then polls the process for the exit status.</p>
<p>Also, WSH version of JavaScript lacks support for include files. My script became big enough that I wanted it, primarily to separate config from code. One can use an <code>eval</code> call to read and execute external file, or use <a href="http://en.wikipedia.org/wiki/Windows_Script_File">WSF</a> files, but both of these options greatly mess up line numbers and make detecting errors virtually impossible.</p>
<pre><code>var fileSystem = new ActiveXObject("Scripting.FileSystemObject");

function include(fileName)
{
    eval(fileSystem.OpenTextFile(fileName, 1).ReadAll());
}
</code></pre>
<p>There are, of course, other alternatives: maybe I will try Python next time. But the situation with a scripting solution available on all currently active version of Windows is bleak. Powershell would be a reasonably good answer if not for Microsoft&#8217;s love of admin-rights installers. Requiring an admin right installer is a huge demotivator in the corporate world.<br />
<a style="display:none" href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=1181663" rel="tag">CodeProject</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ikriv.com/blog/?feed=rss2&#038;p=1228</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>BI Studio: cannot customize auto generated MDX query</title>
		<link>http://www.ikriv.com/blog/?p=1224</link>
		<comments>http://www.ikriv.com/blog/?p=1224#comments</comments>
		<pubDate>Wed, 20 Mar 2013 15:00:57 +0000</pubDate>
		<dc:creator>Ivan</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.ikriv.com/blog/?p=1224</guid>
		<description><![CDATA[Long story short: if you are building an SSRS report in Microsoft BI studio, and if that report has parameters, you cannot customize the automatically generated MDX query. If you switch to text mode, make a change (any change, e.g. adding a space) and hit &#8220;save&#8221;, you get this error: An MDX expression was expected. [...]]]></description>
			<content:encoded><![CDATA[<p>Long story short: if you are building an SSRS report in Microsoft BI studio, and if that report has parameters, you cannot customize the automatically generated MDX query. </p>
<p>If you switch to text mode, make a change (any change, e.g. adding a space) and hit &#8220;save&#8221;, you get this error:</p>
<p><b>An MDX expression was expected. An empty expression was specified.</b></p>
<p>The culprit is this subquery added by the Query Designer:<br />
<code>SELECT ... FROM<br />
( SELECT ( STRTOSET(@parameter, CONSTRAINED) ) ON COLUMNS FROM [data source]) WHERE ...</code></p>
<p>The problem is explained in more detail <a href="http://social.msdn.microsoft.com/Forums/en-US/sqlanalysisservices/thread/c30bf64b-c7e3-4bfc-a955-779afa4bd8bc">in this thread</a> on MSDN forum.</p>
<p>The responder there claims that this is not automatically generated code, but in fact it is. Apparently, someone fiddled with the MDX query generator at the last moment. If you remove the subquery and replace it with just <code>[data source]</code>, customization works like a charm.</p>
<p>Admittedly, we are using an outdated version of the BI studio (2008), but still, this is not cool. And the error message is not that helpful either.<a style="display:none" href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=1181663" rel="tag">CodeProject</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ikriv.com/blog/?feed=rss2&#038;p=1224</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Silverlight Image control does not support GIFs</title>
		<link>http://www.ikriv.com/blog/?p=1217</link>
		<comments>http://www.ikriv.com/blog/?p=1217#comments</comments>
		<pubDate>Sun, 03 Feb 2013 04:36:47 +0000</pubDate>
		<dc:creator>Ivan</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Computers]]></category>

		<guid isPermaLink="false">http://www.ikriv.com/blog/?p=1217</guid>
		<description><![CDATA[Surprise-surprise! WPF: The Image class enables you to load the following image types: .bmp, .gif, .ico, .jpg, .png, .wdp, and .tiff. Silverlight: [Image class] Represents a control that displays an image in the JPEG or PNG file formats. No error is displayed, it just shows a blank rectangle. I understand that GIF format was once [...]]]></description>
			<content:encoded><![CDATA[<p>Surprise-surprise!</p>
<p><a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.image.aspx">WPF</a>: <i>The Image class enables you to load the following image types: .bmp, .gif, .ico, .jpg, .png, .wdp, and .tiff.</i></p>
<p><a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.image%28v=vs.95%29.aspx">Silverlight</a>: <i>[Image class] Represents a control that displays an image in the JPEG or PNG file formats.</i></p>
<p>No error is displayed, it just shows a blank rectangle. I understand that GIF format was once controversial due to patent issues, but the patent has long expired, and most web browsers support GIFs natively. Also, the decompression algorithm is dead simple (I implemented it in college as an exercise), so it is somewhat surprising that Microsoft won&#8217;t include GIF support in a web-oriented library like Silverlight, but will include it in a desktop package like WPF. Anyway, this ship has sailed: both are yesterday&#8217;s news now, and Microsoft is currently busy with WinRT <img src='http://www.ikriv.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> <a style="display:none" href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=1181663" rel="tag">CodeProject</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ikriv.com/blog/?feed=rss2&#038;p=1217</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Touches</title>
		<link>http://www.ikriv.com/blog/?p=1210</link>
		<comments>http://www.ikriv.com/blog/?p=1210#comments</comments>
		<pubDate>Fri, 01 Feb 2013 01:17:22 +0000</pubDate>
		<dc:creator>Ivan</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Programming Languages]]></category>

		<guid isPermaLink="false">http://www.ikriv.com/blog/?p=1210</guid>
		<description><![CDATA[I wrote a little web page that &#8220;debugs&#8221; HTML 5 touch interface (requires touch screen device). Unlike regular mouse clicks, there is no &#8220;onTouch&#8221; attribute, you have to add and remove listeners via addEventListener() method of a DOM element. Event name is passed as string, which is not very safe, but hey, it&#8217;s JavaScript, folks! [...]]]></description>
			<content:encoded><![CDATA[<p>I wrote <a href="http://dev.ikriv.com/m/touches.html">a little web page</a> that &#8220;debugs&#8221; HTML 5 touch interface (requires touch screen device). Unlike regular mouse clicks, there is no &#8220;onTouch&#8221; attribute, you have to add and remove listeners via <code>addEventListener()</code> method of a DOM element. Event name is passed as string, which is not very safe, but hey, it&#8217;s JavaScript, folks! Nothing is save there.</p>
<p>Another quirk is that unlike <code>MouseUp</code> notification in various graphic systems, <code>touchend</code> event does not give you coordinates. In some way this makes sense, because the mouse has only one on-screen cursor, and touch interface must support multiple touches. By the time of <code>touchend</code> the number of current touches is zero, which is reflected in the event.</p>
<p>Unfortunately, this means that even if you are only interested in the start and end point of a touch, you still must monitor the <code>touchmove</code> event. </p>
<p>I tested the app on three different phones and here are the results:</p>
<p><b>Motorola Droid Razr Maxx</b> &#8211; can handle virtually any number of touches. The maximum I was able to reach was 12; I am sure the software can handle even more, but we ran out of screen space. Just in case: I ran out of my own fingers at 10 touches and had to use other people&#8217;s help to reach 12 <img src='http://www.ikriv.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><b>IPhone 4S</b> &#8211; bails out after 5 touches (go backs to zero if I remember correctly). Not very cool and kinda sloppy, but enough for the vast majority of practical applications.</p>
<p><b>HTC Droid Incredible</b> &#8211; I could not get it to work with more than one touch, because it ignores &#8220;<code>user-scalable=no</code>&#8221; meta tag. When you touch screen we second finger, the touch event is not passed to the web page, and the page is zoomed instead.</p>
<p>Oh, yeah, and the relevant piece of JavaScript code is below. I did not use JQuery or any similar framework on purpose, to get to the bare bones API.</p>
<pre><code>function reporter(name) {
    return function (e) {
        e.preventDefault();

        var message =
            name + "&lt;br/&gt;" +
            "touches: " + e.touches.length + "&lt;br/&gt;";

        for (var i = 0; i &lt; e.touches.length; ++i) {
            var touch = e.touches[i];
            message += "screenX: " + touch.screenX + "&lt;br/&gt;";
            message += "screenY: " + touch.screenY + "&lt;br/&gt;";
        }

        var info = document.getElementById("info");
        info.innerHTML = message;
    };
}

function report(name) {
    window.addEventListener(name, reporter(name), true);
}

report("touchstart");
report("touchmove");
report("touchend");</code></pre>
<p><a style="display:none" href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=1181663" rel="tag">CodeProject</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ikriv.com/blog/?feed=rss2&#038;p=1210</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
