Who Broke Hoodwink'd?
Hoodwink’d is my favorite underground club, but right now it’s broken! Many are complaining, _why has been very silent and no one are there to help us. Since no one else wanted to investigate, it looks like I’ve got to do it.
First: The bugs
The first thing that is broken is the fresh sites at onslaught. Right now it looks like this:

But if you go to the satellite office, you’ll see that there are 19 more sites:

My first thought was that something went wrong when I added diskusjon.no, since if you tried to post on any of those sites you’ll get a dirty error:
ActiveRecord::StatementInvalid Mysql::Error: Column 'site_id' cannot be null: INSERT INTO hoodwinkd_posts (`permalink`, `site_id`, `title`, `last_wink_id`, `layer_id`, `wink_count`, `created_at`, `first_wink_id`) VALUES('/posts/haiku.rb.html', NULL, '', 0, 1431, 0, '2008-03-25 06:08:31', 0):
I was wrong. The same error appeared on many other sites too. You’ll get that error if you try to post on a page without any other winks. It also looks like I was the last to post on a page without any other winks:

Something happened after January 11. Someone broke Hoodwink’d!
Use the source!
Luckily for us, the source is freely available at why’s subversion repo. The error claims to be in /home/sites/hoodwink.d/lib/hoodwinkd/controllers.rb:120 and that 'site_id' cannot be null. Let’s check it out:
@post = Post.find_by_sql([<<-END, domain, @permalink]).first SELECT p.*, IFNULL(s.real_domain, s.domain) AS real_domain FROM hoodwinkd_posts p, hoodwinkd_layers l, hoodwinkd_sites s WHERE p.layer_id = l.id AND l.site_id = s.id AND s.domain = ? AND p.permalink = ? END if @post domain = @post.real_domain else @layer = Site.find_by_domain(domain, :include => :layers).layers.detect do |l| @permalink =~ /#{ l.fullpost_url_match }/ end # Line 120 below @post = Post.create :layer_id => @layer.id, :permalink => @permalink, :wink_count => 0 end
Post referrers to a page which has many Winks. First it tries to find a Post based on domain and permalink. If there isn’t such a post, it will create one. The problem is that the database wants site_id, while Post.create is only given layer_id, permalink and wiki_count.
What’s really weird is the schema. The Post-table shouldn’t have a site_id:
create_table :hoodwinkd_posts do |t| t.column :id, :integer, :null => false t.column :layer_id, :integer, :null => false t.column :permalink, :string, :limit => 192, :null => false t.column :wink_count, :integer t.column :created_at, :datetime t.column :title, :string, :limit => 192 t.column :first_wink_id, :integer t.column :last_wink_id, :integer end
Here’s what I think happened: Around January 11 why did some refactoring where he added @siteid@ to hoodwinkd_posts. In the refactoring he simply forgot to update line 120. I have no idea why he didn’t commit the changes to the repo.
Another option is that someone gained access to the database and added another column, but what kind of a hacker does that?
Why The Lucky Stiff, we require answers!