I haven't read all of your code in detail, but instead tried to look at it as a whole. I think the first bit of insight I can offer you is
here.
The questions you ask have many correct answers, as they relate to coding style, software design and architecture. I'm confident you'll find a large amount of suggestions in the Monastery.
What follows are some of my thoughts about what I've seen so far in your task and solution:
- You're using a dispatch table to direct people to different handlers depending on what they need to do. I think this decision is right. However, remember than there are many other ways to do the same. In particular, having one script for each task might significantly ease working with your code.
- You seem to be encapsulating an interaction with a backend database. Try to think about an internal representation for the data and for the operations that can translate for all your tasks. These two things are natural candidates for becoming modules, invoked from different scripts.
- If you manage to encapsulate the access to the data in a set of modules, chances are you will be able to also encapsulate the generation of the interaction forms. Depending on how your scenario looks like, this might be an extension to the modules from the previous bullet, or a new module.
- At the very least, you can try to keep all of your query statements in a single file. This will clean up the rest of the code a bit.
Now, regarding your specific style questions:
- I normally try to improve maintainability and portability over speed, as long as the results are produced within reasonable times. Note that this choice is heavily influenced on what are you being asked to do, and where are you doing it (ie, who do you work for :)).
- In a similar note, try to maximize the speed at which you can provide a prototype for your application. My experience is that programmer's time is more important (and more expensive!) than machine time. Do not over-optimize, it takes a lot of time and the effort might not be worth it. Also, do not optimize until you have a running application that passes all your tests.
- I try to keep my code as general as posible. This increases the chances of it being re-used for other projects.
- I don't like code blocks that are longer than a page of text. When I see such a block, I tend to split it into subroutines.
- I use as many modules as I need to. Sometimes, things fit together nicely in a single module. Some other times, you need many modules to encapsulate different or unrelated functions. Normally, you will be using more than a few modules, but not all are going to be yours... CPAN is your friend (hint, hint, hint!)
- There are many ways to customize the actual behavior of a piece of code. The choice here is heavily influenced by other criteria (size of the resulting code, maintainability, generality, protability, etc.). I've used many schemes, including passing a closure to a function.