Wanted: Migrating To a Newer Image Part 2

In the last post we migrated the Wanted source code to a newer image by using a local Monticello repository. That gave us a working Wanted application, but the WantedItems that we created in the old image weren't copied over. This post will focus on copying the data out of the old image and into the new one.

Write Out the Collection of WantedItems

Fire up the old Squeak image, open a workspace and execute the following:

| out |
out := DataStream newFileNamed:
out nextPutAll: WantedDatabase wantedItems.
out close

This creates the temp variable out to hold a DataStream object pointing to a new "wanted-items.dat" file. The nextPutAll method takes a collection of objects and writes it to the receiving stream before closing it.

Exit the old Squeak image--this will be the last time we need it. From now on, all things in these tutorials will be done in the new image.

Read In the Collection of WantedItems
Fire up the shiny new image, open a new workspace, and execute the following:

in := DataStream fileNamed:
[in atEnd] whileFalse:
[WantedDatabase wantedItems add: in next].
in close

The above creates a new DataStream off of the "wanted-items.dat" file (notice we're using the fileNamed message to create the DataStream instead of newFileNamed). The [in atEnd] block will return false until all objects have been read from the file. We pass that block another block that adds each object read in (using the next message) to the WantedDatabase wantedItems collection. Then we close the DataStream.

We now have our old WantedItems in the new image. Open up a browser and head to http://localhost:8080/seaside/wanted. You should see something like this:

Enable File Serving in Commanche

Our new image is not serving our css since Commanche is not enabled to serve files. Paste the following into a new workspace and "do it":

| ma seaside |
HttpService allInstancesDo:
[:each | each stop. each unregister].
WAKom stop.
seaside := WAKom default.
ma := ModuleAssembly core.
ma serverRoot: FileDirectory default fullName.
ma alias: '/seaside' to:
[ma addPlug: [:request | seaside process: request]].
ma documentRoot: FileDirectory default fullName.
ma directoryIndex: 'index.html index.htm'.
ma serveFiles.
(HttpService startOn: 8080 named: 'httpd') plug: ma rootModule

That should get you to this:

That Entered Date Format Has Been Bugging Me
Me too. We can solve that by adding a formatBlock to the WAReportColumn that handles the enteredDate in WantedList>>initialize:

((WAReportColumn selector: #enteredDate title: 'Entered Date')
[:enteredDate | enteredDate asDate mmddyyyy];

We get the date to show up in mm/dd/yyyy format by sending the asDate message to the enteredDate of the WantedItem, then sending the mmddyyyy message to that date.

While we're there, let's modify the "Can Buy" WAReportColumn to show 'Yes' or 'No' instead of the robot-like 'true' or 'false':

[:item | item isPurchasable
ifTrue: ['Yes'] ifFalse: ['No']]
title: 'Can Buy');

This is accomplished by sending the isPurchasable predicate the ifTrue:ifFalse: message with a "Yes" or "No" value respectively.

Those changes should give you something like this:

Saving Changes
Since we made source changes, we should commit them to our local Monticello repository. Open a Monticello Browser and select the Wanted-Item package in the left pane, and the local repository in the right pane:

Notice that an asterisk appears before the package name: this signifies that changes have occured in the package. Click the Save button and enter a version message describing the changes we made:

When you hit Accept, a version info window will display letting you know that the changes were successfully saved. At this point, save the image so that the WantedItems will be persisted. And that's it for this post--we are now fully migrated over to the new image. By now it feels like we've kinda worn out the simplicity of saving the WantedItems in a collection in the image. If we had had the data in a store somewhere, we could have just pointed the new image there instead of this file reading/writing stuff. Future posts will address this.


Anonymous said...


Are you still around? I want to thank you for taking the time and effort to produce this outstanding series of Seaside tutorials. I've always wanted to learn Seaside, but I found the documentation skimpy, confusing, and foreboding. This tutorial has addressed that void.

Are you still actively working on this blog? Your last post was in April, and now it is October. I'm somewhat familiar with the amount of effort and energy it requires to put together a tutorial of this quality, so I would understand if you have other pressing things to do besides teach us how to program in Seaside.

However, if you ever feel the urge to start writing again, please be sure that you have a willing and eager audience!

Thank you so much for your work to date.

mj said...

Hey--thanks a lot for the nice comments--I appreciate it.

Unfortunately, I'm not sure that I will be producing any more Squeak/Seaside tutorials. After Erlang started getting noticed, I jumped at the chance to learn it since it was something completely different from what I was used to. One thing led to another, and I started looking at other languages (I think it was Ruby, OCaml, Scala, Oz, and Lisp). After getting tired of not producing any real work/projects, I decided to focus on just one language and chose Common Lisp.

I left this site up because it still gets a decent number of hits. I'm not sure what to do with it.

Have you started a blog? I highly recommend writing about your learning experiences--it helped me a lot when learning Squeak and Seaside.