Sunday, October 16, 2011

GWT and HTML Canvas

I started to learn Google Web Toolkit this weekend and am very pleasantly surprised.
I installed it via Eclipse update site and got right to work.
I was able to manipulate the base project and look at the demos to figure out stuff.
I was interested in creating a demo site using HTML 5 Canvas. With little effort and writing zero JavaScript I was able to get an effective Demo.
I used mainly base GWT classes but I did use some of the classes in gwt-g2d. The main classes appear to be partly integrated into GWT so I mainly just used the support classes. It would be nice if gwt-g2d did some of the things it had on it's list and wrapped GWT's canvas classes.
GWT's tooling was very refreshingly fast and easy to use.
I was able to write a little demo artificial intelligence app to show off different programming techniques I had learned in the class I'm taking.

It would be nice if I could fail over my canvas to something else for browsers that don't support HTML 5. LimeJS appears to do this autmatically. LimeJS is probably better for writing HTML based games but I don't want to write a bunch of JavaScript which is why I like GWT. GWT automatically converts all my Java code into JavaScript for me.

Another thing is it puts the war contents in a war directory. All the conventions I've seen it is always a WebContent folder. Also the default source and test directories don't match the standard Maven structure which I imagine I could manually change but it's nice to be able to do it when creating a new project.

Saturday, October 1, 2011

WebGL and game development

I would like to create a game with WebGL and have mainly a Java background.
I don't have much game development experience and no professional experience.
I have worked with OpenGL but it was years ago in college.

I would like to know what engine/framework others would recommend.
I don't really want to pay for a license or pro features so free would be one stipulation.

Akka Actors

I really like the notion of using akka actors in Java. Basically it is trying to solve the problem of easily writing thread safe code. It does this by passing immutable messages to actors which process them. The idea is that the actor should be stateless and only act upon the immutable object it's given. They also appear to have Software Transactional Memory (STM) for when you do need mutable object and locking.


I have doubts novice programmers which couldn't write a correct singleton or proper thread safe class would be able to use akka to write thread safe code. I could see them creating all kind of actors which are not thread safe.


I did find it was really easy to get a lot of concurrency almost to a fault where my laptop was maxed out and overheating. Of course that may have been my fault as I gave it an infinite computation to work on.


I don't understand why packages don't have remoting support built for the Servlet API. Akka has a remoting support but I always work in a full J2EE container so getting ports opened and bypassing it would not be an option. I would like to know who needs stand alone remoting and is not working with at least Tomcat.

I'll definitely check akka out in more depth.

Guava

I really like the Guava libraries. One of the best things in there is ImmutableList. I like the idea of using ImmutableList on an interface. This way you don't have to worry about synchronizing the list because the list won't change on you and throw a concurrent modification exception. The builders are awesome. Unlike Apache Commons Collections it supports Generics on collections which is awesome. There's other Immutable collections and objects in this library too.

I do find a lot of other useful utility classes in Guava but it is not as complete as Apache Commons Lang and Collections. So I find myself using all three.

Wednesday, August 25, 2010

Continuous Integration

We used continuous integration in my department for a year and wanted to share some feedback. First just to summarize I absolutely loved it. I tend to think about the time before we were using it as the dark ages and now we are in the renaissance of development. We used Hudson for our continuous integration server. We used the version prior to the fork with Jenkins and I'm not sure which I'd opt for now. I'd probably go with Jenkins if the community moved there. I may also refer to it as our build server although it really does a lot more than building.

Benefits:
1) Automatic feedback when somebody breaks the build.

This is really important to get that immediate feedback so somebody can go in and fix things right away. No more waiting for days and then discovering somebody made a change and everything is broken. This was immensely helpful with our developers in India as they regularly forget to check in files. If they don't leave things in a stable state they will get an email that the build is broken.

2) Automatic running of unit tests.

Some developers are better at writing unit tests than others. Some don't bother to run them after they make changes. Then when the application went from development to maintenance who knows if the tests were ran or updated.
With a continuous integration the tests get ran automatically every time a build runs so you get an email if you've introduced something that goes against the set behavior outlined in the unit tests.

3) Standardized project configuration and setup.

Every application we created was basically up to the person creating them as to the folder structure and conventions used. Once you start putting things on the build server you see the need for a standardized folders and conventions. User libraries get standardized. This helped us in the fact that once you have a job setup for a project you have standard setup for an application to refer to. Less issues with it working on one persons machine and then not another persons machine.

4) Automatic deployments

We had the capability to automatically deploy the EAR files directly to our developer and staging environments. This is a huge time saver and reduces errors. There was always people exporting EAR files from our IDE, deploying them, and they wouldn't work. Just repeated exporting and deploying can eat up time. It's just nice that if the build is successful and passes unit tests that it is auto deployed. This also helped with people working remotely from home as it was slow to deploy when connected to VPN.


5) Metrics

The reports you get out of Hudson with plugins are great. Unit tests pass/fail, code coverage, bugs.
We utilized FindBugs, PMD, Task scanner, and Checkstyle plugins. We also created a couple custom ones to suit our specific needs.
The FindBugs and PMD bugs are great in that you can find common coding mistakes and critical errors like thread safety problems automatically. They let you navigate to the line of code with issues and then gives you a description of the issue and an example how to fix it. You can also check for duplicate code with the copy and paste feature.
We are in the process of investigating enabling Crap4j and JDepend to measure complexity and dependencies.
These reports are very helpful to determine when coding is complete and ready for integration testing. For example: When the unit tests get to 70% code coverage, they all pass, there are no outsanding critical/high level bugs, and there are no open FIXME or TODO issues then you are ready to start integration testing.
If someone ever asked my how confident that what we wrote is right I'd go to the code coverage to the conditionals covered and say well I'm 30% sure.
The only report I didn't really find was lines of code which there probably is a plugin or option for. With lines of code report you can tell when the lines of code have hit their peek and the developers are refactoring code instead of actually developing code which indicates they will be ready for integration testing soon.
Some of the complexity warnings from PMD and FindBugs are helpful in detecting overly complex code which should be re-written so it will be easier to read and maintain but also less bugs and issues.

6) Traceability and Meta-Information

Every JAR built with the build server was given a fingerprint. If the JAR is used in multiple builds you can trace the JAR back to which build it came from. In addition we wrote out meta information with the build job name, build number in the MANIFEST.MF in the META-INF folder of EARs, JARs, and WARs. This way we could look at our environments and see where an artifact actually came from. We also utilized this a bit for our QA testers to report bugs they would write down this information so we could tell if it was an old bug that potentially needed retested or new bug.

7) History

You can keep a history of builds for however long you want. This was helpful if we wanted to restore old code to back out changes quickly. You can also see who introduced what changes and when.

8) Fun

We enabled the The Continuous Integration Game plugin which helps build good development habits of doing commits small sets of code changes and running unit tests before commits. Basically if you break the build or break unit tests you get points subtracted. If you have a successful build then you get points added. It keeps track of a leader board.

We also enabled the ChuckNorris Plugin which was loads of fun with funny pictures and programmer sayings when the build is broken or successful.


Drawbacks:
1) Setup of projects.

It was nice for new applications we just used a generator to generate it according to standards. However legacy applications were all built in a non-standard way. We had to either add options to our build scripts to override the defaults or change the legacy applications.

Once we got an example of each particular application type on the build server it was not really any effort at all to add another. You just copy an existing job and change the parameters.

2) Abandoned unit tests

Some of our older applications had either no unit tests or were in such bad shape that most didn't pass anymore. We had to set a standard for legacy or maintenance applications verses newly developed applications.

3) Clearcase integration

Clearcase did not seem to integrate well with Hudson as views would randomly get lost from the repository. While this was an occasional hiccup it certainly was not enough to prevent us from continuing. Not sure if we ever figured out the issue but we had the notion that ClearCase command prompt api was never tested with any concurrency of commands.
We later moved to using Subversion with Hudson and it works wonderfully.

4) Ant

While Ant is a wonderful tool I believe we could have managed build inter-dependencies better if we had used Maven with an artifact repository. A lot of times we manually copied jars from the build server and checked them into the consuming application's code. It would be nice if we were using Maven that if we changed a Java Project the build would create a new JAR and publish it to the maven repository. Which in turn would be detected and kick off builds for all the applications that used that JAR.

Saturday, August 21, 2010

Collection Initialization

Early in my career, fresh out of college, I inherited the code for one of our tools that ran on a nightly timer. I was in charge of enhancing part of the application to add some functionality.

Fresh out of college I remembered that initializing hash maps size to just over the desired size leads to optimal hashing. Basically without proper sizing everything is hashed to the same node in a linked list which defeats the purpose of a hash map.

This tool used to take around 8 hours which was scheduled to run at night.
So you might think the following:
1) So what if it is more efficient
2) It re-sizes itself so why bother doing it myself

After I initialized the the hash map to the appropriate size the tool went from running 8 hours to running in less than an hour. That's a 7 hour gain.
After this I realized that:
1) Collections take time to dynamically re-size.
2) Collections will constantly be resizing as they run out of room.

Now that the tool took less than an hour it could be run a couple times during the day ad-hoc. When changes were needed to the tool you could verify the results in a manageable time period. When the job failed for whatever reason the whole task could be restarted and do two days of work in 2 hours instead of 16 hours.

Suggestions as to when you should initialize collections:
1) If you are going to put more than 100 objects in it.
2) If you are a cautious/defensive developer like me.

I'm not as worried about getting the optimal size as long as you are relatively close.

Saturday, July 3, 2010

OSGi and JEE. Is it possible?

I am curious about others experiences OSGi with JEE? OSGi seems like a solution to dependency collisions, allows for versioned modules, and hot deployment. I've seen several different variations on using OSGi with JEE. It seems application servers are starting to pick up on it which is a great thing. However I was wondering if anyone has used it for local native services? I see people use it for Servlets and serving simple JSPs. I was hoping to use it for local native Java services that allow exposing interfaces in Java like web services do but don't bring any dependencies into the picture like normal POJO Java Services do. Unlike web services OSGi services should not have the overhead of transferring things over the wire. I've saw forum postings where people have troubles using JEE resources that are exposed through JNDI. Is this really an issue that is of concern? Also if people have any tools or tips for working with OSGi bundles it would be much appreciated.

Saturday, June 19, 2010

Thread Safe Code and Stress Testing

It just amazes me how much code makes it past code reviews that is not thread safe but should be.
Developers often know that certain code has troubles if it is not thread safe and what thread safe means. However they are not able to effective discern what needs to be thread safe and what does not. I had an individual that was very aware of these issues help mentor me as to how to detect these types of problems. I had seen problems and fix them prior to his mentoring but he really helped me to be proactive and see threading issues when authoring code.

The biggest issue is lack of understanding that beans defined in Spring are singletons. Also even if you inject a prototype into a singleton it effectively makes it a singleton. Then there are the problems where they improperly implement the singleton pattern, randomly synchronize things that don't need to, or create static variables that are not thread safe. I've seen so many times where developers create a static SimpleDateFormat instance. Recently I saw a DAO with local variables that were not thread safe. I also recently saw a persistence layer where they tried to manually implement the singleton pattern but didn't do it correctly so the local variables that were thread safe were not initialized correctly leading to NullPointerExceptions.

I tend to see threading issues revealed when load testing is performed. However to my amazement load testing is not always performed. I've also seen some some threading issues that have snuck past load testing and have never presented themselves as a problem.

We use a continuous integration build server but it only lists thread safety problems as warnings and then only catches half of them because it doesn't know what should or shouldn't be a singleton and thread safe any more than the developers do.

I've recently initialized an internal developer training effort.
There are relatively few developers that can detect these errors and even fewer that can fix them. So it is really an issue as these developers can not code review every line of code.

Are there any ways to catch these kind of problems earlier or some good resources to aid in developer training? Do people have similar experiences?

It seems most developers don't care that code has any more quality than it appears to work correctly. Am I being a little anal retentive and should just go with the flow, realize that code will not be perfect, and just let these problems exist and get resolved later?

Tuesday, June 15, 2010

First Groovy Script

A couple days ago I wrote my first Groovy script. Of course it had to be loaded into the Spring IoC container to wire it up to the beans using it.
Having a Java background and looking at Groovy's website it was very hard to define a pretty simple class with a method that implements a java interface.
First it made me use the def keyword with the method definition whereas the documentation didn't even have an example of how to write a method.
Then it made me define the return type of the method because it was saying it didn't match the interface return wheras the documentation seemed to indicate these did not have to be statically defined/typed.
The method took in no parameters and returned a List and was returning [instanceofMyObject1, instanceofMyObject2]
The documention showed defining typeless variables without using the def keyword.
It kept looking for member variables in the class so I had to define each one with the keyword def to get it to work.

Is the Groovy documentation really lacking good basic examples like writing a class with a method and using local variables?

The documentation outlined some of the power features but did very little to help people learn the basics other than go over some command line Groovy examples.

Can people recommend some good resources for a Java developer to learn and effectively take full advantage of the capabilities of Groovy?

Thursday, August 21, 2008

Integrating Legacy Systems

Recently we tried to integrate a legacy system via exposing a few mainframe programs via web services.

Exposing data as a web service does not make a web service.
Lets examine why:
a) Lack of re-usability - The mainframe programs return course grained data specific to a particular need it was developed for. This leads to having more data and more specific data than any other app would need to reuse the data. For example instead of a code or status returned it returns a message intended to be used by the consuming application. This data is virtually unusable to another application because most of the time you need the deciding code or status to perform logic later on.
b) Lack of performance - Instead of returning a code or status very verbose text is being returned. Now instead of a low overhead code or status you have a large message being transferred over the wire which may not be used. If this web service is consumed by another web service layer then transporting this around is going to be slow.
c) Design constraints - The mainframe program was designed for a particular use which they didn't take into account limiting the repetitive sections. They would return all 100 instances of a section of data. If only the first 5 had data they would return all 100. This adds great overhead on a web service. Also the data that comes from a mainframe program is not trimmed and has filler fields filled with whitespace.


If you don't have somebody regulating or asking the right questions then anything will become a web service which shouldn't be. I recommend a group of architects and/or tech leads making the decision of whether something should be a service.

Here are some guidelines/questions to ask yourself for web services:
1) Ask yourself or group why are we making this a web service? What are we hoping to accomplish?
a) When you go to a web service you are giving up performance for agility.
b) Make sure you're willing to deal or accept the trade off.
2) Does it meet any of this criteria?
a) Is this going to reusable by other applications? Which ones?
b) Is this something that crosses boundaries or something which I can't control? For example if you are exposing something to another business unit or exposing it for public use.
c) Is this enabling system integration for systems that were not able to integrate before.
d) Is this coarse grained enough for general use?
e) Is this data going to be suitable for multiple hops?

Saturday, August 16, 2008

Building the Base - Data Integrity

Something I feel is far too often overlooked in software development is data integrity.
I would like to further define it as strong data typing.

The source of lack of strong data typing is several places.
1) Lack of proper column types in the database.
2) Reuse of typed columns to mean different things.
3) Programs/Stored Procedures that decrease the strength of data typing.
4) Flat file (fixed record formats)

Now I'm not a DBA or anything like that.
But one thing I've noticed when developing JSF applications is lack of data integrity seems to bubble it's way up into the presentation layer.

It should be dealt with at the source to provide a better base for an presentation/gui layer.

1) Lack of proper column types in the database.
If you are using clobs, blobs, text, varchar, or whatever flavor of large catch-me-all for typed data please stop. One symptom is that all your columns seem to have the same type. Please use date, int, time, timestamp, bit, numeric, float, decimal, bigint, tinyint.

2) Reuse of typed columns to mean different things.
Use of low values or high values to mean something:
99.99, -1, or any date like January 1st, 1900.
I think almost any database or language has null built in for this reason.
I'll see logic if 0.00 or 99.99 then display N/A so why don't we just define another column with a one character value and a domain table.
So instead of this:
Effective Date: Jan 1st, 1900
We do this:
Effective Date: null Effective Status: 'P'
where there would be a Domain Table with things like 'P' - Pending, 'T' - Terminated, 'I' - Invalid and 'U' - Under Review


3) Programs/Stored Procedures that decrease the strength of data typing.
If you read in two strongly typed and return a lesser typed one this would be a smell. For example if you take two Numbers in and generate a String number result and N/A result sometimes.

If you take two specific things and return a generic one then that is a smell.
For example if you take name fields and put them together to display. Well this is all good but what if you then want to pre-populate a name into a form. How do you parse a complex name which may or may not have middle initials and a suffix?

4) Flat file (fixed record formats)
This is the root of all evil because there are no rules as to what goes where as long as it fits.
I propose that you establish a contract with the generator about the types if possible.
Don't leave it in flat file format, extract it into a strongly typed database and throw out invalid data. It is better to throw out or reject rows than to have it in your database.

Sunday, August 3, 2008

No Fluff Just Stuff

This is the second year I've attended the No Fluff Just Stuff conference.

If you've never experienced the conference and you do any kind of software development that involves/runs on the Java VM (Java EE, Java SE, Groovy, Grails, etc) I strongly encourage you to go.

Even if you don't do any Java related software development but you work in Quality Assurance/Testing or Business Analyst/Requirements Development there are beneficial courses for you too. Some of these courses seem to be more geared towards this group but are attended mostly by developers. This seems to stress the notion of one software developer to change the world. One thing that comes from some of these sessions is the notion of collaboration. So instead of one person in one group (Software Development in my case) I'd like to encourage people from other groups (Quality Assurance/Testing or Business Analyst/Requirements Development) to attend also. This way we can change the world together!

The only thing I can say in any way negative about this conference is they seem to have a lot of things that are new and shiny new things like Groovy, Grails, Agile, and GWT. I work in a large behemoth of a company that is a slow moving, slow to adopt, vendor locked, internal standards driven. These things seem to be something that can be implemented more in small shops or don't have resistance to change (or regulations). Even this being said I still thing attending some of these are good for me because you can extrapolate some of the tips for your organization even if it really is an apples vs oranges environment.

I really enjoyed some of the concurrency, architecture and scaling, SOA, and Agile sessions. Last year I liked some of the continuous build, testing, and hacking sessions. I find some of the Facelets, JSF, Spring, Hibernate courses rather introductory but for some might be invaluable.

One thing (it's hard to name everything) I really like about the conference is that it is small enough you can ask questions and have a small group feel. A lot of the sessions are interactive and make good points.

You really get a lot of books recommendations from this conference some related more to software development philosophy rather than really technical books.

The keynote speech is greatly entertaining, funny, and informative.

This conference is also big on open source and you don't find any real vendor driven presentations.

Friday, December 7, 2007

JSP vs Facelets

One of the saddening aspects of JSF is the rendering of HTML along with JSF components in JSP pages.
For example


<div><div>Some Header</div>
<ul>
<li><h:outputText value="list item 1">
</h:outputText></li><li><h:outputText value="list item 2">
</h:outputText></li></ul>


will actually render as


list item 1list item 2
Some Header
<ul><li>
</li><li>
</li></ul>


Alright now the problem is that the HTML is written out right away and the JSF components are rendered at a different time.

Another situation is when you have HTML before or after a JSF Component.


<h:panelGroup>
<p>some markup</p>
<h:outputText value="some text"/>
<p>some more markup</p>
</h:panelGroup>


will render as


some text
some markup
some more markup


Now if you ask me since the default view is JSP for JSF they should have taken this into account.

They should key off the include of JSF tags in a page to parse the JSP differently.
Instead of rendering it like they do they should gather the HTML and attach it to the view in a verbatim component or some other kind of ui output component in the appropriate place in the JSF component tree. This should be possible because everything should be enclosed in a <f:view> tag.

Either that or you have the custom jsf tags be body aware which I assume they are and output the html prior to rendering their component/child component and then render html after the component.

I'm not sure which way is best or where this would take place but it seems very doable.

Now some people say Facelets is the answer and dump JSP all together.
I agree this is a way to fix it but this doesn't let you reuse any JSP tags that are non-JSF.
In the real world there are lots of JSP tags that are not JSF that still need to be reusable.
Also there was a reason for JSP pages in the first place and I'm not sure facelets fully fills that gap.

The real answer should be to fix JSP complation, JSP Rendering, or JSF tags where ever this should take place.

Whoever was responsible for the JSF spec should have seen to this in the first 1.0 release.

Sunday, August 12, 2007

Tiles Killed Convention - Facelets Templating

I recently went to a developers conference and listened to a rapid application development with JSF session by David Geary. I found the session very helpful and informative but something keeps bothering me every time somebody talks about templating as he did with Facelets.

Every time I hear about templating I think it should be easier and more reuseable. I started out developing Struts applications which use Tiles. I then moved on to JSF and Tiles. The nice thing about Tiles is "it works". Sometimes just working is not enough and a little convention goes a long ways.

Recently I've been thinking about the convention over configuration mentality that RoR uses. Also I've come upon a great templating package called Sitemesh. What I love about Sitemesh is you can define a decorator and decorate multiple pages by a matching URL pattern. This is a GREAT idea. Using Tiles I've always had to create a definition for every page in a Tiles definition file, a JSP that inserts the definition, and the page that actually has the content. Well that's three files for each page of content the user sees. Now the problem I have with this is the Tiles definition for the page and the tiles insert JSP is basically repeated for every page. Sure you can define a base Tiles definition and extend it but it tends to be mostly repetitive. You can also define your tiles definition in the JSP page which is just as messy and repetitive.

Let me get back to Facelets. Facelets is a wonderful idea to use the html view and bind to components. The problem is when you get to the templating part it goes back to the Tiles mentality again. You have a page which defines a composition and a page which contains the content. The page with the composition is repeated for every content page and in most cases the exact same composition definition. This is where the convention of Sitemesh is nice and could come in handy. It would be nice if you could define a Facelets composition for a URL path and apply it to all pages in a directory. That's a heck of a start for reuse and convention over configuration. Then you can just configure the exceptions to the case which should be rare.
Sidenote: You can use JSF components in a Sitemesh decorator (http://jira.opensymphony.com/browse/SIM-201).
There are a couple of positive benefits to applying templates based on a URL path that are a side effect. I've been on too many projects where everything is thrown into the base directory of a web application or relatively few directories. This gets out of hand quickly and not good structure. There are also security packages like Acegi that will apply security based on the URL path. So if you have your files in an appropriate file structure it should be easy to find pages, apply templates, and apply security.

(If you don't think it can be done check this out: http://jira.opensymphony.com/browse/SIM-223)

This brings up another annoyance of JSF. JSF has no notion of subdirectories built in. With Struts you could define config files for each URL path and then you didn't need to put the subdirectory paths for the JSP pages in a configuration file. JSF should add this in and promote appropriate directory structure.

As a closing note if you're doing something multiple times and not much changes maybe you should refactor it out. If you are doing this in programming maybe you would extract the commonalities out into a method passing in the parameters and then the method can be reused. In the case of a templating package you should refactor the configuration out of the JSP page or Faclets xhtml view and move it into the URL path with a configuring Servlet or Filter.

Thursday, August 9, 2007

Optimistic Locking in Rails with Active Record for Free...almost

Like other persistence frameworks, ActiveRecord helps us with concurrency issues. This is actually fairly simple, but in general the documentation I have found on this subject has been poor. I will try to sum this up very quickly.

1) Add lock_version

For each table where concurrency is a concern a lock_version column must be added; Rails is then supposed to perform some magic behind the scenes...

In your migration this should look as follows.
table_name.column :lock_version, :integer, :default=>0

Alternatively, if you already have a versioning column in your database you can inform rails of your column by adding the line "set_locking_column 'your_versioning_column_name'" to the associated model class.

2) Catch StaleObjectError

Now that you have added the lock_version column you get concurrency for free. Whenever an attempt occurs to save over the same record version an ActiveRecord::StaleObjectError will be raised.

So now you can update your controllers to catch StaleObjectErrors and handle these however you wish...

This would look something like this.

def some_updating_method(an_object)
an_object.update_attributes(params[:an_object])
rescue ActiveRecord::StaleObjectError => e
flash[:notice] = "This record changed while you were editing it. Please try again."
#maybe perform a redirect here...
end

3) But Wait! Update methods aren't actually passed objects that's too much overhead!

How observant you are. This is where most of the example tend to fall short. In fact, try implementing your update method exactly like Recipe 3.18 from the Rails Cookbook and see what happens...

Generally an update method actually looks more like this.

def update
my_object = MyObject.find(params[id])
my_object.update_attributes(params[:my_object])
end

While this will stop to users from updating at the exact same time this isn't exactly what we want in many cases. More often than not we want to prevent two users from editing over each other without knowing.

This is easily fixed with the following...

def edit
my_object = MyObject.find(params[id])
session[lock_version] = my_object.lock_version
# whatever we want edit to do
# ...
# ...
# call update...
end

Now we update update (har har) to detect the concurrency issue...

def update
if my_object.lock_version != session[:lock_version]
raise ActiveRecord::StaleObjectError
end
my_object = MyObject.find(params[id])
my_object.update_attributes(params[:my_object])
rescue ActiveRecord::StaleObjectError => e
flash[:notice] = "This record changed while you were editing it. Please try again."
#maybe perform a redirect here...
end

Hopefully this helps someone out. If you have a better/cleaner way of doing this, let me know.

Thursday, August 2, 2007

Drop all tables in MySQL

From time to time I would like to be able to drop all of the tables in my MySQL database without actually dropping the database. This can be painful if there are many tables in the database. Recently I came across this little nugget that simplifies the process.

mysqldump -u[username] -p[password] --add-drop-table --no-data [database] | grep ^DROP | mysql -u[username] -p[password] [database]

Voila! All your tables are gone!