Tuesday, November 18, 2008

The final Vista Ultimate extra? Windows 7

I am almost certain they won’t but Microsoft should seriously consider how they will make Windows 7 available to the public when it is released next year.  Ever since Vista came out there has been no end to the complaining that there were not enough extras available for Vista Ultimate.  They say it was not worth the cost and I agree.

So here is what Microsoft should do.  Eliminate all versions of Windows 7 but one.  No ultimate edition, or basic edition, or primary basic edition, or grandma’s pro edition.  Just one.  Very simple.  Windows 7.

Then, considering that almost all of the units sold come from new computers, give a free upgrade to Windows 7 to all who purchased Vista Ultimate sort of as a final Vista Ultimate extra.

Finally, sell the Windows 7 upgrade for $99 and the full package for $189 at retail shops.

This is so obvious that a child could figure it out.  Which is why I have no hope that Microsoft will see it.

Tuesday, November 11, 2008

MySQL connector/net 5.2.4 has been released

MySQL Connector/Net 5.2.4, a new version of the all-managed .NET driver for MySQL has been released.  This release is of GA quality and is suitable for  use in production environments.  We strongly urge you to  review the change log that is shipped with the product for a thorough review of the changes.

We have a ton of fixes in this release so please review the changelog and see if your favorite bug has been fixed.  Version 5.2.4 works with all versions of MySQL including MySQL-4.1,  MySQL-5.0, MySQL-5.1, and the MySQL-6.0 beta.

It is now available in source and binary form from [http://dev.mysql.com/downloads/connector/net/5.2.html] and mirror sites (note that not all mirror sites may be up to date at this point of time - if you can't find this version on some mirror, please try again later or choose another download site.)

Changes since 5.2.3

  • fixed web providers autogenerateschema option where it would fail if no schema is   present at all (bug #39072)
  • backported fix for lingering problem related to bug #37239.  If two columns had the same name but different case then an exception would be thrown.
  • fixed stored procedure parameter parsing when used inside server explorer.  (bug #39252)
  • fixed time data type so that negative values are handled properly (bug #39275)
  • added runtime check for the mono platform to our Membership provider.  The mono runtime as of 1.9.1 did not support the methods needed for hashed passwords (bug #38895)
  • fixed problem where negative time values with a zero hour would return as positive values (bug #39294)
  • fixed problem where using a stored procedure with parameters with a table adapter was no longer working after our parameter schema changes (bug #39252)
  • fixed problem with profile provider where INSERT .. ON DUPLICATE UPDATE syntax would not work correctly with some older server versions (bug #39330)
  • Defaulting max allowed packet to 1024 to account for the possible case where the value doesn't come in as a server variable
  • fixed bug #39728 by making MySqlConnectionStringBuilder.GetConnectionString an internal method.   It should not have been publicly available anyway.  It is used internally by the MySqlConnection.ConnectionString property
  • implemented Disposable pattern on MySqlTransaction class so including one in a using statement and then not calling commit will cause a rollback when the using exits (bug #39817)
  • fixed MySqlScript object so that it handles scripts with user variables
  • fixed bug where specifying 'functions return string=yes' would cause strings to be returned using the 'binary' charset which would not properly render some characters.  Now the connection character set is used. (bug #40076)
  • fixed problem that caused in use connection strings to be modified when a pooled connection timed out and was cancelled.  (bug #40091)
  • fixed problem where using respect binary flags would not use the connection char set and therefore return strings with a bad encoding.
  • fixed bug where provider was attempting to use the new parameters I_S view on servers that didn't have it (bug #40382)
  • fixed problem where CharSetMap.GetDefaultCollation and CharSetMap.GetMaxLengths might have a thread sync issue on high load systems.  They were not locking the static collections there were initializing. (bug #40231)
  • added GetSByte to the reader for returning tinyint columns (bug #40571)

Thanks for using MySQL Connector/Net!

Wednesday, November 5, 2008

Using mysql with entity framework webinar

This past Tuesday I was doing more than just voting.  I was giving a live webinar on using MySQL with the Entity Framework.  We had a terrific time (demo machine crash included!) and had a great turnout.  I have been informed that we set records for most number of registrations and attendees.  I’m truly honored and hope that at least some of you got something out of it.

I’ve had a lot of people ask me for the materials from the session so I’ve made them available from my personal server.  You can get the slides, sample projects, and db script here.  The webinar was also recorded and will appear on this page eventually.

Thanks again to all who attended.  I’m hoping to give an expanded version of this session at our users conference in April.  I hope to see some of you there!

Saturday, November 1, 2008

Straight from the WTF category

So last night my family and I go to watch some scary movies that had been recorded and find out that our media center computer is not working.  So like a dutiful geekdad, I march into the office to see what is wrong.  I remote into the media center with no trouble but no matter what I try the 360 just won't connect to it.  Running the network tuner it reports poor network performance, way below the 'Acceptable for TV' line.  Hmm.  So I spend the next hour running wires from various ports around the house, switching ports on the switch in the media cabinet, everything I could think of.  Nothing.

I never really paid much attention to the activation prompt that it was giving me when I remoted into it.  Surely MS would not be that stupid.  Surely.

So this morning I tried to connect to a media center computer I had running in a virtual machine (yeah VirtualBox) and it worked without a hitch.  So I remote back into the non-working media center computer and run through the activation process.  Bingo.  360 now connects perfectly and the network tuning wizard shows the exact same network as maxed out on quality.

Lesson learned?  Instead of just disabling Media center functionality and just telling you that until you activate it won't work, MS apparently just cripples it so that it doesn't work but doesn't tell you what is wrong.  Absolutely ridiculous.


Wednesday, October 29, 2008

it’s on now!

Microsoft has been taking some pretty good body blows from Apple over the past couple of years.  These have primarily been in the form of the PC/Mac ads and are not entirely undeserved.  Vista is a pretty good product but pretty good is clearly not good enough.  Well, Microsoft just landed a right hook to the jaw of OS/X.  It’s on now!

It’s really quite incredible how much work Microsoft has done on Windows during the lifetime of Apple OS/X.  OS/X 10.0 was released in 2001, the same year Windows XP was released.  For the most part OS/X has not changed since then.  Sure, you have new features like Time Machine but the user experience has really not changed much and neither have most of the features.  The same is not true for Windows.  In that same timeframe Microsoft has put out major service packs for XP, created a new server product named Windows Server 2003, and then created the Vista line of products (Vista, Windows Server 2008, etc).  Vista was supposed to be a moon shot but instead Microsoft got so caught up in completely rebuilding the rocket that it never really got off the pad.  With the shiny new Vista rocket sitting idle on the pad it wasn’t too hard for OS/X to look good and Apple to gain some market share.

And then in comes Steven Sinofsky to lead the Windows guys.  Now I’m not going to lay all the credit on him.  I’m sure Jim Allchin deserves a lot of credit for building a solid foundation in Vista but it’s clear that the changes in development models that Sinofsky brought over from the Office team have made a huge difference not only in developer morale but in product quality.  I have yet to read any reviews of the Windows 7 pre-beta that didn’t describe it as fast, stable, and “what Vista should have been”.

So what are some of the features or enhancements in 7 that are going to make the difference?  I’m glad you asked.  Here are the features that I think will make 7 the must have OS for 2009.  This is not nearly a complete list of features however.

Speed, speed, and more speed.  The Windows team has spent a lot of time optimizing the product, reducing it’s memory footprint, and speeding up boot time.  There is evidence that 7 runs great on netbooks, unlike Vista.  Also, some early reviews have reported an install time of 15 minutes compared to Vista’s 45 minutes on the same hardware.  That same review showed 7 booting is much lower time than Vista.  Apparently resume is nearly instantaneous and,  unlike OS/X, the network is available immediately upon resume.

Device Stage.  This feature is actually not getting a lot of attention but I think it will be the killer feature of 7.  In essence it is area where device manufacturers can plug in to 7 and display a management page for their particular device.  So a user could plug in a cell phone, see it appear in device stage, and then click on it to bring up the manufacturers UI for that device.  This UI could contain links to online manuals, launchers for SMS message reading, sync settings, whatever.  This is device specific.  A printer could show ink tank levels, provide UI for maintenance, a button for ordering supplies, etc.  This is huge.  Count on it.

HomeGroups.  This is networking except easier.  This only works with Windows 7 pcs but when multiple Windows 7 computers are put on a single network they will connect to form a HomeGroup and then allow seamless sharing of the content on each computer with the others.  You get a PIN code for the home group so that when a visitor comes over with her laptop running 7 she is prompted to join the home group as soon as she gets on the network.  Enter the PIN code and she can share any of the media that you have made publicly available and print to any printers (use any device for that matter) that are publicly available without any concern or question about which computer she is connecting to.  It’s all seamless.  Just that way it should be.

New Windows Taskbar and Jumplists.  The new task bar has many new features like tab previewing, reordering, blah, blah, blah.  But the coolest new feature is called jumplists.  These are popup menus that appear when you click on the app icon.  These are customizable by the application and it will save clicks.  Want to edit the Word doc you were working on last night.  Just click on the word icon and the most recently edited files list appears in the jumplist.  Pick your doc and it opens right up.  Clicks saved!

Touch support.  It’s all about the touch these days.  From IPhones to G1s, it’s all about touch.  And Windows 7 is ready to be touched.  oh baby.  Pair Windows 7 with any of the already shipping touch screen computers like the HP TouchSmart and you have a fully touch enabled system.  You can drag, flick, and stroke your away around the desktop.  Hmm, that sounds just creepy now.  Just trust me, it’s cool.   You’ll love it. 

With the solid Vista foundation and the excellent feature work in 7, this is the Windows you have been waiting for.  Dell and other companies are starting to make laptops that really compete with Apple.  Dell and HP both have lappies that have battery lives of at least 19 hours (wow!) and Dell is starting to offer backlit keyboards on it’s computers.  OS/X is a nice operating system but with 7 coming at breakneck speed, nice is not going to be enough.  Oh yeah, it’s on now.

Thursday, October 9, 2008

am I the last to figure this out?

In my role with Sun I do quite a bit with the Visual Studio SDK.  I develop our ADO.NET provider and the integration code that allows the provider to work inside of Visual Studio.  We support VS 2005 and 2008 with a single binary and, up until now, I’ve used the VS 2005 SDK.  But I’ve had this nagging feeling that I should be able to use the 2008 SDK and the new VSCT format for producing the CTO files.

After some research I discovered that VS 2008 ships with some binding redirects that allows it to use binaries built with the 2005 SDK.  Of course you can always count on Microsoft to make this as hard as possible.  They could keep in mind that out here in the real world we have to support older VS versions and ship the SDK with all necessary tools and assemblies.  But this is Microsoft we are talking about so the regpkg tool that ships with the SDK and helps with assembly registration is tightly bound to the SDK version. 

But the stupidity doesn’t end there.  With some hacking you can get around the regpkg issue (and you can’t ship that tool anyway) but they don’t provide attributes to handle all the registration tasks that are necessary.  Need to register your assembly as a DDEX data provider?  Out of luck.  Need to specify the technology parameter so your DDEX provider works with the proper wizards?  Out of luck.  So, I don’t really give a flip about regpkg and the attributes.

With all that said, I tested building an integration project with the 2008 SDK after making the following changes.  The resources worked great originating as VSCT files. 

   1: <RegisterOutputPackage>false</RegisterOutputPackage>

   2: <RegisterWithCodebase>true</RegisterWithCodebase>

   3: <!-- Make sure we are 2005 compatible, and don't rely on RegPkg.exe 

   4:      of VS2008 which uses Microsoft.VisualStudio.Shell.9.0 -->

   5: <UseVS2005MPF>true</UseVS2005MPF>

   6: <!-- Don't try to run as a normal user (RANA), 

   7:      create experimental hive in HKEY_LOCAL_MACHINE -->

   8: <RegisterWithRanu>false</RegisterWithRanu>

Friday, September 26, 2008


I don’t know what the hell happened but I still have my blog posts.  Whew!  I recently moved my blog from a cheap GoDaddy account to my Windows Home Server.  I consider this entirely your fault, dear reader, as if I had more readers then I would feel compelled to host it externally with a fatter pipe.  But I digress…  :)

In any case, while was otherwise occupied (attending the Sun DBTG developers conference in Riga, Latvia) something happened to my server and I came home to my files not working.  They were there but any attempt to open them would give some obscure error about the system not being able to access it.  Clearly this had something to do  with the “special” load balancing driver that WHS uses.  In any case it appeared my music and blog was toast.

Earlier today I learned that WHS maintains another link to your shared folders.  I enabled viewing the protected folders and saw a folder named “DE” on c:\.  Peeking there shows the same shared folder directory structure only these work!  Clearly these are sym links as c:\ is only as 20 gig partition but it was showing nearly 80 gig of data in this folder.  I quickly copied these off to a new machine and rebuilt my WHS server.  Blog restored!

Lesson learned?  Get a second hard drive in your WHS machine so the folder duplication junk can do its thing!

Monday, August 25, 2008

Perfect virtual desktops. Almost...

Like most Windows devs I really like the Sysinternals family of products.  So when I caught wind this morning of a new product called Desktops that creates a virtual workspace of up to 4 desktops I just knew it was the product I was looking for.  Well, it sort of is.
You can't ask for an easier installation.  Unzip it and drop it on a folder and run it.  In the dialog that appears you can select whether to run it at startup.  Here's a shot of that dialog.

It has a nice selection of options to select which desktop you are using but sadly it doesn't support the most important one -- the arrow keys!  Someone who is using virtual desktop software is enough of a power user that they will want to switch desktops on-the-fly without looking at the keyboard.  Sure I can whack a number key without looking but the T-shape arrow keypad just fits with the metaphor a bit better.  A simple Ctrl+Shift+Arrow would do the trick.
The other problem is the speed. It's a bit slow and has no nice swipes or transitions but it is free software so I'm really not griping about that too much.
All in all a welcome bit of software.  Thanks Mark!

Wednesday, August 20, 2008

MySQL Connector/Net 5.1.7 has been released

MySQL Connector/Net 5.1.7 a new version of the all-managed .NET driver for MySQL has been released. This is a minor release involving mainly bug fixes.

Version 5.1.7 works with all versions of MySQL including MySQL-4.1,  MySQL-5.0, MySQL-5.1 beta or the MySQL-6.0 beta releases.

It is now available in source and binary form from [http://dev.mysql.com/downloads/connector/net/5.1.html] and mirror sites (note that not all mirror sites may be up to date at this point of time - if you can't find this version on some mirror, please try again later or choose another download site.)

Unless a major, data-loss type bug is found, we expect this to be the last release of the 5.1 product.  We encourage all new work to use the newly released 5.2 product

Bugs Fixed

  • Fixed problem with DDEX provider that could sometimes prevent table altering when working with 4.1 servers (bug #30603)
  • Fixed problem with pooling code where connections pooled from the pool were added twice to the in use pool.  This would cause a semaphore full exception when an attempt is made to release them back to the pool (bug #36688)
  • Reversed order of Datetime and DateTime enums for MySqlDbType so that VB users won't get autocorrection to Datetime (bug #37406)
  • Uncommented access denied error enumeration value (bug #37398)
  • Improved documentation concerning autoincrement columns and the DataColumn class (bug #37350)
  • Fixed problem where executing a command that results in a fatal exception would not close the connection.  (bug #37991)
  • Fixed problem where executing a command with a null connection object would result in a null reference exception instead of an InvalidOp (bug #38276)

Enjoy and thanks for the support!

Monday, August 18, 2008

Connector/Net 5.2.3 GA has been released

MySQL Connector/Net 5.2.3, a new version of the all-managed .NET driver for MySQL has been released.  This release is of GA quality and is suitable for  use in production environments.  We strongly urge you to  review the change log that is shipped with the product for a thorough review of the changes.

Version 5.2.3 works with all versions of MySQL including MySQL-4.1,  MySQL-5.0, MySQL-5.1 beta or the MySQL-6.0 Falcon "Preview".

It is now available in source and binary form from [http://dev.mysql.com/downloads/connector/net/5.2.html] and mirror sites (note that not all mirror sites may be up to date at this point of time - if you can't find this version on some mirror, please try again later or choose another download site.)

Changes since 5.2.2

  • Increased the speed of MySqlDataReader.GetOrdinal dramatically by using a couple of hashes for lookups
  • Fixed problem where some tables that support the web providers used the latin1 character set instead of the database default.  (bug #36444)
  • Changed how the procedure schema collection is retrieved.  If 'use procedure bodies=true' then we select on the mysql.proc table directly as this is up to 50x faster than our current IS implementation.  If 'use procedure bodies=false', then the IS collection is queried.  (bug #36694)
  • Fixed problem with our GetOrdinal speedup where we would attempt to add an already existing key to a hash when a resultset had more than 1 column with the same name. (bug #37239)
  • small fix to how we were allowing in/out and out parameters to slide through parameter serialization.  Before we were setting the AllowUserVariables connection setting but that had the unfortunate side effect of setting the value for all connections that shared that connection string.  This way we isolate it just to our particular command.  This may fix bug #37104
  • Fixed documentation surrounding use of ? vs @ for parameters (bug #37349)
  • Reduced network traffic for the normal case where the web provider schema is up to date (bug #37469)
  • Improved error reporting when a timeout occurs.  It no longer uses a message like 'reading from stream failed'.  (bug #38119)
  • fixed problem where adding a non-existent user to a role would not auto-create the user record (bug #38243)
  • moved string escaping routine from the MySqlString class to the MySqlHelper class and made it public and static.  (bug #36205)
  • Fixed problem where column metadata was not being read with the correct character set  (bug #38721)
  • Fixed problem where the uninstall was not cleaning up the state files (bug #38534)
  • Added 'Functions Return String' connection string option
  • Several other fixes merged in from 5.0 and 5.1

Monday, August 11, 2008

Windows Home Server and blog self-hosting

I recently setup one of my old machines using Windows Home Server and thought it would be nice to run my blog on it instead of GoDaddy.  The obvious approach was to use the terrific Whiist add-in and that's exactly what I did at first.

I encountered the first problem when setting up the web site because my site had to be a subsite under the main site.  I didn't really want my site to be found at xxxx.homeserver.com/reggie so I started playing with domain forwarding and masking at GoDaddy.  With the help of their fine support I managed to get www.reggieburnett.com redirected to my sub-web but none of the sub-links worked (photos, archives, etc).  Plus I didn't really like the CNAME redirect.

So this morning I set out to fix that and fix it I did.  Here's what I did:

  1. Removed forwarding of my site at GoDaddy
  2. Signed up for the free trial at www.zoneedit.com.  You get free dynamic DNS support for up to 5 sites and 200 MB of DNS traffic (apparently that is *ALOT*)
  3. I was already using the excellent dd-wrt firmware on my Linksys router so I just needed to tell it to update zoneedit when my IP changes (and give it my hostname and credentials)
  4. Then I disabled my site using the Whiist add-in
  5. And finally redirected the default site under IIS properties to point to my blog folder.  The /home and /remote subwebs are still there and point to the correct place.

Now you can go to www.reggieburnett.com and land on my self-hosted blog and I can also reach the WHS goodies through subweb URLs.

**EDIT** looks like my home link is broken but I can fix that with some web.config hacking.  No time right now though.  :)

Monday, May 19, 2008

Racing a jet engine

I've spent the last few days working on a support case where a customer was comparing the speed of Connector/Net with an application that uses our native C api.  His test was using a server side prepared statement to insert 3 sets of values in a loop that executed 600,000 times.  The table is a simple 3 column table and the SQL looks like this:

INSERT INTO test VALUES (@p1, @p2, @p3), (@p4, @p5, @p6), (@p7, @p8, @p9)

He was seeing 34,529 records / second using libmysql.dll but only about 24,000 records / second using Connector/Net.  He  understandably wanted to know why there was such a difference and if we could do something about it.  Absolutely!

We solved this problem through a combination of optimizations made to our code and some changes made to the testing application.  I won't say much about the optimizations.  We made some obvious changes like moving a lot more of the prepared statement work to the prepare phase and out of the execute phase.  We also discovered that BitConverter.ToBytes() is a lot slower than our hand-coded methods for reading and writing integer values.  We replaced usages of ArrayList with generic equivalents (it's pretty amazing how much faster generics are actually).

One of the bigger changes we made was to use a second hash for parameter name lookups.  When you are talking about loops with lots of iterations even the smallest inefficiencies can kill you.  Since .NET supports name lookup for parameters we use a hashtable to map parameter names to indices (we made this change when one of our customer was complaining that parameter lookup was slow on one of his commands that had > 30,000 parameters.  Yeah.).  Name lookup should be case-insensitive so we use a case-insensitive comparer with our hashtable.  So the optimization we made this time is to use two hash tables.  The first is case sensitive and is checked first.  If that fails then we check the second and return failure only if both fail.

That's what we did in our code.  We also made some changes to the testing app to make sure the comparison is truly apples to apples.  Let's first look at the loop code in each case.



while (count < 600000)


for (int row = 0; row < 3; ++row)


*(p1 + row) = count;

*(p2 + row) = count;

*(p3 + row) = count;





while (count < numberOfRows)


for (int row = 0; row < 3; ++row)


cmd.Parameters[row].Value = count;

cmd.Parameters[row+3].Value = count;

cmd.Parameters[row+6].Value = count++;




Don't get hung up on the output of these being slightly different.  The point here is that the C code is using simple pointer arithmetic during each loop where the C# code is doing array lookup.  The array lookup code is quite a bit slower because the get accessor for the parameter collection does some bounds checking so that a nicer exception will be thrown in the event of an out-of-bounds index.

Another change that was made to the testing app was to disable the command timeout in the C# code.  This is a small point but when the command timeout is greater than zero then a timer is constructed and started during each execution.  In this case that is 600,000 timers!  Again, since the C code doesn't provide any type of command timeout it's not a true apples-to-apples comparison.

So, in a nutshell, benchmarking against libmysql is sort of like racing a jet engine.  Very fast but not a great deal of "safety features".  Still, after many hours with dotTrace the results speak for themselves.     

C app = 35,294 records per second.

C# app = 35,321 records per second.

Monday, May 12, 2008

How I found out that mixed mode is cool

We ship a DDEX provider with Connector/Net.  This provider plugs into Visual Studio and integrates into server explorer allowing a user to create data connections to MySQL from within the IDE.  This integration is handled, in large part, by a lengthy series of registry entries.  Until 5.2.2, these entries were made by my installer which is written in WiX.  Having the registry changes made in the installer has two problems.  First, I often need to register the provider during debugging and I don't want to do a full install of the product so I end up hand editing a registry file and manually merging that file.  This a awkward at best.  Second I plan to ship a stand-alone configuration utility in 5.3 that will allow the user to configure which installed version of Connector/Net should be used for VS integration. Currently you can only have one instance installed at a time.

My approach to solving this was to write an installer class that made the registry changes for me and just use installutil to register the assembly.  I was already doing this with my core and web assemblies so this is nothing new.  The problem is that installutil will scan the assembly and all referenced assemblies for types looking for installer classes.  This fails when some of the Microsoft assemblies are scanned.  After much effort I gave up and decided to write my own installutil that I would ship with my installer. 

I had no trouble creating this application and then set about executing it from within my installer.  I attempted to use the CAQuietExec custom action available with WiX v3 but just couldn't make it work right.  So I gave up and decided to write my own execute custom action.

So I cracked open Visual Studio 2008 and read a couple of blogs about custom action writing.  One of them mentioned mixing managed and unmanaged code, the unmanaged code being necessary for the proper DLL exports.  I decided I had to see this work.

Within minutes I had a DLL project setup with the /clr option and had hacked out the following code:

   1: extern "C" __declspec(dllexport) UINT InstallAssembly(MSIHANDLE hMSI)

   2: {

   3:     System::Windows::Forms::MessageBox::Show("boo");

   4:     TCHAR name[261]={0};

   5:     DWORD len=261;


   7:     UINT result = ::MsiGetProperty(hMSI, TEXT("CustomActionData"), name, &len);

   8:     InstallVSAssembly(name, true);

   9:     return ERROR_SUCCESS;

  10: }


  12: bool InstallVSAssembly(char *assemblyName)

  13: {

  14:     String^ str = gcnew String(assemblyName);

  15:     bool uninstalling = false;

  16:     IDictionary mySavedState = new Hashtable();

  17:     int arg = 0;


  19:     InstallContext context = new InstallContext();

  20:     while (arg < args.Length)

  21:     {

  22:         string[] parts = args[arg++].Split('=');

  23:         context.Parameters.Add(parts[0], parts[1]);

  24:     }


  26:     Installer installer = null;

  27:     try

  28:     {

  29:         Assembly assem = Assembly.LoadFrom(file);

  30:         installer = (Installer)assem.CreateInstance("MySql.Data.VisualStudio.MyInstaller");

  31:         if (installer == null)

  32:         {

  33:             Console.WriteLine("Unable to find an installer in that assembly.");

  34:             return;

  35:         }

  36:         installer.Context = context;

  37:         if (uninstalling)

  38:             installer.Uninstall(mySavedState);

  39:         else

  40:             installer.Install(mySavedState);

  41:     }

  42:     catch (Exception e)

  43:     {

  44:         Console.WriteLine(e.Message);

  45:     }

  46:     return true;

47: }

Yes, that is managed code and unmanaged code *in the same function*!  Now this code might not compile as it is not what I wound up using and I just grabbed it out of an old folder but you get the idea (and yes I did test a version of this so I know the concept works).  I didn't use this approach because the /clr switch requires the dynamic CRT and I didn't feel like bundling that up.

And, in case you were wondering about the "boo" messagebox on line 3, that is my debugging trap.  You run the installer until that pops up, attach to the proper msiexec using Visual Studio, set a break point, and go.  Yup, that's cool.

MySQL Connector/Net 5.1.6 has been released

MySQL Connector/Net 5.1.6 a new version of the all-managed .NET driver for MySQL has been released. This is a minor release involving mainly bug fixes.
Version 5.1.6 works with all versions of MySQL including MySQL-4.1,  MySQL-5.0, MySQL-5.1 beta or the MySQL-6.0 Falcon "Preview".

It is now available in source and binary form from [http://dev.mysql.com/downloads/connector/net/5.1.html] and mirror sites (note that not all mirror sites may be up to date at this point of time - if you can't find this version on some mirror, please try again later or choose another download site.)

Bugs fixed

  • Fixed problem where parameters lists were not showing when you tried to alter a routine in server explorer.  (bug #34359)
  • Fixed a problem in procedure cache where it was possible to get into a race condition and cause a memory leak (bug #34338)
  • Fixed problem where attempting to use an isolation level other than the default with a transaction scope would use the default instead (bug #34448)
  • Fixed problem that causes the TableAdapter wizard to only generate insert statements.  The problem was that our code to retrieve index columns was broken. (bug #31338)
  • Fixed problem with connections staying open after being used with SqlDataSource.  The problem was that we were not returning an enumerator for our reader with the  closeReader option set to true when we were supposed to.  (Bug #34460)
  • Fixed problem where the bit data type would continue to return null values once it saw a null value in a previous row (bug #36313)     
  • Fixed problem with MembershipUser.GetPassword where attempting to retrieve a  password on a user where password Q&A is not required would throw an exception (bug #36159)     
  • Fixed a problem with MembershipUser.GetNumberOfUsersOnline.  It actually works now  :) (bug #36157)
  • Fixed documentation that still stated that setting port to -1 was necessary for a named pipe connection (bug #35356)     
  • Fixed data type processing so that geometry fields are returned as binary.  (bug #36081)     
  • Fixed problem that kept our provider from showing up in the provider list when configuring a new connection from a SqlDataSource     
  • Fixed problem where setting the ConnectionString property of MySqlConnection to null would throw an exception (bug #35619)

Enjoy and thanks for the support!

MySQL Connector/Net 5.2.2 beta has been released

MySQL Connector/Net 5.2.2, a new version of the all-managed .NET driver for MySQL has been released.  This release is a beta and may contain bugs with some of them possibly being severe.  You are strongly urged to not use this release in production environments.  This release is intended only for testing and feedback purposes.

Version 5.2.2 works with all versions of MySQL including MySQL-4.1,  MySQL-5.0, MySQL-5.1 beta or the MySQL-6.0 Falcon "Preview".

It is now available in source and binary form from [http://dev.mysql.com/downloads/connector/net/5.2.html] and mirror sites (note that not all mirror sites may be up to date at this point of time - if you can't find this version on some mirror, please try again later or choose another download site.)

Features or behavior changes

  • Added support for using the new PARAMETERS I_S view when running against a 6.0 server
  • Implemented interactive session connection string option 
  • The procedure parameters schema collection has been altered to match what is coming with MySQL 6.0.  Some fields have been removed and others combined.  Please review your application for incompatibilities.

Bugs fixed

  • Fixed profile provider that would throw an exception if you were updating a profile that already existed.
  • Fixed problem where new parameter code prevented stored procedures from being altered in Visual Studio (bug #34940)
  • Fixed problem where the TableAdapter wizard was no longer able to generate commands using stored procedures because of our change to using @ instead of ? (bug #34941)
  • Fixed problem in datagrid code related to creating a new table.  This problem may have been introduced with .NET 2.0 SP1.  
  • Fixed guid type so that a null value is still returned as guid type (bug #35041)
  • Fixed bug with the membership provider where the min non alpha numeric option was not working correctly.   
  • Fixed bug where calling GetPassword on a membership user when the password answer is null would cause an exception (bug #35332)
  • Fixed bug where retrieving passwords that are encrypted was not returning proper passwords (bug #35336)   
  • Fixed problem with profile provider where properties that were specified without a given type could not be retrieved properly (bug #36000) 
  • Removed some unnecessary locking from the pool manager and also reworked the pooling code to not use a semaphore (bug #34001)

Enjoy and thanks for the support!

Thursday, April 24, 2008

Still no trackpad love in latest Boot Camp

So Boot Camp 2.1 came out yesterday.  This release has official Vista x64 support but the trackpad issues (no two finger right click, erratic two finger scrolling) have not been fixed.  This is starting to smell bad and it has Steve Jobs' name all over it.

Wednesday, April 16, 2008

MySQL Connector/Net 5.0.9 has been released

MySQL Connector/Net 5.0.9, a new version of the all-managed .NET driver for MySQL has been released. This release is an update to the existing production-quality 5.0 series.

We plan for this to be the last release in the 5.0 series. We will only be updating the 5.0 product in the event a "data-loss" type bug is discovered. We encourage all new products to use the new 5.1 product.

Version 5.0.9 works with all versions of MySQL including MySQL-4.1, MySQL-5.0, MySQL-5.1 beta or the MySQL-6.0 Alpha.

It is now available in source and binary form from here and mirror sites (note that not all mirror sites may be up to date at this point of time - if you can't find this version on some mirror, please try again later or choose another download site.) 

Features or behavior changes

  • added implementation of MySqlCommandBuilder methods QuoteIdentifier and UnquoteIdentifier (bug #35492)

Bugs fixed

  • Fixed problem where fields that were blobs but did not include the BLOB flag were treated as binary when they should have been treated as text. (Bug #30233)
  • Changed from using Array.Copy to Buffer.BlockCopy in MySqlDataReader.GetBytes. This helps with memory usage as we expect the source and destination arrays to not be overlapping. (Bug #31090)
  • Fixed problem that prevented commands from being executed from the state change handler. Not sure why you would want to do this but... (bug #30964)
  • Fixed issue where column name metadata was not using the charset given on the connection string (Bug #31185)
  • Fixed problem with installer where the installation might report a failure to remove the performance counters if the performance counter category had already been removed for some reason
  • Fixed problem with installer where attempting to install over a failed uninstall could leave multiple clients registered in machine.config. (Bug #31731)
  • Fixed problem with connection string caching where our collection class was using case insensitive semantics and this causes cases where a user originally used the wrong case for a user id and then fixed it to still get access denied errors. (Bug #31433)
  • improved the speed of load data local infile significantly
  • fixed MySqlDateTime.ToString() to properly return the date value (Bug #32010)
  • fixed problem where string parameters who have their size set after their value could cause exceptions (Bug #32094)
  • fixed problem where old code was preventing creating parameter objects with non-input direction using just a constructor (Bug #32093)
  • fixed problem where a syntax error in a set of batch statements could leave the data adapter in a state that appears hung (bug #31930)
  • fixed the MySqlException class to set the server error code in the Data[] hash so that DbProviderFactory users can access the server error code (Bug #27436)
  • fixed problem where changing the connection string of a connection to one that changes the parameter marker after the connection had been assigned to a command but before the connection is opened can cause parameters to not be found (bug #13991)
  • some fixes to cancel and timeout operations so that they are more dependable
  • fixed problem where cloning a parameter that has not yet had its type set would yield a cloned parameter that would no longer infer it's type from the value set
  • Sunday, April 13, 2008

    Well isn't that a crapper

    I was so looking forward to hanging out in Santa Clara this week with all the fine people that come to see my .NET and Windows presentations (yes, both of you!) at the annual MySQL Users Conference.  The problem is that I hurt my knee Saturday evening and now I can barely walk.  So I decided it was better for me to stay home and try to stay off the knee as much as I can.  Sorry for those people who were planning on attending my building and debugging on Windows session however the entity framework session should still happen with the ever-capable David Sceppa at the helm.

    So go have fun while I sit here and wince.  :(

    Monday, April 7, 2008

    Referencing Connector/Net on a remote machine

    Recently I've read lots of forum posts from frustrated users claiming that their is something wrong with the Connector/Net installer.  They reference the connector in their web app, then deploy the app to their remote host only to find that the app no longer works.  I'll walk through a simple web app sample and show where the confusion comes from and what they should be doing instead.  This sample assumes you have a recent build of Connector/Net installed with Visual Studio integration enabled.
    First, we'll create a web app using Visual Studio 2008.

    Create a web app dialog
    The next thing that many developers do is create some type of page that references the connector.  Often this is a SqlDataSource that they will be connecting to a datagrid.  To do that you drop a SqlDataSource control and a GridView control on the page.  After setting the grid view to use the sql data source you now need to configure the data source control.  Normally  to do that you would select 'Configure Data Source...' from the smart tasks popup and walk through adding a data connection to your app (as well as Server Explorer).  Due to a bug in our implementation currently you need to add the connection to Server Explorer first and then pick that connection in the Configure Data Source dialog.  Once done with this you can find the new connection string in your web.config and see how the data source control is tied to it.   Here is the connection string added to my web.config.
    <connectionStrings> <add name="testConnectionString" connectionString="server=localhost;user id=root;database=test" providerName="MySql.Data.MySqlClient" /> </connectionStrings>

    Here is how my SqlDataSource is configured now.

    <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:testConnectionString %>" ProviderName="<%$ ConnectionStrings:testConnectionString.ProviderName %>" SelectCommand="select * from t1"></asp:SqlDataSource>

    At this point you can hit F5 in VS and the web app will run and show you the data you specified in your query.  However, if you deploy this application to a remote server that does not have Connector/Net installed then it will fail and you may see something like this:

    What's going on?  The first thing to understand is how the SqlDataSource connects to a data provider.  If you refer back to our connection string you'll see the attribute providerName have the value 'MySql.Data.MySqlClient'.  That is the invariant name of Connector/Net.  However this name is not enough to locate the right assembly to load.  This mapping is done in either the machine.config or web.config files.  The Connector/Net installer makes the proper registrations in the machine.config file.  Here is the DbProviderFactories section from my machine.config (I've omitted all entries but Connector/Net for brevity).

    <system.data> <DbProviderFactories> <add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=, Culture=neutral, PublicKeyToken=c5687fc88969c44d" /> </DbProviderFactories> </system.data>

    With this entry in machine.config then the system can match the invariant name to a fully qualified assembly name and also identify the client factory class that should be used.  You can see that by examining the type attribute above.

    So what do you do if you are deploying this app to a remote server that you can't install Connector/Net on?  Simple.  Add this registration to your web.config.  Just drop it in right outside the system.web block like this:

    <system.data> <DbProviderFactories> <clear/> <add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=, Culture=neutral, PublicKeyToken=c5687fc88969c44d" /> </DbProviderFactories> </system.data>

    So why the <clear/> tag?  You can't doubly add provider factories to the config system so if you have Connector/Net installed on your dev system and you register the provider factory in your web.config then you will be doubly adding them.  The clear tag clears out all the provider factories pulled in from machine.config and then adds in  yours.  Now if you are mixing providers then you'll need to adjust this to your situation.

    I hope this blog post has cleared up some of the reasons why people have working web apps on their dev systems but then are confused when it doesn't work after deploy.

    Wednesday, March 26, 2008

    Slide.Show installed as my photo viewer

    Finally got around to hacking in Slide.Show as my photo viewer.  Yup, you need Silverlight installed to see them but with the way that Silverlight is growing that shouldn't be a problem.

    Go check it out and let me know what you think!

    Thursday, March 13, 2008

    Getting the built in data browser to work in 2005 and 2008

    When we last left our hero he had just got the global data menu working under '05 and '08.  Next step was use of the table browser.  Here's a shot of it working with SQL Server data.  Now there is no particular reason to use this data browser instead of writing our own other than it's just less work and it has a nice look and feel.

    On the surface this looks pretty easy.  After a little digging I discovered that this command binding will add a "Show Table Data" menu option and bring up a nice OleDB-based data browser under VS 2005.
    <CommandBinding name="Browse_Data" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="12384"
      <Parameter value="Open"/>

    The problem, of course, is that this doesn't work under VS 2008.  The handler under VS 2008 is implemented by an object with the guid of 884DD964-5327-461f-9F06-6484DD540F8F.  My first approach was to define two of these bindings and no matter which version of VS ran one of them would fail (and not add any menu item) while the other would succeed.  VS doesn't like that.  Apparently the guid and cmdId together form a key and you get a key added twice error. Hmmm
    My good buddy Stephen at Microsoft offered up the solution of overriding the GetDataViews method of DataViewSupport and tweaking the XML that is returned.  It turns out that he was spot on.  I set all the handlers in the XML file to be proper for VS 2005, changed my DataViewSupport derived class to now use the no parameter constructor base, and then overrode the GetDataViews method like so.
    public override Stream GetDataViews() { string xmlName = "MySql.Data.VisualStudio.DDEX.MySqlDataViewSupport.xml"; Assembly executingAssembly = Assembly.GetExecutingAssembly(); Stream stream = executingAssembly.GetManifestResourceStream(xmlName); StreamReader reader = new StreamReader(stream); string xml = reader.ReadToEnd(); reader.Close(); // if we are running under VS 2008 then we need to switch out a couple // of command handlers DTE dte = Package.GetGlobalService(typeof(DTE)) as DTE; if (dte.Version.StartsWith("9")) xml = xml.Replace ("Microsoft.VisualStudio.DataTools.DBPackage.VDT_OLEDB_CommandHandler_TableTools", "884DD964-5327-461f-9F06-6484DD540F8F"); MemoryStream ms = new MemoryStream(xml.Length); StreamWriter writer = new StreamWriter(ms); writer.Write(xml); writer.Flush(); ms.Position = 0; return ms; }

    I won't bother with showing you a pic of it working in MySQL because it looks just like the other pic.  But, then again, that's the point.  :)

    Supporting a global data menu option under 2005 and 2008

    It's no secret that that SQL Server integrates better into Visual Studio than any other database.  We are trying to change that.  Two of the things that I wanted to implement in the new version of our integration code is to replicate the Add New submenu and use the the built-in table browsers that Sql Server uses.  Here is a screen shot of the global data menu we wanted to reproduce.

    This menu should also work in Visual Studio 2005 though the top four items (Schema Compare, Data Compare, Refactor, and T-SQL Editor) won't be there.  The problem is that adding items to the global data menu is not directly supported in Visual Studio 2005 but it is supported in 2008.  This is further complicated due to the fact that Microsoft moved from using CTC files to VSCT files to define package resources.  I didn't want to ship two binaries (one for 2005 and one for 2008) so I have continued to use the CTC format.  Here is what I had to do to get it working.
    First, I defined a constant for the appropriate menu group in VS 2005.  I put this in my file named guids.h
    #define guidVS2005Data          { 0x501822e5, 0xb5af, 0x11d0, { 0xb4, 0xdc, 0x00, 0xa0, 0xc9, 0x15, 0x06, 0xef } }
    Then I defined two menus and two groups (one for 2005 and one for 2008).
        guidMySqlProviderCmdSet:menuAddNew2005, guidVS2005Data:8706, 0x1000,, "MySQLAdd", "&Add New";
        guidMySqlProviderCmdSet:menuAddNew2008, guidVSData:IDG_DV_GLOBAL1, 0x1000,, "MySQLAdd", "&Add New";

        guidMySqlProviderCmdSet:groupAddNew2005, guidMySqlProviderCmdSet:menuAddNew2005, 0x0000;
        guidMySqlProviderCmdSet:groupAddNew2008, guidMySqlProviderCmdSet:menuAddNew2008, 0x0000;

    Note here that 8706 is the id of the global data menu in VS 2005 and IDG_DV_GLOBAL1 is the id under VS 2008.  menuAddNew2005, menuAddNew2008, groupAddNew2005, and groupAddNew2008 are just simple ids I assigned. The reason you need to define the menu twice is because no matter which version of VS you use it will balk at adding the same menu to two different top level groups.
    Then I define the commands I want to appear on the menus but I don't put them on the menus here since I need to put them on two different menus.
    /* global data menu items */
    guidMySqlProviderCmdSet:cmdidAddNewTableGlobal, Group_Undefined:0, 0x0000, OI_NOID, BUTTON, DIS_DEF, "&Table";
    guidMySqlProviderCmdSet:cmdidAddNewViewGlobal, Group_Undefined:0, 0x0001, OI_NOID, BUTTON, DIS_DEF, "Vie&w";
    guidMySqlProviderCmdSet:cmdidAddNewProcedureGlobal, Group_Undefined:0, 0x0002, OI_NOID, BUTTON, DIS_DEF, "Stored &Procedure";
    guidMySqlProviderCmdSet:cmdidAddNewFunctionGlobal, Group_Undefined:0, 0x0003, OI_NOID, BUTTON, DIS_DEF, "Stored &Function";
    guidMySqlProviderCmdSet:cmdidAddNewUDFGlobal, Group_Undefined:0, 0x0004, OI_NOID, BUTTON, DIS_DEF, "&UDF";

    Now I add the commands to both menus
    guidMySqlProviderCmdSet:cmdidAddNewTableGlobal, guidMySqlProviderCmdSet:groupAddNew2005, 1;
    guidMySqlProviderCmdSet:cmdidAddNewTableGlobal, guidMySqlProviderCmdSet:groupAddNew2008, 1;

    /* others omitted for brevity  */
    Now we need to add our commands to our data view XML file.  Here is what one command binding looks like.
    <CommandBinding name="AddNewTable" guid="B87CB51F-8A01-4c5e-BF3E-5D0565D5397D"
                    cmdid="500" handler="MySql.Data.VisualStudio.MySqlDataViewCommandHandler">
      <Parameter value="HighLevel"/>

    Notice the command parameter named "HighLevel".  This is important because without it the menus will not function correctly in VS 2005.  You also need to add all the commands into the command bindings of every node.  Yes, this is very repetitious but is necessary due to a bug in VS 2005.  Without doing that the menu will appear when the connection node is selected but will disappear when on the other nodes.
    I would also like to thank a developer at Microsoft who answered tons of my questions and helped me sort this out.  His name is Stephen Provine and I really appreciate all his hard work.  With all this done, here is the same shot working with MySQL.