Put your message here! Contact me for more information
 
 







 

Archive for the ‘My Projects’ Category


 


{{http://alexle.net/wp-content/uploads/2007/06/rails.thumbnail.png }}Working on Wars of Earth by myself, I run into several situations when I’d like to move migration files around to get them executed in a particular order. The trick is simple: just rename the sequence of the migration files to get them to be executed in the order you want.

Besides sloppy schema design (hey, I’m trying to be agile here - fix it as you go), an example of a situation when you want to move migration files around: table A has a foreign key to table B. Migration file for A is at 005, while that of B is at 010. If you try to put in the FORIEGN KEY constraint in A migration file after the table creation, migration will fail since table B hasn’t been created yet, not until migration #010. You can add another migration file just to add the FORIEGN KEY constraint from A to B, say at #020. But then you will have fragmented migration code all over the place. For production environment, this is the only solid and proven way to perform database changes. However, during development, you have the luxury to drop and recreate the entire database from scratch, it’s just a lot more convenient and makes more sense to be able to move migration files around. Ideally, you just need to run migration for B first, then you can run migration for A, which also execute the SQL to add in the FOREIGN KEY constraint properly.

Until now, you have to it manually. Imagine if you have 20 migration files in between, from 5 to 25 (like what I have), you will probably have to renumber 20 migration files. And if your project is in SVN, it would be more time-consuming and error-prone. You can either do “svn rename”, or just rename in the shell, then deleted the previous migration files and added the newly-named ones back into the repository. But what would happen if you yawn for a second and misnumber a file at #6, so you have two 006 migration files. Oops.

Worry no more, here comes **numergrate** utility to the rescue. In short, numergrate is “to numerate migration files” (or to renumber migration files)

What you need is to drop in the numergrate script (download below) inside your Rails’ script folder and you are ready to go. With this utility, you can execute at the root of the Rails project

ruby script/numergrate 5 before 25
to (test) move 005 to position 024 instead.

or

ruby script/numergrate 10 after 2 --svn
to move 010 before 002 and also rename the files in the Subversion repository.

I also took the opportunity to integrate the utility with Subversion in case your migration files are in a repository. There’s no easy way for CVS so I didn’t implement it. However, implementing renaming mechanism for other SCM should be straight forward if you know their command line renaming tool.

I hope this comes handy for you.

==== Supported tools ====

* {{http://alexle.net/wp-content/uploads/2007/06/subversion_logo.thumbnail.jpg}} Subversion (renaming files in repository)
* {{http://alexle.net/wp-content/uploads/2007/06/utilities-terminal.png}} Shell (just like renaming manually)

==== Script ====

#!/usr/bin/env ruby
# (c) 2007 Alex Le
# www.alexle.net - nworld3d@yahoo.com
# This script is developed for www.warsofearth.com. (shameless self-promotion)
# Released under the same license as Ruby
# Disclaimer: The author is not responsible for any incorrect results from running
# the script. Use it at your own risk.
#
# USAGE:
# ------
# This script is used to re-number the migration files into the desired sequence
# In development, this comes handy as you can organize migration files into logical groups
# by running a simple command line utility instead of manually renaming the filenames.
#
# numergration = numerate migration files
#
# INSTALL
# -------
# Copy numergration into script/ folder of your Rails application.
# On linux system you may have to chmod the script to be executable (+x)
#
# HOW TO RUN
# ----------
# At your Rails application root, run:
# On Windows:
# > ruby script/numergrate before|after [mode]
# On Linux: users can just run the script without calling the ruby executable since
# there’s a #! on top, provided that you set the permission correctly. (chmod to +x)
# $ script/numergrate before|after [mode]
#
# The [mode] options are
# –test Default mode to test the result before you run
# with –shell or –svn
#
# –shell Renaming file as you would do manually in the shell
#
# –svn Integrate with Subversion by executing `svn rename` on each file
# This option alters your working copy so please be extra careful.
# (a.k.a. use it at your own risk)”
#
# Example:
# ——–
# a. Move Migration file 50 to position 3, hence shifting migration files
# from 3 to 49 to the right by 1.
# > ruby script/numergrate 50 before 3
# (the above will just execute with the –test default option)
#
# Or to actually rename the files,
# > ruby script/numergrate 50 before 3 –shell (or –svn)
#
# Or you can even run
# > ruby script/numergrate 50 after 3
# to put migration file 50 after migration file 3 (shifting migration
# file 4 to 49 to the right by 1)
#
# TODO:
# —-
# 1. Better sequence handling. Currently it’s default to 000 for the
# sequence series. However, there can be potentially a lot migration files.
# (more than 999 files). The solution is to find the max sequence and
# use that as the series template
# 2. Better SVN integration.
# a. Do some checking to see if the svn client exists before running.
# Otherwise throw an error
# 3. Better sequence checking. Currently it doesn’t check for input
# range so we can have “index out of bound” errors.
#

require ‘fileutils’
include FileUtils

# which folder we would skip while iterate through
SKIPPED_FILES = [’.', ‘..’,’.svn’]

# check for arguments
unless ARGV.size == 3 or ARGV.size == 4
puts ‘invalid syntax’
exit
end

# this class hold the information about the migration file
class MigrationFile
attr_accessor :sequence, :name, :new_sequence

def to_s(options={})
if @new_sequence != @sequence
s = sprintf(”%03d”,@new_sequence) << "_#{@name}"
else
s = sprintf("%03d",@sequence) << "_#{@name}"
end
end

def initialize(sequence, name)
@sequence = sequence
@name = name
@new_sequence = @sequence
end

def shift_left()
@new_sequence -= 1
end

def shift_right()
@new_sequence += 1
end

def is_changed?
return @new_sequence != @sequence
end

def old_name
s = sprintf("%03d",@sequence) << "_#{@name}"
end

def new_name
s = sprintf("%03d",@new_sequence) << "_#{@name}"
end
end

# 123 after 234 --test
src, task, dest, mode = [ARGV[0].to_i, ARGV[1], ARGV[2].to_i, ARGV[3]] # got to explicitly convert to number for comparision
# exit if don't have to move
exit if src == dest

# default mode to --test
mode ||= "--test"

#grab the migration files
files = []
Dir.entries("db/migrate").each { |file|
unless SKIPPED_FILES.include?file
files << MigrationFile.new(file.to_i, file.match(/.+?_(.*)/)[1])
end
}

# now perform shifting
files.each{ |file|
if src > dest
if file.sequence == src
if task == “before”
file.new_sequence = dest
elsif task == “after”
file.new_sequence = dest + 1
end
else
# shift the innner range files
if file.sequence >= dest && file.sequence < src
if task == "before"
file.shift_right
else
file.shift_right unless file.sequence == dest # if insert after, we don't need to shift the dest
end
end
end
elsif src < dest
if file.sequence == src
if task == "before"
file.new_sequence = dest - 1
elsif task == "after"
file.new_sequence = dest
end
else
# shift the innner range files
if file.sequence <= dest && file.sequence > src
if task == “before”
file.shift_left unless file.sequence == dest # if insert before, we don’t need to shift the dest
else
file.shift_left
end
end
end
end # if src > dest
}

#files.each{ |f| puts f if f.new_sequence != f.sequence }

# now issue
puts “”
puts ” Execute using #{mode} option”
puts “”
puts ” You can execute with these options: ”
puts “”
puts ” –test Default mode to test the result before you run”
puts ” with –shell or –svn”
puts “”
puts ” –shell Renaming file as you would do manually in the shell”
puts “”
puts ” –svn Integrate with Subversion by executing `svn rename` on each file”
puts ” This option alters your working copy so please be extra careful.”
puts ” (a.k.a. use it at your own risk)”
puts “”

files.each{ |file|
if file.is_changed?
if mode == “–shell”
puts ” rename ” << "db/migrate/" << file.old_name
puts " to " << "db/migrate/" << file.new_name
cp("db/migrate/" << file.old_name, "db/migrate/" << file.new_name )
rm("db/migrate/" << file.old_name)
elsif mode.downcase == "--svn"
#puts "executing svn commmand here"
puts " svn rename " << "db/migrate/" << file.old_name
puts " to " << "db/migrate/" << file.new_name
system 'svn rename --force db/migrate/' << file.old_name << " db/migrate/" << file.new_name
elsif mode.downcase == "--test"
puts " [TEST] rename " << "db/migrate/" << file.old_name
puts " to " << "db/migrate/" << file.new_name
end
end
}

==== Download ====
* To download, please click here: [[http://alexle.net/wp-content/uploads/2007/06/numergrate.zip|numergrate]] (version 1.0, 06/17/2007)

==== Note ====
* Moving migration files around can do serious damage to your database. Please be careful. This comes extremely dangerous if you are working with other people on the same repository. Please be smart about it. Use it at your own rick.
* Comments and suggestions are very welcome.
* Support me at [[http://www.warsofearth.com|Wars of Earth]] if you can. Another shameless self-promotion.

view comments
 

I just updated the scripts on www.lastproxy.com, both the CGI (nph-proxy) and PHP (php-proxy.php) flavors. While installing the php-proxy.php was just an upload,go, and forget, configuring the nph-proxy.cgi script on 1and1 is quite tricky. I called up the 1and1 support staff and the guy seems to be really nice, but clueless about what to do.

Well, to get nph-proxy.cgi to work on 1and1, you have to do these following

1. Upload nph-proxy.cgi as ASCII
2. Chmod the script to 755 using any FTP client (e.g. FileZilla)
3. The default #! usr/bin/perl line of the script works just fine with 1and1 so you don’t have to worry about it.
4. To actually get the script working, change the extension from .cgi to .nph
5. Point your browser to the script, bam, things just work!

For some servers, they use the prefix nph- to signify the PERL engine to not parse the header (nph stands for non-parse-header). My guess is that 1and1 server configs to use the extension .nph to notify the PERL engine instead.

I hope that this saves you some hassles getting nph-proxy.cgi to work. Last of all, check out my proxy page at http://www.lastproxy.com
LastProxy logo

view comments
 

After surfing around sitepoint.com for a few days, I decided to put up my own proxy site. If Intel have Core Duo 2 (shouldn’t it be Core Quadro or something?), then my site should have dual-proxy — both PHP and CGI flavor.

Besides the regular features of the proxy, I’m thinking about adding countries IP-filtering, which should not be too hard to implement becase the documentations at Maxmind have the code exerpt. So it’s a matter of tweaking the script to work with my site. In light of a site-auction at sitepoint.com forum, .htaccess will also be added to avoid hot-linking. I think there are tons tutorials on how to do this.

Below is a screencast (gif!) of the template is below … I’m pretty happy with the result so far. The design process went really well and I have to admit that I LOVE my stripedesigner.com site. It’s awesome! Can you tell what stripes did I use for this particular design?

LastProxy

Comments are welcome as usual. :)

view comments
 

view comments
 

I’ve been working with VirtueMart 1.05 for a while and there’s one specific feature of FF that really annoys me. Copy and Paste results in a “Unprevileged script” error. I’ve made a quick video of my screenshot so you can see what I mean … This is really annoying.

More details of this are here at http://www.mozilla.org/editor/midasdemo/securityprefs.html. This is just crap, Mozilla! Why do you make me to switch to IE? I hate this. But the rich-text editor for my WP is still working just fine. Meanwhile, at http://neosmart.net/blog/archives/181, it was said that the copy&paste bug had been fixed in 1.5.0.4. What’s going on then?

I think the whole under/unpriviliges crap just stupid. Firfox, -1 for you.

view comments