Wednesday, December 09, 2009

Renaming a MySQL database without having access to datafiles

If you've used MySQL then you will know this situation; your database name is wrong & MySQL does not support any kind of command like

rename database my_db to my_real_name;

In fact the only way to do this is to rename the directory name the database files are held in on the data store; or so I thought. Turns out that the rename table command comes to the rescue with this beautiful line
As long as two databases are on the same file system, you can use RENAME TABLE to move a table from one database to another:

Giving us something quite simple looking like this:

RENAME TABLE my_db.tbl_name TO my_real_name.tbl_name;

Pin this together with a loop over all tables in a schema & bob is your uncle you've got a database re-namer without going anywhere near the datafiles. The thing that confuses me is why MySQL dropped support for the rename function (which is still documented) when they could have implemented it like this; I'm sure they had their reasons.

Wednesday, December 02, 2009

each() in Perl can be dangerous

I'm a Java programmer by trade and one of the first things that is hammered into us (right after never using + for multiple string concatenation) is how to correctly iterate through a Map. Now the reason why is if you want to iterate through a Map's contents using keys only and then performing the value retrieval using its get() method then that is really inefficient. Java's hash implementations are good but considering the majority of the time keys are stored with their values in the backing datastructures; to get the pair out at the same time makes sense. So the first time you come to Perl you think
how on earth do I iterate through a hash?
and then you see the each() method. This gives rise to the following code:


while( my ($key, $value) = each(%my_hash)) {
print $key, '->', $value, "\n";
}


This all seems fine & dandy until we want to do something like this:


our %my_hash = (a=>1,b=>2);
my @elements = get_from_somewhere();
print "Starting\n";
OUTERLOOP: foreach my $el (@elements) {
while( my $key, $value) = each(%my_hash)) {
print $key, "\n";
if($key eq 'a') {
last OUTERLOOP;
}
}
}


Still seems okay right? Wrong! See the problem here comes from iteration of the EntrySet belonging to the hash & not to another data structure so on multiple invocations of this code the iteration of the map continues from where it left-off. So if the elements from the hash are returned in the order a,b & we execute it twice you will see:


Starting
a
Starting
b
a


To get to the correct expected output you need:


our %my_hash = (a=>1,b=>2);
my @elements = get_from_somewhere();
print "Starting\n";
OUTERLOOP: foreach my $el (@elements) {
foreach my $key (keys %my_hash) {
my $value = $my_hash{$key};
print $key, "\n";
if($key eq 'a') {
last OUTERLOOP;
}
}
}


So what's the solution? Well if I said never use each then I would be stupid & wrong. each makes sense. What I would recommend is if you might break out of a loop using a data structure where you may require early termination of a hash structure which is persistent between calls then do not use each. Or use one of the Iterator functions/modules in CPAN to provide a more Java like method of access to hashes; but then that wouldn't be Perl :).

Wednesday, August 27, 2008

Singletons; those silly little Singletons

Miško Hevery recent series of articles about Singletons & singletons (note the capitalisation) is one of the best discussions of the topic I have read. In the latest article he has hit the preverbal nail on the head with the distinction between a Singleton & a singleton.

Skip to the end for a quick summary

I have worked with a lot of code containing a lot of Singletons, many caused by my own hand, and they have one thing in common. They all sucked. Sorry let me quantify that horrendous statement; the fact that the object(s) were Singletons made working with the code in an environment other than production nigh on impossible. The underlying code was sound. What was using the Singleton.getInstance() accessor rather than forcing code to pass a reference to the object which at one point so happens to be a singleton. Imagine these scenarios:


public class MyClass {
private final Singleton sing = Singleton.getInstance();
}


public class MyClass {
private final Singleton sing;
public MyClass(Singleton sing) {
this.sing = sing;
}
}


Wow so it's the same overall effect (an instance of Singleton makes its way in MyClass) but the second one is just plain better. Get your Singleton to implement an interface & then you've succeeded in a decent level of separation (which is what my group did with the last Singleton). But there was one thing that I was confused about (but did not know) & it's very similar to people who hate Javascript. A singleton (a single instance of an object) is a very good thing; a Singleton (a globally held reference to a single instance of an object) is not & never will be. However a program needs a context to run from (which is what the Singleton was being used for).

Just think about something like Struts (1.x); there's only normally one instance of an ActionServlet per application. A context if you will. This is where Miško's article has really driven this point home. A single instance of an object is no bad thing; in fact it's normally quite a desirable thing. What hurts you is the Singleton anti-pattern. It becomes gospel; the alpha and the omega and trust me you do not want to program yourself into this cul-de-sac.

Anyway to summarise Singleton bad; single object instance good.

Monday, June 30, 2008

Another Perl Snippit

use Test::Simple tests => 2;

my $array_with_things = [0,1,2,3,4,5,6,7,8,9];
ok(scalar(@{$array_with_things} == 10) ;
@{$array_with_things} = ();  # Here's the magic
ok(scalar(@{$array_with_things}) == 0);

That's right it is a way of clearing an array of all elements. I always forget how to do it which is why it's here.

Tuesday, March 04, 2008

I wouldn't let it lie

Sorry that last article has really gotten to me. I really do not want to do down people's efforts on these Perl to Java projects because I can see that there has been a lot of time spent on them. It is just that this article is recommending me to use a language which to be quite honest is not a good fit for Java. A lot of these libraries seem to have been conceived about 3-4 years ago when there was a lack of an actively developed scripting language (well there was Jython but that was not being actively developed by then).  But now we've got:
  • JRuby
  • Jython (being developed again)
  • Groovy (which really is scriptable Java with lots of sugar)
  • Rhino
I look at the list of libraries and really there's something each of these languages which can do a lot better not to mention running in the JVM. In a way the author is right these are 10 modules a Java programmer should know about if only to remind themselves that there has got to be a better way now.

BTW I like Perl. I like it a lot :-)

Wow ... seriously?

I've just had the misfortune to read an article about how to use Java from Perl. Maybe I am missing the point here but that sounds like one of the most awful things you could possibly do. I've spent the past 5 years working in bioinformatics (an industry where Java & Perl are the major players outside of algorithm work) and not once have I ever thought "I wish I could use my Java in Perl".

It's amazing really but I've encountered this exact problem of Java to Perl communication over the past 3 weeks the final decision was to communicate using JSON & then leave Perl to work over the incoming JSON data. This works brilliantly and we have a very clear separation of concerns between Java & Perl. Java gets the data, passes it into Perl & then Perl can manipulate it to it's hearts content. It's even good for testing since we have canned JSON files with data.

Now if it was a Perl implementation in the JVM I think I'd be more interested; but for the moment I think I'll pass on these modules.

Tuesday, February 12, 2008

A Perl of Wisdom for Me

Every so often I find a really nice construct I didn't know existed in Perl and I can never remember it. Well I'm going to post them here and see if it kicks my memory into gear.

Copying an array

my $array = [1,2,3]; # From somewhere
my $copy = [@{$array}]; #De-reference array into an anonymous array & assign

Populating a hash from an array via a slice

my %hash;
my @keys = qw/ key key2 key3 /;
@hash{@keys} = (); #Populate hash with keys and no values

#Populate hash with keys from array and values from same position in the assigned list
@hash{@keys} = (1,2,3);

Copying one hash to another

my $input = {key => 1, key2 => 2, key3 => 3};
my %target = (key, 4);
#And now for the copy magic
@target{keys(%{$input})} = values(%{$input}); #1 deref is better than 2 but is ok for tiny calls

Anyway I hope this is of use to someone other than me. If not then it'll be of some use to me.

Tuesday, January 29, 2008

You know when you just think 'Oh FFS'

I've just had one of those moments thanks to an article on Chaotic Java (if you're interested in Java then have a look through the archives as it's all gold). Anyway the article is about Java GC & there was a section about using object reference queues instead of a finalize block (a good idea anyway) and there was a line:

I made NativeImage and Image implement Closeable, a new interface in Java 5 for IO classes that need to be closed.

What?!? There's a ... a ... interface called Closeable. Oh yes there is introduced in Java 1.5 and it's been added to just about every IO class. Wish I had know about that before writing the same try finally block for Readers, Writers, InputStreams & OutputStreams. I know it's a case of 20 lines instead of 3 but it seems annoying. I wonder how many more of these interfaces there are in Java 5 & 6 that could have saved me a few more lines of code. 

Oh well